Skip to content

Commit 3a87906

Browse files
bors[bot]ryankurte
andauthored
Merge #464
464: Added transactional SPI implementation r=burrbull a=ryankurte per #445, i don't have a moment to look at the I2C at the moment as the behaviour is a bit more complex wrt. where starts and ends get asserted. Co-authored-by: ryan kurte <[email protected]>
2 parents 1365861 + 1b64d24 commit 3a87906

File tree

2 files changed

+66
-26
lines changed

2 files changed

+66
-26
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616

1717
- Support eMMC peripherals using SDIO module [#458]
1818
- `defmt::Format` derive on enums behind `defmt` feature
19+
- SPI transactional impl [#464]
1920

2021
[#418]: https://github.com/stm32-rs/stm32f4xx-hal/pull/418
2122
[#458]: https://github.com/stm32-rs/stm32f4xx-hal/pull/458
23+
[#464]: https://github.com/stm32-rs/stm32f4xx-hal/pull/464
2224

2325
## [v0.12.0] - 2022-02-23
2426

src/spi/hal_1.rs

+64-26
Original file line numberDiff line numberDiff line change
@@ -77,83 +77,117 @@ mod nb {
7777
mod blocking {
7878
use super::super::{Error, Instance, Spi, TransferModeBidi, TransferModeNormal};
7979
use embedded_hal_one::spi::{
80-
blocking::{Operation, Transactional, TransferInplace, Write, WriteIter},
80+
blocking::{Operation, Read, Transactional, Transfer, TransferInplace, Write, WriteIter},
8181
nb::FullDuplex,
8282
};
8383

84-
impl<SPI, PINS, TRANSFER_MODE> TransferInplace<u8> for Spi<SPI, PINS, TRANSFER_MODE>
84+
impl<SPI, PINS, TRANSFER_MODE, W: Copy + 'static> TransferInplace<W>
85+
for Spi<SPI, PINS, TRANSFER_MODE>
8586
where
86-
Self: FullDuplex<u8, Error = Error>,
87+
Self: FullDuplex<W, Error = Error>,
8788
SPI: Instance,
8889
{
89-
fn transfer_inplace(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
90+
fn transfer_inplace(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
9091
for word in words.iter_mut() {
91-
nb::block!(self.write(*word))?;
92-
*word = nb::block!(self.read())?;
92+
nb::block!(<Self as FullDuplex<W>>::write(self, *word))?;
93+
*word = nb::block!(<Self as FullDuplex<W>>::read(self))?;
9394
}
9495

9596
Ok(())
9697
}
9798
}
9899

99-
impl<SPI, PINS> Write<u8> for Spi<SPI, PINS, TransferModeNormal>
100+
impl<SPI, PINS, TRANSFER_MODE, W: Copy + 'static> Transfer<W> for Spi<SPI, PINS, TRANSFER_MODE>
100101
where
101-
Self: FullDuplex<u8, Error = Error>,
102+
Self: FullDuplex<W, Error = Error>,
102103
SPI: Instance,
103104
{
104-
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
105+
fn transfer(&mut self, buff: &mut [W], data: &[W]) -> Result<(), Self::Error> {
106+
assert_eq!(data.len(), buff.len());
107+
108+
for i in 0..data.len() {
109+
nb::block!(<Self as FullDuplex<W>>::write(self, data[i]))?;
110+
buff[i] = nb::block!(<Self as FullDuplex<W>>::read(self))?;
111+
}
112+
113+
Ok(())
114+
}
115+
}
116+
117+
impl<SPI, PINS, W: Copy + 'static> Write<W> for Spi<SPI, PINS, TransferModeNormal>
118+
where
119+
Self: FullDuplex<W, Error = Error>,
120+
SPI: Instance,
121+
{
122+
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
105123
for word in words {
106-
nb::block!(<Self as FullDuplex<u8>>::write(self, *word))?;
107-
nb::block!(self.read())?;
124+
nb::block!(<Self as FullDuplex<W>>::write(self, *word))?;
125+
nb::block!(<Self as FullDuplex<W>>::read(self))?;
108126
}
109127

110128
Ok(())
111129
}
112130
}
113131

114-
impl<SPI, PINS> Write<u8> for Spi<SPI, PINS, TransferModeBidi>
132+
impl<SPI, PINS, W: Copy + 'static> Write<W> for Spi<SPI, PINS, TransferModeBidi>
115133
where
116-
Self: FullDuplex<u8, Error = Error>,
134+
Self: FullDuplex<W, Error = Error>,
117135
SPI: Instance,
118136
{
119-
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
137+
fn write(&mut self, words: &[W]) -> Result<(), Self::Error> {
120138
for word in words {
121-
nb::block!(<Self as FullDuplex<u8>>::write(self, *word))?;
139+
nb::block!(<Self as FullDuplex<W>>::write(self, *word))?;
122140
}
123141

124142
Ok(())
125143
}
126144
}
127145

128-
impl<SPI, PINS> WriteIter<u8> for Spi<SPI, PINS, TransferModeNormal>
146+
impl<SPI, PINS, W: Copy + 'static> WriteIter<W> for Spi<SPI, PINS, TransferModeNormal>
129147
where
130-
Self: FullDuplex<u8, Error = Error>,
148+
Self: FullDuplex<W, Error = Error>,
131149
SPI: Instance,
132150
{
133151
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
134152
where
135-
WI: IntoIterator<Item = u8>,
153+
WI: IntoIterator<Item = W>,
136154
{
137155
for word in words.into_iter() {
138-
nb::block!(<Self as FullDuplex<u8>>::write(self, word))?;
139-
nb::block!(self.read())?;
156+
nb::block!(<Self as FullDuplex<W>>::write(self, word))?;
157+
nb::block!(<Self as FullDuplex<W>>::read(self))?;
140158
}
141159

142160
Ok(())
143161
}
144162
}
145163

146-
impl<SPI, PINS> WriteIter<u8> for Spi<SPI, PINS, TransferModeBidi>
164+
impl<SPI, PINS, W: Copy + 'static> WriteIter<W> for Spi<SPI, PINS, TransferModeBidi>
147165
where
148-
Self: FullDuplex<u8, Error = Error>,
166+
Self: FullDuplex<W, Error = Error>,
149167
SPI: Instance,
150168
{
151169
fn write_iter<WI>(&mut self, words: WI) -> Result<(), Self::Error>
152170
where
153-
WI: IntoIterator<Item = u8>,
171+
WI: IntoIterator<Item = W>,
154172
{
155173
for word in words.into_iter() {
156-
nb::block!(<Self as FullDuplex<u8>>::write(self, word))?;
174+
nb::block!(<Self as FullDuplex<W>>::write(self, word))?;
175+
}
176+
177+
Ok(())
178+
}
179+
}
180+
181+
impl<SPI, PINS, TRANSFER_MODE, W: Copy + Default + 'static> Read<W>
182+
for Spi<SPI, PINS, TRANSFER_MODE>
183+
where
184+
Self: FullDuplex<W, Error = Error>,
185+
SPI: Instance,
186+
{
187+
fn read(&mut self, words: &mut [W]) -> Result<(), Self::Error> {
188+
for word in words {
189+
nb::block!(<Self as FullDuplex<W>>::write(self, W::default()))?;
190+
*word = nb::block!(<Self as FullDuplex<W>>::read(self))?;
157191
}
158192

159193
Ok(())
@@ -162,14 +196,18 @@ mod blocking {
162196

163197
impl<SPI, PINS, TRANSFER_MODE, W: Copy + 'static> Transactional<W> for Spi<SPI, PINS, TRANSFER_MODE>
164198
where
165-
Self: Write<W, Error = Error> + TransferInplace<W, Error = Error>,
199+
Self: Write<W, Error = Error>
200+
+ Read<W, Error = Error>
201+
+ TransferInplace<W, Error = Error>
202+
+ Transfer<W, Error = Error>,
166203
{
167204
fn exec<'a>(&mut self, operations: &mut [Operation<'a, W>]) -> Result<(), Error> {
168205
for op in operations {
169206
match op {
170207
Operation::Write(w) => self.write(w)?,
171208
Operation::TransferInplace(t) => self.transfer_inplace(t)?,
172-
_ => todo!(),
209+
Operation::Read(r) => self.read(r)?,
210+
Operation::Transfer(w, r) => self.transfer(w, r)?,
173211
}
174212
}
175213

0 commit comments

Comments
 (0)