Hi,
I'm trying to communicate with a SD card using the multiple block write command. As RSI_DATA_LGTH is 16bit width, it limits the data size to 65535, but I would like to test 64k/128k/256k and more data length. The idea is to test maximum throughput of the card, targeting 10MBytes/sec as the physical maximum of the Blackfin (RSI max clock is 25MHz).
I'm using a ADSP-BF506F EZ-KIT and have modified the power on self test code:
uint32_t sd_mmc_write_mblocks_dma_64k(uint32_t card_address, void * pSource)
{
uint32_t error = 0;
uint32_t i = 0;
// DMA setup
*pDMA1_CONFIG = 0x0000;
*pDMA1_START_ADDR = pSource;
*pDMA1_X_COUNT = 65536 / 4; // / 4 => 32bit words
*pDMA1_X_MODIFY = 0; // repeat first word because we don't have enough internal RAM on EZ-KIT
*pDMA1_IRQ_STATUS = *pDMA1_IRQ_STATUS & DMA_DONE;
*pDMA1_CONFIG = DMAEN | WDSIZE_32 |DI_EN | SYNC;
error = sd_mmc_send_command(SD_MMC_CMD_WRITE_MULTIPLE_BLOCK, card_address);
// Setup data transfer
*pRSI_DATA_LGTH = 1024; // 2 x 512 bytes
*pRSI_DATA_TIMER = 0xFFFFFFFF; // not handled for now
// data transfer
for(i=0; i<64; i++)
{
// Start data transfer
*pRSI_DATA_CONTROL = 0x99; // 512 bytes block over DMA
// wait for end of transmission
while(!(*pRSI_STATUS & DAT_END));
// clear status flags
*pRSI_STATUSCL = DAT_END | DAT_BLK_END;
}
error = sd_mmc_send_command(SD_MMC_CMD_STOP_TRANSMISSION, 0);
/* ensure DMA has completed */
while((*pDMA1_IRQ_STATUS & DMA_DONE) != DMA_DONE);
*pDMA1_IRQ_STATUS = *pDMA1_IRQ_STATUS & DMA_DONE;
/* wait for the device to become ready */
sd_mmc_get_wait_until_ready();
return error;
}
This function should send 64k (512 bytes * 2 * 64) to the SD card. It doesn't work, the DSP get stuck into the while(!(*pRSI_STATUS & (DAT_END | DAT_BLK_END))); after the first pass (i==1).
If I test the function using the debugger step by step, it works. If a add large delay (for(j=0; j<100000; j++); between each line of the for loop, it also works.
When the DSP doesn't go out from the DAT_END, the status register value is 0, but value should be (DAT_END | DAT_BLK_END) as the RSI_DATA_CONTROL register was written just before.
Any idea?
Thanks,
Vincent