Compare commits

..

16 Commits
v0.5.0 ... main

Author SHA1 Message Date
2db345af9f prep patch v0.5.2
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2024-06-16 16:08:15 +02:00
09fd0d2aad
that should do the job
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2023-01-11 23:15:48 +01:00
b776bd2823
clippy: remove unnecessary casts
Some checks failed
Rust/va108xx-hal/pipeline/head There was a failure building this commit
2023-01-11 00:41:07 +01:00
6131458a13 Merge branch 'main' of https://egit.irs.uni-stuttgart.de/rust/va108xx-hal
Some checks failed
Rust/va108xx-hal/pipeline/head There was a failure building this commit
2023-01-11 00:39:24 +01:00
2b8a8dc7c8
update Jenkins CI, add docs build 2023-01-11 00:39:12 +01:00
e9f1294572
clippy did not find this..
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-09-14 11:19:19 +02:00
1476f4eebe
bump some dependencies
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-09-13 10:57:07 +02:00
0ee53c70d5
add Eq auto-derives
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-09-13 10:47:11 +02:00
833567037c
typo fix
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-06-18 22:22:56 +02:00
38b9625773
update badge link
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-06-18 22:21:48 +02:00
49b72d683f
update changelog and manifest file for v0.5.1
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-06-18 22:12:58 +02:00
21c44e6327
update dependencies and add category 2022-06-18 22:06:49 +02:00
147c57defb
run cargo fmt
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2022-05-02 16:52:31 +02:00
5cbbb53094 some minor improvements
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
- Docs updated, internal architecture improvements
2021-12-21 00:30:28 +01:00
491ef3ce09
update example documentation
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2021-12-21 00:06:50 +01:00
e3cdd21b41
added link to new example
All checks were successful
Rust/va108xx-hal/pipeline/head This commit looks good
2021-12-20 23:51:37 +01:00
15 changed files with 134 additions and 86 deletions

View File

@ -6,6 +6,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [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]
### Changes
- Updated dependencies:
- `cortex-m-rtic` (dev-depencency) to 1.1.2
- `once_cell` to 1.12.0
- Other dependencies: Only revision has changed
## [v0.5.0] ## [v0.5.0]
### Added ### Added

View File

@ -1,6 +1,6 @@
[package] [package]
name = "va108xx-hal" name = "va108xx-hal"
version = "0.5.0" version = "0.5.2"
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"
@ -8,30 +8,43 @@ homepage = "https://egit.irs.uni-stuttgart.de/rust/va108xx-hal"
repository = "https://egit.irs.uni-stuttgart.de/rust/va108xx-hal" repository = "https://egit.irs.uni-stuttgart.de/rust/va108xx-hal"
license = "Apache-2.0" license = "Apache-2.0"
keywords = ["no-std", "hal", "cortex-m", "vorago", "va108xx"] keywords = ["no-std", "hal", "cortex-m", "vorago", "va108xx"]
categories = ["embedded", "no-std", "hardware-support"] categories = ["aerospace", "embedded", "no-std", "hardware-support"]
[dependencies] [dependencies]
va108xx = "0.2.4"
cortex-m = "0.7" cortex-m = "0.7"
cortex-m-rt = "0.7" cortex-m-rt = "0.7"
nb = "1" nb = "1"
paste = "1.0" paste = "1.0"
embedded-hal = { features = ["unproven"], version = "0.2.6" } libm = "0.2"
void = { version = "1.0", default-features = false }
once_cell = { version = "1.8.0", default-features = false }
libm = "0.2.1"
[dependencies.va108xx] [dependencies.embedded-hal]
version = "0.2.4" version = "0.2.7"
features = ["unproven"]
[dependencies.void]
version = "1.0"
default-features = false
[dependencies.once_cell]
version = "1.14"
default-features = false
[features] [features]
rt = ["va108xx/rt"] rt = ["va108xx/rt"]
[dev-dependencies] [dev-dependencies]
cortex-m-rtic = "0.6.0-rc.4" cortex-m-rtic = "1.1.2"
panic-rtt-target = { version = "0.1", features = ["cortex-m"] }
rtt-target = { version = "0.3", features = ["cortex-m"] }
panic-halt = "0.2" panic-halt = "0.2"
[dev-dependencies.rtt-target]
version = "0.3"
features = ["cortex-m"]
[dev-dependencies.panic-rtt-target]
version = "0.1"
features = ["cortex-m"]
[profile.dev] [profile.dev]
debug = true debug = true
lto = false lto = false

