2017-02-02 08:56 AM
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();
}
2017-02-02 11:08 AM
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;