ncs: I2C

2024/09/09

前回、DevAcademy Fundamental の内容を I2C 以外終わらせた。
I2C はデバイスのありかが見つからなさそうなのでやらないつもりだったが、記事と部品が出てきた(画像がないのは、間違ってGoogleドライブから削除したため)。

hiro99ma blog: [nrf51]SB1602はあっさり動いた

部品はこちらで、SB1602B という名前。

I2C低電圧キャラクタ液晶モジュール(16x2行) - SB1602B - Strawberry

I2C

物理的な線の本数が少なくて済む I2C はそこまで高速さを求められない部品でよく使われている。 RTC、センサー、不揮発メモリの一部などなど。
2本の線はデータとクロック。

1線の通信規格も別にあるが、あれは電圧と電流で使い分けるとかだっけ。 SIMなんかはそうだったと思うが制御したことないのでよくわからない。

SPI は 4線になるのか。
3線シリアル(CSI)という仕様を使ったことがあるのだが、あれは NEC系のチップだっただろうか。

I2C と TWI

Nordic のドキュメントでは I2C と書かずに TWI(Two-Wire Interface)と書かれていて「I2C互換」となっている。
実質 I2C なのだが微妙に仕様が違うのだろうか。 あるいは I2C は Phillips Semiconductors の登録商標です、みたいなことだろうか。

wikipediaによると今はロイヤリティフリーらしい。 では厳密には仕様がちょっと異なるとかか。

zephyerではI2Cだが nrfxではTWIということか。 nrfx は SoftDevice 時代からの名残かもしれないとも思ったが、API名はともかく引数が違う。 nRF5 SDKをベースにしているようなことは書かれているが、私が使っていない API系統があっただけかもしれない。
ただDriver support matrixによると nRF5340 では TWI をサポートしないそうだ。

基本的に Zephyr のドライバーを使い、どうしようもないときは nrfx を使うというやり方が良いということか。

個人的な愚痴

私としては、I2Cデバイスは難しいものだと思っている。

回路図を渡されて抵抗値が書かれているならわかるが、こういう部品は「プルアップ抵抗を付けてください」くらいしか書いていない。 作りたい回路なんて人それぞれだし、I2C は複数デバイスをつなぐことができるのでその数で違ってきそうな気もするから仕方なさそうだ。

仕事ならハード屋さんがいるので頼むのだが、個人でブレッドボードでやっているくらいだと手持ちの抵抗の種類もそんなにないので選択肢が少ないし、そもそも抵抗値の加減がよくわからない。
たしか 4.7kΩくらいを使ってたんじゃなかったか。 大きすぎると波形が鈍って、小さすぎるとそれはそれでダメだった記憶がある。

「ロジアナをつないでも」というのは、信号が取れない立ったか、つなぐと通信がダメになるだったかのどっちかだったと思う。
たしか、入力インピーダンスの都合でロジアナ側に信号が吸い取られる?とかそんな説明をしてもらった気がする。 なので計測するならオシロスコープの方がよかったはず。
そう思ってオシロスコープを購入していたのだが、お仕事が組み込みじゃなくなったのでほとんど使わないままになっている。 もったいない。。。

最後の「アドレス値が 8bit」は八つ当たりというかなんというか。
I2C の仕様としてはアドレス値は 7bit なのだが(10bitもあるらしい)、実際にデータを流すときには 7bit + R/Wのビット で計8bit使うことになる。 なのでデバイスによっては LSB に OR すればよいよう 0 を追加して 8bit にして表記してあることがあるのだ(ちなみに読込の時に1にする)。 悩むのでそういうときは一言書いておいてほしい。

今回の SB1602B の取説はちゃんと 7bit で書かれている。

SB1602B

電源以外で必要なのが SDA/SCL と ~RST だけなので取り付けるのは簡単だ。
~RST も動作するなら VDD に吊っておいてもよいそうだし。

液晶コントローラは ST7032i というものらしい。
幸い制御方法は SB1602B の説明に書かれているので ST7032i の方は読まなくても使うことができる。

ncs と I2C

TF-M

I2C と TF-M の UART はベースアドレスがいくつか共用しているため、I2C を使う場合はCONFIG_TFM_SECURE_UART=nCONFIG_TFM_LOG_LEVEL_SILENCE=yを設定して無効にするそうだ。
TF-M は non-secure と名前が付いているやつだ。 使わないなら無視されるだろうし、I2C を使う場合は機械的に書いておけば良いのかな。

実験

昔つくった、nRF51822 + FeliCa Link + SB1602B でブレッドボードにつなげていた記録が残っていた。

image

私にしては野心的なことに 2つの I2C デバイスをつなげていたようだ。記憶にまったく無いが。

nRF5340 と SB1602B だけをつなげた回路を作り、DevAcademy の Exercise をまねしてプログラムを作った。 プルアップ抵抗は当時と同じく 4.7kΩにした。
初回のi2c_write_dt()-EIO(-5)が返ってきたので、何かダメなのだろう。 エラー値の意味はZephyr Error numbersを参照だ。

せっかくなのでオシロスコープを引っ張り出した。

image

横軸は1メモリで 10usec なので 100kHz。 I2C のスタンダードモードであれば妥当ではあるが、だとしても 1クロック分しか出ていない。
それに SDA の方は立ち下がっていないのでスタートコンディションになっていない。

これはプルアップ抵抗がどうのこうのではないと思う・・・と書いたところで勘違いに気付いた。
「プルアップ抵抗」と自分で書いているにもかかわらず SDA/SCL の接続に抵抗を挟んでいたのだ。プルアップしてない。。

VDD と SDA/SCL をそれぞれ 4.7kΩ の抵抗でつなぐようにするとちゃんと動いてくれた。

image

テストで作ったプログラムは PC に保存しただけにしていたが、積極的に GitHub に上げていこう。

commit

SB1602B はバックライトがないのでちょっと見づらい。

MDBT53ボードを端っこにおいているが、これはアンテナを出した方がよいかと思っただけだ。
しかしこの配置にすると配線が長くなるし、同じ方向に延ばすしかないので線がゴチャゴチャするしでよいことがないな。


Fundamentals 修了

これで DevAcademy nRF Connect SDK Fundamentals は修了だ。
修了証も発行される。

修了証

まあ、全部の科目を完了にしてクイズに正解すれば修了できるのだけどね。
それに基本を軽く抑えたという程度で、仕事で使うにはまだまだ慣れもノウハウも全然足りない。 が、実際の環境で使っていかないと身につかないもんだと思うからよいのだ。