Half duplex DMA Uart
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-12-15 7:22 AM
Hello there,
I am experiencing a weird behaviour in my application. I am using HAL library. I am using STM32F407 and usart2 to send and receive using DMA in half-duplex mode. Everything is working fine, until I decide to send a message with different lenght and wait for an answer with different length. What I mean is, if i send and receive same length frames it is working. If I change it, it skips the first reception packet and after that everything is shifted somehow in the reception buffer. This is my procedure. First of I send:HAL_StatusTypeDef rs485_sendData(uint8_t* buffer, size_t len)
{ HAL_StatusTypeDef ret = HAL_OK; ret |= HAL_HalfDuplex_EnableTransmitter(p_rs485_usartHandle); rs485_SetTransmissionMode(); while (HAL_UART_GetState(p_rs485_usartHandle) != HAL_UART_STATE_READY); ret |= HAL_UART_Transmit_DMA(p_rs485_usartHandle, buffer, len); return ret; } rs485_SetTransmissionMode(); sets DE pin High because this is rs4 After I send i get Tx interrupt: void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { assert_param(huart); if (huart == p_rs485_usartHandle) { assert_param(p_rs485_msgInfo); rs485_SetReceptionMode(); HAL_HalfDuplex_EnableReceiver(p_rs485_usartHandle); HAL_UART_Receive_DMA(p_rs485_usartHandle, rs485_rxBuffer, p_rs485_msgInfo->rxDataLen + RS485_PAYLOADS_SIZE); } } HAL_UART_Receive_DMA I specify for how many bytes I am waiting. WHen they come i get rx interrupt: void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { assert_param(huart); if (huart == p_rs485_usartHandle) { // -1 because crc byte is not taken uint8_t crc = rs485_getCRC(rs485_rxBuffer, p_rs485_msgInfo->rxDataLen + RS485_PAYLOADS_SIZE - 1); // check CRC (-1 because its index) if (rs485_rxBuffer[p_rs485_msgInfo->rxDataLen + RS485_PAYLOADS_SIZE - 1] == crc) { // CRC OK Led_Toggle(2); if (osOK != osMessagePut(msgQId_rs485Frame, (uint32_t)rs485_rxBuffer, 0)) log_PushLine(e_logLevel_Critical, ''Unable to put rs485 rx message in the queue''); } else { log_PushLine(e_logLevel_Warning, ''Received command %u with bad crc!'', rs485_rxBuffer[1]); } } } And this works quite fine if from the begining of code I send the same message all the time. But lets say after a while i start to send a bit different message, that also receives answer with different amount of bytes. I specify that and while debuging I see that for the first different message I send I dont get any answer at all and on my rs485 sniffer i see that the answer is sent. I just dont receive it in code and I have no idea why. Im on this for all day now. I tried doing DMA init before each send but that didnt change anything... Is there something I am missing in the confifuration? I would really apreciate all help!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-12-15 8:13 AM
I think I am on a good track of debugging this... What I cant find in documentation of HAL is either I have to intentionaly clear the DMA uart RX buffers. For example lets say I send a command and now I am waiting for answer but it doesnt come. I want to send another command then, but before I do that i need to clear everything with DMA rx procedures so i can start clean again. Is there a way?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-12-16 1:17 AM
What happens If I set the DMA, but no data will come. Can I simply reconfigure it or do I need to clear some flags before, like transfer flag? Is it a good direction? Please help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-03-07 1:07 PM
Did you ever find an answer?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-03-07 2:09 PM
I'll link in Allen's more recent thread here for completeness, especially if anyone else is looking for this type of functionality or support within HAL
https://community.st.com/0D50X00009XkXRGSA3
DAHMEN.IMEN
‌st.mcu
‌ perhaps you can see if there is any interest among the HAL dev team to review these use cases and perhaps provide some direction or implementation in the F2/F4 libraries.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-03-07 2:40 PM
And, specifically, what the details were in the change right after 1.1.2 - were any app-level code changes required?
- HAL UART
update
Several update on HAL UART driver to implement the new UART state machine:
Add new field in UART_HandleTypeDef structure:
'rxState',
UART
state information related to Rx OperationsRename 'state' field in UART_HandleTypeDef structure by 'gstate':
UART
state information related to global Handle management and Tx OperationsUpdate UART process to manage the new UART states.
Update __HAL_UART_RESET_HANDLE_STATE() macro to handle the new UART state parameters (gState, rxState)
Update UART_BRR_SAMPLING16() and UART_BRR_SAMPLING8() Macros to fix wrong baudrate calculation.
Update Polling management:
The user Timeout value must be estimated for the overall process duration: the Timeout measurement is cumulative
Update DMA process:
Update the m
anagement of UART peripheral errors during DMA process. This requires the following updates in user application:
Configure and enable the UART IRQ in HAL_UART_MspInit() function
In stm32f2xx_it.c file, UART_IRQHandler() function: add a call to HAL_UART_IRQHandler() function
Add and customize the Error Callback API: HAL_UART_ErrorCallback()
