Skip to main content
JR2963
Senior II
October 27, 2023
Question

STM32L083 UART receives only one byte

  • October 27, 2023
  • 3 replies
  • 2378 views

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);

 
 
 
 
This topic has been closed for replies.

3 replies

TDK
October 27, 2023

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""."
JR2963
JR2963Author
Senior II
October 27, 2023

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

UART_DMA_REGs.png

Tesla DeLorean
Guru
October 27, 2023

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 VenmoUp vote any posts that you find helpful, it shows what's working..
JR2963
JR2963Author
Senior II
October 27, 2023

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. 

Tesla DeLorean
Guru
October 27, 2023

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 VenmoUp vote any posts that you find helpful, it shows what's working..
JR2963
JR2963Author
Senior II
October 27, 2023

 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.

Pavel A.
Super User
October 27, 2023

>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).