AnsweredAssumed Answered

RSI/SD card multiple block help needed

Question asked by mx12 on Aug 17, 2012
Latest reply on Aug 27, 2012 by Nabeel



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_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);



   /* wait for the device to become 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?