wokwi / wokwi-features

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

ESP32 UART internal loopback not working #781

Closed P-R-O-C-H-Y closed 1 month ago

P-R-O-C-H-Y commented 1 month ago

Describe the bug We use internal loopbacks to test the UART on real HW, but in Wokwi this test is failing. I don't know if the feature is supported in Wokwi or if it's not working correctly (7 out of 11 tests were failing).

To Reproduce To reproduce the issue you can run the test sketch: https://github.com/espressif/arduino-esp32/blob/master/tests/validation/uart/uart.ino

Log:

2024-04-30 11:37:22 Wokwi CLI v0.9.1 (cfd2078ca922)
2024-04-30 11:37:24 Connected to Wokwi Simulation API 1.0.0-20240423-gf8714897
2024-04-30 11:37:24 Starting simulation...
2024-04-30 11:37:25 ets Jul 29 2019 12:21:46
2024-04-30 11:37:25 
2024-04-30 11:37:25 
2024-04-30 11:37:25 rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
2024-04-30 11:37:26 configsip: 0, SPIWP:0xee
2024-04-30 11:37:26 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
2024-04-30 11:37:26 mode:DIO, clock div:2
2024-04-30 11:37:26 load:0x3fff0030,len:1156
2024-04-30 11:37:26 
2024-04-30 11:37:26 load:0x40078000,len:11456
2024-04-30 11:37:26 
2024-04-30 11:37:26 ho 0 tail 12 room 4
2024-04-30 11:37:26 load:0x40080400,len:2972
2024-04-30 11:37:26 entry 0x400805dc
2024-04-30 11:37:27 Begin when running test successful
2024-04-30 11:37:27 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:596:begin_when_running_test:PASS
2024-04-30 11:37:28 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:108:basic_transmission_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) ' Was ''
2024-04-30 11:37:29 
2024-04-30 11:37:29 Buffer resize test successful
2024-04-30 11:37:29 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:598:resize_buffers_test:PASS
2024-04-30 11:37:29 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:108:change_baudrate_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) using 9600 baudrate' Was ''
2024-04-30 11:37:42 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:108:change_cpu_frequency_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) with new CPU frequency' Was ''
2024-04-30 11:37:42 Disabled UART calls test successful
2024-04-30 11:37:42 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:601:disabled_uart_calls_test:PASS
2024-04-30 11:37:42 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:314:enabled_uart_calls_test:FAIL: Expected -1 to be greater than or equal to 0
2024-04-30 11:38:49 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:493:auto_baudrate_test:FAIL: Values Not Within Delta 2304 Expected 115200 Was 0
2024-04-30 11:38:50 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:108:periman_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) while I2C is disabled' Was ''
2024-04-30 11:38:50 
2024-04-30 11:38:50 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:108:change_pins_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) using new pins' Was '\xFF'
2024-04-30 11:38:50 End when stopped test successful
2024-04-30 11:38:50 
2024-04-30 11:38:50 /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.ino:608:end_when_stopped_test:PASS
2024-04-30 11:38:50 
2024-04-30 11:38:50 -----------------------
2024-04-30 11:38:50 11 Tests 7 Failures 0 Ignored 
2024-04-30 11:38:50 FAIL
2024-04-30 11:38:50 
------------------------------ Captured log call -------------------------------
ERROR    root:plugin.py:1195 Failed Cases:
ERROR    root:plugin.py:1197   - basic_transmission_test
ERROR    root:plugin.py:1197   - change_baudrate_test
ERROR    root:plugin.py:1197   - change_cpu_frequency_test
ERROR    root:plugin.py:1197   - enabled_uart_calls_test
ERROR    root:plugin.py:1197   - auto_baudrate_test
ERROR    root:plugin.py:1197   - periman_test
ERROR    root:plugin.py:1197   - change_pins_test
---------------------------- Captured log teardown -----------------------------
INFO     root:dut.py:59 Created unity output junit report: /tmp/pytest-embedded/2024-04-30_11-37-22-170308/test_uart/dut.xml
- generated xml file: /home/runner/work/arduino-esp32/arduino-esp32/tests/uart/uart.xml -
=========================== short test summary info ============================
FAILED tests/uart/test_uart.py::test_uart - AssertionError: Unity test failed
================== 1 failed, 9 deselected in 88.45s (0:01:28) ==================

Expected behavior Expected is to pass all tests as it does on real HW.

Environment (please complete the following information):

Additional context

urish commented 1 month ago

Relevant underlying code (from ESP-IDF): https://github.com/espressif/esp-idf/issues/12826#issuecomment-1862540712

urish commented 1 month ago

Upon further investigation, the issue is that the code is trying to output the same signal on multiple pins (e.g. on ESP32, U2TXD is mapped both to 25 and 26), and wokwi won't handle that correctly - it would only route the signal to the first defined pin (25 in the example).

