nRF52832での基本設計
それでは、これと同様のことをnRF52832で実現するにはどうしたら良いでしょうか?
Objective Production Specificationの
SPIMのセクションを読んでみます。
まず、先例でやっているような10bitモードのSPIは使えないようです。8bit固定です。
また、 nRF52832ではSPIのクロックも先例のような3MHzという設定はなく、その前後で使えるのは1MHz, 2MHz, 4MHz, 8MHzです。
先ほどのタイミングチャートから、
0codeの場合、Hiを250~550ns, Lowを700~1000ns,
1codeの場合、Hiを700~1000ns, Lowを300ns~600ns
を作る必要があります。さらに、基本周期は1250ns (800kHz)となっています。
実は、これに従った信号を作ろうとすると、結構プログラムが複雑になってしまいます。
例えば、4MHz(250ns単位制御)でやろうとした場合、
0codeにHiが1~2ビット、Lowが3~4ビット、
1codeをHiが3~4ビット、Lowが2ビット、
となり、1ビットの送信に最低5ビットが必要になります。
8MHz(125ns単位制御)でやろうとした場合、
0codeにHiが2~4ビット、Lowが6~8ビット、
1codeをHiが6~8ビット、Lowが3~4ビット、
となり、1ビットの送信に最低9ビットが必要になります。
1バイトは8ビットなので、これではデータの生成が非常に面倒になります。
ただ、
http://aid.her.jp/uratan/led/の記載では
- 432nsec までのパルスは '0' として判別される。 (132nsec のパルスでも '0')
- 536nsec 以上のパルスは '1' として判別される。
- DOUT 出力は判別された論理に従って新規のパルスが出力される。
- その DOUT 出力においては、T0H=330nsec、T1H=660nsec である。
- インターバル 6.7μsec 程度を境に Treset として判別され、 中継処理が中断される。 (しかしながら これは誤点灯になります)
とのこと。
これに従うのであれば、
4MHz(250ns単位制御)でやろうとした場合、
0codeにHiに1ビット、Lowに3ビット、
1codeをHiに3ビット、Lowに1ビット、
とし、1ビットの送信にきりの良い4ビットを割り当てることが出来ます。
もう1つ、22個以上制御するときに限りますが、easyDMAによるSPIMで1度に送信できるのは256バイト(2048ビット)までということに注意が必要です。
WS2812Bの1ビットに4ビットを使うと、1つのLED向けのデータ24ビットはSPIの96ビットとなり、一度に送れるのは21LED分のデータが最大となります。
これ以上のLEDを制御したい場合は、素早く次の伝送を行う必要があります。が、上記の通り6.7μsec以内に伝送が開始されなければなりません。
実は、このタイミングが難しく、SPI伝送とSPI伝送の間に、現在丁度6.2μsecかかっています。最終データの再開ビットがゼロの場合、Lowが3ビット分、つまり750nsec(0.75μsec)がかかってしまい、結果6.95μsecのLowが発生し、中継処理が中断してしまいます。
これを解決するために、最後のデータをLSB側に寄せる必要があります。ただし、SPI伝送直後のMOSIがダラーんと残るので、最後のビットは0にする必要があります。
まとめると、0codeであれば通常0B1000を送るところを0B0010に、1codeであれば0B1110をそのまま送ります。
Labtoolで取得した波形は次のようになります。(今回からプローブ使用。10xで測定。)
7μsec超えているので、苦しいですね。固体によっては、動かないかもしれませんね。だめだな時は、踏み込んで対応することにしましょう。
ドライブ回路
nRF52 DKのVccは3.3V、WS2812BのVccは5Vですので、MOSI信号のレベル変換が必要です。
今回、次の3つを試してみました。
ちなみに、元の波形は次の通り。
MOS FET
2N7000を使って、
こちらの回路を試してみました。
動きましたが、波形はこんな感じです。動くには動きますが、遅延が大きくかなり悲惨ですね.....
TTL (74LS00)
丁度手元にあった74LS00をバッファとして使ってみました。2V以上をHiとみなすので、これでも3.3V系のシグナルを5V系に変換することが出来ます。
バッファは、NANDゲートをNOTとして2つ組み合わせています。新たに準備するのであれば、
こちらを参考に最新のロジックICを用意するのが良いでしょう。
波形は綺麗です。
レベル変換IC(TXB0104)
レベル変換IC TXB0104を使った波形です。製品は
こちら。nRF52側の電圧が低くても安定して動作するので、準備できるのであれば、ここまで試した中では一番よさそうです。ただ、双方向である必要性は無いので、もっと良いソリューションがあると思います。
サンプルプログラム
とりあえず、ここまでの試行錯誤をまとめ、240個のLEDテープを点滅させることに成功したプログラムを
GITHUBに公開しました。といっても、easyDMAで点灯させることが出来ることを確認するだけのプログラムであり、データの自由度など何もない、汚くて恥ずかしいプログラムです。
もう少し使いやすく改良する予定です。
(安心してください(^^♪電波吹いてません)