2024年なのでXMOSを試食
試食ボード
評価ボードがやや大袈裟だったので、XU316-1024-QF60B-C32と必要最低限のパーツのみを実装した試食ボードをJLCPCBで製造。KiCadのプロジェクト一式はここ。 https://scrapbox.io/files/65c1e94142c2a200242196da.jpg
IC周辺回路については外部電源が3つ(0.9V、1.8V、3.3V)必要な点以外は特に
TileやIOの考え方を理解せず勢いで作ったボードなので、オンボードのスイッチとLEDの配線をジャンパーで変更した。もう少し色々触ってから、rev.Bとして修正する予定(リポジトリのデータは修正反映済み)。
ツール類のインストール
ソースのビルドやプログラムの実行等に必要なツールは以下の通り。
Git
CMake
QuickstartをなぞるだけならXTC Toolsを入れればOK。但し、I2SやUSBなど各種ライブラリを使おうとするとXCommon CMakeを導入しておかないと色々とメンドクサイ。 デバッガーの入手
悲しいことにSegger J-Linkが使えない。そのため、自前で作ったボードの開発を進めるにはXMOS純正のXTAG 4 Debug Adapterが必須。必要ならハーフピッチ20ピンのフラットケーブルもどっかで調達しておく。 デバッガーと試食ボードの接続
XTAG 4表面のXSYS2と書かれたJ4コネクタを使うのがベストっぽいが、裏面J3コネクタ(ピンヘッダ未実装)を使うと必要最低限の接続で実機デバッグが可能。
table:connection
XTAG4 試食ボード
1: TCK ---> 4: TCK
2: GND ---> 8: GND
3: TMS ---> 6: TMS
4: TDSRC ---> 3: TDI
5: VREF_JTAG ---> 1: 1V8
6: TDSNK ---> 5: TDO
デバッガーとボードが正しく接続出来ていて、XU316が動いていれば
code:xrun
xrun -l
Available XMOS Devices
----------------------
ID Name Adapter ID Devices
-- ---- ---------- -------
という感じで表示される。XU316が動いていなかったり、XTAG4とボードとの接続が間違っていたりすると、DevicesがNoneと表示される。
XNファイルのコピー
Windowsの場合、XTC ToolsはC:\Program Files (x86)\XMOS\XTC\15.2.1にインストールされる。この中のtargetsの中に、本来であれば試食ボードに採用したXU316-1024-QF60B-C32があるはずだが、無い・・・(XU316-1024-QF60A-C32やXU316-1024-FQ60B-C24はあるのに)。
仕方が無いので、あるものを参考に作ったのがコレ。これをC:\Program Files (x86)\XMOS\XTC\15.2.1\targets以下にコピペしておくと、xccでのコンパイル時に-target=XU316-1024-QF60B-C32とオプションで指定できるようになる。 XCommon CMakeのセットアップ
大したことではないが、リポジトリにREADMEが無く、「え?どしたらいいのさ?」となったので備忘録的として残しておく。
流れとしては適当なところにクローンして、そこをXMOS_CMAKE_PATHとして環境変数に加える。
code:xcommon_cmake
Windowsの場合(ユーザー環境変数に加える)
SET XMOS_CMAKE_PATH=C:\Users\hoge\xcommon_cmake
macOS/Linuxの場合
export XMOS_CMAKE_PATH=/home/hoge/xcommon_cmake
CMakeLists.txtの書き方などはdoc以下を参照。 試食ボードのリポジトリにもhello worldとかLチカとかexample的なのを加えていく予定。評価ボードのリポジトリにあるexampleが最初に触るにはちょいカロリー高めだったので、初歩から徐々に進めたかったのよね。 ビルドと実機動作までの流れ
code:xmake
cd C4NDY_XMOS/xC/app_hello_world
cmake -G "Unix Makefiles" -B build // *1 後述
cd build
xmake
xrun --io ../bin/hello_world.xe
hello worldするだけだったり、Lチカするだけならライブラリのお世話になる必要が無いので
code:xcc
xcc -target=XU316-1024-QF60B-C32 -g main.xc
xrun --io a.xe
とするだけだが、ソースが増えたり、XMOSのライブラリを使うようになると、インクルードやら何やらを自分でコンパイルオプションで指定するのは辛すぎるので、CMakeLists.txtを用意してxmakeする。
GitHubへのssh接続
XCommon CMakeを導入すると、XMOSのリポジトリから必要なライブラリ(lib_から始まるリポジトリ)を引っ張ってくれる。このときにgithubにssh接続するので、公開鍵を事前に登録しておく。パスフレーズを設定していると、上記の*1のところで、正しいパスフレーズを入力しても接続に失敗した(深追いしてないので原因不明)ため、パスフレーズ無しで鍵を作り直し、再登録した。
TileとIOの繋がり
試食ボードで採用したXU316-1024-QF60B-C32には2つのxCoreタイルがあり、それぞれ8コアで計16コアとなっている。一つのタイルのなかにコア以外にIOやスケジューラー、メモリなどが入っている。ボードを設計した段階でこの点をきちんと理解出来ていなかったので、「tile0でX1Dxxのpinが使えない」と1日悩んでしまった・・・。tile0から使えるIOはX0で始まるpin、tile1から使えるIOはX1で始まるpinとなっている。
https://scrapbox.io/files/65c1df96ad2b980024d0a32f.png
IOの考え方
上記のTileとIOもハマったが、それに加えてデータシートのIOのFunctionも実際に動かすまで理解出来なかった。一般的なマイコンだとGPIOは1ピンごとに入出力の方向やプルアップ/ダウンなど設定できるが、XMOSの場合、そこが自分の経験上、特殊と感じ理解するのに時間がかかった。
https://scrapbox.io/files/65c1e19aa862290024013c5c.png
Functionの1L0、1M0など、頭の数字が1だと1bitなので、単独のピンとして扱えるが、4E2や8D0だと4bitの第2bit、8bitの第0bit
という扱い。なので、1Xとなっていないピンは4Xなら4つのIOまとめて、8Xなら8つのIOまとめてでしかIOの設定や利用が出来ない。4Xで2ピン出力、2ピン入力としたくても出来ない。4XのピンでI2Cすると、2ピン余るが、これらは何も出来ない無駄なピンと化す・・・。
これには大分面食らったが、XMOSは汎用的なマイコンではなくアプリケーション・プロセッサということらしい。LチカやボタンはサブマイコンやIOエキスパンダーとか使えという無言の圧がすごい。「A/D無いなー残念」と思っていたが、XMOSからしたら、「それはオレの仕事では無い!」ということ。はい、すいませんでした。
C/C++で書くか、xCで書くか
ボード作った時は「C/C++で書けるらしいし、まぁここら辺は良くある組み込み的な感じだろ」っと油断していたら、xCなる言語でした、ごめんなさい。
とはいえ、C/C++で書き切ることも出来る。ありがたいことにここにxCとCのコードの比較もあり、どうするかは開発者次第かなという印象。個人的には、xCで書く方が可読性も良いと思った。たぶん、実装の規模が大きくなってくると、ハードに近い低レイヤーな部分はxCで書いて、オーディオのエフェクト処理の関数とか上のレイヤーはC/C++で書くという棲み分けになるんだろうなと思う。 24/02/07 追記
オンボードのQSPI Flashへの書き込みとブート
試食ボードに実装したQSPI Flashは評価ボードと同じRenesusのAT25FF321Aにした(ハマりポイントを減らすため)。AT25FF321AとのやりとりはXTC Toolsにあるxflashというコマンドで行う事が出来るので、まずはxflashで基本的なやりとり(Manufacturer IDを取得するなど)をしてみる。 xflashを使うにはXNファイルにいくつか追加する必要があったため、試食ボード用のXNを新たに作成。XU316-1024-QF60B-C32.xnとC4NDY-XMOS.xnを比較すれば分かるが、QSPIに使うポートの指定と、外部フラッシュからブートしますよーっていうのを追記してあげる。
まずは、XU316とAT25FF321Aが通信出来ているか確認するためにManufacturer IDとStatus Register2を取得してみる。
code:xflash_read
xflash --id 0 --target C4NDY-XMOS --spi-command 0x9f 4
Response to SPI command 0x9f on tile0: 0x1f, 0x47, 0x08, 0x01. xflash --id 0 --target C4NDY-XMOS --spi-command 0x35 1
Response to SPI command 0x35 on tile0: 0x00. データシート通りの値が取得出来た。
次に、先ほど読んだStatus Register2の設定を書き換えてみる。
code:xflash_write
xflash --id 0 --target C4NDY-XMOS --spi-command 0x06 // Write Enable(06h)
Executed to SPI command 0x06 on tile0. xflash --id 0 --target C4NDY-XMOS --spi-command 0x31 0 0x01
Executed SPI command 0x31 on tile0. xflash --id 0 --target C4NDY-XMOS --spi-command 0x35 1
Response to SPI command 0x35 on tile0: 0x01. Status Register2への書き込みも出来ているようなので、この流れでプログラムの書き込みをやってみる。
書き込むプログラムはLチカのExampleを一部修正したこちら。 code:xflash_xe
cd C4NDY_XMOS/xC/app_boot_from_flash
cmake -G "Unix Makefiles" -B build
cd build
xmake
xflash --id 0 ..\bin\boot_from_flash.xe
Site 0 write 0x00000000. Verify failed for page 0x00000000, offset 0x0000 (read 0x00, expected 0x02).
Error: F03013 Failed to run : 00CFE74C.
はい、失敗。