SDカードインターフェース
SDカードインターフェースのプログラムを作ってい行きます。
マイクロチップ・ライブラリ(MLA)
マイクロチップ社が提供するライブラリを使います。USBをはじめ、TCPIP、ファイル、グラフィックスなどいくつかのライブラリからなります。最新版は、バージョンv2018-11-26になりますが、作りかけのものがv2017_03_06でしたので完成するまではこれを使います。
プログラム構成
参考にした本が古いため、当時のライブラリv2011-06-02を使っています。基本的な考えは同じですが、ライブラリのファイル名、関数名などもだいぶ変わっていますので、まずは、MPLABのプロジェクトとして構成するところからです。
ライブラリのフォルダ構成は、次のようになっています。ここで使うのはframeworkですが、appsフォルダにサンプルプログラムがありますので、これも参考になります。ライブラリには、一応、マニュアル(docフォルダ内)が付いていますが、分量も多いので全体像が中々把握しずらいです。
今回、使うのはfileioライブラリになりますが、SDカードとのインターフェースがSPIを使うので、driverライブラリの中のspiライブラリも使うことになります。
具体的には以下となります。
- fileio/src/fileio.c
- fieio/inc/fileio.c
- fileio/drivers/sd_spi/sd_spi.c
- fileio/drivers/sd_spi/sd_spi.h
- driver/spi/src/drv_spi_16bit.c
- driver/spi/drv_spi.h
これらは、プロジェクトに追加するときは、コピーは不要です。(中身は一切変更しないで使うということ)
ユーザアプリに合わせて変更するところは、ユーザ作成関数とコンフィグファイルですべて指定します。上記について使うコンフィグファイルは以下の通り。テンプレートはライブラリにあり、コピーして使います。ファイルの中のコメントを見れば大体わかります。
- fileio_config.h (fileio/config/fileio_config_template.hから作成)
- sd_spi_config.h (fileio/drivers/sd_spi/sd_spi_config_template.hから作成)
- drc_spi_config.h (driver/spi/config/drv_spi_config_template.hから作成)
これに、ユーザが用意する関数があります。
- FILEIO_SD_CSSet SPIのチップセレクト(CS)ピンを制御
- FILEIO_SD_CDGet SDカードの装着有無を検出
- FILEIO_SD_WPGet SDカードのライトプロテクト(WP)を検出
- FILEIO_SD_PinConfigure SDカード用のI/Oの初期化。SPIの各ピン割り当てなど。
これで、大体そろいます。
ライブラリの全体構成は次の様になっていて、使用するファイルは上に書いたようになりますが、まだまだ重要なことがあります。。
コンフィグ(Config)
汎用性の高いライブラリなので、File IOレイヤーがどのPhysicalレイヤーを使うかを指定する必要がありあます。これを、関数ポインタの構造体として定義してあげる必要があり、ここらへんのやり方がマニュアルにはあまり親切に書かれていない感じです。ユーザ作成関数の指定も同じやりかたです。
具体的な方法としては、appsフォルダのサンプルを参照した試行錯誤しました。appsのfileioサンプル(apps/fileio/sd_card_demo/firmware/scr)には、main.c、system.cのファイルにまとめれています。
Physicalレイヤーの指定(main.cにあり)
const FILEIO_DRIVE_CONFIG gSdDrive =
{
(FILEIO_DRIVER_IOInitialize)FILEIO_SD_IOInitialize, // Function to initialize the I/O pins used by the driver.
(FILEIO_DRIVER_MediaDetect)FILEIO_SD_MediaDetect, // Function to detect that the media is inserted.
(FILEIO_DRIVER_MediaInitialize)FILEIO_SD_MediaInitialize, // Function to initialize the media.
(FILEIO_DRIVER_MediaDeinitialize)FILEIO_SD_MediaDeinitialize, // Function to de-initialize the media.
(FILEIO_DRIVER_SectorRead)FILEIO_SD_SectorRead, // Function to read a sector from the media.
(FILEIO_DRIVER_SectorWrite)FILEIO_SD_SectorWrite, // Function to write a sector to the media.
(FILEIO_DRIVER_WriteProtectStateGet)FILEIO_SD_WriteProtectStateGet, // Function to determine if the media is write-protected.
};
ユーザ定義関数の指定(system.cにあり)
FILEIO_SD_DRIVE_CONFIG sdCardMediaParameters =
{
1, // Use SPI module 2
USER_SdSpiSetCs, // User-specified function to set/clear the Chip Select pin.
USER_SdSpiGetCd, // User-specified function to get the status of the Card Detect pin.
USER_SdSpiGetWp, // User-specified function to get the status of the Write Protect pin.
USER_SdSpiConfigurePins // User-specified function to configure the pins' TRIS bits.
};
これで、やっとライブラリの使用ができます。
ライブラリ使用方法
使う関数と順番は以下のようになります。InitializeとMountを忘れずにやってください。あとは、普通のファイル処理関数のように使えばいいです。(サンプルが、apps/fileioにあります)
FILEIO_OBJECT file;
FILEIO_Initialize();
FILEIO_DriveMount('A', &gSdDrive, &sdCardMediaParameters);
↑ここで2つの構造体を指定(登録)します。
FILEIO_Open(&file,"LOGDATA.TXT",FILEIO_OPEN_WRITE );
FILEIO_Write (sampleData, 1, 9, &file);
FILEIO_Close (&file);
FILEIO_DriveUnmount ('A');
なんとか、PICでSDカードを使える様になりました。PICで書いたSDカードをパソコンで中身を確認し、確かに書かれているのを見た時は、何か感激してしまいました。
終わりに
ライブラリが汎用的過ぎて、構造体で関数群を指定(Config)するところで、かなりハマりましたが、1回やってしまえば他も同じような構造だと思うので楽になります。
また、ライブラリ中のどのファイルを使えばいいのかが手探り状態であったのと、例によりファイルへのパスをMPLAB上で全て指定しないとBuildエラーが取れなくて苦労しました。プロジェクトに登録しているのに、更にパスを指定しないといけないとは何とかならないんでしょうか。(単に私のやり方がまずいだけかもしれませんが。誰か、分かっているひとがいたら教えてください)
つぎは、USBをつなげていきます。