17 Commits

Author SHA1 Message Date
86ac7428bb small README update 2025-03-11 16:32:52 +01:00
686b689a91 Merge pull request 'UART embedded-io fixes' (#72) from uart-embedded-io-fixes into main
Reviewed-on: #72
2025-03-10 17:36:19 +01:00
5daa85269f UART embedded-io fixes 2025-03-10 17:33:13 +01:00
3bc2ee4343 Merge pull request 'use released packages' (#71) from use-released-packages into main
Reviewed-on: #71
2025-03-07 16:44:37 +01:00
1ec66e826c use released packages 2025-03-07 16:43:29 +01:00
606d6a43b4 bump embassy version to v0.2.1 2025-03-07 16:40:22 +01:00
a83d9cca16 bump bitfield dep 2025-03-07 16:35:12 +01:00
9eeaae76f7 some typos 2025-03-07 16:33:52 +01:00
39aaea086a Merge pull request 'prepare reb1 and embassy releases' (#70) from prep-reb1-embassy-release into main
Reviewed-on: #70
2025-03-07 16:32:43 +01:00
a6ef0954cb prepare reb1 and embassy releases 2025-03-07 16:30:11 +01:00
102d11114a doc improvements 2025-03-07 16:22:13 +01:00
8cdee8b733 minor tweak for simple UART example 2025-03-07 16:20:23 +01:00
d419325312 Merge pull request 'check all updated dependencies' (#69) from check-all-updates-deps into main
Reviewed-on: #69
2025-03-07 16:17:41 +01:00
561a8419c5 check all updated dependencies 2025-03-07 16:15:17 +01:00
9bd8efcada Merge pull request 'simplfied UART error handling' (#68) from simplify-uart-error-handling into main
Reviewed-on: #68
2025-03-07 16:06:41 +01:00
b401085f32 simplfied UART error handling 2025-03-07 16:06:18 +01:00
c693530ab7 Move to released packages, done 2025-02-18 00:00:27 +01:00
20 changed files with 177 additions and 176 deletions

View File

@ -148,3 +148,13 @@ 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.
## 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)

View File

@ -14,6 +14,6 @@ embedded-hal-nb = "1"
embedded-io = "0.6" embedded-io = "0.6"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
path = "../va108xx-hal" version = "0.11"
features = ["rt"] features = ["rt"]

View File

@ -15,12 +15,10 @@ num_enum = { version = "0.7", default-features = false }
static_assertions = "1" static_assertions = "1"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.9" version = "0.11"
# path = "../va108xx-hal"
[dependencies.vorago-reb1] [dependencies.vorago-reb1]
version = "0.7" version = "0.8"
# path = "../vorago-reb1"
[features] [features]
default = [] default = []

View File

@ -27,10 +27,8 @@ version = "1"
features = ["cortex-m-systick"] features = ["cortex-m-systick"]
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.6" version = "0.10"
path = "../va108xx-hal"
features = ["rt", "defmt"] features = ["rt", "defmt"]
[dependencies.va108xx] [dependencies.va108xx]
version = "0.3" version = "0.5"
path = "../va108xx"

View File

@ -27,8 +27,8 @@ embassy-executor = { version = "0.7", features = [
"executor-interrupt" "executor-interrupt"
]} ]}
va108xx-hal = { version = "0.10" } va108xx-hal = { version = "0.11" }
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"]

View File

@ -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.10" } va108xx-hal = { version = "0.11" }
vorago-reb1 = { version = "0.8", path = "../../vorago-reb1" } vorago-reb1 = { version = "0.8" }

View File

@ -16,9 +16,8 @@ embedded-io = "0.6"
cortex-m-semihosting = "0.5.0" cortex-m-semihosting = "0.5.0"
[dependencies.va108xx-hal] [dependencies.va108xx-hal]
version = "0.10" version = "0.11"
features = ["rt", "defmt"] features = ["rt", "defmt"]
[dependencies.vorago-reb1] [dependencies.vorago-reb1]
path = "../../vorago-reb1"
version = "0.8" version = "0.8"

View File

@ -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);
}
} }
} }
} }

