-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Reason
HardwareSerial::end()
calls uart_deinit(serial_t *obj)
, and inside this function:
void uart_deinit(serial_t *obj)
{
/* Reset UART and disable clock */
switch (obj->index) {
#if defined(USART1_BASE)
case UART1_INDEX:
__HAL_RCC_USART1_FORCE_RESET();
__HAL_RCC_USART1_RELEASE_RESET();
__HAL_RCC_USART1_CLK_DISABLE();
break;
#endif
#if defined(USART2_BASE)
case UART2_INDEX:
__HAL_RCC_USART2_FORCE_RESET();
__HAL_RCC_USART2_RELEASE_RESET();
__HAL_RCC_USART2_CLK_DISABLE();
break;
#endif
...
HAL_UART_DeInit(uart_handlers[obj->index]);
...
}
It finds corresponding uart peripheral by obj->index
, which is always 0 before begin()
is called. And UART1_INDEX == 0
, so it always deinit Serial1 if HardSerial::end()
is called before begin()
.
Consequence
When Serial1 is deinit-ed, tx interrupt of USART1 will not be enabled, and any data in tx buffer will not be sent, causing mcu dead locked in flush()
or availableForWrite()
.
This problem is quite confusing. I think it is a bit hard to debug when someone encounters it. Maybe it' s better to make sure that calling end()
does not cause any side effects.
By the way
My program needs to modifiy baudrate randomly after setup, so I wrote:
void config_baudrate() {
u16 b = _reg[REG_INDEX_BAUD];
u32 baud;
if (b > sizeof(BAUD_LIST) / sizeof(BAUD_LIST[0])) {
baud = 9600;
}
else {
baud = BAUD_LIST[b];
}
Serial485.end();
Serial485.begin(baud);
}
Serial485
is alias to Serial3
. Everything was ok before I started to use Serial1. Any better approach?
Reproduce
These code should be able to reproduce the problem:
#include <Arduino.h>
HardwareSerial Serial1{PA10, PA9};
HardwareSerial Serial3{PB11, PB10};
void setup() {
Serial1.begin(9600);
Serial3.end();
Serial3.begin(9600);
Serial1.print("I'm stuck");
Serial1.flush();
}
void loop() {}
Solution
Just leave uart_handlers[0]
as a placeholder, so as uart_handlers[0] == nullptr
. This solution only cost little RAM.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status