LPCXpresso LPC1769でFatFsを動かす
前回に引き続き、LPCXpresso + MARY-XBを使って、micro SDカードとFatFsを使えるようにしました。Low level I/Oの部分は、Interfacing ARM controllers with Memory-Cardsの実装をベースにしました。
ソースの入手と変更点
ソースコードは冒頭のリンクから、ChaN's FAT-code with interface for NXP LPC17xx (LPC1766, LPC1768 and others)をたどってダウンロードします。
このソースはOlimex LPC1766-STKがターゲットになっておりSSP1を使っていますが、今回micro SDカードをSSP0に接続しているため、Low level I/OのSSP定義部分だけを変更すれば簡単に動作しそうです。Low level I/OにCMSIS Peripheral Libraryを使っておりダウンロードしたzipにも入っているのですが、バージョンがv1.0とずいぶん古いです。人様の成果をそのまま使うのも何なので、この部分だけ最新のv3.0を使うことにしました(ついでに、Low level I/O codeの学習も兼ねて)。
v3.0ではオリジナルコードで使っている旧APIが削除されたりしており、部分的に書き換えが発生しました。以下変更箇所の概要です。
- comm.c(コンソール出力用のUARTドライバ):
割り込みハンドラー内でライブラリが提供しているUART0_StdIntHandler()を呼び出して、割り込み要因毎の処理(送信やら受信)はUART_SetupCbs()関数を使ってCallback関数を登録する方法になっていますが、最新のCMSISライブラリではUART_SetupCbs()関数が削除されています。そのため、割り込みハンドラー内で割り込み要因別の処理を書く形にしました - spi_sd_lpc17xx.c(SPIの制御とLow Level I/Oを受け持つ部分):
使用するSSPポートの変更(SSP1→ SSP0)に加えて、SSPの初期化関連でLibraryの差し替えに伴う変更がありました。SDカードの初期化とその後のファイルI/OでSPIクロックを変えるために、オリジナルはSSP_SetClock()関数を呼んでいますが、v3.0ではpublicな関数として定義されていいません(名前も変わっている)。そのため、SSP_Init()を呼ぶ形で対応。SSP_Init()を呼ぶとSSPのEnable bitがクリアされてしまうため、SSP_Cmd(LPC_SSP0, ENABLE)を再度呼ぶ必要があります。
変更を行った箇所を含むファイル一式は以下です。
プロジェクトのビルド
LPC1769_FatFS.zipをダウンロードして、workspaceにインポートを行います。CMSISライブラリは含んでいないため個別に用意して下さい。最新のCMSISは、このリンクからLPC17xx CMSIS-Compliant Standard Peripheral Firmware Driver Libraryをダウンロードします。
最新版はCore Libraryがv2.01になっているため、LPCXpresso IDEに別のCMSIS Libraryを作っていたのですが、新規プロジェクトを作るとデフォルトの参照先がIDE組み込みのv1.30になってしまい毎回変更が面倒です。そのため、workspace\CMSISv1p30_LPC17xxにPeripheral Library v3.0をコピーします。
- system_LPC17xx.c → IDE添付版の方が版数が進んでいるため、IDE添付版を使用
- LPC1700CMSIS\Drivers\includeフォルダ配下のファイル一式 → workspace\CMSISv1p30_LPC17xx\inc
- LPC1700CMSIS\Drivers\sourceフォルダ配下のファイル一式 → workspace\CMSISv1p30_LPC17xx\src
動作確認
対話式のコマンドシェルから操作を行って、ディスクのマウント→ ファイルの書き込み → 読み出しの試験を行いました。SPIのクロックは30MHzにしています → Peripheral clock (pclk)の1/2
動作確認時のログは以下の通りです。
Hello from the ChaN FatFs Demo on LPC1700 Version 0.0.2, Martin Thomas 7/2010 xprintf is working CPU Clock: 120MHz Peripheral Clock: 60MHz SPI Clock: 30MHz FatFs module test monitor for LPC17xx/SSP LFN Enabled, Code page: 1252 >di 0 rc=0 >fi 0 rc=0 FR_OK >fs FAT type = FAT32 Bytes/Cluster = 4096 Number of FATs = 2 Root DIR entries = 0 Sectors/FAT = 3744 Number of clusters = 479214 FAT start (lba) = 841 DIR start (lba,clustor) = 2 Data start (lba) = 8329 ...0 files, 0 bytes. 0 folders. 1916856 KB total disk space. 1916852 KB available. > >fo 10 test1.txt rc=0 FR_OK > >fw 10000000 30 10000000 bytes written with 866 kB/sec. >fw 10000000 31 10000000 bytes written with 471 kB/sec. >fw 10000000 32 10000000 bytes written with 535 kB/sec. >fw 10000000 33 10000000 bytes written with 478 kB/sec. >fw 10000000 34 10000000 bytes written with 606 kB/sec. > >fc rc=0 FR_OK >fl ----A 2010/07/15 11:59 50000000 test1.txt 1 File(s), 50000000 bytes total 0 Dir(s), 1912852480 bytes free > >fo 1 test1.txt rc=0 FR_OK > >fr 10000000 10000000 bytes read with 2369 kB/sec. >fr 10000000 10000000 bytes read with 1581 kB/sec. >fr 10000000 10000000 bytes read with 1655 kB/sec. >fr 10000000 10000000 bytes read with 1657 kB/sec. >fr 1 >fc rc=0 FR_OK >fo 1 test1.txt rc=0 FR_OK > >fr 30000000 30000000 bytes read with 2371 kB/sec.
- 34行目で10MBの文字(文字コード30)を書き込み → 転送レート866KB/sec
- 36行目以降で、10MB毎に追加書き込みを行うと転送レートが増減します
- 55行目で、10MBの読み出しを実施 → 転送レート2369KB/sec
- 57行目以降で、10MB毎に追加読み出しを行うと、書き込み同様に転送レートが低下
- 64行目でファイルを一旦クローズして新規に読み出しを行うと元通りの転送レートになります
おわりに
転送はFIFOモードでDMAは使っていません。DMAのコードも作りこまれているのですが、"does not work yet"のコメントが入っていたりしてまだ動かないようです。コンパイラオプションでDMAを有効にできますが、割り込みハンドラーが旧CMSIS Library v1.0をベースにしているためそのままでは動きません。DMAの有効化は今後の課題です。
追記:DMAハンドラーを最新CMSISにあわせて修正したらDMA版も動作してくれました。DMA版は未完成という訳ではなく、メモリ上のデータをSSP_TxポートからSDカードに転送する際に、現状はSSP_Rxポートで受信したデータをダミーのバッファーに格納しているのですがこれを読み飛ばす処理がまだできていないようです。(メモリーリードに加えてライトが発生するため性能に影響があると思われます)
DMAを使わないFIFO転送ですが、転送レートはそこそこ出ていると思います。
追記:DMA版はダミーデータの読み書きを行うせいか、FIFO版より若干転送性能が落ちました。
今回の移植は低レベル処理が主体だったので、SWD(JTAG)デバッグに助けられました。SPIクロック変更のためにSSP_Init()を呼ぶとSSPのEnable bitがクリアされる問題は、当初SPIが動かないように見えていたのですが原因が分からず、SSP0CR1レジスタの値を見ながらトレースして原因判明するなどデバッガが活躍してくれました。時々エミュレーターが起動できなくなってWindows再起動で復旧させることがあったのですが、このあたりがもうちょっと安定すると文句なしです。
参考資料
- FatFsをARIES(STM32F103)で試してみる - Under Power 研究所
- Interfacing ARM controllers with Memory-Cards
« LPCXpresso LPC1769にMARY拡張基板を乗せる | トップページ | LPCXpresso LPC1769でFatFsを動かす - DMA編 »
「NXP-ARM」カテゴリの記事
- LPCXpresso IDEでのC++コードサイズ肥大化の対策(2011.10.15)
- XBee APIモードライブラリのLPCXpressoへの移植(2011.10.09)
- LPCXpresso LPC1769でFree RTOSを使う(2011.07.27)
- LPCXpresso LPC1769でFatFsを動かす–USB Host編(2011.07.19)
- LPCXpresso LPC1769でFatFsを動かす - DMA編(2011.05.14)
この記事へのコメントは終了しました。
コメント