View File

@ -29,9 +29,7 @@ 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.9" version = "0.11"
# path = "../va108xx-hal"
[dependencies.vorago-reb1] [dependencies.vorago-reb1]
version = "0.7" version = "0.8"
# path = "../vorago-reb1"

View File

@ -11,7 +11,7 @@ panic-rtt-target = { version = "0.1.3" }
rtt-target = { version = "0.5" } rtt-target = { version = "0.5" }
cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
embedded-hal = "1" embedded-hal = "1"
va108xx-hal = { path = "../../va108xx-hal" } va108xx-hal = { version = "0.10.0" }
[profile.dev] [profile.dev]
codegen-units = 1 codegen-units = 1

View File

@ -11,7 +11,7 @@ panic-rtt-target = { version = "0.1.3" }
rtt-target = { version = "0.5" } rtt-target = { version = "0.5" }
cortex-m = { version = "0.7", features = ["critical-section-single-core"] } cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
embedded-hal = "1" embedded-hal = "1"
va108xx-hal = { path = "../../va108xx-hal" } va108xx-hal = { version = "0.10.0" }
[profile.dev] [profile.dev]
codegen-units = 1 codegen-units = 1

View File

@ -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

View File

@ -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.10" } 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"] }

View File

@ -8,6 +8,24 @@ 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
## 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 ## [v0.10.0] 2025-02-17
## Added ## Added
@ -104,14 +122,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Updated `embedded-hal` to v1 - Updated `embedded-hal` to v1
- Added optional `defmt` v0.3 feature and support. - Added optional `defmt` v0.3 feature and support.
## [v0.5.2] 2024-06-16 ## v0.5.2 2024-06-16
## Fixed ## Fixed
- Replaced usage to `ptr::write_volatile` in UART module which is denied on more recent Rust - Replaced usage to `ptr::write_volatile` in UART module which is denied on more recent Rust
compilers. compilers.
## [v0.5.1] ## v0.5.1
### Changes ### Changes
@ -120,7 +138,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- `once_cell` to 1.12.0 - `once_cell` to 1.12.0
- Other dependencies: Only revision has changed - Other dependencies: Only revision has changed
## [v0.5.0] ## v0.5.0
### Added ### Added
@ -133,14 +151,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 - 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 - Various smaller fixes for READMEs, update of links in documentation
- Simplified CI for github, do not use `cross` - Simplified CI for github, do not use `cross`
- New `blinky-pac` example - New `blinky-pac` example
- Use HAL delay in `blinky` example - Use HAL delay in `blinky` example
## [v0.4.2] ## v0.4.2
### Added ### Added
@ -150,24 +168,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Clear TX and RX FIFO in SPI transfer function - Clear TX and RX FIFO in SPI transfer function
## [v0.4.1] ## v0.4.1
### Fixed ### Fixed
- Initial blockmode setting was not set in SPI constructor - Initial blockmode setting was not set in SPI constructor
## [v0.4.0] ## v0.4.0
### Changed ### Changed
- Replaced `Hertz` by `impl Into<Hertz>` completely and removed - Replaced `Hertz` by `impl Into<Hertz>` completely and removed
`+ Copy` where not necessary `+ Copy` where not necessary
## [v0.3.1] ## v0.3.1
- Updated all links to point to new repository - Updated all links to point to new repository
## [v0.3.0] ## v0.3.0
### Added ### Added
@ -179,7 +197,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 - Primary repository now hosted on IRS external git: https://egit.irs.uni-stuttgart.de/rust/va108xx-hal
- Relicensed as Apache-2.0 - Relicensed as Apache-2.0
## [0.2.3] ## v0.2.3
### Added ### Added
@ -191,7 +209,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Improved Timer API. It is now possible to simply use `new` on `CountDownTimer` - Improved Timer API. It is now possible to simply use `new` on `CountDownTimer`
## [0.2.2] ## v0.2.2
### Added ### Added
@ -203,7 +221,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 - API which expects values in Hertz now uses `impl Into<Hertz>` as input parameter
## [0.2.1] ## v0.2.1
### Added ### Added
@ -217,7 +235,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Moved the `FilterClkSel` struct to the `clock` module, re-exporting in `gpio` - Moved the `FilterClkSel` struct to the `clock` module, re-exporting in `gpio`
- Clearing output state at initialization of Output pins - Clearing output state at initialization of Output pins
## [0.2.0] ## v0.2.0
### Changed ### Changed
@ -232,7 +250,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Some bugfixes for GPIO implementation - Some bugfixes for GPIO implementation
- Rust edition updated to 2021 - Rust edition updated to 2021
## [0.1.0] ## v0.1.0
### Added ### Added
@ -241,3 +259,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- RTT example application - RTT example application
- Added basic test binary in form of an example - Added basic test binary in form of an example
- 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
[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.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

View File

@ -1,6 +1,6 @@
[package] [package]
name = "va108xx-hal" name = "va108xx-hal"
version = "0.10.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"

View File

@ -198,13 +198,13 @@ 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) | (self.tr as u32)
} }
} }
@ -376,7 +376,7 @@ impl<I2c: Instance> I2cBase<I2c> {
if let Some(max_words) = max_words { if let Some(max_words) = max_words {
self.i2c self.i2c
.s0_maxwords() .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); 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 // 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)?; let clk_div = self.calc_clk_div(speed_mode)?;
self.i2c self.i2c
.clkscale() .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(()) Ok(())
} }

