STM32F4シリーズを使ってみる3 -FatFsと下部レイヤ(SDIO・MMC)ドライバたちの実装-


来たぞー!
…って来たのはもう2週間以上前ですけど…
144PinのSTM32F4も手に入ったのでSTM32F2の時と同じく中華生基板に組んで
みました。STM32F2とF4はほとんど同じです。特にコードは上位互換があるので
回路を完全に合わせるとF2のコードがそのまま使用できちゃったりします。
まあでもさっさとCortex-M4F用にしてしまった方が良いでしょう。



↑ということでいつものChan氏のプログラムを走らせて
 みました。

特筆すべきはF2系では何とか動くものの安定していなかった48MHz動作の
SDIOがF4系では非常に安定してることで、SDカードとさらに大容量/高速な
データのやり取りができるようになっています。ただし高速なクロックに耐え
うるSDカードの選択は必須で、Class10のカードを必ず選んでください。
最近出回ってるUHS-1の奴は逆に駄目なものもありましたので幾つか購入して
試してみてください。あと当たり前のことですが、配線の引き回しももの
すごく重要なので注意してください。

↑でたらめ書いてました。SDカードの仕様上通常モード(NomalSpeed)は
 25MHzが上限値でSTM32F2/F4ではUSBとの共用を考えると24MHzが現実的に
 安定して動かせられるクロック上限となります。
 お詫びして訂正しましま。

