2018年8月15日水曜日

STM32H743 SPI の DMA 受信できず

STM32H743 で USB MSC の storage として SPI flash rom を使用する為, SPI の送受信の code を書いていた. 例によって CubeMX で生成される code を使用せずに自前で driver を作成していた.

とりあえず PIO access で送受信できる様にし PC から drive として見える所まで持っていった. 使用頻度は少ないので PIO access でもいいが, data 転送だけの為に CPU resource を使うのももったいないので DMA  access に変更した. しかし, 送信だけを DMA, 受信だけを DMA にした場合は, 問題なく転送できる. しかし, 送受信両方 DMA にすると転送ができない.
SPI の転送残量 (SPIx->SR & CTSIZE)DMA の転送残量 (DMAx->NDTR)  を確認すると SPI 受信時 DMA 残量が SPI 残量より速く減算されており, 見るからに受信したより多く転送されている. SPI の受信信号が正しく DMA の転送 request に接続されていないかと, code を色々見たが
特に問題がなさそう (試しに他の request にすると, 全く転送されてない).
もしやと思い errata を見てみると, DMA 受信は, request が出っぱなしで正しく転送できないと書いてある!!!

 
対策として hardware reset を掛けるのが唯一の方法らしい. この "hardware reset" が CPU全体の reset なのか, SPI module だけなのか良くわからない. ただ, CPU reset はありえないので, RCC の RST を試してみた. Cの code 上 bit を立てて, 寝かせてを連続に行なった.
まぁ, とりあえず全 register が clear されているみたいな感じなので, 該当 SPI の reset はかかっていそう. とりあえず initialize と受信 request の設定を行なってみた.  が, やはり ng, 今度は SPIx->CR1 の MASTER bit が立たない. とにかくやたら MASTER を or する様にしたがそれでも立たない.
 とりあえずあきらめて, 送信は PIO, 受信は DMA として運用する.

現状 simplex RX/TX で実装しているので, Full Duplex で転送してみてどうなるかを検討してみようと思う. ただ, 使用頻度がそれほどないと, 他の SPI module は data 量も少なく送信だけなので, このままかもしれない.

愚痴: この SPI の 送受信 clock 生成の divider って 2の累乗しかできない... すげー仕様

2018年8月5日日曜日

STM32H743 USB の SOF 信号が 2回発生する

STM32H743 にて USB AUDIO 2.0 の実装を行っているが, そこで使用する Clock 周波数の feedback 用に SOF timing 信号を TIMx の Input Caputre 入力に入れ, 信号の立ち上がり事にAudio clock の count 値を latch し前回からの差分で kHz 単位の周波数を計算しようとしている.
現在は TIM5 経由で SOF timing を取り出しているが, 他の用途で32bit counter が必要となった. 32bit counter は TIM2, 5 の 2つ ***だけ*** で, TIM2 はすでに Audio clock 周波数の計測用に使用済で, TIM5 しか空いていない. TIM5 経由でなく, やはり SOF 端子そのものから SOF timing 信号を取りだしたい.

しかし, chip から出力される SOF timing 信号が SOF 毎に 2本立っており使えない状態にあった. その原因を調べ対策を行なった.

問題点: SOF 信号 USB 上の SOF packet 毎に 2 本  pulse が出力
                                         上が USB 信号,  下が SOF 出力端子の信号
                                         前側が偽信号,  後ろ側が本来の信号

環境:
             Ubuntu 17.10
             NUCLEO-H743ZI
             とある target board (NUCLEO-H743ZI を daughter board として使用)
             arm-none-eabi-gcc 5.4.1 20160919
             CubeMX 4.25.0
             CubeMX 4.25.0 で吐かれる HAL + 独自 driver

期待値: SOF packet 毎に 1 回  pulse を出力

行った事:
   とりあえず, ずーっとそういう bug と思っていたが, 念の為 CubeMX で USB と SOF timing 信号出力だけの source を作成し, USB33DEN 対策を入れたものを NUCLEO に焼いた. なんと問題く 1 本しかない!!!
   もしやと思い CRS の実装を行ない target に焼いた所問題なく 1 本なった.

結論:
  とりあえず USB としてだけ使うのであれば, 実力で通信ができるが, SOF 信号の取り出しなど細かい事をすると, CRS を使用しないと問題が発生してしまう.  CubeMX の code そのままであれば問題はなかったが, あまり使用しないとする方針としているので, 大切な一歩となった


余談 (ぐち):
TIMx はなんであんなに細か仕様なのか, すべて TIM2 の様に 32bit の仕様にできないのか.