mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 13:09:37 +01:00
Update support/example for ESP32-C3 to use latest versions of dependencies (#975)
* Update `rtic` package to use latest version of `esp32c3` dependency * Update `rtic-macros` ESP32-C3 bindings to reflect changes in HAL * Update the ESP32-C3 examples to use latest versions of all dependencies * Update changelogs * adjust expected qemu output, add compile-time checks * remove runtime checks, this is checked at compile time * fix expected qemu output * Clean up interrupt enable code a bit * Update `rtic-monotonic` to use the latest PAC for ESP32-C3 * Update `CHANGELOG.md` for `rtic-monotonic` * ci: esp32c3: Format runner.sh * ci: esp32c3: Default to silent boot export DEBUGGING while running to get verbose boot env DEBUGGING=1 cargo xtask ... * ci: esp32c3: Update expected example output --------- Co-authored-by: onsdagens <pawdzi-7@student.ltu.se> Co-authored-by: Henrik Tjäder <henrik@tjaders.com>
This commit is contained in:
parent
89d76a53d8
commit
1f6b6a42e5
14 changed files with 463 additions and 440 deletions
|
@ -1,33 +1,5 @@
|
||||||
QEMU 8.2.0 monitor - type 'help' for more information
|
QEMU 8.2.0 monitor - type 'help' for more information
|
||||||
(qemu) q[K
|
(qemu) q[K
|
||||||
ESP-ROM:esp32c3-api1-20210207
|
|
||||||
Build:Feb 7 2021
|
|
||||||
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
|
|
||||||
SPIWP:0xee
|
|
||||||
mode:DIO, clock div:2
|
|
||||||
load:0x3fcd5820,len:0x1714
|
|
||||||
load:0x403cc710,len:0x968
|
|
||||||
load:0x403ce710,len:0x2f9c
|
|
||||||
entry 0x403cc710
|
|
||||||
[0;32mI (0) boot: ESP-IDF v5.1.2-342-gbcf1645e44 2nd stage bootloader[0m
|
|
||||||
[0;32mI (0) boot: compile time Dec 12 2023 10:50:58[0m
|
|
||||||
[0;32mI (0) boot: chip revision: v0.3[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Speed : 40MHz[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Mode : SLOW READ[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Flash Size : 4MB[0m
|
|
||||||
[0;32mI (0) boot: Enabling RNG early entropy source...[0m
|
|
||||||
[0;32mI (1) boot: Partition Table:[0m
|
|
||||||
[0;32mI (1) boot: ## Label Usage Type ST Offset Length[0m
|
|
||||||
[0;32mI (1) boot: 0 nvs WiFi data 01 02 00009000 00006000[0m
|
|
||||||
[0;32mI (1) boot: 1 phy_init RF data 01 01 0000f000 00001000[0m
|
|
||||||
[0;32mI (1) boot: 2 factory factory app 00 00 00010000 003f0000[0m
|
|
||||||
[0;32mI (1) boot: End of partition table[0m
|
|
||||||
[0;32mI (1) esp_image: REDACTED
|
|
||||||
[0;32mI (3) esp_image: REDACTED
|
|
||||||
[0;32mI (3) esp_image: REDACTED
|
|
||||||
[0;32mI (8) esp_image: REDACTED
|
|
||||||
[0;32mI (11) boot: Loaded app from partition at offset 0x10000[0m
|
|
||||||
[0;32mI (11) boot: Disabling RNG early entropy source...[0m
|
|
||||||
init
|
init
|
||||||
hello from bar
|
hello from bar
|
||||||
hello from baz
|
hello from baz
|
||||||
|
|
|
@ -1,33 +1,5 @@
|
||||||
QEMU 8.2.0 monitor - type 'help' for more information
|
QEMU 8.2.0 monitor - type 'help' for more information
|
||||||
(qemu) q[K
|
(qemu) q[K
|
||||||
ESP-ROM:esp32c3-api1-20210207
|
|
||||||
Build:Feb 7 2021
|
|
||||||
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
|
|
||||||
SPIWP:0xee
|
|
||||||
mode:DIO, clock div:2
|
|
||||||
load:0x3fcd5820,len:0x1714
|
|
||||||
load:0x403cc710,len:0x968
|
|
||||||
load:0x403ce710,len:0x2f9c
|
|
||||||
entry 0x403cc710
|
|
||||||
[0;32mI (0) boot: ESP-IDF v5.1.2-342-gbcf1645e44 2nd stage bootloader[0m
|
|
||||||
[0;32mI (0) boot: compile time Dec 12 2023 10:50:58[0m
|
|
||||||
[0;32mI (0) boot: chip revision: v0.3[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Speed : 40MHz[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Mode : SLOW READ[0m
|
|
||||||
[0;32mI (0) boot.esp32c3: SPI Flash Size : 4MB[0m
|
|
||||||
[0;32mI (0) boot: Enabling RNG early entropy source...[0m
|
|
||||||
[0;32mI (1) boot: Partition Table:[0m
|
|
||||||
[0;32mI (1) boot: ## Label Usage Type ST Offset Length[0m
|
|
||||||
[0;32mI (1) boot: 0 nvs WiFi data 01 02 00009000 00006000[0m
|
|
||||||
[0;32mI (1) boot: 1 phy_init RF data 01 01 0000f000 00001000[0m
|
|
||||||
[0;32mI (1) boot: 2 factory factory app 00 00 00010000 003f0000[0m
|
|
||||||
[0;32mI (1) boot: End of partition table[0m
|
|
||||||
[0;32mI (1) esp_image: REDACTED
|
|
||||||
[0;32mI (3) esp_image: REDACTED
|
|
||||||
[0;32mI (3) esp_image: REDACTED
|
|
||||||
[0;32mI (8) esp_image: REDACTED
|
|
||||||
[0;32mI (11) boot: Loaded app from partition at offset 0x10000[0m
|
|
||||||
[0;32mI (11) boot: Disabling RNG early entropy source...[0m
|
|
||||||
init
|
init
|
||||||
Inside high prio task, press button now!
|
Inside high prio task, press button now!
|
||||||
Leaving high prio task.
|
Leaving high prio task.
|
||||||
|
|
700
examples/esp32c3/Cargo.lock
generated
700
examples/esp32c3/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -7,18 +7,17 @@ license = "MIT OR Apache-2.0"
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rtic = {path = "../../rtic/"}
|
rtic = { path = "../../rtic/" }
|
||||||
rtic-monotonics = {path = "../../rtic-monotonics/"}
|
rtic-monotonics = {path = "../../rtic-monotonics/"}
|
||||||
esp-hal = { version = "0.16.1", features = ["esp32c3", "direct-vectoring", "interrupt-preemption"] }
|
esp-hal = { version = "0.20.1", features = ["esp32c3"] }
|
||||||
esp-backtrace = { version = "0.11.0", features = [
|
esp-backtrace = { version = "0.14.0", features = [
|
||||||
"esp32c3",
|
"esp32c3",
|
||||||
"panic-handler",
|
"panic-handler",
|
||||||
"exception-handler",
|
"exception-handler",
|
||||||
"println",
|
"println",
|
||||||
] }
|
] }
|
||||||
|
esp32c3 = {version = "0.25.0", features = ["critical-section"]}
|
||||||
esp32c3 = {version = "0.22.0", features = ["critical-section"]}
|
esp-println = { version = "0.11.0", features = ["esp32c3"] }
|
||||||
esp-println = { version = "0.9.0", features = ["esp32c3", "uart"] }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
test-critical-section = []
|
test-critical-section = []
|
||||||
|
|
|
@ -4,17 +4,17 @@
|
||||||
mod app {
|
mod app {
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
gpio::{Event, Gpio9, Input, PullDown, IO},
|
gpio::{Event, GpioPin, Input, Io, Pull},
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
|
||||||
};
|
};
|
||||||
use esp_println::println;
|
use esp_println::println;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
|
||||||
#[local]
|
#[local]
|
||||||
struct Local {
|
struct Local {
|
||||||
button: Gpio9<Input<PullDown>>,
|
button: Input<'static, GpioPin<9>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// do nothing in init
|
// do nothing in init
|
||||||
|
@ -22,14 +22,14 @@ mod app {
|
||||||
fn init(_: init::Context) -> (Shared, Local) {
|
fn init(_: init::Context) -> (Shared, Local) {
|
||||||
println!("init");
|
println!("init");
|
||||||
let peripherals = Peripherals::take();
|
let peripherals = Peripherals::take();
|
||||||
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
|
let io = Io::new_no_bind_interrupt(peripherals.GPIO, peripherals.IO_MUX);
|
||||||
let mut button = io.pins.gpio9.into_pull_down_input();
|
let mut button = Input::new(io.pins.gpio9, Pull::Up);
|
||||||
button.listen(Event::FallingEdge);
|
button.listen(Event::FallingEdge);
|
||||||
foo::spawn().unwrap();
|
foo::spawn().unwrap();
|
||||||
(Shared {}, Local { button })
|
(Shared {}, Local { button })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[idle()]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
println!("idle");
|
println!("idle");
|
||||||
loop {}
|
loop {}
|
||||||
|
@ -46,6 +46,7 @@ mod app {
|
||||||
}
|
}
|
||||||
println!("Leaving high prio task.");
|
println!("Leaving high prio task.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(priority = 2)]
|
#[task(priority = 2)]
|
||||||
async fn bar(_: bar::Context) {
|
async fn bar(_: bar::Context) {
|
||||||
println!("Inside low prio task, press button now!");
|
println!("Inside low prio task, press button now!");
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
if [ $# -eq 0 ]
|
if [ $# -eq 0 ]; then
|
||||||
then
|
echo "No arguments supplied! Provide path to ELF as argument"
|
||||||
echo "No arguments supplied! Provide path to ELF as argument"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
outputfilenamecargo=$1
|
outputfilenamecargo=$1
|
||||||
|
@ -19,13 +18,20 @@ espflash save-image --chip esp32c3 --merge "$outputfilenamecargo" "$outputfilena
|
||||||
esptool.py image_info --version 2 "$outputfilename" 1>&2
|
esptool.py image_info --version 2 "$outputfilename" 1>&2
|
||||||
|
|
||||||
# Run in QEMU
|
# Run in QEMU
|
||||||
$qemuexec -nographic -monitor tcp:127.0.0.1:55555,server,nowait -icount 3 -machine esp32c3 -drive file="$outputfilename",if=mtd,format=raw -serial file:"$logfile" &
|
$qemuexec -nographic -monitor tcp:127.0.0.1:55555,server,nowait -icount 3 -machine esp32c3 -drive file="$outputfilename",if=mtd,format=raw -serial file:"$logfile" &
|
||||||
|
|
||||||
# Let it run
|
# Let it run
|
||||||
sleep 3s
|
sleep 3s
|
||||||
|
|
||||||
# Kill QEMU nicely by sending 'q' (quit) over tcp
|
# Kill QEMU nicely by sending 'q' (quit) over tcp
|
||||||
echo q | nc -N 127.0.0.1 55555
|
echo q | nc -N 127.0.0.1 55555
|
||||||
# Output that will be compared, remove the esp_image segments as they change
|
|
||||||
# between runs
|
# Output that will be compared must be printed to stdout
|
||||||
cat "$logfile" | sed 's/esp_image: .*$/esp_image: REDACTED/'
|
|
||||||
|
# Make boot phase silent, for debugging change, run with e.g. $ `env DEBUGGING=true` cargo xtask....
|
||||||
|
if [ -n "${DEBUGGING}" ]; then
|
||||||
|
# Debugging: strip leading "I (xyz)" where xyz is an incrementing number, and esp_image specifics
|
||||||
|
sed -e 's/esp_image: .*$/esp_image: REDACTED/' -e 's/I\s\([0-9]*\)(.*)/\1/' < $logfile
|
||||||
|
else
|
||||||
|
tail -n +12 "$logfile" | sed -e '/I\s\([0-9]*\)(.*)/d'
|
||||||
|
fi
|
||||||
|
|
|
@ -14,6 +14,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
- Fix codegen emitting unqualified `Result`
|
- Fix codegen emitting unqualified `Result`
|
||||||
- Improve error output for prios > dispatchers
|
- Improve error output for prios > dispatchers
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix interrupt handlers when targeting esp32c3 and using latest version of esp-hal
|
||||||
|
|
||||||
## [v2.1.0] - 2024-02-27
|
## [v2.1.0] - 2024-02-27
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -80,11 +80,13 @@ mod esp32c3 {
|
||||||
}
|
}
|
||||||
stmts
|
stmts
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
|
pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
|
||||||
let mut stmts = vec![];
|
let mut stmts = vec![];
|
||||||
let mut curr_cpu_id: u8 = 1; //cpu interrupt id 0 is reserved
|
let mut curr_cpu_id: u8 = 16; // cpu interrupt ids 0-15 are reserved
|
||||||
let rt_err = util::rt_err_ident();
|
let rt_err = util::rt_err_ident();
|
||||||
let max_prio: usize = 15; //unfortunately this is not part of pac, but we know that max prio is 15.
|
let max_prio: usize = 15; //unfortunately this is not part of pac, but we know that max prio is 15.
|
||||||
|
let min_prio: usize = 1;
|
||||||
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
|
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
|
||||||
// Unmask interrupts and set their priorities
|
// Unmask interrupts and set their priorities
|
||||||
for (&priority, name) in interrupt_ids.chain(
|
for (&priority, name) in interrupt_ids.chain(
|
||||||
|
@ -95,9 +97,11 @@ mod esp32c3 {
|
||||||
let es = format!(
|
let es = format!(
|
||||||
"Maximum priority used by interrupt vector '{name}' is more than supported by hardware"
|
"Maximum priority used by interrupt vector '{name}' is more than supported by hardware"
|
||||||
);
|
);
|
||||||
|
let es_zero = format!("Priority {priority} used by interrupt vector '{name}' is less than supported by hardware");
|
||||||
// Compile time assert that this priority is supported by the device
|
// Compile time assert that this priority is supported by the device
|
||||||
stmts.push(quote!(
|
stmts.push(quote!(
|
||||||
const _: () = if (#max_prio) <= #priority as usize { ::core::panic!(#es); };
|
const _: () = if (#max_prio) <= #priority as usize { ::core::panic!(#es); };
|
||||||
|
const _: () = if (#min_prio) > #priority as usize { ::core::panic!(#es_zero);};
|
||||||
));
|
));
|
||||||
stmts.push(quote!(
|
stmts.push(quote!(
|
||||||
rtic::export::enable(
|
rtic::export::enable(
|
||||||
|
@ -218,14 +222,14 @@ mod esp32c3 {
|
||||||
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max;
|
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max;
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler_config(
|
pub fn handler_config(
|
||||||
app: &App,
|
app: &App,
|
||||||
analysis: &CodegenAnalysis,
|
analysis: &CodegenAnalysis,
|
||||||
dispatcher_name: Ident,
|
dispatcher_name: Ident,
|
||||||
) -> Vec<TokenStream2> {
|
) -> Vec<TokenStream2> {
|
||||||
let mut stmts = vec![];
|
let mut stmts = vec![];
|
||||||
let mut curr_cpu_id = 1;
|
let mut curr_cpu_id = 16; // cpu interrupt ids 0-15 are reserved
|
||||||
//let mut ret = "";
|
|
||||||
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
|
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
|
||||||
for (_, name) in interrupt_ids.chain(
|
for (_, name) in interrupt_ids.chain(
|
||||||
app.hardware_tasks
|
app.hardware_tasks
|
||||||
|
@ -233,7 +237,7 @@ mod esp32c3 {
|
||||||
.filter_map(|task| Some((&task.args.priority, &task.args.binds))),
|
.filter_map(|task| Some((&task.args.priority, &task.args.binds))),
|
||||||
) {
|
) {
|
||||||
if *name == dispatcher_name {
|
if *name == dispatcher_name {
|
||||||
let ret = &("cpu_int_".to_owned() + &curr_cpu_id.to_string() + "_handler");
|
let ret = &("interrupt".to_owned() + &curr_cpu_id.to_string());
|
||||||
stmts.push(quote!(#[export_name = #ret]));
|
stmts.push(quote!(#[export_name = #ret]));
|
||||||
}
|
}
|
||||||
curr_cpu_id += 1;
|
curr_cpu_id += 1;
|
||||||
|
|
|
@ -11,6 +11,10 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
|
|
||||||
- RP235x support
|
- RP235x support
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Update `esp32c3` dependency
|
||||||
|
|
||||||
## v2.0.2 - 2024-07-05
|
## v2.0.2 - 2024-07-05
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -67,7 +67,7 @@ stm32-metapac = { version = "15.0.0", optional = true }
|
||||||
imxrt-ral = { version = "0.5.3", optional = true }
|
imxrt-ral = { version = "0.5.3", optional = true }
|
||||||
|
|
||||||
|
|
||||||
esp32c3 = {version = "0.22.0", optional = true }
|
esp32c3 = {version = "0.25.0", optional = true }
|
||||||
riscv = {version = "0.11.1", optional = true }
|
riscv = {version = "0.11.1", optional = true }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! [`Monotonic`](rtic_time::Monotonic) implementation for ESP32C3's SYSTIMER.
|
//! [`Monotonic`](rtic_time::Monotonic) implementation for ESP32-C3's SYSTIMER.
|
||||||
//!
|
//!
|
||||||
//! Always runs at a fixed rate of 16 MHz.
|
//! Always runs at a fixed rate of 16 MHz.
|
||||||
//!
|
//!
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
/// Common definitions and traits for using the RP2040 timer monotonic
|
/// Common definitions and traits for using the ESP32-C3 timer monotonic
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::esp32c3_systimer_monotonic;
|
pub use crate::esp32c3_systimer_monotonic;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ impl TimerBackend {
|
||||||
.cpu_int_enable()
|
.cpu_int_enable()
|
||||||
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); //enable the CPU interupt.
|
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); //enable the CPU interupt.
|
||||||
let intr = INTERRUPT_CORE0::ptr();
|
let intr = INTERRUPT_CORE0::ptr();
|
||||||
let intr_prio_base = (*intr).cpu_int_pri_0().as_ptr();
|
let intr_prio_base = (*intr).cpu_int_pri(0).as_ptr();
|
||||||
|
|
||||||
intr_prio_base
|
intr_prio_base
|
||||||
.offset(cpu_interrupt_number)
|
.offset(cpu_interrupt_number)
|
||||||
|
@ -84,18 +84,11 @@ impl TimerQueueBackend for TimerBackend {
|
||||||
peripherals
|
peripherals
|
||||||
.SYSTIMER
|
.SYSTIMER
|
||||||
.unit0_op()
|
.unit0_op()
|
||||||
.write(|w| w.timer_unit0_update().set_bit());
|
.write(|w| w.update().set_bit());
|
||||||
// this must be polled until value is valid
|
// this must be polled until value is valid
|
||||||
while {
|
while peripherals.SYSTIMER.unit0_op().read().value_valid() == false {}
|
||||||
peripherals
|
let instant: u64 = (peripherals.SYSTIMER.unit_value(0).lo().read().bits() as u64)
|
||||||
.SYSTIMER
|
| ((peripherals.SYSTIMER.unit_value(0).hi().read().bits() as u64) << 32);
|
||||||
.unit0_op()
|
|
||||||
.read()
|
|
||||||
.timer_unit0_value_valid()
|
|
||||||
== false
|
|
||||||
} {}
|
|
||||||
let instant: u64 = (peripherals.SYSTIMER.unit0_value_lo().read().bits() as u64)
|
|
||||||
| ((peripherals.SYSTIMER.unit0_value_hi().read().bits() as u64) << 32);
|
|
||||||
instant
|
instant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,19 +96,19 @@ impl TimerQueueBackend for TimerBackend {
|
||||||
let systimer = unsafe { esp32c3::Peripherals::steal() }.SYSTIMER;
|
let systimer = unsafe { esp32c3::Peripherals::steal() }.SYSTIMER;
|
||||||
systimer
|
systimer
|
||||||
.target0_conf()
|
.target0_conf()
|
||||||
.write(|w| w.target0_timer_unit_sel().set_bit());
|
.write(|w| w.timer_unit_sel().set_bit());
|
||||||
systimer
|
systimer
|
||||||
.target0_conf()
|
.target0_conf()
|
||||||
.write(|w| w.target0_period_mode().clear_bit());
|
.write(|w| w.period_mode().clear_bit());
|
||||||
systimer
|
systimer
|
||||||
.target0_lo()
|
.trgt(0)
|
||||||
|
.lo()
|
||||||
.write(|w| unsafe { w.bits((instant & 0xFFFFFFFF).try_into().unwrap()) });
|
.write(|w| unsafe { w.bits((instant & 0xFFFFFFFF).try_into().unwrap()) });
|
||||||
systimer
|
systimer
|
||||||
.target0_hi()
|
.trgt(0)
|
||||||
|
.hi()
|
||||||
.write(|w| unsafe { w.bits((instant >> 32).try_into().unwrap()) });
|
.write(|w| unsafe { w.bits((instant >> 32).try_into().unwrap()) });
|
||||||
systimer
|
systimer.comp0_load().write(|w| w.load().set_bit()); //sync period to comp register
|
||||||
.comp0_load()
|
|
||||||
.write(|w| w.timer_comp0_load().set_bit()); //sync period to comp register
|
|
||||||
systimer.conf().write(|w| w.target0_work_en().set_bit());
|
systimer.conf().write(|w| w.target0_work_en().set_bit());
|
||||||
systimer.int_ena().write(|w| w.target0().set_bit());
|
systimer.int_ena().write(|w| w.target0().set_bit());
|
||||||
}
|
}
|
||||||
|
@ -129,13 +122,13 @@ impl TimerQueueBackend for TimerBackend {
|
||||||
|
|
||||||
fn pend_interrupt() {
|
fn pend_interrupt() {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn cpu_int_31_handler();
|
fn interrupt31();
|
||||||
}
|
}
|
||||||
//run the timer interrupt handler in a critical section to emulate a max priority
|
//run the timer interrupt handler in a critical section to emulate a max priority
|
||||||
//interrupt.
|
//interrupt.
|
||||||
//since there is no hardware support for pending a timer interrupt.
|
//since there is no hardware support for pending a timer interrupt.
|
||||||
riscv::interrupt::disable();
|
riscv::interrupt::disable();
|
||||||
unsafe { cpu_int_31_handler() };
|
unsafe { interrupt31() };
|
||||||
unsafe { riscv::interrupt::enable() };
|
unsafe { riscv::interrupt::enable() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +155,7 @@ macro_rules! esp32c3_systimer_monotonic {
|
||||||
///
|
///
|
||||||
/// This method must be called only once.
|
/// This method must be called only once.
|
||||||
pub fn start(timer: esp32c3::SYSTIMER) {
|
pub fn start(timer: esp32c3::SYSTIMER) {
|
||||||
#[export_name = "cpu_int_31_handler"]
|
#[export_name = "interrupt31"]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn Systimer() {
|
unsafe extern "C" fn Systimer() {
|
||||||
use $crate::TimerQueueBackend;
|
use $crate::TimerQueueBackend;
|
||||||
|
|
|
@ -13,6 +13,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
- Use `riscv-slic` from `crates.io`
|
- Use `riscv-slic` from `crates.io`
|
||||||
- Replace `atomic-polyfill` with `portable-atomic`
|
- Replace `atomic-polyfill` with `portable-atomic`
|
||||||
- Remove unused dependency `rtic-monotonics`
|
- Remove unused dependency `rtic-monotonics`
|
||||||
|
- Updated esp32c3 dependency to v0.25.0
|
||||||
|
|
||||||
## [v2.1.1] - 2024-03-13
|
## [v2.1.1] - 2024-03-13
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ name = "rtic"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
riscv-slic = { version = "0.1.1", optional = true }
|
riscv-slic = { version = "0.1.1", optional = true }
|
||||||
esp32c3 = { version = "0.22.0", optional = true }
|
esp32c3 = { version = "0.25.0", optional = true }
|
||||||
riscv = { version = "0.11.0", optional = true }
|
riscv = { version = "0.11.0", optional = true }
|
||||||
cortex-m = { version = "0.7.0", optional = true }
|
cortex-m = { version = "0.7.0", optional = true }
|
||||||
bare-metal = "1.0.0"
|
bare-metal = "1.0.0"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use esp32c3::INTERRUPT_CORE0; //priority threshold control
|
use esp32c3::INTERRUPT_CORE0;
|
||||||
pub use esp32c3::{Interrupt, Peripherals};
|
pub use esp32c3::{Interrupt, Peripherals};
|
||||||
pub use riscv::interrupt;
|
pub use riscv::{interrupt, register::mcause};
|
||||||
pub use riscv::register::mcause; //low level interrupt enable/disable
|
|
||||||
|
|
||||||
#[cfg(all(feature = "riscv-esp32c3", not(feature = "riscv-esp32c3-backend")))]
|
#[cfg(all(feature = "riscv-esp32c3", not(feature = "riscv-esp32c3-backend")))]
|
||||||
compile_error!("Building for the esp32c3, but 'riscv-esp32c3-backend not selected'");
|
compile_error!("Building for the esp32c3, but 'riscv-esp32c3-backend not selected'");
|
||||||
|
@ -138,28 +137,20 @@ pub fn unpend(int: Interrupt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable(int: Interrupt, prio: u8, cpu_int_id: u8) {
|
pub fn enable(int: Interrupt, prio: u8, cpu_int_id: u8) {
|
||||||
const INTERRUPT_MAP_BASE: u32 = 0x600c2000; //this isn't exposed properly in the PAC,
|
|
||||||
//should maybe figure out a workaround that
|
|
||||||
//doesnt involve raw pointers.
|
|
||||||
//Again, this is how they do it in the HAL
|
|
||||||
//but i'm really not a fan.
|
|
||||||
let interrupt_number = int as isize;
|
|
||||||
let cpu_interrupt_number = cpu_int_id as isize;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let intr_map_base = INTERRUPT_MAP_BASE as *mut u32;
|
// Map the peripheral interrupt to a CPU interrupt:
|
||||||
intr_map_base
|
(INTERRUPT_CORE0::ptr() as *mut u32)
|
||||||
.offset(interrupt_number)
|
.offset(int as isize)
|
||||||
.write_volatile(cpu_interrupt_number as u32);
|
.write_volatile(cpu_int_id as u32);
|
||||||
//map peripheral interrupt to CPU interrupt
|
|
||||||
|
// Set the interrupt's priority:
|
||||||
|
(*INTERRUPT_CORE0::ptr())
|
||||||
|
.cpu_int_pri(cpu_int_id as usize)
|
||||||
|
.modify(|_, w| w.bits(prio as u32));
|
||||||
|
|
||||||
|
// Finally, enable the CPU interrupt:
|
||||||
(*INTERRUPT_CORE0::ptr())
|
(*INTERRUPT_CORE0::ptr())
|
||||||
.cpu_int_enable()
|
.cpu_int_enable()
|
||||||
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); //enable the CPU interupt.
|
.modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
|
||||||
let intr = INTERRUPT_CORE0::ptr();
|
|
||||||
let intr_prio_base = (*intr).cpu_int_pri_0().as_ptr();
|
|
||||||
|
|
||||||
intr_prio_base
|
|
||||||
.offset(cpu_interrupt_number)
|
|
||||||
.write_volatile(prio as u32);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue