wokwi / wokwi-features

Wokwi Feature requests & Bug Reports
https://wokwi.com
74 stars 17 forks source link

ESP32s Timer write/read have unexpected value #779

Closed P-R-O-C-H-Y closed 6 months ago

P-R-O-C-H-Y commented 6 months ago

Describe the bug

For all ESP32 SoCs the timer test is failing on the same function calls.

  1. Ensure timer is stopped.
  2. Set the timer value by calling timerWrite() with value 255
  3. Read the timer value bytimerRead(), the expected value is 255 (on real HW it works), but in Wokwi its 278-282.

CI run: https://github.com/P-R-O-C-H-Y/arduino-esp32/actions/runs/8939891850/job/24556842309

Log:

2024-05-03 13:38:27 Wokwi CLI v0.9.1 (cfd2078ca922)
2024-05-03 13:38:29 Connected to Wokwi Simulation API 1.0.0-20240423-gf8714897
2024-05-03 13:38:29 Starting simulation...
2024-05-03 13:38:30 ESP-ROM:esp32c3-api1-20210207
2024-05-03 13:38:30 
2024-05-03 13:38:30 Build:Feb  7 2021
2024-05-03 13:38:30 rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
2024-05-03 13:38:30 SPIWP:0xee
2024-05-03 13:38:30 mode:DIO, clock div:1
2024-05-03 13:38:30 load:0x3fcd6100,len:0x420
2024-05-03 13:38:30 load:0x403ce000,len:0x90c
2024-05-03 13:38:30 load:0x403d0000,len:0x2370
2024-05-03 13:38:30 entry 0x403ce000
2024-05-03 13:38:30 /home/runner/work/arduino-esp32/arduino-esp32/tests/timer/timer.ino:103:timer_read_test:FAIL: Expected 255 Was 278
2024-05-03 13:38:34 /home/runner/work/arduino-esp32/arduino-esp32/tests/timer/timer.ino:124:timer_interrupt_test:PASS
2024-05-03 13:38:37 /home/runner/work/arduino-esp32/arduino-esp32/tests/timer/timer.ino:125:timer_divider_test:PASS
2024-05-03 13:38:37 /home/runner/work/arduino-esp32/arduino-esp32/tests/timer/timer.ino:127:timer_clock_select_test:PASS
2024-05-03 13:38:37 
2024-05-03 13:38:37 -----------------------
2024-05-03 13:38:37 4 Tests 1 Failures 0 Ignored 
2024-05-03 13:38:37 
2024-05-03 13:38:37 FAIL

To Reproduce

Run the Timer test sketch from arduino-esp32 repository:

/* HW Timer test */
#include <unity.h>

#define TIMER_FREQUENCY          4000000
#define TIMER_FREQUENCY_XTAL_CLK 1000

/*
 * ESP32 - APB clk only (1kHz not possible)
 * C3 - APB + XTAL clk
 * S2 - APB + XTAL clk
 * S3 - APB + XTAL clk
 */

static hw_timer_t *timer = NULL;
static volatile bool alarm_flag;

/* setUp / tearDown functions are intended to be called before / after each test. */
void setUp(void) {
  timer = timerBegin(TIMER_FREQUENCY);
  if (timer == NULL) {
    TEST_FAIL_MESSAGE("Timer init failed in setUp()");
  }
  timerStop(timer);
  timerRestart(timer);
}

void tearDown(void) {
  timerEnd(timer);
}

void ARDUINO_ISR_ATTR onTimer() {
  alarm_flag = true;
}

void timer_interrupt_test(void) {

  alarm_flag = false;
  timerAttachInterrupt(timer, &onTimer);
  timerAlarm(timer, (1.2 * TIMER_FREQUENCY), true, 0);
  timerStart(timer);

  delay(2000);

  TEST_ASSERT_EQUAL(true, alarm_flag);

  timerStop(timer);
  timerRestart(timer);
  alarm_flag = false;
  timerDetachInterrupt(timer);
  timerStart(timer);

  delay(2000);
  TEST_ASSERT_EQUAL(false, alarm_flag);
}

void timer_divider_test(void) {

  uint64_t time_val;
  uint64_t comp_time_val;

  timerStart(timer);

  delay(1000);
  time_val = timerRead(timer);

  // compare divider  16 and 8, value should be double
  timerEnd(timer);

  timer = timerBegin(2 * TIMER_FREQUENCY);
  if (timer == NULL) {
    TEST_FAIL_MESSAGE("Timer init failed!");
  }
  timerRestart(timer);
  delay(1000);
  comp_time_val = timerRead(timer);

  TEST_ASSERT_INT_WITHIN(4000, 4000000, time_val);
  TEST_ASSERT_INT_WITHIN(8000, 8000000, comp_time_val);

  // divider is 256, value should be 2^4
  timerEnd(timer);

  timer = timerBegin(TIMER_FREQUENCY / 16);
  if (timer == NULL) {
    TEST_FAIL_MESSAGE("Timer init failed!");
  }
  timerRestart(timer);
  delay(1000);
  comp_time_val = timerRead(timer);

  TEST_ASSERT_INT_WITHIN(4000, 4000000, time_val);
  TEST_ASSERT_INT_WITHIN(2500, 250000, comp_time_val);
}

void timer_read_test(void) {

  uint64_t set_timer_val = 0xFF;
  uint64_t get_timer_val = 0;

  timerWrite(timer, set_timer_val);
  get_timer_val = timerRead(timer);

  TEST_ASSERT_EQUAL(set_timer_val, get_timer_val);
}

void timer_clock_select_test(void) {
  // Set timer frequency that can be achieved using XTAL clock source (autoselected)
  timer = timerBegin(TIMER_FREQUENCY_XTAL_CLK);

  uint32_t resolution = timerGetFrequency(timer);
  TEST_ASSERT_EQUAL(TIMER_FREQUENCY_XTAL_CLK, resolution);
}

void setup() {

  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ;
  }

  UNITY_BEGIN();
  RUN_TEST(timer_read_test);
  RUN_TEST(timer_interrupt_test);
  RUN_TEST(timer_divider_test);
#if !CONFIG_IDF_TARGET_ESP32
  RUN_TEST(timer_clock_select_test);
#endif
  UNITY_END();
}

void loop() {}

Expected behavior As timer peripheral is supported on Wokwi, the expectations are that the test is passing as it is on real HW.

Environment (please complete the following information):

Additional context Add any other context about the problem here.

urish commented 6 months ago

Thanks for reporting! Issue reproduces for me.

urish commented 6 months ago

Should be fixed now! Can you please rerun the failing workflows and report back?

P-R-O-C-H-Y commented 6 months ago

Should be fixed now! Can you please rerun the failing workflows and report back?

@urish Its fixed on all chips (did not test P4, don't know if timer is supported and we don't have a support in Arduino). But there is still an issue with H2 timer test number 2 and 3 - https://github.com/P-R-O-C-H-Y/arduino-esp32/actions/runs/8939891850. Can you please take a look? On other chips its fine :)

urish commented 6 months ago

Can you please take a look? On other chips its fine :)

Taking a look

urish commented 6 months ago

Found the issue, related to the TIMG clock configuration. Fix will be ready later today.

urish commented 6 months ago

Fix is up!

P-R-O-C-H-Y commented 6 months ago

Looking good! 👍 Closing as solved, Thanks Uri.