Catalystize!

コーヒー美味しい

PDRUNCFG0の挙動とSDK APIの対応

LPC55S69に搭載されているPower Management機能は細かくペリフェラルごとに電源を落とせるようになっている。 クロックの供給を止めることによる電力制御もあるが今回はPDRUNCFG0による電源制御についてメモ

PDRUNCFG0

NXPのWebページからダウンロードできるUser Guide UM11126 Rev1.9のChapter13によると、このレジスタを操作することによってアナログコンポーネントの電源を制御できるという。

ただしこれはActive Mode1での挙動で、Sleep Modeなどの場合の制御については別途設定があるようだ。

ここでいうアナログコンポーネントには以下のコンポーネントが含まれている。

  1. VBAT Brown out detect
  2. Free Running oscillator 32khz
  3. Xtal 32kHz
  4. Xtal 32MHz
  5. PLL 0
  6. PLL 1
  7. USB Full-Speed PHY
  8. USB High-Speed PHY
  9. Analog Comparator
  10. LDO for USB High-Speed PHY
  11. Auxiliary Bias (?)
  12. LDO for Xtal 32MHz
  13. Random Number Generator
  14. PLL 0 Spread Spectrum module

そしてこのPDRUNCFG0にはSetとClearを行うためのレジスタも別途用意されており、fsl_power ライブラリからはこれらレジスタから操作されている。

fsl_power に含まれているPOWER_DisablePD関数ではPDRUNCFGCLR0レジスタを使用してアナログコンポーネントのPower Upを行う。 それと逆にPOWER_EnablePD関数ではPDRUNCFGSET0レジスタを使用してアナログコンポーネントのPower Downを行う。

これらはBOARD_BootClockPLL150M関数の中だったりUSBを利用するときに呼ばれているのを見る。

そして一箇所、PDRUNCFG0レジスタではReservedとなっているBit5にて、どうもサンプルコードではそこを触ってFRO 192MHzをOnにしているような挙動が見えるのだが…


  1. Reset直後の動作モード

Visual Studio Code で NXP製 ARM Cortex-M マイコン向けの開発環境を作る

主に自分の備忘録&同じ環境を作って欲しい人向けの記事です。

NXP製のマイコンのなかでも、最近のCortex-Mシリーズを採用した製品はWeb上のMCUXpresso SDK BuilderによってIDE向けのプロジェクトファイルを作成して利用することができます。

このSDK Builderで生成できるプロジェクトファイルはターゲットのIDEを選ぶことができ、MCU Xpresso IDE以外にもKeil MDK や IAR向けにも作る事ができ、さらにGCC ARM Embeddedという選択肢もあります。 GCC ARM Embeddedを選択して作成されるプロジェクトファイルの中にはbuildのためのスクリプトとCMakeを利用するためのCMakeListが含まれていて、ツールチェインが正しく設定されているならばMCU Xpressoなしで開発をすることができます。

今回は下のくにゅくにゅ氏の記事をベースに、NXP製マイコン向けの開発環境を作る手順をまとめます。

kunukunu.hatenablog.com

必要なソフトウェア / VSCode拡張

VSCode 本体

Visual Studio Code - Code Editing. Redefined

GNU ARM Embedded Toolchain

GNU Toolchain | GNU-RM Downloads – Arm Developer

インストール先はなるべくスペースとか入らないような場所にする。たとえばC:\tools\gcc-arm-none-eabi-9-2019-q4-majorとかにする。 インストール時にPATHに追加する

・CMake

Download | CMake

インストール時にPATHに追加する

・OpenOCD

Releases · xpack-dev-tools/openocd-xpack · GitHub

適当な場所に展開しておきます。 自分は以下のようなフォルダ構成になるよう設置しました。

C:\tools\xpack-openocd-0.10.0-13-win32-x64\xPack\OpenOCD\0.10.0-13\bin

・msys2

MSYS2 homepage

・JLink Driver

https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack

これはデバッグインターフェースにJLinkを使用する場合は必要です。

インストール後の作業など

まずはVSCode自体が必要です。これをインストールし、さらに氏の記事にもあるように、VScode上でC/C++拡張とCortex-Debugの拡張機能をインストールします。 さらにCMake Toolsをインストールします。CMakeをVSCodeから利用するための拡張機能は複数ありますが、Microsoftが出しているものを利用してください。

