Hello there,
I am trying to get some bytes received in SCI using DMA (FreeRTOS application), and I am getting STRANGE results. I only get ONE interrupt and then the code goes to some _dabort section and some self-test routines.
I pasted some parts of the code, which is really simple. I think I am setting things up properly but missing something. It also looks like I should do something inside the ISR (which I don't exactly know what it is, clearing some bits somewhere?).
void dmaSciConfigTXCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize,g_dmaCTRL* ctrl_packet) { ctrl_packet->SADD = sadd; /* source address */ ctrl_packet->DADD = dadd; /* destination address */ ctrl_packet->CHCTRL = 0; /* channel control */ ctrl_packet->FRCNT = dsize; /* frame count */ ctrl_packet->ELCNT = 1; /* element count */ ctrl_packet->ELDOFFSET = 0; /* element destination offset */ ctrl_packet->ELSOFFSET = 0; /* element destination offset */ ctrl_packet->FRDOFFSET = 0; /* frame destination offset */ ctrl_packet->FRSOFFSET = 0; /* frame destination offset */ ctrl_packet->PORTASGN = 4; /* port b */ ctrl_packet->RDSIZE = ACCESS_8_BIT; /* read size */ ctrl_packet->WRSIZE = ACCESS_8_BIT; /* write size */ ctrl_packet->TTYPE = FRAME_TRANSFER ; /* transfer type */ ctrl_packet->ADDMODERD = ADDR_INC1; /* address mode read */ ctrl_packet->ADDMODEWR = ADDR_FIXED; /* address mode write */ ctrl_packet->AUTOINIT = AUTOINIT_OFF; /* autoinit */ } void dmaSciConfigRXCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize,g_dmaCTRL* ctrl_packet) { ctrl_packet->SADD = sadd; /* source address */ ctrl_packet->DADD = dadd; /* destination address */ ctrl_packet->CHCTRL = 0; /* channel control */ ctrl_packet->FRCNT = dsize; /* frame count */ ctrl_packet->ELCNT = 1; /* element count */ ctrl_packet->ELDOFFSET = 0; /* element destination offset */ ctrl_packet->ELSOFFSET = 0; /* element destination offset */ ctrl_packet->FRDOFFSET = 0; /* frame destination offset */ ctrl_packet->FRSOFFSET = 0; /* frame destination offset */ ctrl_packet->PORTASGN = 4; /* port b */ ctrl_packet->RDSIZE = ACCESS_8_BIT; /* read size */ ctrl_packet->WRSIZE = ACCESS_8_BIT; /* write size */ ctrl_packet->TTYPE = FRAME_TRANSFER ; /* transfer type */ ctrl_packet->ADDMODERD = ADDR_FIXED; /* address mode read */ ctrl_packet->ADDMODEWR = ADDR_INC1; /* address mode write */ ctrl_packet->AUTOINIT = AUTOINIT_OFF; /* autoinit */ } void dmaSciInit(void){ dmaEnable(); dmaReqAssign(DMA_CH0,31U); // Assign DMA request channel 0 dmaEnableInterrupt(DMA_CH0,BTC); // Enable interrupt of block complete dmaSciConfigTXCtrlPacket((uint32_t)&DMA_SCI_TX_DATA,((uint32)&(sciREG->TD))+3U, 10,&g_dmaCTRLPKT_TX); // Configure DMA control packet (big endian device!) dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT_TX); // Set DMA control packet dmaReqAssign(DMA_CH1,30U); // Assign DMA request channel 1 dmaEnableInterrupt(DMA_CH1,BTC); // Enable interrupt of block complete dmaSciConfigRXCtrlPacket(((uint32)&(sciREG->RD))+3U,(uint32_t)&DMA_SCI_RX_DATA, 10,&g_dmaCTRLPKT_RX); // Configure DMA control packet (big endian device!) dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT_RX); // Set DMA control packet //dmaSetChEnable(DMA_CH0, DMA_HW);//Trigger DMA transmission dmaSetChEnable(DMA_CH1, DMA_HW);//Trigger DMA reception } //ISR void dmaBTCAInterrupt(void) { uint32 offset = dmaREG->BTCAOFFSET; /* USER CODE BEGIN (0) */ /* USER CODE END */ if (offset != 0U) { //dmaGroupANotification(BTC, offset - 1U); //I am doing nothing here } /* USER CODE BEGIN (1) */ /* USER CODE END */ } // Simple task to trigger DMA and blik a LED void vTask1(void *pvParameters){ sciREG->SETINT |= SET_RX_DMA | SET_RX_DMA_ALL; //Trigger RX using DMA on SCI for(;;){ /* Toggle HET[1] with timer tick */ gioSetBit(hetPORT1, 17, gioGetBit(hetPORT1, 17) ^ 1); //just blink a LED vTaskDelay(200); } } //Main part void main(void) { /* USER CODE BEGIN (3) */ /* USER CODE END */ gioSetDirBit(hetPORT1,17,1); //LED PIN sciInit(); dmaSciInit(); if (xTaskCreate(vTask1,"Task1", configMINIMAL_STACK_SIZE, NULL, 1, &xTask1Handle) != pdTRUE){ while(1); } /* Start Scheduler */ vTaskStartScheduler(); /* Run forever */ while(1); }