2017-02-06 05:22 AM
I had problem for 'HAL_UART_Transmit_DMA', once I transmitted some data, I couldn't send any data after that.
I used this function,
'HAL_UART_Transmit_DMA' in 'USART1_IRQHander'.
(Because I should parse the data as soon as I receive any data. (N of data is not fixed.).)
So I found the solution in this forum. And I succeeded using'HAL_UART_Transmit_DMA'.
I attached one line(huart->gState = HAL_UART_STATE_READY;) in 'UART_DMATransmitCplt' like below.
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
huart->TxXferCount = 0U;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
huart->gState = HAL_UART_STATE_READY; <- this!!!!
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?
But I wonder if I can use
'HAL_UART_Transmit_DMA' in'USART1_IRQHander'.
Does any problem happen later?
Please answer me,
#usart1 #dam2017-02-06 12:58 PM
Try this one...
void CheckTxDMABufferProgress(void){ if ( DMABufHasData ){ char uartState = HAL_UART_GetState(&huart1); if ((uartState == HAL_UART_STATE_READY) || (uartState == HAL_UART_STATE_BUSY_RX)) { DMABufHasData = false; // sending now if (HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Usart1TxDMABuffer + U1TxBufferPtrOUT ,U1TxBufferPtrIN - U1TxBufferPtrOUT) == HAL_OK){ HAL_UART_Transmit_DMA_Status = UartDMAsuccess; U1TxBufferPtrOUT = U1TxBufferPtrIN; } else{ Error_Handler(); /* Transfer error in transmission process */ HAL_UART_Transmit_DMA_Status = UartDMAfailed; } } }}�?�?�?�?�?�?
2017-02-07 06:39 AM
Good afternoon.
It seems I have encountered the same problem ...There is no need to modify the HAL code.You must enable global interrupt USART1Good luck.2017-02-07 09:47 AM
Hi
Min-Kyoung Kim,
The HAL code does not need to be modified. Make sure to call
HAL_UART_IRQHandler(&UartHandle)
inside yourUSART1_IRQHander()
before doing anotherHAL_UART_Transmit_DMA()
:void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&UartHandle); // Should reset gState to HAL_UART_STATE_READY
HAL_UART_Transmit_DMA(&UartHandle, buffer, BUFFER_SIZE);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Guillaume
2017-02-09 05:02 AM
- where can I put your function?
- where can I get 'DMABufHasData' ?
2017-02-09 05:13 AM
I constantly check the 'DMABufHasData' code within the foreground main loop;
after I add bytes to the DMA buffer with puts(string), I set the flag 'DMABufHasData' true from anywhere in the code..
the foreground loop will send the data out instantly..
ie
while (1){
delayCounter++; // small delay loop if ( delayCounter > 0x0ff){ delayCounter = 0;checkBackgroundServices(); // Uart1RxPort, TxDMA, RxDMA etc.
}
}
2017-02-09 06:13 AM
you mean that i should 'SET_BIT(huart1.Instance->CR1, USART_CR1_RXNEIE);' after
'HAL_UART_Transmit_DMA
'
???2017-02-09 06:24 AM
It works!!!!!
should I put your code before 'HAL_UART_Transmit_DMA'?
2017-02-09 01:34 PM
Which part of my code exactly? In the example I posted, HAL_UART_Transmit_DMA() is called in the IRQHandler, you could also call that function in HAL_UART_TxCpltCallback() or in your main code if you look for a flag. Just make sure
HAL_UART_IRQHandler() is called BEFORE.
2017-02-09 02:12 PM
It is right that
HAL_UART_Transmit_DMA() is called in the IRQHandler.
I mean your code is below.
HAL_UART_IRQHandler(&UartHandle);
I put this code in USART1_IRQHandler and put it before
HAL_UART_Transmit_DMA