SD writes never complete

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

cross mob
NiBu_1198441
Level 2
Level 2
5 replies posted 5 questions asked First question asked

I'm attempting to implement FatFs on a PSoC 6 (https://github.com/nlbutts/psoc6_fatfs). I've gotten reads working, but when I try to write to the SD card the code spins forever. I started with the PDL documentation. I thought I would try and get polled reads/writes to work. The example they show is slightly wrong. For reads you need to call

Cy_SD_Host_ClearNormalInterruptStatus(SDCARD_HW, CY_SD_HOST_XFER_COMPLETE);

prior to polling for read complete. Otherwise the system thinks the read is complete and returns incorrect data. I then tried writes using the following code. But the code sits in the while loop waiting for the write to complete, which it never does.

DRESULT disk_write (

BYTE drv, /* Physical drive number (0) */

const BYTE *buff, /* Ponter to the data to write */

DWORD sector, /* Start sector number (LBA) */

UINT count /* Number of sectors to write (1..128) */

)

{

if (drv || !count) return RES_PARERR; /* Check parameter */

if (Stat & STA_NOINIT) return RES_NOTRDY; /* Check drive status */

if (Stat & STA_PROTECT) return RES_WRPRT; /* Check write protect */

//if (!(CardType & CT_BLOCK)) sector *= 512; /* LBA ==> BA conversion (byte addressing cards) */

    cy_stc_sd_host_write_read_config_t data;

    cy_en_sd_host_status_t ret;

    data.address = sector;         /* The address to write/read data on the card or eMMC. */

    data.numberOfBlocks = count;  /* The number of blocks to write/read (Single block write/read). */

    data.autoCommand = CY_SD_HOST_AUTO_CMD_NONE;  /* Selects which auto commands are used if any. */

    data.dataTimeout = 12UL;     /* The timeout value for the transfer. */

    data.enReliableWrite = false; /* For EMMC cards enable reliable write. */

    data.enableDma = true;  /* Enable DMA mode. */

    data.data = (uint32_t*)buff;  /* The pointer to data to write. */

    ret = Cy_SD_Host_Write(SDHC1, &data, &_sdHostContext);  /* Write data to the card. */

    if (CY_SD_HOST_SUCCESS == ret)

    {

        while (CY_SD_HOST_XFER_COMPLETE != (Cy_SD_Host_GetNormalInterruptStatus(SDHC1) & CY_SD_HOST_XFER_COMPLETE))

        {

            /* Wait for the data-transaction complete event. */

        }

    }

    else

    {

    return RES_ERROR;

    }

return RES_OK; /* Return result */

}

0 Likes
1 Reply
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Yes, you are right. After a check, a reset must be done using Cy_SD_Host_ClearNormalInterruptStatus(SDCARD_HW, CY_SD_HOST_XFER_COMPLETE). Will update the PDL documentation to include this.

Can you please debug and check where the code is stuck?

You can try implementing a timeout counter to break the while loop if the write fails. Also, you can directlly call the API Cy_SD_Host_GetNormalInterruptStatus(SDHC1) to check what value is being returned.

Couldn't find your design.modus file in Github. Please attach it here.

Let me know your observations.

Regards,

Dheeraj

0 Likes