1

I have an interrupt (RXNE) based receive cycle running on STM32F1. I do only use receive command which is:

HAL_UART_Receive_IT(&huart3, RxBuffer, sizeof(RxBuffer));

Thus I receive a message then write my buffer which is:

uint8_t RxBuffer[25];

After using RxBuffer's content, I am clearing this array using this function:

memset(RxBuffer, '\0', sizeof(RxBuffer));

The incoming data is never bigger than 24 byte btw. It's all OK until another data is received and written to RxBuffer. When next data is received something strange is happening and HAL_UART_Receive_IT(&huart3, RxBuffer, sizeof(RxBuffer)); function is starting to fill the data to my RxBuffer which byte it left off on last receive.

For example;

1 -> RxBuffer is normally initialized with NULL

RxBuffer = {'\0', '\0', '\0', '\0', ... '\0'} (25 bytes NULL)

2 -> After receiving first data it becomes like this

RxBufer = "xc32 CMD1 400 200 50" (it's 20 bytes total and last 5 bytes are still NULL)

RxBuffer = {'x', 'c', '3', '2', ' ', 'C' ... '\0', '\0', '\0'}

3 -> Then I clear the buffer content using memset(...) function.

RxBuffer = {'\0', '\0', '\0', '\0', ... '\0'} (25 bytes NULL again)

4 -> After receiving another data like "xc32 CMD2":

RxBuffer = {'C', 'M', 'D', '2', '\0', '\0', '\0' ... 'x', 'c', '3', '2', ' '} (still 25 bytes of data but UART begins to write data which byte it left off last time, and it becomes some shifted shit..)

It's behaving like a ring buffer. How to properly do this receive process to make it begin 0th index of buffer every single receive?

daaarwiin
  • 127
  • 1
  • 13
  • Can you show us (part of) the code that you use to set up the call to `HAL_UART_Receive_IT` and the code you use to process the returned buffer. Looks like you may be modifying the passed data pointer at some stage. – Adrian Mole Aug 20 '21 at 11:51
  • ... particularly, if the `memset` call is not clearing the 'old' data, that would support the fact that the `RxBuffer` pointer is being incremented (or otherwise modified). Or else where does that old data come from? – Adrian Mole Aug 20 '21 at 11:53
  • `extern uint8_t RxBuffer[25];` `void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ /* USER CODE END USART3_IRQn 0 */ HAL_UART_IRQHandler(&huart3); /* USER CODE BEGIN USART3_IRQn 1 */ HAL_UART_Receive_IT(&huart3, RxBuffer, sizeof(RxBuffer)); SplitCommandMsg(RxBuffer, id, cmd, &xPoint, &yPoint, &vel); /* USER CODE END USART3_IRQn 1 */ }` – daaarwiin Aug 20 '21 at 12:05
  • `memset(...)` is clearing my buffer correctly, I can say that because I do watch them while debugging. – daaarwiin Aug 20 '21 at 12:08
  • OK, then you're out of my field of expertise. Does your 'sender' need to be flushed between successive reads by the receiver? – Adrian Mole Aug 20 '21 at 12:10
  • Actually no, all the 'sender' has to do is send commands when it's turn. – daaarwiin Aug 20 '21 at 13:22
  • Show the code that starts the transaction. I assume you pass there the buffer length, which is 25, so the HAL will continue to fill the buffer until it will receive 25 bytes. – Dabo Aug 20 '21 at 19:41

2 Answers2

1

Because it is interrupt routine it works in the background. And it will receeive data to this buffer until the end of the buffer.

If your data is not fixed length you should enable the "IDLE" interrupt and process the data in this interrupt handler (or better in HAL callback). Then restart the reception.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • My incoming data is not fixed length, it varies between 8-24 bytes (char array). So check me if I do got it? I should enable _IDLE_ interrupt in addition to _RXNE_? Can you explain a bit details about _IDLE_ please? – daaarwiin Aug 20 '21 at 13:39
  • So you need to look for the IDLE interrupt which comes when UART is quiet for more than 9 bits. It probably cannot be done using HAL – 0___________ Aug 20 '21 at 13:40
  • I will be looking this possibly with LL or register level checking. – daaarwiin Aug 20 '21 at 13:41
0

The problem can be solved by receiving data byte-by-byte using DMA.

char rx_buff[10];
HAL_UART_Receive_DMA(&huart1, (uint8_t*)rx_buff, 1);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    ...
    array[i++] = rx_buff[0];
    /* Then reset buffer using bzero() or memset() */
}
daaarwiin
  • 127
  • 1
  • 13