rtic
rtic copied to clipboard
Added esp32c6 support
Quickly ported the ESP32C3 support and example to the ESP32C6 HP core.
TODO
- [ ] Restructure & deduplicate this code with the ESPC3 code.
- [x] The GPIO button does not seem to work.
- [ ] ~LP core support.~
- [x] Add CI support.
I would love to hear some recommendations or ideas on how to properly deduplicate the code with regards to the existing unstable support for the ESPC3.
I am leaving LP core support out of this MR for a separate MR later on.
Really neat, seems that went quite smoothly :)
I'm not too familiar with the differences C3 and C6, are they close enough that sharing examples is expected to work throughout?
Looks like how you've done it in xtask is quite clean as is :+1:
Could you please re-sync C6 support with C3 (latest master branch)? Then it should be possible to also run examples on C6 in QEMU :)
@AfoHT While the ESP32C3 and ESP32C6 are very similar, they differ in RISCV instruction set with atomics, peripheral layout, and chip ID. Still to give it a go I replicated the CI QEMU setup and ran the example image on the ESP32C3 ROM but it fails when checking the image chip ID, as expected.
$ cargo run --example sw_and_hw --features=riscv-esp32c6-backend
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `/home/wouter/tmp/rtic/examples/esp32c6/./runner.sh target/riscv32imac-unknown-none-elf/debug/examples/sw_and_hw`
Chip type: esp32c6
Merge: true
Skip padding: false
App/part. size: 241,088/4,128,768 bytes, 5.84%
[2024-04-17T09:05:31Z INFO ] Image successfully saved!
esptool.py v4.7.0
File size: 4194304 (bytes)
Detected image type: ESP32-C6
ESP32-C6 image header
=====================
Image version: 1
Entry point: 0x4086c410
Segments: 3
Flash size: 4MB
Flash freq: 80m
Flash mode: DIO
ESP32-C6 extended image header
==============================
WP pin: 0xee (disabled)
Flash pins drive settings: clk_drv: 0x0, q_drv: 0x0, d_drv: 0x0, cs0_drv: 0x0, hd_drv: 0x0, wp_drv: 0x0
Chip ID: 13 (ESP32-C6)
Minimal chip revision: v0.0, (legacy min_rev = 0)
Maximal chip revision: v0.99
Segments information
====================
Segment Length Load addr File offs Memory types
------- ------- ---------- ---------- ------------
1 0x00d48 0x4086c410 0x00000018 DRAM, BYTE_ACCESSIBLE, IRAM
2 0x02d68 0x4086e610 0x00000d68 DRAM, BYTE_ACCESSIBLE, IRAM
3 0x01800 0x40875720 0x00003ad8 DRAM, BYTE_ACCESSIBLE, IRAM
ESP32-C6 image footer
=====================
Checksum: 0x21 (valid)
Validation hash: aff89878a96cbff57c66c38aa6d1a422b7785040b5efea582babef6c357427c2 (valid)
Adding SPI flash device
QEMU 8.2.0 monitor - type 'help' for more information
(qemu) q
ESP-ROM:esp32c3-api1-20210207
Build:Feb 7 2021
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
Invalid chip id. Expected 5 read 13. Bootloader for wrong chip?
ets_main.c 333
Looks good, thanks for adding this. Would it be possible to add example that shows how to connect to a WiFi network?
I am very excited to see RTIC esp32c6 support in progress!
I tried running the esp32c6 example from this PR on my esp32c6 hardware. Unfortunately, the hardware task does not appear to work. I trimmed it down to a minimal broken example:
Source code: https://github.com/dlaw/esp32c6/blob/rtic/src/main.rs
Entire project including all cargo configurations: https://github.com/dlaw/esp32c6/tree/rtic
I build and run this code by using cargo run --release, which launches espflash flash --monitor.
Expected behavior:
When pressing the button, Button! prints in between Tick prints.
Actual behavior:
When pressing the button, the Tick printing halts and no further output is observed until the chip is reset. Furthermore, when I set a breakpoint in gpio_handler(), the breakpoint never triggers.
Further debugging:
- When I change
binds=GPIOtobinds=XXXforgpio_handler(), where XXX is any other interrupt, the behavior is unchanged. - When the
button.listen()call is removed, pressing the button does not stop theTickprinting. So, it's a problem which is specific to the GPIO interrupt being enabled.
Wassasin pointed out that my example was not working because I was using esp-hal 0.17. It works fine with esp-hal 0.16. However, there is a snag which currently prevents the use of esp-wifi with RTIC:
- esp-hal 0.16 has an optional direct-vectoring feature
- this PR requires esp-hal 0.16 with direct-vectoring enabled
- esp-wifi 0.4 requires esp-hal 0.16 with direct-vectoring disabled
The issue would be solved by supporting esp-hal 0.17, because:
- direct-vectoring is enabled by default (no longer an optional feature) in esp-hal 0.17
- esp-wifi 0.5 works with esp-hal 0.17
Cheers!
I've updated support for the ESP32-C3 with #975. Once this is merged I was planning on adding support for the ESP32-C6 as well, but stumbled across this PR. @Wassasin would you mind if I continued the work you started here and opened a new PR building on top of this one?
@jessebraham Sure, no problem. I think it would be easier to start a new branch and take what you need from this PR. As mentioned above there are some issues with this branch.
I'll add some new background context - esp32c6 has CLINT peripheral which makes it compatible with backend that already exists and is less target specific.
@jessebraham already fulfilled some prerequisites to make it happen, but it requires adding additional settings file to esp-pacs, upgrade esp32c6-hal to use it and perhaps match some minor details (for example CLINT registers are 64-bit and they are mapped as pairs of 32-bit in example target (e310x) and as 64-bit ones in esp32c6)
I have started adding the additional RISC-V settings files to esp-pacs, and this is mostly complete other than some small details. I am a little preoccupied with some other work right now but hope to have a PR for this next week.
We are actively working on getting a new esp-hal release out for next week, so once this is published we can start working on the necessary changes there as well.
What's the status of this? Is there anything I can do to move it forwards?
I have rebased this branch and the code mostly works on my C6. I haven't tested the rtic-monotonics crate but a timer with interrupts created with esp_hal::timer::TimerGroup::new() works, as well as a button interrupt and SPI for https://crates.io/crates/ws2812-spi. I say mostly because the changes to the interrupt handler names cause a duplicate interrupt1 symbol error (keeping the interrupts as e.g. cpu_int_1_handler causes a panic due to unhandled interrupts)
I bet you guessed it but I stopped working on CLINT for the time being and afaik @jessebraham have at least partialy exposed CLINT in pac and maybe hal.
I guess it's better to have C3-like support for C6 than nothing
I'm closer now - rtic-monotonics now works, but interrupt priorities are being ignored - testing the sw_and_hw task on an MCU shows that the GPIO task can break out of the higher priority software task. This was the case even before the latest commit on my branch that started switching to PLIC_MX insteaed of INTPRI to enable interrupts & set priorities.
I'm unsure where to go from here - the technical reference manual doesn't seem to mention PLIC_MX (it just mentions its register as "CPU Sub-system region"), and the only places I can find it on Google are in esp-hal. It works better than INTPRI for the monotonics example, but lack of safety around task priorities is a pretty big deal in either case.
I did some more digging today and saw esp-hal notes some external interrupts are reserved, so in my latest commit I excluded them and now it looks like it is working fully 🎉 . Should I create a new PR with my changes?
... and now it looks like it is working fully 🎉 .
Awesome!
Should I create a new PR with my changes?
That would be great! Yes please 😃
How large is the diff compared to this PR?
I wonder if it makes sense to target this branch with the changes needed, or a new PR still is the easiest way about it on GitHub...
Either way, the other authors commits would carry over even if just a new PR so maybe that's the easiest after all. 👍