This code in general works as follows:
There are 3 interrupts: the Rx Complete Interrupt (created by DMA), the Tx Complete Interrupt (also created by DMA) and the „Idle Line“ Interrupt, coded manually in the stm32f1xx_it.c.
The Rx Complete Interrupt always occurs, when the Rx Buffer rolls over. To demonstrate this, the Rx buffer size was intentionally made very low (16 bytes) for this example. We use this interrupt to count the „Buffer rollovers“. A Buffer may only roll over once before an Idle Interrupt occurs for a valid transmission. If it rolls over two or more times, we can assume, that some data have been overwritten and the transmission is corrupted.
The incoming data is checked when the idle interrupt occurs. The start position of the new incoming data stream is the last end position, which can be calculated from querying the DMA “CNDTR” register (which tells us, how many bytes are left until the buffer is full / rolls over) and subtracting that value from the (known) buffer size. This information needs to be consistent over the whole runtime of the program, so you have to store it “in a safe place” 😉 – don’t lose it …
With the information of the last known buffer position and the current buffer position we can calculate the length of the received data. We have to check, if a buffer rollover occurred during the transmission and have to take that into account. See the source code for details …
The Tx Complete Interrupt is used here only to toggle the LED of the Bluepill.