View File

@ -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)
@ -64,55 +71,6 @@ pub struct NoInterruptIdWasSet;
#[error("transer is pending")] #[error("transer is pending")]
pub struct TransferPendingError; 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)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Event { pub enum Event {
@ -363,7 +321,7 @@ impl UartErrors {
impl UartErrors { impl UartErrors {
#[inline(always)] #[inline(always)]
pub fn error(&self) -> bool { 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 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>) { pub fn split(self) -> (Tx<Uart>, Rx<Uart>) {
(self.tx, self.rx) (self.tx, self.rx)
} }
} }
impl<UartInstance> embedded_io::ErrorType for UartBase<UartInstance> { impl<UartInstance> embedded_io::ErrorType for UartBase<UartInstance> {
type Error = Error; type Error = Infallible;
} }
impl<UartInstance> embedded_hal_nb::serial::ErrorType for UartBase<UartInstance> { 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> { impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for UartBase<Uart> {
fn read(&mut self) -> nb::Result<u8, Self::Error> { 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 self
} }
/// Poll receiver errors.
pub fn poll_rx_errors(&self) -> Option<UartErrors> {
self.inner.poll_rx_errors()
}
#[inline] #[inline]
pub fn enable_rx(&mut self) { pub fn enable_rx(&mut self) {
self.inner.enable_rx(); self.inner.enable_rx();
@ -825,6 +793,23 @@ impl<Uart: Instance> Rx<Uart> {
&self.0 &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] #[inline]
pub fn clear_fifo(&self) { pub fn clear_fifo(&self) {
self.0.fifo_clr().write(|w| w.rxfifo().set_bit()); 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> { impl<Uart> embedded_io::ErrorType for Rx<Uart> {
type Error = RxError; type Error = Infallible;
} }
impl<Uart> embedded_hal_nb::serial::ErrorType for Rx<Uart> { 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> { impl<Uart: Instance> embedded_hal_nb::serial::Read<u8> for Rx<Uart> {
fn read(&mut self) -> nb::Result<u8, Self::Error> { 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| { self.read_fifo().map(|val| (val & 0xff) as u8).map_err(|e| {
if let nb::Error::Other(_) = e { if let nb::Error::Other(_) = e {
unreachable!() unreachable!()
@ -929,13 +895,23 @@ impl<Uart: Instance> embedded_io::Read for Rx<Uart> {
if buf.is_empty() { if buf.is_empty() {
return Ok(0); return Ok(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() {
let w = nb::block!(<Self as embedded_hal_nb::serial::Read<u8>>::read(self))?; match <Self as embedded_hal_nb::serial::Read<u8>>::read(self) {
*byte = w; Ok(w) => {
*byte = w;
read += 1;
}
Err(nb::Error::WouldBlock) => break,
}
} }
Ok(buf.len()) Ok(read)
} }
} }
@ -1093,14 +1069,20 @@ impl<Uart: Instance> embedded_io::Write for Tx<Uart> {
if buf.is_empty() { if buf.is_empty() {
return Ok(0); return Ok(0);
} }
loop {
if self.0.txstatus().read().wrrdy().bit_is_set() {
break;
}
}
let mut written = 0;
for byte in buf.iter() { for byte in buf.iter() {
nb::block!(<Self as embedded_hal_nb::serial::Write<u8>>::write( match <Self as embedded_hal_nb::serial::Write<u8>>::write(self, *byte) {
self, *byte Ok(_) => written += 1,
))?; Err(nb::Error::WouldBlock) => return Ok(written),
}
} }
Ok(buf.len()) Ok(written)
} }
fn flush(&mut self) -> Result<(), Self::Error> { fn flush(&mut self) -> Result<(), Self::Error> {
@ -1218,15 +1200,10 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
// Timeout, empty the FIFO completely. // Timeout, empty the FIFO completely.
if irq_end.irq_rx_to().bit_is_set() { if irq_end.irq_rx_to().bit_is_set() {
loop { // While there is data in the FIFO, write it into the reception buffer
// While there is data in the FIFO, write it into the reception buffer while let Ok(byte) = self.0.read_fifo() {
let read_result = self.0.read(); buf[result.bytes_read] = byte as u8;
if let Some(byte) = self.read_handler(&mut result.errors, &read_result) { result.bytes_read += 1;
buf[result.bytes_read] = byte;
result.bytes_read += 1;
} else {
break;
}
} }
} }
@ -1303,12 +1280,13 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
if context.rx_idx == context.max_len { if context.rx_idx == context.max_len {
break; break;
} }
let read_result = self.0.read(); // While there is data in the FIFO, write it into the reception buffer
if let Some(byte) = self.read_handler(&mut result.errors, &read_result) { match self.0.read() {
buf[context.rx_idx] = byte; Ok(byte) => {
context.rx_idx += 1; buf[result.bytes_read] = byte;
} else { result.bytes_read += 1;
break; }
Err(_) => break,
} }
} }
self.irq_completion_handler_max_size_timeout(&mut result, context); self.irq_completion_handler_max_size_timeout(&mut result, context);
@ -1327,29 +1305,6 @@ impl<Uart: Instance> RxWithInterrupt<Uart> {
Ok(result) 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>) { fn check_for_errors(&self, errors: &mut Option<UartErrors>) {
let rx_status = self.uart().rxstatus().read(); let rx_status = self.uart().rxstatus().read();

View File

@ -26,7 +26,7 @@ use embedded_io::ErrorType;
use portable_atomic::AtomicBool; use portable_atomic::AtomicBool;
use va108xx::uarta as uart_base; 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 UART_RX_WAKERS: [AtomicWaker; 2] = [const { AtomicWaker::new() }; 2];
static RX_READ_ACTIVE: [AtomicBool; 2] = [const { AtomicBool::new(false) }; 2]; static RX_READ_ACTIVE: [AtomicBool; 2] = [const { AtomicBool::new(false) }; 2];
@ -46,7 +46,7 @@ impl RxFuture {
} }
impl Future for RxFuture { impl Future for RxFuture {
type Output = Result<(), RxError>; type Output = Result<(), Infallible>;
fn poll( fn poll(
self: core::pin::Pin<&mut Self>, self: core::pin::Pin<&mut Self>,

View File

@ -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

View File

@ -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", features = ["rt"] } va108xx-hal = { version = ">=0.10, <=0.11", features = ["rt"] }
[features] [features]
rt = ["va108xx-hal/rt"] rt = ["va108xx-hal/rt"]