cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO dma not working

pedro23
Senior
 
1 ACCEPTED SOLUTION

Accepted Solutions
pedro23
Senior

Ok then problem was the buffer that i was using, its address was 0x10000400 instead of a 0x200xxxxx address

View solution in original post

5 REPLIES 5
pedro23
Senior

With DMA it hangs on SD_WaitReadOperation(); With polling it is ok. Btw, any speed adventage polling vs dma?

 void NVIC_Configuration_SD(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
 
   // Configure the NVIC Preemption Priority Bits
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
 	// SDIO Interrupt ENABLE
   NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   // DMA2 STREAMx Interrupt ENABLE
   NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
   NVIC_Init(&NVIC_InitStructure);
}
 
void main(void)
{
 
System_Setup();
  
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
 
SD_Init();
NVIC_Configuration_SD();
int Status;
uint16_t Error;
for(int i=0;i<125;i++)
{
  
  Debugprintf("Sector: %d",i);
  Status = SD_ReadBlock ( (uint8_t *) Scr, i<<9, 512);
  Status = SD_WaitReadOperation();
  while(SD_GetStatus() != SD_TRANSFER_OK);
  Debugprintf("   RD Status: %d",Status);
  Error=0;
  for(int j=0;j<512;j++)
      if(((uint8_t *) Scr)[i]!=(i+1))
         Error++;
   if(Error)
     {
      Debugprintf("   RD Error: %d",Error);
      memset((uint8_t *) Scr,i+1,512);
      do 
         {
          Status=SD_WriteBlock ( (uint8_t *) Scr, i<<9 , 512);
          Status = SD_WaitWriteOperation();
          while(SD_GetStatus() != SD_TRANSFER_OK);
          Debugprintf("   WR Status: %d",Status);
         }while(Status);
     } 
    else 
      Debugprintf("   NO ERROR");              
}
while(1)
  IWDG_ReloadCounter();

pedro23
Senior

Adding more information it calls SDIO_IRQHandler but it is not calling SD_SDIO_DMA_IRQHANDLER interrupt

void SDIO_IRQHandler(void)
{
	SD_ProcessIRQ();
}
 
void SD_SDIO_DMA_IRQHANDLER(void)
{
	SD_ProcessDMAIRQ();
}

What part?

Double check IRQ Handler name and linkage via .MAP file and inspection of vector table.

Inspect peripheral registers for DMA, SDIO and RCC in debugger.

Review DMA unit/channel settings and initialization

Check if SDIO IRQ firing for transfer actually completing

Advantage of DMA is that it isn't affected by interrupt loading, and less affected by bus loading against LTDC traffic.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pedro23
Senior

I have been checking and all seems ok

Yes, SDIO IRQ fires with error SD_RX_OVERRUN when reading, than then it hangs on SD_WaitReadOperation here:

while(((SDIO->STA & SDIO_FLAG_RXACT)) && (timeout > 0))
  {
    timeout--;
  }
 

pedro23
Senior

Ok then problem was the buffer that i was using, its address was 0x10000400 instead of a 0x200xxxxx address