Nordic Connect SDKでもPPI
直近の記事ではなぜか(?)nRF Connect SDK(以下NCS)ではなくnRF SDKの記事をいくつか書いていました。もちろん理由があって、業務において消費電力を減らす工夫をしなくてはいけなくなり、その中でProgramable Peripheral Interconnect(以下PPI)という機能の存在を知ったからです。正確に言うとPPIという言葉自体はsdk_config.hやサンプルプロジェクトの中で何度も見かけているので言葉そのものは知っていましたが、具体的に何なのかは分かっていませんでしたし、必要ないと思っていたので理解しようともしませんでした。
PPIとは
こんなところで説明するのもなんですが、PPIとはPeripheral Interconnectの名前の通りTWI(I2C)やSPI、タイマーやGPIOなどのPeripheralと呼ばれる機能をダイレクトに接続してコントロールするものです。例えば500msecで割り込みが発生するタイマーとTWIを接続して500msec毎にTWIのコマンドを発行することができます。
なぜ消費電力が下がる?
PPIは前述のとおりPeripheral同士が直接動くのでCPUの介入がありません。通常の処理であれば、タイマー割込みが発生し、CPUがそれを割り込みとしてスタックに積み、順番が回ってきたら現在のスタックポインターの処理を中断して割り込みのスタックポインターに移動するという動きになります。その処理が必要ないので
CPUがスリープしているのであればそのままスリープしている(ので消費電力が下がる)
副次効果としては
CPUがスタックに積むわけではないのでディレイはほぼ0
と言ったメリットが得られます。おお、スゲーじゃん!
といいことづくめのように見えなくもないですが、実際にはそれを考慮したファームウェアの記述にしないといけないので若干めんどくさいです。例えば定期的にTWIを発行するのであれば、それは基本的にI2Cデバイスからのリードなのでコールバックを使用して処理が終わってから値を格納しに行くなどの記述が必要になります。当たり前ですが非同期処理が必須になります。
消費電力を減らす目的でなくても後者の副次効果を目当てに高精度な時間管理が必要な時にも使えます。
サンプル
実は完全体のサンプルが最初から用意されているため、ここで特にソースコードを公開して貼り付ける必要がなかったりします(笑)
またか・・・でもそういう情報があると助かる人も・・・きっといるよね?
NCSフォルダーのzephyr/samples/boards/nrf/nrfxにあります。
もっと詳しくPPIを知りたい
nRF SDKのサンプルですが、こちらの記事をご覧ください。