Catalystize!

コーヒー美味しい

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

気が向いたら追記する。

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

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

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で書きました。レツプリは真改造されていていますので、もう一台作りたいなあ…