PSoC6でFatFs

やりたいこと

PSoC6でSPI接続でSDカードにアクセスしたい。

経緯

PSoC3 や PSoC5 には emFile というコンポーネントが用意されています。emFile は、SDカードのSPIモードI/FとFATファイルシステムカプセル化した便利なコンポーネントです。しかし、PSoC6 ではまだ emFile がサポートされていません。

f:id:licheng:20200720211750p:plain

そこで、おなじみの ChaNさんのFatFs を使うことにしました。

移植

FatFs の PSoC への移植として、下記のものがあります。少し古いバージョン(R0.11a, 2015年)の FatFs をベースにしていますがが、とりあえずこれを使うことにします。

github.com

ただし、これは PSoC4 と 5 には対応していますが PSoC6 には対応していません。そこで、低レベルの移植部分のソースである sdcard.c を PSoC6 用に次のように修正します。

条件コンパイルのためのマクロの定義
#include <project.h>
//#include <cytypes.h>
#define CY_PSOC6    1
SS(スレーブセレクト)を操作するマクロの定義
#if (CY_PSOC6) 
#define mmSPI_SS_Write(value)     Cy_GPIO_Write(SPI_SS_PORT, SPI_SS_NUM, value)
#else
#define mmSPI_SS_Write(value)     SPI_SS_Write(value)
#endif

SPIマスターを操作するマクロの定義

#if (CY_PSOC4)
    (中略)
#endif 
#if (CY_PSOC5LP) 
    (中略)
#endif 
#if (CY_PSOC6) 
    #define mmSPI_SpiUartClearTxBuffer        CONCATENATE(SPI_NAME, _ClearTxFifo)
    #define mmSPI_SpiUartClearRxBuffer        CONCATENATE(SPI_NAME, _ClearRxFifo)
    #define mmSPI_SpiUartPutArray(a, b)       CONCATENATE(SPI_NAME, _WriteArrayBlocking(a, b))
    #define mmSPI_SpiUartWriteTxData(value)   CONCATENATE(SPI_NAME, _Write(value))
    #define mmSPI_SpiUartReadRxData           CONCATENATE(SPI_NAME, _Read)
    #define mmSPI_IsTxComplete                CONCATENATE(SPI_NAME, _IsTxComplete)
#endif

バイトデータ送信関数の定義

static void xmit_mmc(const BYTE* buff, UINT bc)
{
#if (CY_PSOC4)
    (中略)
#endif 
#if (CY_PSOC5LP) 
    (中略)
#endif 
#if (CY_PSOC6)
    mmSPI_SpiUartClearTxBuffer();
    mmSPI_SpiUartClearRxBuffer();
    mmSPI_SpiUartPutArray((void *)buff, bc);
    while(!mmSPI_IsTxComplete());
#endif
}

バイトデータ受信関数の定義

static void rcvr_mmc(BYTE *buff, UINT bc)
{
#if (CY_PSOC4)
    (中略)
#endif 
#if (CY_PSOC5LP) 
    (中略)
#endif 
#if (CY_PSOC6)
    mmSPI_SpiUartClearTxBuffer();
    mmSPI_SpiUartClearRxBuffer();
    do{
        mmSPI_SpiUartWriteTxData(0xFF);
        while(!mmSPI_IsTxComplete());
        CyDelayUs(M_DELAY_US); // <*> adjust, why?
        *buff++ = (BYTE)mmSPI_SpiUartReadRxData();
    } while (--bc);
#endif
}

使い方

  • SPI(SCB)コンポーネントの名前を「SPI」とする。
    • 「Mode」は「Master」
    • 「SCLK Mode」は「CPHA=0, CPOL=0」
    • 「Data Rate (kbps)」は 400
    • 「RX Data Width」「TX Data Width」は 8
    • 「Number of SS」は 0
  • SSはGPIOを用いる。Digital Outputコンポーネントの名前を「SPI_SS」とする。