« LPCXpresso LPC1769にMARY拡張基板を乗せる | トップページ | LPCXpresso LPC1769でFatFsを動かす - DMA編 »

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再起動で復旧させることがあったのですが、このあたりがもうちょっと安定すると文句なしです。


参考資料

« LPCXpresso LPC1769にMARY拡張基板を乗せる | トップページ | LPCXpresso LPC1769でFatFsを動かす - DMA編 »

NXP-ARM」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