cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F437 DMA FEIF0 error

John Hite
Associate III
Posted on February 02, 2017 at 17:56

I have the following DMA/UART setups on my processor. I print a login prompt. The first two characters get echoed OK but then I get an FEIF0 error. Also the documents talk about 'beats'. What are beats?

Thanks,

jh

//TX setup

DMA_InitTypeDef uart_dma;

if (chars_in_buffer > 0)

{

    DMA_DeInit(DMA1_Stream0);

    DMA_StructInit(&uart_dma);

    uart_dma.DMA_Channel = DMA_Channel_5;

    uart_dma.DMA_DIR = DMA_DIR_MemoryToPeripheral;

    uart_dma.DMA_Memory0BaseAddr = (uint32_t)&dma_tx_block[0];

    uart_dma.DMA_BufferSize = (uint32_t)chars_in_buffer;

    uart_dma.DMA_PeripheralBaseAddr = (uint32_t)&DebugUart->DR;

    uart_dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    uart_dma.DMA_MemoryInc = DMA_MemoryInc_Enable;

    uart_dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    uart_dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    uart_dma.DMA_Mode = DMA_Mode_Normal;//XX

    uart_dma.DMA_Priority = DMA_Priority_High;

    uart_dma.DMA_FIFOMode = DMA_FIFOMode_Enable;//XX    

    uart_dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;//XX

    uart_dma.DMA_MemoryBurst = DMA_MemoryBurst_INC4;

    uart_dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_Init(DMA1_Stream0, &uart_dma);

    USART_DMACmd(UART8, USART_DMAReq_Tx, ENABLE);

    DMA_Cmd(DMA1_Stream0, ENABLE);

    DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0);

    DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);

    FLAG_SET(portminder_flags, PFLAG_TX_BUSY);

}

//RX setup

static void RestartDMA(void)

{

    DMA_InitTypeDef uart_dma;

    DMA_DeInit(DMA1_Stream6);

    DMA_StructInit(&uart_dma);

    uart_dma.DMA_Channel = DMA_Channel_5;

    uart_dma.DMA_DIR = DMA_DIR_PeripheralToMemory;

    uart_dma.DMA_Memory0BaseAddr = (uint32_t)&dma_rx_block[0];

    uart_dma.DMA_BufferSize = PORTMINDER_BLOCK_SZ;

    uart_dma.DMA_PeripheralBaseAddr = (uint32_t)&DebugUart->DR;

    uart_dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    uart_dma.DMA_MemoryInc = DMA_MemoryInc_Enable;

    uart_dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    uart_dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    uart_dma.DMA_Mode = DMA_Mode_Circular;

    uart_dma.DMA_Priority = DMA_Priority_High;

    uart_dma.DMA_FIFOMode = DMA_FIFOMode_Enable;

    uart_dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

    uart_dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;

    uart_dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    //DMA_FlowControllerConfig(DMA1_Stream6, 0);

    DMA_Init(DMA1_Stream6, &uart_dma);

    USART_DMACmd(UART8, USART_DMAReq_Rx, ENABLE);

    DMA_Cmd(DMA1_Stream6, ENABLE);

    DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);///????

    DMA_ITConfig(DMA1_Stream6, DMA_IT_TC, ENABLE);

}

void DMARxISR(void)

{

    CPU_SR_ALLOC();

    CPU_INT_DIS();

    OSIntNestingCtr++;

    CPU_INT_EN();

    if (DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) == SET) {

        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);

        //DMA_Cmd(DMA1_Stream6, DISABLE);

    }

    OSIntExit();

}

void DMATxISR(void)

{

    CPU_SR_ALLOC();

    CPU_INT_DIS();

    OSIntNestingCtr++;

    CPU_INT_EN();

    if (DMA_GetITStatus(DMA1_Stream0, DMA_IT_TCIF0) == SET) {

        DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0);

        DMA_Cmd(DMA1_Stream0, DISABLE);

    }

    OSIntExit();

}

1 REPLY 1
Posted on February 02, 2017 at 20:08

I think you need to manage ownership of the resource, ie mutex taken when starting, released with TC IRQ. I suspect the FE is coming from attempting to start a new transaction while one already in flight.

I don't like the sequencing here

    DMA_Init(DMA1_Stream0, &uart_dma);

    USART_DMACmd(UART8, USART_DMAReq_Tx, ENABLE);

    DMA_Cmd(DMA1_Stream0, ENABLE);

    DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0);

    DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);

prefer

    DMA_Init(DMA1_Stream0, &uart_dma);

    USART_DMACmd(UART8, USART_DMAReq_Tx, ENABLE); // Only once, in UART Init, no need to switch on/off here

    DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0); // not sure required

    DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);

    DMA_Cmd(DMA1_Stream0, ENABLE); // now ready to go

The DMA controller in Normal mode is going to be self stopping, so just validating the TC and clearing it should suffice

Don't like this, also going to be sensitive to address alignment

  uart_dma.DMA_MemoryBurst = DMA_MemoryBurst_INC4;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..