2022-02-16 07:06 AM
Hello,
I'm currently working on an application that integrates the LoRaWAN stack (version 2.1.0), and has to use USART2 to send/receive data. USART2 is already used by the trace utility, to send trace messages. I activated RX on interruption by calling UTIL_ADV_TRACE_StartRxProcess().
While performing some tests, I discovered a problem: if a byte is received while HAL_UART_Transmit_DMA() is being executed, the RX interrupt service code sees the USART's data as being locked and returns without re-enabling RX interrupt. Consequence: the USART can't receive bytes anymore.
I just corrected this by disabling USART interrupts when a DMA TX operation is initialized:
UTIL_ADV_TRACE_Status_t vcom_Trace_DMA(uint8_t *p_data, uint16_t size)
{
// Disable USART interrupts while starting the DMA TX otherwise an RX
// interrupt could happen while USART's data is locked, and RXNEIE would
// be left reset.
HAL_NVIC_DisableIRQ(USARTx_IRQn);
HAL_UART_Transmit_DMA(&huart2, p_data, size);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
return UTIL_ADV_TRACE_OK;
}
This works. But I wonder whether this is the best solution. Any thoughts?
The place where the interrupt service code fails to re-enable RX interruption:
2023-06-09 10:13 AM
Hi, I'm doing the exact same thing i.e. enabling UART2 IT reception via UTIL_ADV_TRACE_StartRxProcess() but I can't receive a character even in the very first time, so the callback function never gets called. I tried what you mention here but it's still not working.
If I comment HAL_UART_Transmit_DMA(&huart2, p_data, size); inside vcom_Trace_DMA or if I initialize first UART2 and then DMA inside vcom_Init, I can receive data and successfully transmit it via LoRa modulation in P2P mode but obviously no trace information is printed from the MCU.
Do you have any idea what the problem might be?
Im using STM32WL55JC17
2023-06-09 11:17 AM
Have a critical section around the DMA stuff, or have in occur in an interrupt/callback that prevents secondary interrupt occurring.
Have another instance of huart2 for DMA ?
Fix the underlying code/library ?
2023-06-12 12:07 PM
The DMA transmition begins with the macro APP_LOG, which invokes the function UTIL_ADV_TRACE_COND_FSend that returns TRACE_Send(), which in turn calls HAL_UART_Transmit_DMA through the UTIL_TraceDriver.Send struct member.
The function TRACE_TxCpltCallback is passed through a series of pointers to the HAL_UART_IRQHandler and therefore executed every time a transmition is completed. The thing is that inside TRACE_TxCpltCallback, UTIL_TraceDriver.Send is called again causing the UART to transmit in DMA mode and generate its corresponding interrupt. It doesn't make sense to me why the advanced trace functions are this way.
If i comment UTIL_TraceDriver.Send line, I can receive data in interrupt mode as the code is not entering TRACE_TxCpltCallback again and again, or at least I think that's the reason. So I compared the state of UART2 registers in both cases and the changes are in FIFOEN bit of CR1 register and in TXFT and TXFE of ISR register. However I read that some USART registers get changed when using the debug mode of STM32 CubeIDE so I'm not sure if the values are correct.
I could simply use HAL_UART_Transmit_DMA directly in my application code but I wanted to use the utilities STM provides.
Btw, there are some UTIL_ADV_TRACE_INIT/ENTER/EXIT_CRITICAL_SECTION() and TRACE_Lock/UnLock() sentences inside TRACE functions but I can't figure out its function so I only commented out some of them randomly and observed its effects. In some cases no trace info whatsoever was printed but i never did I managed to send and receive simultaneously.