Unverified Commit 43b15f3d authored by Rodrigo Garcia's avatar Rodrigo Garcia Committed by GitHub

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"
parent 381d7efd
...@@ -406,7 +406,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in ...@@ -406,7 +406,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
if(detectedBaudRate) { if(detectedBaudRate) {
delay(100); // Give some time... delay(100); // Give some time...
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd); _uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
} else { #if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
// S3 and C3 have a limitation and both can't detect a baud rate lower than 9600
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.");
#endif
} else {
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible"); log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
_uart = NULL; _uart = NULL;
} }
......
...@@ -462,7 +462,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) ...@@ -462,7 +462,11 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
return; return;
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate)); uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate));
#else
uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate);
#endif
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
} }
...@@ -474,6 +478,12 @@ uint32_t uartGetBaudRate(uart_t* uart) ...@@ -474,6 +478,12 @@ uint32_t uartGetBaudRate(uart_t* uart)
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
uint32_t baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num)); uint32_t baud_rate = uart_ll_get_baudrate(UART_LL_GET_HW(uart->num));
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
uint32_t Freq = getApbFrequency()/1000000;
if (Freq < 80) {
baud_rate = baud_rate / (80 / Freq);
}
#endif
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
return baud_rate; return baud_rate;
} }
...@@ -630,32 +640,31 @@ void log_print_buf(const uint8_t *b, size_t len){ ...@@ -630,32 +640,31 @@ void log_print_buf(const uint8_t *b, size_t len){
/* /*
* if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two. * if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.
* In the case of S3 and C3 using XTAL as UART CLK SOURCE, one bit period = Negative Pulse Count + 1
* This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses. * 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) unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
{ {
// Baud rate detection only works for ESP32 and ESP32S2
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
if(uart == NULL) { if(uart == NULL) {
return 0; return 0;
} }
uart_dev_t *hw = UART_LL_GET_HW(uart->num); uart_dev_t *hw = UART_LL_GET_HW(uart->num);
while(hw->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num) while(uart_ll_get_rxd_edge_cnt(hw) < 30) { // UART_PULSE_NUM(uart_num)
if(flg) return 0; if(flg) return 0;
ets_delay_us(1000); ets_delay_us(1000);
} }
UART_MUTEX_LOCK(); UART_MUTEX_LOCK();
//log_i("lowpulse_min_cnt = %d hightpulse_min_cnt = %d", hw->lowpulse.min_cnt, hw->highpulse.min_cnt); #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
unsigned long ret = ((hw->lowpulse.min_cnt + hw->highpulse.min_cnt) >> 1); unsigned long ret = ((uart_ll_get_low_pulse_cnt(hw) + uart_ll_get_high_pulse_cnt(hw)) >> 1);
#else
unsigned long ret = uart_ll_get_neg_pulse_cnt(hw) + 1;
#endif
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
return ret; return ret;
#else
return 0;
#endif
} }
...@@ -664,61 +673,23 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg) ...@@ -664,61 +673,23 @@ unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is * detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
* rounded to the closed real baudrate. * rounded to the closed real baudrate.
* *
* ESP32-C3 reports wrong baud rate detection as shown below:
*
* This will help in a future recall for the C3.
* Baud Sent: Baud Read:
* 300 --> 19536
* 2400 --> 19536
* 4800 --> 19536
* 9600 --> 28818
* 19200 --> 57678
* 38400 --> 115440
* 57600 --> 173535
* 115200 --> 347826
* 230400 --> 701754
*
*
*/ */
void uartStartDetectBaudrate(uart_t *uart) { void uartStartDetectBaudrate(uart_t *uart) {
if(uart == NULL) { if(uart == NULL) {
return; return;
} }
#ifdef CONFIG_IDF_TARGET_ESP32C3
// ESP32-C3 requires further testing
// Baud rate detection returns wrong values
log_e("ESP32-C3 baud rate detection is not supported.");
return;
// Code bellow for C3 kept for future recall
//hw->rx_filt.glitch_filt = 0x08;
//hw->rx_filt.glitch_filt_en = 1;
//hw->conf0.autobaud_en = 0;
//hw->conf0.autobaud_en = 1;
#elif CONFIG_IDF_TARGET_ESP32S3
log_e("ESP32-S3 baud rate detection is not supported.");
return;
#else
uart_dev_t *hw = UART_LL_GET_HW(uart->num); uart_dev_t *hw = UART_LL_GET_HW(uart->num);
hw->auto_baud.glitch_filt = 0x08; uart_ll_set_autobaud_en(hw, false);
hw->auto_baud.en = 0; uart_ll_set_autobaud_en(hw, true);
hw->auto_baud.en = 1;
#endif
} }
unsigned long unsigned long uartDetectBaudrate(uart_t *uart)
uartDetectBaudrate(uart_t *uart)
{ {
if(uart == NULL) { if(uart == NULL) {
return 0; return 0;
} }
// Baud rate detection only works for ESP32 and ESP32S2
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
static bool uartStateDetectingBaudrate = false; static bool uartStateDetectingBaudrate = false;
if(!uartStateDetectingBaudrate) { if(!uartStateDetectingBaudrate) {
...@@ -732,37 +703,27 @@ uartDetectBaudrate(uart_t *uart) ...@@ -732,37 +703,27 @@ uartDetectBaudrate(uart_t *uart)
} }
uart_dev_t *hw = UART_LL_GET_HW(uart->num); uart_dev_t *hw = UART_LL_GET_HW(uart->num);
hw->auto_baud.en = 0; uart_ll_set_autobaud_en(hw, false);
uartStateDetectingBaudrate = false; // Initialize for the next round uartStateDetectingBaudrate = false; // Initialize for the next round
unsigned long baudrate = getApbFrequency() / divisor;
//log_i("APB_FREQ = %d\nraw baudrate detected = %d", getApbFrequency(), baudrate); #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
unsigned long baudrate = getApbFrequency() / divisor; // ESP32 and S2 APB Freq
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400}; #else
unsigned long baudrate = (getXtalFrequencyMhz() * 1000000) / divisor; // S3 and C3 XTAL Frequency
#endif
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000,
256000, 460800, 500000, 921600, 1000000, 1843200, 2000000, 3686400};
size_t i; size_t i;
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate 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]) if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) i--;
{
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) {
i--;
}
break; break;
} }
} }
return default_rates[i]; return default_rates[i];
#else
#ifdef CONFIG_IDF_TARGET_ESP32C3
log_e("ESP32-C3 baud rate detection is not supported.");
#else
log_e("ESP32-S3 baud rate detection is not supported.");
#endif
return 0;
#endif
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment