TG-LPC11U35-501のSPIについて

11 Apr 2016

みなさん今日は。 連続ですみません。 もう1件教えてください。

こちらのページ https://developer.mbed.org/users/tkasa/code/LEDTape_WS2812/wiki/Homepage のプログラムをインポートして、そのままでTG-LPC11U35-501でも使えるように修正しました。

Import program20160411_LEDTape_WS2812

TG-LPC11U35-501に対応


修正後のプログラムはLPC1768では特に問題なく実行できます。 しかし、TG-LPC11U35-501ではうまく動作しません。
コンパイル時にワーニングは出ていますが、動作に影響は無い事を確認しています。

LEDStrip_WS2812.cpp

    if (freq) {
        tape.frequency(freq * 1000);
    } else {
        tape.frequency(8000000);
    }
ここの8000000を800000に変更
 ->コンパイル
 ->実行
 ->8000000に戻す
 ->コンパイル
 ->実行
とやると動作します。

いじっている数値はSPIのクロックの周波数設定だと思いますので、SPI周りの設定なのだとは思うのですが、
たまたま動作する条件を見つけたものの、なぜこのような操作ををすると動くのか理解できません。

どなたか判る方いらしゃいましたら、ご教示いただけますようお願いいたします。

ひろべ
16 Jun 2016

こんにちは。

現象が再現したので、調査してみました。

Publish して頂いたソースコードを読むと、WS2812Bへのデータを作成している部分で、クロックの幅を考慮した定数値があります。
1データ : 0x1F
0データ : 0x0F

SPIのフォーマットは、10-bitなので、それぞれ
1データ : High level = 5 clock, Low level = 5 clock
0データ : High level = 4 clock, Low level = 6 clock

となり、SCLK = 8MHz時の時間はそれぞれ
1データ : High level = 625nsec, Low level = 625nsec
0データ : High level = 500nsec, Low level = 750nsec

となります。この値はWS2812Bのデータシートに記載されている T0H, T1H, T0L, T1L の範囲内になりますが、SCLKの周波数を8MHzから800KHzに変更した場合は、スペック外の値になるため動作しなくなると思われます。

12 Apr 2016

Wataraiさま
Resありがとうございます。

やっぱり状況が思った通りに伝わりませんでした。
周波数の設定を800kHzにすると動かないのは理解していますし、実際動かないのも確認しています。
1度800kHzの設定のプログラムを書き込まないと、8MHzの設定のプログラムを書き込んでも動かないのです。

発生している状況を書き直してみます。これでうまく伝わりますでしょうか。

1) 動かない時
     ・動いている状態があります
     ・プログラムを修正します。この時、周波数の設定は8MHzのままです。
     ・TG-LPC11U35-501にプログラムを書き込みます。
     ・リセットボタンを押してもプログラムは動きません。

2)動く時
     ・動いている状態があります
     ・プログラムを修正します。この時、周波数の設定も800kHzに変えます。
     ・TG-LPC11U35-501にプログラムを書き込みます。
     ・リセットボタンを押してプログラムを動かします。もちろん期待通りには動きません。
     ・プログラムの周波数の設定を8MHzに変えます。
     ・TG-LPC11U35-501にプログラムを書き込みます。
     ・リセットボタンを押してプログラムを動かします。期待通りにうごきます。

以上の通りです。
LPC1768ではこんなまどろっこしい事をしなくても書き換えられるので、TG-LPC11U35-501の時
にどこか書き換えなければ行けないところが抜けているのでは、もしくは私のTG-LPC11U35-501が
異常なのではないかと疑っています。
お手数ですが、再度の検証よろしくお願いします。

ひろべ

12 Apr 2016

ご連絡ありがとうございます。勘違い失礼しました。

SPIからデータ自体が正しく出ているのであれば、リセットシーケンスなどに問題は無いでしょうか? リセットの幅はスペック上、50 usec以上と規定されているようですが、ソースコードではクロック50回分のループが回っているだけのようです。

125 nsec x 50 = 6.26 usec

13 Apr 2016

Wataraiさま
続けてResありがとうございます。

アドバイスありがとうございました。
試しにリセットの部分のループを51回まわすようにしたら、余計な手順を踏まなくても書き換えられるようになりました。(嬉)

また、この件をふまえて出力するデータが0の時のパルス幅データを0x0Fから0x07に変更したところ、時々発生していた白点灯の
誤動作も見られなくなりました。

いままでLPC1768等では問題になっていなかったところをみると、私のトラ技ライタが何か問題点を抱えていて、SPIのMOSI出力
が乱れているのかもしれません。 たとえmbedでも、他のデバイスで動いているからといって移植時の動作検証が省けるというこ
とは無いですね.......残念

てっきりSPIの設定周りかと思い込みドツボにはまり込んでしまっていましたが、おかげ様で解決する事ができました。
本当にありがとうございました。

ひろべ

13 Apr 2016

ご確認ありがとうございます。

Quote:

試しにリセットの部分のループを51回まわすようにしたら、余計な手順を踏まなくても書き換えられるようになりました。(嬉)

スペック上は51回でも足りていないと思うので、400以上の値を設定するのをお勧めします。

Quote:

いままでLPC1768等では問題になっていなかったところをみると、私のトラ技ライタが何か問題点を抱えていて、SPIのMOSI出力 が乱れているのかもしれません。 たとえmbedでも、他のデバイスで動いているからといって移植時の動作検証が省けるというこ とは無いですね.......残念

ここからは想像なのですが、デバイスによって初期値や初期化シーケンスは異なりますので、LPC1768の場合は50回のlow level 出力ループ期間よりも前のタイミングでMOSI出力がlow levelになっていて、たまたまLEDのリセットシーケンスが正常に行われていたのかもしれません。

移植時の動作検証に関してはおっしゃる通りで、残念ながらデバイス依存の問題で期待した動作にならないこともゼロではありません。このあたりの問題を少しで解消するために、Componentsライブラリにはtested platformという項目を追加し、「このライブラリで動作確認されいているプラットフォームのリスト」が見えるようになっています。今後、Componentsに登録されているライブラリをご使用される場合は、ご参照ください。

15 Apr 2016

Wataraiさま
コメントとアドバイスありがとうございます。

お恥ずかしい話ですが、このプログラムの動作を把握しきれておりません。
スキをみて、職場のオシロで波形見ながらデバッグ続けることにします。

Componentsライブラリにtested platformという項目があること、気がついていませんでした。
次の機会には、忘れずに参考にします。

いろいろとありがとうございました。

ひろべ