View File

@ -1,5 +1,5 @@
[![Crates.io](https://img.shields.io/crates/v/va108xx-hal)](https://crates.io/crates/va108xx-hal) [![Crates.io](https://img.shields.io/crates/v/va108xx-hal)](https://crates.io/crates/va108xx-hal)
[![ci](https://github.com/robamu-org/va108xx-hal-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/robamu-org/va108xx-hal-rs/actions/workflows/ci.yml) [![ci](https://github.com/us-irs/va108xx-hal-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/us-irs/va108xx-hal-rs/actions/workflows/ci.yml)
[![docs.rs](https://img.shields.io/docsrs/va108xx-hal)](https://docs.rs/va108xx-hal) [![docs.rs](https://img.shields.io/docsrs/va108xx-hal)](https://docs.rs/va108xx-hal)
# HAL for the Vorago VA108xx MCU family # HAL for the Vorago VA108xx MCU family
@ -63,7 +63,7 @@ is contained within the
1. Set up your Rust cross-compiler if you have not done so yet. See more in the [build chapter](#Building) 1. Set up your Rust cross-compiler if you have not done so yet. See more in the [build chapter](#Building)
2. Create a new binary crate with `cargo init` 2. Create a new binary crate with `cargo init`
3. To ensure that `cargo build` cross-compiles, it is recommended to create a `cargo/config.toml` 3. To ensure that `cargo build` cross-compiles, it is recommended to create a `.cargo/config.toml`
file. A sample `.cargo/config.toml` file is provided in this repository as well file. A sample `.cargo/config.toml` file is provided in this repository as well
4. Copy the `memory.x` file into your project. This file contains information required by the linker. 4. Copy the `memory.x` file into your project. This file contains information required by the linker.
5. Copy the `blinky.rs` file to the `src/main.rs` file in your binary crate 5. Copy the `blinky.rs` file to the `src/main.rs` file in your binary crate

View File

@ -7,5 +7,7 @@ RUN apt-get --yes upgrade
# tzdata is a dependency, won't install otherwise # tzdata is a dependency, won't install otherwise
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
RUN rustup target add thumbv6m-none-eabi && \ RUN rustup install nightly && \
rustup target add thumbv6m-none-eabi && \
rustup +nightly target add thumbv6m-none-eabi && \
rustup component add rustfmt clippy rustup component add rustfmt clippy

View File

@ -1,47 +1,34 @@
pipeline { pipeline {
agent any
stages {
stage('Clippy') {
agent { agent {
dockerfile { dockerfile {
dir 'automation' dir 'automation'
reuseNode true reuseNode true
} }
} }
stages {
stage('Clippy') {
steps { steps {
sh 'cargo clippy' sh 'cargo clippy'
} }
} }
stage('Rustfmt') { stage('Rustfmt') {
agent {
dockerfile {
dir 'automation'
reuseNode true
}
}
steps { steps {
sh 'cargo fmt' sh 'cargo fmt'
} }
} }
stage('Docs') {
steps {
sh 'cargo +nightly doc'
}
}
stage('Check') { stage('Check') {
agent {
dockerfile {
dir 'automation'
reuseNode true
}
}
steps { steps {
sh 'cargo check --target thumbv6m-none-eabi' sh 'cargo check --target thumbv6m-none-eabi'
} }
} }
stage('Check Examples') { stage('Check Examples') {
agent {
dockerfile {
dir 'automation'
reuseNode true
}
}
steps { steps {
sh 'cargo check --target thumbv6m-none-eabi --examples' sh 'cargo check --target thumbv6m-none-eabi --examples'
} }

View File

@ -1,5 +1,12 @@
//! UART example application. Sends a test string over a UART and then enters //! More complex UART application
//! echo mode //!
//! Uses the IRQ capabilities of the VA10820 peripheral and the RTIC framework to poll the UART in
//! a non-blocking way. You can send variably sized strings to the VA10820 which will be echoed
//! back to the sender.
//!
//! This script was tested with an Arduino Due. You can find the test script in the
//! [`/test/DueSerialTest`](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/test/DueSerialTest)
//! folder.
#![no_main] #![no_main]
#![no_std] #![no_std]

View File

@ -11,7 +11,7 @@ static SYS_CLOCK: Mutex<OnceCell<Hertz>> = Mutex::new(OnceCell::new());
pub type PeripheralClocks = PeripheralSelect; pub type PeripheralClocks = PeripheralSelect;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum FilterClkSel { pub enum FilterClkSel {
SysClk = 0, SysClk = 0,
Clk1 = 1, Clk1 = 1,

View File

@ -143,14 +143,14 @@ pub const DYN_ALT_FUNC_3: DynPinMode = DynPinMode::Alternate(DynAlternate::Funse
//================================================================================================== //==================================================================================================
/// Value-level `enum` for pin groups /// Value-level `enum` for pin groups
#[derive(PartialEq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]
pub enum DynGroup { pub enum DynGroup {
A, A,
B, B,
} }
/// Value-level `struct` representing pin IDs /// Value-level `struct` representing pin IDs
#[derive(PartialEq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]
pub struct DynPinId { pub struct DynPinId {
pub group: DynGroup, pub group: DynGroup,
pub num: u8, pub num: u8,

View File

@ -106,27 +106,27 @@ use paste::paste;
// Errors and Definitions // Errors and Definitions
//================================================================================================== //==================================================================================================
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum InterruptEdge { pub enum InterruptEdge {
HighToLow, HighToLow,
LowToHigh, LowToHigh,
BothEdges, BothEdges,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum InterruptLevel { pub enum InterruptLevel {
Low = 0, Low = 0,
High = 1, High = 1,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum PinState { pub enum PinState {
Low = 0, Low = 0,
High = 1, High = 1,
} }
/// GPIO error type /// GPIO error type
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum PinError { pub enum PinError {
/// The pin did not have the correct ID or mode for the requested operation. /// The pin did not have the correct ID or mode for the requested operation.
/// [`DynPin`](crate::gpio::DynPin)s are not tracked and verified at compile-time, so run-time /// [`DynPin`](crate::gpio::DynPin)s are not tracked and verified at compile-time, so run-time
@ -182,7 +182,7 @@ pub struct Input<C: InputConfig> {
impl<C: InputConfig> Sealed for Input<C> {} impl<C: InputConfig> Sealed for Input<C> {}
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum FilterType { pub enum FilterType {
SystemClock = 0, SystemClock = 0,
DirectInputWithSynchronization = 1, DirectInputWithSynchronization = 1,

View File

@ -18,13 +18,13 @@ pub use embedded_hal::blocking::i2c::{SevenBitAddress, TenBitAddress};
// Defintions // Defintions
//================================================================================================== //==================================================================================================
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum FifoEmptyMode { pub enum FifoEmptyMode {
Stall = 0, Stall = 0,
EndTransaction = 1, EndTransaction = 1,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum Error { pub enum Error {
InvalidTimingParams, InvalidTimingParams,
ArbitrationLost, ArbitrationLost,
@ -46,19 +46,19 @@ enum I2cCmd {
Cancel = 0b100, Cancel = 0b100,
} }
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum I2cSpeed { pub enum I2cSpeed {
Regular100khz = 0, Regular100khz = 0,
Fast400khz = 1, Fast400khz = 1,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum I2cDirection { pub enum I2cDirection {
Send = 0, Send = 0,
Read = 1, Read = 1,
} }
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum I2cAddress { pub enum I2cAddress {
Regular(u8), Regular(u8),
TenBit(u16), TenBit(u16),
@ -119,14 +119,14 @@ impl TimingCfg {
} }
pub fn reg(&self) -> u32 { pub fn reg(&self) -> u32 {
((self.tbuf as u32) << 28 (self.tbuf as u32) << 28
| (self.thd_sta as u32) << 24 | (self.thd_sta as u32) << 24
| (self.tsu_sta as u32) << 20 | (self.tsu_sta as u32) << 20
| (self.tsu_sto as u32) << 16 | (self.tsu_sto as u32) << 16
| (self.tlow as u32) << 12 | (self.tlow as u32) << 12
| (self.thigh as u32) << 8 | (self.thigh as u32) << 8
| (self.tf as u32) << 4 | (self.tf as u32) << 4
| (self.tr as u32)) as u32 | (self.tr as u32)
} }
} }

View File

@ -25,7 +25,7 @@ use embedded_hal::{
// Defintions // Defintions
//================================================================================================== //==================================================================================================
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum HwChipSelectId { pub enum HwChipSelectId {
Id0 = 0, Id0 = 0,
Id1 = 1, Id1 = 1,
@ -38,7 +38,7 @@ pub enum HwChipSelectId {
Invalid = 0xff, Invalid = 0xff,
} }
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum WordSize { pub enum WordSize {
OneBit = 0x00, OneBit = 0x00,
FourBits = 0x03, FourBits = 0x03,

View File

@ -6,7 +6,7 @@
//! allowing it to be converted into frequencies. //! allowing it to be converted into frequencies.
/// Bits per second /// Bits per second
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
pub struct Bps(pub u32); pub struct Bps(pub u32);
/// Hertz /// Hertz
@ -25,7 +25,7 @@ pub struct Bps(pub u32);
/// ///
/// let freq = 60.hz(); /// let freq = 60.hz();
/// ``` /// ```
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
pub struct Hertz(pub u32); pub struct Hertz(pub u32);
/// Kilohertz /// Kilohertz
@ -47,7 +47,7 @@ pub struct Hertz(pub u32);
/// ///
/// let freq = 100.khz(); /// let freq = 100.khz();
/// ``` /// ```
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
pub struct KiloHertz(pub u32); pub struct KiloHertz(pub u32);
/// Megahertz /// Megahertz
@ -68,14 +68,14 @@ pub struct KiloHertz(pub u32);
/// ///
/// let freq = 8.mhz(); /// let freq = 8.mhz();
/// ``` /// ```
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
pub struct MegaHertz(pub u32); pub struct MegaHertz(pub u32);
/// Time unit /// Time unit
#[derive(PartialEq, PartialOrd, Clone, Copy)] #[derive(PartialEq, Eq, PartialOrd, Clone, Copy)]
pub struct MilliSeconds(pub u32); pub struct MilliSeconds(pub u32);
#[derive(PartialEq, PartialOrd, Clone, Copy)] #[derive(PartialEq, Eq, PartialOrd, Clone, Copy)]
pub struct MicroSeconds(pub u32); pub struct MicroSeconds(pub u32);
/// Extension trait that adds convenience methods to the `u32` type /// Extension trait that adds convenience methods to the `u32` type

View File

@ -45,7 +45,7 @@ pub enum Event {
TimeOut, TimeOut,
} }
#[derive(Default, Debug, PartialEq, Copy, Clone)] #[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
pub struct CascadeCtrl { pub struct CascadeCtrl {
/// Enable Cascade 0 signal active as a requirement for counting /// Enable Cascade 0 signal active as a requirement for counting
pub enb_start_src_csd0: bool, pub enb_start_src_csd0: bool,
@ -74,7 +74,7 @@ pub struct CascadeCtrl {
pub trg_csd2: bool, pub trg_csd2: bool,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum CascadeSel { pub enum CascadeSel {
Csd0 = 0, Csd0 = 0,
Csd1 = 1, Csd1 = 1,
@ -82,7 +82,7 @@ pub enum CascadeSel {
} }
/// The numbers are the base numbers for bundles like PORTA, PORTB or TIM /// The numbers are the base numbers for bundles like PORTA, PORTB or TIM
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum CascadeSource { pub enum CascadeSource {
PortABase = 0, PortABase = 0,
PortBBase = 32, PortBBase = 32,
@ -95,7 +95,7 @@ pub enum CascadeSource {
ClockDividerBase = 120, ClockDividerBase = 120,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq, Eq)]
pub enum TimerErrors { pub enum TimerErrors {
Canceled, Canceled,
/// Invalid input for Cascade source /// Invalid input for Cascade source

View File

@ -2,7 +2,8 @@
//! //!
//! ## Examples //! ## Examples
//! //!
//! - [UART example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart.rs) //! - [UART simple example](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart.rs)
//! - [UART with IRQ and RTIC](https://egit.irs.uni-stuttgart.de/rust/va108xx-hal/src/branch/main/examples/uart-irq-rtic.rs)
use core::{convert::Infallible, ptr}; use core::{convert::Infallible, ptr};
use core::{marker::PhantomData, ops::Deref}; use core::{marker::PhantomData, ops::Deref};
use libm::floorf; use libm::floorf;
@ -59,7 +60,7 @@ pub enum Error {
IrqError, IrqError,
} }
#[derive(Debug, PartialEq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Event { pub enum Event {
// Receiver FIFO interrupt enable. Generates interrupt // Receiver FIFO interrupt enable. Generates interrupt
// when FIFO is at least half full. Half full is defined as FIFO // when FIFO is at least half full. Half full is defined as FIFO
@ -83,20 +84,20 @@ pub enum Event {
TxCts, TxCts,
} }
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum Parity { pub enum Parity {
None, None,
Odd, Odd,
Even, Even,
} }
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum StopBits { pub enum StopBits {
One = 0, One = 0,
Two = 1, Two = 1,
} }
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum WordSize { pub enum WordSize {
Five = 0, Five = 0,
Six = 1, Six = 1,
@ -177,7 +178,7 @@ impl From<Bps> for Config {
// IRQ Definitions // IRQ Definitions
//================================================================================================== //==================================================================================================
pub struct IrqInfo { struct IrqInfo {
rx_len: usize, rx_len: usize,
rx_idx: usize, rx_idx: usize,
irq_cfg: IrqCfg, irq_cfg: IrqCfg,
@ -196,6 +197,7 @@ pub enum IrqResultMask {
Unknown = 7, Unknown = 7,
} }
/// This struct is used to return the default IRQ handler result to the user
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct IrqResult { pub struct IrqResult {
raw_res: u32, raw_res: u32,
@ -276,32 +278,36 @@ impl IrqResult {
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum IrqReceptionMode { enum IrqReceptionMode {
Idle, Idle,
FixedLen, Pending,
VarLen,
} }
//================================================================================================== //==================================================================================================
// UART implementation // UART implementation
//================================================================================================== //==================================================================================================
/// Type erased variant of a UART. Can be created with the [`Uart::downgrade`] function.
pub struct UartBase<UART> { pub struct UartBase<UART> {
uart: UART, uart: UART,
tx: Tx<UART>, tx: Tx<UART>,
rx: Rx<UART>, rx: Rx<UART>,
} }
/// Serial abstraction /// Serial abstraction. Entry point to create a new UART
pub struct Uart<UART, PINS> { pub struct Uart<UART, PINS> {
uart_base: UartBase<UART>, uart_base: UartBase<UART>,
pins: PINS, pins: PINS,
} }
/// UART using the IRQ capabilities of the peripheral. Can be created with the
/// [`Uart::into_uart_with_irq`] function.
pub struct UartWithIrq<UART, PINS> { pub struct UartWithIrq<UART, PINS> {
irq_base: UartWithIrqBase<UART>, irq_base: UartWithIrqBase<UART>,
pins: PINS, pins: PINS,
} }
/// Type-erased UART using the IRQ capabilities of the peripheral. Can be created with the
/// [`UartWithIrq::downgrade`] function.
pub struct UartWithIrqBase<UART> { pub struct UartWithIrqBase<UART> {
pub uart: UartBase<UART>, pub uart: UartBase<UART>,
irq_info: IrqInfo, irq_info: IrqInfo,
@ -348,7 +354,7 @@ impl<UART: Instance> UartBase<UART> {
}; };
let x = sys_clk.0 as f32 / (config.baudrate.0 * baud_multiplier) as f32; let x = sys_clk.0 as f32 / (config.baudrate.0 * baud_multiplier) as f32;
let integer_part = floorf(x) as u32; let integer_part = floorf(x) as u32;
let frac = floorf((64.0 * (x - integer_part as f32) + 0.5) as f32) as u32; let frac = floorf(64.0 * (x - integer_part as f32) + 0.5) as u32;
self.uart self.uart
.clkscale .clkscale
.write(|w| unsafe { w.bits(integer_part * 64 + frac) }); .write(|w| unsafe { w.bits(integer_part * 64 + frac) });
@ -477,6 +483,8 @@ where
self self
} }
/// If the IRQ capabilities of the peripheral are used, the UART needs to be converted
/// with this function
pub fn into_uart_with_irq( pub fn into_uart_with_irq(
self, self,
irq_cfg: IrqCfg, irq_cfg: IrqCfg,
@ -631,6 +639,14 @@ impl<UART: Instance> UartWithIrqBase<UART> {
self self
} }
/// This initializes a non-blocking read transfer using the IRQ capabilities of the UART
/// peripheral.
///
/// The only required information is the maximum length for variable sized reception
/// or the expected length for fixed length reception. If variable sized packets are expected,
/// the timeout functionality of the IRQ should be enabled as well. After calling this function,
/// the [`irq_handler`](Self::irq_handler) function should be called in the user interrupt
/// handler to read the received packets and reinitiate another transfer if desired.
pub fn read_fixed_len_using_irq( pub fn read_fixed_len_using_irq(
&mut self, &mut self,
max_len: usize, max_len: usize,
@ -639,6 +655,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
if self.irq_info.mode != IrqReceptionMode::Idle { if self.irq_info.mode != IrqReceptionMode::Idle {
return Err(Error::TransferPending); return Err(Error::TransferPending);
} }
self.irq_info.mode = IrqReceptionMode::Pending;
self.irq_info.rx_idx = 0; self.irq_info.rx_idx = 0;
self.irq_info.rx_len = max_len; self.irq_info.rx_len = max_len;
self.uart.enable_rx(); self.uart.enable_rx();
@ -689,6 +706,10 @@ impl<UART: Instance> UartWithIrqBase<UART> {
self.irq_info.rx_len = 0; self.irq_info.rx_len = 0;
} }
/// Default IRQ handler which can be used to read the packets arriving on the UART peripheral.
///
/// If passed buffer is equal to or larger than the specified maximum length, an
/// [`Error::BufferTooShort`] will be returned
pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> { pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> {
if buf.len() < self.irq_info.rx_len { if buf.len() < self.irq_info.rx_len {
return Err(Error::BufferTooShort); return Err(Error::BufferTooShort);
@ -799,6 +820,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
res.bytes_read = self.irq_info.rx_idx; res.bytes_read = self.irq_info.rx_idx;
res.clear_result(); res.clear_result();
res.set_result(IrqResultMask::Complete); res.set_result(IrqResultMask::Complete);
self.irq_info.mode = IrqReceptionMode::Idle;
self.irq_info.rx_idx = 0; self.irq_info.rx_idx = 0;
self.irq_info.rx_len = 0; self.irq_info.rx_len = 0;
} }
@ -809,6 +831,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
} }
impl<UART: Instance, PINS> UartWithIrq<UART, PINS> { impl<UART: Instance, PINS> UartWithIrq<UART, PINS> {
/// See [`UartWithIrqBase::read_fixed_len_using_irq`] doc
pub fn read_fixed_len_using_irq( pub fn read_fixed_len_using_irq(
&mut self, &mut self,
max_len: usize, max_len: usize,
@ -822,6 +845,7 @@ impl<UART: Instance, PINS> UartWithIrq<UART, PINS> {
self.irq_base.cancel_transfer() self.irq_base.cancel_transfer()
} }
/// See [`UartWithIrqBase::irq_handler`] doc
pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> { pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> {
self.irq_base.irq_handler(res, buf) self.irq_base.irq_handler(res, buf)
} }
@ -876,11 +900,10 @@ impl<UART: Instance> serial::Write<u8> for Tx<UART> {
return Err(nb::Error::WouldBlock); return Err(nb::Error::WouldBlock);
} else { } else {
// DPARITY bit not supported yet // DPARITY bit not supported yet
// NOTE(unsafe) atomic write to data register
unsafe { unsafe {
// NOTE(unsafe) atomic write to data register // NOTE(unsafe) atomic write to data register
// NOTE(write_volatile) 8-bit write that's not (*UART::ptr()).data.write(|w| w.bits(word as u32));
// possible through the svd2rust API
ptr::write_volatile(&(*UART::ptr()).data as *const _ as *mut _, word);
} }
} }
Ok(()) Ok(())

View File

@ -6,7 +6,7 @@
use crate::pac; use crate::pac;
use va108xx::{IOCONFIG, SYSCONFIG}; use va108xx::{IOCONFIG, SYSCONFIG};
#[derive(PartialEq, Debug)] #[derive(PartialEq, Eq, Debug)]
pub enum UtilityError { pub enum UtilityError {
InvalidCounterResetVal, InvalidCounterResetVal,
InvalidPin, InvalidPin,
@ -19,13 +19,13 @@ pub enum Funsel {
Funsel3 = 0b11, Funsel3 = 0b11,
} }
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum PortSel { pub enum PortSel {
PortA, PortA,
PortB, PortB,
} }
#[derive(Copy, Clone, PartialEq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum PeripheralSelect { pub enum PeripheralSelect {
PortA = 0, PortA = 0,
PortB = 1, PortB = 1,
@ -46,7 +46,7 @@ pub enum PeripheralSelect {
/// use the IRQSEL register to route an interrupt, and whether the IRQ will be unmasked in the /// use the IRQSEL register to route an interrupt, and whether the IRQ will be unmasked in the
/// Cortex-M0 NVIC. Both are generally necessary for IRQs to work, but the user might perform /// Cortex-M0 NVIC. Both are generally necessary for IRQs to work, but the user might perform
/// this steps themselves /// this steps themselves
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct IrqCfg { pub struct IrqCfg {
/// Interrupt target vector. Should always be set, might be required for disabling IRQs /// Interrupt target vector. Should always be set, might be required for disabling IRQs
pub irq: pac::Interrupt, pub irq: pac::Interrupt,