cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L083 UART receives only one byte

JR2963
Senior

Hi,

I am trying to receive data (on STM32L083) via USART1, the way I was used to doing it on STM32L071. Specifically, I used a circular buffer that was continuously written to by DMA - RX. Now, I've ported the code to this L083 and it seems that nothing is being written to the global DMA buffer (although I am 100% sure that data is coming in on the UART pin). As a test, I tried to receive data simply using HAL without DMA and am able to receive only 1 byte; there are never more. Do you know what the problem might be? It seems like nothing can go wrong. I have a speed of 9600, and the data on the pin has been verified with a logic analyzer. What else can I check?

 

Here the simple RX I used:

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_DMA_Init();

MX_USART1_UART_Init();

/* USER CODE BEGIN 2 */

HAL_UART_Receive(&huart1, myArray, 5, HAL_MAX_DELAY);

/* USER CODE END 2 */

 

And there is variant of code for using DMA and circular buffer:

/*Uart Init DMA */

LL_DMA_DisableChannel(DMA1,LL_DMA_CHANNEL_3);

LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_3,

LL_DMA_DIRECTION_PERIPH_TO_MEMORY |

LL_DMA_PRIORITY_LOW |

LL_DMA_MODE_CIRCULAR |

LL_DMA_PERIPH_NOINCREMENT |

LL_DMA_MEMORY_INCREMENT |

LL_DMA_PDATAALIGN_BYTE |

LL_DMA_MDATAALIGN_BYTE);

 

LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_3,

LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE),

(uint32_t)GlUartRxBuffer,LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3));

 

LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, UART_CIRCLE_MAX_BUFFER_SIZE);

LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_3, LL_DMA_REQUEST_3);

 

/* Enable DMA RX Interrupt */

LL_USART_EnableDMAReq_RX(USART1);

/* Enable DMA Channel Rx */

LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);

 
 
 
 
8 REPLIES 8
TDK
Guru

Would be good to see more of the code. For example, to see if UART_CIRCLE_MAX_BUFFER_SIZE is 1 or 5.

Debug the code in the faulted state, look at the UART registers to see if an error occurred. Look at the DMA registers to see if the stream is still active.

If you feel a post has answered your question, please click "Accept as Solution".

Hi, Thank you, UART_CIRCLE_MAX_BUFFER_SIZE > 1 (for now I tried = 60). Registers bellow:

UART_DMA_REGs.png

Clear the overrun issue.

Identify why you aren't monitoring receiver continuously (probably when it's not in the blocking function), and implement identification and clearing of errors like Overrun, Noise, Parity, Framing which will block reception until explicitly cleared.

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

If ORE is set, does it means the DMA does not read the RDR and pass t to the GlUartRxBuffer?

I want the DMA to read every received byte on UART1 and store it in GlUartRxBuffer - and do this in circular mode, without any interrupts. 

Suggests at some point you weren't servicing it.

Large circular / continuous DMA shouldn't miss data, but might get other errors that need to be cleared, say the lines glitched, or baud rates changed, cables connected, etc. DMA perhaps best serviced in HT/TC interrupts, or data periodically harvested.

I don't use HAL to manage UART IRQ/DMA, overly cumbersome for the task

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

 As far as I know, DMA should be able to automatically transfer data from RDR to memory (globalBuffer), and in my case, Circular mode should start over from index 0 if it reaches the end of the buffer. I think the registers for this are set correctly, but I must have overlooked something.

I spent some time trying to track it down but didn't see any red flags.

It's odd how NDTR is 59, and the DMA stream is still active. Like it transferred one byte and stopped, as you say.

It is not a mystery why more bytes are not transferred--ORE needs to be cleared.

Perhaps ORE was set prior to the DMA being enabled, so one byte was immediately transferred (as RXNE=1) but no more as possible (due to ORE). That's my best guess. Easy enough to check. But at 9600 baud and with the code you presented, that shouldn't be happening. Perhaps there is some other code which blocks.

 

If you feel a post has answered your question, please click "Accept as Solution".
Pavel A.
Evangelist III

>If ORE is set, does it means the DMA does not read the RDR and pass t to the GlUartRxBuffer?

If ORE is set, the DMA doesn't know that and keeps running. It's the UART stops receiving - you need to detect and clear ORE to let it go. Newer STM32s have option to disable ORE so it never occurs at all (TL;DR but this has other complications).