CubeF4, when is a UART DMA transmission over ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-26 1:01 AM
Hello,
I'm sending data on UART using DMA with HAL_UART_Transmit_DMA().
As sometimes I need to send two messages consecutively, I'm testing if the previous
message is sent before preparing the new one. I do something like this:
void sendData(){
uint8_t toSendCount;
while (HAL_UART_GetState(usart) != HAL_UART_STATE_READY)
;
s->size = 12;
s->code = CommandConsts::GET_PARAMS;
protocol->initTxFrame((uint8_t*)s, counter, txBuffer, &toSendCount);
HAL_UART_Transmit_DMA(usart, txBuffer, toSendCount);
}
Generaly it works but sometimes, HAL_UART_GetState() never stop returning HAL_UART_STATE_BUSY_TX
I'm using F446.
What should I do ? Which function(s) should I call? Which register should I check?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-26 1:14 AM
A DMA transmission is over when the last item (byte) is placed at the target address - the UART TX register in your case.
This, in turn, might depend on the hardware and your UART settings. If you use flow control, the other site can delay the transmissions.
Or you just run in one of Cube's randomly determined timeouts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-26 7:50 AM
this is how I check if the Tx DMA has completed,
works on F7 and F0 processors
void CheckTxDMABufferProgress(void) {
if (TxDMABufHasData) {
char uartState = HAL_UART_GetState(&huart7);
if ((uartState == HAL_UART_STATE_READY) || (uartState == HAL_UART_STATE_BUSY_RX))
{
TxDMABufHasData = false; // sending now
if (HAL_UART_Transmit_DMA(&huart7, (uint8_t *)Usart1TxDMABuffer + U1TxBufferPtrOUT,
U1TxBufferPtrIN - U1TxBufferPtrOUT) == HAL_OK) {
HAL_UART_Transmit_DMA_Status = UartDMAsuccess;
U1TxBufferPtrOUT = U1TxBufferPtrIN;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-26 8:54 AM
@Community member​ Thanks, your method is a bit better than mine by chekcing busy_rx (but btw, I'm not using DMA for rx...)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-28 11:39 PM
why not ?
the Rx DMA works very well and its endless.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-01 1:11 AM
Is RX endless?
First, only if you set it to CIRCULAR, obviously.
Second, per my observation any error, even the slightest stops the "endless". Noise error, frame error, parity error.
So you need a place where you restart it. Agreed? Or is my observation wrong?
(I am still in the learning phase in regards to DMA, hence asking)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-10-01 1:17 PM
I am not sure why my code is so stable.
I am not sure why I never fall into any error interrupt, probably not enabled.
I only initialise the DMA on startup, I have boards running here on test for over a year now.
Yes, you could probably check for the DMA "not ok" and restart it.
what that flag is, I am not sure, I never needed it.
I have a foreground process that checks some flags every mS and others every Second
