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.
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;
}