espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.28k stars 7.35k forks source link

ESP32-C6: light sleep causes changes in Serial baud rate when CPU < 80MHz #10065

Closed oseiler2 closed 1 month ago

oseiler2 commented 1 month ago

Board

esp32-c6-devkitc-1

Device Description

ESP32-C6-DevKitC-1 V1.2

Also occurs on another custom ESP32-C6 board (ESP32-C6-WROOM-1-N8CT-ND)

Hardware Configuration

Nothing else connected.

Version

v3.0.3

IDE Name

PlatformIO

Operating System

Win10

Flash frequency

80

PSRAM enabled

no

Upload speed

460800

Description

When waking up from light sleep, the UART0 (serial) baud rate changes from configured 115200 to about 105000 if the CPU clock is running slower than 80MHz (eg 40 MHz). No issues at 80 or 160MHz CPU clk.

Re-initialising the serial after wake up does not fix the issue.

When I change the baud rate after wake up to 126390 (~115200/105000*115200), it sends at about the desired 115200 baud (confirmed with scope).

I've had a look at https://github.com/espressif/arduino-esp32/issues/8122#issuecomment-1524381223 When I edit esp32-hal-uart.c and change UART_SCLK_DEFAULT to SOC_MOD_CLK_XTAL the problem goes away, and the UART remains at 115200 after light sleep.

Sketch attached: ESP32-C6 light sleep minimal.zip

Sketch

#include <Arduino.h>

void setup() {
  delay(500);

  Serial.begin(115200);
  Serial.println("Begin");
  Serial.printf("Current Clock: %u MHz\n", getCpuFrequencyMhz());
  setCpuFrequencyMhz(40);
  Serial.printf("Current Clock: %u MHz\n", getCpuFrequencyMhz());
  Serial.println("Setup done.");
}

unsigned long lastSleep = 0;

void loop() {
  if (millis() - lastSleep > 10000) {
    lastSleep = millis();

    Serial.println("preparing for light sleep...");

    int result = esp_sleep_enable_timer_wakeup((uint64_t)2 * 1000000UL);
    if (result != ESP_OK) Serial.println("error in esp_sleep_enable_timer_wakeup");

    Serial.flush();

    esp_light_sleep_start();

    Serial.end();
    Serial.begin(126390);

    Serial.printf("Current CPU Clock: %u MHz, Serial baud rate %u\n", getCpuFrequencyMhz(), Serial.baudRate());

    Serial.printf("Slept for %u msec\n", millis() - lastSleep);
  }
  vTaskDelay(pdMS_TO_TICKS(5));
}

Debug Message

Without Serial.begin(126390);

ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x15 (USB_UART_HPSYS),boot:0x4 (DOWNLOAD(USB/UART0/SDIO_FEI_FEO))
Saved PC:0x4086ff5a
waiting for download
Current Clock: 160 MHz
Current Clock: 40 MHz
Setup done.
preparing for light sleep...
�ՙ�%y�2��۬]�@l��)_��ܕ��b�.�2`�"�Ӯ�c���%��My=b�.�lٝA�:a%%�q��Y��ՙ�%y�:��۬]�@d`��
�/AR����b�.�2``��k��\���%��Ey=b�.�lٝA�:a%%�y��Y��ՙ�%y�:��۬]�@��)_��ܕ��b�.�2`�"�ۮ�c���%��My=b�.�lٝA�:a%%�q��Y��ՙ�-y

With Serial.begin(126390)
ESP-ROM:esp32c6-20220919
Build:Sep 19 2022
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:2
load:0x4086c410,len:0xc64
load:0x4086e610,len:0x2758
load:0x40875728,len:0x594
entry 0x4086c410
Begin
Current Clock: 160 MHz
Current Clock: 40 MHz 
Setup done.
preparing for light sleep...
Current CPU Clock: 40 MHz, Serial baud rate 126394
Slept for 2003 msec
preparing for light sleep...
Current CPU Clock: 40 MHz, Serial baud rate 126394
Slept for 2003 msec

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

oseiler2 commented 1 month ago

Maybe related to this https://github.com/espressif/arduino-esp32/pull/8097/files

SuGlider commented 1 month ago

Issue confirmed.

SuGlider commented 1 month ago

This issue only happens with IDF esp_light_sleep_start();.

The example from https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Serial/Serial_All_CPU_Freqs/Serial_All_CPU_Freqs.ino that changes the CPU frequency from 160MHz to 10MHz works fine.

ESP32-C3 works correctly after esp_light_sleep_start();. This seems to be an exclusive issue for the C6 /H2+ esp_light_sleep_start();.

oseiler2 commented 1 month ago

Thanks for the quick fix!