2016-06-13 07:56 AM
Hi everybody.
I have an stm32f4 micro trying to communicate with device via UART. I want to receive with interrupts and possibly, based on some conditions, stop the reception process (i.e. if some time expires from the last \n received). Since I am reading one char at once (receiving variable length strings) and the reception is called again within the callback (see https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fBest%20way%20to%20use%20HAL%20UART%20Receiver%20IT%20Function&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E..., I have to stop it outside the callback. Unfortunately I am not able to do that, this causing an overrun error next time I start reception again (since the conditions allow to do that), and I am a little stuck. I tried with something like__HAL_UART_DISABLE_IT(&UART_MOBILE_Handle, UART_IT_RXNE);
__HAL_UART_DISABLE_IT(&UART_MOBILE_Handle, UART_IT_PE);
__HAL_UART_DISABLE_IT(&UART_MOBILE_Handle, UART_IT_ERR);
but it seems not working.
Does anybody have any suggestion?
Thank you and regards.
2016-06-13 08:22 AM
Turning off the RXNE isn't going to stop the sending device sending data, nor the USART from trying to receive it. For that consider flow-control, ie CTS/RTS or DTR/DSR type implementations.
The USART RE (Receive Enable) is part of control register, this would stop the USART from attempting to receive data, but might result in framing or loss of data issues if the sending side isn't cooperating.2016-06-13 11:39 PM
Thank you Clive for your advise. Actually I can't use a flow control mechanism because of the board I am working on: no RTS/CTS or DTR/DSR lines have been used to connect the module with the micro, and clearly I can't change it :).
However to be more precise I have implemented a mechanism like
.
.
.
SIM3560E_IO_Read_IT(&mobileRxSingle, 1);
currentTick = osKernelSysTick();
while
(osKernelSysTick() - currentTick < LFTIMEOUT)
{
if
(mobileRxReady != SET)
currentTick = osKernelSysTick();
}
mobileRxReady = RESET;
StopReceive_IT();
.
.
.
where
osKernelSysTick()
belongs to the RTOS HAL middleware and is similar to HAL_GetTick(). The reception callback is
void
mobileReceiveCallback(UART_HandleTypeDef *huart)
{
ringBufferPushSingle(&mobileRxBuffer, mobileRxSingle);
SIM3560E_IO_Read_IT(&mobileRxSingle, 1);
if
(mobileRxSingle ==
'
'
)
mobileRxReady = SET;
}
Everytime a
is received
currentTick
is reset and the while loop keeps going on. If a is receivedcurrentTick
is not reset and if the module doesn't throw any other char withinLFTIMEOUT,
then the while loop is exited and I need to stop reception (clearly I need a global timeout to avoid waiting forever if the module is not replying anything). I have not came up with any other mechanism to do that with interrupts (the problem is that reception is retriggered everytime the callback is reentered): this modulethrows strings terminating with BUT several might be put within a string, so the only way it seems to me I can do to identify an end string is with a timeout. Maybe a reception with polling would be a better way but I wanted to investigate the implementation with interrupts.