未だ実装されていない
1年半くらい前にDevZoneで以下のようなやりとりをしました。
非同期I2Cを使いたかったのですが、ソースコードを追いかけていくとどうも実装されていない(少なくともNordicのSoCは非対応)ということが判明しました。
SDKは絶賛開発中だし、まだ実装されていなくてもしょうがないか、そのうち実装されるはずだ……なんて考えてはや1年半、未だ実装されていません。厳密に言うとAPIレベルではすでに実装されていて常に非同期I2C(Callbackあり)で動いており、それをセマフォで制御することにより同期I2Cとして動いています。なので、そこからセマフォの同期制御を止めてコールバック関数の登録があれば呼び出す、みたいなのでいけそうな感じはあるのですが、何も進んでおりません。
なんで僕がソースコード解析しないといけないんだw
本題に行く前に訂正
上記のスレッドでは「I2Cがまともに動いていないんだけど?200kHzってなに?」という質問を投げかけています。最近になってやっとこれの正体が分かりまして、実は内蔵プルアップを使ったI2Cだったのです。元々、内蔵プルアップというのは入力ピンのプルアップ抵抗のために存在しており、非常に弱い電流でよいので100~300kΩが一般的です。この内蔵プルアップがI2Cで使うときにも設定できてしまうため、このような問題が発生したわけです。だって普通のI2Cのプルアップに300kΩなんて絶対使わないでしょ、電流足りなくてなまりまくりますよ。
もっと言うと内蔵プルアップはGPIOを入力ピンとして設定した場合だけ使えるのが一般的で、ルネサスのマイコンはそのようになっています。それがどんな設定でも使えてしまうほうがおかしいわけですよねw
いいわけですw
ということで、外付けのプルアップ抵抗は必須です。頓珍漢な質問をしてすみませんでした……。
これ以外にも頓珍漢な質問結構しておりますw
人はそうやって強くなっていくのさ(適当w)
APIでは未来永劫対応できない(と思う)
先にも書いたように内部処理の深いところでコールバックをすでに使っているので、ユーザーレベルに引っ張り出してくるのはかなり難しいんじゃないかなと思っています。
Nordicもそう思っているらしい(ただし未確認)
先のスレッドの最後の回答が「NRFX TWIMドライバーを直接叩け」でした(笑)。そして、それをサポートするかのように実はサンプルプロジェクトが存在していたりします。tx_rx_non_blockingというプロジェクトですが、プロジェクト名にI2CもTWI[M]も入っていないので知らないと見つけようがないですよね。
はたしていつごろからあったのか……分かりません。
nRF7002で4系統非同期動作
nRF7002(nRF5340)はI2Cを最大4系統持っています。nRF528xxと違ってUARTとペリフェラルが共通なので全部使おうと思うとコンソールのログ出力とかUSB通信とかができなくなってしまいますが、IoTデバイスを扱うには非常に魅力的なペリフェラル数です。
ただし、これを同期通信で動かしてしまうとせっかく4系統ある魅力も半減してしまいます。いくらスレッド処理ができると言っても、スレッドでI2Cをアクセスしている間は他が動けないからです。
ということで、上記のサンプルを使って4系統の非同期動作を実装してみました。
クロック出力動作が完全に終わらない段階で違う系統のクロックが動き始めているので、これはまごうことなき非同期動作ですね。
単に非同期で動いていることを確認するためだけのものなので、すべてのペリフェラルがNACKで終わっています
2024/11/13 追記
ちゃんと実装してみたものです。美しい非同期処理ですね(笑)
CH1がTWIM1のSCL, CH2がTWIM1のSDA, CH3がTWIM0のSCL, CH4がTWIM0のSDAです。
余談:非同期SPIMは実装されている
同じ非同期動作でもSPIMはすでに実装されており、問題なく使えることが確認できています。