Compare commits
15 Commits
vorago-reb
...
vorago-reb
Author | SHA1 | Date | |
---|---|---|---|
a83d9cca16 | |||
9eeaae76f7 | |||
39aaea086a | |||
a6ef0954cb | |||
102d11114a | |||
8cdee8b733 | |||
d419325312 | |||
561a8419c5 | |||
9bd8efcada | |||
b401085f32 | |||
c693530ab7 | |||
45ee5ad726 | |||
16591346e5 | |||
9ccd147ff6 | |||
521c07460a |
@ -14,6 +14,6 @@ embedded-hal-nb = "1"
|
||||
embedded-io = "0.6"
|
||||
|
||||
[dependencies.va108xx-hal]
|
||||
path = "../va108xx-hal"
|
||||
version = "0.10.0"
|
||||
features = ["rt"]
|
||||
|
||||
|
@ -15,12 +15,10 @@ num_enum = { version = "0.7", default-features = false }
|
||||
static_assertions = "1"
|
||||
|
||||
[dependencies.va108xx-hal]
|
||||
version = "0.9"
|
||||
# path = "../va108xx-hal"
|
||||
version = "0.10"
|
||||
|
||||
[dependencies.vorago-reb1]
|
||||
version = "0.7"
|
||||
# path = "../vorago-reb1"
|
||||
version = "0.8"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
@ -27,10 +27,8 @@ version = "1"
|
||||
features = ["cortex-m-systick"]
|
||||
|
||||
[dependencies.va108xx-hal]
|
||||
version = "0.6"
|
||||
path = "../va108xx-hal"
|
||||
version = "0.10"
|
||||
features = ["rt", "defmt"]
|
||||
|
||||
[dependencies.va108xx]
|
||||
version = "0.3"
|
||||
path = "../va108xx"
|
||||
version = "0.5"
|
||||
|
@ -27,8 +27,8 @@ embassy-executor = { version = "0.7", features = [
|
||||
"executor-interrupt"
|
||||
]}
|
||||
|
||||
va108xx-hal = { version = "0.10" }
|
||||
va108xx-embassy = { version = "0.1", path = "../../va108xx-embassy" }
|
||||
va108xx-hal = { version = "0.11", path = "../../va108xx-hal" }
|
||||
va108xx-embassy = { version = "0.2", path = "../../va108xx-embassy" }
|
||||
|
||||
[features]
|
||||
default = ["ticks-hz-1_000", "va108xx-embassy/irq-oc30-oc31"]
|
||||
|
@ -12,7 +12,6 @@ use embassy_time::{Duration, Instant, Timer};
|
||||
use embedded_hal_async::digital::Wait;
|
||||
use panic_rtt_target as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_embassy::embassy;
|
||||
use va108xx_hal::gpio::{
|
||||
on_interrupt_for_async_gpio_for_port, InputDynPinAsync, InputPinAsync, PinsB, Port,
|
||||
};
|
||||
@ -65,15 +64,13 @@ async fn main(spawner: Spawner) {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
)
|
||||
};
|
||||
va108xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
|
||||
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
|
||||
let portb = PinsB::new(&mut dp.sysconfig, dp.portb);
|
||||
|
@ -23,7 +23,6 @@ use embedded_io_async::Read;
|
||||
use heapless::spsc::{Consumer, Producer, Queue};
|
||||
use panic_rtt_target as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_embassy::embassy;
|
||||
use va108xx_hal::{
|
||||
gpio::PinsA,
|
||||
pac::{self, interrupt},
|
||||
@ -56,15 +55,13 @@ async fn main(spawner: Spawner) {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
}
|
||||
va108xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
|
||||
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
|
||||
let mut led0 = porta.pa10.into_readable_push_pull_output();
|
||||
|
@ -15,7 +15,6 @@ use embassy_time::{Duration, Instant, Ticker};
|
||||
use embedded_io_async::Write;
|
||||
use panic_rtt_target as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_embassy::embassy;
|
||||
use va108xx_hal::{
|
||||
gpio::PinsA,
|
||||
pac::{self, interrupt},
|
||||
@ -42,15 +41,13 @@ async fn main(_spawner: Spawner) {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
}
|
||||
va108xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
|
||||
let porta = PinsA::new(&mut dp.sysconfig, dp.porta);
|
||||
let mut led0 = porta.pa10.into_readable_push_pull_output();
|
||||
|
@ -4,7 +4,6 @@ use embassy_executor::Spawner;
|
||||
use embassy_time::{Duration, Instant, Ticker};
|
||||
use panic_rtt_target as _;
|
||||
use rtt_target::{rprintln, rtt_init_print};
|
||||
use va108xx_embassy::embassy;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "custom-irqs")] {
|
||||
@ -27,27 +26,25 @@ async fn main(_spawner: Spawner) {
|
||||
let mut dp = pac::Peripherals::take().unwrap();
|
||||
|
||||
// Safety: Only called once here.
|
||||
unsafe {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "custom-irqs"))] {
|
||||
embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
} else {
|
||||
embassy::init_with_custom_irqs(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
pac::Interrupt::OC23,
|
||||
pac::Interrupt::OC24,
|
||||
);
|
||||
}
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(not(feature = "custom-irqs"))] {
|
||||
va108xx_embassy::init(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
);
|
||||
} else {
|
||||
va108xx_embassy::init_with_custom_irqs(
|
||||
&mut dp.sysconfig,
|
||||
&dp.irqsel,
|
||||
SYSCLK_FREQ,
|
||||
dp.tim23,
|
||||
dp.tim22,
|
||||
pac::Interrupt::OC23,
|
||||
pac::Interrupt::OC24,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,5 +22,5 @@ rtic-sync = { version = "1.3", features = ["defmt-03"] }
|
||||
once_cell = {version = "1", default-features = false, features = ["critical-section"]}
|
||||
ringbuf = { version = "0.4.7", default-features = false, features = ["portable-atomic"] }
|
||||
|
||||
va108xx-hal = { version = "0.10" }
|
||||
va108xx-hal = { version = "0.11", path = "../../va108xx-hal" }
|
||||
vorago-reb1 = { version = "0.8", path = "../../vorago-reb1" }
|
||||
|
@ -16,9 +16,10 @@ embedded-io = "0.6"
|
||||
cortex-m-semihosting = "0.5.0"
|
||||
|
||||
[dependencies.va108xx-hal]
|
||||
version = "0.10"
|
||||
version = "0.11"
|
||||
path = "../../va108xx-hal"
|
||||
features = ["rt", "defmt"]
|
||||
|
||||
[dependencies.vorago-reb1]
|
||||
path = "../../vorago-reb1"
|
||||
version = "0.8"
|
||||
path = "../../vorago-reb1"
|
||||
|
@ -45,9 +45,6 @@ fn main() -> ! {
|
||||
.expect("TX send error");
|
||||
}
|
||||
Err(nb::Error::WouldBlock) => (),
|
||||
Err(nb::Error::Other(uart_error)) => {
|
||||
rprintln!("UART receive error {:?}", uart_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,9 +29,7 @@ rtic-monotonics = { version = "2", features = ["cortex-m-systick"] }
|
||||
rtic-sync = {version = "1", features = ["defmt-03"]}
|
||||
|
||||
[dependencies.va108xx-hal]
|
||||
version = "0.9"
|
||||
# path = "../va108xx-hal"
|
||||
version = "0.10"
|
||||
|
||||
[dependencies.vorago-reb1]
|
||||
version = "0.7"
|
||||
# path = "../vorago-reb1"
|
||||
version = "0.8"
|
||||
|
@ -11,7 +11,7 @@ panic-rtt-target = { version = "0.1.3" }
|
||||
rtt-target = { version = "0.5" }
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
embedded-hal = "1"
|
||||
va108xx-hal = { path = "../../va108xx-hal" }
|
||||
va108xx-hal = { version = "0.10.0" }
|
||||
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
|
@ -11,7 +11,7 @@ panic-rtt-target = { version = "0.1.3" }
|
||||
rtt-target = { version = "0.5" }
|
||||
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
|
||||
embedded-hal = "1"
|
||||
va108xx-hal = { path = "../../va108xx-hal" }
|
||||
va108xx-hal = { version = "0.10.0" }
|
||||
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
|
@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [unreleased]
|
||||
|
||||
## [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
|
||||
@ -15,3 +25,7 @@ Docs patch
|
||||
## [v0.1.0] 2025-02-13
|
||||
|
||||
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]
|
||||
name = "va108xx-embassy"
|
||||
version = "0.1.2"
|
||||
version = "0.2.0"
|
||||
edition = "2021"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
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"] }
|
||||
|
||||
va108xx-hal = { version = "0.10", path = "../va108xx-hal" }
|
||||
va108xx-hal = { version = ">=0.10, <=0.11" }
|
||||
|
||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))'.dependencies]
|
||||
portable-atomic = { version = "1", features = ["unsafe-assume-single-core"] }
|
||||
|
@ -1,17 +1,17 @@
|
||||
//! # 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.
|
||||
//! 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.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! This library only exposes the [embassy::init] method which sets up the time driver. This
|
||||
//! function must be called once at the start of the application.
|
||||
//! This library exposes the [init] or the [init_with_custom_irqs] functions which set up the time
|
||||
//! driver. This function must be called once at the start of the application.
|
||||
//!
|
||||
//! This implementation requires two TIM peripherals provided by the VA108xx device.
|
||||
//! The user can freely specify the two used TIM peripheral by passing the concrete TIM instances
|
||||
//! into the [embassy::init_with_custom_irqs] and [embassy::init] method.
|
||||
//! into the [init_with_custom_irqs] and [init] method.
|
||||
//!
|
||||
//! The application also requires two interrupt handlers to handle the timekeeper and alarm
|
||||
//! interrupts. By default, this library will define the interrupt handler inside the library
|
||||
@ -24,7 +24,7 @@
|
||||
//! 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
|
||||
//! application code. If this is done, [embassy::init_with_custom_irqs] must be used
|
||||
//! application code. If this is done, [init_with_custom_irqs] must be used
|
||||
//! method to pass the IRQ numbers to the library.
|
||||
//!
|
||||
//! ## Examples
|
||||
@ -76,7 +76,7 @@ macro_rules! embassy_time_driver_irqs {
|
||||
#[allow(non_snake_case)]
|
||||
fn $timekeeper_irq() {
|
||||
// Safety: We call it once here.
|
||||
unsafe { $crate::embassy::time_driver().on_interrupt_timekeeping() }
|
||||
unsafe { $crate::time_driver().on_interrupt_timekeeping() }
|
||||
}
|
||||
|
||||
const ALARM_IRQ: pac::Interrupt = pac::Interrupt::$alarm_irq;
|
||||
@ -85,7 +85,7 @@ macro_rules! embassy_time_driver_irqs {
|
||||
#[allow(non_snake_case)]
|
||||
fn $alarm_irq() {
|
||||
// Safety: We call it once here.
|
||||
unsafe { $crate::embassy::time_driver().on_interrupt_alarm() }
|
||||
unsafe { $crate::time_driver().on_interrupt_alarm() }
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -99,71 +99,58 @@ embassy_time_driver_irqs!(timekeeper_irq = OC30, alarm_irq = OC29);
|
||||
#[cfg(feature = "irq-oc28-oc29")]
|
||||
embassy_time_driver_irqs!(timekeeper_irq = OC29, alarm_irq = OC28);
|
||||
|
||||
pub mod embassy {
|
||||
use super::*;
|
||||
use va108xx_hal::{pac, timer::TimRegInterface};
|
||||
/// Expose the time driver so the user can specify the IRQ handlers themselves.
|
||||
pub fn time_driver() -> &'static TimerDriver {
|
||||
&TIME_DRIVER
|
||||
}
|
||||
|
||||
/// Expose the time driver so the user can specify the IRQ handlers themselves.
|
||||
pub fn time_driver() -> &'static TimerDriver {
|
||||
&TIME_DRIVER
|
||||
}
|
||||
/// 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")]
|
||||
pub fn init<TimekeeperTim: TimRegInterface + ValidTim, AlarmTim: TimRegInterface + ValidTim>(
|
||||
syscfg: &mut pac::Sysconfig,
|
||||
irqsel: &pac::Irqsel,
|
||||
sysclk: impl Into<Hertz>,
|
||||
timekeeper_tim: TimekeeperTim,
|
||||
alarm_tim: AlarmTim,
|
||||
) {
|
||||
TIME_DRIVER.init(
|
||||
syscfg,
|
||||
irqsel,
|
||||
sysclk,
|
||||
timekeeper_tim,
|
||||
alarm_tim,
|
||||
TIMEKEEPER_IRQ,
|
||||
ALARM_IRQ,
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialization method for embassy
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This has to be called once at initialization time to initiate the time driver for
|
||||
/// embassy.
|
||||
#[cfg(feature = "irqs-in-lib")]
|
||||
pub unsafe fn init<
|
||||
TimekeeperTim: TimRegInterface + ValidTim,
|
||||
AlarmTim: TimRegInterface + ValidTim,
|
||||
>(
|
||||
syscfg: &mut pac::Sysconfig,
|
||||
irqsel: &pac::Irqsel,
|
||||
sysclk: impl Into<Hertz>,
|
||||
timekeeper_tim: TimekeeperTim,
|
||||
alarm_tim: AlarmTim,
|
||||
) {
|
||||
TIME_DRIVER.init(
|
||||
syscfg,
|
||||
irqsel,
|
||||
sysclk,
|
||||
timekeeper_tim,
|
||||
alarm_tim,
|
||||
TIMEKEEPER_IRQ,
|
||||
ALARM_IRQ,
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialization method for embassy
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This has to be called once at initialization time to initiate the time driver for
|
||||
/// embassy.
|
||||
pub unsafe fn init_with_custom_irqs<
|
||||
TimekeeperTim: TimRegInterface + ValidTim,
|
||||
AlarmTim: TimRegInterface + ValidTim,
|
||||
>(
|
||||
syscfg: &mut pac::Sysconfig,
|
||||
irqsel: &pac::Irqsel,
|
||||
sysclk: impl Into<Hertz>,
|
||||
timekeeper_tim: TimekeeperTim,
|
||||
alarm_tim: AlarmTim,
|
||||
timekeeper_irq: pac::Interrupt,
|
||||
alarm_irq: pac::Interrupt,
|
||||
) {
|
||||
TIME_DRIVER.init(
|
||||
syscfg,
|
||||
irqsel,
|
||||
sysclk,
|
||||
timekeeper_tim,
|
||||
alarm_tim,
|
||||
timekeeper_irq,
|
||||
alarm_irq,
|
||||
)
|
||||
}
|
||||
/// Initialization method for embassy when using custom IRQ handlers.
|
||||
///
|
||||
/// Requires an explicit [pac::Interrupt] argument for the timekeeper and alarm IRQs.
|
||||
pub fn init_with_custom_irqs<
|
||||
TimekeeperTim: TimRegInterface + ValidTim,
|
||||
AlarmTim: TimRegInterface + ValidTim,
|
||||
>(
|
||||
syscfg: &mut pac::Sysconfig,
|
||||
irqsel: &pac::Irqsel,
|
||||
sysclk: impl Into<Hertz>,
|
||||
timekeeper_tim: TimekeeperTim,
|
||||
alarm_tim: AlarmTim,
|
||||
timekeeper_irq: pac::Interrupt,
|
||||
alarm_irq: pac::Interrupt,
|
||||
) {
|
||||
TIME_DRIVER.init(
|
||||
syscfg,
|
||||
irqsel,
|
||||
sysclk,
|
||||
timekeeper_tim,
|
||||
alarm_tim,
|
||||
timekeeper_irq,
|
||||
alarm_irq,
|
||||
)
|
||||
}
|
||||
|
||||
struct AlarmState {
|
||||
|
@ -8,6 +8,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [unreleased]
|
||||
|
||||
## [v0.11.0] 2025-03-07
|
||||
|
||||
## Changed
|
||||
|
||||
- Bugfix for I2C `TimingCfg::reg`
|
||||
- Simplified UART error handling. All APIs are now infallible because writing to a FIFO or
|
||||
reading from a FIFO never fails. Users can either poll errors using `Rx::poll_errors` or
|
||||
`Uart::poll_rx_errors` / `UartBase::poll_rx_errors`, or detect errors using the provided
|
||||
interrupt handlers.
|
||||
|
||||
## [v0.10.0] 2025-02-17
|
||||
|
||||
## Added
|
||||
@ -104,14 +114,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Updated `embedded-hal` to v1
|
||||
- Added optional `defmt` v0.3 feature and support.
|
||||
|
||||
## [v0.5.2] 2024-06-16
|
||||
## v0.5.2 2024-06-16
|
||||
|
||||
## Fixed
|
||||
|
||||
- Replaced usage to `ptr::write_volatile` in UART module which is denied on more recent Rust
|
||||
compilers.
|
||||
|
||||
## [v0.5.1]
|
||||
## v0.5.1
|
||||
|
||||
### Changes
|
||||
|
||||
@ -120,7 +130,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- `once_cell` to 1.12.0
|
||||
- Other dependencies: Only revision has changed
|
||||
|
||||
## [v0.5.0]
|
||||
## v0.5.0
|
||||
|
||||
### Added
|
||||
|
||||
@ -133,14 +143,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- Bugfix in UART code where RX and TX could not be enabled or disabled independently
|
||||
|
||||
## [v0.4.3]
|
||||
## v0.4.3
|
||||
|
||||
- Various smaller fixes for READMEs, update of links in documentation
|
||||
- Simplified CI for github, do not use `cross`
|
||||
- New `blinky-pac` example
|
||||
- Use HAL delay in `blinky` example
|
||||
|
||||
## [v0.4.2]
|
||||
## v0.4.2
|
||||
|
||||
### Added
|
||||
|
||||
@ -150,24 +160,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- Clear TX and RX FIFO in SPI transfer function
|
||||
|
||||
## [v0.4.1]
|
||||
## v0.4.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- Initial blockmode setting was not set in SPI constructor
|
||||
|
||||
## [v0.4.0]
|
||||
## v0.4.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Replaced `Hertz` by `impl Into<Hertz>` completely and removed
|
||||
`+ Copy` where not necessary
|
||||
|
||||
## [v0.3.1]
|
||||
## v0.3.1
|
||||
|
||||
- Updated all links to point to new repository
|
||||
|
||||
## [v0.3.0]
|
||||
## v0.3.0
|
||||
|
||||
### Added
|
||||
|
||||
@ -179,7 +189,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Primary repository now hosted on IRS external git: https://egit.irs.uni-stuttgart.de/rust/va108xx-hal
|
||||
- Relicensed as Apache-2.0
|
||||
|
||||
## [0.2.3]
|
||||
## v0.2.3
|
||||
|
||||
### Added
|
||||
|
||||
@ -191,7 +201,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- Improved Timer API. It is now possible to simply use `new` on `CountDownTimer`
|
||||
|
||||
## [0.2.2]
|
||||
## v0.2.2
|
||||
|
||||
### Added
|
||||
|
||||
@ -203,7 +213,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
- API which expects values in Hertz now uses `impl Into<Hertz>` as input parameter
|
||||
|
||||
## [0.2.1]
|
||||
## v0.2.1
|
||||
|
||||
### Added
|
||||
|
||||
@ -217,7 +227,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Moved the `FilterClkSel` struct to the `clock` module, re-exporting in `gpio`
|
||||
- Clearing output state at initialization of Output pins
|
||||
|
||||
## [0.2.0]
|
||||
## v0.2.0
|
||||
|
||||
### Changed
|
||||
|
||||
@ -232,7 +242,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Some bugfixes for GPIO implementation
|
||||
- Rust edition updated to 2021
|
||||
|
||||
## [0.1.0]
|
||||
## v0.1.0
|
||||
|
||||
### Added
|
||||
|
||||
@ -241,3 +251,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- RTT example application
|
||||
- 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.11.0...HEAD
|
||||
[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.9.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.8.0...va108xx-hal-v0.9.0
|
||||
[v0.8.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.7.0...va108xx-hal-v0.8.0
|
||||
[v0.7.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/compare/va108xx-hal-v0.6.0...va108xx-hal-v0.7.0
|
||||
[v0.6.0]: https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/tag/va108xx-hal-v0.6.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "va108xx-hal"
|
||||
version = "0.10.0"
|
||||
version = "0.11.0"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
edition = "2021"
|
||||
description = "HAL for the Vorago VA108xx family of microcontrollers"
|
||||
|
@ -198,13 +198,13 @@ impl TimingCfg {
|
||||
}
|
||||
|
||||
pub fn reg(&self) -> u32 {
|
||||
(self.tbuf as u32) << 28
|
||||
| (self.thd_sta as u32) << 24
|
||||
| (self.tsu_sta as u32) << 20
|
||||
| (self.tsu_sto as u32) << 16
|
||||
| (self.tlow as u32) << 12
|
||||
| (self.thigh as u32) << 8
|
||||
| (self.tf as u32) << 4
|
||||
((self.tbuf as u32) << 28)
|
||||
| ((self.thd_sta as u32) << 24)
|
||||
| ((self.tsu_sta as u32) << 20)
|
||||
| ((self.tsu_sto as u32) << 16)
|
||||
| ((self.tlow as u32) << 12)
|
||||
| ((self.thigh as u32) << 8)
|
||||
| ((self.tf as u32) << 4)
|
||||
| (self.tr as u32)
|
||||
}
|
||||
}
|
||||
@ -376,7 +376,7 @@ impl<I2c: Instance> I2cBase<I2c> {
|
||||
if let Some(max_words) = max_words {
|
||||
self.i2c
|
||||
.s0_maxwords()
|
||||
.write(|w| unsafe { w.bits(1 << 31 | max_words as u32) });
|
||||
.write(|w| unsafe { w.bits((1 << 31) | max_words as u32) });
|
||||
}
|
||||
let (addr, addr_mode_mask) = Self::unwrap_addr(sl_cfg.addr);
|
||||
// The first bit is the read/write value. Normally, both read and write are matched
|
||||
@ -437,7 +437,7 @@ impl<I2c: Instance> I2cBase<I2c> {
|
||||
let clk_div = self.calc_clk_div(speed_mode)?;
|
||||
self.i2c
|
||||
.clkscale()
|
||||
.write(|w| unsafe { w.bits((speed_mode as u32) << 31 | clk_div as u32) });
|
||||
.write(|w| unsafe { w.bits(((speed_mode as u32) << 31) | clk_div as u32) });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
//! # 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
|
||||
//!
|
||||
//! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/uart.rs)
|
||||
@ -64,55 +71,6 @@ pub struct NoInterruptIdWasSet;
|
||||
#[error("transer is pending")]
|
||||
pub struct TransferPendingError;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum RxError {
|
||||
#[error("overrun error")]
|
||||
Overrun,
|
||||
#[error("framing error")]
|
||||
Framing,
|
||||
#[error("parity error")]
|
||||
Parity,
|
||||
}
|
||||
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
#[error("rx error: {0}")]
|
||||
Rx(#[from] RxError),
|
||||
#[error("break condition")]
|
||||
BreakCondition,
|
||||
}
|
||||
|
||||
impl embedded_io::Error for Error {
|
||||
fn kind(&self) -> embedded_io::ErrorKind {
|
||||
embedded_io::ErrorKind::Other
|
||||
}
|
||||
}
|
||||
|
||||
impl embedded_io::Error for RxError {
|
||||
fn kind(&self) -> embedded_io::ErrorKind {
|
||||
embedded_io::ErrorKind::Other
|
||||
}
|
||||
}
|
||||
impl embedded_hal_nb::serial::Error for RxError {
|
||||
fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
|
||||
match self {
|
||||
RxError::Overrun => embedded_hal_nb::serial::ErrorKind::Overrun,
|
||||
RxError::Framing => embedded_hal_nb::serial::ErrorKind::FrameFormat,
|
||||
RxError::Parity => embedded_hal_nb::serial::ErrorKind::Parity,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl embedded_hal_nb::serial::Error for Error {
|
||||
fn kind(&self) -> embedded_hal_nb::serial::ErrorKind {
|
||||
match self {
|
||||
Error::Rx(rx_error) => embedded_hal_nb::serial::Error::kind(rx_error),
|
||||
Error::BreakCondition => embedded_hal_nb::serial::ErrorKind::Other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Event {
|
||||
@ -363,7 +321,7 @@ impl UartErrors {
|
||||
impl UartErrors {
|
||||
#[inline(always)]
|
||||
pub fn error(&self) -> bool {
|
||||
self.overflow || self.framing || self.parity
|
||||
self.overflow || self.framing || self.parity || self.other
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,22 +543,27 @@ impl<Uart: Instance> UartBase<Uart> {
|
||||
self.uart
|
||||
}
|
||||
|
||||
/// Poll receiver errors.
|
||||
pub fn poll_rx_errors(&self) -> Option<UartErrors> {
|
||||
self.rx.poll_errors()
|
||||
}
|
||||
|
||||
pub fn split(self) -> (Tx<Uart>, Rx<Uart>) {
|
||||
(self.tx, self.rx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<UartInstance> embedded_io::ErrorType for UartBase<UartInstance> {
|
||||
type Error = Error;
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
impl<UartInstance> embedded_hal_nb::serial::ErrorType for UartBase<UartInstance> {
|
||||
type Error = Error;
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for UartBase<Uart> {
|
||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||
self.rx.read().map_err(|e| e.map(Error::Rx))
|
||||
self.rx.read()
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,6 +674,11 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
/// Poll receiver errors.
|
||||
pub fn poll_rx_errors(&self) -> Option<UartErrors> {
|
||||
self.inner.poll_rx_errors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn enable_rx(&mut self) {
|
||||
self.inner.enable_rx();
|
||||
@ -825,6 +793,23 @@ impl<Uart: Instance> Rx<Uart> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn poll_errors(&self) -> Option<UartErrors> {
|
||||
let mut errors = UartErrors::default();
|
||||
|
||||
let uart = unsafe { &(*Uart::ptr()) };
|
||||
let status_reader = uart.rxstatus().read();
|
||||
if status_reader.rxovr().bit_is_set() {
|
||||
errors.overflow = true;
|
||||
} else if status_reader.rxfrm().bit_is_set() {
|
||||
errors.framing = true;
|
||||
} else if status_reader.rxpar().bit_is_set() {
|
||||
errors.parity = true;
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
Some(errors)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clear_fifo(&self) {
|
||||
self.0.fifo_clr().write(|w| w.rxfifo().set_bit());
|
||||
@ -887,34 +872,15 @@ impl<Uart: Instance> Rx<Uart> {
|
||||
}
|
||||
|
||||
impl<Uart> embedded_io::ErrorType for Rx<Uart> {
|
||||
type Error = RxError;
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
impl<Uart> embedded_hal_nb::serial::ErrorType for Rx<Uart> {
|
||||
type Error = RxError;
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for Rx<Uart> {
|
||||
fn read(&mut self) -> nb::Result<u8, Self::Error> {
|
||||
let uart = unsafe { &(*Uart::ptr()) };
|
||||
let status_reader = uart.rxstatus().read();
|
||||
let err = if status_reader.rxovr().bit_is_set() {
|
||||
Some(RxError::Overrun)
|
||||
} else if status_reader.rxfrm().bit_is_set() {
|
||||
Some(RxError::Framing)
|
||||
} else if status_reader.rxpar().bit_is_set() {
|
||||
Some(RxError::Parity)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(err) = err {
|
||||
// The status code is always related to the next bit for the framing
|
||||
// and parity status bits. We have to read the DATA register
|
||||
// so that the next status reflects the next DATA word
|
||||
// For overrun error, we read as well to clear the peripheral
|
||||
self.read_fifo_unchecked();
|
||||
return Err(err.into());
|
||||
}
|
||||
self.read_fifo().map(|val| (val & 0xff) as u8).map_err(|e| {
|
||||
if let nb::Error::Other(_) = e {
|
||||
unreachable!()
|
||||
@ -926,16 +892,18 @@ impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for Rx<Uart> {
|
||||
|
||||
impl<Uart: Instance> embedded_io::Read for Rx<Uart> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let mut read = 0;
|
||||
for byte in buf.iter_mut() {
|
||||
let w = nb::block!(<Self as embedded_hal_nb::serial::Read<u8>>::read(self))?;
|
||||
*byte = w;
|
||||
match <Self as embedded_hal_nb::serial::Read<u8>>::read(self) {
|
||||
Ok(w) => {
|
||||
*byte = w;
|
||||
read += 1;
|
||||
}
|
||||
Err(nb::Error::WouldBlock) => break,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(buf.len())
|
||||
Ok(read)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1090,14 +1058,12 @@ impl<Uart: Instance> embedded_hal_nb::serial::Write<u8> for Tx<Uart> {
|
||||
|
||||
impl<Uart: Instance> embedded_io::Write for Tx<Uart> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let mut written = 0;
|
||||
for byte in buf.iter() {
|
||||
nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::write(
|
||||
self, *byte
|
||||
))?;
|
||||
match <Self as embedded_hal_nb::serial::Write<u8>>::write(self, *byte) {
|
||||
Ok(_) => written += 1,
|
||||
Err(nb::Error::WouldBlock) => return Ok(written),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(buf.len())
|
||||
@ -1218,15 +1184,10 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
|
||||
|
||||
// Timeout, empty the FIFO completely.
|
||||
if irq_end.irq_rx_to().bit_is_set() {
|
||||
loop {
|
||||
// While there is data in the FIFO, write it into the reception buffer
|
||||
let read_result = self.0.read();
|
||||
if let Some(byte) = self.read_handler(&mut result.errors, &read_result) {
|
||||
buf[result.bytes_read] = byte;
|
||||
result.bytes_read += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
// While there is data in the FIFO, write it into the reception buffer
|
||||
while let Ok(byte) = self.0.read_fifo() {
|
||||
buf[result.bytes_read] = byte as u8;
|
||||
result.bytes_read += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1303,12 +1264,13 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
|
||||
if context.rx_idx == context.max_len {
|
||||
break;
|
||||
}
|
||||
let read_result = self.0.read();
|
||||
if let Some(byte) = self.read_handler(&mut result.errors, &read_result) {
|
||||
buf[context.rx_idx] = byte;
|
||||
context.rx_idx += 1;
|
||||
} else {
|
||||
break;
|
||||
// While there is data in the FIFO, write it into the reception buffer
|
||||
match self.0.read() {
|
||||
Ok(byte) => {
|
||||
buf[result.bytes_read] = byte;
|
||||
result.bytes_read += 1;
|
||||
}
|
||||
Err(_) => break,
|
||||
}
|
||||
}
|
||||
self.irq_completion_handler_max_size_timeout(&mut result, context);
|
||||
@ -1327,29 +1289,6 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_handler(
|
||||
&self,
|
||||
errors: &mut Option<UartErrors>,
|
||||
read_res: &nb::Result<u8, RxError>,
|
||||
) -> Option<u8> {
|
||||
match read_res {
|
||||
Ok(byte) => Some(*byte),
|
||||
Err(nb::Error::WouldBlock) => None,
|
||||
Err(nb::Error::Other(e)) => {
|
||||
// Ensure `errors` is Some(IrqUartError), initializing if it's None
|
||||
let err = errors.get_or_insert(UartErrors::default());
|
||||
|
||||
// Now we can safely modify fields inside `err`
|
||||
match e {
|
||||
RxError::Overrun => err.overflow = true,
|
||||
RxError::Framing => err.framing = true,
|
||||
RxError::Parity => err.parity = true,
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_errors(&self, errors: &mut Option<UartErrors>) {
|
||||
let rx_status = self.uart().rxstatus().read();
|
||||
|
||||
|
@ -26,7 +26,7 @@ use embedded_io::ErrorType;
|
||||
use portable_atomic::AtomicBool;
|
||||
use va108xx::uarta as uart_base;
|
||||
|
||||
use super::{Bank, Instance, Rx, RxError, UartErrors};
|
||||
use super::{Bank, Instance, Rx, UartErrors};
|
||||
|
||||
static UART_RX_WAKERS: [AtomicWaker; 2] = [const { AtomicWaker::new() }; 2];
|
||||
static RX_READ_ACTIVE: [AtomicBool; 2] = [const { AtomicBool::new(false) }; 2];
|
||||
@ -46,7 +46,7 @@ impl RxFuture {
|
||||
}
|
||||
|
||||
impl Future for RxFuture {
|
||||
type Output = Result<(), RxError>;
|
||||
type Output = Result<(), Infallible>;
|
||||
|
||||
fn poll(
|
||||
self: core::pin::Pin<&mut Self>,
|
||||
|
@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [unreleased]
|
||||
|
||||
## [v0.8.1] 2025-03-07
|
||||
|
||||
- Bumped allowed `va108xx-hal` dependency to 0.11
|
||||
- Bumped `bitfield` dependency
|
||||
|
||||
## [v0.8.0] 2025-02-17
|
||||
|
||||
- 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
|
||||
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.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]
|
||||
name = "vorago-reb1"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
edition = "2021"
|
||||
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"
|
||||
embedded-hal = "1"
|
||||
nb = "1"
|
||||
bitfield = ">=0.17, <=0.18"
|
||||
bitfield = ">=0.17, <=0.19"
|
||||
max116xx-10bit = "0.3"
|
||||
|
||||
va108xx-hal = { version = "0.10", features = ["rt"] }
|
||||
va108xx-hal = { version = ">=0.10, <=0.11", features = ["rt"] }
|
||||
|
||||
[features]
|
||||
rt = ["va108xx-hal/rt"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user