I'm looking at what changes we'd need to do for supporting this scenario.

urish commented 1 month ago

Update: still on it

urish commented 1 month ago

Should be fixed now.

Solving the original issue uncovered a few more issues with the UART implementation (baud rate not calculated correctly on ESP32-S3/C3, UART1 interrupt broken on ESP32-S2, incorrect RX FIFO timeout calculation), but now I believe UART should behave well in your tests.

Can you please rerun the tests and report?

lucasssvaz commented 1 month ago

@urish H2 still fails one of the tests: https://github.com/lucasssvaz/arduino-esp32/actions/runs/9190470217/job/25275142106?pr=12

urish commented 1 month ago

Thanks @lucasssvaz!

I looked into this. It seems like the tests use pins 6/7 for the pin swap test: https://github.com/espressif/arduino-esp32/blob/d164df89de350aa945ccb0cb4261f56306bfdb3c/tests/validation/uart/uart.ino#L51-L52

Looking at the datasheet, the H2 does not have GPIO6 / GPIO7 pins:

image

So that's why it fails on Wokwi.

I'm not sure what's the correct behavior in this case, as even the TRM mentions GPIO6/7 are not configurable in the IO MUX:

image

lucasssvaz commented 1 month ago

Thanks @lucasssvaz!

I looked into this. It seems like the tests use pins 6/7 for the pin swap test: https://github.com/espressif/arduino-esp32/blob/d164df89de350aa945ccb0cb4261f56306bfdb3c/tests/validation/uart/uart.ino#L51-L52

Looking at the datasheet, the H2 does not have GPIO6 / GPIO7 pins:

image

So that's why it fails on Wokwi.

I'm not sure what's the correct behavior in this case, as even the TRM mentions GPIO6/7 are not configurable in the IO MUX:

image

Then Idk why the hardware tests work fine πŸ˜†

I'll take a look, thanks!

urish commented 1 month ago

Then Idk why the hardware tests work fine πŸ˜†

Yeah, that's strange!

lucasssvaz commented 1 month ago

@urish Also, this is what I mentioned that some random bytes appear in the buffer for ESP32-S2

https://github.com/lucasssvaz/arduino-esp32/actions/runs/9197178547/job/25297205058?pr=12

It happened 2 times while I'm testing the refactoring in my fork.

urish commented 1 month ago

2024-05-22 19:26:48 /home/runner/work/arduino-esp32/arduino-esp32/tests/validation/uart/uart.ino:101:periman_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> via loopback >>> Serial1 (UART1) while I2C is disabled' Was '\xC1Hello from Serial1 (UART1) >>> via loopback >>> Serial1 (UART1) while I2C is disabled'

So this sometimes happens sometimes not?

lucasssvaz commented 1 month ago

2024-05-22 19:26:48 /home/runner/work/arduino-esp32/arduino-esp32/tests/validation/uart/uart.ino:101:periman_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> via loopback >>> Serial1 (UART1) while I2C is disabled' Was '\xC1Hello from Serial1 (UART1) >>> via loopback >>> Serial1 (UART1) while I2C is disabled'

So this sometimes happens sometimes not?

Yep, most of the time it works fine. Now it happened for ESP32:

https://github.com/lucasssvaz/arduino-esp32/actions/runs/9197367574/job/25297810900?pr=12

I never saw this happening with the tests in actual hardware. So I guess in this case it might be related to wokwi.

urish commented 1 month ago

I see. It might happen because of a floating wire for the UART receiver that generates some noise. I guess we are not properly resetting the receiver or something like that. How often does this happen? if it's about 50% of the times, then it's most likely a floating wire.

lucasssvaz commented 1 month ago

No, it's around 20-30% of the time if I had to guess

lucasssvaz commented 1 month ago

I've been seeing this issue more frequently. One interesting thing is that the "garbage text" is always the same for the chips: In S2 it is \xC1 and ESP32 it's \xFE. I would suspect that something that was meant to be sent as a byte is being sent as a string, based on the error message:

/home/runner/work/arduino-esp32/arduino-esp32/tests/validation/uart/uart.ino:108:change_pins_test:FAIL: Expected 'Hello from Serial1 (UART1) >>> to >>> Serial2 (UART2) using new pins' Was '\xFEHello from Serial1 (UART1) >>> to >>> Serial2 (UART2) using new pins'
urish commented 1 month ago

Thanks for investigating! I pushed a fix that implements the UART RX FIFO reset functionality, and I believe this should fix the random bytes issue. Can you please test once more?

lucasssvaz commented 1 month ago

No problem, I'll report back once I have performed enough tests

lucasssvaz commented 1 month ago

Still happening on ESP32: https://github.com/lucasssvaz/arduino-esp32/actions/runs/9240024519/job/25419849144?pr=12

I'll check for S2 tomorrow

urish commented 1 month ago

Thanks for checking! Should be fixed now too :-)