20 Commits

Author SHA1 Message Date
muellerr 0d1bd3aa47 Merge pull request 'also bump version number' (#36) from bump-version-number into main
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
Reviewed-on: #36
2026-05-18 21:01:51 +02:00
Robin Mueller 09ba2d3675 also bump version number
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
shared-hal-ci / Check build (pull_request) Waiting to run
shared-hal-ci / Check formatting (pull_request) Waiting to run
shared-hal-ci / Check Documentation Build (pull_request) Waiting to run
shared-hal-ci / Clippy (pull_request) Waiting to run
va108xx-ci / Check build (pull_request) Waiting to run
va108xx-ci / Run Tests (pull_request) Waiting to run
va108xx-ci / Check formatting (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (pull_request) Waiting to run
va108xx-ci / Clippy (pull_request) Waiting to run
va416xx-ci / Check build (pull_request) Waiting to run
va416xx-ci / Run Tests (pull_request) Waiting to run
va416xx-ci / Check formatting (pull_request) Waiting to run
va416xx-ci / Check Documentation Build (pull_request) Waiting to run
va416xx-ci / Clippy (pull_request) Waiting to run
2026-05-18 20:59:37 +02:00
muellerr 6225b8d183 Merge pull request 'prepare shared HAL release' (#35) from prep-shared-hal-release into main
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
Reviewed-on: #35
2026-05-18 20:57:25 +02:00
Robin Mueller 1138b65203 prepare shared HAL release
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
shared-hal-ci / Check build (pull_request) Waiting to run
shared-hal-ci / Check formatting (pull_request) Waiting to run
shared-hal-ci / Check Documentation Build (pull_request) Waiting to run
shared-hal-ci / Clippy (pull_request) Waiting to run
va108xx-ci / Check build (pull_request) Waiting to run
va108xx-ci / Run Tests (pull_request) Waiting to run
va108xx-ci / Check formatting (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (pull_request) Waiting to run
va108xx-ci / Clippy (pull_request) Waiting to run
va416xx-ci / Check build (pull_request) Waiting to run
va416xx-ci / Run Tests (pull_request) Waiting to run
va416xx-ci / Check formatting (pull_request) Waiting to run
va416xx-ci / Check Documentation Build (pull_request) Waiting to run
va416xx-ci / Clippy (pull_request) Waiting to run
2026-05-18 20:55:30 +02:00
muellerr d36282d34b Merge pull request 'bump fugit to v0.4' (#34) from bump-fugit-dep into main
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
Reviewed-on: #34
2026-05-18 20:52:25 +02:00
Robin Mueller 15fed28281 bump fugit to v0.4
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Check build (pull_request) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
shared-hal-ci / Check formatting (pull_request) Waiting to run
shared-hal-ci / Check Documentation Build (pull_request) Waiting to run
shared-hal-ci / Clippy (pull_request) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check build (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Run Tests (pull_request) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va108xx-ci / Check formatting (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (pull_request) Waiting to run
va108xx-ci / Clippy (pull_request) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Check build (pull_request) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
va416xx-ci / Run Tests (pull_request) Waiting to run
va416xx-ci / Check formatting (pull_request) Waiting to run
va416xx-ci / Check Documentation Build (pull_request) Waiting to run
va416xx-ci / Clippy (pull_request) Waiting to run
2026-05-18 20:51:00 +02:00
muellerr adad36db89 Merge pull request 'invert Pull enum' (#33) from bugfix-pull-enum into main
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
Reviewed-on: #33
2026-05-18 20:27:07 +02:00
Robin Mueller e1b3abcba9 invert Pull enum
shared-hal-ci / Check build (push) Waiting to run
shared-hal-ci / Check formatting (push) Waiting to run
shared-hal-ci / Check Documentation Build (push) Waiting to run
shared-hal-ci / Clippy (push) Waiting to run
shared-hal-ci / Check build (pull_request) Waiting to run
shared-hal-ci / Check formatting (pull_request) Waiting to run
shared-hal-ci / Check Documentation Build (pull_request) Waiting to run
shared-hal-ci / Clippy (pull_request) Waiting to run
va108xx-ci / Check build (push) Waiting to run
va108xx-ci / Run Tests (push) Waiting to run
va108xx-ci / Check formatting (push) Waiting to run
va108xx-ci / Check build (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (push) Waiting to run
va108xx-ci / Run Tests (pull_request) Waiting to run
va108xx-ci / Clippy (push) Waiting to run
va108xx-ci / Check formatting (pull_request) Waiting to run
va108xx-ci / Check Documentation Build (pull_request) Waiting to run
va108xx-ci / Clippy (pull_request) Waiting to run
va416xx-ci / Check build (push) Waiting to run
va416xx-ci / Run Tests (push) Waiting to run
va416xx-ci / Check formatting (push) Waiting to run
va416xx-ci / Check build (pull_request) Waiting to run
va416xx-ci / Check Documentation Build (push) Waiting to run
va416xx-ci / Run Tests (pull_request) Waiting to run
va416xx-ci / Clippy (push) Waiting to run
va416xx-ci / Check formatting (pull_request) Waiting to run
va416xx-ci / Check Documentation Build (pull_request) Waiting to run
va416xx-ci / Clippy (pull_request) Waiting to run
2026-05-18 20:26:50 +02:00
muellerr 682655c036 Merge pull request 'improvements for SPI driver' (#31) from improvements-spi into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/31
2026-05-04 11:50:47 +02:00
Robin Mueller 79b6f6124b improvements for SPI driver
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
2026-05-04 11:48:45 +02:00
muellerr 2424fbf075 Merge pull request 'more robustness improvements for async SPI' (#30) from more-robustness-improvements-for-spi into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/30
2026-05-01 16:02:40 +02:00
Robin Mueller eb41170fa2 more robustness improvements for async SPI
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
2026-05-01 15:59:08 +02:00
muellerr 8108beb70f Merge pull request 'more SPI cleanup' (#29) from more-spi-cleanup into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/29
2026-04-30 11:01:15 +02:00
Robin Mueller 4493cddb32 more SPI cleanup
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
2026-04-30 10:55:24 +02:00
muellerr f8114ba3f3 Merge pull request 'more SPI improvements' (#28) from spi-tweaks into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/28
2026-04-29 23:28:24 +02:00
Robin Mueller 6f0890c6b2 more improvements
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
2026-04-29 23:23:26 +02:00
muellerr 3fcc13a179 Merge pull request 'possible fixes for async SPI' (#27) from possible-fixes-async-spi into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/27
2026-04-29 22:15:39 +02:00
Robin Mueller 427862d54b possible fixes for async SPI
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
2026-04-29 22:07:06 +02:00
muellerr db26553ed4 Merge pull request 'possible bugfix for asynch GPIO' (#25) from possible-bugfixes-gpio-asynch into main
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
Reviewed-on: http://localhost:3000/rust/vorago-rs/pulls/25
2026-04-27 11:15:55 +02:00
Robin Mueller 232b3e8c39 possible bugfix for asynch GPIO
shared-hal-ci / Check build (push) Has been cancelled
shared-hal-ci / Check formatting (push) Has been cancelled
shared-hal-ci / Check Documentation Build (push) Has been cancelled
shared-hal-ci / Clippy (push) Has been cancelled
shared-hal-ci / Check build (pull_request) Has been cancelled
shared-hal-ci / Check formatting (pull_request) Has been cancelled
shared-hal-ci / Check Documentation Build (pull_request) Has been cancelled
shared-hal-ci / Clippy (pull_request) Has been cancelled
va108xx-ci / Check build (push) Has been cancelled
va108xx-ci / Run Tests (push) Has been cancelled
va108xx-ci / Check formatting (push) Has been cancelled
va108xx-ci / Check Documentation Build (push) Has been cancelled
va108xx-ci / Clippy (push) Has been cancelled
va108xx-ci / Check build (pull_request) Has been cancelled
va108xx-ci / Run Tests (pull_request) Has been cancelled
va108xx-ci / Check formatting (pull_request) Has been cancelled
va108xx-ci / Check Documentation Build (pull_request) Has been cancelled
va108xx-ci / Clippy (pull_request) Has been cancelled
va416xx-ci / Check build (push) Has been cancelled
va416xx-ci / Run Tests (push) Has been cancelled
va416xx-ci / Check formatting (push) Has been cancelled
va416xx-ci / Check Documentation Build (push) Has been cancelled
va416xx-ci / Clippy (push) Has been cancelled
va416xx-ci / Check build (pull_request) Has been cancelled
va416xx-ci / Run Tests (pull_request) Has been cancelled
va416xx-ci / Check formatting (pull_request) Has been cancelled
va416xx-ci / Check Documentation Build (pull_request) Has been cancelled
va416xx-ci / Clippy (pull_request) Has been cancelled
2026-04-27 11:14:33 +02:00
38 changed files with 406 additions and 275 deletions
+1 -1
View File
@@ -161,7 +161,7 @@ fn main() -> ! {
delay_timer.delay_ms(500);
}
let ahb_freq: Hertz = 50.MHz();
let mut syst_delay = cortex_m::delay::Delay::new(cp.SYST, ahb_freq.raw());
let mut syst_delay = cortex_m::delay::Delay::new(cp.SYST, ahb_freq.to_raw());
// Release image should be used to verify timings for pin PA0
for _ in 0..5 {
pa0.toggle();
+5 -4
View File
@@ -4,8 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
cfg-if = "1"
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
cfg-if = "1"
embedded-hal-async = "1"
embedded-io = "0.7"
embedded-io-async = "0.7"
@@ -18,10 +19,10 @@ panic-probe = { version = "1", features = ["print-defmt"] }
critical-section = "1"
embassy-sync = "0.7"
embassy-sync = "0.8"
embassy-time = "0.5"
embassy-executor = { version = "0.9", features = [
"arch-cortex-m",
embassy-executor = { version = "0.10", features = [
"platform-cortex-m",
"executor-thread",
"executor-interrupt"
]}
+30 -28
View File
@@ -62,6 +62,9 @@ async fn main(spawner: Spawner) {
// Safety: Only called once here.
va108xx_embassy::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
unsafe {
cortex_m::interrupt::enable();
}
let porta = PinsA::new(dp.porta);
let portb = PinsB::new(dp.portb);
@@ -71,36 +74,35 @@ async fn main(spawner: Spawner) {
let out_pb22 = Output::new(portb.pb22, PinState::Low);
let in_pb23 = Input::new_floating(portb.pb23);
let mut in_pa1_async = InputPinAsync::new(in_pa1, pac::Interrupt::OC10);
let mut in_pb23_async = InputPinAsync::new(in_pb23, PB22_TO_PB23_IRQ);
let mut in_pa1_async = InputPinAsync::new(
in_pa1,
va108xx_hal::InterruptConfig::new(pac::Interrupt::OC10, true, true),
);
let mut in_pb23_async = InputPinAsync::new(
in_pb23,
va108xx_hal::InterruptConfig::new(PB22_TO_PB23_IRQ, true, true),
);
spawner
.spawn(output_task(
"PA0 to PA1",
out_pa0,
CHANNEL_PA0_PA1.receiver(),
))
.unwrap();
spawner
.spawn(output_task(
"PB22 to PB23",
out_pb22,
CHANNEL_PB22_TO_PB23.receiver(),
))
.unwrap();
spawner.spawn(output_task("PA0 to PA1", out_pa0, CHANNEL_PA0_PA1.receiver()).unwrap());
spawner.spawn(output_task("PB22 to PB23", out_pb22, CHANNEL_PB22_TO_PB23.receiver()).unwrap());
if CHECK_PA0_TO_PA1 {
check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_PA1.sender(), &mut in_pa1_async).await;
defmt::info!("Example PA0 to PA1 done");
}
if CHECK_PB22_TO_PB23 {
check_pin_to_pin_async_ops(
"PB22 to PB23",
CHANNEL_PB22_TO_PB23.sender(),
&mut in_pb23_async,
)
.await;
defmt::info!("Example PB22 to PB23 done");
for i in 0..3 {
defmt::info!("Starting async GPIO operations check {}", i);
if CHECK_PA0_TO_PA1 {
check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_PA1.sender(), &mut in_pa1_async)
.await;
defmt::info!("Example PA0 to PA1 done");
}
if CHECK_PB22_TO_PB23 {
check_pin_to_pin_async_ops(
"PB22 to PB23",
CHANNEL_PB22_TO_PB23.sender(),
&mut in_pb23_async,
)
.await;
defmt::info!("Example PB22 to PB23 done");
}
Timer::after(Duration::from_millis(500)).await;
}
defmt::info!("Example done, toggling LED0");
@@ -97,9 +97,7 @@ async fn main(spawner: Spawner) {
});
let mut async_rx_uart_a = RxAsync::new(rx_uart_a, cons_uart_a);
let async_rx_uart_b = RxAsyncOverwriting::new(rx_uart_b, &CONSUMER_UART_B);
spawner
.spawn(uart_b_task(async_rx_uart_b, tx_uart_b))
.unwrap();
spawner.spawn(uart_b_task(async_rx_uart_b, tx_uart_b).unwrap());
let mut buf = [0u8; 256];
loop {
defmt::info!("Current time UART A: {}", Instant::now().as_secs());
+1
View File
@@ -9,6 +9,7 @@ embedded-io = "0.7"
defmt-rtt = "1"
defmt = "1"
panic-probe = { version = "1", features = ["defmt"] }
fugit = "0.4"
rtic = { version = "2", features = ["thumbv6-backend"] }
rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
@@ -43,7 +43,7 @@ mod app {
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
defmt::println!("-- Vorago Button IRQ Example --");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
Mono::start(cx.core.SYST, SYSCLK_FREQ.to_raw());
let mode = DEFAULT_MODE;
defmt::info!("Using {:?} mode", mode);
@@ -20,11 +20,11 @@ mod app {
use panic_probe as _;
// Import global logger.
use defmt_rtt as _;
use rtic_monotonics::fugit::ExtU32 as _;
use rtic_monotonics::Monotonic;
use va108xx_hal::{
pac,
pins::PinsA,
prelude::*,
uart::{self, RxWithInterrupt, Tx},
InterruptConfig,
};
@@ -46,15 +46,18 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) {
defmt::println!("-- VA108xx UART Echo with IRQ example application--");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
Mono::start(cx.core.SYST, SYSCLK_FREQ.to_raw());
let dp = cx.device;
let gpioa = PinsA::new(dp.porta);
let tx = gpioa.pa9;
let rx = gpioa.pa8;
let clock_config =
uart::ClockConfig::calculate(SYSCLK_FREQ, 115200.Hz(), uart::BaudMode::_16);
let clock_config = uart::ClockConfig::calculate(
SYSCLK_FREQ,
fugit::HertzU32::from_raw(115200),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let irq_uart = uart::Uart::new_with_interrupt_uart0(
dp.uarta,
+1 -1
View File
@@ -34,7 +34,7 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) {
defmt::println!("-- Vorago VA108xx RTIC template --");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
Mono::start(cx.core.SYST, SYSCLK_FREQ.to_raw());
let porta = PinsA::new(cx.device.porta);
let led0 = Output::new(porta.pa10, PinState::Low);
@@ -46,8 +46,8 @@ fn main() -> ! {
}
let sys_clk: Hertz = 50.MHz();
let cnt_ms = sys_clk.raw() / 1000 - 1;
let cnt_sec = sys_clk.raw() - 1;
let cnt_ms = sys_clk.to_raw() / 1000 - 1;
let cnt_sec = sys_clk.to_raw() - 1;
unsafe {
dp.tim0.cnt_value().write(|w| w.bits(cnt_ms));
dp.tim0.rst_value().write(|w| w.bits(cnt_ms));
+1
View File
@@ -13,6 +13,7 @@ panic-probe = { version = "1", features = ["print-defmt"] }
num_enum = { version = "0.7", default-features = false }
cobs = { version = "0.5", default-features = false }
satrs = { version = "0.3.0-alpha.3", default-features = false, features = ["defmt"] }
fugit = "0.4"
arbitrary-int = "2"
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
# spacepackets = { version = "0.17", path = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false, features = ["defmt"] }
+10 -6
View File
@@ -10,7 +10,8 @@ use ringbuf::{
traits::{Consumer, Observer, Producer},
StaticRb,
};
use va108xx_hal::prelude::*;
use rtic_monotonics::fugit::ExtU32;
use va108xx_hal::time::Hertz;
const SYSCLK_FREQ: Hertz = Hertz::from_raw(50_000_000);
@@ -64,7 +65,7 @@ mod app {
use cortex_m::asm;
use embedded_io::Write;
use rtic::Mutex;
use rtic_monotonics::systick::prelude::*;
use rtic_monotonics::Monotonic;
use satrs::pus::verification::{FailParams, VerificationReportCreator};
use satrs::spacepackets::ecss::PusServiceId;
use satrs::spacepackets::ecss::{
@@ -106,7 +107,7 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) {
defmt::println!("-- Vorago flashloader --");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
Mono::start(cx.core.SYST, SYSCLK_FREQ.to_raw());
let dp = cx.device;
let spi_clock_config = SpiClockConfig::new(2, 4);
@@ -116,8 +117,11 @@ mod app {
let tx = gpioa.pa9;
let rx = gpioa.pa8;
let clock_config =
uart::ClockConfig::calculate(SYSCLK_FREQ, UART_BAUDRATE.Hz(), uart::BaudMode::_16);
let clock_config = uart::ClockConfig::calculate(
SYSCLK_FREQ,
fugit::HertzU32::from_raw(UART_BAUDRATE),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let irq_uart = uart::Uart::new_with_interrupt_uart0(
dp.uarta,
@@ -254,7 +258,7 @@ mod app {
let packet_len = cx.shared.tc_rb.lock(|rb| rb.sizes.try_pop());
if packet_len.is_none() {
// Small delay, TCs might arrive very quickly.
Mono::delay(20.millis()).await;
Mono::delay(20_u32.millis()).await;
continue;
}
let packet_len = packet_len.unwrap();
+1 -1
View File
@@ -11,7 +11,7 @@ keywords = ["no-std", "hal", "cortex-m", "vorago", "va108xx"]
categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies]
vorago-shared-hal = { version = "0.2", path = "../../vorago-shared-hal", features = ["vor1x"] }
vorago-shared-hal = { version = "0.3", path = "../../vorago-shared-hal", features = ["vor1x"] }
va108xx-hal = { version = "0.12", path = "../va108xx-hal" }
[features]
+2 -2
View File
@@ -12,8 +12,8 @@ categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"]}
vorago-shared-hal = { version = "0.2", path = "../../vorago-shared-hal", features = ["vor1x"] }
fugit = "0.3"
vorago-shared-hal = { version = "0.3", path = "../../vorago-shared-hal", features = ["vor1x"] }
fugit = "0.4"
thiserror = { version = "2", default-features = false }
va108xx = { version = "0.6", path = "../va108xx", default-features = false, features = ["critical-section"] }
defmt = { version = "1", optional = true }
+2 -2
View File
@@ -36,7 +36,7 @@ impl Button {
irq_cfg: InterruptConfig,
) {
self.0.configure_edge_interrupt(edge_type);
self.0.enable_interrupt(irq_cfg);
self.0.enable_interrupt(irq_cfg, true);
}
/// Configures an IRQ on level.
@@ -46,7 +46,7 @@ impl Button {
irq_cfg: InterruptConfig,
) {
self.0.configure_level_interrupt(level);
self.0.enable_interrupt(irq_cfg);
self.0.enable_interrupt(irq_cfg, true);
}
/// Configures a filter on the button. This can be useful for debouncing the switch.
+1 -1
View File
@@ -41,7 +41,7 @@ mod app {
.xtal_n_clk_with_src_freq(EXTCLK_FREQ)
.freeze()
.unwrap();
Mono::start(cx.core.SYST, clocks.sysclk().raw());
Mono::start(cx.core.SYST, clocks.sysclk().to_raw());
let pinsg = PinsG::new(cx.device.portg);
let led = Output::new(pinsg.pg5, PinState::Low);
blinky::spawn().ok();
+1 -1
View File
@@ -40,7 +40,7 @@ fn main() -> ! {
.freeze()
.unwrap();
enable_and_init_irq_router();
let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.apb0().raw());
let mut delay = cortex_m::delay::Delay::new(cp.SYST, clocks.apb0().to_raw());
let mut last_interrupt_counter = 0;
let mut wdt_ctrl = Wdt::start(dp.watch_dog, &clocks, WDT_ROLLOVER_MS);
+1
View File
@@ -10,6 +10,7 @@ defmt-rtt = "1"
defmt = "1"
panic-probe = { version = "1", features = ["defmt"] }
static_cell = "2"
fugit = "0.4"
ringbuf = { version = "0.4", default-features = false }
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
satrs = { version = "0.3.0-alpha.3", default-features = false, features = ["defmt"] }
+3 -4
View File
@@ -97,12 +97,12 @@ mod app {
use arbitrary_int::{u11, u14};
use cortex_m::asm;
use embedded_io::Write;
use rtic_monotonics::{fugit::ExtU32, Monotonic};
// Import panic provider.
use panic_probe as _;
// Import logger.
use defmt_rtt as _;
use rtic::Mutex;
use rtic_monotonics::systick::prelude::*;
use satrs::pus::verification::VerificationReportCreator;
use satrs::spacepackets::ecss::PusServiceId;
use satrs::spacepackets::ecss::{
@@ -116,7 +116,6 @@ mod app {
nvm::Nvm,
pac,
pins::PinsG,
prelude::*,
uart::{self, Uart},
};
@@ -171,7 +170,7 @@ mod app {
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
UART_BAUDRATE.Hz(),
fugit::HertzU32::from_raw(UART_BAUDRATE),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
@@ -195,7 +194,7 @@ mod app {
.init(StaticRb::<usize, SIZES_RB_SIZE_TC>::default())
.split_ref();
Mono::start(cx.core.SYST, clocks.sysclk().raw());
Mono::start(cx.core.SYST, clocks.sysclk().to_raw());
CLOCKS.set(clocks).unwrap();
let mut rx = rx.into_rx_with_irq();
+1 -1
View File
@@ -11,7 +11,7 @@ keywords = ["no-std", "hal", "cortex-m", "vorago", "va416xx"]
categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies]
vorago-shared-hal = { version = "0.2", path = "../../vorago-shared-hal", features = ["vor4x"] }
vorago-shared-hal = { version = "0.3", path = "../../vorago-shared-hal", features = ["vor4x"] }
va416xx-hal = { version = "0.6", path = "../va416xx-hal" }
[features]
+2 -2
View File
@@ -15,7 +15,7 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
va416xx = { version = "0.5", path = "../va416xx", features = ["critical-section"], default-features = false }
derive-mmio = "0.6.1"
static_assertions = "1.1"
vorago-shared-hal = { version = "0.2", path = "../../vorago-shared-hal", features = ["vor4x"] }
vorago-shared-hal = { version = "0.3", path = "../../vorago-shared-hal", features = ["vor4x"] }
libm = "0.2"
nb = "1"
@@ -24,7 +24,7 @@ num_enum = { version = "0.7", default-features = false }
bitflags = "2"
bitbybit = "2"
arbitrary-int = "2"
fugit = "0.3"
fugit = "0.4"
embedded-can = "0.4"
embassy-sync = "0.8"
thiserror = { version = "2", default-features = false }
+9 -8
View File
@@ -150,18 +150,19 @@ impl ClockConfig {
tseg2: u8,
sjw: u8,
) -> Result<ClockConfig, ClockConfigError> {
if bitrate.raw() == 0 {
if bitrate.to_raw() == 0 {
return Err(ClockConfigError::BitrateIsZero);
}
let nominal_bit_time = 1 + tseg1 as u32 + tseg2 as u32;
let prescaler =
roundf(clocks.apb1().raw() as f32 / (bitrate.raw() as f32 * nominal_bit_time as f32))
as u32;
let prescaler = roundf(
clocks.apb1().to_raw() as f32 / (bitrate.to_raw() as f32 * nominal_bit_time as f32),
) as u32;
if !(PRESCALER_MIN as u32..=PRESCALER_MAX as u32).contains(&prescaler) {
return Err(ClockConfigError::CanNotFindPrescaler);
}
let actual_bitrate = (clocks.apb1().raw() as f32) / (prescaler * nominal_bit_time) as f32;
let actual_bitrate =
(clocks.apb1().to_raw() as f32) / (prescaler * nominal_bit_time) as f32;
let bitrate_deviation = calculate_bitrate_deviation(actual_bitrate, bitrate);
if bitrate_deviation > MAX_BITRATE_DEVIATION {
return Err(ClockConfigError::BitrateErrorTooLarge);
@@ -269,17 +270,17 @@ pub const fn calculate_nominal_bit_time(
target_bitrate: Hertz,
prescaler: u8,
) -> u32 {
apb1_clock.raw() / (target_bitrate.raw() * prescaler as u32)
apb1_clock.to_raw() / (target_bitrate.to_raw() * prescaler as u32)
}
#[inline]
pub const fn calculate_actual_bitrate(apb1_clock: Hertz, prescaler: u8, nom_bit_time: u32) -> f32 {
apb1_clock.raw() as f32 / (prescaler as u32 * nom_bit_time) as f32
apb1_clock.to_raw() as f32 / (prescaler as u32 * nom_bit_time) as f32
}
#[inline]
pub const fn calculate_bitrate_deviation(actual_bitrate: f32, target_bitrate: Hertz) -> f32 {
(actual_bitrate - target_bitrate.raw() as f32).abs() / target_bitrate.raw() as f32
(actual_bitrate - target_bitrate.to_raw() as f32).abs() / target_bitrate.to_raw() as f32
}
pub trait CanInstance {
+4 -4
View File
@@ -94,9 +94,9 @@ pub struct PllConfig {
pub const fn clock_after_division(clk: Hertz, div_sel: ClockDivisorSelect) -> Hertz {
match div_sel {
ClockDivisorSelect::Div1 => clk,
ClockDivisorSelect::Div2 => Hertz::from_raw(clk.raw() / 2),
ClockDivisorSelect::Div4 => Hertz::from_raw(clk.raw() / 4),
ClockDivisorSelect::Div8 => Hertz::from_raw(clk.raw() / 8),
ClockDivisorSelect::Div2 => Hertz::from_raw(clk.to_raw() / 2),
ClockDivisorSelect::Div4 => Hertz::from_raw(clk.to_raw() / 4),
ClockDivisorSelect::Div8 => Hertz::from_raw(clk.to_raw() / 8),
}
}
@@ -382,7 +382,7 @@ impl ClockConfigurator {
// ADC clock (must be 2-12.5 MHz)
// NOTE: Not using divide by 1 or /2 ratio in REVA silicon because of triggering issue
// For this reason, keep SYSCLK above 8MHz to have the ADC /4 ratio in range)
if final_sysclk.raw() <= ADC_MAX_CLK.raw() * 4 {
if final_sysclk.to_raw() <= ADC_MAX_CLK.to_raw() * 4 {
self.clkgen.ctrl1().modify(|_, w| unsafe {
w.adc_clk_div_sel().bits(AdcClockDivisorSelect::Div4 as u8)
});
+1 -1
View File
@@ -58,7 +58,7 @@ impl Wdt {
#[inline]
pub fn set_freq(&mut self, freq_ms: u32) {
let counter = (self.clock_freq.raw() / 1000) * freq_ms;
let counter = (self.clock_freq.to_raw() / 1000) * freq_ms;
self.wdt.wdogload().write(|w| unsafe { w.bits(counter) });
}
+8 -1
View File
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v0.3.0] 2026-05-18
### Added
- Add `is_high` and `is_low` for `InputPinAsync`.
@@ -16,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Bumped `fugit` from v0.3 to v0.4
- Added `RxWithInterrupt::steal`.
- Renamed UART `Data` register `value` field to `data`
- Improved type level support for resource management for SPI, PWM, UART.
@@ -26,10 +29,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- `Pull::Up` and `Pull::High` were inverted.
- Removed HW CS pin provider implementation for PA23, PA22 and PA21, which are multi HW CS pins.
- Added missing `AnyPin` trait impl for Multi HW CS pins.
- Expose inner `Input` pin for `InputPinAsync`.
- Bugfix for UART clock calculation with 8x baud mode.
- Possible bugfix for Asynch GPIO where the interrupt handler could become stuck in a loop.
- Robustness improvements for the Asynch GPIO driver code.
## [v0.2.0] 2025-09-03
@@ -51,6 +57,7 @@ Renamed to `vorago-shared-hal`
Init commit.
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/vorago-shared-hal/compare/v0.2.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/vorago-shared-hal/compare/v0.3.0...HEAD
[v0.3.0]: https://egit.irs.uni-stuttgart.de/rust/vorago-shared-hal/compare/v0.2.0...v0.3.0
[v0.2.0]: https://egit.irs.uni-stuttgart.de/rust/vorago-shared-hal/compare/v0.1.0...v0.2.0
[v0.1.0]: https://egit.irs.uni-stuttgart.de/rust/vorago-shared-hal/src/tag/v0.1.0
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "vorago-shared-hal"
version = "0.2.0"
version = "0.3.0"
description = "Peripheral HAL components shared between Vorago families"
edition = "2024"
homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-rs"
@@ -25,11 +25,11 @@ embedded-io-async = "0.7"
raw-slicee = "0.1"
thiserror = { version = "2", default-features = false }
paste = "1"
fugit = "0.3"
fugit = "0.4"
defmt = { version = "1", optional = true }
va108xx = { version = "0.6", path = "../va108xx/va108xx", default-features = false, optional = true }
va416xx = { version = "0.5", path = "../va416xx/va416xx", default-features = false, optional = true }
embassy-sync = "0.7"
embassy-sync = "0.8"
embassy-time-driver = "0.2"
embassy-time-queue-utils = "0.3"
once_cell = { version = "1", default-features = false, features = [
+4 -2
View File
@@ -79,7 +79,9 @@ impl TimerDriver {
let mut timekeeper_reg_block = unsafe { TimekeeperTim::ID.steal_regs() };
let mut alarm_tim_reg_block = unsafe { AlarmTim::ID.steal_regs() };
// Initiate scale value here. This is required to convert timer ticks back to a timestamp.
SCALE.set((sysclk.raw() / TICK_HZ as u32) as u64).unwrap();
SCALE
.set((sysclk.to_raw() / TICK_HZ as u32) as u64)
.unwrap();
timekeeper_reg_block.write_reset_value(u32::MAX);
// Decrementing counter.
timekeeper_reg_block.write_count_value(u32::MAX);
@@ -137,7 +139,7 @@ impl TimerDriver {
// Initiate scale value here. This is required to convert timer ticks back to a timestamp.
SCALE
.set((TimekeeperTim::clock(clocks).raw() / TICK_HZ as u32) as u64)
.set((TimekeeperTim::clock(clocks).to_raw() / TICK_HZ as u32) as u64)
.unwrap();
timekeeper_regs.write_reset_value(u32::MAX);
// Decrementing counter.
+22 -25
View File
@@ -21,9 +21,6 @@ use crate::{InterruptConfig, NUM_PORT_A, NUM_PORT_B};
#[cfg(feature = "vor4x")]
use super::ll::PortDoesNotSupportInterrupts;
#[cfg(feature = "vor1x")]
use va108xx as pac;
pub use super::ll::InterruptEdge;
use super::{
Input, Port,
@@ -118,7 +115,7 @@ pub fn on_interrupt_for_async_gpio_for_port(
}
fn on_interrupt_for_async_gpio_for_port_generic(port: Port) {
let gpio = unsafe { port.steal_gpio() };
let mut gpio = unsafe { port.steal_regs() };
let irq_enb = gpio.read_irq_enable();
let edge_status = gpio.read_edge_status();
@@ -134,18 +131,19 @@ fn on_interrupt_for_port(
wakers: &'static [AtomicWaker],
edge_detection: &'static [AtomicBool],
) {
// Check all enabled interrupts.
while irq_enb != 0 {
// For all enabled interrupts, check whether the corresponding edge detection has
// triggered.
let bit_pos = irq_enb.trailing_zeros() as usize;
let bit_mask = 1 << bit_pos;
wakers[bit_pos].wake();
if edge_status & bit_mask != 0 {
edge_detection[bit_pos].store(true, core::sync::atomic::Ordering::Relaxed);
// Clear the processed bit
irq_enb &= !bit_mask;
wakers[bit_pos].wake();
}
// Clear the processed bit
irq_enb &= !bit_mask;
}
}
@@ -163,13 +161,12 @@ pub struct InputPinFuture {
impl InputPinFuture {
/// Create a new input pin future from mutable reference to an [Input] pin.
#[cfg(feature = "vor1x")]
pub fn new_with_input_pin(pin: &mut Input, irq: pac::Interrupt, edge: InterruptEdge) -> Self {
pub fn new_with_input_pin(pin: &mut Input, edge: InterruptEdge) -> Self {
let (waker_group, edge_detection_group) =
pin_group_to_waker_and_edge_detection_group(pin.id().port());
edge_detection_group[pin.id().offset()].store(false, core::sync::atomic::Ordering::Relaxed);
pin.configure_edge_interrupt(edge);
#[cfg(feature = "vor1x")]
pin.enable_interrupt(InterruptConfig::new(irq, true, true));
pin.enable_interrupt_gpio_only();
Self {
id: pin.id(),
waker_group,
@@ -186,7 +183,7 @@ impl InputPinFuture {
let (waker_group, edge_detection_group) =
pin_group_to_waker_and_edge_detection_group(pin.id().port());
pin.configure_edge_interrupt(edge);
pin.enable_interrupt(true)?;
pin.enable_interrupt_gpio_only();
Ok(Self {
id: pin.id(),
waker_group,
@@ -223,8 +220,6 @@ impl Future for InputPinFuture {
/// Input pin which has additional asynchronous support.
pub struct InputPinAsync {
pin: Input,
#[cfg(feature = "vor1x")]
irq: va108xx::Interrupt,
}
impl InputPinAsync {
@@ -235,8 +230,10 @@ impl InputPinAsync {
/// generic [on_interrupt_for_async_gpio_for_port] function must be called inside that function
/// for the asynchronous functionality to work.
#[cfg(feature = "vor1x")]
pub fn new(pin: Input, irq: va108xx::Interrupt) -> Self {
Self { pin, irq }
pub fn new(mut pin: Input, irq_config: InterruptConfig) -> Self {
// Do not enable GPIO interrupt bit yet.
pin.enable_interrupt(irq_config, false);
Self { pin }
}
/// Create a new asynchronous input pin from an [Input] pin. The interrupt ID to be used must be
@@ -246,10 +243,12 @@ impl InputPinAsync {
/// generic [on_interrupt_for_async_gpio_for_port] function must be called inside that function
/// for the asynchronous functionality to work.
#[cfg(feature = "vor4x")]
pub fn new(pin: Input) -> Result<Self, PortDoesNotSupportInterrupts> {
pub fn new(mut pin: Input) -> Result<Self, PortDoesNotSupportInterrupts> {
if pin.id().port() == Port::G {
return Err(PortDoesNotSupportInterrupts);
}
// Do not enable GPIO interrupt bit yet.
pin.enable_interrupt(true, false)?;
Ok(Self { pin })
}
@@ -259,8 +258,7 @@ impl InputPinAsync {
pub async fn wait_for_high(&mut self) {
// Unwrap okay, checked pin in constructor.
#[cfg(feature = "vor1x")]
let fut =
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::LowToHigh);
let fut = InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh);
#[cfg(feature = "vor4x")]
let fut =
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh).unwrap();
@@ -300,8 +298,7 @@ impl InputPinAsync {
pub async fn wait_for_low(&mut self) {
// Unwrap okay, checked pin in constructor.
#[cfg(feature = "vor1x")]
let fut =
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::HighToLow);
let fut = InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow);
#[cfg(feature = "vor4x")]
let fut =
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow).unwrap();
@@ -315,7 +312,7 @@ impl InputPinAsync {
pub async fn wait_for_falling_edge(&mut self) {
// Unwrap okay, checked pin in constructor.
#[cfg(feature = "vor1x")]
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::HighToLow).await;
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow).await;
#[cfg(feature = "vor4x")]
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::HighToLow)
.unwrap()
@@ -326,14 +323,14 @@ impl InputPinAsync {
pub async fn wait_for_rising_edge(&mut self) {
// Unwrap okay, checked pin in constructor.
#[cfg(feature = "vor1x")]
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::LowToHigh).await;
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::LowToHigh).await;
}
/// Asynchronously wait until the pin sees any edge (either rising or falling).
pub async fn wait_for_any_edge(&mut self) {
// Unwrap okay, checked pin in constructor.
#[cfg(feature = "vor1x")]
InputPinFuture::new_with_input_pin(&mut self.pin, self.irq, InterruptEdge::BothEdges).await;
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::BothEdges).await;
#[cfg(feature = "vor4x")]
InputPinFuture::new_with_input_pin(&mut self.pin, InterruptEdge::BothEdges)
.unwrap()
+33 -12
View File
@@ -384,32 +384,53 @@ impl LowLevelGpio {
self.gpio.write_tog_out(self.mask_32());
}
#[cfg(feature = "vor1x")]
pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig) {
if irq_cfg.route {
self.configure_irqsel(irq_cfg.id);
}
if irq_cfg.enable_in_nvic {
unsafe { crate::enable_nvic_interrupt(irq_cfg.id) };
}
/// Only enabled GPIO peripheral interrupt bit without enabling the interrupt in NVIC
/// or routing it in the IRQSEL peripheral for VA108xx devices.
#[inline]
pub fn enable_interrupt_gpio_only(&mut self) {
self.gpio.modify_irq_enable(|mut value| {
value |= 1 << self.id.offset;
value
});
}
/// Depending on the configuration parameters, does the following:
///
/// - Routes the interrupt in the IRQSEL peripheral
/// - Enables the interrupt in the NVIC,
/// - Enable the GPIO peripheral interrupt bit for this pin if configured.
#[cfg(feature = "vor1x")]
pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig, gpio: bool) {
if irq_cfg.route {
self.configure_irqsel(irq_cfg.id);
}
if irq_cfg.enable_in_nvic {
unsafe { crate::enable_nvic_interrupt(irq_cfg.id) };
}
if gpio {
self.enable_interrupt_gpio_only();
}
}
/// Depending on the configuration parameters, does the following:
///
/// - Enables the interrupt in the NVIC,
/// - Enable the GPIO peripheral interrupt bit for this pin if configured.
#[cfg(feature = "vor4x")]
pub fn enable_interrupt(
&mut self,
enable_in_nvic: bool,
gpio: bool,
) -> Result<(), PortDoesNotSupportInterrupts> {
if self.id().port() == Port::G {
return Err(PortDoesNotSupportInterrupts);
}
if enable_in_nvic {
unsafe { crate::enable_nvic_interrupt(self.id().irq_unchecked()) };
}
self.gpio.modify_irq_enable(|mut value| {
value |= 1 << self.id.offset;
value
});
if gpio {
self.enable_interrupt_gpio_only();
}
Ok(())
}
+19 -4
View File
@@ -132,19 +132,34 @@ impl Input {
self.0.id()
}
#[cfg(feature = "vor1x")]
#[inline]
pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig) {
self.0.enable_interrupt(irq_cfg);
pub fn enable_interrupt_gpio_only(&mut self) {
self.0.enable_interrupt_gpio_only();
}
/// Depending on the configuration parameters, does the following:
///
/// - Routes the interrupt in the IRQSEL peripheral
/// - Enables the interrupt in the NVIC,
/// - Enable the GPIO peripheral interrupt bit for this pin if configured.
#[cfg(feature = "vor1x")]
#[inline]
pub fn enable_interrupt(&mut self, irq_cfg: crate::InterruptConfig, gpio: bool) {
self.0.enable_interrupt(irq_cfg, gpio);
}
/// Depending on the configuration parameters, does the following:
///
/// - Enables the interrupt in the NVIC,
/// - Enable the GPIO peripheral interrupt bit for this pin if configured.
#[cfg(feature = "vor4x")]
#[inline]
pub fn enable_interrupt(
&mut self,
enable_in_nvic: bool,
gpio: bool,
) -> Result<(), ll::PortDoesNotSupportInterrupts> {
self.0.enable_interrupt(enable_in_nvic)
self.0.enable_interrupt(enable_in_nvic, gpio)
}
#[inline]
+2 -1
View File
@@ -58,7 +58,8 @@ pub struct Gpio {
/// Read-only register which shows enabled and active interrupts. Called IRQ_end by Vorago.
#[mmio(PureRead)]
irq_status: u32,
#[mmio(PureRead)]
// Reading this register clears it.
#[mmio(Read)]
edge_status: u32,
#[cfg(feature = "vor1x")]
+3 -3
View File
@@ -149,12 +149,12 @@ fn calc_clk_div_generic(
speed_mode: I2cSpeed,
) -> Result<u8, ClockTooSlowForFastI2cError> {
if speed_mode == I2cSpeed::Regular100khz {
Ok(((ref_clk.raw() / CLK_100K.raw() / 20) - 1) as u8)
Ok(((ref_clk.to_raw() / CLK_100K.to_raw() / 20) - 1) as u8)
} else {
if ref_clk.raw() < MIN_CLK_400K.raw() {
if ref_clk.to_raw() < MIN_CLK_400K.to_raw() {
return Err(ClockTooSlowForFastI2cError);
}
Ok(((ref_clk.raw() / CLK_400K.raw() / 25) - 1) as u8)
Ok(((ref_clk.to_raw() / CLK_400K.to_raw() / 25) - 1) as u8)
}
}
+2 -2
View File
@@ -39,8 +39,8 @@ pub enum FilterClockSelect {
#[bitbybit::bitenum(u1, exhaustive = true)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Pull {
Up = 0,
Down = 1,
Down = 0,
Up = 1,
}
#[derive(Debug, Eq, PartialEq)]
+1 -1
View File
@@ -137,7 +137,7 @@ impl Port {
/// # Safety
///
/// Circumvents ownership and safety guarantees by the HAL.
pub unsafe fn steal_gpio(&self) -> gpio::regs::MmioGpio<'static> {
pub unsafe fn steal_regs(&self) -> gpio::regs::MmioGpio<'static> {
gpio::regs::Gpio::new_mmio(*self)
}
}
+2 -2
View File
@@ -164,10 +164,10 @@ impl<Mode> PwmPin<Mode> {
pub fn set_period(&mut self, period: impl Into<Hertz>) {
self.current_period = period.into();
// Avoid division by 0
if self.current_period.raw() == 0 {
if self.current_period.to_raw() == 0 {
return;
}
self.current_rst_val = self.ref_clk.raw() / self.current_period.raw();
self.current_rst_val = self.ref_clk.to_raw() / self.current_period.to_raw();
self.regs.write_reset_value(self.current_rst_val);
}
+210 -133
View File
@@ -1,4 +1,4 @@
use core::{cell::RefCell, convert::Infallible};
use core::cell::RefCell;
use arbitrary_int::u5;
use critical_section::Mutex;
@@ -8,7 +8,10 @@ use raw_slice::{RawBufSlice, RawBufSliceMut};
use crate::{
shared::{FifoClear, TriggerLevel},
spi::regs::{Data, InterruptClear, InterruptControl, InterruptStatus},
spi::{
FIFO_DEPTH,
regs::{Data, InterruptClear, InterruptControl},
},
};
#[cfg(feature = "vor1x")]
@@ -23,6 +26,17 @@ static TRANSFER_CONTEXTS: [Mutex<RefCell<TransferContext>>; NUM_SPIS] =
// critical section.
static DONE: [AtomicBool; NUM_SPIS] = [const { AtomicBool::new(false) }; NUM_SPIS];
#[derive(Debug, Clone, Copy, thiserror::Error)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[error("SPI RX FIFO overrun")]
pub struct RxOverrunError;
impl embedded_hal_async::spi::Error for RxOverrunError {
fn kind(&self) -> embedded_hal::spi::ErrorKind {
embedded_hal::spi::ErrorKind::Overrun
}
}
/// This is a generic interrupt handler to handle asynchronous SPI operations for a given
/// SPI peripheral.
///
@@ -30,18 +44,24 @@ static DONE: [AtomicBool; NUM_SPIS] = [const { AtomicBool::new(false) }; NUM_SPI
/// the given SPI bank.
pub fn on_interrupt(peripheral: super::Bank) {
let mut spi = unsafe { peripheral.steal_regs() };
let idx = peripheral as usize;
let interrupt_enabled = spi.read_interrupt_control();
let isr = spi.read_interrupt_status();
// IRQ is not related.
if interrupt_enabled.raw_value() == 0 {
return;
}
let index = peripheral as usize;
let enabled_irqs = spi.read_interrupt_control();
let interrupt_status = spi.read_interrupt_status();
spi.write_interrupt_clear(InterruptClear::ALL);
// Prevent spurious interrupts from messing with out logic here.
spi.write_interrupt_control(InterruptControl::DISABLE_ALL);
spi.write_interrupt_clear(InterruptClear::ALL);
// IRQ is not related.
if enabled_irqs.raw_value() == 0 {
reset_trigger_levels(&mut spi);
spi.write_fifo_clear(FifoClear::ALL);
return;
}
if interrupt_status.rx_overrun() {
// Not sure how to otherwise handle this cleanly..
return handle_rx_overrun(&mut spi, index);
}
let mut context = critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
let context_ref = TRANSFER_CONTEXTS[index].borrow(cs);
*context_ref.borrow()
});
// No transfer active.
@@ -50,30 +70,47 @@ pub fn on_interrupt(peripheral: super::Bank) {
}
let transfer_type = context.transfer_type.unwrap();
match transfer_type {
TransferType::Read => on_interrupt_read(idx, &mut context, &mut spi, isr),
TransferType::Write => on_interrupt_write(idx, &mut context, &mut spi, isr),
TransferType::Transfer => on_interrupt_transfer(idx, &mut context, &mut spi, isr),
TransferType::Read => on_interrupt_read(index, &mut context, &mut spi, enabled_irqs),
TransferType::Write => on_interrupt_write(index, &mut context, &mut spi, enabled_irqs),
TransferType::Transfer => {
on_interrupt_transfer(index, &mut context, &mut spi, enabled_irqs)
}
TransferType::TransferInPlace => {
on_interrupt_transfer_in_place(idx, &mut context, &mut spi, isr)
on_interrupt_transfer_in_place(index, &mut context, &mut spi, enabled_irqs)
}
};
}
fn handle_rx_overrun(spi: &mut super::regs::MmioSpi<'static>, idx: usize) {
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
context_ref.borrow_mut().rx_overrun = true;
});
// Clean up, restore clean state.
reset_trigger_levels(spi);
spi.write_fifo_clear(FifoClear::ALL);
// Interrupts were already disabled and cleared.
DONE[idx].store(true, core::sync::atomic::Ordering::Relaxed);
WAKERS[idx].wake();
}
fn on_interrupt_read(
idx: usize,
context: &mut TransferContext,
spi: &mut super::regs::MmioSpi<'static>,
isr: InterruptStatus,
enabled_irqs: InterruptControl,
) {
let read_slice = unsafe { context.rx_slice.get_mut().unwrap() };
let transfer_len = read_slice.len();
// Read data from RX FIFO first.
let read_len = calculate_read_len(spi, isr, transfer_len, context.rx_progress);
(0..read_len).for_each(|_| {
read_slice[context.rx_progress] = (spi.read_data().data() & 0xFF) as u8;
context.rx_progress += 1;
});
while spi.read_status().rx_not_empty() {
let data = spi.read_data();
if context.rx_progress < transfer_len {
read_slice[context.rx_progress] = (data.data() & 0xFF) as u8;
context.rx_progress += 1;
}
}
// The FIFO still needs to be pumped.
while context.tx_progress < read_slice.len() && spi.read_status().tx_not_full() {
@@ -81,24 +118,25 @@ fn on_interrupt_read(
context.tx_progress += 1;
}
isr_finish_handler(idx, spi, context, transfer_len)
isr_finish_handler(idx, spi, context, transfer_len, enabled_irqs)
}
fn on_interrupt_write(
idx: usize,
context: &mut TransferContext,
spi: &mut super::regs::MmioSpi<'static>,
isr: InterruptStatus,
enabled_irqs: InterruptControl,
) {
let write_slice = unsafe { context.tx_slice.get().unwrap() };
let transfer_len = write_slice.len();
// Read data from RX FIFO first.
let read_len = calculate_read_len(spi, isr, transfer_len, context.rx_progress);
(0..read_len).for_each(|_| {
while spi.read_status().rx_not_empty() {
spi.read_data();
context.rx_progress += 1;
});
if context.rx_progress < transfer_len {
context.rx_progress += 1;
}
}
// Data still needs to be sent
while context.tx_progress < transfer_len && spi.read_status().tx_not_full() {
@@ -108,14 +146,14 @@ fn on_interrupt_write(
context.tx_progress += 1;
}
isr_finish_handler(idx, spi, context, transfer_len)
isr_finish_handler(idx, spi, context, transfer_len, enabled_irqs)
}
fn on_interrupt_transfer(
idx: usize,
context: &mut TransferContext,
spi: &mut super::regs::MmioSpi<'static>,
isr: InterruptStatus,
enabled_irqs: InterruptControl,
) {
let read_slice = unsafe { context.rx_slice.get_mut().unwrap() };
let read_len = read_slice.len();
@@ -125,36 +163,31 @@ fn on_interrupt_transfer(
// Send data first to avoid overwriting data that still needs to be sent.
while context.tx_progress < transfer_len && spi.read_status().tx_not_full() {
if context.tx_progress < write_len {
spi.write_data(Data::new_with_raw_value(
write_slice[context.tx_progress] as u32,
));
} else {
// Dummy write.
spi.write_data(Data::new_with_raw_value(0));
}
spi.write_data(Data::new_with_raw_value(
write_slice.get(context.tx_progress).copied().unwrap_or(0) as u32,
));
// Always increment this.
context.tx_progress += 1;
}
// Read data from RX FIFO.
let read_len = calculate_read_len(spi, isr, transfer_len, context.rx_progress);
(0..read_len).for_each(|_| {
while spi.read_status().rx_not_empty() {
let data = spi.read_data();
if context.rx_progress < read_len {
read_slice[context.rx_progress] = (spi.read_data().data() & 0xFF) as u8;
} else {
spi.read_data();
read_slice[context.rx_progress] = (data.data() & 0xFF) as u8;
}
// Always increment this.
context.rx_progress += 1;
});
}
isr_finish_handler(idx, spi, context, transfer_len)
isr_finish_handler(idx, spi, context, transfer_len, enabled_irqs)
}
fn on_interrupt_transfer_in_place(
idx: usize,
context: &mut TransferContext,
spi: &mut super::regs::MmioSpi<'static>,
isr: InterruptStatus,
enabled_irqs: InterruptControl,
) {
let transfer_slice = unsafe { context.rx_slice.get_mut().unwrap() };
let transfer_len = transfer_slice.len();
@@ -166,29 +199,15 @@ fn on_interrupt_transfer_in_place(
context.tx_progress += 1;
}
// Read data from RX FIFO.
let read_len = calculate_read_len(spi, isr, transfer_len, context.rx_progress);
(0..read_len).for_each(|_| {
transfer_slice[context.rx_progress] = (spi.read_data().data() & 0xFF) as u8;
context.rx_progress += 1;
});
isr_finish_handler(idx, spi, context, transfer_len)
}
fn calculate_read_len(
spi: &mut super::regs::MmioSpi<'static>,
isr: InterruptStatus,
total_read_len: usize,
rx_progress: usize,
) -> usize {
if isr.rx() {
core::cmp::min(super::FIFO_DEPTH, total_read_len - rx_progress)
} else if spi.read_status().rx_not_empty() {
let fifo_level = spi.read_state().rx_fifo();
core::cmp::min(total_read_len - rx_progress, fifo_level as usize)
} else {
0
while spi.read_status().rx_not_empty() {
let data = spi.read_data();
if context.rx_progress < transfer_len {
transfer_slice[context.rx_progress] = (data.data() & 0xFF) as u8;
context.rx_progress += 1;
}
}
isr_finish_handler(idx, spi, context, transfer_len, enabled_irqs)
}
/// Generic handler after RX FIFO and TX FIFO were handled. Checks and handles finished
@@ -198,49 +217,73 @@ fn isr_finish_handler(
spi: &mut super::regs::MmioSpi<'static>,
context: &mut TransferContext,
transfer_len: usize,
enabled: InterruptControl,
) {
// Transfer finish condition.
if context.rx_progress == context.tx_progress && context.rx_progress == transfer_len {
finish_transfer(idx, context, spi);
finish_transfer(spi, idx, context);
return;
}
unfinished_transfer(spi, transfer_len, context.rx_progress);
// If the transfer is done, the context structure was already written back.
// Write back updated context structure.
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
*context_ref.borrow_mut() = *context;
});
unfinished_transfer(spi, transfer_len, context, enabled);
}
fn finish_transfer(
spi: &mut super::regs::MmioSpi<'static>,
idx: usize,
context: &mut TransferContext,
spi: &mut super::regs::MmioSpi<'static>,
) {
// Write back updated context structure.
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
*context_ref.borrow_mut() = *context;
});
spi.write_rx_fifo_trigger(TriggerLevel::new(u5::new(0x08)));
spi.write_tx_fifo_trigger(TriggerLevel::new(u5::new(0x00)));
// Clean up, restore clean state.
reset_trigger_levels(spi);
spi.write_fifo_clear(FifoClear::ALL);
// Interrupts were already disabled and cleared.
DONE[idx].store(true, core::sync::atomic::Ordering::Relaxed);
WAKERS[idx].wake();
}
#[inline]
fn unfinished_transfer(
spi: &mut super::regs::MmioSpi<'static>,
transfer_len: usize,
rx_progress: usize,
context: &TransferContext,
enabled_irqs: InterruptControl,
) {
let new_trig_level = core::cmp::min(super::FIFO_DEPTH, transfer_len - rx_progress);
// Take 8 as a conservative value to make sure that the FIFO does not overflow even if there
// is a significant delay between the interrupt being triggered and the handler being executed.
let new_trig_level = core::cmp::min(8, transfer_len - context.rx_progress);
spi.write_rx_fifo_trigger(TriggerLevel::new(u5::new(new_trig_level as u8)));
// If TX was already enabled and the transfer is finished, stop enabling it. Otherwise, we can
// become stuck in an interrupt loop. In any other case, enable it. I am not fully sure
// why this is necessary and why we can not stop interrupts as soon as we have the full
// TX progress, but tests with ADCs have shown that not doing this causes timeouts.
let enable_tx = !(enabled_irqs.tx() && context.tx_progress == transfer_len);
// Re-enable interrupts with the new RX FIFO trigger level.
spi.write_interrupt_control(InterruptControl::ENABLE_ALL);
spi.write_interrupt_control(
InterruptControl::builder()
.with_tx(enable_tx)
.with_rx(true)
.with_rx_timeout(true)
.with_rx_overrun(true)
.build(),
);
}
#[inline]
fn reset_trigger_levels(spi: &mut super::regs::MmioSpi<'static>) {
spi.write_rx_fifo_trigger(TriggerLevel::new(u5::new(0x08)));
spi.write_tx_fifo_trigger(TriggerLevel::new(u5::new(0x00)));
}
#[derive(Debug, Clone, Copy)]
@@ -259,6 +302,7 @@ pub struct TransferContext {
rx_progress: usize,
tx_slice: RawBufSlice,
rx_slice: RawBufSliceMut,
rx_overrun: bool,
}
#[allow(clippy::new_without_default)]
@@ -270,6 +314,7 @@ impl TransferContext {
rx_progress: 0,
tx_slice: RawBufSlice::new_nulled(),
rx_slice: RawBufSliceMut::new_nulled(),
rx_overrun: false,
}
}
}
@@ -285,33 +330,30 @@ impl<'spi> SpiFuture<'spi> {
if words.is_empty() {
panic!("words length unexpectedly 0");
}
let idx = bank as usize;
DONE[idx].store(false, core::sync::atomic::Ordering::Relaxed);
spi.regs
.write_interrupt_control(InterruptControl::DISABLE_ALL);
spi.regs.write_fifo_clear(FifoClear::ALL);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(true));
let write_idx = core::cmp::min(super::FIFO_DEPTH, words.len());
Self::generic_init_transfer(spi, bank);
let write_index = core::cmp::min(super::FIFO_DEPTH, words.len());
// Send dummy bytes.
(0..write_idx).for_each(|_| {
(0..write_index).for_each(|_| {
spi.regs.write_data(Data::new_with_raw_value(0));
});
Self::set_triggers(spi, write_idx, words.len());
Self::set_triggers(spi, write_index, words.len());
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
let context_ref = TRANSFER_CONTEXTS[bank as usize].borrow(cs);
let mut context = context_ref.borrow_mut();
context.transfer_type = Some(TransferType::Read);
unsafe {
context.rx_slice.set(words);
}
context.tx_slice.set_null();
context.tx_progress = write_idx;
context.tx_progress = write_index;
context.rx_progress = 0;
spi.regs.write_interrupt_clear(InterruptClear::ALL);
spi.regs
.write_interrupt_control(InterruptControl::ENABLE_ALL);
spi.regs.write_interrupt_control(
InterruptControl::ENABLE_ALL.with_tx(words.len() > FIFO_DEPTH),
);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(false));
});
Self {
@@ -325,20 +367,22 @@ impl<'spi> SpiFuture<'spi> {
if words.is_empty() {
panic!("words length unexpectedly 0");
}
let (idx, write_idx) = Self::generic_init_transfer(spi, bank, words);
let index = bank as usize;
let write_index = Self::generic_init_transfer_write_transfer_in_place(spi, bank, words);
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
let context_ref = TRANSFER_CONTEXTS[index].borrow(cs);
let mut context = context_ref.borrow_mut();
context.transfer_type = Some(TransferType::Write);
unsafe {
context.tx_slice.set(words);
}
context.rx_slice.set_null();
context.tx_progress = write_idx;
context.tx_progress = write_index;
context.rx_progress = 0;
spi.regs.write_interrupt_clear(InterruptClear::ALL);
spi.regs
.write_interrupt_control(InterruptControl::ENABLE_ALL);
spi.regs.write_interrupt_control(
InterruptControl::ENABLE_ALL.with_tx(words.len() > FIFO_DEPTH),
);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(false));
});
Self {
@@ -350,31 +394,44 @@ impl<'spi> SpiFuture<'spi> {
fn new_for_transfer(
spi: &'spi mut super::Spi<u8>,
spi_id: super::Bank,
bank: super::Bank,
read: &mut [u8],
write: &[u8],
) -> Self {
if read.is_empty() || write.is_empty() {
panic!("read or write buffer unexpectedly empty");
}
let (idx, write_idx) = Self::generic_init_transfer(spi, spi_id, write);
let index = bank as usize;
let full_write_len = core::cmp::max(read.len(), write.len());
let fifo_prefill = core::cmp::min(super::FIFO_DEPTH, full_write_len);
Self::generic_init_transfer(spi, bank);
for write_index in 0..fifo_prefill {
let value = write.get(write_index).copied().unwrap_or(0);
spi.regs.write_data(Data::new_with_raw_value(value as u32));
}
Self::set_triggers(spi, fifo_prefill, full_write_len);
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
let context_ref = TRANSFER_CONTEXTS[index].borrow(cs);
let mut context = context_ref.borrow_mut();
context.transfer_type = Some(TransferType::Transfer);
unsafe {
context.tx_slice.set(write);
context.rx_slice.set(read);
}
context.tx_progress = write_idx;
context.tx_progress = fifo_prefill;
context.rx_progress = 0;
spi.regs.write_interrupt_clear(InterruptClear::ALL);
spi.regs
.write_interrupt_control(InterruptControl::ENABLE_ALL);
spi.regs.write_interrupt_control(
InterruptControl::ENABLE_ALL.with_tx(fifo_prefill > FIFO_DEPTH),
);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(false));
});
Self {
bank: spi_id,
bank,
spi,
finished_regularly: core::cell::Cell::new(false),
}
@@ -382,15 +439,15 @@ impl<'spi> SpiFuture<'spi> {
fn new_for_transfer_in_place(
spi: &'spi mut super::Spi<u8>,
spi_id: super::Bank,
bank: super::Bank,
words: &mut [u8],
) -> Self {
if words.is_empty() {
panic!("read and write buffer unexpectedly empty");
}
let (idx, write_idx) = Self::generic_init_transfer(spi, spi_id, words);
let write_idx = Self::generic_init_transfer_write_transfer_in_place(spi, bank, words);
critical_section::with(|cs| {
let context_ref = TRANSFER_CONTEXTS[idx].borrow(cs);
let context_ref = TRANSFER_CONTEXTS[bank as usize].borrow(cs);
let mut context = context_ref.borrow_mut();
context.transfer_type = Some(TransferType::TransferInPlace);
unsafe {
@@ -400,28 +457,34 @@ impl<'spi> SpiFuture<'spi> {
context.tx_progress = write_idx;
context.rx_progress = 0;
spi.regs.write_interrupt_clear(InterruptClear::ALL);
spi.regs
.write_interrupt_control(InterruptControl::ENABLE_ALL);
spi.regs.write_interrupt_control(
InterruptControl::ENABLE_ALL.with_tx(words.len() > FIFO_DEPTH),
);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(false));
});
Self {
bank: spi_id,
bank,
spi,
finished_regularly: core::cell::Cell::new(false),
}
}
fn generic_init_transfer(
spi: &mut super::Spi<u8>,
bank: super::Bank,
write: &[u8],
) -> (usize, usize) {
fn generic_init_transfer(spi: &mut super::Spi<u8>, bank: super::Bank) {
let idx = bank as usize;
DONE[idx].store(false, core::sync::atomic::Ordering::Relaxed);
spi.regs
.write_interrupt_control(InterruptControl::DISABLE_ALL);
spi.regs.write_fifo_clear(FifoClear::ALL);
spi.regs.modify_ctrl1(|v| v.with_mtxpause(true));
}
// Returns amount of bytes written to FIFO.
fn generic_init_transfer_write_transfer_in_place(
spi: &mut super::Spi<u8>,
bank: super::Bank,
write: &[u8],
) -> usize {
Self::generic_init_transfer(spi, bank);
let write_idx = core::cmp::min(super::FIFO_DEPTH, write.len());
(0..write_idx).for_each(|idx| {
@@ -430,20 +493,21 @@ impl<'spi> SpiFuture<'spi> {
});
Self::set_triggers(spi, write_idx, write.len());
(idx, write_idx)
write_idx
}
fn set_triggers(spi: &mut super::Spi<u8>, write_idx: usize, write_len: usize) {
// This should never fail because it is never larger than the FIFO depth.
fn set_triggers(spi: &mut super::Spi<u8>, fifo_prefill: usize, write_len: usize) {
spi.regs
.write_rx_fifo_trigger(TriggerLevel::new(u5::new(write_idx as u8)));
.write_rx_fifo_trigger(TriggerLevel::new(u5::new(core::cmp::min(
fifo_prefill,
FIFO_DEPTH / 2,
) as u8)));
// We want to re-fill the TX FIFO before it is completely empty if the full transfer size
// is larger than the FIFO depth. I am not sure whether the default value of 1 ensures
// this because the PG says that this interrupt is triggered when the FIFO has less than
// threshold entries.
// is larger than the FIFO depth. Otherwise, set it to 0. Not exactly sure what that does,
// but we do not enable interrupts anyway.
if write_len > super::FIFO_DEPTH {
spi.regs
.write_tx_fifo_trigger(TriggerLevel::new(u5::new(2)));
.write_tx_fifo_trigger(TriggerLevel::new(u5::new(8)));
} else {
spi.regs
.write_tx_fifo_trigger(TriggerLevel::new(u5::new(0)));
@@ -452,7 +516,7 @@ impl<'spi> SpiFuture<'spi> {
}
impl<'spi> Future for SpiFuture<'spi> {
type Output = ();
type Output = Result<(), RxOverrunError>;
fn poll(
self: core::pin::Pin<&mut Self>,
@@ -460,14 +524,19 @@ impl<'spi> Future for SpiFuture<'spi> {
) -> core::task::Poll<Self::Output> {
WAKERS[self.bank as usize].register(cx.waker());
if DONE[self.bank as usize].swap(false, core::sync::atomic::Ordering::Relaxed) {
critical_section::with(|cs| {
let rx_overrun = critical_section::with(|cs| {
let mut ctx = TRANSFER_CONTEXTS[self.bank as usize]
.borrow(cs)
.borrow_mut();
let overrun = ctx.rx_overrun;
*ctx = TransferContext::default();
overrun
});
self.finished_regularly.set(true);
return core::task::Poll::Ready(());
if rx_overrun {
return core::task::Poll::Ready(Err(RxOverrunError));
}
return core::task::Poll::Ready(Ok(()));
}
core::task::Poll::Pending
}
@@ -554,28 +623,36 @@ impl SpiAsync {
}
impl embedded_hal_async::spi::ErrorType for SpiAsync {
type Error = Infallible;
type Error = RxOverrunError;
}
impl embedded_hal_async::spi::SpiBus for SpiAsync {
async fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.read(words).unwrap().await;
Ok(())
if words.is_empty() {
return Ok(());
}
self.read(words).unwrap().await
}
async fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.write(words).unwrap().await;
Ok(())
if words.is_empty() {
return Ok(());
}
self.write(words).unwrap().await
}
async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.transfer(read, write).unwrap().await;
Ok(())
if read.is_empty() && write.is_empty() {
return Ok(());
}
self.transfer(read, write).unwrap().await
}
async fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.transfer_in_place(words).unwrap().await;
Ok(())
if words.is_empty() {
return Ok(());
}
self.transfer_in_place(words).unwrap().await
}
async fn flush(&mut self) -> Result<(), Self::Error> {
+3 -3
View File
@@ -499,11 +499,11 @@ pub fn clk_div_for_target_clock(sys_clk: Hertz, spi_clk: Hertz) -> Option<u16> {
}
// Step 1: Calculate raw divider.
let raw_div = sys_clk.raw() / spi_clk.raw();
let remainder = sys_clk.raw() % spi_clk.raw();
let raw_div = sys_clk.to_raw() / spi_clk.to_raw();
let remainder = sys_clk.to_raw() % spi_clk.to_raw();
// Step 2: Round up if necessary.
let mut rounded_div = if remainder * 2 >= spi_clk.raw() {
let mut rounded_div = if remainder * 2 >= spi_clk.to_raw() {
raw_div + 1
} else {
raw_div
+2 -2
View File
@@ -406,7 +406,7 @@ impl CountdownTimer {
pub fn load(&mut self, timeout: impl Into<Hertz>) {
self.disable();
self.curr_freq = timeout.into();
self.rst_val = self.ref_clk.raw() / self.curr_freq.raw();
self.rst_val = self.ref_clk.to_raw() / self.curr_freq.to_raw();
self.set_reload(self.rst_val);
self.set_count(self.rst_val);
}
@@ -497,7 +497,7 @@ impl CountdownTimer {
//
impl embedded_hal::delay::DelayNs for CountdownTimer {
fn delay_ns(&mut self, ns: u32) {
let ticks = (u64::from(ns)) * (u64::from(self.ref_clk.raw())) / 1_000_000_000;
let ticks = (u64::from(ns)) * (u64::from(self.ref_clk.to_raw())) / 1_000_000_000;
let full_cycles = ticks >> 32;
let mut last_count;
+4 -4
View File
@@ -161,11 +161,11 @@ impl ClockConfig {
// This is the calculation: (64.0 * (x - integer_part as f32) + 0.5) as u32 without floating
// point calculations.
let multiplier = baud_mode.multiplier();
let frac = ((ref_clk.raw() % (baudrate.raw() * multiplier)) * 64
+ (baudrate.raw() * (multiplier / 2)))
/ (baudrate.raw() * multiplier);
let frac = ((ref_clk.to_raw() % (baudrate.to_raw() * multiplier)) * 64
+ (baudrate.to_raw() * (multiplier / 2)))
/ (baudrate.to_raw() * multiplier);
// Calculations here are derived from chapter 4.8.5 (p.79) of the datasheet.
let integer_div = ref_clk.raw() / (baudrate.raw() * multiplier);
let integer_div = ref_clk.to_raw() / (baudrate.to_raw() * multiplier);
Self {
frac: u6::new(frac as u8),
div: u18::new(integer_div),