lpcware

DMA interrupt  stops working

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by justmakeit on Wed Sep 30 00:10:45 MST 2015
Hello everyone,

I have written a code to send/receive ip packets over rs485. Its (almost) working.The receiver is started with a uart interrupt and starts a dma transfer. When the dma is finished it should fire a interrupt but this not always the case. It stops firing dma interrupts after a random time. I checked if the dma cannel was still active with the function GPDMA_IntGetStatus(GPDMA_STAT_ENABLED_CH, 0) and it returned SET so it is still running. When i enable the uart irq it is still firing so there is data in the FIFO.

How can i debug this problem?

Thank you in advance!

//Interrupt function for the rs485 module
void RS485_IRQHandler(void)
{
if(UART_ReceiveByte((LPC_UART_TypeDef *) LPC_UART1) != 0x01){
return;
}
UART_RS485ReceiverCmd(LPC_UART1, ENABLE);
UART_Receive((LPC_UART_TypeDef *) LPC_UART1, received_data, 10, BLOCKING);
if((memcmp (&received_data[4], Net_settings.MAC_Address.addr, 6) == 0)||memcmp (&received_data[4], broadcast_mac, 6) == 0){
received_len = 0;
received_len |= (received_data[0] << 24);
received_len |= (received_data[1] << 16);
received_len |= (received_data[2] << 8);
received_len |= (received_data[3]);

if(rs485_buffer != NULL){
free(rs485_buffer);
rs485_buffer = NULL;
}
rs485_buffer = malloc(received_len);
if(rs485_buffer == NULL){printf("rs485:malloc failed\r\n");}
memmove(rs485_buffer,&received_data[4],6);

GPDMA_Channel_CFG_Type GPDMAChannelConfig;
GPDMAChannelConfig.ChannelNum = 0;
GPDMAChannelConfig.TransferSize = received_len - 6;
GPDMAChannelConfig.DstMemAddr = (uint32_t)(&rs485_buffer[5]);
GPDMAChannelConfig.TransferType = GPDMA_TRANSFERTYPE_P2M;
GPDMAChannelConfig.SrcConn = GPDMA_CONN_UART1_Rx;
GPDMAChannelConfig.DMALLI = 0;
if(GPDMA_Setup(&GPDMAChannelConfig) == ERROR){printf("dma error\r\n");}

GPDMA_ChannelCmd(0, ENABLE);
NVIC_DisableIRQ (UART1_IRQn);
NVIC_EnableIRQ (DMA_IRQn);
}else{
UART_RS485ReceiverCmd(LPC_UART1, DISABLE);
}
}

void DMA_IRQHandler(void){
if (GPDMA_IntGetStatus(GPDMA_STAT_INT, 0)){
// Check counter terminal status
if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, 0)){
// Clear terminate counter Interrupt pending
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
poll_eth_RS485_driver();
}
// Check error terminal status
if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, 0)){
// Clear error counter Interrupt pending
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
free(rs485_buffer);
rs485_buffer = NULL;
printf("rs485: DMA error\n\r");
}
}
GPDMA_ChannelCmd(0, DISABLE);
UART_RS485ReceiverCmd(LPC_UART1, DISABLE);
NVIC_EnableIRQ (UART1_IRQn);

}

Outcomes