2018-09-26 01: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?
2018-09-26 01: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.
2018-09-26 07: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;
}
2018-09-26 08: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...)
2018-09-28 11:39 PM
why not ?
the Rx DMA works very well and its endless.
2018-10-01 01: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)
2018-10-01 01: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