Seeeduino XIAO (ATSAMD21G18) のGPIO速度

Seeduino XIAO の予約販売をポチッたのは確か1月だったような...でも届いたのは3月に入ってから。ウイルス騒ぎのせいで出荷がかなり遅れたようだ。

Seeeduino XIAO – Arduino 互換ボード – SAMD21 Cortex M0+

16MHz動作のATtiny85はソフトでポートたたくと確か8MHz出たような気がするがATSAMD21G18はどうなんだろうという素朴な疑問があるのでまずはLチカかねてGPIOの速度試験をしてみた。

armのドキュメントによるとレジスタアクセスには2サイクルかかるとあるので48MHz動作のATSAMD21G18なら12MHz出るのかなと思っていたらなぜか6MHzしか出ない。シングルサイクルI/Oポートなら1サイクルとも記載されているが1命令に4サイクルかかっているのはなぜ?誰か知ってる人いる?

ちなみに下記写真の波形がナマってるのは上記写真のようないい加減な配線するとそうなりますよというお手本なのでマネしないように。(笑)

【サンプル・コード】

【サンプル・コードを逆アセンブル】

その後、下記ページの内容からシングルサイクルI/Oポートが0x60000000からマップされてることがわかった。

Cortex®-M0+シングルサイクルIOBUS

再度試してみたらな~んと本当に1サイクルで実行できてしまった。波形は綺麗ではないが確かに24MHz出てる。ということは通常のIOBUSは24MHzで動作してるということなのかな?

【シングルサイクルI/Oポートの例】

ついでにチョー高速なIOBUSライブラリも作ってみた。引数を定数指定することでコンパイラの最適化により高速にアクセス可能となる。
おまけの機能としてArduinoではサポートされていないトグル操作、I/Oピンのディセーブル、出力ドライブ強度の設定も可能だ。出力ドライブ強度は規定だと数mA程度しか流せないので以外に便利かもしれない。
ちなみにピン番号はArduinoのものとは違うので注意してほしい。

【修正履歴】
2020-06-20
内部マクロ定義の変更とそれに伴う修正。

2020-06-03
非ARDUINO環境への対応

2020-05-13
XIAOポート定義にDACポートとコメントを追加

2020-05-12
multiplexing()の仕様変更と、このライブラリで指定するピン番号がわからない人が多そうなのでSeeeduino-XIAO限定でポート定義を追加してみた。

2020-05-09
multiplexing()を追加。

2020-04-30
各レジスタ及びポートのビット位置/値を取得するマクロの追加とそれに伴うコード変更。

2020-04-27
Single Cycle I/O Port からの入力は、古いデータを読まないよう連続サンプリングを有効にする必要があると書かれていたのでその対応をしてみた。

2020-04-25
ライブラリにピン番号を計算してくれるIOBUS_PIN(port,pos)マクロを追加。

【サンプル・スケッチ】

【チョー高速IOBUSライブラリ】