2012-10-04 07:36 AM
Hi,
I'm creating a program that uses several USARTs for communication. All of them uses DMA circular buffer for reception and normal interuptdriven DMA transfers. The code is the same for all 4 USARTs (and one UART) and is as follow (different variable names):void DMA1_Stream3_IRQHandler(void)
{
/* Clear DMA Streams flags */
DMA_ClearFlag(DMA1_Stream3, DMA_FLAG_HTIF3 | DMA_FLAG_TCIF3);
/* Disable the DMA Streams */
DMA_Cmd(DMA1_Stream3, DISABLE);
/* Disable the USART Tx DMA request */
USART_DMACmd(USART3, USART_DMAReq_Tx, DISABLE);
tx_buf_index = 0;
}
void StartTransfer(void)
{
DMA_StructInit(&DMA_InitStruct);
// DMA_DeInit(DMA1_Stream1);
/* Settings for USART DMA transfer */
DMA_InitStruct.DMA_Channel = DMA_Channel_4;
DMA_InitStruct.DMA_PeripheralBaseAddr = &(USART3->DR);
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Byte;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct.DMA_Priority = DMA_Priority_Low;
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)TXBuf;
DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.DMA_BufferSize = (uint16_t)tx_buf_index;
DMA_Init(DMA1_Stream3, &DMA_InitStruct);
/* Enable the USART DMA requests */
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
/* Clear the TC bit in the SR register by writing 0 to it */
USART_ClearFlag(USART3, USART_FLAG_TC);
/* Enable the DMA TX Stream, USART will start sending the command code (2bytes) */
DMA_Cmd(DMA1_Stream3, ENABLE);
}
The thing is that sometimes the DMA for all usarts goes down. All communication stops. I have no idea what may cause this and would be happy if someone could help me bring som reliability to my communications.
If it is of importance, the baudrates are 115200, 115200, 19200 and 57600 on the four used usarts. I really don't know what might be of importance because I can't understand this problem.
EDIT:
I forgot to mention, I have a lock when trying to add new data while transfer is active according to:
void AddTXData(uint8_t data)
{
while(DMA_GetCmdStatus(DMA1_Stream3) == ENABLE)
{
/* Wait for DMA stream to be available for transaction */
}
TXBuf[tx_buf_index] = data;
tx_buf_index++;
}
// Tom
2012-10-04 09:47 AM
I'd wager it's because you aren't clearing the interrupts properly.
Perhaps you can condense this into a complete example, fragments fail to tell the whole story. Use a debugger, break execution, figure where the processor is stuck, and look at the peripheral states. When you know why it hung you'll be in a better place to solve the issue.