CMake Tools - Visual Studio Marketplace

msys2はMake自体を走らせるために必要です。 インストール後にpacman -Syuとしてリポジトリの情報をアップデートしたあとに、pacman -Sy makeなどでインストールします。 msys2にmakeをインストールしたので、Windows側でPATHを通します。さらに環境変数MSYS2_PATH_TYPEを作成し値にinheritを指定しておきます。

VSCode 上の設定

VSCodeにインストールした拡張機能を使う上での設定をいくつか行う必要があります。 VSCode本体や拡張機能の設定を行うためのsettings.jsonと、デバッガ起動のためのlaunch.jsonの二つを設定する必要があります。

setting.json

以下に示すコードはターミナルとしてMSYS2のbashを利用するための設定も含んでいます。

{
    "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
    "terminal.integrated.env.windows": {
        "MSYSTEM": "MINGW64",
        "CHERE_INVOKING": "1",
        "MSYS2_PATH_TYPE": "inherit"
    },
    "terminal.integrated.shellArgs.windows": [
        "--login"
    ],
    "terminal.integrated.cursorStyle": "line",
    "cmake.configureOnOpen": true,
    "cmake.buildDirectory": "${workspaceRoot}/build",
    "cmake.sourceDirectory":"${workspaceRoot}/armgcc",
    "cmake.generator": "MSYS Makefiles",
    "cmake.configureArgs":[
        "-DCMAKE_TOOLCHAIN_FILE=${workspaceRoot}/../../../../tools/cmake_toolchain_files/armgcc.cmake"
    ],
    "C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
    "cortex-debug.JLinkGDBServerPath": "C:\\tools\\SEGGER\\JLink_V660c\\JLinkGDBServerCL.exe"
}

上記の設定で特に重要なのはCMakeまわりです。

GeneratorとしてはMSYS上のMakeを使うことを前提にMSYS Makefilesを指定しています。

そしてcmake.configureArgs で指定しているファイルパスですが、これはMCUXpresso SDK Builderで吐き出されたSDKの中のarmgcc.cmakeを指定してください。 このときは相対パスで記述していますが、絶対パスでも問題無いはずです。

また最後にcortex-debugでJLinkを使用する場合の設定を加えています。このときJLinkのGDBサーバーを起動するために実行ファイルまでのフルパスを記述する必要があります。

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "cwd": "${workspaceRoot}",
            "executable": "./build/Debug/led_blinky.elf",
            "name": "Debug Microcontroller",
            "runToMain": true,
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "device": "LPC845M301",
            "configFiles": [
                "interface/cmsis-dap.cfg",
                "target/lpc84x.cfg"
            ]
        },
        {
            "cwd": "${workspaceRoot}",
            "executable": "./build/Debug/led_blinky.elf",
            "name": "Debug Microcontroller(JLink)",
            "runToMain": true,
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "jlink",
            "device": "LPC845M301",
            "interface": "swd",
            "ipAddress": null,
            "serialNumber": null,
        }
    ]
}

上記のJSONファイルには、デフォルトのオンボードLPC-LinkをCMSIS-DAP経由で利用する場合の設定と、JLink経由で利用する方法の二つを書いています。

詳しい説明はCortex-Debugの設定方法を見て貰うとして、CMSIS-DAPを利用する場合の設定にあるconfigFilesについては、target/lpc84x.cfgとしている箇所を 利用するdeviceに併せて変更してください。 ここのcfgファイルはOpenOCDのディレクトリ下にあるscriptsディレクトリの中に格納されています。 評価ボードとして純正のLPCXpressoを利用している場合、board/nxp_lpc-link2.cfg を指定しないでください。 これはNXPの単体デバッガーであるLPC-Link2に使われているLPC4370用のファームウェアを書き換えるためのものです。

おわりに

そのほか、IntelliSenseまわりの設定はほかのサイトを参考にしてほしいです。自分でもよく分かってないです。

また誤記など見つけましたら教えて貰えると助かります。

AMD Radeon向けOpenCLの開発環境構築のためのメモ書き

ハードウェア構成

  • CPU: Core i5 6600
  • MEM: DDR4 2666 16GB
  • M/B: Asrock Z170 Pro4
  • GPU: RX480+RX470
  • OS: Windows10 (1809)

