mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-11 15:22:13 +03:00
Function added to detect baudrate (#4978)
* Function added to detect baudrate * Added uart_start_detect_baudrate, detectBaudrate() wrappers for HardwareSerial and an example usage SerialDetectBaudrate.ino * Some layout changes to pass Travis tests * Some more nitty-gritty layout changes to pass Travis tests * Some even more nitty-gritty layout changes to pass Travis tests * renamed one function to testBaudrate() and updated doc/reference.rst * Minor updates to doc/reference.rst * New lines added
This commit is contained in:
@ -108,6 +108,30 @@ void HardwareSerial::flush()
|
||||
delayMicroseconds(11000000 / uart_get_baudrate(_uart) + 1);
|
||||
}
|
||||
|
||||
void HardwareSerial::startDetectBaudrate()
|
||||
{
|
||||
uart_start_detect_baudrate(_uart_nr);
|
||||
}
|
||||
|
||||
unsigned long HardwareSerial::testBaudrate()
|
||||
{
|
||||
return uart_detect_baudrate(_uart_nr);
|
||||
}
|
||||
|
||||
unsigned long HardwareSerial::detectBaudrate(time_t timeoutMillis)
|
||||
{
|
||||
time_t startMillis = millis();
|
||||
unsigned long detectedBaudrate;
|
||||
while ((time_t) millis() - startMillis < timeoutMillis) {
|
||||
if ((detectedBaudrate = testBaudrate())) {
|
||||
break;
|
||||
}
|
||||
yield();
|
||||
delay(100);
|
||||
}
|
||||
return detectedBaudrate;
|
||||
}
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
HardwareSerial Serial(UART0);
|
||||
#endif
|
||||
|
@ -184,6 +184,12 @@ public:
|
||||
return uart_has_overrun(_uart);
|
||||
}
|
||||
|
||||
void startDetectBaudrate();
|
||||
|
||||
unsigned long testBaudrate();
|
||||
|
||||
unsigned long detectBaudrate(time_t timeoutMillis);
|
||||
|
||||
protected:
|
||||
int _uart_nr;
|
||||
uart_t* _uart = nullptr;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "uart.h"
|
||||
#include "esp8266_peri.h"
|
||||
#include "user_interface.h"
|
||||
#include "uart_register.h"
|
||||
|
||||
const char overrun_str [] ICACHE_RODATA_ATTR STORE_ATTR = "uart input full!\r\n";
|
||||
static int s_uart_debug_nr = UART0;
|
||||
@ -739,3 +740,49 @@ uart_get_debug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
|
||||
/*
|
||||
To start detection of baud rate with the UART the UART_AUTOBAUD_EN bit needs to be cleared and set. The ROM function uart_baudrate_detect() does this only once, so on a next call the UartDev.rcv_state is not equal to BAUD_RATE_DET. Instead of poking around in the UartDev struct with unknown effect, the UART_AUTOBAUD_EN bit is directly triggered by the function uart_detect_baudrate().
|
||||
*/
|
||||
void
|
||||
uart_start_detect_baudrate(int uart_nr)
|
||||
{
|
||||
USA(uart_nr) &= ~(UART_GLITCH_FILT << UART_GLITCH_FILT_S | UART_AUTOBAUD_EN);
|
||||
USA(uart_nr) = 0x08 << UART_GLITCH_FILT_S | UART_AUTOBAUD_EN;
|
||||
}
|
||||
|
||||
int
|
||||
uart_detect_baudrate(int uart_nr)
|
||||
{
|
||||
static bool doTrigger = true;
|
||||
|
||||
if (doTrigger)
|
||||
{
|
||||
uart_start_detect_baudrate(uart_nr);
|
||||
doTrigger = false;
|
||||
}
|
||||
|
||||
int32_t divisor = uart_baudrate_detect(uart_nr, 1);
|
||||
if (!divisor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
doTrigger = true; // Initialize for a next round
|
||||
int32_t baudrate = UART_CLK_FREQ / divisor;
|
||||
|
||||
static const int 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];
|
||||
}
|
||||
|
@ -141,6 +141,9 @@ bool uart_has_overrun (uart_t* uart); // returns then clear overrun flag
|
||||
void uart_set_debug(int uart_nr);
|
||||
int uart_get_debug();
|
||||
|
||||
void uart_start_detect_baudrate(int uart_nr);
|
||||
int uart_detect_baudrate(int uart_nr);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
} // extern "C"
|
||||
|
@ -155,6 +155,17 @@ current speed. For example
|
||||
| Note that this implementation is **only for ESP8266 based boards**,
|
||||
and will not works with other Arduino boards.
|
||||
|
||||
|
||||
To detect an unknown baudrate of data coming into Serial use ``Serial.detectBaudrate(time_t timeoutMillis)``. This method tries to detect the baudrate for a maximum of timeoutMillis ms. It returns zero if no baudrate was detected, or the detected baudrate otherwise. The ``detectBaudrate()`` function may be called before ``Serial.begin()`` is called, because it does not need the receive buffer nor the SerialConfig parameters.
|
||||
|
||||
The uart can not detect other parameters like number of start- or stopbits, number of data bits or parity.
|
||||
|
||||
The detection itself does not change the baudrate, after detection it should be set as usual using ``Serial.begin(detectedBaudrate)``.
|
||||
|
||||
Detection is very fast, it takes only a few incoming bytes.
|
||||
|
||||
SerialDetectBaudrate.ino is a full example of usage.
|
||||
|
||||
Progmem
|
||||
-------
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
#define TIMEOUT (10000UL) // Maximum time to wait for serial activity to start
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
// Serial.detectBaudrate() may also be called before Serial.begin()
|
||||
// There must be activity on the serial port for the baudrate to be detected
|
||||
unsigned long detectedBaudrate = Serial.detectBaudrate(TIMEOUT);
|
||||
|
||||
if (detectedBaudrate) {
|
||||
Serial.printf("\nDetected baudrate is %lu, switching to that baudrate now...\n", detectedBaudrate);
|
||||
|
||||
// Wait for printf to finish
|
||||
while (Serial.availableForWrite() != UART_TX_FIFO_SIZE) {
|
||||
yield();
|
||||
}
|
||||
|
||||
// Clear Tx buffer to avoid extra characters being printed
|
||||
Serial.flush();
|
||||
|
||||
// After this, any writing to Serial will print gibberish on the serial monitor if the baudrate doesn't match
|
||||
Serial.begin(detectedBaudrate);
|
||||
} else {
|
||||
Serial.println("\nNothing detected");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user