AnsweredAssumed Answered

ADSP BF 548 SD card Write cycle Timing issue

Question asked by amar26121993 on Feb 20, 2018
Latest reply on Mar 9, 2018 by Jithul_Janardhanan

Hi everybody

Iam using ADSP BF 548 Evaluation board,iam using SD card in my project,i used MULTIPLE BLOCK WRITE option for write, but its taking 400-500millisec to write 1KB data ,my block size is 512, that delay is because iam waiting for DATA_BLK_END to happen and iam waiting in while loop.below is code snippet,can anybody suggest me if any other command has to be sent or any configuration is missing,

 

how much time does  " asm("nop;"); " instruction to execute ?

unsigned long SD_TX_SRC_BUF[256];//Transmit buffer

//------------------------------------------------------------------------------------------------------------------------------------------------

void Init_DMA(unsigned long *buf_addr, unsigned short config_value)
{
*pDMA22_CONFIG =0;
// give the SDH control of the DMA channel
// SDH and NFC share DMA channel 22
*pDMAC1_PERIMUX = 0x1;

*pDMA22_START_ADDR = buf_addr;
*pDMA22_X_COUNT = 256;
*pDMA22_X_MODIFY = 4;
*pDMA22_CONFIG = config_value;//word size 32bit , DMA CH EN, SYNC (Work Unit Transitions), DI_EN bit

ssync();

}

//------------------------------------------------------------------------------------------------------------------------------------------------

void SD_TransmitData(unsigned long SD_address)
{
   unsigned long i=0;
   *pDMA22_CONFIG = 0x0;
   ssync();
   Init_DMA(SD_TX_SRC_BUF, 0x00a9); //setup DMA

   TX_Block(SD_address);
}

//------------------------------------------------------------------------------------------------------------------------------------------------

int TX_Block(void)
{
// set blk len to 512(SET_BLOCKLEN)
   SendCommand( &SD_CmdTable[SD_CMD16], 0 );

// send write command(WRITE_MULTIPLE_BLOCK)
   SendCommand( &SD_CmdTable[SD_CMD25], SD_WRITE_ADDRESS );

// tx 1024 bytes
   *pSDH_DATA_LGTH = 1024;
   ssync();

// set the timer
   *pSDH_DATA_TIMER = 0xFFFFFFFF;
   ssync();

// 2^9 = 512 block length, enable write transfer
   *pSDH_DATA_CTL = 0x99; //use DMA
   ssync();

// wait until the data has been sent
  while( !(*pSDH_STATUS & DAT_END) )
   {
      asm("nop;");
    }

for(k=0;k<1024;k++);//delay before sending stop transmission command

SendCommand_TXRX( &SD_CmdTable[SD_CMD12], 0 , 0x00000000 );  //MULTIPLE BLOCK COMMAND

*pDMA22_IRQ_STATUS |= 0x1;// clear the DMA DONE BIT

// clear the status bits
*pSDH_STATUS_CLR = DAT_END_STAT | DAT_BLK_END;

// stop transfer
*pSDH_DATA_CTL = 0x0;
ssync();

return 1;
}

//------------------------------------------------------------------------------------------------------------------------------------------------

int SendCommand_TXRX( SD_CMD *pSD_Cmd, bool bGetStatusReg, unsigned long Argument)
{
unsigned long ulStatusPoll = 0,ulResponse = 0;
int timeout = 0;

// need to poll on either Response end
// or CMD sent depending on whether we
// are waiting for a response or not
   if( pSD_Cmd->CmdResponse & CMD_RSP )
      ulStatusPoll = CMD_RESP_END;
   else
      ulStatusPoll = CMD_SENT;


// OR in the RCA if it is required in the argument
   if( pSD_Cmd->UseRCA )
   {
         // clear out the old RCA in case we
         // are doing the test more than 1 time
            pSD_Cmd->CmdArg &= 0xFFFF;
            pSD_Cmd->CmdArg |= g_ulCardRCA;
}

// set the argument
   *pSDH_ARGUMENT = Argument;
   ssync();

// set the command, command response and enable it
   *pSDH_COMMAND = pSD_Cmd->CmdID | pSD_Cmd->CmdResponse | CMD_E;
   ssync();

// poll to make sure command was sent and
// a response was received if expected
   while( (!(*pSDH_STATUS & ulStatusPoll)) && (timeout < TIMEOUT_VAL) )
   {
      timeout++;
      asm("nop;");
     }

// clear the Resp end or CMD sent bit
   *pSDH_STATUS_CLR |= ulStatusPoll;

// if ACMD41, the CRC will fail so we need to clear it
   if( (pSD_Cmd->CmdID & 0x29) && (*pSDH_STATUS & CMD_CRC_FAIL) )
   {
      *pSDH_STATUS_CLR = CMD_CRC_FAIL_STAT;
   }

// clear the timeout status bit on a timeout
   if( timeout >= TIMEOUT_VAL )
      *pSDH_STATUS_CLR = CMD_TIMEOUT_STAT;

     if( bGetStatusReg )
      {
            SendCommand( &SD_CmdTable[SD_CMD13], 0 );
      }

      return 1;
}

 

 

Best regards

AMAR TR

Software engineer 

SLN technologies.

Outcomes