Skip to content

Commit 9ff56af

Browse files
committed
embedded-io implementations
1 parent df544aa commit 9ff56af

File tree

10 files changed

+216
-98
lines changed

10 files changed

+216
-98
lines changed

e310x-hal/Cargo.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ edition = "2021"
1111
rust-version = "1.76"
1212

1313
[dependencies]
14-
embedded-hal = { version = "1.0.0" }
15-
embedded-hal-nb = { version = "1.0.0" }
16-
nb = "1.0.0"
17-
riscv = { version = "0.12.1", features = ["critical-section-single-hart"] }
14+
embedded-hal = "1.0.0"
15+
embedded-hal-nb = "1.0.0"
16+
embedded-io = "0.6.1"
1817
e310x = { path = "../e310x", version = "0.12.0", features = ["rt", "critical-section"] }
18+
nb = "1.0.0"
1919
portable-atomic = { version = "1.9", default-features = false}
20+
riscv = { version = "0.12.1", features = ["critical-section-single-hart"] }
2021

2122
[features]
2223
g002 = ["e310x/g002"]

e310x-hal/src/prelude.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub use e310x::interrupt::{
1111
PriorityNumber,
1212
};
1313
pub use embedded_hal::{
14+
self,
1415
delay::DelayNs,
1516
digital::{InputPin, OutputPin, StatefulOutputPin},
1617
i2c::I2c as _embedded_hal_i2c_I2c,
@@ -19,6 +20,9 @@ pub use embedded_hal::{
1920
};
2021

2122
pub use embedded_hal_nb::{
22-
serial::{Read, Write},
23+
self,
24+
serial::{Read as _embedded_hal_nb_Read, Write as _embedded_hal_nb_Write},
2325
spi::FullDuplex,
2426
};
27+
28+
pub use embedded_io;

e310x-hal/src/serial.rs

+116-21
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
1616
use core::ops::Deref;
1717
use e310x::{uart0, Uart0, Uart1};
18-
use embedded_hal_nb::serial::{ErrorKind, ErrorType, Read, Write};
19-
use nb;
18+
use embedded_hal_nb::serial;
2019

2120
use crate::{clock::Clocks, time::Bps};
2221

@@ -73,12 +72,17 @@ impl<UART, PIN> Rx<UART, PIN> {
7372
}
7473
}
7574