まず大事なところから

IntelOpenCL SDKを使おう

Visual Studio向けに拡張が入る。そしてOpenCL関係のHeaderとテンプレートがある。

そもそもベンダーを横断して使えるものだからコレで問題無いはず。

software.intel.com

AMD純正のAPP SDKは廃止された

ここのAMD Forumのスレッドを読むとなんとなくわかる。

community.amd.com

基本的にはOpenCLのサポートはドライバ(この場合だとRadeon Software Adrenalinとかのグラフィックスのドライバ)によって有効になっている。 で、OpenCL Header自体はよそから取ってきてねって感じみたい。OpenCL Headerは以下のリポジトリにある。

github.com

Header自体はKhronosのサイトからもダウンロードできたりする。AMDもHeaderを配っている。 APP自体にふくまれていたが、すでにダウンロードできない。 それに付随していたサンプルは使えないが、OpenCL Heade単体は以下のリポジトリのReleaseから取得できる。

github.com

いろんなところでAPPを廃止して分かりにくくしたAMDへの批判を見ることができる。

LinuxではROCmを使おう

よく調べたわけではないけども、コンパイラー含むHPCのためのプラットフォームとかなんとか。 Linuxでしか動かないようなので、今回はスルー。

rocm.github.io

気が向いたら追記する。

gcc-arm-none-eabiで変数を指定したセクションに配置する

LPC54102を使用していて躓いたのでメモ。

Cortex-M系のMCUを積んだマイコンなら同様にできると思う。

attribute((section("name")))の使い方について。

MCUXpresso上ではLPC5102のメモリはPROGRAM_FLASHSRAM[0-2]が設定されているが、変数を任意のSRAMに配置しようとしたとき、 attribute((section("SRAM1")))のように指定してもなにも変化がない。

ここのnameに入れるべきは、以下のリンカスクリプトにある.data.$RAM2という文字列である。

/* DATA section for SRAM1 */
    .data_RAM2 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM2 = .) ;
        *(.ramfunc.$RAM2)
        *(.ramfunc.$SRAM1)
        *(.data.$RAM2*)
        *(.data.$SRAM1*)
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM2 = .) ;
     } > SRAM1 AT>PROGRAM_FLASH

リンカスクリプト上で、*(.data.$RAM2) と記述されている箇所は、最初のアスタリスクですべてのオブジェクトファイルを対象にしている。 二つ目のアスタリスクはセクション名のワイルドカード?軽く調べてもあまり分かりやすい説明がなかった。

つまりは__attribute__((section(".data.$RAM2"))) とするべきのようだ

Let's Splitで自作キーボード入門したので、I2Cで遊んでみた

この記事は自作キーボード Advent Calendar 2017 12/20 分の記事です。

adventar.org

はじめまして、ひでん (@klNth) です。

今回は友人に誘われ、まんまとキーボードを作ってしまったのでその話と、 せっかくマイコンが載っていてI2Cで通信できるということなので、それで遊んでみた話になります。

あらすじ

今年8月頃、Twitterで散々「Ergodox作りたい。Let's Split作りたい」と言っていたのがきっかけで、出来心で検索してしまい 挙げ句の果てにはその友人とLet's Splitの部品を共同購入し作ってしまいました。

f:id:klaNath:20171220220823j:plain

手前のが自分ので、奥のが友人のです。

スイッチやアクリルボードなどの手配、加工は友人が。自分はダイオードとケーブル類の調達などをやりました。 主に友人が調達で大変な部分をやってくれて、本当に助かりました。

キーキャップは袋詰めでいろいろな色が入っているものを購入し山分けしました。スイッチはGateronの黒をチョイス。 一通り組み立てた後に、I2C接続のためにはちょっとしたジャンパーを接続しないといけないことを知り、苦し紛れで接続しました。

初めて分離型&格子状配列なキーボードを使ってますが、肩を開いてタイピングできることに惚れて仕事先へ投入しました。 コレなしだとどうも捗らなくなってしまいました。

I2Cで遊ぶ話

さて、本題です。

このLet's Splitは4極ケーブルを使用し追加の部品をいくつか付ける事でI2Cで分離させているキーボード同士を通信させることができます。

