45 Commits

Author SHA1 Message Date
muellerr a65b8d1dd3 Merge pull request 'prepare va108xx releases' (#40) from prepare-va108xx-releases 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: #40
2026-05-19 18:53:04 +02:00
Robin Mueller a8cbcda7cc prepare va108xx releases
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 Documentation Build (push) Waiting to run
va108xx-ci / Check build (pull_request) Waiting to run
va108xx-ci / Clippy (push) 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 (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-19 18:52:32 +02:00
muellerr 946af6ff85 Merge pull request 'start updating the ancient flash loader' (#39) from update-ancient-flash-loader 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: #39
2026-05-19 18:36:57 +02:00
Robin Mueller 926fb15822 update the ancient flash loader
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
va108xx-ci / Check build (push) Waiting to run
shared-hal-ci / Clippy (pull_request) 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 / Check build (pull_request) Waiting to run
va108xx-ci / Clippy (push) 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 (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-19 18:29:29 +02:00
muellerr 28c5628163 Merge pull request 'continue cleanup and release prep' (#38) from cleanup 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: #38
2026-05-19 10:41:43 +02:00
Robin Mueller ebd6fa060a continue cleanup and release prep
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-19 10:40:33 +02:00
muellerr 03e9e6fa6a Merge pull request 'integrate va108xx-embassy into HAL, bump version' (#37) from integrate-va108xx-embassy 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: #37
2026-05-19 10:34:49 +02:00
Robin Mueller 1baea3ccb2 integrate va108xx-embassy into HAL, bump version
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-05-18 21:30:06 +02:00
Robin Mueller 027161d45d fix changelog
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
2026-05-18 21:06:57 +02:00
muellerr 0d1bd3aa47 Merge pull request 'also bump version number' (#36) from bump-version-number 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: #36
2026-05-18 21:01:51 +02:00
Robin Mueller 09ba2d3675 also bump version number
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-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) 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: #35
2026-05-18 20:57:25 +02:00
Robin Mueller 1138b65203 prepare shared HAL release
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-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) 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: #34
2026-05-18 20:52:25 +02:00
Robin Mueller 15fed28281 bump fugit to v0.4
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-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) 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: #33
2026-05-18 20:27:07 +02:00
Robin Mueller e1b3abcba9 invert Pull enum
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-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
muellerr cb61ff7ae0 Merge pull request 'clean up builder API' (#24) from clean-up-uart-cfg-bulder-api 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/24
2026-04-25 22:27:48 +02:00
Robin Mueller 5cf1e679af clean up builder API
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
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 (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 (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-25 22:27:28 +02:00
muellerr 97f656ddde Merge pull request 'update UART clock config, bugfix' (#23) from update-uart-clock-config-and-bugfix 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/23
2026-04-25 22:17:48 +02:00
Robin Mueller 97a66f22e2 update UART clock config, bugfix
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
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 (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 (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-25 22:16:22 +02:00
muellerr 73c8d30078 Merge pull request 'added asynch SPI implementation' (#22) from asynch-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 / 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/22
2026-04-24 11:30:52 +02:00
Robin Mueller a1489285c9 added asynch SPI implementation
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-23 21:54:16 +02:00
muellerr 2ac6c2f002 Merge pull request 'bump VA416xx HAL dependencies' (#21) from bump-va416xx-hal-deps 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: #21
2026-04-10 12:16:43 +02:00
Robin Mueller 6d67953b3b bump VA416xx HAL dependencies
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 (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
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
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
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
2026-04-10 12:16:32 +02:00
muellerr 08ba36966e Merge pull request 'smaller tweaks, note on VA108xx target' (#20) from smaller-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 / 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: #20
2026-04-10 12:13:36 +02:00
Robin Mueller 732e4d5e73 smaller tweaks, note on VA108xx target
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
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 (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 (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-10 12:13:04 +02:00
muellerr 7c984feba3 Merge pull request 'use volatile_write instead of ASM' (#19) from use-volatile-write-instead-of-asm 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: #19
2026-04-09 11:41:26 +02:00
Robin Mueller 66b2506c7d use volatile_write instead of ASM
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 (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
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
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
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
2026-04-09 11:40:37 +02:00
muellerr d1bb378bfa Merge pull request 'feature tweak for the VA108xx HAL' (#18) from feature-tweak-va108xx-hal 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: #18
2026-04-08 17:38:02 +02:00
Robin Mueller 684db0a57b feature tweak for the VA108xx HAL
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
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 (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 (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-08 16:42:52 +02:00
muellerr 35b4a73368 Merge pull request 'improve SPI module' (#17) from improve-spi-module 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: #17
2026-04-02 23:22:38 +02:00
Robin Mueller 0994837251 improve SPI module
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 (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
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
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
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
2026-04-02 23:20:26 +02:00
123 changed files with 2130 additions and 1439 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- name: Install nextest
uses: taiki-e/install-action@nextest
- run: cargo nextest run --all-features -p va108xx-hal --no-tests=pass
- run: cargo nextest run -p va108xx-hal --no-tests=pass
# I think we can skip those on an embedded crate..
# - run: cargo test --doc -p va108xx-hal
@@ -57,7 +57,7 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx --all-features
- run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx-hal --all-features --no-deps
- run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx-hal --features "defmt, embassy-oc30-oc31" --no-deps
- run: RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p vorago-reb1 --no-deps
clippy:
+2 -3
View File
@@ -22,13 +22,12 @@ check-va108xx:
[working-directory: 'va416xx']
check-va416xx:
cargo check --target thumbv7em-none-eabihf
cargo check --target thumbv7em-none-eabihf --examples
cargo check -p va416xx --target thumbv7em-none-eabihf --all-features
cargo check -p va416xx-hal --target thumbv7em-none-eabihf --features "defmt va41630"
[working-directory: 'va108xx']
build-va108xx:
cargo build --target thumbv6m-none-eabi
cargo build --target thumbv6m-none-eabi --release
[working-directory: 'va416xx']
build-va416xx:
@@ -70,7 +69,7 @@ clippy-shared-hal:
[working-directory: 'va108xx']
docs-va108xx:
RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx --all-features
RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx-hal --all-features --no-deps
RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p va108xx-hal --features "defmt, embassy-oc30-oc31" --no-deps
RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options" cargo +nightly doc -p vorago-reb1 --no-deps
[working-directory: 'va416xx']
+7
View File
@@ -0,0 +1,7 @@
[package]
name = "uart-clock-calc"
version = "0.1.0"
edition = "2024"
[dependencies]
arbitrary-int = "2"
+50
View File
@@ -0,0 +1,50 @@
use arbitrary_int::{u6, u18};
#[derive(Debug, Copy, Clone)]
pub struct ClockConfig {
pub frac: u6,
pub int: u18,
}
#[derive(Debug, Copy, Clone)]
pub enum BaudMultiplier {
_8 = 8,
_16 = 16,
}
pub fn uart_clock_calc(ref_clk: u32, baudrate: u32, baud_mult: BaudMultiplier) -> ClockConfig {
// This is the calculation: (64.0 * (x - integer_part as f32) + 0.5) as u32 without floating
// point calculations.
let multiplier = baud_mult as u32;
let frac = ((ref_clk % (baudrate * multiplier)) * 64 + (baudrate * (multiplier / 2)))
/ (baudrate * multiplier);
// Calculations here are derived from chapter 4.8.5 (p.79) of the datasheet.
let integer_part = ref_clk / (baudrate * multiplier);
ClockConfig {
frac: u6::new(frac as u8),
int: u18::new(integer_part),
}
}
const SYS_CLK_50_MHZ: u32 = 50_000_000;
fn main() {
println!("UART Clock Configuration App");
let clock_config = uart_clock_calc(SYS_CLK_50_MHZ, 38400, BaudMultiplier::_16);
println!(
"For a reference clock of {} Hz and baud rate of {} bps with multiplier {}, the clock configuration is: {:?}",
SYS_CLK_50_MHZ,
38400,
BaudMultiplier::_16 as u32,
clock_config
);
let clock_config = uart_clock_calc(SYS_CLK_50_MHZ, 38400, BaudMultiplier::_8);
println!(
"For a reference clock of {} Hz and baud rate of {} bps with multiplier {}, the clock configuration is: {:?}",
SYS_CLK_50_MHZ,
38400,
BaudMultiplier::_8 as u32,
clock_config
);
()
}
@@ -0,0 +1 @@
output.log
@@ -0,0 +1,22 @@
[package]
name = "va108xx-image-loader"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "4", features = ["derive"] }
fern = "0.7"
object = "0.39"
humantime = "2"
crc = "3"
log = "0.4"
toml = "1.1.2+spec-1.1.0"
anyhow = "1"
serialport = "4"
cobs = "0.5"
serde = { version = "1", features = ["derive"] }
postcard = { version = "1", features = ["alloc"] }
spacepackets = { version = "0.17" }
tmtc-utils = { git = "https://egit.irs.uni-stuttgart.de/rust/tmtc-utils.git", version = "0.1" }
models = { path = "../../va108xx/flashloader/models" }
@@ -0,0 +1,3 @@
# VA108XX Flashloader Client
See the [flasherloader app](../../va108xx/flashloader/README.md) for more details.
@@ -0,0 +1,2 @@
[interface]
serial_port = "/dev/ttyUSB0"
@@ -0,0 +1,92 @@
use std::path::Path;
use models::{
APP_A_START_ADDR, APP_A_MAX_SIZE, APP_B_START_ADDR, APP_B_MAX_SIZE,
BOOTLOADER_START_ADDR, BOOTLOADER_MAX_SIZE,
};
use crate::Target;
pub struct LoadableSegment {
pub name: String,
pub offset: u32,
pub data: Vec<u8>,
}
pub fn parse_elf(target: &Target, path: &Path) -> anyhow::Result<Vec<LoadableSegment>> {
use object::{Object, ObjectSection, ObjectSegment};
let raw = std::fs::read(path)?;
let obj = object::File::parse(raw.as_slice())?;
let expected_base: u32 = match target {
Target::Bl => BOOTLOADER_START_ADDR,
Target::A => APP_A_START_ADDR,
Target::B => APP_B_START_ADDR,
};
let mut segments = Vec::new();
for (idx, segment) in obj.segments().enumerate() {
let data = segment.data()?;
if data.is_empty() {
continue;
}
let addr = segment.address() as u32;
if idx == 0 && addr != expected_base {
anyhow::bail!(
"unexpected base address {addr:#010x} for {target:?}, expected {expected_base:#010x}"
);
}
let name = obj
.sections()
.find(|s| {
let s_addr = s.address() as u32;
s_addr >= addr
&& s_addr < addr + data.len() as u32
&& !s.name().unwrap_or("").is_empty()
})
.and_then(|s| s.name().ok().map(str::to_owned))
.unwrap_or_else(|| format!("<segment {idx}>"));
segments.push(LoadableSegment {
name,
offset: addr,
data: data.to_vec(),
});
}
Ok(segments)
}
pub fn check_total_size(target: &Target, total_size: usize) -> anyhow::Result<()> {
let max = match target {
Target::Bl => BOOTLOADER_MAX_SIZE,
Target::A => APP_A_MAX_SIZE,
Target::B => APP_B_MAX_SIZE,
} as usize;
if total_size > max {
anyhow::bail!(
"{target:?} image is {total_size} bytes, exceeds maximum of {max} bytes"
);
}
Ok(())
}
pub fn log_segments_info(target: &Target, segments: &[LoadableSegment], total_size: usize, path: &Path) {
log::info!(
"Flashing {target:?} with image '{}' — {} segment(s), {total_size} bytes total",
path.display(),
segments.len()
);
for (i, seg) in segments.iter().enumerate() {
log::info!(
" segment {i}: '{}' @ {:#010x}, {} bytes",
seg.name, seg.offset, seg.data.len()
);
}
}
@@ -0,0 +1,142 @@
use std::path::Path;
use anyhow::Context;
use crc::{CRC_16_IBM_3740, Crc};
use spacepackets::CcsdsPacketReader;
use tmtc_utils::transport::serial::PacketTransportSerialCobs;
use crate::{
Target,
elf::{check_total_size, log_segments_info, parse_elf},
tc,
};
use models::{
APP_A_CRC_ADDR, APP_A_SIZE_ADDR, APP_B_CRC_ADDR, APP_B_SIZE_ADDR, BOOTLOADER_CRC_ADDR,
};
use models::{Request, Response};
pub const CHUNK_SIZE: usize = 256;
fn send_and_await_ok(
transport: &mut PacketTransportSerialCobs,
request: &Request,
payload: &[u8],
timeout: std::time::Duration,
) -> anyhow::Result<()> {
let tc = tc::create_tc_with_additional_payload(request, payload);
log::debug!(
"TX TC {:#010x}: {request:?} + {} payload bytes",
tc.ccsds_packet_id_and_psc().raw(),
payload.len()
);
transport.send(&tc.to_vec())?;
let deadline = std::time::Instant::now() + timeout;
let mut got_ok = false;
while !got_ok {
if std::time::Instant::now() > deadline {
anyhow::bail!("timeout waiting for Ok response to {request:?}");
}
transport.receive(|packet| {
let Ok(reader) = CcsdsPacketReader::new_with_checksum(packet) else {
return;
};
match postcard::take_from_bytes::<Response>(reader.packet_data()) {
Ok((Response::Ok, _)) => got_ok = true,
#[allow(unreachable_patterns)]
Ok((other, _)) => log::warn!("unexpected response: {other:?}"),
Err(e) => log::error!("failed to deserialise response: {e}"),
}
})?;
}
Ok(())
}
pub fn flash_image(
transport: &mut PacketTransportSerialCobs,
target: &Target,
path: &Path,
) -> anyhow::Result<()> {
let segments = parse_elf(target, path)
.with_context(|| format!("failed to parse ELF: {}", path.display()))?;
let total_size: usize = segments.iter().map(|s| s.data.len()).sum();
check_total_size(target, total_size)?;
log_segments_info(target, &segments, total_size, path);
let ack_timeout = std::time::Duration::from_secs(2);
// 1. Write all segments in chunks, waiting for Ok after each.
for seg in &segments {
let mut pos = 0usize;
while pos < seg.data.len() {
let chunk_len = CHUNK_SIZE.min(seg.data.len() - pos);
let offset = seg.offset + pos as u32;
let chunk = &seg.data[pos..pos + chunk_len];
log::info!(
"Writing {chunk_len} bytes @ {offset:#010x} ({}/{} of '{}')",
pos + chunk_len,
seg.data.len(),
seg.name,
);
send_and_await_ok(transport, &Request::WriteNvm { offset }, chunk, ack_timeout)?;
pos += chunk_len;
}
}
// 2. CRC + size postprocessing.
match target {
Target::Bl => {
log::info!("Blanking bootloader CRC @ {BOOTLOADER_CRC_ADDR:#010x}");
send_and_await_ok(
transport,
&Request::WriteNvm {
offset: BOOTLOADER_CRC_ADDR,
},
&[0x00, 0x00],
ack_timeout,
)?;
}
Target::A | Target::B => {
let (size_addr, crc_addr) = match target {
Target::A => (APP_A_SIZE_ADDR, APP_A_CRC_ADDR),
Target::B => (APP_B_SIZE_ADDR, APP_B_CRC_ADDR),
Target::Bl => unreachable!(),
};
log::info!("Writing app size {total_size} @ {size_addr:#010x}");
send_and_await_ok(
transport,
&Request::WriteNvm { offset: size_addr },
&(total_size as u32).to_be_bytes(),
ack_timeout,
)?;
let crc = Crc::<u16>::new(&CRC_16_IBM_3740);
let mut digest = crc.digest();
for seg in &segments {
digest.update(&seg.data);
}
let checksum = digest.finalize().to_be_bytes();
log::info!(
"Writing CRC [{:#04x}, {:#04x}] @ {crc_addr:#010x}",
checksum[0],
checksum[1]
);
send_and_await_ok(
transport,
&Request::WriteNvm { offset: crc_addr },
&checksum,
ack_timeout,
)?;
}
}
log::info!("Flash complete.");
Ok(())
}
@@ -0,0 +1,194 @@
use std::{
fs::File,
io::Read as _,
net::SocketAddr,
path::{Path, PathBuf},
time::SystemTime,
};
use anyhow::bail;
use clap::Parser as _;
use cobs::CobsDecoderOwned;
use models::Response;
use spacepackets::CcsdsPacketReader;
use tmtc_utils::transport::serial::PacketTransportSerialCobs;
pub mod elf;
pub mod flash;
pub mod tc;
#[derive(clap::Parser)]
#[command(name = "image-loader", about = "VA416XX Image Loader Application")]
pub struct Cli {
/// Serial port to use (overrides loader.toml)
#[arg(short, long)]
pub port: Option<String>,
#[command(subcommand)]
pub command: Command,
}
#[derive(clap::Subcommand)]
pub enum Command {
/// Send a ping command
Ping,
/// Set the active boot slot
SetBootSlot {
/// Boot slot to activate
app: AppTarget,
},
/// Corrupt an app slot (for testing)
Corrupt {
/// Target slot to corrupt
app: AppTarget,
},
/// Flash an ELF image to a target slot
Flash {
/// Target to flash
target: Target,
/// Path to the ELF image
path: PathBuf,
},
}
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum Target {
/// Bootloader slot
Bl,
/// Application slot A
A,
/// Application slot B
B,
}
/// Only app slots can be corrupted (not the bootloader)
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum AppTarget {
A,
B,
}
#[derive(Debug, serde::Deserialize)]
pub struct Config {
pub interface: Interface,
}
#[derive(Debug, serde::Deserialize)]
pub struct Interface {
pub serial_port: Option<String>,
pub udp_addr: Option<SocketAddr>,
}
impl Config {
pub fn new_from_file() -> Self {
let mut config_file =
File::open(Path::new("config.toml")).expect("opening config.toml file failed");
let mut toml_str = String::new();
config_file
.read_to_string(&mut toml_str)
.expect("reading config.toml file failed");
let config: Config = toml::from_str(&toml_str).expect("parsing config.toml file failed");
config
}
}
pub fn setup_logger() -> Result<(), fern::InitError> {
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"[{} {} {}] {}",
humantime::format_rfc3339_seconds(SystemTime::now()),
record.level(),
record.target(),
message
))
})
.level(log::LevelFilter::Info)
.chain(std::io::stdout())
.chain(fern::log_file("output.log")?)
.apply()?;
Ok(())
}
fn main() -> anyhow::Result<()> {
setup_logger().expect("failed to initialize logger");
println!("-- VA108xx Flashloader Client --");
let cli = Cli::parse();
let config = Config::new_from_file();
if config.interface.serial_port.is_none() {
bail!("Serial port not specified in configuration file.");
}
let serial_port = config.interface.serial_port.as_ref().unwrap();
let serial = serialport::new(serial_port, 115200)
.open()
.expect("opening serial port failed");
let mut transport = PacketTransportSerialCobs::new(serial, CobsDecoderOwned::new(4096));
match cli.command {
Command::Ping => {
let tc = tc::create_tc(&models::Request::Ping);
log::info!(
"Sending ping request with TC ID: {:#010x}",
tc.ccsds_packet_id_and_psc().raw()
);
let tc_raw = tc.to_vec();
transport.send(&tc_raw).unwrap();
}
Command::SetBootSlot { app } => {
let app_sel = match app {
AppTarget::A => models::AppSel::A,
AppTarget::B => models::AppSel::B,
};
let tc = tc::create_tc(&models::Request::SetBootSlot(app_sel));
log::info!(
"Sending app select {:?} command with TC ID: {:#010x}",
app_sel,
tc.ccsds_packet_id_and_psc().raw()
);
transport.send(&tc.to_vec()).unwrap();
}
Command::Corrupt { app } => {
let app_sel = match app {
AppTarget::A => models::AppSel::A,
AppTarget::B => models::AppSel::B,
};
let tc = tc::create_tc(&models::Request::SetBootSlot(app_sel));
log::info!(
"Sending corrupt slot {:?} command with TC ID: {:#010x}",
app_sel,
tc.ccsds_packet_id_and_psc().raw()
);
transport.send(&tc.to_vec()).unwrap();
}
Command::Flash { target, path } => {
flash::flash_image(&mut transport, &target, &path)?;
}
}
log::info!("Waiting for response...");
loop {
transport
.receive(|packet: &[u8]| {
let reader = CcsdsPacketReader::new_with_checksum(packet);
log::debug!("Received packet: {:?}", reader);
if let Ok(reader) = reader {
let packet_data = reader.packet_data();
let response_result = postcard::take_from_bytes::<Response>(packet_data);
if let Ok((response, _remainder)) = response_result {
log::info!("Received TM with response: {:?}", response);
} else {
log::error!(
"Failed to parse response from packet data: {:?}",
response_result
);
}
}
})
.unwrap();
}
}
@@ -0,0 +1,14 @@
use spacepackets::{CcsdsPacketCreatorOwned, SpHeader};
pub fn create_tc(request: &models::Request) -> CcsdsPacketCreatorOwned {
let req_raw = postcard::to_allocvec(&request).unwrap();
let sp_header = SpHeader::new_from_apid(models::APID);
CcsdsPacketCreatorOwned::new_tc_with_checksum(sp_header, &req_raw).unwrap()
}
pub fn create_tc_with_additional_payload(request: &models::Request, payload: &[u8]) -> CcsdsPacketCreatorOwned {
let mut req_raw = postcard::to_allocvec(&request).unwrap();
req_raw.extend_from_slice(payload);
let sp_header = SpHeader::new_from_apid(models::APID);
CcsdsPacketCreatorOwned::new_tc_with_checksum(sp_header, &req_raw).unwrap()
}
+5 -2
View File
@@ -1,16 +1,16 @@
[workspace]
resolver = "2"
resolver = "3"
members = [
"vorago-reb1",
"va108xx",
"va108xx-hal",
"va108xx-embassy",
"examples/simple",
"examples/rtic",
"examples/embassy",
"board-tests",
"bootloader",
"flashloader",
"flashloader/models",
]
exclude = [
"flashloader/slot-a-blinky",
@@ -44,3 +44,6 @@ lto = true
opt-level = 'z' # <-
overflow-checks = false # <-
strip = true # Automatically strip symbols from the binary.
[patch.crates-io]
spacepackets = { git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", rev = "ec952b771cc62a371786cb1a04fd1baa9c33523c" }
+10 -5
View File
@@ -14,8 +14,6 @@ This workspace contains the following released crates:
crate containing basic low-level register definition.
- The [`va108xx-hal`](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/va108xx-hal)
HAL crate containing higher-level abstractions on top of the PAC register crate.
- The [`va108xx-embassy`](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/va108xx-embassy)
crate containing support for running the embassy-rs asynchronous runtime.
- The [`vorago-reb1`](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/vorago-reb1)
BSP crate containing support for the REB1 development board.
@@ -90,15 +88,22 @@ work yet.
After installation, you can run the following command
```sh
probe-rs run --chip VA108xx_RAM --protocol jtag target/thumbv6m-none-eabi/debug/examples/blinky
probe-rs run --chip VA108xx_RAM --protocol jtag target/thumbv6m-none-eabi/debug/blinky
```
to flash and run the blinky program on the RAM. There is also a `VA108xx` chip target
available for persistent flashing.
available for persistent flashing (see note below!).
Runner configuration is available in the `.cargo/def-config.toml` file to use `probe-rs` for
Runner configuration is available in the `.cargo/config.toml.template` file to use `probe-rs` for
convenience. `probe-rs` is also able to process and display `defmt` strings directly.
Special note on the `VA108xx` target: This target allows flashing the NVM, but doing a soft reset
with a tool like `probe-rs` can only perform a soft reset where the code already running in RAM
is reset. If you want to immediately run the code flashed to the NVM and get `defmt` printouts,
use `probe-rs download` to flash to NVM, then flash a binary which issues the system reset
(e.g. the `reset` app inside the example folder), and then attach with `probe-rs attach`, passing
the image downloaded to NVM to the attach command.
### Using VS Code
Assuming a working debug connection to your VA108xx board, you can debug using VS Code with
+1 -1
View File
@@ -12,7 +12,7 @@ panic-probe = { version = "1", features = ["print-defmt"] }
embedded-hal = "1"
[dependencies.va108xx-hal]
version = "0.12"
version = "0.13"
features = ["rt"]
path = "../va108xx-hal"
+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();
+3 -3
View File
@@ -9,18 +9,18 @@ cortex-m-rt = "0.7"
embedded-hal = "1"
defmt-rtt = "1"
defmt = "1"
panic-probe = { version = "1", features = ["defmt"] }
panic-probe = { version = "1" }
crc = "3"
num_enum = { version = "0.7", default-features = false }
static_assertions = "1"
[dependencies.va108xx-hal]
version = "0.12"
version = "0.13"
path = "../va108xx-hal"
features = ["defmt"]
[dependencies.vorago-reb1]
version = "0.9"
version = "0.10"
path = "../vorago-reb1"
[features]
+12 -10
View File
@@ -159,6 +159,12 @@ fn main() -> ! {
if check_app_crc(preferred_app) {
boot_app(&dp.sysconfig, &cp, preferred_app, &mut timer)
} else if check_app_crc(other_app) {
if DEFMT_PRINTOUT {
defmt::warn!(
"CRC check for preferred image {} failed. Checking alternative slot",
preferred_app
);
}
boot_app(&dp.sysconfig, &cp, other_app, &mut timer)
} else {
if DEBUG_PRINTOUTS && DEFMT_PRINTOUT {
@@ -181,7 +187,8 @@ fn check_own_crc(
// because the address of the bootloader is 0x0, so the NULL check fails and the functions
// panics.
#[allow(clippy::zero_ptr)]
let first_four_bytes = unsafe { core::ptr::read_volatile(0x0 as *const u32) }.to_ne_bytes();
let first_four_bytes =
unsafe { core::ptr::read_volatile(BOOTLOADER_START_ADDR as *const u32) }.to_ne_bytes();
let mut digest = CRC_ALGO.digest();
digest.update(&first_four_bytes);
digest.update(unsafe {
@@ -209,7 +216,6 @@ fn check_own_crc(
crc_exp
);
}
// TODO: Shift out minimal CCSDS frame to notify about bootloader corruption.
boot_app(sysconfig, cp, AppSel::A, timer);
}
}
@@ -270,14 +276,10 @@ fn boot_app(
APP_B_START_ADDR
};
unsafe {
// First 4 bytes done with inline assembly, writing to the physical address 0x0 can not
// be done without it. See https://users.rust-lang.org/t/reading-from-physical-address-0x0/117408/2.
let first_four_bytes = core::ptr::read(base_addr as *const u32);
core::arch::asm!(
"str {0}, [{1}]",
in(reg) first_four_bytes, // Input: App vector table.
in(reg) BOOTLOADER_START_ADDR as *mut u32, // Input: destination pointer
);
let first_four_bytes = core::ptr::read_volatile(base_addr as *const u32);
#[allow(clippy::zero_ptr)]
core::ptr::write_volatile(BOOTLOADER_START_ADDR as *mut u32, first_four_bytes);
core::slice::from_raw_parts_mut(
(BOOTLOADER_START_ADDR + 4) as *mut u8,
(VECTOR_TABLE_LEN - 4) as usize,
+7 -7
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,19 +19,18 @@ 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"
]}
va108xx-hal = { version = "0.12", path = "../../va108xx-hal", features = ["defmt"] }
va108xx-embassy = { version = "0.3", path = "../../va108xx-embassy" }
va108xx-hal = { version = "0.13", path = "../../va108xx-hal", features = ["defmt"] }
[features]
default = ["ticks-hz-1_000", "va108xx-embassy/irq-oc30-oc31"]
default = ["ticks-hz-1_000", "va108xx-hal/embassy-oc30-oc31"]
custom-irqs = []
ticks-hz-1_000 = ["embassy-time/tick-hz-1_000"]
ticks-hz-32_768 = ["embassy-time/tick-hz-32_768"]
+31 -29
View File
@@ -61,7 +61,10 @@ async fn main(spawner: Spawner) {
let dp = pac::Peripherals::take().unwrap();
// Safety: Only called once here.
va108xx_embassy::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
va108xx_hal::embassy_time::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");
@@ -55,7 +55,7 @@ async fn main(spawner: Spawner) {
let dp = pac::Peripherals::take().unwrap();
// Safety: Only called once here.
va108xx_embassy::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
va108xx_hal::embassy_time::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
let porta = PinsA::new(dp.porta);
let mut led0 = Output::new(porta.pa10, PinState::Low);
@@ -65,12 +65,13 @@ async fn main(spawner: Spawner) {
let tx_uart_a = porta.pa9;
let rx_uart_a = porta.pa8;
let clock_config = uart::ClockConfig::calculate(50.MHz(), 115200.Hz(), uart::BaudMode::_16);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uarta = uart::Uart::new_with_interrupt_uart0(
dp.uarta,
tx_uart_a,
rx_uart_a,
50.MHz(),
115200.Hz().into(),
uart_config,
InterruptConfig::new(pac::Interrupt::OC2, true, true),
);
@@ -81,8 +82,7 @@ async fn main(spawner: Spawner) {
dp.uartb,
tx_uart_b,
rx_uart_b,
50.MHz(),
115200.Hz().into(),
uart_config,
InterruptConfig::new(pac::Interrupt::OC3, true, true),
);
let (mut tx_uart_a, rx_uart_a) = uarta.split();
@@ -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());
@@ -41,7 +41,7 @@ async fn main(_spawner: Spawner) {
let dp = pac::Peripherals::take().unwrap();
// Safety: Only called once here.
va108xx_embassy::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
va108xx_hal::embassy_time::init(dp.tim23, dp.tim22, SYSCLK_FREQ);
let porta = PinsA::new(dp.porta);
@@ -52,12 +52,13 @@ async fn main(_spawner: Spawner) {
let tx = porta.pa9;
let rx = porta.pa8;
let clock_config = uart::ClockConfig::calculate(50.MHz(), 115200.Hz(), uart::BaudMode::_16);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uarta = uart::Uart::new_with_interrupt_uart0(
dp.uarta,
tx,
rx,
50.MHz(),
115200.Hz().into(),
uart_config,
InterruptConfig::new(pac::Interrupt::OC2, true, true),
);
let (tx, _rx) = uarta.split();
+3 -3
View File
@@ -6,7 +6,7 @@ use embassy_time::{Duration, Instant, Ticker};
cfg_if::cfg_if! {
if #[cfg(feature = "custom-irqs")] {
use va108xx_embassy::embassy_time_driver_irqs;
use va108xx_hal::embassy_time_driver_irqs;
use va108xx_hal::pac::interrupt;
embassy_time_driver_irqs!(timekeeper_irq = OC23, alarm_irq = OC24);
}
@@ -31,13 +31,13 @@ async fn main(_spawner: Spawner) {
// Safety: Only called once here.
cfg_if::cfg_if! {
if #[cfg(not(feature = "custom-irqs"))] {
va108xx_embassy::init(
va108xx_hal::embassy_time::init(
dp.tim23,
dp.tim22,
SYSCLK_FREQ,
);
} else {
va108xx_embassy::init_with_custom_irqs(
va108xx_hal::embassy_time::init_with_custom_irqs(
dp.tim23,
dp.tim22,
SYSCLK_FREQ,
+4 -3
View File
@@ -9,9 +9,10 @@ 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"] }
ringbuf = { version = "0.5", default-features = false, features = ["portable-atomic"] }
va108xx-hal = { version = "0.12", path = "../../va108xx-hal" }
vorago-reb1 = { version = "0.9", path = "../../vorago-reb1" }
va108xx-hal = { version = "0.13", path = "../../va108xx-hal" }
vorago-reb1 = { version = "0.10", path = "../../vorago-reb1" }
@@ -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,23 +46,28 @@ 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,
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,
tx,
rx,
SYSCLK_FREQ,
115200.Hz().into(),
uart_config,
InterruptConfig::new(pac::Interrupt::OC3, true, true),
);
let (tx, rx) = irq_uart.split();
let mut rx = rx.into_rx_with_irq();
let mut rx = rx.into_rx_with_interrupt();
rx.start();
+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);
+1 -1
View File
@@ -16,6 +16,6 @@ embedded-io = "0.7"
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"] }
[dependencies.va108xx-hal]
version = "0.12"
version = "0.13"
path = "../../va108xx-hal"
features = ["defmt"]
+12
View File
@@ -0,0 +1,12 @@
//! Dummy app which does not do anything.
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use panic_halt as _;
use va108xx_hal as _;
#[entry]
fn main() -> ! {
cortex_m::peripheral::SCB::sys_reset();
}
@@ -87,7 +87,7 @@ fn main() -> ! {
bmstall: true,
hw_cs: None,
};
spi.cfg_transfer(&transfer_cfg);
spi.configure_transfer(&transfer_cfg);
}
SpiBusSelect::SpiBPortB => {
let hw_cs_pin = configure_pin_as_hw_cs_pin(pinsb.pb2);
@@ -99,7 +99,7 @@ fn main() -> ! {
bmstall: true,
hw_cs: Some(hw_cs_pin),
};
spi.cfg_transfer(&transfer_cfg);
spi.configure_transfer(&transfer_cfg);
}
}
@@ -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));
@@ -28,8 +28,9 @@ fn main() -> ! {
let gpioa = PinsA::new(dp.porta);
let tx = gpioa.pa9;
let rx = gpioa.pa8;
let uart =
uart::Uart::new_without_interrupt_uart0(dp.uarta, tx, rx, 50.MHz(), 115200.Hz().into());
let clock_config = uart::ClockConfig::calculate(50.MHz(), 115200.Hz(), uart::BaudMode::_16);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uart = uart::Uart::new_without_interrupt_uart0(dp.uarta, tx, rx, uart_config);
let (mut tx, mut rx) = uart.split();
writeln!(tx, "Hello World\r").unwrap();
+13 -8
View File
@@ -11,25 +11,30 @@ defmt = "1"
defmt-rtt = { version = "1" }
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"] }
cobs = { version = "0.5", 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"] }
embassy-sync = "0.8"
embedded-io-async = "0.7"
embassy-time = { version = "0.5", features = ["defmt-timestamp-uptime-ms"] }
static_cell = "2"
postcard = { version = "1", features = ["use-defmt"] }
spacepackets = { version = "0.17", default-features = false, features = ["defmt"] }
serde = { version = "1", default-features = false }
# Even though we do not use this directly, we need to activate this feature explicitely
# so that RTIC compiles because thumv6 does not have CAS operations natively.
portable-atomic = {version = "1", features = ["unsafe-assume-single-core"]}
models = { path = "./models", features = ["defmt"] }
rtic = { version = "2", features = ["thumbv6-backend"] }
rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
[dependencies.va108xx-hal]
version = "0.12"
version = "0.13"
path = "../va108xx-hal"
features = ["defmt"]
features = ["defmt", "embassy-oc30-oc31"]
[dependencies.vorago-reb1]
version = "0.9"
version = "0.10"
path = "../vorago-reb1"
[package.metadata.cargo-machete]
+20 -26
View File
@@ -2,45 +2,40 @@ VA108xx Flashloader Application
========
This flashloader shows a minimal example for a self-updatable Rust software which exposes
a simple PUS (CCSDS) interface to update the software. It also provides a Python application
called the `image-loader.py` which can be used to upload compiled images to the flashloader
application to write them to the NVM.
a simple PUS (CCSDS) interface to update the software. It also provides a Rust application
which can be used to upload compiled images to the flashloader application to write them to the NVM.
You can find it inside the `tools/va108xx-image-loader` directory of the monorepo.
Please note that the both the application and the image loader are tailored towards usage
with the [bootloader provided by this repository](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/bootloader).
The software can quickly be adapted to interface with a real primary on-board software instead of
the Python script provided here to upload images because it uses a low-level CCSDS based packet
interface.
The flashloader software could be be adapted to interface with a real primary on-board software
instead of the loader application provided here to upload images because it already uses a
low-level CCSDS based packet interface.
## Using the Python image loader
## Using the image loader
The Python image loader communicates with the Rust flashload application using a dedicated serial
port with a baudrate of 115200.
Inside `tools/va108xx-image-loader` you can find a Rust application which can be used to
update the image slots via a serial port.
It is recommended to run the script in a dedicated virtual environment. For example, on UNIX
systems you can use `python3 -m venv venv` and then `source venv/bin/activate` to create
and activate a virtual environment.
You can install this tool using the following command inside the project folder:
After that, you can use
```sh
pip install -r requirements.txt
```
cargo install --path .
```
to install all required dependencies.
After that, you can run `va108xx-iamge-loader --help` to get some to get usage informations.
After that, it is recommended to use `./image-load.py -h` to get an overview of some options.
The flash loader uses the UART0 with the Pins PA8 (RX) and PA9 (TX) interface of the VA108xx to perform CCSDS based
communication. The Python image loader application will search for a file named `loader.toml` and
use the `serial_port` key to determine the serial port to use for serial communication.
The flash loader uses the UART0 with the Pins PA8 (RX) and PA9 (TX) interface of the VA108xx to
perform CCSDS based communication. The serial port can be set inside the `config.toml` file
or with the `--port` argument.
### Examples
You can use
```sh
./image-loader.py -p
va108xx-image-loader ping
```
to send a ping an verify the connection.
@@ -50,8 +45,7 @@ You can use
```sh
cd flashloader/slot-a-blinky
cargo build --release
cd ../..
./image-loader.py -t a ./slot-a-blinky/target/thumbv6m-none-eabi/release/slot-a-blinky
va108xx-image-loader flash a ./target/thumbv6m-none-eabi/release/slot-a-blinky
```
to build the slot A sample application and upload it to a running flash loader application
@@ -60,7 +54,7 @@ to write it to slot A.
You can use
```sh
./image-loader.py -s a
va108xx-image-loader set-boot-slot a
```
to select the Slot A as a boot slot. The boot slot is stored in a reserved section in EEPROM
@@ -69,7 +63,7 @@ and will be read and used by the bootloader to determine which slot to boot.
You can use
```sh
./image-loader.py -c -t a
va108xx-image-loader corrupt a
```
to corrupt the image A and test that it switches to image B after a failed CRC check instead.
-476
View File
@@ -1,476 +0,0 @@
#!/usr/bin/env python3
from typing import List, Tuple
from spacepackets.ecss.defs import PusService
from spacepackets.ecss.tm import PusTm
import toml
import struct
import logging
import argparse
import time
import enum
from com_interface import ComInterface
from com_interface.serial_base import SerialCfg
from com_interface.serial_cobs import SerialCobsComIF
from crcmod.predefined import PredefinedCrc
from spacepackets.ecss.tc import PusTc
from spacepackets.ecss.pus_verificator import PusVerificator, StatusField
from spacepackets.ecss.pus_1_verification import Service1Tm, UnpackParams
from spacepackets.seqcount import SeqCountProvider
from pathlib import Path
import dataclasses
from elftools.elf.elffile import ELFFile
BAUD_RATE = 115200
BOOTLOADER_START_ADDR = 0x0
BOOTLOADER_END_ADDR = 0x3000
BOOTLOADER_CRC_ADDR = BOOTLOADER_END_ADDR - 2
BOOTLOADER_MAX_SIZE = BOOTLOADER_END_ADDR - BOOTLOADER_START_ADDR - 2
APP_A_START_ADDR = 0x3000
APP_B_END_ADDR = 0x20000 - 8
IMG_SLOT_SIZE = (APP_B_END_ADDR - APP_A_START_ADDR) // 2
APP_A_END_ADDR = APP_A_START_ADDR + IMG_SLOT_SIZE
# The actual size of the image which is relevant for CRC calculation.
APP_A_SIZE_ADDR = APP_A_END_ADDR - 8
APP_A_CRC_ADDR = APP_A_END_ADDR - 4
APP_A_MAX_SIZE = APP_A_END_ADDR - APP_A_START_ADDR - 8
APP_B_START_ADDR = APP_A_END_ADDR
# The actual size of the image which is relevant for CRC calculation.
APP_B_SIZE_ADDR = APP_B_END_ADDR - 8
APP_B_CRC_ADDR = APP_B_END_ADDR - 4
APP_B_MAX_SIZE = APP_A_END_ADDR - APP_A_START_ADDR - 8
CHUNK_SIZE = 400
MEMORY_SERVICE = 6
ACTION_SERVICE = 8
RAW_MEMORY_WRITE_SUBSERVICE = 2
BOOT_NVM_MEMORY_ID = 1
PING_PAYLOAD_SIZE = 0
class ActionId(enum.IntEnum):
CORRUPT_APP_A = 128
CORRUPT_APP_B = 129
SET_BOOT_SLOT = 130
_LOGGER = logging.getLogger(__name__)
SEQ_PROVIDER = SeqCountProvider(bit_width=14)
@dataclasses.dataclass
class LoadableSegment:
name: str
offset: int
size: int
data: bytes
class Target(enum.Enum):
BOOTLOADER = 0
APP_A = 1
APP_B = 2
class AppSel(enum.IntEnum):
APP_A = 0
APP_B = 1
class ImageLoader:
def __init__(self, com_if: ComInterface, verificator: PusVerificator) -> None:
self.com_if = com_if
self.verificator = verificator
def handle_boot_sel_cmd(self, target: AppSel):
_LOGGER.info("Sending ping command")
action_tc = PusTc(
apid=0x00,
service=PusService.S8_FUNC_CMD,
subservice=ActionId.SET_BOOT_SLOT,
seq_count=SEQ_PROVIDER.get_and_increment(),
app_data=bytes([target]),
)
self.verificator.add_tc(action_tc)
self.com_if.send(bytes(action_tc.pack()))
self.await_for_command_copletion("boot image selection command")
def handle_ping_cmd(self):
_LOGGER.info("Sending ping command")
ping_tc = PusTc(
apid=0x00,
service=PusService.S17_TEST,
subservice=1,
seq_count=SEQ_PROVIDER.get_and_increment(),
app_data=bytes(PING_PAYLOAD_SIZE),
)
self.verificator.add_tc(ping_tc)
self.com_if.send(bytes(ping_tc.pack()))
self.await_for_command_copletion("ping command")
def await_for_command_copletion(self, context: str):
done = False
now = time.time()
while time.time() - now < 2.0:
if not self.com_if.data_available():
time.sleep(0.2)
continue
for reply in self.com_if.receive():
result = self.verificator.add_tm(
Service1Tm.from_tm(PusTm.unpack(reply, 0), UnpackParams(0))
)
if result is not None and result.completed:
_LOGGER.info(f"received {context} reply")
done = True
if done:
break
if not done:
_LOGGER.warning(f"no {context} reply received")
def handle_corruption_cmd(self, target: Target):
if target == Target.BOOTLOADER:
_LOGGER.error("can not corrupt bootloader")
if target == Target.APP_A:
self.send_tc(
PusTc(
apid=0,
service=ACTION_SERVICE,
subservice=ActionId.CORRUPT_APP_A,
),
)
if target == Target.APP_B:
self.send_tc(
PusTc(
apid=0,
service=ACTION_SERVICE,
subservice=ActionId.CORRUPT_APP_B,
),
)
def handle_flash_cmd(self, target: Target, file_path: Path) -> int:
loadable_segments = []
_LOGGER.info("Parsing ELF file for loadable sections")
total_size = 0
loadable_segments, total_size = create_loadable_segments(target, file_path)
check_segments(target, total_size)
print_segments_info(target, loadable_segments, total_size, file_path)
result = self._perform_flashing_algorithm(loadable_segments)
if result != 0:
return result
self._crc_and_app_size_postprocessing(target, total_size, loadable_segments)
return 0
def _perform_flashing_algorithm(
self,
loadable_segments: List[LoadableSegment],
) -> int:
# Perform the flashing algorithm.
for segment in loadable_segments:
segment_end = segment.offset + segment.size
current_addr = segment.offset
pos_in_segment = 0
while pos_in_segment < segment.size:
next_chunk_size = min(segment_end - current_addr, CHUNK_SIZE)
data = segment.data[pos_in_segment : pos_in_segment + next_chunk_size]
next_packet = pack_memory_write_command(current_addr, data)
_LOGGER.info(
f"Sending memory write command for address {current_addr:#08x} and data with "
f"length {len(data)}"
)
self.verificator.add_tc(next_packet)
self.com_if.send(bytes(next_packet.pack()))
current_addr += next_chunk_size
pos_in_segment += next_chunk_size
start_time = time.time()
while True:
if time.time() - start_time > 1.0:
_LOGGER.error("Timeout while waiting for reply")
return -1
data_available = self.com_if.data_available(0.1)
done = False
if not data_available:
continue
replies = self.com_if.receive()
for reply in replies:
tm = PusTm.unpack(reply, 0)
if tm.service != 1:
continue
service_1_tm = Service1Tm.from_tm(tm, UnpackParams(0))
check_result = self.verificator.add_tm(service_1_tm)
# We could send after we have received the step reply, but that can
# somehow lead to overrun errors. I think it's okay to do it like
# this as long as the flash loader only uses polling..
if (
check_result is not None
and check_result.status.completed == StatusField.SUCCESS
):
done = True
# This is an optimized variant, but I think the small delay is not an issue.
"""
if (
check_result is not None
and check_result.status.step == StatusField.SUCCESS
and len(check_result.status.step_list) == 1
):
done = True
"""
self.verificator.remove_completed_entries()
if done:
break
return 0
def _crc_and_app_size_postprocessing(
self,
target: Target,
total_size: int,
loadable_segments: List[LoadableSegment],
):
if target == Target.BOOTLOADER:
_LOGGER.info("Blanking the bootloader checksum")
# Blank the checksum. For the bootloader, the bootloader will calculate the
# checksum itself on the initial run.
checksum_write_packet = pack_memory_write_command(
BOOTLOADER_CRC_ADDR, bytes([0x00, 0x00])
)
self.send_tc(checksum_write_packet)
else:
crc_addr = None
size_addr = None
if target == Target.APP_A:
crc_addr = APP_A_CRC_ADDR
size_addr = APP_A_SIZE_ADDR
elif target == Target.APP_B:
crc_addr = APP_B_CRC_ADDR
size_addr = APP_B_SIZE_ADDR
assert crc_addr is not None
assert size_addr is not None
_LOGGER.info(f"Writing app size {total_size} at address {size_addr:#08x}")
size_write_packet = pack_memory_write_command(
size_addr, struct.pack("!I", total_size)
)
self.com_if.send(bytes(size_write_packet.pack()))
time.sleep(0.2)
crc_calc = PredefinedCrc("crc-ccitt-false")
for segment in loadable_segments:
crc_calc.update(segment.data)
checksum = crc_calc.digest()
_LOGGER.info(
f"Writing checksum 0x[{checksum.hex(sep=',')}] at address {crc_addr:#08x}"
)
self.send_tc(pack_memory_write_command(crc_addr, checksum))
def send_tc(self, tc: PusTc):
self.com_if.send(bytes(tc.pack()))
def main() -> int:
print("Python VA108XX Image Loader Application")
logging.basicConfig(
format="[%(asctime)s] [%(levelname)s] %(message)s", level=logging.DEBUG
)
parser = argparse.ArgumentParser(
prog="image-loader", description="Python VA416XX Image Loader Application"
)
parser.add_argument("-p", "--ping", action="store_true", help="Send ping command")
parser.add_argument(
"-s", "--sel", choices=["a", "b"], help="Set boot slot (Slot A or B)"
)
parser.add_argument("-c", "--corrupt", action="store_true", help="Corrupt a target")
parser.add_argument(
"-t",
"--target",
choices=["bl", "a", "b"],
help="Target (Bootloader or slot A or B)",
)
parser.add_argument(
"path", nargs="?", default=None, help="Path to the App to flash"
)
args = parser.parse_args()
serial_port = None
if Path("loader.toml").exists():
with open("loader.toml", "r") as toml_file:
parsed_toml = toml.loads(toml_file.read())
if "serial_port" in parsed_toml:
serial_port = parsed_toml["serial_port"]
if serial_port is None:
serial_port = input("Please specify the serial port manually: ")
serial_cfg = SerialCfg(
com_if_id="ser_cobs",
serial_port=serial_port,
baud_rate=BAUD_RATE,
polling_frequency=0.1,
)
verificator = PusVerificator()
com_if = SerialCobsComIF(serial_cfg)
com_if.open()
target = None
if args.target == "bl":
target = Target.BOOTLOADER
elif args.target == "a":
target = Target.APP_A
elif args.target == "b":
target = Target.APP_B
boot_sel = None
if args.sel:
if args.sel == "a":
boot_sel = AppSel.APP_A
elif args.sel == "b":
boot_sel = AppSel.APP_B
image_loader = ImageLoader(com_if, verificator)
file_path = None
result = -1
if args.ping:
image_loader.handle_ping_cmd()
com_if.close()
return 0
if args.sel and boot_sel is not None:
image_loader.handle_boot_sel_cmd(boot_sel)
if target:
if not args.corrupt:
if not args.path:
_LOGGER.error("App Path needs to be specified for the flash process")
file_path = Path(args.path)
if not file_path.exists():
_LOGGER.error("File does not exist")
if args.corrupt:
if not target:
_LOGGER.error("target for corruption command required")
com_if.close()
return -1
image_loader.handle_corruption_cmd(target)
else:
if file_path is not None:
assert target is not None
result = image_loader.handle_flash_cmd(target, file_path)
com_if.close()
return result
def create_loadable_segments(
target: Target, file_path: Path
) -> Tuple[List[LoadableSegment], int]:
loadable_segments = []
total_size = 0
with open(file_path, "rb") as app_file:
elf_file = ELFFile(app_file)
for idx, segment in enumerate(elf_file.iter_segments("PT_LOAD")):
if segment.header.p_filesz == 0:
continue
# Basic validity checks of the base addresses.
if idx == 0:
if (
target == Target.BOOTLOADER
and segment.header.p_paddr != BOOTLOADER_START_ADDR
):
raise ValueError(
f"detected possibly invalid start address {segment.header.p_paddr:#08x} for "
f"bootloader, expected {BOOTLOADER_START_ADDR}"
)
if (
target == Target.APP_A
and segment.header.p_paddr != APP_A_START_ADDR
):
raise ValueError(
f"detected possibly invalid start address {segment.header.p_paddr:#08x} for "
f"App A, expected {APP_A_START_ADDR}"
)
if (
target == Target.APP_B
and segment.header.p_paddr != APP_B_START_ADDR
):
raise ValueError(
f"detected possibly invalid start address {segment.header.p_paddr:#08x} for "
f"App B, expected {APP_B_START_ADDR}"
)
name = None
for section in elf_file.iter_sections():
if (
section.header.sh_offset == segment.header.p_offset
and section.header.sh_size > 0
):
name = section.name
if name is None:
_LOGGER.warning("no fitting section found for segment")
continue
# print(f"Segment Addr: {segment.header.p_paddr}")
# print(f"Segment Offset: {segment.header.p_offset}")
# print(f"Segment Filesize: {segment.header.p_filesz}")
loadable_segments.append(
LoadableSegment(
name=name,
offset=segment.header.p_paddr,
size=segment.header.p_filesz,
data=segment.data(),
)
)
total_size += segment.header.p_filesz
return loadable_segments, total_size
def check_segments(
target: Target,
total_size: int,
):
# Set context string and perform basic sanity checks.
if target == Target.BOOTLOADER and total_size > BOOTLOADER_MAX_SIZE:
raise ValueError(
f"provided bootloader app larger than allowed {total_size} bytes"
)
elif target == Target.APP_A and total_size > APP_A_MAX_SIZE:
raise ValueError(f"provided App A larger than allowed {total_size} bytes")
elif target == Target.APP_B and total_size > APP_B_MAX_SIZE:
raise ValueError(f"provided App B larger than allowed {total_size} bytes")
def print_segments_info(
target: Target,
loadable_segments: List[LoadableSegment],
total_size: int,
file_path: Path,
):
# Set context string and perform basic sanity checks.
if target == Target.BOOTLOADER:
context_str = "Bootloader"
elif target == Target.APP_A:
context_str = "App Slot A"
elif target == Target.APP_B:
context_str = "App Slot B"
_LOGGER.info(f"Flashing {context_str} with image {file_path} (size {total_size})")
for idx, segment in enumerate(loadable_segments):
_LOGGER.info(
f"Loadable section {idx} {segment.name} with offset {segment.offset:#08x} and "
f"size {segment.size}"
)
def pack_memory_write_command(addr: int, data: bytes) -> PusTc:
app_data = bytearray()
app_data.append(BOOT_NVM_MEMORY_ID)
# N parameter is always 1 here.
app_data.append(1)
app_data.extend(struct.pack("!I", addr))
app_data.extend(struct.pack("!I", len(data)))
app_data.extend(data)
return PusTc(
apid=0,
service=MEMORY_SERVICE,
subservice=RAW_MEMORY_WRITE_SUBSERVICE,
seq_count=SEQ_PROVIDER.get_and_increment(),
app_data=bytes(app_data),
)
if __name__ == "__main__":
main()
-1
View File
@@ -1 +0,0 @@
serial_port = "/dev/ttyUSB1"
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "models"
version = "0.1.0"
edition = "2024"
[dependencies]
postcard = { version = "1" }
spacepackets = { version = "0.17", default-features = false, features = ["defmt"] }
num_enum = { version = "0.7", default-features = false }
defmt = { version = "1", optional = true }
serde = { version = "1", default-features = false, features = ["derive"] }
cobs = { version = "0.5", default-features = false }
thiserror = { version = "2", default-features = false }
arbitrary-int = "2"
+98
View File
@@ -0,0 +1,98 @@
#![no_std]
use arbitrary_int::u11;
use cobs::DestBufTooSmallError;
use spacepackets::{
CcsdsPacketCreationError, CcsdsPacketCreatorWithReservedData, SpacePacketHeader,
};
pub const APID: u11 = u11::new(0x01);
pub const BOOTLOADER_START_ADDR: u32 = 0x0000_0000;
pub const BOOTLOADER_END_ADDR: u32 = 0x0000_3000;
pub const BOOTLOADER_CRC_ADDR: u32 = BOOTLOADER_END_ADDR - 2;
pub const BOOTLOADER_MAX_SIZE: u32 = BOOTLOADER_END_ADDR - BOOTLOADER_START_ADDR - 2;
pub const APP_A_START_ADDR: u32 = 0x0000_3000;
pub const APP_B_END_ADDR: u32 = 0x0002_0000 - 8;
pub const IMG_SLOT_SIZE: u32 = (APP_B_END_ADDR - APP_A_START_ADDR) / 2;
pub const APP_A_END_ADDR: u32 = APP_A_START_ADDR + IMG_SLOT_SIZE;
pub const APP_A_SIZE_ADDR: u32 = APP_A_END_ADDR - 8;
pub const APP_A_CRC_ADDR: u32 = APP_A_END_ADDR - 4;
pub const APP_A_MAX_SIZE: u32 = IMG_SLOT_SIZE - 8;
pub const APP_B_START_ADDR: u32 = APP_A_END_ADDR;
pub const APP_B_SIZE_ADDR: u32 = APP_B_END_ADDR - 8;
pub const APP_B_CRC_ADDR: u32 = APP_B_END_ADDR - 4;
pub const APP_B_MAX_SIZE: u32 = IMG_SLOT_SIZE - 8;
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
num_enum::TryFromPrimitive,
serde::Serialize,
serde::Deserialize,
)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum AppSel {
A = 0,
B = 1,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Request {
Ping,
Corrupt(AppSel),
WriteNvm { offset: u32 },
SetBootSlot(AppSel),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Response {
Ok,
}
pub fn create_tm_packet(
buf: &mut [u8],
sp_header: SpacePacketHeader,
response: Response,
) -> Result<usize, CcsdsPacketCreationError> {
let packet_data_size = postcard::experimental::serialized_size(&response).unwrap();
let mut creator =
CcsdsPacketCreatorWithReservedData::new_tm_with_checksum(sp_header, packet_data_size, buf)?;
let current_index = 0;
postcard::to_slice(&response, &mut creator.packet_data_mut()[current_index..]).unwrap();
Ok(creator.finish())
}
#[derive(Debug, thiserror::Error)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PacketCreationAndEncodingError {
#[error("packet creation failed: {0}")]
Creation(#[from] CcsdsPacketCreationError),
#[error("destination buffer too small: {0}")]
Encoding(#[from] DestBufTooSmallError),
}
pub fn create_encoded_tm_packet(
buf: &mut [u8],
encoded_buf: &mut [u8],
sp_header: SpacePacketHeader,
response: Response,
) -> Result<usize, PacketCreationAndEncodingError> {
let packet_len = create_tm_packet(buf, sp_header, response)?;
let encoded_len =
cobs::try_encode_including_sentinels(&buf[0..packet_len], &mut encoded_buf[..])?;
Ok(encoded_len)
}
#[cfg(test)]
mod tests {}
-5
View File
@@ -1,5 +0,0 @@
spacepackets == 0.28
com-interface == 0.1
toml == 0.10
pyelftools == 0.31
crcmod == 1.7
+173 -333
View File
@@ -4,50 +4,22 @@
#![no_std]
use defmt_rtt as _; // global logger
use num_enum::TryFromPrimitive;
use panic_probe as _;
use ringbuf::{
traits::{Consumer, Observer, Producer},
StaticRb,
};
use va108xx_hal::prelude::*;
use va108xx_hal::time::Hertz;
const SYSCLK_FREQ: Hertz = Hertz::from_raw(50_000_000);
const UART_BANK: va108xx_hal::uart::Bank = va108xx_hal::uart::Bank::Uart0;
const MAX_TC_SIZE: usize = 524;
const MAX_TC_FRAME_SIZE: usize = cobs::max_encoding_length(MAX_TC_SIZE);
pub const MAX_TC_SIZE: usize = 524;
pub const MAX_TC_FRAME_SIZE: usize = cobs::max_encoding_length(MAX_TC_SIZE);
const MAX_TM_SIZE: usize = 128;
const MAX_TM_FRAME_SIZE: usize = cobs::max_encoding_length(MAX_TM_SIZE);
const UART_BAUDRATE: u32 = 115200;
const BOOT_NVM_MEMORY_ID: u8 = 1;
const RX_DEBUGGING: bool = false;
pub enum ActionId {
CorruptImageA = 128,
CorruptImageB = 129,
SetBootSlot = 130,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, defmt::Format)]
#[repr(u8)]
enum AppSel {
A = 0,
B = 1,
}
// Larger buffer for TC to be able to hold the possibly large memory write packets.
const BUF_RB_SIZE_TC: usize = 1024;
const SIZES_RB_SIZE_TC: usize = 16;
const BUF_RB_SIZE_TM: usize = 256;
const SIZES_RB_SIZE_TM: usize = 16;
pub struct RingBufWrapper<const BUF_SIZE: usize, const SIZES_LEN: usize> {
pub buf: StaticRb<u8, BUF_SIZE>,
pub sizes: StaticRb<usize, SIZES_LEN>,
}
const TC_PIPE_SIZE: usize = 1024;
const TM_PIPE_SIZE: usize = 128;
pub const APP_A_START_ADDR: u32 = 0x3000;
pub const APP_A_END_ADDR: u32 = 0x117FC;
@@ -59,21 +31,16 @@ pub const PREFERRED_SLOT_OFFSET: u32 = 0x20000 - 1;
#[rtic::app(device = pac, dispatchers = [OC20, OC21, OC22])]
mod app {
use super::*;
use arbitrary_int::traits::Integer as _;
use arbitrary_int::{u11, u14};
use cobs::CobsDecoderHeapless;
use cortex_m::asm;
use embedded_io::Write;
use rtic::Mutex;
use rtic_monotonics::systick::prelude::*;
use satrs::pus::verification::{FailParams, VerificationReportCreator};
use satrs::spacepackets::ecss::PusServiceId;
use satrs::spacepackets::ecss::{
tc::PusTcReader, tm::PusTmCreator, EcssEnumU8, PusPacket, WritablePusPacket,
};
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex};
use embedded_io_async::Write as _;
use models::{create_encoded_tm_packet, Response};
use spacepackets::{CcsdsPacketReader, SpacePacketHeader};
use va108xx_hal::pins::PinsA;
use va108xx_hal::spi::SpiClockConfig;
use va108xx_hal::uart::InterruptContextTimeoutOrMaxSize;
use va108xx_hal::{pac, uart, InterruptConfig};
use va108xx_hal::uart::{self, TxAsync};
use va108xx_hal::{pac, InterruptConfig};
use vorago_reb1::m95m01::M95M01;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
@@ -87,71 +54,73 @@ mod app {
#[local]
struct Local {
uart_rx: uart::RxWithInterrupt,
uart_tx: uart::Tx,
rx_context: InterruptContextTimeoutOrMaxSize,
verif_reporter: VerificationReportCreator,
uart_tx: uart::TxAsync,
nvm: M95M01,
tc_tx: embassy_sync::pipe::Writer<'static, CriticalSectionRawMutex, TC_PIPE_SIZE>,
tc_rx: embassy_sync::pipe::Reader<'static, CriticalSectionRawMutex, TC_PIPE_SIZE>,
// We are only using this in threads, and RTIC ensures there are no conflicts.
tm_tx: embassy_sync::pipe::Writer<'static, NoopRawMutex, TM_PIPE_SIZE>,
tm_rx: embassy_sync::pipe::Reader<'static, NoopRawMutex, TM_PIPE_SIZE>,
}
#[shared]
struct Shared {
// Having this shared allows multiple tasks to generate telemetry.
tm_rb: RingBufWrapper<BUF_RB_SIZE_TM, SIZES_RB_SIZE_TM>,
tc_rb: RingBufWrapper<BUF_RB_SIZE_TC, SIZES_RB_SIZE_TC>,
}
rtic_monotonics::systick_monotonic!(Mono, 1000);
struct Shared {}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
defmt::println!("-- Vorago flashloader --");
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
let periphs = cx.device;
va108xx_hal::embassy_time::init(periphs.tim14, periphs.tim15, SYSCLK_FREQ);
let dp = cx.device;
let spi_clock_config = SpiClockConfig::new(2, 4);
let nvm = M95M01::new(dp.spic, spi_clock_config);
let nvm = M95M01::new(periphs.spic, spi_clock_config);
let gpioa = PinsA::new(dp.porta);
let gpioa = PinsA::new(periphs.porta);
let tx = gpioa.pa9;
let rx = gpioa.pa8;
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,
periphs.uarta,
tx,
rx,
SYSCLK_FREQ,
UART_BAUDRATE.Hz().into(),
uart_config,
InterruptConfig::new(pac::Interrupt::OC0, true, true),
);
let (tx, rx) = irq_uart.split();
// Unwrap is okay, we explicitely set the interrupt ID.
let mut rx = rx.into_rx_with_irq();
let mut rx = rx.into_rx_with_interrupt();
let verif_reporter = VerificationReportCreator::new(u11::new(0));
rx.start();
tc_handler::spawn().unwrap();
tm_tx_handler::spawn().unwrap();
let mut rx_context = InterruptContextTimeoutOrMaxSize::new(MAX_TC_FRAME_SIZE);
rx.read_fixed_len_or_timeout_based_using_irq(&mut rx_context)
.expect("initiating UART RX failed");
pus_tc_handler::spawn().unwrap();
pus_tm_tx_handler::spawn().unwrap();
let tx_async = TxAsync::new(tx);
static TC_PIPE: static_cell::ConstStaticCell<
embassy_sync::pipe::Pipe<CriticalSectionRawMutex, TC_PIPE_SIZE>,
> = static_cell::ConstStaticCell::new(embassy_sync::pipe::Pipe::new());
static TM_PIPE: static_cell::ConstStaticCell<
embassy_sync::pipe::Pipe<NoopRawMutex, TM_PIPE_SIZE>,
> = static_cell::ConstStaticCell::new(embassy_sync::pipe::Pipe::new());
let (tc_rx, tc_tx) = TC_PIPE.take().split();
let (tm_rx, tm_tx) = TM_PIPE.take().split();
(
Shared {
tc_rb: RingBufWrapper {
buf: StaticRb::default(),
sizes: StaticRb::default(),
},
tm_rb: RingBufWrapper {
buf: StaticRb::default(),
sizes: StaticRb::default(),
},
},
Shared {},
Local {
uart_rx: rx,
uart_tx: tx,
rx_context,
verif_reporter,
uart_tx: tx_async,
nvm,
tc_tx,
tc_rx,
tm_tx,
tm_rx,
},
)
}
@@ -168,285 +137,156 @@ mod app {
#[task(
binds = OC0,
local = [
cnt: u32 = 0,
rx_buf: [u8; MAX_TC_FRAME_SIZE] = [0; MAX_TC_FRAME_SIZE],
rx_context,
uart_rx,
tc_tx
],
shared = [tc_rb]
)]
fn uart_rx_irq(mut cx: uart_rx_irq::Context) {
match cx
.local
.uart_rx
.on_interrupt_max_size_or_timeout_based(cx.local.rx_context, cx.local.rx_buf)
{
Ok(result) => {
if RX_DEBUGGING {
defmt::debug!("RX Info: {:?}", cx.local.rx_context);
defmt::debug!("RX Result: {:?}", result);
fn uart_irq(cx: uart_irq::Context) {
let mut buf: [u8; 16] = [0; 16];
let result = cx.local.uart_rx.on_interrupt(&mut buf);
if result.bytes_read > 0 {
let mut written_so_far = 0;
while written_so_far < result.bytes_read {
let write_result = cx
.local
.tc_tx
.try_write(&buf[written_so_far..result.bytes_read]);
if write_result.is_err() {
defmt::warn!("TC pipe full, dropping bytes");
break;
}
if result.complete() {
// Check frame validity (must have COBS format) and decode the frame.
// Currently, we expect a full frame or a frame received through a timeout
// to be one COBS frame. We could parse for multiple COBS packets in one
// frame, but the additional complexity is not necessary here..
if cx.local.rx_buf[0] == 0 && cx.local.rx_buf[result.bytes_read - 1] == 0 {
let decoded_size =
cobs::decode_in_place(&mut cx.local.rx_buf[1..result.bytes_read]);
if decoded_size.is_err() {
defmt::warn!("COBS decoding failed");
} else {
let decoded_size = decoded_size.unwrap();
let mut tc_rb_full = false;
cx.shared.tc_rb.lock(|rb| {
if rb.sizes.vacant_len() >= 1 && rb.buf.vacant_len() >= decoded_size
{
rb.sizes.try_push(decoded_size).unwrap();
rb.buf.push_slice(&cx.local.rx_buf[1..1 + decoded_size]);
} else {
tc_rb_full = true;
}
});
if tc_rb_full {
defmt::warn!("COBS TC queue full");
}
}
} else {
defmt::warn!(
"COBS frame with invalid format, start and end bytes are not 0"
);
}
// Initiate next transfer.
cx.local
.uart_rx
.read_fixed_len_or_timeout_based_using_irq(cx.local.rx_context)
.expect("read operation failed");
}
if result.has_errors() {
defmt::warn!("UART error: {:?}", result.errors.unwrap());
}
}
Err(e) => {
defmt::warn!("UART error: {:?}", e);
written_so_far += write_result.unwrap();
}
}
va108xx_hal::uart::tx_async::on_interrupt_tx(UART_BANK);
}
#[task(
priority = 2,
local=[
tc_buf: [u8; MAX_TC_SIZE] = [0; MAX_TC_SIZE],
readback_buf: [u8; MAX_TC_SIZE] = [0; MAX_TC_SIZE],
src_data_buf: [u8; 16] = [0; 16],
verif_buf: [u8; 32] = [0; 32],
nvm,
verif_reporter
tc_rx,
tm_tx
],
shared=[tm_rb, tc_rb]
)]
async fn pus_tc_handler(mut cx: pus_tc_handler::Context) {
async fn tc_handler(cx: tc_handler::Context) {
let mut read_buf: [u8; 64] = [0; 64];
let mut tm_buf: [u8; MAX_TM_FRAME_SIZE] = [0; MAX_TM_FRAME_SIZE];
let mut encoded_tm_buf: [u8; MAX_TM_FRAME_SIZE] = [0; MAX_TM_FRAME_SIZE];
let mut cobs_decoder = CobsDecoderHeapless::<TC_PIPE_SIZE>::new();
loop {
// Try to read a TC from the ring buffer.
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;
continue;
let read_bytes = cx.local.tc_rx.read(&mut read_buf).await;
for &byte in read_buf[0..read_bytes].iter() {
match cobs_decoder.feed(byte) {
Ok(result) => {
if result.is_none() {
continue;
}
let frame = result.unwrap();
match CcsdsPacketReader::new_with_checksum(&cobs_decoder.dest()[0..frame]) {
Ok(packet) => {
let request = postcard::take_from_bytes::<models::Request>(
packet.user_data(),
);
if request.is_err() {
defmt::warn!(
"Failed to parse command: {}",
request.err().unwrap()
);
continue;
}
let (request, remainder) = request.unwrap();
let response = match request {
models::Request::Corrupt(slot) => {
match slot {
models::AppSel::A => {
defmt::info!("corrupting App Image A");
corrupt_image(APP_A_START_ADDR, cx.local.nvm);
}
models::AppSel::B => {
defmt::info!("corrupting App Image B");
corrupt_image(APP_B_START_ADDR, cx.local.nvm);
}
}
Response::Ok
}
models::Request::WriteNvm { offset } => {
defmt::info!(
"writing {} bytes to NVM at offset 0x{:08x}",
remainder.len(),
offset
);
cx.local.nvm.write(offset as usize, remainder);
defmt::info!("write complete");
Response::Ok
}
models::Request::SetBootSlot(app_sel) => {
defmt::info!(
"received boot selection command with app select: {:?}",
app_sel
);
cx.local.nvm.write(
PREFERRED_SLOT_OFFSET as usize,
&[app_sel as u8],
);
Response::Ok
}
models::Request::Ping => {
defmt::info!("received ping TC");
Response::Ok
}
};
match create_encoded_tm_packet(
&mut tm_buf,
&mut encoded_tm_buf,
SpacePacketHeader::new_from_apid(models::APID),
response,
) {
Ok(encoded_len) => {
cx.local
.tm_tx
.write_all(&encoded_tm_buf[0..encoded_len])
.await;
}
Err(e) => {
defmt::warn!("Failed to create or encode TM packet: {}", e);
}
}
}
Err(e) => {
defmt::warn!("CCSDS packet error: {}", e);
}
}
}
Err(e) => {
defmt::warn!("COBS decoding error: {}", e);
}
}
}
let packet_len = packet_len.unwrap();
defmt::info!("received packet with length {}", packet_len);
let popped_packet_len = cx
.shared
.tc_rb
.lock(|rb| rb.buf.pop_slice(&mut cx.local.tc_buf[0..packet_len]));
assert_eq!(popped_packet_len, packet_len);
// Read a telecommand, now handle it.
handle_valid_pus_tc(&mut cx);
}
}
fn handle_valid_pus_tc(cx: &mut pus_tc_handler::Context) {
let pus_tc = PusTcReader::new(cx.local.tc_buf);
if let Err(e) = pus_tc {
defmt::warn!("PUS TC error: {}", e);
return;
}
let pus_tc = pus_tc.unwrap();
let mut write_and_send = |tm: &PusTmCreator| {
let written_size = tm.write_to_bytes(cx.local.verif_buf).unwrap();
cx.shared.tm_rb.lock(|prod| {
prod.sizes.try_push(tm.len_written()).unwrap();
prod.buf.push_slice(&cx.local.verif_buf[0..written_size]);
});
};
let request_id = cx.local.verif_reporter.read_request_id(&pus_tc);
let tm = cx
.local
.verif_reporter
.acceptance_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("acceptance success failed");
write_and_send(&tm);
let tm = cx
.local
.verif_reporter
.start_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("acceptance success failed");
write_and_send(&tm);
if pus_tc.service_type_id() == PusServiceId::Action as u8 {
let mut corrupt_image = |base_addr: u32| {
let mut buf = [0u8; 4];
cx.local.nvm.read(base_addr as usize + 32, &mut buf);
buf[0] += 1;
cx.local.nvm.write(base_addr as usize + 32, &buf);
let tm = cx
.local
.verif_reporter
.completion_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("completion success failed");
write_and_send(&tm);
};
if pus_tc.message_subtype_id() == ActionId::CorruptImageA as u8 {
defmt::info!("corrupting App Image A");
corrupt_image(APP_A_START_ADDR);
}
if pus_tc.message_subtype_id() == ActionId::CorruptImageB as u8 {
defmt::info!("corrupting App Image B");
corrupt_image(APP_B_START_ADDR);
}
if pus_tc.message_subtype_id() == ActionId::SetBootSlot as u8 {
if pus_tc.app_data().is_empty() {
defmt::warn!("App data for preferred image command too short");
}
let app_sel_result = AppSel::try_from(pus_tc.app_data()[0]);
if app_sel_result.is_err() {
defmt::warn!("Invalid app selection value: {}", pus_tc.app_data()[0]);
}
defmt::info!(
"received boot selection command with app select: {:?}",
app_sel_result.unwrap()
);
cx.local
.nvm
.write(PREFERRED_SLOT_OFFSET as usize, &[pus_tc.app_data()[0]]);
let tm = cx
.local
.verif_reporter
.completion_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("completion success failed");
write_and_send(&tm);
}
}
if pus_tc.service_type_id() == PusServiceId::Test as u8 && pus_tc.message_subtype_id() == 1
{
defmt::info!("received ping TC");
let tm = cx
.local
.verif_reporter
.completion_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("completion success failed");
write_and_send(&tm);
} else if pus_tc.service_type_id() == PusServiceId::MemoryManagement as u8 {
let tm = cx
.local
.verif_reporter
.step_success(
cx.local.src_data_buf,
&request_id,
u14::ZERO,
0,
&[],
EcssEnumU8::new(0),
)
.expect("step success failed");
write_and_send(&tm);
// Raw memory write TC
if pus_tc.message_subtype_id() == 2 {
let app_data = pus_tc.app_data();
if app_data.len() < 10 {
defmt::warn!(
"app data for raw memory write is too short: {}",
app_data.len()
);
}
let memory_id = app_data[0];
if memory_id != BOOT_NVM_MEMORY_ID {
defmt::warn!("memory ID {} not supported", memory_id);
// TODO: Error reporting
return;
}
let offset = u32::from_be_bytes(app_data[2..6].try_into().unwrap());
let data_len = u32::from_be_bytes(app_data[6..10].try_into().unwrap());
if 10 + data_len as usize > app_data.len() {
defmt::warn!(
"invalid data length {} for raw mem write detected",
data_len
);
// TODO: Error reporting
return;
}
let data = &app_data[10..10 + data_len as usize];
defmt::info!("writing {} bytes at offset {} to NVM", data_len, offset);
cx.local.nvm.write(offset as usize, data);
let tm = if !cx.local.nvm.verify(offset as usize, data) {
defmt::warn!("verification of data written to NVM failed");
cx.local
.verif_reporter
.completion_failure(
cx.local.src_data_buf,
&request_id,
u14::ZERO,
0,
FailParams::new(&[], &EcssEnumU8::new(0), &[]),
)
.expect("completion success failed")
} else {
cx.local
.verif_reporter
.completion_success(cx.local.src_data_buf, &request_id, u14::ZERO, 0, &[])
.expect("completion success failed")
};
write_and_send(&tm);
defmt::info!("NVM operation done");
}
}
pub fn corrupt_image(base_addr: u32, nvm: &mut M95M01) {
let mut buf = [0u8; 4];
nvm.read(base_addr as usize + 32, &mut buf);
buf[0] += 1;
nvm.write(base_addr as usize + 32, &buf);
}
#[task(
priority = 1,
local=[
read_buf: [u8;MAX_TM_SIZE] = [0; MAX_TM_SIZE],
encoded_buf: [u8;MAX_TM_FRAME_SIZE] = [0; MAX_TM_FRAME_SIZE],
uart_tx,
tm_rx
],
shared=[tm_rb]
)]
async fn pus_tm_tx_handler(mut cx: pus_tm_tx_handler::Context) {
async fn tm_tx_handler(cx: tm_tx_handler::Context) {
let mut buf: [u8; 256] = [0; 256];
loop {
let mut occupied_len = cx.shared.tm_rb.lock(|rb| rb.sizes.occupied_len());
while occupied_len > 0 {
let next_size = cx.shared.tm_rb.lock(|rb| {
let next_size = rb.sizes.try_pop().unwrap();
rb.buf.pop_slice(&mut cx.local.read_buf[0..next_size]);
next_size
});
cx.local.encoded_buf[0] = 0;
let send_size = cobs::encode(
&cx.local.read_buf[0..next_size],
&mut cx.local.encoded_buf[1..],
);
cx.local.encoded_buf[send_size + 1] = 0;
cx.local
.uart_tx
.write_all(&cx.local.encoded_buf[0..send_size + 2])
.unwrap();
occupied_len -= 1;
Mono::delay(2.millis()).await;
let read_len = cx.local.tm_rx.read(&mut buf).await;
if let Err(e) = cx.local.uart_tx.write_all(&buf[0..read_len]).await {
defmt::warn!("UART TX overrun error: {}", e);
}
Mono::delay(50.millis()).await;
}
}
}
+4
View File
@@ -0,0 +1,4 @@
[toolchain]
channel = "stable"
components = ["clippy", "llvm-tools"]
target = "thumbv6m-none-eabi"
-36
View File
@@ -1,36 +0,0 @@
Change Log
=======
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v0.3.0] 2025-09-03
Bumped allowed va108xx-hal to v0.12
## [v0.2.1] 2025-03-07
- Bumped allowed va108xx-hal to v0.11
## [v0.2.0] 2025-02-17
- Bumped va108xx-hal to v0.10.0
- Remove `embassy` module, expose public functions in library root directly
## [v0.1.2] and [v0.1.1] 2025-02-13
Docs patch
## [v0.1.0] 2025-02-13
Initial release
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-embassy-v0.3.0...HEAD
[v0.3.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-embassy-v0.2.1...va10xx-embassy-v0.3.0
[v0.2.1]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-embassy-v0.2.0...va10xx-embassy-v0.2.1
[v0.2.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-embassy-v0.1.2...va10xx-embassy-v0.2.0
-28
View File
@@ -1,28 +0,0 @@
[package]
name = "va108xx-embassy"
version = "0.3.0"
edition = "2021"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
description = "Embassy-rs support for the Vorago VA108xx family of microcontrollers"
homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-rs"
repository = "https://egit.irs.uni-stuttgart.de/rust/vorago-rs"
license = "Apache-2.0"
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"] }
va108xx-hal = { version = "0.12", path = "../va108xx-hal" }
[features]
default = ["irq-oc30-oc31"]
irqs-in-lib = []
# This determines the reserved interrupt functions for the embassy time drivers. Only one
# is allowed to be selected!
irq-oc28-oc29 = ["irqs-in-lib"]
irq-oc29-oc30 = ["irqs-in-lib"]
irq-oc30-oc31 = ["irqs-in-lib"]
[package.metadata.docs.rs]
targets = ["thumbv6m-none-eabi"]
rustdoc-args = ["--generate-link-to-definition"]
+1 -10
View File
@@ -1,10 +1 @@
[![Crates.io](https://img.shields.io/crates/v/va108xx-embassy)](https://crates.io/crates/va108xx-embassy)
[![docs.rs](https://img.shields.io/docsrs/va108xx-embassy)](https://docs.rs/va108xx-embassy)
# Embassy-rs support for the Vorago VA108xx MCU family
This repository contains the [embassy-rs](https://github.com/embassy-rs/embassy) support for the
VA108xx family. Currently, it contains the time driver to allow using embassy-rs. It uses the TIM
peripherals provided by the VA108xx family for this purpose.
The documentation contains more information on how to use this crate.
This crate was moved into `va108xx-hal`.
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
export RUSTDOCFLAGS="--cfg docsrs --generate-link-to-definition -Z unstable-options"
cargo +nightly doc --open
+7 -1
View File
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v0.13.0] 2026-05-19
- Bump `vorago-shared-hal` dependency to v0.4
- Integrate `va108xx-embassy` as a `embassy-time` module.
## [v0.12.0] 2025-09-03
## Changed
@@ -276,7 +281,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Added basic test binary in form of an example
- README with basic instructions how to set up own binary crate
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.12.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/vorago-rs/compare/va108xx-hal-v0.13.0...HEAD
[v0.13.0]: https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/tag/va108xx-hal-v0.13.0
[v0.12.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.11.1...va108xx-hal-v0.12.0
[v0.11.1]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.11.0...va108xx-hal-v0.11.1
[v0.11.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.10.0...va108xx-hal-v0.11.0
+14 -6
View File
@@ -1,8 +1,8 @@
[package]
name = "va108xx-hal"
version = "0.12.0"
version = "0.13.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2021"
edition = "2024"
description = "HAL for the Vorago VA108xx family of microcontrollers"
homepage = "https://egit.irs.uni-stuttgart.de/rust/vorago-rs"
repository = "https://egit.irs.uni-stuttgart.de/rust/vorago-rs"
@@ -12,10 +12,10 @@ 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.4", 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"] }
va108xx = { version = "0.6", path = "../va108xx", default-features = false, features = ["critical-section"] }
defmt = { version = "1", optional = true }
[target.'cfg(all(target_arch = "arm", target_os = "none"))'.dependencies]
@@ -26,7 +26,15 @@ portable-atomic = "1"
[features]
default = ["rt"]
rt = ["va108xx/rt"]
defmt = ["dep:defmt", "vorago-shared-hal/defmt"]
defmt = ["dep:defmt", "vorago-shared-hal/defmt", "va108xx/defmt"]
# Embassy time features
_irqs-in-lib = []
# This determines the reserved interrupt functions for the embassy time drivers. Only one
# is allowed to be selected!
embassy-oc30-oc31 = ["_irqs-in-lib"]
embassy-oc29-oc30 = ["_irqs-in-lib"]
embassy-oc28-oc29 = ["_irqs-in-lib"]
[package.metadata.docs.rs]
all-features = true
@@ -23,21 +23,20 @@
//!
//! You can disable the default features and then specify one of the features above to use the
//! documented combination of IRQs. It is also possible to specify custom IRQs by importing and
//! using the [embassy_time_driver_irqs] macro to declare the IRQ handlers in the
//! using the [crate::embassy_time_driver_irqs] macro to declare the IRQ handlers in the
//! application code. If this is done, [init_with_custom_irqs] must be used
//! method to pass the IRQ numbers to the library.
//!
//! ## Examples
//!
//! [embassy example projects](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/embassy)
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "irqs-in-lib")]
use va108xx_hal::pac::{self, interrupt};
use va108xx_hal::time::Hertz;
use va108xx_hal::timer::TimInstance;
use vorago_shared_hal::embassy::time_driver;
#[cfg(feature = "_irqs-in-lib")]
use crate::pac::{self, interrupt};
use crate::time::Hertz;
use crate::timer::TimInstance;
pub use vorago_shared_hal::embassy::time_driver;
/// Macro to define the IRQ handlers for the time driver.
///
@@ -45,7 +44,7 @@ use vorago_shared_hal::embassy::time_driver;
/// the feature flags specified. However, the macro is exported to allow users to specify the
/// interrupt handlers themselves.
///
/// Please note that you have to explicitely import the [macro@va108xx_hal::pac::interrupt]
/// Please note that you have to explicitely import the [macro@crate::pac::interrupt]
/// macro in the application code in case this macro is used there.
#[macro_export]
macro_rules! embassy_time_driver_irqs {
@@ -59,7 +58,7 @@ macro_rules! embassy_time_driver_irqs {
#[allow(non_snake_case)]
fn $timekeeper_irq() {
// Safety: We call it once here.
unsafe { $crate::time_driver().on_interrupt_timekeeping() }
unsafe { $crate::embassy_time::time_driver().on_interrupt_timekeeping() }
}
const ALARM_IRQ: pac::Interrupt = pac::Interrupt::$alarm_irq;
@@ -68,25 +67,25 @@ macro_rules! embassy_time_driver_irqs {
#[allow(non_snake_case)]
fn $alarm_irq() {
// Safety: We call it once here.
unsafe { $crate::time_driver().on_interrupt_alarm() }
unsafe { $crate::embassy_time::time_driver().on_interrupt_alarm() }
}
};
}
// Provide three combinations of IRQs for the time driver by default.
#[cfg(feature = "irq-oc30-oc31")]
#[cfg(feature = "embassy-oc30-oc31")]
embassy_time_driver_irqs!(timekeeper_irq = OC31, alarm_irq = OC30);
#[cfg(feature = "irq-oc29-oc30")]
#[cfg(feature = "embassy-oc29-oc30")]
embassy_time_driver_irqs!(timekeeper_irq = OC30, alarm_irq = OC29);
#[cfg(feature = "irq-oc28-oc29")]
#[cfg(feature = "embassy-oc28-oc29")]
embassy_time_driver_irqs!(timekeeper_irq = OC29, alarm_irq = OC28);
/// Initialization method for embassy.
///
/// This should be used if the interrupt handler is provided by the library, which is the
/// default case.
#[cfg(feature = "irqs-in-lib")]
#[cfg(feature = "_irqs-in-lib")]
pub fn init<TimekeeperTim: TimInstance, AlarmTim: TimInstance>(
timekeeper_tim: TimekeeperTim,
alarm_tim: AlarmTim,
@@ -102,8 +101,8 @@ pub fn init_with_custom_irqs<TimekeeperTim: TimInstance, AlarmTim: TimInstance>(
timekeeper_tim: TimekeeperTim,
alarm_tim: AlarmTim,
sysclk: Hertz,
timekeeper_irq: pac::Interrupt,
alarm_irq: pac::Interrupt,
timekeeper_irq: crate::pac::Interrupt,
alarm_irq: crate::pac::Interrupt,
) {
time_driver().__init(sysclk, timekeeper_tim, alarm_tim, timekeeper_irq, alarm_irq)
}
-5
View File
@@ -12,9 +12,4 @@
//!
//! The [crate::pins] module exposes singletons to access the [Pin]s required by this module
//! in a type-safe way.
//!
//! ## Examples
//!
//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/blinky.rs)
//! - [Async GPIO example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/embassy/src/bin/async-gpio.rs)
pub use vorago_shared_hal::gpio::*;
-4
View File
@@ -1,6 +1,2 @@
//! API for the I2C peripheral
//!
//! ## Examples
//!
//! - [REB1 I2C temperature sensor example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/vorago-reb1/examples/adt75-temp-sensor.rs)
pub use vorago_shared_hal::i2c::*;
+7 -2
View File
@@ -7,6 +7,9 @@
//! raw PAC. This crate also implements traits specified by the
//! [embedded-hal](https://github.com/rust-embedded/embedded-hal) project, making it compatible with
//! various drivers in the embedded rust ecosystem.
//!
//! The [examples folder](https://github.com/us-irs/vorago-rs/tree/main/va108xx/examples) contains
//! various example applications using the HAL.
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
@@ -26,9 +29,11 @@ pub mod time;
pub mod timer;
pub mod uart;
pub mod embassy_time;
pub use vorago_shared_hal::{
disable_nvic_interrupt, enable_nvic_interrupt, FunctionSelect, InterruptConfig,
PeripheralSelect,
FunctionSelect, InterruptConfig, PeripheralSelect, disable_nvic_interrupt,
enable_nvic_interrupt,
};
/// This is the NONE destination reigster value for the IRQSEL peripheral.
-6
View File
@@ -1,8 +1,2 @@
//! API for Pulse-Width Modulation (PWM)
//!
//! The Vorago VA108xx devices use the TIM peripherals to perform PWM related tasks
//!
//! ## Examples
//!
//! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/pwm.rs)
pub use vorago_shared_hal::pwm::*;
-6
View File
@@ -3,10 +3,4 @@
//! The main abstraction provided by this module is the [Spi] an structure.
//! It provides the [SpiBus trait](https://docs.rs/embedded-hal/latest/embedded_hal/spi/trait.SpiBus.html),
//! but also offer a low level interface via the [SpiLowLevel] trait.
//!
//! ## Examples
//!
//! - [Blocking SPI example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/spi.rs)
//! - [REB1 ADC example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/vorago-reb1/examples/max11519-adc.rs)
//! - [REB1 EEPROM library](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/vorago-reb1/src/m95m01.rs)
pub use vorago_shared_hal::spi::*;
+2 -1
View File
@@ -39,5 +39,6 @@ pub fn disable_ram_scrubbing() {
}
pub use vorago_shared_hal::sysconfig::{
assert_peripheral_reset, disable_peripheral_clock, enable_peripheral_clock,
assert_peripheral_reset, deassert_peripheral_reset, disable_peripheral_clock,
enable_peripheral_clock, reset_peripheral_for_cycles,
};
-5
View File
@@ -1,7 +1,2 @@
//! API for the TIM peripherals
//!
//! ## Examples
//!
//! - [MS and second tick implementation](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/timer-ticks.rs)
//! - [Cascade feature example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/cascade.rs)
pub use vorago_shared_hal::timer::*;
-8
View File
@@ -6,12 +6,4 @@
//!
//! The [rx_async] and [tx_async] modules provide an asynchronous non-blocking API for the UART
//! peripheral.
//!
//! ## Examples
//!
//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/simple/examples/uart.rs)
//! - [UART with IRQ and RTIC](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/rtic/src/bin/uart-echo-rtic.rs)
//! - [Flashloader exposing a CCSDS interface via UART](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/flashloader)
//! - [Async UART RX example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/embassy/src/bin/async-uart-rx.rs)
//! - [Async UART TX example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va108xx/examples/embassy/src/bin/async-uart-tx.rs)
pub use vorago_shared_hal::uart::*;
+6 -1
View File
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [unreleased]
## [v0.10.0] 2026-05-19
- Bumped `va108xx-hal` dependency to 0.13
## [v0.9.0] 2025-09-03
- Bumped `va108xx-hal` dependency to 0.12
@@ -66,7 +70,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
it provides a starting point
- Added ADC base library and example building on the new max116xx-10bit device driver crate
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.9.0...HEAD
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/vorago-rs/compare/vorago-reb1-v0.10.0...HEAD
[v0.10.0]: https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/tag/vorago-reb1-v0.10.0
[v0.9.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.8.1...vorago-reb1-v0.9.0
[v0.8.1]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.8.0...vorago-reb1-v0.8.1
[v0.8.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.7.0...vorago-reb1-v0.8.0
+5 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "vorago-reb1"
version = "0.9.0"
version = "0.10.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
edition = "2021"
description = "Board Support Crate for the Vorago REB1 development board"
@@ -11,20 +11,20 @@ keywords = ["no-std", "reb1", "cortex-m", "vorago", "va108xx"]
categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
cortex-m = { version = "0.7" }
embedded-hal = "1"
nb = "1"
bitbybit = "1.3"
bitbybit = "2"
arbitrary-int = "2"
max116xx-10bit = "0.3"
va108xx-hal = { version = "0.12", path = "../va108xx-hal", features = ["rt"] }
va108xx-hal = { version = "0.13", path = "../va108xx-hal", features = ["rt"] }
[features]
rt = ["va108xx-hal/rt"]
[dev-dependencies]
cortex-m-rt = "0.7"
panic-halt = "1"
nb = "1"
rtt-target = "0.6"
@@ -47,7 +47,7 @@ fn main() -> ! {
.mode(MODE_3)
.slave_output_disable(true);
let mut spi = Spi::new_for_spi1(dp.spib, (sck, miso, mosi), spi_cfg);
spi.cfg_hw_cs(hw_cs_id);
spi.configure_hw_cs(hw_cs_id);
let mut tx_rx_buf: [u8; 3] = [0; 3];
tx_rx_buf[0] = READ_MASK | DEVID_REG;
+2 -2
View File
@@ -83,7 +83,7 @@ impl<Delay: DelayNs> SpiDevice for SpiWithHwCs<Delay> {
) -> Result<(), Self::Error> {
// Only the HW CS is configured here. This is not really necessary, but showcases
// that we could scale this multiple SPI devices.
self.inner.cfg_hw_cs(self.hw_cs_id);
self.inner.configure_hw_cs(self.hw_cs_id);
for operation in operations {
match operation {
spi::Operation::Read(buf) => self.inner.read(buf),
@@ -93,7 +93,7 @@ impl<Delay: DelayNs> SpiDevice for SpiWithHwCs<Delay> {
spi::Operation::DelayNs(delay) => self.delay_provider.delay_ns(*delay),
};
}
self.inner.cfg_hw_cs_disable();
self.inner.disable_hw_cs();
Ok(())
}
}
+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
@@ -1,5 +1,5 @@
[workspace]
resolver = "2"
resolver = "3"
members = [
"va416xx",
"va416xx-hal",
+1 -1
View File
@@ -88,7 +88,7 @@ work yet.
After installation, you can run the following command
```sh
probe-rs run --chip VA416xx_RAM --protocol jtag target/thumbv7em-none-eabihf/debug/examples/blinky
probe-rs run --chip VA416xx_RAM --protocol jtag target/thumbv7em-none-eabihf/debug/blinky
```
to flash and run the blinky program on the RAM. There is also a `VA416xx` chip target
@@ -61,8 +61,14 @@ async fn main(_spawner: Spawner) {
let portg = PinsG::new(dp.portg);
let mut led = Output::new(portg.pg5, PinState::Low);
let uarta =
uart::Uart::new_for_uart0(dp.uart0, portg.pg0, portg.pg1, &clocks, 115200.Hz().into());
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
115200.Hz(),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uarta = uart::Uart::new_for_uart0(dp.uart0, portg.pg0, portg.pg1, uart_config);
let (mut tx_uart_a, rx_uart_a) = uarta.split();
let (prod_uart_a, cons_uart_a) = QUEUE_UART_A.take().split();
@@ -59,8 +59,14 @@ async fn main(_spawner: Spawner) {
let pinsg = PinsG::new(dp.portg);
let mut led = Output::new(pinsg.pg5, PinState::Low);
let uarta =
uart::Uart::new_for_uart0(dp.uart0, pinsg.pg0, pinsg.pg1, &clocks, 115200.Hz().into());
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
115200.Hz(),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uarta = uart::Uart::new_for_uart0(dp.uart0, pinsg.pg0, pinsg.pg1, uart_config);
let (tx, _rx) = uarta.split();
let mut async_tx = TxAsync::new(tx);
let mut ticker = Ticker::every(Duration::from_secs(1));
@@ -67,15 +67,16 @@ async fn main(spawner: Spawner) {
let portg = PinsG::new(dp.portg);
let uart0 = uart::Uart::new_for_uart0(
dp.uart0,
portg.pg0,
portg.pg1,
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
Hertz::from_raw(BAUDRATE).into(),
Hertz::from_raw(BAUDRATE),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uart0 = uart::Uart::new_for_uart0(dp.uart0, portg.pg0, portg.pg1, uart_config);
let (mut tx, rx) = uart0.split();
let mut rx = rx.into_rx_with_irq();
let mut rx = rx.into_rx_with_interrupt();
rx.start();
RX.lock(|static_rx| {
static_rx.borrow_mut().replace(rx);
+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();
+2 -16
View File
@@ -22,23 +22,9 @@ va416xx = { version = "0.5", path = "../../va416xx" }
[dependencies.vorago-peb1]
path = "../../vorago-peb1"
optional = true
[features]
default = ["va41630"]
va41630 = ["va416xx-hal/va41630", "has-adc-dac"]
va41629 = ["va416xx-hal/va41629", "has-adc-dac"]
va41630 = ["va416xx-hal/va41630"]
va41629 = ["va416xx-hal/va41629"]
va41628 = ["va416xx-hal/va41628"]
has-adc-dac = []
[[example]]
name = "peb1-accelerometer"
required-features = ["vorago-peb1"]
[[example]]
name = "dac-adc"
required-features = ["has-adc-dac"]
[[example]]
name = "adc"
required-features = ["has-adc-dac"]
@@ -15,7 +15,6 @@ use va416xx_hal::{
clock::ClockConfigurator,
i2c,
pac::{self},
prelude::*,
timer::CountdownTimer,
};
use vorago_peb1::lis2dh12::{self, detect_i2c_addr, FullScale, Odr};
@@ -29,7 +28,7 @@ const DISPLAY_MODE: DisplayMode = DisplayMode::Normalized;
#[entry]
fn main() -> ! {
let mut dp = pac::Peripherals::take().unwrap();
let dp = pac::Peripherals::take().unwrap();
defmt::println!("-- Vorago PEB1 accelerometer example --");
// Use the external clock connected to XTAL_N.
let clocks = ClockConfigurator::new(dp.clkgen)
@@ -30,13 +30,14 @@ fn main() -> ! {
let gpiog = PinsG::new(dp.portg);
let uart0 = uart::Uart::new_for_uart0(
dp.uart0,
gpiog.pg0,
gpiog.pg1,
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
Hertz::from_raw(115200).into(),
Hertz::from_raw(115200),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uart0 = uart::Uart::new_for_uart0(dp.uart0, gpiog.pg0, gpiog.pg1, uart_config);
let (mut tx, mut rx) = uart0.split();
writeln!(tx, "Hello World\n\r").unwrap();
loop {
@@ -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);
@@ -49,7 +49,7 @@ fn main() -> ! {
let mut counter: u32 = 0;
loop {
counter = counter.wrapping_add(1);
if counter % log_divisor == 0 {
if counter.is_multiple_of(log_divisor) {
defmt::info!("wdt example main loop alive");
}
if TEST_MODE != TestMode::AllowReset {
+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"] }
+10 -8
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::{
@@ -167,13 +167,15 @@ mod app {
let gpiog = PinsG::new(cx.device.portg);
let uart0 = Uart::new_for_uart0(
cx.device.uart0,
gpiog.pg0,
gpiog.pg1,
let clock_config = uart::ClockConfig::calculate_with_clocks(
uart::Bank::Uart0,
&clocks,
Hertz::from_raw(UART_BAUDRATE).into(),
fugit::HertzU32::from_raw(UART_BAUDRATE),
uart::BaudMode::_16,
);
let uart_config = uart::Config::new_with_clock_config(clock_config);
let uart0 = Uart::new_for_uart0(cx.device.uart0, gpiog.pg0, gpiog.pg1, uart_config);
let (tx, rx) = uart0.split();
let verif_reporter = VerificationReportCreator::new(u11::new(0));
@@ -192,10 +194,10 @@ 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();
let mut rx = rx.into_rx_with_interrupt();
let mut rx_context = InterruptContextTimeoutOrMaxSize::new(MAX_TC_FRAME_SIZE);
rx.read_fixed_len_or_timeout_based_using_irq(&mut rx_context)
.expect("initiating UART RX failed");
+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.4", path = "../../vorago-shared-hal", features = ["vor4x"] }
va416xx-hal = { version = "0.6", path = "../va416xx-hal" }
[features]
+4 -4
View File
@@ -15,18 +15,18 @@ 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.4", path = "../../vorago-shared-hal", features = ["vor4x"] }
libm = "0.2"
nb = "1"
embedded-hal = "1"
num_enum = { version = "0.7", default-features = false }
bitflags = "2"
bitbybit = "1.3"
bitbybit = "2"
arbitrary-int = "2"
fugit = "0.3"
fugit = "0.4"
embedded-can = "0.4"
embassy-sync = "0.7"
embassy-sync = "0.8"
thiserror = { version = "2", default-features = false }
defmt = { version = "1", optional = true }
-5
View File
@@ -1,9 +1,4 @@
//! Analog to Digital Converter (ADC) driver.
//!
//! ## Examples
//!
//! - [ADC and DAC example](https://github.com/us-irs/vorago-rs/blob/main/va416xx/examples/simple/examples/dac-adc.rs)
//! - [ADC](https://github.com/us-irs/vorago-rs/blob/main/va416xx/examples/simple/examples/adc.rs)
use core::marker::PhantomData;
use crate::clock::Clocks;
+3 -1
View File
@@ -3,6 +3,8 @@ use core::{
sync::atomic::{AtomicU8, Ordering},
};
use arbitrary_int::u4;
use crate::can::regs::BufferState;
use super::{
@@ -58,7 +60,7 @@ pub enum InterruptResult {
pub enum InterruptError {
UnexpectedError,
InvalidInterruptId(StatusPending),
InvalidStatus(u8),
InvalidStatus(u4),
UnexpectedState(BufferState),
CanError(DiagnosticRegister),
}
+1 -1
View File
@@ -81,7 +81,7 @@ impl CanChannelLowLevel {
}
#[inline]
pub fn read_state(&self) -> Result<BufferState, u8> {
pub fn read_state(&self) -> Result<BufferState, u4> {
self.msg_buf.read_stat_ctrl().state()
}
+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 -8
View File
@@ -6,10 +6,6 @@
//!
//! Calling [ClockConfigurator::freeze] returns the frozen clock configuration inside the [Clocks]
//! structure. This structure can also be used to configure other structures provided by this HAL.
//!
//! # Examples
//!
//! - [UART example on the PEB1 board](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/simple/examples/uart.rs)
#[cfg(not(feature = "va41628"))]
use crate::adc::ADC_MAX_CLK;
use crate::pac;
@@ -98,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),
}
}
@@ -386,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)
});
-4
View File
@@ -1,8 +1,4 @@
//! Digital to Analog Converter (DAC) driver.
//!
//! ## Examples
//!
//! - [ADC and DAC example](https://github.com/us-irs/vorago-rs/blob/main/va416xx/examples/simple/examples/dac-adc.rs)
use core::ops::Deref;
use vorago_shared_hal::{
-4
View File
@@ -1,8 +1,4 @@
//! API for the DMA peripheral
//!
//! ## Examples
//!
//! - [Simple DMA example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/simple/examples/dma.rs)
use arbitrary_int::{u10, u3};
use vorago_shared_hal::{enable_peripheral_clock, reset_peripheral_for_cycles, PeripheralSelect};
-5
View File
@@ -12,9 +12,4 @@
//!
//! The [crate::pins] module exposes singletons to access the [Pin]s required by this module
//! in a type-safe way.
//!
//! # Examples
//!
//! - [Blinky example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/simple/examples/blinky.rs)
//! - [Async GPIO example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/embassy/src/bin/async-gpio.rs)
pub use vorago_shared_hal::gpio::*;
-4
View File
@@ -1,6 +1,2 @@
//! API for the I2C peripheral
//!
//! ## Examples
//!
//! - [PEB1 accelerometer example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/simple/examples/peb1-accelerometer.rs)
pub use vorago_shared_hal::i2c::*;
+3
View File
@@ -25,6 +25,9 @@
//! with interrupts, it is strongly recommended to set up the IRQ router with the
//! [crate::irq_router] module at the very least because that peripheral has confusing and/or
//! faulty register reset values which might lead to weird bugs and glitches.
//!
//! The [examples folder](https://github.com/us-irs/vorago-rs/tree/main/va416xx/examples) contains
//! various example applications using the HAL.
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "alloc")]
-4
View File
@@ -1,8 +1,4 @@
//! API for Pulse-Width Modulation (PWM)
//!
//! The Vorago devices use the TIM peripherals to perform PWM related tasks
//!
//! ## Examples
//!
//! - [PWM example](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/examples/simple/examples/pwm.rs)
pub use vorago_shared_hal::pwm::*;

Some files were not shown because too many files have changed in this diff Show More