diff --git a/README.md b/README.md index ef7a9dad..31015c24 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,9 @@ editing `BIT_RATE_DEFAULT` in `app/include/user_config.h`: #define BIT_RATE_DEFAULT BIT_RATE_115200 ``` +Note that, by default, the firmware runs an auto-baudrate detection algorithm so that typing a few characters at boot time will cause +the firmware to lock onto that baud rate (between 1200 and 230400). + ### Debugging To enable runtime debug messages to serial console edit `app/include/user_config.h` diff --git a/app/driver/uart.c b/app/driver/uart.c index f70c4f44..d086c236 100755 --- a/app/driver/uart.c +++ b/app/driver/uart.c @@ -15,6 +15,7 @@ #include "task/task.h" #include "user_config.h" #include "user_interface.h" +#include "osapi.h" #define UART0 0 #define UART1 1 @@ -33,6 +34,8 @@ static task_handle_t sig = 0; // UartDev is defined and initialized in rom code. extern UartDevice UartDev; +static os_timer_t autobaud_timer; + LOCAL void ICACHE_RAM_ATTR uart0_rx_intr_handler(void *para); @@ -271,6 +274,36 @@ uart0_rx_intr_handler(void *para) task_post_low (sig, false); } +static void +uart_autobaud_timeout(void *timer_arg) +{ + uint32_t uart_no = (uint32_t) timer_arg; + uint32_t divisor = uart_baudrate_detect(uart_no, 1); + static int called_count = 0; + + // Shut off after two minutes to stop wasting CPU cycles if insufficient input received + if (called_count++ > 10 * 60 * 2 || divisor) { + os_timer_disarm(&autobaud_timer); + } + + if (divisor) { + uart_div_modify(uart_no, divisor); + } +} + +static void +uart_init_autobaud(uint32_t uart_no) +{ + os_timer_setfn(&autobaud_timer, uart_autobaud_timeout, (void *) uart_no); + os_timer_arm(&autobaud_timer, 100, TRUE); +} + +static void +uart_stop_autobaud() +{ + os_timer_disarm(&autobaud_timer); +} + /****************************************************************************** * FunctionName : uart_init * Description : user interface for init uart @@ -291,11 +324,17 @@ uart_init(UartBautRate uart0_br, UartBautRate uart1_br, os_signal_t sig_input) UartDev.baut_rate = uart1_br; uart_config(UART1); ETS_UART_INTR_ENABLE(); +#ifdef BIT_RATE_AUTOBAUD + uart_init_autobaud(0); +#endif } void ICACHE_FLASH_ATTR uart_setup(uint8 uart_no) { +#ifdef BIT_RATE_AUTOBAUD + uart_stop_autobaud(); +#endif ETS_UART_INTR_DISABLE(); uart_config(uart_no); ETS_UART_INTR_ENABLE(); diff --git a/app/include/user_config.h b/app/include/user_config.h index 5a865fd3..5f04a616 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -34,10 +34,12 @@ extern void luaL_assertfail(const char *file, int line, const char *message); #ifdef DEVELOP_VERSION #define NODE_DEBUG #define COAP_DEBUG -#else -#define BIT_RATE_DEFAULT BIT_RATE_115200 #endif /* DEVELOP_VERSION */ +#define BIT_RATE_DEFAULT BIT_RATE_115200 + +// This enables automatic baud rate detection at startup +#define BIT_RATE_AUTOBAUD #define NODE_ERROR diff --git a/docs/en/modules/uart.md b/docs/en/modules/uart.md index 2d5d6806..2c449b73 100644 --- a/docs/en/modules/uart.md +++ b/docs/en/modules/uart.md @@ -5,6 +5,8 @@ The [UART](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter) (Universal asynchronous receiver/transmitter) module allows configuration of and communication over the UART serial port. +The default setup for the uart is controlled by build-time settings. The default rate is 115,200 bps. In addition, auto-baudrate detection is enabled for the first two minutes +after platform boot. This will cause a switch to the correct baud rate once a few characters are received. Auto-baudrate detection is disabled when `uart.setup` is called. ## uart.alt() Change UART pin assignment. diff --git a/sdk-overrides/include/osapi.h b/sdk-overrides/include/osapi.h index 2b98729e..9253e581 100644 --- a/sdk-overrides/include/osapi.h +++ b/sdk-overrides/include/osapi.h @@ -8,6 +8,8 @@ int atoi(const char *nptr); int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); int os_printf_plus(const char *format, ...) __attribute__ ((format (printf, 1, 2))); +unsigned int uart_baudrate_detect(unsigned int uart_no, unsigned int async); + void NmiTimSetFunc(void (*func)(void)); #include_next "osapi.h"