76-
impl<UART: UartX, PIN: RxPin<UART>> ErrorType for Rx<UART, PIN> {
77-
type Error = ErrorKind;
75+
impl<UART: UartX, PIN: RxPin<UART>> serial::ErrorType for Rx<UART, PIN> {
76+
type Error = serial::ErrorKind;
7877
}
7978

80-
impl<UART: UartX, PIN: RxPin<UART>> Read for Rx<UART, PIN> {
81-
fn read(&mut self) -> nb::Result<u8, ErrorKind> {
79+
impl<UART: UartX, PIN: RxPin<UART>> embedded_io::ErrorType for Rx<UART, PIN> {
80+
type Error = embedded_io::ErrorKind;
81+
}
82+
83+
impl<UART: UartX, PIN: RxPin<UART>> serial::Read for Rx<UART, PIN> {
84+
#[inline]
85+
fn read(&mut self) -> nb::Result<u8, Self::Error> {
8286
let rxdata = self.uart.rxdata().read();
8387

8488
if rxdata.empty().bit_is_set() {
@@ -89,6 +93,28 @@ impl<UART: UartX, PIN: RxPin<UART>> Read for Rx<UART, PIN> {
8993
}
9094
}
9195

96+
impl<UART: UartX, PIN: RxPin<UART>> embedded_io::Read for Rx<UART, PIN> {
97+
#[inline]
98+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
99+
if buf.is_empty() {
100+
return Ok(0);
101+
}
102+
buf[0] = nb::block!(serial::Read::read(self)).unwrap(); // first byte may block
103+
let mut count = 1;
104+
for byte in buf.iter_mut().skip(1) {
105+
match serial::Read::read(self) {
106+
Ok(b) => {
107+
*byte = b;
108+
count += 1
109+
}
110+
Err(nb::Error::WouldBlock) => break,
111+
_ => unreachable!(),
112+
}
113+
}
114+
Ok(count)
115+
}
116+
}
117+
92118
/// Serial transmitter half
93119
pub struct Tx<UART, PIN> {
94120
uart: UART,
@@ -102,23 +128,34 @@ impl<UART, PIN> Tx<UART, PIN> {
102128
}
103129
}
104130

105-
impl<UART: UartX, PIN: TxPin<UART>> ErrorType for Tx<UART, PIN> {
106-
type Error = ErrorKind;
131+
impl<UART: UartX, PIN: TxPin<UART>> Tx<UART, PIN> {
132+
/// Returns true if the transmit buffer is full
133+
fn is_buffer_full(&self) -> bool {
134+
self.uart.txdata().read().full().bit_is_set()
135+
}
107136
}
108137

109-
impl<UART: UartX, PIN: TxPin<UART>> Write for Tx<UART, PIN> {
110-
fn write(&mut self, byte: u8) -> nb::Result<(), ErrorKind> {
111-
let txdata = self.uart.txdata().read();
138+
impl<UART: UartX, PIN: TxPin<UART>> serial::ErrorType for Tx<UART, PIN> {
139+
type Error = serial::ErrorKind;
140+
}
112141

113-
if txdata.full().bit_is_set() {
114-
Err(::nb::Error::WouldBlock)
142+
impl<UART: UartX, PIN: TxPin<UART>> embedded_io::ErrorType for Tx<UART, PIN> {
143+
type Error = embedded_io::ErrorKind;
144+
}
145+
146+
impl<UART: UartX, PIN: TxPin<UART>> serial::Write for Tx<UART, PIN> {
147+
#[inline]
148+
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
149+
if self.is_buffer_full() {
150+
Err(nb::Error::WouldBlock)
115151
} else {
116152
self.uart.txdata().write(|w| unsafe { w.data().bits(byte) });
117153
Ok(())
118154
}
119155
}
120156

121-
fn flush(&mut self) -> nb::Result<(), ErrorKind> {
157+
#[inline]
158+
fn flush(&mut self) -> nb::Result<(), Self::Error> {
122159
if self.uart.ip().read().txwm().bit_is_set() {
123160
// FIFO count is below the receive watermark (1)
124161
Ok(())
@@ -128,6 +165,38 @@ impl<UART: UartX, PIN: TxPin<UART>> Write for Tx<UART, PIN> {
128165
}
129166
}
130167

168+
impl<UART: UartX, PIN: TxPin<UART>> embedded_io::WriteReady for Tx<UART, PIN> {
169+
#[inline]
170+
fn write_ready(&mut self) -> Result<bool, Self::Error> {
171+
Ok(!self.is_buffer_full())
172+
}
173+
}
174+
175+
impl<UART: UartX, PIN: TxPin<UART>> embedded_io::Write for Tx<UART, PIN> {
176+
#[inline]
177+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
178+
if buf.is_empty() {
179+
return Ok(0);
180+
}
181+
nb::block!(serial::Write::write(self, buf[0])).unwrap(); // first byte may block
182+
let mut count = 1;
183+
for byte in buf.iter().skip(1) {
184+
match serial::Write::write(self, *byte) {
185+
Ok(()) => count += 1,
186+
Err(nb::Error::WouldBlock) => break,
187+
_ => unreachable!(),
188+
}
189+
}
190+
Ok(count)
191+
}
192+
193+
#[inline]
194+
fn flush(&mut self) -> Result<(), Self::Error> {
195+
nb::block!(serial::Write::flush(self)).unwrap();
196+
Ok(())
197+
}
198+
}
199+
131200
/// Serial abstraction
132201
pub struct Serial<UART, TX, RX> {
133202
uart: UART,
@@ -186,22 +255,48 @@ impl<UART: UartX, TX: TxPin<UART>, RX: RxPin<UART>> Serial<UART, TX, RX> {
186255
}
187256
}
188257

189-
impl<UART, TX, RX> ErrorType for Serial<UART, TX, RX> {
190-
type Error = ErrorKind;
258+
impl<UART: UartX, TX, RX> serial::ErrorType for Serial<UART, TX, RX> {
259+
type Error = serial::ErrorKind;
191260
}
192261

193-
impl<UART: UartX, TX, RX: RxPin<UART>> Read for Serial<UART, TX, RX> {
194-
fn read(&mut self) -> nb::Result<u8, ErrorKind> {
262+
impl<UART: UartX, TX, RX: RxPin<UART>> serial::Read for Serial<UART, TX, RX> {
263+
fn read(&mut self) -> nb::Result<u8, Self::Error> {
195264
self.rx.read()
196265
}
197266
}
198267

199-
impl<UART: UartX, TX: TxPin<UART>, RX> Write for Serial<UART, TX, RX> {
200-
fn write(&mut self, byte: u8) -> nb::Result<(), ErrorKind> {
268+
impl<UART: UartX, TX: TxPin<UART>, RX> serial::Write for Serial<UART, TX, RX> {
269+
fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
201270
self.tx.write(byte)
202271
}
203272

204-
fn flush(&mut self) -> nb::Result<(), ErrorKind> {
273+
fn flush(&mut self) -> nb::Result<(), Self::Error> {
274+
self.tx.flush()
275+
}
276+
}
277+
278+
impl<UART, TX, RX> embedded_io::ErrorType for Serial<UART, TX, RX> {
279+
type Error = embedded_io::ErrorKind;
280+
}
281+
282+
impl<UART: UartX, TX, RX: RxPin<UART>> embedded_io::Read for Serial<UART, TX, RX> {
283+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
284+
self.rx.read(buf)
285+
}
286+
}
287+
288+
impl<UART: UartX, TX: TxPin<UART>, RX> embedded_io::WriteReady for Serial<UART, TX, RX> {
289+
fn write_ready(&mut self) -> Result<bool, Self::Error> {
290+
self.tx.write_ready()
291+
}
292+
}
293+
294+
impl<UART: UartX, TX: TxPin<UART>, RX> embedded_io::Write for Serial<UART, TX, RX> {
295+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
296+
self.tx.write(buf)
297+
}
298+
299+
fn flush(&mut self) -> Result<(), Self::Error> {
205300
self.tx.flush()
206301
}
207302
}

e310x-hal/src/spi/bus.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use embedded_hal::spi::{self, ErrorKind, ErrorType, Phase, Polarity};
1+
use embedded_hal::{
2+
delay::DelayNs,
3+
spi::{self, ErrorKind, ErrorType, Phase, Polarity},
4+
};
25
use embedded_hal_nb::spi::FullDuplex;
36

47
use super::{Pins, PinsFull, PinsNoCS, SharedBus, SpiConfig, SpiExclusiveDevice, SpiX};
@@ -76,8 +79,12 @@ impl<SPI: SpiX, PINS: Pins<SPI>> SpiBus<SPI, PINS> {
7679
}
7780

7881
/// Create a new [`SpiExclusiveDevice`] for exclusive use on this bus
79-
pub fn new_device(self, config: &SpiConfig) -> SpiExclusiveDevice<SPI, PINS> {
80-
SpiExclusiveDevice::new(self, config)
82+
pub fn new_device<D: DelayNs>(
83+
self,
84+
config: &SpiConfig,
85+
delay: D,
86+
) -> SpiExclusiveDevice<SPI, PINS, D> {
87+
SpiExclusiveDevice::new(self, config, delay)
8188
}
8289

8390
/// Configure the [`SpiBus`] with given [`SpiConfig`]

e310x-hal/src/spi/exclusive_device.rs

+37-14
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,54 @@
1-
use embedded_hal::spi::{ErrorKind, ErrorType, Operation, SpiBus, SpiDevice};
1+
use embedded_hal::{
2+
delay::DelayNs,
3+
spi::{self, ErrorType, Operation, SpiBus, SpiDevice},
4+
};
25

36
use crate::spi::SpiConfig;
47

58
use super::{Pins, PinsFull, SpiBus as Bus, SpiX};
69

7-
/// SPI exclusive device abstraction
8-
pub struct SpiExclusiveDevice<SPI, PINS> {
10+
/// SPI exclusive device abstraction with delay support.
11+
pub struct SpiExclusiveDevice<SPI, PINS, D> {
912
bus: Bus<SPI, PINS>,
13+
delay: D,
1014
}
1115

12-
impl<SPI: SpiX, PINS: Pins<SPI>> SpiExclusiveDevice<SPI, PINS> {
13-
/// Create [`SpiExclusiveDevice`] using existing [`SpiBus`](Bus) with the given [`SpiConfig`]
14-
pub fn new(mut bus: Bus<SPI, PINS>, config: &SpiConfig) -> Self {
16+
impl<SPI, PINS, D> SpiExclusiveDevice<SPI, PINS, D>
17+
where
18+
SPI: SpiX,
19+
PINS: Pins<SPI>,
20+
D: DelayNs,
21+
{
22+
/// Create [`SpiDelayedExclusiveDevice`] using existing [`SpiBus`](Bus) with the given [`SpiConfig`]
23+
pub fn new(mut bus: Bus<SPI, PINS>, config: &SpiConfig, delay: D) -> Self {
1524
// Safety: valid CS index
1625
unsafe { bus.configure(config, PINS::CS_INDEX) };
1726

18-
Self { bus }
27+
Self { bus, delay }
1928
}
2029

21-
/// Releases the Bus back deconstructing it
22-
pub fn release(self) -> (SPI, PINS) {
23-
self.bus.release()
30+
/// Releases the Bus and Delay back deconstructing it
31+
pub fn release(self) -> (SPI, PINS, D) {
32+
let (spi, pins) = self.bus.release();
33+
(spi, pins, self.delay)
2434
}
2535
}
2636

27-
impl<SPI: SpiX, PINS: Pins<SPI>> ErrorType for SpiExclusiveDevice<SPI, PINS> {
28-
type Error = ErrorKind;
37+
impl<SPI, PINS, D> ErrorType for SpiExclusiveDevice<SPI, PINS, D>
38+
where
39+
SPI: SpiX,
40+
PINS: Pins<SPI>,
41+
D: DelayNs,
42+
{
43+
type Error = spi::ErrorKind;
2944
}
3045

31-
impl<SPI: SpiX, PINS: PinsFull<SPI>> SpiDevice for SpiExclusiveDevice<SPI, PINS> {
46+
impl<SPI, PINS, D> SpiDevice for SpiExclusiveDevice<SPI, PINS, D>
47+
where
48+
SPI: SpiX,
49+
PINS: PinsFull<SPI>,
50+
D: DelayNs,
51+
{
3252
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
3353
self.bus.start_frame();
3454

@@ -39,7 +59,10 @@ impl<SPI: SpiX, PINS: PinsFull<SPI>> SpiDevice for SpiExclusiveDevice<SPI, PINS>
3959
Operation::Write(write) => self.bus.write(write),
4060
Operation::Transfer(read, write) => self.bus.transfer(read, write),
4161
Operation::TransferInPlace(read_write) => self.bus.transfer_in_place(read_write),
42-
Operation::DelayNs(_ns) => todo!(),
62+
Operation::DelayNs(ns) => {
63+
self.delay.delay_ns(*ns);
64+
Ok(())
65+
}
4366
};
4467
if res.is_err() {
4568
break;

e310x-hal/src/spi/shared_bus.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::cell::RefCell;
22
use core::ops::Deref;
3+
use embedded_hal::delay::DelayNs;
34
use riscv::interrupt;
45

56
use super::{PinCS, PinsNoCS, SpiBus, SpiConfig, SpiSharedDevice, SpiX};
@@ -18,15 +19,17 @@ where
1819
}
1920

2021
/// Create a new shared device on this SPI bus.
21-
pub fn new_device<'bus, CS>(
22+
pub fn new_device<'bus, CS, D>(
2223
&'bus self,
2324
cs: CS,
2425
config: &SpiConfig,
25-
) -> SpiSharedDevice<'bus, SPI, PINS, CS>
26+
delay: D,
27+
) -> SpiSharedDevice<'bus, SPI, PINS, CS, D>
2628
where
2729
CS: PinCS<SPI>,
30+
D: DelayNs,
2831
{
29-
SpiSharedDevice::new(self, cs, config)
32+
SpiSharedDevice::new(self, cs, config, delay)
3033
}
3134
}
3235

0 commit comments

Comments
 (0)