Skip to content

Commit 43b15f3

Browse files
authored
feat: adds baudrate detection to S3 and C3 using LL API for all SoC (#9261)
* feat: adds baudrate detection to S3 and C3 using LL API for all SoC * feat: adds the baud rate detection feature to ESP32-S3 and ESP32-C3 * Fix: fixes uartSetBaudrate() for ESP32-S3 and ESP32-C3 considering XTAL as Clock Source * fix: Fixes ESP32 and ESP32-S2 uartGetBaudrate() with CPU Freq lower than 80MHz * Feat: prints a warning message for detected baud rate under 9600 - S3 C3 only * Fix: removes commentary about baud rate detection - "works for ESP32/S2 only"
1 parent 381d7ef commit 43b15f3

File tree

2 files changed

+37
-72
lines changed

2 files changed

+37
-72
lines changed

Diff for: cores/esp32/HardwareSerial.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
406406
if(detectedBaudRate) {
407407
delay(100); // Give some time...
408408
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
409-
} else {
409+
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
410+
// S3 and C3 have a limitation and both can't detect a baud rate lower than 9600
411+
if (detectedBaudRate == 9600) log_w("The baud detected, as 9600, may be wrong. ESP32-C3 and ESP32-S3 can't detect a baud rate under 9600.");
412+
#endif
413+
} else {
410414
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
411415
_uart = NULL;
412416
}

Diff for: cores/esp32/esp32-hal-uart.c

+32-71
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
462462
return;
463463
}
464464
UART_MUTEX_LOCK();
465+
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
465466
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate));
467+
#else
468+
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate);
469+
#endif
466470
UART_MUTEX_UNLOCK();
467471
}
468472

@@ -474,6 +478,12 @@ uint32_t uartGetBaudRate(uart_t* uart)
474478

