Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
2db345af9f | |||
09fd0d2aad | |||
b776bd2823 | |||
6131458a13 | |||
2b8a8dc7c8 | |||
e9f1294572 | |||
1476f4eebe | |||
0ee53c70d5 | |||
833567037c | |||
38b9625773 | |||
49b72d683f | |||
21c44e6327 | |||
147c57defb | |||
5cbbb53094 | |||
491ef3ce09 | |||
e3cdd21b41 |
16
CHANGELOG.md
16
CHANGELOG.md
@ -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/)
|
||||
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]
|
||||
|
||||
### Added
|
||||
|
35
Cargo.toml
35
Cargo.toml
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "va108xx-hal"
|
||||
version = "0.5.0"
|
||||
version = "0.5.2"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
edition = "2021"
|
||||
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"
|
||||
license = "Apache-2.0"
|
||||
keywords = ["no-std", "hal", "cortex-m", "vorago", "va108xx"]
|
||||
categories = ["embedded", "no-std", "hardware-support"]
|
||||
categories = ["aerospace", "embedded", "no-std", "hardware-support"]
|
||||
|
||||
[dependencies]
|
||||
va108xx = "0.2.4"
|
||||
cortex-m = "0.7"
|
||||
cortex-m-rt = "0.7"
|
||||
nb = "1"
|
||||
paste = "1.0"
|
||||
embedded-hal = { features = ["unproven"], version = "0.2.6" }
|
||||
void = { version = "1.0", default-features = false }
|
||||
once_cell = { version = "1.8.0", default-features = false }
|
||||
libm = "0.2.1"
|
||||
libm = "0.2"
|
||||
|
||||
[dependencies.va108xx]
|
||||
version = "0.2.4"
|
||||
[dependencies.embedded-hal]
|
||||
version = "0.2.7"
|
||||
features = ["unproven"]
|
||||
|
||||
[dependencies.void]
|
||||
version = "1.0"
|
||||
default-features = false
|
||||
|
||||
[dependencies.once_cell]
|
||||
version = "1.14"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
rt = ["va108xx/rt"]
|
||||
|
||||
[dev-dependencies]
|
||||
cortex-m-rtic = "0.6.0-rc.4"
|
||||
panic-rtt-target = { version = "0.1", features = ["cortex-m"] }
|
||||
rtt-target = { version = "0.3", features = ["cortex-m"] }
|
||||
cortex-m-rtic = "1.1.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]
|
||||
debug = true
|
||||
lto = false
|
||||
|
@ -1,5 +1,5 @@
|
||||
[![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)
|
||||
|
||||
# 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)
|
||||
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
|
||||
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
|
||||
|
@ -7,5 +7,7 @@ RUN apt-get --yes upgrade
|
||||
# tzdata is a dependency, won't install otherwise
|
||||
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
|
||||
|
37
automation/Jenkinsfile
vendored
37
automation/Jenkinsfile
vendored
@ -1,47 +1,34 @@
|
||||
pipeline {
|
||||
agent any
|
||||
agent {
|
||||
dockerfile {
|
||||
dir 'automation'
|
||||
reuseNode true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stages {
|
||||
stage('Clippy') {
|
||||
agent {
|
||||
dockerfile {
|
||||
dir 'automation'
|
||||
reuseNode true
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'cargo clippy'
|
||||
}
|
||||
}
|
||||
stage('Rustfmt') {
|
||||
agent {
|
||||
dockerfile {
|
||||
dir 'automation'
|
||||
reuseNode true
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'cargo fmt'
|
||||
}
|
||||
}
|
||||
stage('Check') {
|
||||
agent {
|
||||
dockerfile {
|
||||
dir 'automation'
|
||||
reuseNode true
|
||||
}
|
||||
stage('Docs') {
|
||||
steps {
|
||||
sh 'cargo +nightly doc'
|
||||
}
|
||||
}
|
||||
stage('Check') {
|
||||
steps {
|
||||
sh 'cargo check --target thumbv6m-none-eabi'
|
||||
}
|
||||
}
|
||||
stage('Check Examples') {
|
||||
agent {
|
||||
dockerfile {
|
||||
dir 'automation'
|
||||
reuseNode true
|
||||
}
|
||||
}
|
||||
steps {
|
||||
sh 'cargo check --target thumbv6m-none-eabi --examples'
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
//! UART example application. Sends a test string over a UART and then enters
|
||||
//! echo mode
|
||||
//! More complex UART application
|
||||
//!
|
||||
//! 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_std]
|
||||
|
||||
|
@ -11,7 +11,7 @@ static SYS_CLOCK: Mutex<OnceCell<Hertz>> = Mutex::new(OnceCell::new());
|
||||
|
||||
pub type PeripheralClocks = PeripheralSelect;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum FilterClkSel {
|
||||
SysClk = 0,
|
||||
Clk1 = 1,
|
||||
|
@ -143,14 +143,14 @@ pub const DYN_ALT_FUNC_3: DynPinMode = DynPinMode::Alternate(DynAlternate::Funse
|
||||
//==================================================================================================
|
||||
|
||||
/// Value-level `enum` for pin groups
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum DynGroup {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
/// Value-level `struct` representing pin IDs
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct DynPinId {
|
||||
pub group: DynGroup,
|
||||
pub num: u8,
|
||||
|
@ -106,27 +106,27 @@ use paste::paste;
|
||||
// Errors and Definitions
|
||||
//==================================================================================================
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum InterruptEdge {
|
||||
HighToLow,
|
||||
LowToHigh,
|
||||
BothEdges,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum InterruptLevel {
|
||||
Low = 0,
|
||||
High = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum PinState {
|
||||
Low = 0,
|
||||
High = 1,
|
||||
}
|
||||
|
||||
/// GPIO error type
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum PinError {
|
||||
/// 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
|
||||
@ -182,7 +182,7 @@ pub struct Input<C: InputConfig> {
|
||||
|
||||
impl<C: InputConfig> Sealed for Input<C> {}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum FilterType {
|
||||
SystemClock = 0,
|
||||
DirectInputWithSynchronization = 1,
|
||||
|
14
src/i2c.rs
14
src/i2c.rs
@ -18,13 +18,13 @@ pub use embedded_hal::blocking::i2c::{SevenBitAddress, TenBitAddress};
|
||||
// Defintions
|
||||
//==================================================================================================
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum FifoEmptyMode {
|
||||
Stall = 0,
|
||||
EndTransaction = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Error {
|
||||
InvalidTimingParams,
|
||||
ArbitrationLost,
|
||||
@ -46,19 +46,19 @@ enum I2cCmd {
|
||||
Cancel = 0b100,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum I2cSpeed {
|
||||
Regular100khz = 0,
|
||||
Fast400khz = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum I2cDirection {
|
||||
Send = 0,
|
||||
Read = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum I2cAddress {
|
||||
Regular(u8),
|
||||
TenBit(u16),
|
||||
@ -119,14 +119,14 @@ impl TimingCfg {
|
||||
}
|
||||
|
||||
pub fn reg(&self) -> u32 {
|
||||
((self.tbuf as u32) << 28
|
||||
(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)) as u32
|
||||
| (self.tr as u32)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ use embedded_hal::{
|
||||
// Defintions
|
||||
//==================================================================================================
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum HwChipSelectId {
|
||||
Id0 = 0,
|
||||
Id1 = 1,
|
||||
@ -38,7 +38,7 @@ pub enum HwChipSelectId {
|
||||
Invalid = 0xff,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum WordSize {
|
||||
OneBit = 0x00,
|
||||
FourBits = 0x03,
|
||||
|
12
src/time.rs
12
src/time.rs
@ -6,7 +6,7 @@
|
||||
//! allowing it to be converted into frequencies.
|
||||
|
||||
/// Bits per second
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
|
||||
pub struct Bps(pub u32);
|
||||
|
||||
/// Hertz
|
||||
@ -25,7 +25,7 @@ pub struct Bps(pub u32);
|
||||
///
|
||||
/// let freq = 60.hz();
|
||||
/// ```
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
|
||||
pub struct Hertz(pub u32);
|
||||
|
||||
/// Kilohertz
|
||||
@ -47,7 +47,7 @@ pub struct Hertz(pub u32);
|
||||
///
|
||||
/// let freq = 100.khz();
|
||||
/// ```
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
|
||||
pub struct KiloHertz(pub u32);
|
||||
|
||||
/// Megahertz
|
||||
@ -68,14 +68,14 @@ pub struct KiloHertz(pub u32);
|
||||
///
|
||||
/// let freq = 8.mhz();
|
||||
/// ```
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)]
|
||||
pub struct MegaHertz(pub u32);
|
||||
|
||||
/// Time unit
|
||||
#[derive(PartialEq, PartialOrd, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Clone, Copy)]
|
||||
pub struct MilliSeconds(pub u32);
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Clone, Copy)]
|
||||
pub struct MicroSeconds(pub u32);
|
||||
|
||||
/// Extension trait that adds convenience methods to the `u32` type
|
||||
|
@ -45,7 +45,7 @@ pub enum Event {
|
||||
TimeOut,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Default, Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub struct CascadeCtrl {
|
||||
/// Enable Cascade 0 signal active as a requirement for counting
|
||||
pub enb_start_src_csd0: bool,
|
||||
@ -74,7 +74,7 @@ pub struct CascadeCtrl {
|
||||
pub trg_csd2: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum CascadeSel {
|
||||
Csd0 = 0,
|
||||
Csd1 = 1,
|
||||
@ -82,7 +82,7 @@ pub enum CascadeSel {
|
||||
}
|
||||
|
||||
/// The numbers are the base numbers for bundles like PORTA, PORTB or TIM
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum CascadeSource {
|
||||
PortABase = 0,
|
||||
PortBBase = 32,
|
||||
@ -95,7 +95,7 @@ pub enum CascadeSource {
|
||||
ClockDividerBase = 120,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum TimerErrors {
|
||||
Canceled,
|
||||
/// Invalid input for Cascade source
|
||||
|
51
src/uart.rs
51
src/uart.rs
@ -2,7 +2,8 @@
|
||||
//!
|
||||
//! ## 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::{marker::PhantomData, ops::Deref};
|
||||
use libm::floorf;
|
||||
@ -59,7 +60,7 @@ pub enum Error {
|
||||
IrqError,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Event {
|
||||
// Receiver FIFO interrupt enable. Generates interrupt
|
||||
// when FIFO is at least half full. Half full is defined as FIFO
|
||||
@ -83,20 +84,20 @@ pub enum Event {
|
||||
TxCts,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Parity {
|
||||
None,
|
||||
Odd,
|
||||
Even,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum StopBits {
|
||||
One = 0,
|
||||
Two = 1,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum WordSize {
|
||||
Five = 0,
|
||||
Six = 1,
|
||||
@ -177,7 +178,7 @@ impl From<Bps> for Config {
|
||||
// IRQ Definitions
|
||||
//==================================================================================================
|
||||
|
||||
pub struct IrqInfo {
|
||||
struct IrqInfo {
|
||||
rx_len: usize,
|
||||
rx_idx: usize,
|
||||
irq_cfg: IrqCfg,
|
||||
@ -196,6 +197,7 @@ pub enum IrqResultMask {
|
||||
Unknown = 7,
|
||||
}
|
||||
|
||||
/// This struct is used to return the default IRQ handler result to the user
|
||||
#[derive(Debug, Default)]
|
||||
pub struct IrqResult {
|
||||
raw_res: u32,
|
||||
@ -276,32 +278,36 @@ impl IrqResult {
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum IrqReceptionMode {
|
||||
enum IrqReceptionMode {
|
||||
Idle,
|
||||
FixedLen,
|
||||
VarLen,
|
||||
Pending,
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// UART implementation
|
||||
//==================================================================================================
|
||||
|
||||
/// Type erased variant of a UART. Can be created with the [`Uart::downgrade`] function.
|
||||
pub struct UartBase<UART> {
|
||||
uart: UART,
|
||||
tx: Tx<UART>,
|
||||
rx: Rx<UART>,
|
||||
}
|
||||
/// Serial abstraction
|
||||
/// Serial abstraction. Entry point to create a new UART
|
||||
pub struct Uart<UART, PINS> {
|
||||
uart_base: UartBase<UART>,
|
||||
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> {
|
||||
irq_base: UartWithIrqBase<UART>,
|
||||
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 uart: UartBase<UART>,
|
||||
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 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
|
||||
.clkscale
|
||||
.write(|w| unsafe { w.bits(integer_part * 64 + frac) });
|
||||
@ -477,6 +483,8 @@ where
|
||||
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(
|
||||
self,
|
||||
irq_cfg: IrqCfg,
|
||||
@ -631,6 +639,14 @@ impl<UART: Instance> UartWithIrqBase<UART> {
|
||||
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(
|
||||
&mut self,
|
||||
max_len: usize,
|
||||
@ -639,6 +655,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
|
||||
if self.irq_info.mode != IrqReceptionMode::Idle {
|
||||
return Err(Error::TransferPending);
|
||||
}
|
||||
self.irq_info.mode = IrqReceptionMode::Pending;
|
||||
self.irq_info.rx_idx = 0;
|
||||
self.irq_info.rx_len = max_len;
|
||||
self.uart.enable_rx();
|
||||
@ -689,6 +706,10 @@ impl<UART: Instance> UartWithIrqBase<UART> {
|
||||
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> {
|
||||
if buf.len() < self.irq_info.rx_len {
|
||||
return Err(Error::BufferTooShort);
|
||||
@ -799,6 +820,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
|
||||
res.bytes_read = self.irq_info.rx_idx;
|
||||
res.clear_result();
|
||||
res.set_result(IrqResultMask::Complete);
|
||||
self.irq_info.mode = IrqReceptionMode::Idle;
|
||||
self.irq_info.rx_idx = 0;
|
||||
self.irq_info.rx_len = 0;
|
||||
}
|
||||
@ -809,6 +831,7 @@ impl<UART: Instance> UartWithIrqBase<UART> {
|
||||
}
|
||||
|
||||
impl<UART: Instance, PINS> UartWithIrq<UART, PINS> {
|
||||
/// See [`UartWithIrqBase::read_fixed_len_using_irq`] doc
|
||||
pub fn read_fixed_len_using_irq(
|
||||
&mut self,
|
||||
max_len: usize,
|
||||
@ -822,6 +845,7 @@ impl<UART: Instance, PINS> UartWithIrq<UART, PINS> {
|
||||
self.irq_base.cancel_transfer()
|
||||
}
|
||||
|
||||
/// See [`UartWithIrqBase::irq_handler`] doc
|
||||
pub fn irq_handler(&mut self, res: &mut IrqResult, buf: &mut [u8]) -> Result<(), Error> {
|
||||
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);
|
||||
} else {
|
||||
// DPARITY bit not supported yet
|
||||
// NOTE(unsafe) atomic write to data register
|
||||
unsafe {
|
||||
// NOTE(unsafe) atomic write to data register
|
||||
// NOTE(write_volatile) 8-bit write that's not
|
||||
// possible through the svd2rust API
|
||||
ptr::write_volatile(&(*UART::ptr()).data as *const _ as *mut _, word);
|
||||
(*UART::ptr()).data.write(|w| w.bits(word as u32));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -6,7 +6,7 @@
|
||||
use crate::pac;
|
||||
use va108xx::{IOCONFIG, SYSCONFIG};
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub enum UtilityError {
|
||||
InvalidCounterResetVal,
|
||||
InvalidPin,
|
||||
@ -19,13 +19,13 @@ pub enum Funsel {
|
||||
Funsel3 = 0b11,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum PortSel {
|
||||
PortA,
|
||||
PortB,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum PeripheralSelect {
|
||||
PortA = 0,
|
||||
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
|
||||
/// Cortex-M0 NVIC. Both are generally necessary for IRQs to work, but the user might perform
|
||||
/// this steps themselves
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct IrqCfg {
|
||||
/// Interrupt target vector. Should always be set, might be required for disabling IRQs
|
||||
pub irq: pac::Interrupt,
|
||||
|
Reference in New Issue
Block a user