Compare commits
15 Commits
va108xx-ha
...
main
Author | SHA1 | Date | |
---|---|---|---|
5b2ded51f9 | |||
bab979ece3 | |||
0515ca5eaa | |||
86ac7428bb | |||
686b689a91 | |||
5daa85269f | |||
3bc2ee4343 | |||
1ec66e826c | |||
606d6a43b4 | |||
a83d9cca16 | |||
9eeaae76f7 | |||
39aaea086a | |||
a6ef0954cb | |||
102d11114a | |||
8cdee8b733 |
@ -18,9 +18,9 @@ rustflags = [
|
|||||||
"-C", "link-arg=-Tlink.x",
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
|
||||||
# knurling-rs tooling. If you want to use flip-link, ensure it is installed first.
|
# knurling-rs tooling. If you want to use flip-link, ensure it is installed first.
|
||||||
# "-C", "linker=flip-link",
|
"-C", "linker=flip-link",
|
||||||
# Unfortunately, defmt is clunky to use without probe-rs..
|
# Unfortunately, defmt is clunky to use without probe-rs..
|
||||||
# "-C", "link-arg=-Tdefmt.x",
|
"-C", "link-arg=-Tdefmt.x",
|
||||||
|
|
||||||
# Can be useful for debugging.
|
# Can be useful for debugging.
|
||||||
# "-Clink-args=-Map=app.map"
|
# "-Clink-args=-Map=app.map"
|
||||||
|
@ -13,7 +13,6 @@ members = [
|
|||||||
"flashloader",
|
"flashloader",
|
||||||
]
|
]
|
||||||
exclude = [
|
exclude = [
|
||||||
"defmt-testapp",
|
|
||||||
"flashloader/slot-a-blinky",
|
"flashloader/slot-a-blinky",
|
||||||
"flashloader/slot-b-blinky",
|
"flashloader/slot-b-blinky",
|
||||||
]
|
]
|
||||||
|
26
README.md
26
README.md
@ -77,7 +77,7 @@ to flash and run the blinky program on the RAM. There is also a `VA108xx` chip t
|
|||||||
available for persistent flashing.
|
available for persistent flashing.
|
||||||
|
|
||||||
Runner configuration avilable in the `.cargo/def-config.toml` file to use `probe-rs` for
|
Runner configuration avilable in the `.cargo/def-config.toml` file to use `probe-rs` for
|
||||||
convenience.
|
convenience. `probe-rs` is also able to process and display `defmt` strings directly.
|
||||||
|
|
||||||
### Using VS Code
|
### Using VS Code
|
||||||
|
|
||||||
@ -123,13 +123,13 @@ is also run when running the `jlink-gdb.sh` script)
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG-speed auto \
|
JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG-speed auto \
|
||||||
-LocalhostOnly
|
-LocalhostOnly -jtagconf -1,-1
|
||||||
```
|
```
|
||||||
|
|
||||||
After this, you can flash and debug the application with the following command
|
After this, you can flash and debug the application with the following command
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
gdb-mutliarch -q -x jlink/jlink.gdb target/thumbv6m-none-eabihf/debug/examples/blinky
|
gdb-mutliarch -q -x jlink/jlink.gdb target/thumbv6m-none-eabihf/debug/examples/blinky -tui
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note that you can automate all steps except starting the GDB server by using a cargo
|
Please note that you can automate all steps except starting the GDB server by using a cargo
|
||||||
@ -148,3 +148,23 @@ example.
|
|||||||
The Segger RTT viewer can be used to display log messages received from the target. The base
|
The Segger RTT viewer can be used to display log messages received from the target. The base
|
||||||
address for the RTT block placement is 0x10000000. It is recommended to use a search range of
|
address for the RTT block placement is 0x10000000. It is recommended to use a search range of
|
||||||
0x1000 around that base address when using the RTT viewer.
|
0x1000 around that base address when using the RTT viewer.
|
||||||
|
|
||||||
|
The RTT viewer will not be able to process `defmt` printouts. However, you can view the defmt
|
||||||
|
logs by [installing defmt-print](https://crates.io/crates/defmt-print) first and then piping
|
||||||
|
the output on telnet port 19021 into `defmt-print`, for example by running
|
||||||
|
|
||||||
|
```sh
|
||||||
|
telnet localhost 19021 | defmt-print -e <pathToElfFile>
|
||||||
|
```
|
||||||
|
|
||||||
|
The path of the ELF file which is being debugged needs to be specified for this to work.
|
||||||
|
|
||||||
|
## Learning (Embedded) Rust
|
||||||
|
|
||||||
|
If you are unfamiliar with Rust on Embedded Systems or Rust in general, the following resources
|
||||||
|
are recommended:
|
||||||
|
|
||||||
|
- [Rust Book](https://doc.rust-lang.org/book/)
|
||||||
|
- [Embedded Rust Book](https://docs.rust-embedded.org/book/)
|
||||||
|
- [Embedded Rust Discovery](https://docs.rust-embedded.org/discovery/microbit/)
|
||||||
|
- [Awesome Embedded Rust](https://github.com/rust-embedded/awesome-embedded-rust)
|
||||||
|
@ -14,6 +14,6 @@ embedded-hal-nb = "1"
|
|||||||
embedded-io = "0.6"
|
embedded-io = "0.6"
|
||||||
|
|
||||||
[dependencies.va108xx-hal]
|
[dependencies.va108xx-hal]
|
||||||
version = "0.10.0"
|
version = "0.11"
|
||||||
features = ["rt"]
|
features = ["rt"]
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ num_enum = { version = "0.7", default-features = false }
|
|||||||
static_assertions = "1"
|
static_assertions = "1"
|
||||||
|
|
||||||
[dependencies.va108xx-hal]
|
[dependencies.va108xx-hal]
|
||||||
version = "0.10"
|
version = "0.11"
|
||||||
|
|
||||||
[dependencies.vorago-reb1]
|
[dependencies.vorago-reb1]
|
||||||
version = "0.8"
|
version = "0.8"
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
|
||||||
# uncomment ONE of these three option to make `cargo run` start a GDB session
|
|
||||||
# which option to pick depends on your system
|
|
||||||
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
|
|
||||||
# runner = "gdb-multiarch -q -x openocd.gdb"
|
|
||||||
# runner = "gdb -q -x openocd.gdb"
|
|
||||||
runner = "gdb-multiarch -q -x jlink.gdb"
|
|
||||||
|
|
||||||
# Probe-rs is currently problematic: https://github.com/probe-rs/probe-rs/issues/2567
|
|
||||||
# runner = "probe-rs run --chip VA108xx --chip-description-path ./scripts/VA108xx_Series.yaml"
|
|
||||||
# runner = ["probe-rs", "run", "--chip", "$CHIP", "--log-format", "{L} {s}"]
|
|
||||||
|
|
||||||
rustflags = [
|
|
||||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
|
||||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
|
||||||
"-C", "link-arg=--nmagic",
|
|
||||||
|
|
||||||
# LLD (shipped with the Rust toolchain) is used as the default linker
|
|
||||||
"-C", "link-arg=-Tlink.x",
|
|
||||||
|
|
||||||
# knurling-rs tooling. If you want to use flip-link, ensure it is installed first.
|
|
||||||
"-C", "linker=flip-link",
|
|
||||||
# Unfortunately, defmt is clunky to use without probe-rs..
|
|
||||||
"-C", "link-arg=-Tdefmt.x",
|
|
||||||
|
|
||||||
# Can be useful for debugging.
|
|
||||||
"-Clink-args=-Map=app.map"
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
[build]
|
|
||||||
# Pick ONE of these compilation targets
|
|
||||||
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
|
||||||
# target = "thumbv7m-none-eabi" # Cortex-M3
|
|
||||||
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
|
||||||
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
|
||||||
# target = "thumbv8m.base-none-eabi" # Cortex-M23
|
|
||||||
# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU)
|
|
||||||
# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU)
|
|
||||||
|
|
||||||
[alias]
|
|
||||||
re = "run --example"
|
|
||||||
rb = "run --bin"
|
|
||||||
rrb = "run --release --bin"
|
|
||||||
ut = "test --target x86_64-unknown-linux-gnu"
|
|
||||||
|
|
||||||
[env]
|
|
||||||
DEFMT_LOG = "info"
|
|
1
defmt-testapp/.gitignore
vendored
1
defmt-testapp/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/target
|
|
@ -1,34 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "defmt-testapp"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
cortex-m = {version = "0.7", features = ["critical-section-single-core"]}
|
|
||||||
panic-rtt-target = "0.1"
|
|
||||||
cortex-m-rt = "0.7"
|
|
||||||
rtt-target = "0.5"
|
|
||||||
rtic-sync = { version = "1.3", features = ["defmt-03"] }
|
|
||||||
embedded-hal = "1"
|
|
||||||
embedded-hal-nb = "1"
|
|
||||||
embedded-io = "0.6"
|
|
||||||
cortex-m-semihosting = "0.5.0"
|
|
||||||
# Tricky without probe-rs.
|
|
||||||
defmt = "0.3"
|
|
||||||
defmt-brtt = { version = "0.1", default-features = false, features = ["rtt"] }
|
|
||||||
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
|
||||||
|
|
||||||
[dependencies.rtic]
|
|
||||||
version = "2"
|
|
||||||
features = ["thumbv6-backend"]
|
|
||||||
|
|
||||||
[dependencies.rtic-monotonics]
|
|
||||||
version = "1"
|
|
||||||
features = ["cortex-m-systick"]
|
|
||||||
|
|
||||||
[dependencies.va108xx-hal]
|
|
||||||
version = "0.10"
|
|
||||||
features = ["rt", "defmt"]
|
|
||||||
|
|
||||||
[dependencies.va108xx]
|
|
||||||
version = "0.5"
|
|
@ -1,9 +0,0 @@
|
|||||||
defmt Testapp
|
|
||||||
======
|
|
||||||
|
|
||||||
`defmt` is clunky to use without probe-rs and requires special configuration inside the
|
|
||||||
`.cargo/config.toml` file.
|
|
||||||
|
|
||||||
`probe-rs` is currently problematic for usage with the VA108xx , so it is not the default tool
|
|
||||||
recommended and used for the whole workspace. This project contains an isolated, `defmt` compatible
|
|
||||||
configuration for testing with `defmt` (and `probe-rs`).
|
|
@ -1,53 +0,0 @@
|
|||||||
#![no_main]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
use cortex_m_semihosting::debug;
|
|
||||||
|
|
||||||
use defmt_brtt as _; // global logger
|
|
||||||
|
|
||||||
use va108xx_hal as _; // memory layout
|
|
||||||
|
|
||||||
use panic_probe as _;
|
|
||||||
|
|
||||||
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
|
||||||
// this prevents the panic message being printed *twice* when `defmt::panic` is invoked
|
|
||||||
// #[defmt::panic_handler]
|
|
||||||
/*
|
|
||||||
fn panic() -> ! {
|
|
||||||
cortex_m::asm::udf()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Terminates the application and makes a semihosting-capable debug tool exit
|
|
||||||
/// with status code 0.
|
|
||||||
pub fn exit() -> ! {
|
|
||||||
loop {
|
|
||||||
debug::exit(debug::EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hardfault handler.
|
|
||||||
///
|
|
||||||
/// Terminates the application and makes a semihosting-capable debug tool exit
|
|
||||||
/// with an error. This seems better than the default, which is to spin in a
|
|
||||||
/// loop.
|
|
||||||
#[cortex_m_rt::exception]
|
|
||||||
unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
|
|
||||||
loop {
|
|
||||||
debug::exit(debug::EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// defmt-test 0.3.0 has the limitation that this `#[tests]` attribute can only be used
|
|
||||||
// once within a crate. the module can be in any file but there can only be at most
|
|
||||||
// one `#[tests]` module in this library crate
|
|
||||||
#[cfg(test)]
|
|
||||||
#[defmt_test::tests]
|
|
||||||
mod unit_tests {
|
|
||||||
use defmt::assert;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn it_works() {
|
|
||||||
assert!(true)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
//! Empty RTIC project template
|
|
||||||
#![no_main]
|
|
||||||
#![no_std]
|
|
||||||
|
|
||||||
use defmt_testapp as _;
|
|
||||||
|
|
||||||
#[rtic::app(device = pac)]
|
|
||||||
mod app {
|
|
||||||
use va108xx_hal::pac;
|
|
||||||
|
|
||||||
#[local]
|
|
||||||
struct Local {}
|
|
||||||
|
|
||||||
#[shared]
|
|
||||||
struct Shared {}
|
|
||||||
|
|
||||||
#[init]
|
|
||||||
fn init(_ctx: init::Context) -> (Shared, Local) {
|
|
||||||
defmt::println!("-- Vorago RTIC template --");
|
|
||||||
(Shared {}, Local {})
|
|
||||||
}
|
|
||||||
|
|
||||||
// `shared` cannot be accessed from this context
|
|
||||||
#[idle]
|
|
||||||
fn idle(_cx: idle::Context) -> ! {
|
|
||||||
#[allow(clippy::empty_loop)]
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,8 +14,10 @@ embedded-io-async = "0.6"
|
|||||||
heapless = "0.8"
|
heapless = "0.8"
|
||||||
static_cell = "2"
|
static_cell = "2"
|
||||||
|
|
||||||
rtt-target = "0.6"
|
defmt = "1"
|
||||||
panic-rtt-target = "0.2"
|
defmt-rtt = "0.4"
|
||||||
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
|
|
||||||
critical-section = "1"
|
critical-section = "1"
|
||||||
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"]}
|
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"]}
|
||||||
|
|
||||||
@ -27,8 +29,8 @@ embassy-executor = { version = "0.7", features = [
|
|||||||
"executor-interrupt"
|
"executor-interrupt"
|
||||||
]}
|
]}
|
||||||
|
|
||||||
va108xx-hal = { version = "0.11", path = "../../va108xx-hal" }
|
va108xx-hal = { version = "0.11", features = ["defmt"] }
|
||||||
va108xx-embassy = { version = "0.2", path = "../../va108xx-embassy" }
|
va108xx-embassy = { version = "0.2" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ticks-hz-1_000", "va108xx-embassy/irq-oc30-oc31"]
|
default = ["ticks-hz-1_000", "va108xx-embassy/irq-oc30-oc31"]
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
//! and then set the `CHECK_PB22_TO_PB23` to true to also test async operations on Port B.
|
//! and then set the `CHECK_PB22_TO_PB23` to true to also test async operations on Port B.
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
// This imports the logger and the panic handler.
|
||||||
|
use embassy_example as _;
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_sync::channel::{Receiver, Sender};
|
use embassy_sync::channel::{Receiver, Sender};
|
||||||
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, channel::Channel};
|
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, channel::Channel};
|
||||||
use embassy_time::{Duration, Instant, Timer};
|
use embassy_time::{Duration, Instant, Timer};
|
||||||
use embedded_hal_async::digital::Wait;
|
use embedded_hal_async::digital::Wait;
|
||||||
use panic_rtt_target as _;
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
|
||||||
use va108xx_hal::gpio::{
|
use va108xx_hal::gpio::{
|
||||||
on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, Port,
|
on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, Port,
|
||||||
};
|
};
|
||||||
@ -58,8 +58,7 @@ static CHANNEL_PB22_TO_PB23: Channel<ThreadModeRawMutex, GpioCmd, 3> = Channel::
|
|||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
rtt_init_print!();
|
defmt::println!("-- VA108xx Async GPIO Demo --");
|
||||||
rprintln!("-- VA108xx Async GPIO Demo --");
|
|
||||||
|
|
||||||
let mut dp = pac::Peripherals::take().unwrap();
|
let mut dp = pac::Peripherals::take().unwrap();
|
||||||
|
|
||||||
@ -102,15 +101,15 @@ async fn main(spawner: Spawner) {
|
|||||||
|
|
||||||
if CHECK_PA0_TO_PA1 {
|
if CHECK_PA0_TO_PA1 {
|
||||||
check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_PA1.sender(), in_pa1_async).await;
|
check_pin_to_pin_async_ops("PA0 to PA1", CHANNEL_PA0_PA1.sender(), in_pa1_async).await;
|
||||||
rprintln!("Example PA0 to PA1 done");
|
defmt::info!("Example PA0 to PA1 done");
|
||||||
}
|
}
|
||||||
if CHECK_PB22_TO_PB23 {
|
if CHECK_PB22_TO_PB23 {
|
||||||
check_pin_to_pin_async_ops("PB22 to PB23", CHANNEL_PB22_TO_PB23.sender(), in_pb23_async)
|
check_pin_to_pin_async_ops("PB22 to PB23", CHANNEL_PB22_TO_PB23.sender(), in_pb23_async)
|
||||||
.await;
|
.await;
|
||||||
rprintln!("Example PB22 to PB23 done");
|
defmt::info!("Example PB22 to PB23 done");
|
||||||
}
|
}
|
||||||
|
|
||||||
rprintln!("Example done, toggling LED0");
|
defmt::info!("Example done, toggling LED0");
|
||||||
loop {
|
loop {
|
||||||
led0.toggle();
|
led0.toggle();
|
||||||
Timer::after(Duration::from_millis(500)).await;
|
Timer::after(Duration::from_millis(500)).await;
|
||||||
@ -122,46 +121,46 @@ async fn check_pin_to_pin_async_ops(
|
|||||||
sender: Sender<'static, ThreadModeRawMutex, GpioCmd, 3>,
|
sender: Sender<'static, ThreadModeRawMutex, GpioCmd, 3>,
|
||||||
mut async_input: impl Wait,
|
mut async_input: impl Wait,
|
||||||
) {
|
) {
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending SetHigh command ({} ms)",
|
"{}: sending SetHigh command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
sender.send(GpioCmd::new(GpioCmdType::SetHigh, 20)).await;
|
sender.send(GpioCmd::new(GpioCmdType::SetHigh, 20)).await;
|
||||||
async_input.wait_for_high().await.unwrap();
|
async_input.wait_for_high().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: Input pin is high now ({} ms)",
|
"{}: Input pin is high now ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending SetLow command ({} ms)",
|
"{}: sending SetLow command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
sender.send(GpioCmd::new(GpioCmdType::SetLow, 20)).await;
|
sender.send(GpioCmd::new(GpioCmdType::SetLow, 20)).await;
|
||||||
async_input.wait_for_low().await.unwrap();
|
async_input.wait_for_low().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: Input pin is low now ({} ms)",
|
"{}: Input pin is low now ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending RisingEdge command ({} ms)",
|
"{}: sending RisingEdge command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await;
|
sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await;
|
||||||
async_input.wait_for_rising_edge().await.unwrap();
|
async_input.wait_for_rising_edge().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: input pin had rising edge ({} ms)",
|
"{}: input pin had rising edge ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending Falling command ({} ms)",
|
"{}: sending Falling command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
@ -170,13 +169,13 @@ async fn check_pin_to_pin_async_ops(
|
|||||||
.send(GpioCmd::new(GpioCmdType::FallingEdge, 20))
|
.send(GpioCmd::new(GpioCmdType::FallingEdge, 20))
|
||||||
.await;
|
.await;
|
||||||
async_input.wait_for_falling_edge().await.unwrap();
|
async_input.wait_for_falling_edge().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: input pin had a falling edge ({} ms)",
|
"{}: input pin had a falling edge ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending Falling command ({} ms)",
|
"{}: sending Falling command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
@ -185,20 +184,20 @@ async fn check_pin_to_pin_async_ops(
|
|||||||
.send(GpioCmd::new(GpioCmdType::FallingEdge, 20))
|
.send(GpioCmd::new(GpioCmdType::FallingEdge, 20))
|
||||||
.await;
|
.await;
|
||||||
async_input.wait_for_any_edge().await.unwrap();
|
async_input.wait_for_any_edge().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: input pin had a falling (any) edge ({} ms)",
|
"{}: input pin had a falling (any) edge ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
|
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: sending Falling command ({} ms)",
|
"{}: sending Falling command ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
);
|
);
|
||||||
sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await;
|
sender.send(GpioCmd::new(GpioCmdType::RisingEdge, 20)).await;
|
||||||
async_input.wait_for_any_edge().await.unwrap();
|
async_input.wait_for_any_edge().await.unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"{}: input pin had a rising (any) edge ({} ms)",
|
"{}: input pin had a rising (any) edge ({} ms)",
|
||||||
ctx,
|
ctx,
|
||||||
Instant::now().as_millis()
|
Instant::now().as_millis()
|
||||||
@ -216,22 +215,22 @@ async fn output_task(
|
|||||||
Timer::after(Duration::from_millis(next_cmd.after_delay.into())).await;
|
Timer::after(Duration::from_millis(next_cmd.after_delay.into())).await;
|
||||||
match next_cmd.cmd_type {
|
match next_cmd.cmd_type {
|
||||||
GpioCmdType::SetHigh => {
|
GpioCmdType::SetHigh => {
|
||||||
rprintln!("{}: Set output high", ctx);
|
defmt::info!("{}: Set output high", ctx);
|
||||||
out.set_high().unwrap();
|
out.set_high().unwrap();
|
||||||
}
|
}
|
||||||
GpioCmdType::SetLow => {
|
GpioCmdType::SetLow => {
|
||||||
rprintln!("{}: Set output low", ctx);
|
defmt::info!("{}: Set output low", ctx);
|
||||||
out.set_low().unwrap();
|
out.set_low().unwrap();
|
||||||
}
|
}
|
||||||
GpioCmdType::RisingEdge => {
|
GpioCmdType::RisingEdge => {
|
||||||
rprintln!("{}: Rising edge", ctx);
|
defmt::info!("{}: Rising edge", ctx);
|
||||||
if !out.is_low().unwrap() {
|
if !out.is_low().unwrap() {
|
||||||
out.set_low().unwrap();
|
out.set_low().unwrap();
|
||||||
}
|
}
|
||||||
out.set_high().unwrap();
|
out.set_high().unwrap();
|
||||||
}
|
}
|
||||||
GpioCmdType::FallingEdge => {
|
GpioCmdType::FallingEdge => {
|
||||||
rprintln!("{}: Falling edge", ctx);
|
defmt::info!("{}: Falling edge", ctx);
|
||||||
if !out.is_high().unwrap() {
|
if !out.is_high().unwrap() {
|
||||||
out.set_high().unwrap();
|
out.set_high().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,16 @@
|
|||||||
//! RTT logs to see received data.
|
//! RTT logs to see received data.
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
use core::cell::RefCell;
|
// This imports the logger and the panic handler.
|
||||||
|
use embassy_example as _;
|
||||||
|
|
||||||
|
use core::cell::RefCell;
|
||||||
use critical_section::Mutex;
|
use critical_section::Mutex;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_time::Instant;
|
use embassy_time::Instant;
|
||||||
use embedded_io::Write;
|
use embedded_io::Write;
|
||||||
use embedded_io_async::Read;
|
use embedded_io_async::Read;
|
||||||
use heapless::spsc::{Consumer, Producer, Queue};
|
use heapless::spsc::{Consumer, Producer, Queue};
|
||||||
use panic_rtt_target as _;
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
|
||||||
use va108xx_hal::{
|
use va108xx_hal::{
|
||||||
gpio::PinsA,
|
gpio::PinsA,
|
||||||
pac::{self, interrupt},
|
pac::{self, interrupt},
|
||||||
@ -49,8 +49,7 @@ static CONSUMER_UART_B: Mutex<RefCell<Option<Consumer<u8, 256>>>> = Mutex::new(R
|
|||||||
// main is itself an async function.
|
// main is itself an async function.
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
rtt_init_print!();
|
defmt::println!("-- VA108xx Async UART RX Demo --");
|
||||||
rprintln!("-- VA108xx Async UART RX Demo --");
|
|
||||||
|
|
||||||
let mut dp = pac::Peripherals::take().unwrap();
|
let mut dp = pac::Peripherals::take().unwrap();
|
||||||
|
|
||||||
@ -108,13 +107,13 @@ async fn main(spawner: Spawner) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut buf = [0u8; 256];
|
let mut buf = [0u8; 256];
|
||||||
loop {
|
loop {
|
||||||
rprintln!("Current time UART A: {}", Instant::now().as_secs());
|
defmt::info!("Current time UART A: {}", Instant::now().as_secs());
|
||||||
led0.toggle();
|
led0.toggle();
|
||||||
led1.toggle();
|
led1.toggle();
|
||||||
led2.toggle();
|
led2.toggle();
|
||||||
let read_bytes = async_rx_uart_a.read(&mut buf).await.unwrap();
|
let read_bytes = async_rx_uart_a.read(&mut buf).await.unwrap();
|
||||||
let read_str = core::str::from_utf8(&buf[..read_bytes]).unwrap();
|
let read_str = core::str::from_utf8(&buf[..read_bytes]).unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"Read {} bytes asynchronously on UART A: {:?}",
|
"Read {} bytes asynchronously on UART A: {:?}",
|
||||||
read_bytes,
|
read_bytes,
|
||||||
read_str
|
read_str
|
||||||
@ -127,11 +126,11 @@ async fn main(spawner: Spawner) {
|
|||||||
async fn uart_b_task(mut async_rx: RxAsyncOverwriting<pac::Uartb, 256>, mut tx: Tx<pac::Uartb>) {
|
async fn uart_b_task(mut async_rx: RxAsyncOverwriting<pac::Uartb, 256>, mut tx: Tx<pac::Uartb>) {
|
||||||
let mut buf = [0u8; 256];
|
let mut buf = [0u8; 256];
|
||||||
loop {
|
loop {
|
||||||
rprintln!("Current time UART B: {}", Instant::now().as_secs());
|
defmt::info!("Current time UART B: {}", Instant::now().as_secs());
|
||||||
// Infallible asynchronous operation.
|
// Infallible asynchronous operation.
|
||||||
let read_bytes = async_rx.read(&mut buf).await.unwrap();
|
let read_bytes = async_rx.read(&mut buf).await.unwrap();
|
||||||
let read_str = core::str::from_utf8(&buf[..read_bytes]).unwrap();
|
let read_str = core::str::from_utf8(&buf[..read_bytes]).unwrap();
|
||||||
rprintln!(
|
defmt::info!(
|
||||||
"Read {} bytes asynchronously on UART B: {:?}",
|
"Read {} bytes asynchronously on UART B: {:?}",
|
||||||
read_bytes,
|
read_bytes,
|
||||||
read_str
|
read_str
|
||||||
@ -149,7 +148,7 @@ fn OC2() {
|
|||||||
critical_section::with(|cs| *PRODUCER_UART_A.borrow(cs).borrow_mut() = Some(prod));
|
critical_section::with(|cs| *PRODUCER_UART_A.borrow(cs).borrow_mut() = Some(prod));
|
||||||
// In a production app, we could use a channel to send the errors to the main task.
|
// In a production app, we could use a channel to send the errors to the main task.
|
||||||
if let Err(errors) = errors {
|
if let Err(errors) = errors {
|
||||||
rprintln!("UART A errors: {:?}", errors);
|
defmt::info!("UART A errors: {:?}", errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +161,6 @@ fn OC3() {
|
|||||||
critical_section::with(|cs| *PRODUCER_UART_B.borrow(cs).borrow_mut() = Some(prod));
|
critical_section::with(|cs| *PRODUCER_UART_B.borrow(cs).borrow_mut() = Some(prod));
|
||||||
// In a production app, we could use a channel to send the errors to the main task.
|
// In a production app, we could use a channel to send the errors to the main task.
|
||||||
if let Err(errors) = errors {
|
if let Err(errors) = errors {
|
||||||
rprintln!("UART B errors: {:?}", errors);
|
defmt::info!("UART B errors: {:?}", errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,12 @@
|
|||||||
//! can verify the correctness of the sent strings.
|
//! can verify the correctness of the sent strings.
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
// This imports the logger and the panic handler.
|
||||||
|
use embassy_example as _;
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_time::{Duration, Instant, Ticker};
|
use embassy_time::{Duration, Instant, Ticker};
|
||||||
use embedded_io_async::Write;
|
use embedded_io_async::Write;
|
||||||
use panic_rtt_target as _;
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
|
||||||
use va108xx_hal::{
|
use va108xx_hal::{
|
||||||
gpio::PinsA,
|
gpio::PinsA,
|
||||||
pac::{self, interrupt},
|
pac::{self, interrupt},
|
||||||
@ -35,8 +36,7 @@ const STR_LIST: &[&str] = &[
|
|||||||
// main is itself an async function.
|
// main is itself an async function.
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
rtt_init_print!();
|
defmt::println!("-- VA108xx Async UART TX Demo --");
|
||||||
rprintln!("-- VA108xx Async UART TX Demo --");
|
|
||||||
|
|
||||||
let mut dp = pac::Peripherals::take().unwrap();
|
let mut dp = pac::Peripherals::take().unwrap();
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
loop {
|
loop {
|
||||||
rprintln!("Current time: {}", Instant::now().as_secs());
|
defmt::info!("Current time: {}", Instant::now().as_secs());
|
||||||
led0.toggle();
|
led0.toggle();
|
||||||
led1.toggle();
|
led1.toggle();
|
||||||
led2.toggle();
|
led2.toggle();
|
||||||
|
3
examples/embassy/src/lib.rs
Normal file
3
examples/embassy/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#![no_std]
|
||||||
|
use defmt_rtt as _;
|
||||||
|
use panic_probe as _;
|
@ -1,9 +1,8 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
use embassy_example as _;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_time::{Duration, Instant, Ticker};
|
use embassy_time::{Duration, Instant, Ticker};
|
||||||
use panic_rtt_target as _;
|
|
||||||
use rtt_target::{rprintln, rtt_init_print};
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "custom-irqs")] {
|
if #[cfg(feature = "custom-irqs")] {
|
||||||
@ -20,8 +19,7 @@ const SYSCLK_FREQ: Hertz = Hertz::from_raw(50_000_000);
|
|||||||
// main is itself an async function.
|
// main is itself an async function.
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
rtt_init_print!();
|
defmt::println!("-- VA108xx Embassy Demo --");
|
||||||
rprintln!("-- VA108xx Embassy Demo --");
|
|
||||||
|
|
||||||
let mut dp = pac::Peripherals::take().unwrap();
|
let mut dp = pac::Peripherals::take().unwrap();
|
||||||
|
|
||||||
@ -55,7 +53,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||||
loop {
|
loop {
|
||||||
ticker.next().await;
|
ticker.next().await;
|
||||||
rprintln!("Current time: {}", Instant::now().as_secs());
|
defmt::info!("Current time: {}", Instant::now().as_secs());
|
||||||
led0.toggle();
|
led0.toggle();
|
||||||
led1.toggle();
|
led1.toggle();
|
||||||
led2.toggle();
|
led2.toggle();
|
||||||
|
@ -22,5 +22,5 @@ rtic-sync = { version = "1.3", features = ["defmt-03"] }
|
|||||||
once_cell = {version = "1", default-features = false, features = ["critical-section"]}
|
once_cell = {version = "1", default-features = false, features = ["critical-section"]}
|
||||||
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
|
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
|
||||||
|
|
||||||
va108xx-hal = { version = "0.11", path = "../../va108xx-hal" }
|
va108xx-hal = { version = "0.11" }
|
||||||
vorago-reb1 = { version = "0.8", path = "../../vorago-reb1" }
|
vorago-reb1 = { version = "0.8" }
|
||||||
|
@ -17,9 +17,7 @@ cortex-m-semihosting = "0.5.0"
|
|||||||
|
|
||||||
[dependencies.va108xx-hal]
|
[dependencies.va108xx-hal]
|
||||||
version = "0.11"
|
version = "0.11"
|
||||||
path = "../../va108xx-hal"
|
features = ["defmt"]
|
||||||
features = ["rt", "defmt"]
|
|
||||||
|
|
||||||
[dependencies.vorago-reb1]
|
[dependencies.vorago-reb1]
|
||||||
version = "0.8"
|
version = "0.8"
|
||||||
path = "../../vorago-reb1"
|
|
||||||
|
@ -45,9 +45,6 @@ fn main() -> ! {
|
|||||||
.expect("TX send error");
|
.expect("TX send error");
|
||||||
}
|
}
|
||||||
Err(nb::Error::WouldBlock) => (),
|
Err(nb::Error::WouldBlock) => (),
|
||||||
Err(nb::Error::Other(uart_error)) => {
|
|
||||||
rprintln!("UART receive error {:?}", uart_error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
use panic_rtt_target as _;
|
use panic_rtt_target as _;
|
||||||
|
use va108xx_hal as _;
|
||||||
|
|
||||||
#[entry]
|
#[entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
|
@ -9,17 +9,16 @@ cortex-m-rt = "0.7"
|
|||||||
embedded-hal = "1"
|
embedded-hal = "1"
|
||||||
embedded-hal-nb = "1"
|
embedded-hal-nb = "1"
|
||||||
embedded-io = "0.6"
|
embedded-io = "0.6"
|
||||||
panic-rtt-target = "0.2"
|
defmt = "1"
|
||||||
rtt-target = "0.6"
|
defmt-rtt = { version = "0.4" }
|
||||||
|
panic-probe = { version = "0.3", features = ["print-defmt"] }
|
||||||
num_enum = { version = "0.7", default-features = false }
|
num_enum = { version = "0.7", default-features = false }
|
||||||
log = "0.4"
|
|
||||||
crc = "3"
|
crc = "3"
|
||||||
cobs = { version = "0.3", default-features = false }
|
cobs = { version = "0.3", default-features = false }
|
||||||
satrs = { version = "0.2", default-features = false }
|
satrs = { version = "0.2", default-features = false }
|
||||||
rtt-log = "0.5"
|
|
||||||
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
|
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
|
||||||
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
||||||
spacepackets = { version = "0.11", default-features = false }
|
spacepackets = { version = "0.11", default-features = false, features = ["defmt"] }
|
||||||
# Even though we do not use this directly, we need to activate this feature explicitely
|
# 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.
|
# so that RTIC compiles because thumv6 does not have CAS operations natively.
|
||||||
portable-atomic = {version = "1", features = ["unsafe-assume-single-core"]}
|
portable-atomic = {version = "1", features = ["unsafe-assume-single-core"]}
|
||||||
@ -29,7 +28,8 @@ rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
|
|||||||
rtic-sync = {version = "1", features = ["defmt-03"]}
|
rtic-sync = {version = "1", features = ["defmt-03"]}
|
||||||
|
|
||||||
[dependencies.va108xx-hal]
|
[dependencies.va108xx-hal]
|
||||||
version = "0.10"
|
version = "0.11"
|
||||||
|
features = ["defmt"]
|
||||||
|
|
||||||
[dependencies.vorago-reb1]
|
[dependencies.vorago-reb1]
|
||||||
version = "0.8"
|
version = "0.8"
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn simple() {
|
|
||||||
assert_eq!(1 + 1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,8 +3,9 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
use defmt_rtt as _; // global logger
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use panic_rtt_target as _;
|
use panic_probe as _;
|
||||||
use ringbuf::{
|
use ringbuf::{
|
||||||
traits::{Consumer, Observer, Producer},
|
traits::{Consumer, Observer, Producer},
|
||||||
StaticRb,
|
StaticRb,
|
||||||
@ -29,7 +30,7 @@ pub enum ActionId {
|
|||||||
SetBootSlot = 130,
|
SetBootSlot = 130,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, TryFromPrimitive, defmt::Format)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum AppSel {
|
enum AppSel {
|
||||||
A = 0,
|
A = 0,
|
||||||
@ -60,10 +61,8 @@ mod app {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use cortex_m::asm;
|
use cortex_m::asm;
|
||||||
use embedded_io::Write;
|
use embedded_io::Write;
|
||||||
use panic_rtt_target as _;
|
|
||||||
use rtic::Mutex;
|
use rtic::Mutex;
|
||||||
use rtic_monotonics::systick::prelude::*;
|
use rtic_monotonics::systick::prelude::*;
|
||||||
use rtt_target::rprintln;
|
|
||||||
use satrs::pus::verification::{FailParams, VerificationReportCreator};
|
use satrs::pus::verification::{FailParams, VerificationReportCreator};
|
||||||
use spacepackets::ecss::PusServiceId;
|
use spacepackets::ecss::PusServiceId;
|
||||||
use spacepackets::ecss::{
|
use spacepackets::ecss::{
|
||||||
@ -102,8 +101,7 @@ mod app {
|
|||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(cx: init::Context) -> (Shared, Local) {
|
fn init(cx: init::Context) -> (Shared, Local) {
|
||||||
rtt_log::init();
|
defmt::println!("-- Vorago flashloader --");
|
||||||
rprintln!("-- Vorago flashloader --");
|
|
||||||
|
|
||||||
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
|
Mono::start(cx.core.SYST, SYSCLK_FREQ.raw());
|
||||||
|
|
||||||
@ -181,8 +179,8 @@ mod app {
|
|||||||
{
|
{
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
if RX_DEBUGGING {
|
if RX_DEBUGGING {
|
||||||
log::debug!("RX Info: {:?}", cx.local.rx_context);
|
defmt::debug!("RX Info: {:?}", cx.local.rx_context);
|
||||||
log::debug!("RX Result: {:?}", result);
|
defmt::debug!("RX Result: {:?}", result);
|
||||||
}
|
}
|
||||||
if result.complete() {
|
if result.complete() {
|
||||||
// Check frame validity (must have COBS format) and decode the frame.
|
// Check frame validity (must have COBS format) and decode the frame.
|
||||||
@ -193,7 +191,7 @@ mod app {
|
|||||||
let decoded_size =
|
let decoded_size =
|
||||||
cobs::decode_in_place(&mut cx.local.rx_buf[1..result.bytes_read]);
|
cobs::decode_in_place(&mut cx.local.rx_buf[1..result.bytes_read]);
|
||||||
if decoded_size.is_err() {
|
if decoded_size.is_err() {
|
||||||
log::warn!("COBS decoding failed");
|
defmt::warn!("COBS decoding failed");
|
||||||
} else {
|
} else {
|
||||||
let decoded_size = decoded_size.unwrap();
|
let decoded_size = decoded_size.unwrap();
|
||||||
let mut tc_rb_full = false;
|
let mut tc_rb_full = false;
|
||||||
@ -207,11 +205,13 @@ mod app {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if tc_rb_full {
|
if tc_rb_full {
|
||||||
log::warn!("COBS TC queue full");
|
defmt::warn!("COBS TC queue full");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::warn!("COBS frame with invalid format, start and end bytes are not 0");
|
defmt::warn!(
|
||||||
|
"COBS frame with invalid format, start and end bytes are not 0"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate next transfer.
|
// Initiate next transfer.
|
||||||
@ -221,11 +221,11 @@ mod app {
|
|||||||
.expect("read operation failed");
|
.expect("read operation failed");
|
||||||
}
|
}
|
||||||
if result.has_errors() {
|
if result.has_errors() {
|
||||||
log::warn!("UART error: {:?}", result.errors.unwrap());
|
defmt::warn!("UART error: {:?}", result.errors.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("UART error: {:?}", e);
|
defmt::warn!("UART error: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -252,7 +252,7 @@ mod app {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let packet_len = packet_len.unwrap();
|
let packet_len = packet_len.unwrap();
|
||||||
log::info!(target: "TC Handler", "received packet with length {}", packet_len);
|
defmt::info!("received packet with length {}", packet_len);
|
||||||
let popped_packet_len = cx
|
let popped_packet_len = cx
|
||||||
.shared
|
.shared
|
||||||
.tc_rb
|
.tc_rb
|
||||||
@ -266,7 +266,7 @@ mod app {
|
|||||||
fn handle_valid_pus_tc(cx: &mut pus_tc_handler::Context) {
|
fn handle_valid_pus_tc(cx: &mut pus_tc_handler::Context) {
|
||||||
let pus_tc = PusTcReader::new(cx.local.tc_buf);
|
let pus_tc = PusTcReader::new(cx.local.tc_buf);
|
||||||
if pus_tc.is_err() {
|
if pus_tc.is_err() {
|
||||||
log::warn!(target: "TC Handler", "PUS TC error: {}", pus_tc.unwrap_err());
|
defmt::warn!("PUS TC error: {}", pus_tc.unwrap_err());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (pus_tc, _) = pus_tc.unwrap();
|
let (pus_tc, _) = pus_tc.unwrap();
|
||||||
@ -312,22 +312,25 @@ mod app {
|
|||||||
write_and_send(&tm);
|
write_and_send(&tm);
|
||||||
};
|
};
|
||||||
if pus_tc.subservice() == ActionId::CorruptImageA as u8 {
|
if pus_tc.subservice() == ActionId::CorruptImageA as u8 {
|
||||||
rprintln!("corrupting App Image A");
|
defmt::info!("corrupting App Image A");
|
||||||
corrupt_image(APP_A_START_ADDR);
|
corrupt_image(APP_A_START_ADDR);
|
||||||
}
|
}
|
||||||
if pus_tc.subservice() == ActionId::CorruptImageB as u8 {
|
if pus_tc.subservice() == ActionId::CorruptImageB as u8 {
|
||||||
rprintln!("corrupting App Image B");
|
defmt::info!("corrupting App Image B");
|
||||||
corrupt_image(APP_B_START_ADDR);
|
corrupt_image(APP_B_START_ADDR);
|
||||||
}
|
}
|
||||||
if pus_tc.subservice() == ActionId::SetBootSlot as u8 {
|
if pus_tc.subservice() == ActionId::SetBootSlot as u8 {
|
||||||
if pus_tc.app_data().is_empty() {
|
if pus_tc.app_data().is_empty() {
|
||||||
log::warn!(target: "TC Handler", "App data for preferred image command too short");
|
defmt::warn!("App data for preferred image command too short");
|
||||||
}
|
}
|
||||||
let app_sel_result = AppSel::try_from(pus_tc.app_data()[0]);
|
let app_sel_result = AppSel::try_from(pus_tc.app_data()[0]);
|
||||||
if app_sel_result.is_err() {
|
if app_sel_result.is_err() {
|
||||||
log::warn!("Invalid app selection value: {}", pus_tc.app_data()[0]);
|
defmt::warn!("Invalid app selection value: {}", pus_tc.app_data()[0]);
|
||||||
}
|
}
|
||||||
log::info!(target: "TC Handler", "received boot selection command with app select: {:?}", app_sel_result.unwrap());
|
defmt::info!(
|
||||||
|
"received boot selection command with app select: {:?}",
|
||||||
|
app_sel_result.unwrap()
|
||||||
|
);
|
||||||
cx.local
|
cx.local
|
||||||
.nvm
|
.nvm
|
||||||
.write(PREFERRED_SLOT_OFFSET as usize, &[pus_tc.app_data()[0]])
|
.write(PREFERRED_SLOT_OFFSET as usize, &[pus_tc.app_data()[0]])
|
||||||
@ -341,7 +344,7 @@ mod app {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pus_tc.service() == PusServiceId::Test as u8 && pus_tc.subservice() == 1 {
|
if pus_tc.service() == PusServiceId::Test as u8 && pus_tc.subservice() == 1 {
|
||||||
log::info!(target: "TC Handler", "received ping TC");
|
defmt::info!("received ping TC");
|
||||||
let tm = cx
|
let tm = cx
|
||||||
.local
|
.local
|
||||||
.verif_reporter
|
.verif_reporter
|
||||||
@ -366,23 +369,21 @@ mod app {
|
|||||||
if pus_tc.subservice() == 2 {
|
if pus_tc.subservice() == 2 {
|
||||||
let app_data = pus_tc.app_data();
|
let app_data = pus_tc.app_data();
|
||||||
if app_data.len() < 10 {
|
if app_data.len() < 10 {
|
||||||
log::warn!(
|
defmt::warn!(
|
||||||
target: "TC Handler",
|
|
||||||
"app data for raw memory write is too short: {}",
|
"app data for raw memory write is too short: {}",
|
||||||
app_data.len()
|
app_data.len()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let memory_id = app_data[0];
|
let memory_id = app_data[0];
|
||||||
if memory_id != BOOT_NVM_MEMORY_ID {
|
if memory_id != BOOT_NVM_MEMORY_ID {
|
||||||
log::warn!(target: "TC Handler", "memory ID {} not supported", memory_id);
|
defmt::warn!("memory ID {} not supported", memory_id);
|
||||||
// TODO: Error reporting
|
// TODO: Error reporting
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let offset = u32::from_be_bytes(app_data[2..6].try_into().unwrap());
|
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());
|
let data_len = u32::from_be_bytes(app_data[6..10].try_into().unwrap());
|
||||||
if 10 + data_len as usize > app_data.len() {
|
if 10 + data_len as usize > app_data.len() {
|
||||||
log::warn!(
|
defmt::warn!(
|
||||||
target: "TC Handler",
|
|
||||||
"invalid data length {} for raw mem write detected",
|
"invalid data length {} for raw mem write detected",
|
||||||
data_len
|
data_len
|
||||||
);
|
);
|
||||||
@ -390,12 +391,7 @@ mod app {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data = &app_data[10..10 + data_len as usize];
|
let data = &app_data[10..10 + data_len as usize];
|
||||||
log::info!(
|
defmt::info!("writing {} bytes at offset {} to NVM", data_len, offset);
|
||||||
target: "TC Handler",
|
|
||||||
"writing {} bytes at offset {} to NVM",
|
|
||||||
data_len,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
cx.local
|
cx.local
|
||||||
.nvm
|
.nvm
|
||||||
.write(offset as usize, data)
|
.write(offset as usize, data)
|
||||||
@ -406,7 +402,7 @@ mod app {
|
|||||||
.verify(offset as usize, data)
|
.verify(offset as usize, data)
|
||||||
.expect("NVM verification failed")
|
.expect("NVM verification failed")
|
||||||
{
|
{
|
||||||
log::warn!("verification of data written to NVM failed");
|
defmt::warn!("verification of data written to NVM failed");
|
||||||
cx.local
|
cx.local
|
||||||
.verif_reporter
|
.verif_reporter
|
||||||
.completion_failure(
|
.completion_failure(
|
||||||
@ -424,9 +420,7 @@ mod app {
|
|||||||
.expect("completion success failed")
|
.expect("completion success failed")
|
||||||
};
|
};
|
||||||
write_and_send(&tm);
|
write_and_send(&tm);
|
||||||
log::info!(
|
defmt::info!("NVM operation done");
|
||||||
target: "TC Handler",
|
|
||||||
"NVM operation done");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
JLinkGDBServer -select USB -device Cortex-M0 -endian little -if JTAG -speed auto \
|
JLinkGDBServer -select USB -device VA10820 -endian little -if JTAG -speed auto \
|
||||||
-LocalhostOnly
|
-LocalhostOnly -jtagconf -1,-1
|
||||||
|
18
scripts/defmt-telnet.sh
Executable file
18
scripts/defmt-telnet.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Check if binary path was provided
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "Usage: $0 <path-to-binary>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BINARY="$1"
|
||||||
|
|
||||||
|
# Check if file exists
|
||||||
|
if [ ! -f "$BINARY" ]; then
|
||||||
|
echo "Error: File '$BINARY' not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the command
|
||||||
|
telnet localhost 19021 | defmt-print -e "$BINARY"
|
21524
sections/sec-debug.txt
21524
sections/sec-debug.txt
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
|
||||||
|
## [v0.2.1] 2025-03-07
|
||||||
|
|
||||||
|
- Bumped allowed va108xx-hal to v0.11
|
||||||
|
|
||||||
## [v0.2.0] 2025-02-17
|
## [v0.2.0] 2025-02-17
|
||||||
|
|
||||||
- Bumped va108xx-hal to v0.10.0
|
- Bumped va108xx-hal to v0.10.0
|
||||||
@ -21,3 +25,7 @@ Docs patch
|
|||||||
## [v0.1.0] 2025-02-13
|
## [v0.1.0] 2025-02-13
|
||||||
|
|
||||||
Initial release
|
Initial release
|
||||||
|
|
||||||
|
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-embassy-v0.2.1...HEAD
|
||||||
|
[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
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "va108xx-embassy"
|
name = "va108xx-embassy"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||||
description = "Embassy-rs support for the Vorago VA108xx family of microcontrollers"
|
description = "Embassy-rs support for the Vorago VA108xx family of microcontrollers"
|
||||||
@ -20,7 +20,7 @@ embassy-time-queue-utils = "0.1"
|
|||||||
|
|
||||||
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
once_cell = { version = "1", default-features = false, features = ["critical-section"] }
|
||||||
|
|
||||||
va108xx-hal = { version = "0.11", path = "../va108xx-hal" }
|
va108xx-hal = { version = ">=0.10, <=0.11" }
|
||||||
|
|
||||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))'.dependencies]
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))'.dependencies]
|
||||||
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"] }
|
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"] }
|
||||||
|
@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
|
||||||
|
## [v0.11.1] 2025-03-10
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Fix `embedded_io` UART implementation to implement the documented contract properly.
|
||||||
|
The implementation will now block until at least one byte is available or can be written, unless
|
||||||
|
the send or receive buffer is empty.
|
||||||
|
|
||||||
## [v0.11.0] 2025-03-07
|
## [v0.11.0] 2025-03-07
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
@ -253,6 +261,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- README with basic instructions how to set up own binary crate
|
- 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.11.0...HEAD
|
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.11.0...HEAD
|
||||||
|
[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
|
[v0.11.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.10.0...va108xx-hal-v0.11.0
|
||||||
[v0.10.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.9.0...va108xx-hal-v0.10.0
|
[v0.10.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.9.0...va108xx-hal-v0.10.0
|
||||||
[v0.9.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.8.0...va108xx-hal-v0.9.0
|
[v0.9.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.8.0...va108xx-hal-v0.9.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "va108xx-hal"
|
name = "va108xx-hal"
|
||||||
version = "0.11.0"
|
version = "0.11.1"
|
||||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "HAL for the Vorago VA108xx family of microcontrollers"
|
description = "HAL for the Vorago VA108xx family of microcontrollers"
|
||||||
|
@ -1004,7 +1004,7 @@ where
|
|||||||
/// * `sys_clk` - System clock
|
/// * `sys_clk` - System clock
|
||||||
/// * `spi` - SPI bus to use
|
/// * `spi` - SPI bus to use
|
||||||
/// * `pins` - Pins to be used for SPI transactions. These pins are consumed
|
/// * `pins` - Pins to be used for SPI transactions. These pins are consumed
|
||||||
/// to ensure the pins can not be used for other purposes anymore
|
/// to ensure the pins can not be used for other purposes anymore
|
||||||
/// * `spi_cfg` - Configuration specific to the SPI bus
|
/// * `spi_cfg` - Configuration specific to the SPI bus
|
||||||
pub fn new(
|
pub fn new(
|
||||||
syscfg: &mut pac::Sysconfig,
|
syscfg: &mut pac::Sysconfig,
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
//! # API for the UART peripheral
|
//! # API for the UART peripheral
|
||||||
//!
|
//!
|
||||||
|
//! The core of this API are the [Uart], [UartBase], [Rx] and [Tx] structures.
|
||||||
|
//! The RX structure also has a dedicated [RxWithInterrupt] variant which allows reading the receiver
|
||||||
|
//! using interrupts.
|
||||||
|
//!
|
||||||
|
//! The [rx_asynch] and [tx_asynch] modules provide an asynchronous non-blocking API for the UART
|
||||||
|
//! peripheral.
|
||||||
|
//!
|
||||||
//! ## Examples
|
//! ## Examples
|
||||||
//!
|
//!
|
||||||
//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/uart.rs)
|
//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/uart.rs)
|
||||||
@ -624,8 +631,8 @@ where
|
|||||||
/// - `pins`: UART TX and RX pin tuple.
|
/// - `pins`: UART TX and RX pin tuple.
|
||||||
/// - `config`: UART specific configuration parameters like baudrate.
|
/// - `config`: UART specific configuration parameters like baudrate.
|
||||||
/// - `irq_cfg`: Optional interrupt configuration. This should be a valid value if the plan
|
/// - `irq_cfg`: Optional interrupt configuration. This should be a valid value if the plan
|
||||||
/// is to use TX or RX functionality relying on interrupts. If only the blocking API without
|
/// is to use TX or RX functionality relying on interrupts. If only the blocking API without
|
||||||
/// any interrupt support is used, this can be [None].
|
/// any interrupt support is used, this can be [None].
|
||||||
pub fn new(
|
pub fn new(
|
||||||
syscfg: &mut va108xx::Sysconfig,
|
syscfg: &mut va108xx::Sysconfig,
|
||||||
sys_clk: impl Into<Hertz>,
|
sys_clk: impl Into<Hertz>,
|
||||||
@ -885,7 +892,15 @@ impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for Rx<Uart> {
|
|||||||
|
|
||||||
impl<Uart: Instance> embedded_io::Read for Rx<Uart> {
|
impl<Uart: Instance> embedded_io::Read for Rx<Uart> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||||
|
if buf.is_empty() {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
let mut read = 0;
|
let mut read = 0;
|
||||||
|
loop {
|
||||||
|
if self.0.rxstatus().read().rdavl().bit_is_set() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
for byte in buf.iter_mut() {
|
for byte in buf.iter_mut() {
|
||||||
match <Self as embedded_hal_nb::serial::Read<u8>>::read(self) {
|
match <Self as embedded_hal_nb::serial::Read<u8>>::read(self) {
|
||||||
Ok(w) => {
|
Ok(w) => {
|
||||||
@ -1051,6 +1066,14 @@ impl<Uart: Instance> embedded_hal_nb::serial::Write<u8> for Tx<Uart> {
|
|||||||
|
|
||||||
impl<Uart: Instance> embedded_io::Write for Tx<Uart> {
|
impl<Uart: Instance> embedded_io::Write for Tx<Uart> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||||
|
if buf.is_empty() {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
if self.0.txstatus().read().wrrdy().bit_is_set() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut written = 0;
|
let mut written = 0;
|
||||||
for byte in buf.iter() {
|
for byte in buf.iter() {
|
||||||
match <Self as embedded_hal_nb::serial::Write<u8>>::write(self, *byte) {
|
match <Self as embedded_hal_nb::serial::Write<u8>>::write(self, *byte) {
|
||||||
@ -1059,7 +1082,7 @@ impl<Uart: Instance> embedded_io::Write for Tx<Uart> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(buf.len())
|
Ok(written)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
|
@ -13,7 +13,7 @@ categories = ["embedded", "no-std", "hardware-support"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
cortex-m = "0.7"
|
cortex-m = "0.7"
|
||||||
vcell = "0.1.3"
|
vcell = "0.1.3"
|
||||||
defmt = { version = "0.3", optional = true }
|
defmt = { version = "1", optional = true }
|
||||||
critical-section = { version = "1", optional = true }
|
critical-section = { version = "1", optional = true }
|
||||||
|
|
||||||
[dependencies.cortex-m-rt]
|
[dependencies.cortex-m-rt]
|
||||||
|
@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
## [unreleased]
|
## [unreleased]
|
||||||
|
|
||||||
|
## [v0.8.1] 2025-03-07
|
||||||
|
|
||||||
|
- Bumped allowed `va108xx-hal` dependency to 0.11
|
||||||
|
- Bumped `bitfield` dependency
|
||||||
|
|
||||||
## [v0.8.0] 2025-02-17
|
## [v0.8.0] 2025-02-17
|
||||||
|
|
||||||
- Bumped `va108xx-hal` dependency to 0.10
|
- Bumped `va108xx-hal` dependency to 0.10
|
||||||
@ -56,3 +61,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- Added basic accelerometer example. Board in not populated so it is not complete, but
|
- Added basic accelerometer example. Board in not populated so it is not complete, but
|
||||||
it provides a starting point
|
it provides a starting point
|
||||||
- Added ADC base library and example building on the new max116xx-10bit device driver crate
|
- 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.8.1...HEAD
|
||||||
|
[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
|
||||||
|
[v0.7.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.6.0...vorago-reb1-v0.7.0
|
||||||
|
[v0.6.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/vorago-reb1-v0.5.0...vorago-reb1-v0.6.0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vorago-reb1"
|
name = "vorago-reb1"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Board Support Crate for the Vorago REB1 development board"
|
description = "Board Support Crate for the Vorago REB1 development board"
|
||||||
@ -15,10 +15,10 @@ cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
|||||||
cortex-m-rt = "0.7"
|
cortex-m-rt = "0.7"
|
||||||
embedded-hal = "1"
|
embedded-hal = "1"
|
||||||
nb = "1"
|
nb = "1"
|
||||||
bitfield = ">=0.17, <=0.18"
|
bitfield = ">=0.17, <=0.19"
|
||||||
max116xx-10bit = "0.3"
|
max116xx-10bit = "0.3"
|
||||||
|
|
||||||
va108xx-hal = { version = ">=0.10, <=0.11", path = "../va108xx-hal", features = ["rt"] }
|
va108xx-hal = { version = ">=0.10, <=0.11", features = ["rt"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
rt = ["va108xx-hal/rt"]
|
rt = ["va108xx-hal/rt"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user