475479
UART_MUTEX_LOCK();
476480
uint32_t baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num));
481+
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
482+
uint32_t Freq = getApbFrequency()/1000000;
483+
if (Freq < 80) {
484+
baud_rate = baud_rate / (80 / Freq);
485+
}
486+
#endif
477487
UART_MUTEX_UNLOCK();
478488
return baud_rate;
479489
}
@@ -630,32 +640,31 @@ void log_print_buf(const uint8_t *b, size_t len){
630640

631641
/*
632642
* if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.
643+
* In the case of S3 and C3 using XTAL as UART CLK SOURCE, one bit period = Negative Pulse Count + 1
633644
* This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses.
634645
*/
635646
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
636647
{
637-
// Baud rate detection only works for ESP32 and ESP32S2
638-
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
639648
if(uart == NULL) {
640649
return 0;
641650
}
642651

643652
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
644653

645-
while(hw->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num)
654+
while(uart_ll_get_rxd_edge_cnt(hw) < 30) { // UART_PULSE_NUM(uart_num)
646655
if(flg) return 0;
647656
ets_delay_us(1000);
648657
}
649658

650659
UART_MUTEX_LOCK();
651-
//log_i("lowpulse_min_cnt = %d hightpulse_min_cnt = %d", hw->lowpulse.min_cnt, hw->highpulse.min_cnt);
652-
unsigned long ret = ((hw->lowpulse.min_cnt + hw->highpulse.min_cnt) >> 1);
660+
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
661+
unsigned long ret = ((uart_ll_get_low_pulse_cnt(hw) + uart_ll_get_high_pulse_cnt(hw)) >> 1);
662+
#else
663+
unsigned long ret = uart_ll_get_neg_pulse_cnt(hw) + 1;
664+
#endif
653665
UART_MUTEX_UNLOCK();
654666

655667
return ret;
656-
#else
657-
return 0;
658-
#endif
659668
}
660669

661670

@@ -664,61 +673,23 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
664673
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
665674
* rounded to the closed real baudrate.
666675
*
667-
* ESP32-C3 reports wrong baud rate detection as shown below:
668-
*
669-
* This will help in a future recall for the C3.
670-
* Baud Sent: Baud Read:
671-
* 300 --> 19536
672-
* 2400 --> 19536
673-
* 4800 --> 19536
674-
* 9600 --> 28818
675-
* 19200 --> 57678
676-
* 38400 --> 115440
677-
* 57600 --> 173535
678-
* 115200 --> 347826
679-
* 230400 --> 701754
680-
*
681-
*
682676
*/
683677
void uartStartDetectBaudrate(uart_t *uart) {
684678
if(uart == NULL) {
685679
return;
686680
}
687681

688-
#ifdef CONFIG_IDF_TARGET_ESP32C3
689-
690-
// ESP32-C3 requires further testing
691-
// Baud rate detection returns wrong values
692-
693-
log_e("ESP32-C3 baud rate detection is not supported.");
694-
return;
695-
696-
// Code bellow for C3 kept for future recall
697-
//hw->rx_filt.glitch_filt = 0x08;
698-
//hw->rx_filt.glitch_filt_en = 1;
699-
//hw->conf0.autobaud_en = 0;
700-
//hw->conf0.autobaud_en = 1;
701-
#elif CONFIG_IDF_TARGET_ESP32S3
702-
log_e("ESP32-S3 baud rate detection is not supported.");
703-
return;
704-
#else
705682
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
706-
hw->auto_baud.glitch_filt = 0x08;
707-
hw->auto_baud.en = 0;
708-
hw->auto_baud.en = 1;
709-
#endif
683+
uart_ll_set_autobaud_en(hw, false);
684+
uart_ll_set_autobaud_en(hw, true);
710685
}
711686

712-
unsigned long
713-
uartDetectBaudrate(uart_t *uart)
687+
unsigned long uartDetectBaudrate(uart_t *uart)
714688
{
715689
if(uart == NULL) {
716690
return 0;
717691
}
718692

719-
// Baud rate detection only works for ESP32 and ESP32S2
720-
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
721-
722693
static bool uartStateDetectingBaudrate = false;
723694

724695
if(!uartStateDetectingBaudrate) {
@@ -732,37 +703,27 @@ uartDetectBaudrate(uart_t *uart)
732703
}
733704

734705
uart_dev_t *hw = UART_LL_GET_HW(uart->num);
735-
hw->auto_baud.en = 0;
706+
uart_ll_set_autobaud_en(hw, false);
736707

737708
uartStateDetectingBaudrate = false; // Initialize for the next round
738-
739-
unsigned long baudrate = getApbFrequency() / divisor;
740709

741-
//log_i("APB_FREQ = %d\nraw baudrate detected = %d", getApbFrequency(), baudrate);
742-
743-
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400};
744-
710+
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
711+
unsigned long baudrate = getApbFrequency() / divisor; // ESP32 and S2 APB Freq
712+
#else
713+
unsigned long baudrate = (getXtalFrequencyMhz() * 1000000) / divisor; // S3 and C3 XTAL Frequency
714+
#endif
715+
716+
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000,
717+
256000, 460800, 500000, 921600, 1000000, 1843200, 2000000, 3686400};
745718
size_t i;
746-
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate
747-
{
748-
if (baudrate <= default_rates[i])
749-
{
750-
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) {
751-
i--;
752-
}
719+
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) { // find the nearest real baudrate
720+
if (baudrate <= default_rates[i]) {
721+
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) i--;
753722
break;
754723
}
755724
}
756725

757726
return default_rates[i];
758-
#else
759-
#ifdef CONFIG_IDF_TARGET_ESP32C3
760-
log_e("ESP32-C3 baud rate detection is not supported.");
761-
#else
762-
log_e("ESP32-S3 baud rate detection is not supported.");
763-
#endif
764-
return 0;
765-
#endif
766727
}
767728

768729
/*

0 commit comments

Comments
 (0)