This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SSI DMA to microSD Card (LM4F232H5QD)

Hi all,

I am having a problem getting DMA to work with the microSD Card. The DMA section of code works when tested between memory to memory transfers.

For writing to the SD Card, I am using Chan's FatFs and modifying his function, xmit_datablock() below by calling another function SHEER_DMATransfer(). However after the transfer is done, there is an error in the response received. I believe there is no change in the protocol as I am only editing the transfer of the data block.

I tried putting in the line "while(ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSIRX));" to check if all the data has been received but it just loops endlessly indicating the transfer process has not ended?

Does anyone have any suggestions? Thanks.

Regards,

Tian Hao

// Chan's FatFs code to transmit a data block.

static
BOOL xmit_datablock (
    const BYTE *buff,    /* 512 byte data block to be transmitted */
    BYTE token            /* Data/Stop token */
)
{
    BYTE resp, wc;

    if (wait_ready() != 0xFF) return FALSE;

    xmit_spi(token);                    /* Xmit data token */
    if (token != 0xFD) {    /* Is data token */

        if (DMAEnable)
        {
            SHEER_DMATransfer(buff);
        }
        else
        {
            wc = 0;
            do {                            /* Xmit the 512 byte data block to MMC */
                xmit_spi(*buff++);
                xmit_spi(*buff++);
            } while (--wc);
        }

        xmit_spi(0xFF);                    /* CRC (Dummy) */
        xmit_spi(0xFF);
        resp = rcvr_spi();                /* Reveive data response */
        if ((resp & 0x1F) != 0x05)        /* If not accepted, return with error */
        return FALSE;
    }

    return TRUE;
}

// Transmit block of data using DMA.
static void
SHEER_DMATransfer(const BYTE *buff)
{
    // Read any residual data from the SSI port.  This makes sure the receive
    // FIFOs are empty, so we don't read any unwanted junk.
    static unsigned long dummy_data;
    while(ROM_SSIDataGetNonBlocking(SDC_SSI_BASE, &dummy_data));

    // Enable SSI DMA.
    ROM_SSIDMAEnable(SDC_SSI_BASE, SSI_DMA_RX | SSI_DMA_TX);

    // Disable TX Channel for configuration.
    ROM_uDMAChannelDisable(UDMA_CHANNEL_SSITX);

    // Disable RX Channel for configuration.
    ROM_uDMAChannelDisable(UDMA_CHANNEL_SSIRX);

    // Configure RX control structure.
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSIRX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void*)(SDC_SSI_BASE + SSI_O_DR),
                               (void*)dummy_receive_buffer,
                               sizeof(dummy_receive_buffer));

    // Configure TX control structure.
    ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SSITX | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *) buff,
                               (void *)(SDC_SSI_BASE + SSI_O_DR),
                               sizeof(buff));

    // Enable Channel to start transferring.
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSITX);

    // Enable Channel to start receiving.
    ROM_uDMAChannelEnable(UDMA_CHANNEL_SSIRX);

    // Loop until transfer is complete.
    //while(ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSIRX)){} // Stuck here.

    // Disable the SSI DMA.
    ROM_SSIDMADisable(SDC_SSI_BASE, SSI_DMA_RX | SSI_DMA_TX);

    return;
}