NXP JN516X (TWELITE) をプログラミングする(TWELITE CUE/MC3630)

TWELITE CUEを小型無線リモコンとして使えないかなと考えてみた。ボタン電池駆動は消費電力が非常に気になるし1個のアクションだけ実行できれば良いのでボタンSWがあるといいかもと思ったが調べてみるとCUEに内蔵されている加速度センサー(MC3630)はマイクロアンペア未満という超低消費電力で動作するため振ることでボタンSWの代わりになりそうだ。CUEは動きを検出したら無線送信するための製品なので本来の使い方そのものとも言える。

MC36XXシリーズ用のドライバーが製造元のmCube社から公開されているが、MC36XXシリーズの製品毎に微妙に異なる仕様に対応するためなのか基本的な共通機能のみとなっていることに加えて余計なコードが入っているために雑然としていてなんとなく使う気にはならなかった。さらに調べてみると...製品は有名そうなのに独自ドライバーを書いてる人がいない...

モノワイヤレス社のコードには”おまじない”という言葉とともに苦労した様子も伺える...なんだか不吉な予感...あとで的中!(笑)

ドキュメント通りに作ってみると...ピクリともしない。初期化処理が駄目みたいでうんともすんとも言わないのだ。これには複数の原因があったのでまたまた大ハマりしてしまった。最近、ハマることがほんとに多すぎる。(笑)

MC3630は読み書きするレジスタ・アドレスを指定しレジスタ・ビットを操作するタイプのデバイスであるがレジスタ数が多くビット割当てされた機能も結構あったりして対応はそれなりに大変だ。そして、普通の人ならビット操作のためにレジスタを読んでビットをAND/ORして書き戻すというコードを書いてしまうだろう。

だが普通じゃ面白くないので高速化のためにデバイスのレジスタ・マップと同じ構造のバッファ変数によりレジスタ・リードを省略可能にしてみたり、簡略化のためにビットフィールドを使い繁雑なビット操作はコンパイラーにお任せするようにしてみた。

但し、ビットフィールド毎にAND/ORしてしまうので複数ビットをまとめてAND/ORするよりも非効率かつ巨大なコードになりやすく非力なCPUでの使用には注意する必要もある。ビットフィールドの非互換性の理由は知らなかったが知識だけはあったので注意しなきゃなと思いつつもコードが完成する頃にはすっかり忘れてしまっていたのが敗因の一つだ。あとでわかったことではあるがバイト・エンディアンではなくビット・エンディアンなる言葉があるなんて生まれて初めて知ったのだがハマってるときの原因というのは無知或いは正しいと思ってる部分にあることが多く解決するのは本当に難しい。(-_-;)

大ハマりの最大の原因は”おまじない”。”おまじない”と書かれてるドキュメントなど見たこともないが”おまじない”が書かれていないドキュメント通りにしても動かないので”おまじない”は必要なものらしい。

再度、製造元のドライバーのコードを確認してみると...しっかり”おまじない”してるやん! orz

今回は、TWELITE CUEに内蔵されている各周辺チップに対応したボード・クラスも作ってみた。ボード・クラスを使うとLED制御やウォッチドッグ(TPL5010)、磁気センサー(DRV5032FD)、加速度センサー(MC3630)などを簡単に扱えるので便利かも。

※Board::handle()の呼び出しがないと約100秒後にリセットがかかるので注意しよう!
 ↑
※yield()からの呼び出すようにしたので普段は意識しなくても良い。

mc3630.h/mc3630.cppは汎用的に使えるようにしたつもり。JN516xだとvirtualが使えないので苦肉の策でC言語のように関数アドレスを構造体渡ししているがvirtualが使える開発環境なら継承クラス側でvirtual宣言された4個のメソッドをオーバーライド実装すればOKだ。

【サンプル・コード】

【修正履歴】
2022-06-01
前回の修正が正しく動作するには割り込みを排他制御する必要がありその対応をしたとしてもメリットよりもデメリットのほうが大きいと判断し元に戻すことにした。wake割り込みが発生する最短のタイミングはstartSniff()呼び出しから規定レートで166ms以降、最高レートでは770us以降となるので注意してほしい。startSniff()~sleep()の間に余計なコードを入れない限り問題はないはず。

2022-05-29
サンプルの★の間でWake割り込みが発生してしまうと二度と生き返らなくなってしまうので対策を行った。宝くじが当たるよりも確率は低いと思うけど念の為。

【ライブラリ(BLUE/RED共通)】

【関連投稿】
NXP JN516X (TWELITE) をプログラミングする(開発環境の構築)
NXP JN516X (TWELITE) をプログラミングする(メイン・ルーチン)
NXP JN516X (TWELITE) をプログラミングする(TICKTIMER)
NXP JN516X (TWELITE) をプログラミングする(UART)
NXP JN516X (TWELITE) をプログラミングする(SYSTEM)
NXP JN516X (TWELITE) をプログラミングする(GPIO)
NXP JN516X (TWELITE) をプログラミングする(TIMER)
NXP JN516X (TWELITE) をプログラミングする(ALARM)
NXP JN516X (TWELITE) をプログラミングする(WAKETIMER)
NXP JN516X (TWELITE) をプログラミングする(WATCHDOG)
NXP JN516X (TWELITE) をプログラミングする(I2C)
NXP JN516X (TWELITE) をプログラミングする(SPI)
NXP JN516X (TWELITE) をプログラミングする(ADC)
NXP JN516X (TWELITE) をプログラミングする(COMPARATOR)
NXP JN516X (TWELITE) をプログラミングする(CLOCK)
NXP JN516X (TWELITE) をプログラミングする(BROWNOUT)
NXP JN516X (TWELITE) をプログラミングする(PULSCOUNTER)
NXP JN516X (TWELITE) をプログラミングする(INFRARED)
NXP JN516X (TWELITE) をプログラミングする(RANDOM-GENERATOR)
NXP JN516X (TWELITE) をプログラミングする(FLASH)
NXP JN516X (TWELITE) をプログラミングする(EEPROM)
NXP JN516X (TWELITE) をプログラミングする(WPAN)
NXP JN516X (TWELITE) をプログラミングする(Eclipse-CDT+MWSTAGE)
NXP JN516X (TWELITE) をプログラミングする(乗算と除算)
NXP JN516X (TWELITE) をプログラミングする(マルチタスク)
NXP JN516X (TWELITE) をプログラミングする(フラッシュ・プログラマー)
NXP JN516X (TWELITE) をプログラミングする(OTA UPDATE)
NXP JN516X (TWELITE) をプログラミングする(TWELITE CUE/MC3630)
NXP JN516X (TWELITE) をプログラミングする(LED)
NXP JN516X (TWELITE) をプログラミングする(AES)
NXP JN516X (TWELITE) をプログラミングする(Downloads)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください