-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(esp32-s3): Add support for auto-baudrate-detection on S3 #7782
Conversation
|
@imwhocodes - Please check the CLA and if you agree, please sign it. |
@SuGlider I accepted multiple times the CLA, if i click on the link it say ' Edit: OK I pushed my first commit from a pc with the author/email configured wrongly |
I'm sorry, but it seems that CI won't let it pass because of commit 16ade7e Please close this PR and open a new one with a single commit from you valid GH user ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry but this PR doesn't work for ESP32-S3. Neither for the ESP32-C3.
The baud rate detection only works for the ESP32 and ESP32-S2
This is the sketch I have used to test it:
// This sketch works correctly with ESP32 and ESP32S2 only, so far.
// ESP32C3 and ESP32S3 seems to fail with baud rate detection
void setup() {
Serial.begin(115200);
Serial.println("\nTesting baud rate detection\n");
}
void loop() {
Serial.println("Started detection for next 20 seconds.");
Serial.println("Use the Serial Monitor. Change the baud rate in the botton of the window.");
Serial.println("Send characters using the Serial Monitor and get the detected baud rate.");
Serial.flush();
Serial.begin(0);
unsigned long detectedBaudRate = Serial.baudRate();
if (detectedBaudRate) {
Serial.printf("\nDetected baudrate is %lu\n\n", detectedBaudRate);
} else {
// this may not display correctly in the Serial Monitor, given that it failed.
Serial.println("\nNo baudrate detected, Serial will not work!\n\n");
}
}
@VojtechBartoska @me-no-dev |
@SuGlider I don't have a chip at hands right now, as I said in the issue I have this code running on production and I can confirm it working, as I said heavily tested on ESP32-WROOM-32UE and ESP32-S3-WROOM-1U-N8 at both 115200 and 460800 (other baudrates tested but not in production) Two things:
Let me know |
It works correctly for any baud rate on the ESP32-WROOM-32, but not on the ESP32-S3-WROOM.
I tried changing the number of bits read and other parameters with no success - using the S3.
I always tested the baud detection using UART. @imwhocodes - If you have a working sketch that demonstrates this PR working correctly for any baud rate, please post it here with instructions on how to replicate the test case. I'll happily try it again. |
@SuGlider I asked about I will try your sketch and explore the the influence of the length of consecutive bytes Also I check and in my code the operations that I do are:
(I'm not using |
Ok. Please provide an Arduino example code that I can test here. from https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/HardwareSerial.h#L25-L42 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 |
This PR must work using only Arduino API from |
@SuGlider I run some test yesterday and indeed your example don't work Something strange is happening, if you call What I'm doing on my prod codebase is adding this function to unsigned long HardwareSerial::detectBaudRate(const unsigned long timeout_ms) //timeout 0 for infinite timeout
{
uartStartDetectBaudrate(_uart);
unsigned long detectedBaudRate = 0;
unsigned long start_detection = millis();
while( ( ( ( millis() - start_detection ) < timeout_ms ) || timeout_ms == 0 ) && ( !( detectedBaudRate = uartDetectBaudrate(_uart) ) ) ){
delay(1);
};
return detectedBaudRate;
} And the with: #include <Arduino.h>
void setup() {
Serial.begin(230400);
Serial.println("\nTesting baud rate detection\n");
}
void loop() {
Serial.println("Started detection for next 20 seconds.");
Serial.println("Use the Serial Monitor. Change the baud rate in the botton of the window.");
Serial.println("Send characters using the Serial Monitor and get the detected baud rate.");
Serial.flush();
unsigned long detectedBaudRate = Serial.detectBaudRate(20000);
// unsigned long detectedBaudRate = Serial.baudRate();
if (detectedBaudRate) {
Serial.updateBaudRate(detectedBaudRate);
Serial.printf("\nDetected baudrate is %lu\n\n", detectedBaudRate);
} else {
// Serial.updateBaudRate(115200);
// this may not display correctly in the Serial Monitor, given that it failed.
Serial.println("\nNo baudrate detected, Serial will not work!\n\n");
}
} And baud rate is correctly detected Strange thing is that it keep detecting (seem like hardware register with values for detection are not cleared) |
e828e74
to
45ce2d0
Compare
👋 Hello imwhocodes, we appreciate your contribution to this project! Click to see more instructions ...
Review and merge process you can expect ...
|
Is the auto detection working now and if yes for all speeds too? |
It should, I wanted to write before but i didn't had time yet |
45ce2d0
to
3628ff8
Compare
… of Esp32, with different clock support
3628ff8
to
302f676
Compare
Master branch do not compile (on platformIO) so I based my test on top of v2.0.14 Next week I will clean up the code and do more tests (now it work but btw) Here is a code snippet that I used to test the auto-baud function (and connecting TX of Serial1 to RX of Serial2): #define NO_GLOBAL_SERIAL
#include <Arduino.h>
HardwareSerial log_stream = HardwareSerial(0);
HardwareSerial snd_serial = HardwareSerial{1};
HardwareSerial rcv_serial = HardwareSerial{2};
static const unsigned long default_rates[] = {
0, // TEST FOR FALSE POSITIVE
// 600, // THIS FAIL, PULSE COUNTER IS LIMITED AT 4095
// 1200, // THIS FAIL, PULSE COUNTER IS LIMITED AT 4095
// 2400, // THIS FAIL, PULSE COUNTER IS LIMITED AT 4095
4800,
9600,
19200,
38400,
57600,
74880,
115200,
230400,
256000,
460800,
921600,
1843200,
// 3686400 // THIS ALWAYS FAIL, Need investigation
};
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
TaskHandle_t parse_task;
TaskHandle_t send_task;
void sendTask(void *pvParameters){
while(true){
log_stream.println("\n\n\n");
const auto & rate = default_rates[random(0, ARRAY_SIZE(default_rates) - 1)];
if(rate){
log_stream.printf("SND opening with: %d bauds\n", rate);
snd_serial.begin(rate, SERIAL_8N1, 0, 1, false);
xTaskNotify(parse_task, rate, eSetValueWithOverwrite);
const size_t qty = random(128, 1024);
log_stream.printf("SND will send: %d bytes\n", qty);
for(size_t i = 0; i < qty; i++){
const uint8_t b = random();
snd_serial.write(b);
}
snd_serial.flush();
log_stream.println("SND Finished");
}
else{
log_stream.println("SND Not Opening");
xTaskNotify(parse_task, rate, eSetValueWithOverwrite);
}
uint32_t rcv_rate;
xTaskNotifyWait(0, 0, &rcv_rate, portMAX_DELAY);
delay(1000);
}
}
void parseTask(void *pvParameters){
while(true){
uint32_t should_be;
xTaskNotifyWait(0, 0, &should_be, portMAX_DELAY);
rcv_serial.begin(0, SERIAL_8N1, 45, 46, false, 5000);
const auto detected_rate = rcv_serial.baudRate();
if(should_be){
if(detected_rate){
const float_t min = should_be * 0.9;
const float_t max = should_be * 1.1;
const bool valid = ( detected_rate > min ) && ( detected_rate < max );
if(valid){
log_stream.printf("RCV SUCCESS!\t%d\tis\t%d\n", detected_rate, should_be);;
xTaskNotify(send_task, detected_rate, eSetValueWithOverwrite);
}
else{
log_stream.printf("RCV FAIL\t%d\tis not\t%d\n", detected_rate, should_be);
}
}
else{
log_stream.println("RCV FAILED DETECTION!!!");
}
}
else{
log_stream.println("RCV SUCCESS! (nothing was send)");
xTaskNotify(send_task, detected_rate, eSetValueWithOverwrite);
}
}
}
void setup() {
log_stream.begin(921600);
delay(100);
while (!log_stream)
{
delay(100);
}
log_stream.setDebugOutput(true);
log_i("!INIT!");
log_i("Connected!");
assert( pdPASS ==
xTaskCreatePinnedToCore(
sendTask, /* Function to implement the task */
"sendTask", /* Name of the task */
1024 * 4, /* Stack size in bytes */
NULL, /* Task input parameter */
5, /* Priority of the task */
&send_task, /* Task handle. */
PRO_CPU_NUM /* Core where the task should run */
)
);
assert( pdPASS ==
xTaskCreatePinnedToCore(
parseTask, /* Function to implement the task */
"parseTask", /* Name of the task */
1024 * 4, /* Stack size in bytes */
NULL, /* Task input parameter */
5, /* Priority of the task */
&parse_task, /* Task handle. */
APP_CPU_NUM /* Core where the task should run */
)
);
log_e("Task Created:\t%d", millis());
}
void loop() {
vTaskDelete(NULL);
} |
About the detection of seem like there is something broken on the original rounding algorithm As you can see from this log:
2222222 get rounded to 3686400 even if:
|
@imwhocodes Your work is really appreciated in the sad state of affair of Espressif S3/C3 autobauding. A finalized PR welcomed, can validate on all ESP32 MCU if still needed. BTW "Git Squash" welcomed ;) |
@imwhocodes - I think that it will be necessary to rebase this PR. |
I will rebase the commit, it is not ready to be merged anyway (currently is rebased on v2.0.14) My platformio.ini is:
|
@imwhocodes You can use branch master with Platformio using this PR platformio/platform-espressif32#1281 |
@imwhocodes - This PR should be use I have run exaustive testing and also I have checked ESP32-S3 and ESP32-C3 datasheet and TRM.
In order to get the Negative Pulse Count, the code shall use additional note:I found a couple issues when the APB Freq is lower than 80MHz - ESP32 and ESP32-S2. Please check PR #9261 - This works for 2.0.14 |
Closing this in favor of #9261. If you find a solution for 3.0.0, please open a new PR. |
Add support for auto-baudrate-detection on S3 variant of esp32, with different clock support (could be extended to C3 variant)
Description of Change
Add support (fix
hal
wrapper) for auto-baudrate-detection to the esp32-S3Currently there was no support for it and correct codepath was missing (and not even hinting to the missing support like done for the C3)
Added
#ifdef
for enabling the baudrate detection hardwareAdded codepath for correctly computing baudrate given the clock source used for the uart hardware block
Tests scenarios
I have tested my Pull Request on Arduino-esp32 core master with ESP32-S3 Boards
Related links
Close #7718
Progress https://github.com/orgs/espressif/projects/3/views/15?pane=issue&itemId=19207281
Note about calculations and ESP32-C3
I cannot test because i have no board with this chip (esp32-C3) but I'm supposing that the same code could be used also for fixing this:
arduino-esp32/cores/esp32/esp32-hal-uart.c
Lines 670 to 674 in 23d715a
In particular S3 and C3 variant support other clock sources other than APB and they are in fact defaulted to XTAL clock as source by Arduino, so the previous problem could be by this line not tacking that in account:
arduino-esp32/cores/esp32/esp32-hal-uart.c
Line 725 in 23d715a