Added baudrate detection to esp32-hal-uart and HardwareSerial (#1961)
* Added baudrate detection to esp32-hal-uart and HardwareSerial * Solved compiler warning for uartResizeRxBuffer() * Add unit to header variable name (timeout_ms) * Reverting accidentally changed files to master * Add small delay after baudrate detection
This commit is contained in:
parent
65c861ad4c
commit
233d31bed2
@ -30,7 +30,7 @@ HardwareSerial Serial2(2);
|
|||||||
|
|
||||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
|
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
|
||||||
|
|
||||||
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert)
|
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms)
|
||||||
{
|
{
|
||||||
if(0 > _uart_nr || _uart_nr > 2) {
|
if(0 > _uart_nr || _uart_nr > 2) {
|
||||||
log_e("Serial number is invalid, please use 0, 1 or 2");
|
log_e("Serial number is invalid, please use 0, 1 or 2");
|
||||||
@ -51,7 +51,26 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
|||||||
rxPin = RX2;
|
rxPin = RX2;
|
||||||
txPin = TX2;
|
txPin = TX2;
|
||||||
}
|
}
|
||||||
_uart = uartBegin(_uart_nr, baud, config, rxPin, txPin, 256, invert);
|
|
||||||
|
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
|
||||||
|
|
||||||
|
if(!baud) {
|
||||||
|
time_t startMillis = millis();
|
||||||
|
unsigned long detectedBaudRate;
|
||||||
|
while(millis() - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
end();
|
||||||
|
|
||||||
|
if(detectedBaudRate) {
|
||||||
|
delay(100); // Give some time...
|
||||||
|
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert);
|
||||||
|
} else {
|
||||||
|
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
|
||||||
|
_uart = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HardwareSerial::end()
|
void HardwareSerial::end()
|
||||||
|
@ -22,6 +22,24 @@
|
|||||||
Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support)
|
Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support)
|
||||||
Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
|
Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
|
||||||
Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
|
Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
|
||||||
|
Modified 13 October 2018 by Jeroen Döll (add baudrate detection)
|
||||||
|
Baudrate detection example usage (detection on Serial1):
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(100);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL); // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms
|
||||||
|
|
||||||
|
unsigned long detectedBaudRate = Serial1.baudRate();
|
||||||
|
if(detectedBaudRate) {
|
||||||
|
Serial.printf("Detected baudrate is %lu\n", detectedBaudRate);
|
||||||
|
} else {
|
||||||
|
Serial.println("No baudrate detected, Serial1 will not work!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pay attention: the baudrate returned by baudRate() may be rounded, eg 115200 returns 115201
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HardwareSerial_h
|
#ifndef HardwareSerial_h
|
||||||
@ -37,7 +55,7 @@ class HardwareSerial: public Stream
|
|||||||
public:
|
public:
|
||||||
HardwareSerial(int uart_nr);
|
HardwareSerial(int uart_nr);
|
||||||
|
|
||||||
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false);
|
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL);
|
||||||
void end();
|
void end();
|
||||||
int available(void);
|
int available(void);
|
||||||
int availableForWrite(void);
|
int availableForWrite(void);
|
||||||
|
@ -242,7 +242,7 @@ void uartEnd(uart_t* uart)
|
|||||||
|
|
||||||
size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
|
size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
|
||||||
if(uart == NULL) {
|
if(uart == NULL) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UART_MUTEX_LOCK();
|
UART_MUTEX_LOCK();
|
||||||
@ -455,3 +455,65 @@ int log_printf(const char *format, ...)
|
|||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.
|
||||||
|
* This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses.
|
||||||
|
*/
|
||||||
|
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||||
|
{
|
||||||
|
while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num)
|
||||||
|
if(flg) return 0;
|
||||||
|
ets_delay_us(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
UART_MUTEX_LOCK();
|
||||||
|
unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12;
|
||||||
|
UART_MUTEX_UNLOCK();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To start detection of baud rate with the uart the auto_baud.en bit needs to be cleared and set. The bit period is
|
||||||
|
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
|
||||||
|
* rounded to the closed real baudrate.
|
||||||
|
*/
|
||||||
|
unsigned long
|
||||||
|
uartDetectBaudrate(uart_t *uart)
|
||||||
|
{
|
||||||
|
static bool uartStateDetectingBaudrate = false;
|
||||||
|
|
||||||
|
if(!uartStateDetectingBaudrate) {
|
||||||
|
uart->dev->auto_baud.glitch_filt = 0x08;
|
||||||
|
uart->dev->auto_baud.en = 0;
|
||||||
|
uart->dev->auto_baud.en = 1;
|
||||||
|
uartStateDetectingBaudrate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long divisor = uartBaudrateDetect(uart, true);
|
||||||
|
if (!divisor) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uart->dev->auto_baud.en = 0;
|
||||||
|
uartStateDetectingBaudrate = false; // Initialize for the next round
|
||||||
|
|
||||||
|
unsigned long baudrate = UART_CLK_FREQ / divisor;
|
||||||
|
|
||||||
|
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400};
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate
|
||||||
|
{
|
||||||
|
if (baudrate <= default_rates[i])
|
||||||
|
{
|
||||||
|
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) {
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return default_rates[i];
|
||||||
|
}
|
||||||
|
@ -72,6 +72,8 @@ size_t uartResizeRxBuffer(uart_t* uart, size_t new_size);
|
|||||||
void uartSetDebug(uart_t* uart);
|
void uartSetDebug(uart_t* uart);
|
||||||
int uartGetDebug();
|
int uartGetDebug();
|
||||||
|
|
||||||
|
unsigned long uartDetectBaudrate(uart_t *uart);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user