Implementing a SPIM interface to an SD Card

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
timoc_264486
Level 2
Level 2

I have Segger's emFile product running with FreeRTOS on a PSoC 5LP using a dedicate SPI master. I haven't implemented locks because the hardware is not shared and so per Segger locks are not needed.

Hardware layer really only requires two calls be implemented which I have done:

static int _HW_Read(U8 Unit, U8 * pData, int NumBytes)
{

    SD_Card_ClearRxBuffer();
   
    do
    {
        SD_Card_WriteTxData(0xff);              // Write dummy data to clock the SPI slave
       
        while (SD_Card_GetRxBufferSize() == 0); // Wait until receive FIFO is not empty
       
        *pData++ = SD_Card_ReadRxData();          // Read data from buffer
    }
    while (--NumBytes);
 
    return 0;
}


static int _HW_Write(U8 Unit, const U8 * pData, int NumBytes) {
    FS_USE_PARA(Unit);

    int i;
   
    for (i = 0; i < NumBytes; i++)
    {
        {
            SD_Card_WriteTxData((uint8)pData);
        }
    }

    CyDelay(1);
  return 0;
}

This works OK (but slow) if I include the 1ms delay in the write call. If I remove the delay I get read and/or write error depending upon what commend is executed next. I have tried nearly every type of status check in the write, TX_FIFO_DONE (also or'd with SPI_IDLE), SPI_DONE and just about anything I can think of. BTW - the SPIM is configured to 400KHz internal clock with just the 4 byte FIFO. I have also tried larger read and write buffers to no avail.

Any help, even guesses would be appreciated.

0 Likes
1 Solution

You can find more information in the section "6.5.8.1.8 (*pfWrite)()" of the emFile manual.

I think the implementation of Card write expects delay as depicted in this example by Segger:

Example

static void _Write(U8 Unit, const U8 * pData, int NumBytes) {

int i;

U8 Mask;

U8 Data;

for (i = 0; i < NumBytes; i++) {

Data = pData;

Mask = 0x80;

while (Mask) {

if (Data & Mask) {

SPI_SET_DATAOUT();

} else {

SPI_CLR_DATAOUT();

}

SPI_CLR_CLK();

SPI_DELAY();/////////////////////////

SPI_SET_CLK();

SPI_DELAY();//////////////////////////

Mask >>= 1;

}

}

SPI_SET_DATAOUT(); // Default state of data line is high.

}

Please contact Segger for the proper understanding at implementation for Card  write at these links:

emFile related - SEGGER - Forum

Technical Support | SEGGER - The Embedded Experts

View solution in original post

0 Likes
3 Replies
AnkitaS_51
Employee
Employee
100 likes received 50 likes received 25 likes received

Are you using the emfile component provided with PSoC5LP? If possible please share the Creator project.

0 Likes

Hi, thanks for the response. And no, this is not the emFile licensed to Cypress. This is the real product purchased from Segger so unfortunately I cannot post the project.

0 Likes

You can find more information in the section "6.5.8.1.8 (*pfWrite)()" of the emFile manual.

I think the implementation of Card write expects delay as depicted in this example by Segger:

Example

static void _Write(U8 Unit, const U8 * pData, int NumBytes) {

int i;

U8 Mask;

U8 Data;

for (i = 0; i < NumBytes; i++) {

Data = pData;

Mask = 0x80;

while (Mask) {

if (Data & Mask) {

SPI_SET_DATAOUT();

} else {

SPI_CLR_DATAOUT();

}

SPI_CLR_CLK();

SPI_DELAY();/////////////////////////

SPI_SET_CLK();

SPI_DELAY();//////////////////////////

Mask >>= 1;

}

}

SPI_SET_DATAOUT(); // Default state of data line is high.

}

Please contact Segger for the proper understanding at implementation for Card  write at these links:

emFile related - SEGGER - Forum

Technical Support | SEGGER - The Embedded Experts

0 Likes