Changed: - Move most library components to new [`vorago-shared-periphs`](https://egit.irs.uni-stuttgart.de/rust/vorago-shared-periphs) which is mostly re-exported in this crate. - Overhaul and simplification of several HAL APIs. The system configuration and IRQ router peripheral instance generally does not need to be passed to HAL API anymore. - All HAL drivers are now type erased. The constructors will still expect and consume the PAC singleton component for resource management purposes, but are not cached anymore. - Refactoring of GPIO library to be more inline with embassy GPIO API. Added: - I2C clock timeout feature support.
118 lines
4.9 KiB
Rust
118 lines
4.9 KiB
Rust
//! # Embassy-rs support for the Vorago VA416xx MCU family
|
|
//!
|
|
//! This repository contains the [embassy-rs](https://github.com/embassy-rs/embassy) support for the
|
|
//! VA416xx family. Currently, it contains the time driver to allow using embassy-rs. It uses the TIM
|
|
//! peripherals provided by the VA416xx 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 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 [init] method. If the interrupt handlers are provided by the library, the ID of the
|
|
//! used TIM peripherals has to match the ID of the passed timer peripherals. Currently, this
|
|
//! can only be checked at run-time, and a run-time assertion will panic on the embassy
|
|
//! initialization in case of a missmatch.
|
|
//!
|
|
//! 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
|
|
//! itself by using the `irq-tim14-tim15` feature flag. This library exposes three combinations:
|
|
//!
|
|
//! - `irq-tim14-tim15`: Uses [pac::Interrupt::TIM14] for alarm and [pac::Interrupt::TIM15]
|
|
//! for timekeeper
|
|
//! - `irq-tim13-tim14`: Uses [pac::Interrupt::TIM13] for alarm and [pac::Interrupt::TIM14]
|
|
//! for timekeeper
|
|
//! - `irq-tim22-tim23`: Uses [pac::Interrupt::TIM22] for alarm and [pac::Interrupt::TIM23]
|
|
//! for timekeeper
|
|
//!
|
|
//! 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
|
|
//! method to pass the IRQ numbers to the library.
|
|
//!
|
|
//! ## Examples
|
|
//!
|
|
//! [embassy example projects](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/embassy)
|
|
#![no_std]
|
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
|
use va416xx_hal::{
|
|
clock::Clocks,
|
|
irq_router::enable_and_init_irq_router,
|
|
pac::{self, interrupt},
|
|
timer::{TimMarker, TIM_IRQ_OFFSET},
|
|
};
|
|
use vorago_shared_periphs::embassy::time_driver;
|
|
|
|
/// Macro to define the IRQ handlers for the time driver.
|
|
///
|
|
/// By default, the code generated by this macro will be defined inside the library depending on
|
|
/// the feature flags specified. However, the macro is exported to allow users to specify the
|
|
/// interrupt handlers themselves.
|
|
///
|
|
/// Please note that you have to explicitely import the [macro@va108xx_hal::pac::interrupt]
|
|
/// macro in the application code in case this macro is used there.
|
|
#[macro_export]
|
|
macro_rules! embassy_time_driver_irqs {
|
|
(
|
|
timekeeper_irq = $timekeeper_irq:ident,
|
|
alarm_irq = $alarm_irq:ident
|
|
) => {
|
|
const TIMEKEEPER_IRQ: pac::Interrupt = pac::Interrupt::$timekeeper_irq;
|
|
|
|
#[interrupt]
|
|
#[allow(non_snake_case)]
|
|
fn $timekeeper_irq() {
|
|
// Safety: We call it once here.
|
|
unsafe { $crate::time_driver().on_interrupt_timekeeping() }
|
|
}
|
|
|
|
const ALARM_IRQ: pac::Interrupt = pac::Interrupt::$alarm_irq;
|
|
|
|
#[interrupt]
|
|
#[allow(non_snake_case)]
|
|
fn $alarm_irq() {
|
|
// Safety: We call it once here.
|
|
unsafe { $crate::time_driver().on_interrupt_alarm() }
|
|
}
|
|
};
|
|
}
|
|
|
|
// Provide three combinations of IRQs for the time driver by default.
|
|
|
|
#[cfg(feature = "irq-tim14-tim15")]
|
|
embassy_time_driver_irqs!(timekeeper_irq = TIM15, alarm_irq = TIM14);
|
|
#[cfg(feature = "irq-tim13-tim14")]
|
|
embassy_time_driver_irqs!(timekeeper_irq = TIM14, alarm_irq = TIM13);
|
|
#[cfg(feature = "irq-tim22-tim23")]
|
|
embassy_time_driver_irqs!(timekeeper_irq = TIM23, alarm_irq = TIM22);
|
|
|
|
/// Initialization method for embassy
|
|
///
|
|
/// If the interrupt handlers are provided by the library, the ID of the
|
|
/// used TIM peripherals has to match the ID of the passed timer peripherals. Currently, this
|
|
/// can only be checked at run-time, and a run-time assertion will panic on the embassy
|
|
/// initialization in case of a missmatch.
|
|
pub fn init<TimekeeperTim: TimMarker, AlarmTim: TimMarker>(
|
|
timekeeper: TimekeeperTim,
|
|
alarm: AlarmTim,
|
|
clocks: &Clocks,
|
|
) {
|
|
#[cfg(feature = "_irqs-in-lib")]
|
|
assert_eq!(
|
|
TimekeeperTim::ID.value(),
|
|
TIMEKEEPER_IRQ as u8 - TIM_IRQ_OFFSET as u8,
|
|
"Timekeeper TIM and IRQ missmatch"
|
|
);
|
|
#[cfg(feature = "_irqs-in-lib")]
|
|
assert_eq!(
|
|
AlarmTim::ID.value(),
|
|
ALARM_IRQ as u8 - TIM_IRQ_OFFSET as u8,
|
|
"Alarm TIM and IRQ missmatch"
|
|
);
|
|
enable_and_init_irq_router();
|
|
time_driver().__init(timekeeper, alarm, clocks)
|
|
}
|