I2Cというのは低速の通信バス規格ですが、これはマスターに対して複数のスレーブをぶら下げることができるので、いろんな機器の中でセンサーだったりちょっとしたICだったりを接続するためによく使用されています。

つまり、I2Cで接続しているLet's Split同士の間に全く異なるICを接続し利用することができます。QMK Firmwareのキーマップの中にもOLEDディスプレイを使用するサンプルがあるようです。

今回はこのI2CにRTC(Real Time Clock)ICであるPCF2127 をぶら下げて、キーボード側からいじれるか試してみました。

まずは信号を見る

ぶら下げる前に、通常状態でのI2C信号を見てみました。ディジタルオシロスコープを使用してやっていきましょう。

f:id:klaNath:20171220223032j:plain オシロスコープをLet's Splitのこの位置に接続し、波形を見てみます。

f:id:klaNath:20171220222932p:plain 長めのケーブルを使用しているからか、I2Cの信号がかなり鈍っていて、良くないです。 ケーブルを短くするのは実用上避けたいので、とりあえずは5.1kOhmと大きめだったI2Cのプルアップ抵抗を1.4kOhm程度に小さくしました。

f:id:klaNath:20171220222938p:plain まあこんなものでしょう。面倒くさくなって片方の基板にしかプルアップ抵抗を着けてないのも原因の一つでしょうが、とりあえずはこれでいきます。

ソースコードをいじる

ここからはQMK Firmwareをいじっていきます。

Let's SplitではI2C通信用にi2c.hを自前で持っていて、lets_splitディレクトリ下のmatrix.cにそれを使用した通信用の関数i2c_transaction()があります。

これを参考にすれば、I2C通信用のコードを仕込めそうです。

今回使用するPCF2127のデータシートを読んで、初期設定値をいくつか設定したいと思います。 キーボードの起動時に一度だけ呼ばれる関数は、lets_splitディレクトリ下のsplit_util.c にあります。

なのでこの中でこんな感じの関数を書いてあげると、起動時に一度だけ走る、初期化用の関数ができあがります。

次はキーが押されたときにI2C通信が行われるようにします。こちらはkeymap.cにいくつか追加すればいけそうだったので、こんな感じに追加しました。

qmk_firmware/keymap.c at master · klaNath/qmk_firmware · GitHub

基本的にはキーが押されたときに分岐してI2C通信用の関数を呼ぶようにすればOKみたいです。 このテスト用のコードでは、I2CTESTを割り当てたキーが押された場合に、RTCの秒数をカウントしているレジスタを読みにいっています。 戻り値は捨てているので、まだLet's Splitのほうではなにもできません。ので、オシロスコープで読んで見ておきます。

f:id:klaNath:20171220232601j:plain

ICをブレッドボードに乗っけて、それをICクリップを使って半ば無理矢理に電源と信号を接続しています。このLet's Splitに使用しているPro Microは5V版なので電源電圧も5Vが出ていますが、PCF2127は3.3Vを要求していますので手頃なシリーズレギュレーターで電圧を合わせておきます。

それではファームウェアをビルドし直して書き込み、試してみます。

f:id:klaNath:20171220234205p:plain

これは初期化関数で送信された通信の様子です。問題無く送信されているようです。

f:id:klaNath:20171220233022p:plain

これはキーを押したときに、秒レジスタを読んでいる時の様子です。うまく読めているみたいです。 波形下のI2Cと引かれたラインにあるDATA=B9H~Aがデータの内容です。MSBは秒数データに関係なく1になっていて、あとは4bitごとのBCDフォーマットとすれば良いらしいので39秒を表しているようです。

このデータを読んだ後も、一秒間隔くらいでキーを押すことでデータがカウントアップしていくのが確認できたので、正しくデータは読めているようです。

今後

今回は仕事であまり時間が取れず、ここまでとなってしまいました。

本来ならば、ここからRTCの時刻設定と液晶制御を追加して、Let's Splitに時計機能を追加する予定でした。いつかきっと・・・

思ったよりもQMK Firmwareはいじって遊べるようです。なにか新しいネタを思いついたら試してみたいと思いますし、正直言ってファームウェアの全体像がまだつかめていないので、コードを読んでいこうとも思います。

次の記事は IKeJI さんです。

この記事はSun Type 7 USB Keyboardで書きました。レツプリは真改造されていていますので、もう一台作りたいなあ…