cancel
Showing results for 
Search instead for 
Did you mean: 

usart -> dma fifo error int

michaelmccartyeng
Associate II
Posted on September 05, 2013 at 04:09

Every time I hit my dma int handler I have an error and it looks like the data i'm sending is all screwed up. Any ideas ?

Better yet, any direction as to how to solve these issues myself ? There are ints like ovf and FEIF6 but where can you go to find out what they mean and what could be a possible solution ? I can read the manual but it just tells me its a ''fifo error''. I didnt initially have a fifo and I tried to make one to get rid of the error but its still there. i'm sorry but this is not super helpful, how are you supposed to figure this stuff out ? 0: No FIFO error event on stream x 1: A FIFO error event occurred on stream x

void
setupCommDMA(
void
)
{
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure; 
// init clocks 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
// // int our vector table
// /* Enable the DMA Stream IRQ Channel */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); 
// 
// /* Enable the USARTz Interrupt */
// NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
USART_InitStructure.USART_BaudRate = 921600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR); 
// usart2 data register
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)frame_bufferA;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; 
DMA_InitStructure.DMA_BufferSize = 
sizeof
(frame_bufferA) / 
sizeof
(u8);
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
// init the dma
DMA_Init(DMA1_Stream6, &DMA_InitStructure);
// activate channel
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
// enable usart
USART_Cmd(USART2, ENABLE);
// setup transfer complete int, 
DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE);
// start the dma transfer, it will execute now
DMA_Cmd(DMA1_Stream6, ENABLE);
}

3 REPLIES 3
michaelmccartyeng
Associate II
Posted on September 06, 2013 at 03:12

So do yall think my code is ok ? 

Posted on September 06, 2013 at 04:32

I'm not sure of the merit of VeryHigh for a 90 KBps stream that can be pretty tardy (11-22us), not that it impacts the Fifo mode, or if the Fifo mode serves a useful purpose in this context.

Some of these modes relate to high rate, hard time line transfers, like video. Say 10-20 MBps

Do you have other DMA operations contending for resources here?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michaelmccartyeng
Associate II
Posted on September 06, 2013 at 23:22

I had DCMI->DMA transfer to a buffer, then in the int of that transfer I start the USART->DMA transfer, then in the int of that transfer I start the dcmi again. 

So 

on(dcmi.frame || dcmi.ovf){kick off usart dma xfer}

on(usart.TC || usart.ERR){kick off dcmi to mem dma xfer}

The same buffer is being written to by the dcmi and read from the usart. But the dcmi uses DMA2 and the usart uses DMA1. 

So I guess it boils down to these questions 

1.) can / should I trigger a dma transaction from the ''tc'' interrupt of another ? 

     -- if so do i need to de-int the expired dma or something so it releases the control ? 

2.) will dma deadlock if we are writing via one dma and reading from another (same buffer)?

 

about the fifo, i only turned it on to try and remove the ''fifo error'' the fifo was disabled when i was firs getting these errors.

When I do the dcmi transfer then the usart transfer in the main loop instead of the intterupt handlers the usart does not get the fifo error anymore.