2019-08-27 04:43 PM
Hi Community,
I find a method to reset a buffer of USART DMA Buffer.
because I use USART DMA basically.
my system is consist of android smartphone, bluetooth and microcontroller(STM32F407VET), PC
when I click a button that implemented in a android, some packet is send to the bluetooth RX
and Bluetooth TX that connected to micro controller USART3 RX.
than Received USART3 Data directly send to USART1 and I can see the packet in PC program.
(So... long)
I learned about HAL USART DMA is need a fixed buffer size.
so I designed the system the length of the packet is always fixed.
But! when the Bluetooth is connected, the packet is occurred by Bluetooth like
"Connected X" (X is MAC address of Bluetooth)
Due to the packet that I don't want, DMA buffer is shifted.
like under example.
ex)
Normal State
buffer size 5
send "12345" => receive "12345"
Abnormal state
send "12345" => add packet "ab"=>receive "ab123"
For this reason, I would like to ask community How to reset DMA buffer.
Of course, using a ring buffer is best way, but I'm not have a code that work normally, and other is I can't understand the code algorithms.
Ask for help...
Thank.
2019-08-27 06:03 PM
So more of a Synchronization issue.
The code in your other thread receives data into the buffer twice, and blocks (I assume)
Doing one byte at a time with DMA seems overkill.
Blocking doing 5 bytes and ping-pong between send/receive looks prone to lose data. You need to use DMA/IT versions that can function concurrently, and manages how much data comes in and goes out.
Fixed length receive really requires a continuous stream of data.
2019-08-27 06:10 PM
Thanks you!
That link is just test.
Now I'm not use DMA only one byte.
I set a length of DMA buffer, size 32byte.
I fixed a length of buffer(send / receive).
2019-08-27 06:14 PM
So I check
HAL_UART_Receive_DMA(&huart1, rxBuffer, SIZE_OF_RX_TX);
function means that, USART1 RX channel wait untill RXbuffer size is same SIZE_OF_RX_TX.
SIZE_OF_RX_TX is define, 32byte,
finally, I think if I send and receive fixed packet, it is easy to use USART DMA.
but, I didn't think of Bluetooth make a packet itself...
Eventually I try to reset the DMA buffer (or counter) as soon as it detects a Bluetooth packet.
2019-08-27 06:22 PM
This is the code I'm thinking of.
char StartChar = '&';
char bluetoothCode = 'C' //or MAC Address first char
void HAL_UART_RxCpltCallback
{
if (huart->Instance == USART3)
{
if(rxBuffer[0] != StartChar || (strchr(rxBuffer, bluetoothCode) != null))
{
//reset RX buffer or count.
}
else if (rxBuffer[0] == StartChar)
{
HAL_UART_Transmit_DMA(&huart1, rxBuffer, SIZE_OF_RX_TX);
HAL_UART_Receive_DMA(&huart3, rxBuffer, SIZE_OF_RX_TX);
}
}
}
2019-08-27 07:28 PM
I have found this to be
void initUart1RxDMABuffer(void) {
if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
{
sprintf(string, "initUart1RxDMABuffer Failed\n");
puts1(string);
}
else
{
sprintf(string, "initUart1RxDMABuffer OK!\n");
puts1(string);
}
}
char peekRxU1(int offset) {
// offset of zero returns the next byte to be read
int relativePtr = (U1RxBufferPtrOUT + offset) & (U1RxBufSize - 1);
char PeekRx = Usart1RxDMABuffer[relativePtr]; // just looking Don't increment pointer
return PeekRx;
}
char readU1(void) {
char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];
if (U1RxBufferPtrOUT >= U1RxBufSize) U1RxBufferPtrOUT = 0;
return readByte;
}
char readableU1(void) {
U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
return U1RxBufferPtrIN - U1RxBufferPtrOUT;
}
void clearRxBuffer(void) {
U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
U1RxBufferPtrOUT = U1RxBufferPtrIN;
}
the best way:
2019-08-27 10:43 PM
Thanks Trevor, where did you find it?
2019-08-27 11:25 PM
I wrote it
2019-08-27 11:35 PM
I'm trying use huart1.hdmarx->Instance->CNDTR, but CNDTR is not member of structure DMA_Stream_TypeDef
can't found it.
2019-08-28 12:50 AM
I use this on the F7, just looking over the code I sent you, in Peek(), there is a requirement that the Rx buffer size is 2^N
char readableU1(void) {
U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->NDTR;
return U1RxBufferPtrIN - U1RxBufferPtrOUT;
}