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