2025年4月7日月曜日

STM32 SPIってhangupしやすくね?

STM32ポエムです.

別電源のCPU同士をSPIで結んで通信させたい.つまりいつ起動するか、いつ消え失せるか判らないCPU同士のSPI通信だ.レートは200kbit/secぐらいでいい.諸般の事情でUSBは使わない.

だけど、SPIってhangupしやすいというか、通信経路が寸断されるとリカバリがうまくいかない気がする.

今日はその試験をやった.
毎秒のloopで、SPI masterが数BYTE送信し、別CPUのSPI slaveが読む.
2つのCPUにブシブシresetかけると、化けるわ、通信が途切れるわでどうにもならない.
やっぱSPIってこんな感じだよね.

NSSがassertしたら初手からやり直してくれよと思うんだけど、一度同期がズレるとresetしない限り復帰しない.ライブラリ次第だろうが、なんだかなー

STM32のサイトを徘徊すると、CRCなどでエラー検出してHAL_SPI_Init()からやりなおしなされ、と書かれていたりする.しかしそんな事はしたくない.

SPIは厄介なので諦めよう.

シンプルにUARTで通信できないか?
UARTの最大bit rateはどのくらいか?
→UARTの回路としては10Mbpsぐらいまで可能らしい(伝送線による劣化はさておく)

というわけでUARTで通信するわ.
logic直結でもいいけど、、、RS485でも使うかね.transceiver ICを探してみよう.
→秋月で5MbpsのIC売ってるな   これとか

ーーーー
翌日
UARTで1Mbpsで伝送実験やってるところ.ポコポコbit errorする.
原因は、CPU個体の内蔵RC発振器の周波数偏差だと思われる.ASCIIキャラクタを送受信する実験なのだが、ランダムエラーではなくて、明らかに周期性がある.加えて、単一CPUでloopbackするとこのerrorは出なくなる.RC発振器の周波数偏差を測定したところ0.05%だった.たった0.05%で馬脚とはシブい.UARTの調歩同期回路ダサくね? ref. manualによれば周波数偏差数%までOKなはず.なにかがおかしい.ちなUART clk=120MHzで1Mbpsさせるのは問題ない.なおUSARTにはしたくない事情.
ともあれUSBのようにPLLでclock再生する上位構成に比べるとUARTの調歩同期の限界だ.
CPUの発振器をXTALに変更すれば治るかもしれないが、信頼性はいまいち.
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmTTTTTtuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnTTTTTTvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>TTTTDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|} !"#$%&'()*+,-./

かしこ

18 件のコメント:

  1. murasaki
    SPIは使ったこと無いですが、I2Cみたいなものなんですかね。伝送線にクロックをのせるのはよくないのかも。受け側でミッシングクロックを検出して状態をリセットするとかしないとすぐハングしそう。
    結局クロックをそれぞれで持つのがスピードは上がらないけどハングはしづらいシステムになっていそうです。

    返信削除
    返信
    1. I2Cよりは上位っぽい雰囲気が漂います.
      1st clockで反応がないとhandshake的に待ち続けるとかそんな雰囲気を感じます、挙動から
      お堅いんだよなぁ

      削除
    2. 「I2C」のほうが「SPI」よりも「上位」では?
      ※SPIには、「ハンドシェーク」という概念が無いような?
      「I2C」には、一応ある。(余談ですが、「I2S」にも、「ハンドシェーク」という概念はないです。SPIに近い。)

      削除
    3. I2Cは400kbpsかそこらで進歩を止めちゃったみたい
      SPIは4パラとか8パラとかわけわからんく増やしてアゲアゲ

      任天堂switch2がSD expressとかいう8bit幅みたいなSD規格を採用するそうです マイナー企画ですが、普及に拍車がかかるんでしょか?

      削除
    4. I2Sは投げっぱなし 超投げっぱなし

      削除
  2. SPIはこの間使いました。
    4線コントロールなのに、CSとビットの関係が途中で変更できなかったのでCSをソフトコントロールにして逃げました。
    EEPROMへのリードライトだけでしたが、一度制御できたら不安定な動きはなかったです。

    返信削除
    返信
    1. ふつーに使うぶんにはちゃんとうごきます
      CS(NSS)をソフト制御にする場面はありますね

      削除
  3. SPI は、おそらく、
    ・ボード内での通信
    しか想定してないから、そんなもんだと思います。
    (「切れる」ことを想定していない。同期をとるのは「電源投入時」ダケで、あとは「条件変更」しない。とか。)
    ※そういう意味では、「UART」は、一応、
    ・外部との通信
    を、考慮してる(対ホストとの通信とか)から、やっぱり、そっち使ったほうが良いような気がします。欲を言えば、
    ・RS485(アドレスが付けられるので、N対N の通信も出来る。ただし、ドライバの値段が高い。)
    とかのほうが、より良い選択だと思います。

    返信削除
    返信
    1. いま、UARTで接続して1Mbps実験やってるところで、ポコポコbit errorしてます もちっと頑張ってくれそうなもんだがなぁ なんだかなー

      削除
    2. しかしSPIみたくfreezeはしにくいUARTくん

      削除
    3. 「RS485(RS422)」だと、「平衡駆動」なので、それ自体は、
      ・2Mbps ~
      は、余裕で行けたはず。(ノイズにも強いです)
      ※なので「ビット落ち」は、「ソフト的な問題」な、気がします。
      マシンパワーの限界か、割り込み処理の作りが悪い。

      削除
    4. いまのところ割り込みはしてない基礎実験です

      削除
  4. >CPUの発振器をXTALに変更すれば治る
    と思います。
    ※逆に「CPU個体の内蔵RC発振器」で、数Mbps いけるほうがスゴイです。

    返信削除
    返信
    1. 意外と内蔵RC OSCがgoodなSTM32です
      USBぐらい平気で動かせてしまうくらい

      でも今般の使い方だとキツいみたいよ

      削除
  5. これ地味にスゴイ
    https://www.youtube.com/watch?v=sXwDrcd1t-E
    This ESP32 Antenna Array Can See WiFi
    ※一番安い ESP32 モジュールなんて、AliExpress で「ワンコイン」(500円)で、買えちゃうし。
    まさに「Wifiレーダー」が、作れますね。

    返信削除
    返信
    1. どうもこれ開発したのって、
      ・University of Stuttgart
      と言う、大学?の研究室っぽい。Made in Germany ですね。

      削除
    2. サイトはココらしい
      https://espargos.net

      削除
    3. 位相で位置検出してるんですよね
      よくそんな時間精度で抽出できるもんだわ

      削除