んでもって前回さらっとお見せしたSTM32F4 Discoveryの方のいつものですが、
ちゃんとした実装にあたり、周辺にぶら下がってる回路の影響でどのように
構成すべきか悩みました。なぜならば…
SDIO : SDIO_CLKがCS43L22のSDINとかぶってるから使えない
FSMC : 肝心のnRDがCS43L22のResetに、nWRがUSBの過電流検出に被ってて(ry
    その他諸々のペリフェラルが被ってて(ry
SPI3 : CS43L22がI2S3として使ってて(ryついでにI2C1も
SPI2 : MP45DT02がI2S2とし(ry
SPI1 : LIS302DLがSPI1(ry


まぢでひっぺがしたろかと思いましたが先に書いた通りSTM32F407ZGTが
手に入ったのでSTM32+SDIO+FATFS+FSMCの構成はこっちに実装してDiscoveryの
方は既存のペリフェラルと何とか共存する道を選んでみました。
てわけで妥協したのが以下のSTM32+MMC+FATFS+SPI-LCDのプラン…。

SDカード : SPI1(LIS302DL(SPI通信)と共用)
TFT液晶 : SPI2(MP45DT02(I2S通信)と排他)
      ※STM32F4DiscoveryではSPITFT液晶のみ対応
その他  : CS43L22は丸々残す!
      UARTはUART2(TX:PA2 RX:PA3)
SDカードとSPITFT液晶はもちろんDMA化してあります。

TFT液晶がシリアルしか使えない上にMOSIがI2Sの入力とかぶってしまうので
MP45DT02とは排他になっていますが、必要な人はGPIOによるソフトSPI
(超遅いですが)で逃げてもよいと思います。
私のLCD表示ドライバは潰しが効くようにかなり柔軟にデバイス依存の部分を
作り込んであります。またSTM32F1系ではペリフェラルはひとかたまり単位で
しかリマップできない構成でしたが、F2系以降はピン単位で柔軟なリマップが
できるようになったのでみなさんもデータシートとにらめっこして工夫して
みてください。

とりあえずSTM32F4 Discovery上でこの構成でハード改造を行わずに音楽
再生はかろうじてできるでしょうか?
音再生関係の作り込みはこれからなのでがんばってみます!




てわけでいつものコードでSDカードの読み出し速度比較を行ってみました。
使用したカードはClass10が策定される前に販売されたATP製4GBClass6の
microSD
です。



STM32F4Discovery上で組んだFatFsは先に書いた通りの構成ですが、SPI1は42MHz
まで叩きだせるので読み出し速度もめっちゃ速いです!(注:SDカードは選びます)
音楽再生程度ならもう十分な早さですね♥今回の実装に際してMMCのSTM32用
ドライバも移植性をかなり高めた作りにしてみました(もちろんDMA化も)!

ちなみにDMA化に際する注意事項ですが前回も言及していますが、CCM領域を
DMAの読み書き先として利用することは一切できません!
STM32F4系でCCM
領域を高速なスタック領域として使用する前提でF2系から移植を考えた場合、
既存のプログラムがauto変数をDMAの読み書き先として定義されていると
特定困難な不具合に悩まされる可能性がありますのでよく吟味してください。


お次は中華生基板(STM32F407ZGT6)で組んだSDIOの読み出しスピードです。
上にも書いていますが、F2系ではコケまくって全く安定してなかった48MHzの
クロックでも安定してアクセスができるようになり、20MByte/Sec以上の
すさまじいスピードで読み出しが可能になりました♥ちなみにこの
基板上ではFSMCもDMA化してます!



バグ出しもほとんど終わり、最低限のドキュメントもそろいましたので
STM32F4 Discoveryと中華基板対応のいつものコードを公開します。
makeファイル内の定義でSTM32F4Discoveryと中華生基板のビルドを切り替える
ことができます。その他細かい部分のノウハウは口で説明するよりソース見て
もらった方が分かると思います。
だから誰か早くSTM32F4Discoverymp3プレーヤー作ってくだち!!
20121220追:
STM32F4Discovery用でMP3再生機能追加しました!




あ、お伝え忘れてました。今回の公開に当たってSTM32F2系STM32F107、そして
最近この検索ワードでアクセスが急増中のSTM32VLDiscovery向けのFatFs+液晶表示
プログラムも大幅に更新しておきました。
んでもってOpenOCD用Flash書き込みCFG群もSTM32F4xx用を追加しておきましたよぅ

Comments

開発環境、使わせてもらってます。
大助かりで、ありがと。

  • yees
  • 2011/11/28 4:01 PM

こんにちは。いつも巡回させてもらっております。
ところで、OLIMEX STM32-P207 PCB環境下、SDのFindSCRにて
SDIO_FLAG_RXDAVLフラグが立たないストール現象で悩んでおります。
接続は、SDIO仕様に接続変更しております。
STM32F4系のSDIOでは問題無く動作しているのでしょうか。
とりあえず、F4チップに交換予定ですが、STM32F1xx(STM32-LCD等)では問題無かったので残念です。
海外ブログにも似たような話があるようで、早くBug Fixedされる事を祈ります。

  • また〜り
  • 2012/04/19 10:36 AM

また〜りです。 失礼しました。
問題フラグは、SDIO_FLAG_DBCKENDの間違いでした。

  • また〜り
  • 2012/04/19 4:47 PM

また〜り様、こんばんは。ねむいです。


私の環境ではF1/F2/F4ともSDIO/MMCの両方で全く問題なくFatFsが
使用できています。ともかく問題の切り分けから行いましょうか。
以下の項目を順番に再度確認してください。

*ハード
1.OLIMEXのボードのSDカードインターフェースの結線はSDIOに
 正しく繋がっているか
2.SDIOの各信号線のプルアップはちゃんと行われているか
3.SDカードに給電されている3.3Vラインがふらついていないか

*ソフト
4.HSEの値は実装されている外付けの水晶の周波数と同一になっているか
5.SDIOのクロックが25MHzを越えてしまっていないか
6.SDIOの割り込み処理を忘れていないか
7.転送にDMAを使用している場合、転送待ちのルーチン挿入を忘れていないか

"6."と"7."はSTM32F1系からF2/F4系に移植した時によく引っかかるポイント
です。Readの例を取るとSD_ReadMultiBlocks()のあとに
Status = SD_WaitReadOperation();
while(SD_GetStatus() != SD_TRANSFER_OK);
の2行の処理が必要で、これを故意に削除するとまた〜りさんのおっしゃる
現象がこちらのSTM32F2の環境でも再現します。


私の公開しているF2/F4向けのサンプルはもちろんこれらの処理を入れて
いますが、それをもとにした上で現象が発生しているのならばまだ別の
個所に問題があるとおもわれます。

ねむい様 ご丁寧なアドバイスありがとうございます。
また〜りです。

その後、STM32F407チップ交換で動作は正常になりました。
症状は、FindSCR()のDPSMがWait_Rから即座に完了してしまい、
DCTRLに書き込んだ途端にDBCKENDが立ってしまうという現象でした。
F207特有のノイズ脆弱性による誤動作とも思われますが、明確には判断できませんでした。

以上 御礼まで。

  • また〜り
  • 2012/04/21 4:53 PM

ねむいさんソースでお勉強中のひとです、こんにちは。

手前環境で_delay_us()が
2倍のスピードで動くという現象にぶつかりまして。
これは環境の差かなとお勉強コミで
色々調べてみたのですが、
どうもSTの提供するsystem_stm32f4xx.c設定用な
STM32F4xx_Clock_Configuration_V1.0.1.xlsでは、
TIM2/3/4/5/6/7/12/13/14に提供されるクロックが
APB1の2倍と表記されています。
実は肝心なマニュアルで
それらしい記述を見つけられていないのですが、
とりあえずのご報告までに。

  • ななし
  • 2012/04/25 3:45 PM

ねむいです。こんばんは。

すみません、これはおもいくそ私の見落としですorz.

STM32のタイマのカウントに用いられるクロックは、APBのクロック
プリスケーラの値によりハードウエア的に固定化されます。これは
F1,F2,F4シリーズ共通の仕様となっています。

STM32F4のマニュアル(RM0090)の86ページの中段に記述があります。
> The timer clock frequencies are automatically set by hardware.
> There are two cases:
> 1. If the APB prescaler is 1, the timer clock frequencies
> are set to the same frequency as that of the APB domain
> to which the timers are connected.
> 2. Otherwise, they are set to twice (×2) the frequency of the
> APB domain to which the timers are connected.

正直いいますと_delay_us()は私自身も全く使用してなかったので元々
バギーな状態で作り投げていたF1用の物をさらにF2/F4に何も考えないで
移植して放置してましたorz

というわけで、この際なのでどのクロックの組み合わせが来ても正し
くカウント出来るようにsystick.c内のTIM5の設定部分を新たに組み直
してF2/F4向けのプログラムの更新を行いました。
お手数ですが再度ダウンロードして確かめて見てくださいね〜

おおお、お早い回答&更新ありがとうございます。
何というか、恐縮です。

STM32はTIM5->CNTにアトミックにアクセスできるんですね。
32bitにフルアクセスできるって素敵。

  • ななし
  • 2012/04/26 1:02 AM

Post a Comment








Go to top of page