Skip to content

Commit 087043e

Browse files
committed
support u16 frame size
1 parent a9a34a9 commit 087043e

File tree

4 files changed

+151
-87
lines changed

4 files changed

+151
-87
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Changed
1111

12+
- Support `u16` read/write for SPI
1213
- Use `bool` for BIDI mode type
1314
- `PwmHz::get_period`: fix computation of return value, prevent division by zero
1415
- apply #[inline] attribute to bitbanding functions [#517]

src/spi.rs

Lines changed: 82 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,23 @@ impl Ms for Master {
131131
const MSTR: bool = true;
132132
}
133133

134+
pub trait FrameSize: Copy + Default {
135+
const DFF: bool;
136+
}
137+
138+
impl FrameSize for u8 {
139+
const DFF: bool = false;
140+
}
141+
142+
impl FrameSize for u16 {
143+
const DFF: bool = true;
144+
}
145+
134146
#[derive(Debug)]
135-
pub struct Spi<SPI, PINS, const BIDI: bool = false, FrameSize = u8, OPERATION = Master> {
147+
pub struct Spi<SPI, PINS, const BIDI: bool = false, W = u8, OPERATION = Master> {
136148
spi: SPI,
137149
pins: PINS,
138-
_operation: PhantomData<(FrameSize, OPERATION)>,
150+
_operation: PhantomData<(W, OPERATION)>,
139151
}
140152

141153
// Implemented by all SPI instances
@@ -149,8 +161,8 @@ pub trait Instance:
149161
// Implemented by all SPI instances
150162
macro_rules! spi {
151163
($SPI:ty: $Spi:ident) => {
152-
pub type $Spi<PINS, const BIDI: bool = false, FrameSize = u8, OPERATION = Master> =
153-
Spi<$SPI, PINS, BIDI, FrameSize, OPERATION>;
164+
pub type $Spi<PINS, const BIDI: bool = false, W = u8, OPERATION = Master> =
165+
Spi<$SPI, PINS, BIDI, W, OPERATION>;
154166

155167
impl Instance for $SPI {
156168
fn ptr() -> *const spi1::RegisterBlock {
@@ -182,7 +194,7 @@ pub trait SpiExt: Sized + Instance {
182194
mode: impl Into<Mode>,
183195
freq: Hertz,
184196
clocks: &Clocks,
185-
) -> Spi<Self, (SCK, MISO, MOSI), false, Master>
197+
) -> Spi<Self, (SCK, MISO, MOSI), false, u8, Master>
186198
where
187199
(SCK, MISO, MOSI): Pins<Self>;
188200
fn spi_bidi<SCK, MISO, MOSI>(
@@ -191,7 +203,7 @@ pub trait SpiExt: Sized + Instance {
191203
mode: impl Into<Mode>,
192204
freq: Hertz,
193205
clocks: &Clocks,
194-
) -> Spi<Self, (SCK, MISO, MOSI), true, Master>
206+
) -> Spi<Self, (SCK, MISO, MOSI), true, u8, Master>
195207
where
196208
(SCK, MISO, MOSI): Pins<Self>;
197209
fn spi_slave<SCK, MISO, MOSI>(
@@ -200,7 +212,7 @@ pub trait SpiExt: Sized + Instance {
200212
mode: impl Into<Mode>,
201213
freq: Hertz,
202214
clocks: &Clocks,
203-
) -> Spi<Self, (SCK, MISO, MOSI), false, Slave>
215+
) -> Spi<Self, (SCK, MISO, MOSI), false, u8, Slave>
204216
where
205217
(SCK, MISO, MOSI): Pins<Self>;
206218
fn spi_bidi_slave<SCK, MISO, MOSI>(
@@ -209,7 +221,7 @@ pub trait SpiExt: Sized + Instance {
209221
mode: impl Into<Mode>,
210222
freq: Hertz,
211223
clocks: &Clocks,
212-
) -> Spi<Self, (SCK, MISO, MOSI), true, Slave>
224+
) -> Spi<Self, (SCK, MISO, MOSI), true, u8, Slave>
213225
where
214226
(SCK, MISO, MOSI): Pins<Self>;
215227
}
@@ -221,7 +233,7 @@ impl<SPI: Instance> SpiExt for SPI {
221233
mode: impl Into<Mode>,
222234
freq: Hertz,
223235
clocks: &Clocks,
224-
) -> Spi<Self, (SCK, MISO, MOSI), false, Master>
236+
) -> Spi<Self, (SCK, MISO, MOSI), false, u8, Master>
225237
where
226238
(SCK, MISO, MOSI): Pins<Self>,
227239
{
@@ -233,7 +245,7 @@ impl<SPI: Instance> SpiExt for SPI {
233245
mode: impl Into<Mode>,
234246
freq: Hertz,
235247
clocks: &Clocks,
236-
) -> Spi<Self, (SCK, MISO, MOSI), true, Master>
248+
) -> Spi<Self, (SCK, MISO, MOSI), true, u8, Master>
237249
where
238250
(SCK, MISO, MOSI): Pins<Self>,
239251
{
@@ -245,7 +257,7 @@ impl<SPI: Instance> SpiExt for SPI {
245257
mode: impl Into<Mode>,
246258
freq: Hertz,
247259
clocks: &Clocks,
248-
) -> Spi<Self, (SCK, MISO, MOSI), false, Slave>
260+
) -> Spi<Self, (SCK, MISO, MOSI), false, u8, Slave>
249261
where
250262
(SCK, MISO, MOSI): Pins<Self>,
251263
{
@@ -257,22 +269,26 @@ impl<SPI: Instance> SpiExt for SPI {
257269
mode: impl Into<Mode>,
258270
freq: Hertz,
259271
clocks: &Clocks,
260-
) -> Spi<Self, (SCK, MISO, MOSI), true, Slave>
272+
) -> Spi<Self, (SCK, MISO, MOSI), true, u8, Slave>
261273
where
262274
(SCK, MISO, MOSI): Pins<Self>,
263275
{
264276
Spi::new_bidi_slave(self, pins, mode, freq, clocks)
265277
}
266278
}
267279

268-
impl<SPI: Instance, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI, OPERATION> {
280+
impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize, OPERATION: Ms>
281+
Spi<SPI, PINS, BIDI, W, OPERATION>
282+
{
269283
pub fn init(self) -> Self {
270284
self.spi.cr1.modify(|_, w| {
271285
// bidimode: 2-line or 1-line unidirectional
272286
w.bidimode().bit(BIDI);
273287
w.bidioe().bit(BIDI);
274288
// master/slave mode
275289
w.mstr().bit(OPERATION::MSTR);
290+
// data frame size
291+
w.dff().bit(W::DFF);
276292
// spe: enable the SPI bus
277293
w.spe().set_bit()
278294
});
@@ -281,59 +297,51 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI,
281297
}
282298
}
283299

284-
impl<SPI: Instance, PINS, FrameSize, OPERATION: Ms> Spi<SPI, PINS, false, OPERATION> {
285-
pub fn to_bidi_transfer_mode(self) -> Spi<SPI, PINS, true, OPERATION> {
300+
impl<SPI: Instance, PINS, W: FrameSize, OPERATION: Ms> Spi<SPI, PINS, false, W, OPERATION> {
301+
pub fn to_bidi_transfer_mode(self) -> Spi<SPI, PINS, true, W, OPERATION> {
286302
self.into_mode()
287303
}
288304
}
289305

290-
impl<SPI: Instance, PINS, FrameSize, OPERATION: Ms> Spi<SPI, PINS, true, OPERATION> {
291-
pub fn to_normal_transfer_mode(self) -> Spi<SPI, PINS, false, OPERATION> {
306+
impl<SPI: Instance, PINS, W: FrameSize, OPERATION: Ms> Spi<SPI, PINS, true, W, OPERATION> {
307+
pub fn to_normal_transfer_mode(self) -> Spi<SPI, PINS, false, W, OPERATION> {
292308
self.into_mode()
293309
}
294310
}
295311

296-
impl<SPI: Instance, PINS, const BIDI: bool, FrameSize> Spi<SPI, PINS, BIDI, FrameSize, Master> {
297-
pub fn to_slave_operation(self) -> Spi<SPI, PINS, BIDI, Slave> {
312+
impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize> Spi<SPI, PINS, BIDI, W, Master> {
313+
pub fn to_slave_operation(self) -> Spi<SPI, PINS, BIDI, W, Slave> {
298314
self.into_mode()
299315
}
300316
}
301317

302-
impl<SPI: Instance, PINS, const BIDI: bool, FrameSize> Spi<SPI, PINS, BIDI, FrameSize, Slave> {
303-
pub fn to_master_operation(self) -> Spi<SPI, PINS, BIDI, Master> {
318+
impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize> Spi<SPI, PINS, BIDI, W, Slave> {
319+
pub fn to_master_operation(self) -> Spi<SPI, PINS, BIDI, W, Master> {
304320
self.into_mode()
305321
}
306322
}
307323

308-
impl<SPI, REMAP, PINS, const BIDI: bool, OPERATION> Spi<SPI, REMAP, PINS, u8, OPERATION>
324+
impl<SPI, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI, u8, OPERATION>
309325
where
310326
SPI: Instance,
311327
{
312328
/// Converts from 8bit dataframe to 16bit.
313-
pub fn frame_size_16bit(self) -> Spi<SPI, REMAP, PINS, u16> {
314-
self.spi.cr1.modify(|_, w| w.spe().clear_bit());
315-
self.spi
316-
.cr1
317-
.modify(|_, w| w.dff().set_bit().spe().set_bit());
318-
Spi::_new(spi, pins)
329+
pub fn frame_size_16bit(self) -> Spi<SPI, PINS, BIDI, u16, OPERATION> {
330+
self.into_mode()
319331
}
320332
}
321333

322-
impl<SPI, REMAP, PINS, const BIDI: bool, OPERATION> Spi<SPI, REMAP, PINS, u16, OPERATION>
334+
impl<SPI, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI, u16, OPERATION>
323335
where
324336
SPI: Instance,
325337
{
326338
/// Converts from 16bit dataframe to 8bit.
327-
pub fn frame_size_8bit(self) -> Spi<SPI, REMAP, PINS, u8> {
328-
self.spi.cr1.modify(|_, w| w.spe().clear_bit());
329-
self.spi
330-
.cr1
331-
.modify(|_, w| w.dff().clear_bit().spe().set_bit());
332-
Spi::_new(spi, pins)
339+
pub fn frame_size_8bit(self) -> Spi<SPI, PINS, BIDI, u8, OPERATION> {
340+
self.into_mode()
333341
}
334342
}
335343

336-
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Master> {
344+
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, u8, Master> {
337345
pub fn new(
338346
spi: SPI,
339347
mut pins: (SCK, MISO, MOSI),
@@ -359,7 +367,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Master>
359367
}
360368
}
361369

362-
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Master> {
370+
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, u8, Master> {
363371
pub fn new_bidi(
364372
spi: SPI,
365373
mut pins: (SCK, MISO, MOSI),
@@ -385,7 +393,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Master> {
385393
}
386394
}
387395

388-
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Slave> {
396+
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, u8, Slave> {
389397
pub fn new_slave(
390398
spi: SPI,
391399
mut pins: (SCK, MISO, MOSI),
@@ -411,7 +419,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Slave> {
411419
}
412420
}
413421

414-
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Slave> {
422+
impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, u8, Slave> {
415423
pub fn new_bidi_slave(
416424
spi: SPI,
417425
mut pins: (SCK, MISO, MOSI),
@@ -449,7 +457,7 @@ where
449457
}
450458
}
451459

452-
impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPERATION> {
460+
impl<SPI: Instance, PINS, const BIDI: bool, W, OPERATION> Spi<SPI, PINS, BIDI, W, OPERATION> {
453461
fn _new(spi: SPI, pins: PINS) -> Self {
454462
Self {
455463
spi,
@@ -459,7 +467,9 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
459467
}
460468

461469
/// Convert the spi to another mode.
462-
fn into_mode<const BIDI2: bool, OPERATION2: Ms>(self) -> Spi<SPI, PINS, BIDI2, OPERATION2> {
470+
fn into_mode<const BIDI2: bool, W2: FrameSize, OPERATION2: Ms>(
471+
self,
472+
) -> Spi<SPI, PINS, BIDI2, W2, OPERATION2> {
463473
let mut spi = Spi::_new(self.spi, self.pins);
464474
spi.enable(false);
465475
spi.init()
@@ -578,13 +588,36 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
578588
pub fn is_overrun(&self) -> bool {
579589
self.spi.sr.read().ovr().bit_is_set()
580590
}
591+
}
581592

582-
pub fn use_dma(self) -> DmaBuilder<SPI> {
583-
DmaBuilder { spi: self.spi }
593+
trait ReadWriteReg<W> {
594+
fn read_data_reg(&mut self) -> W;
595+
fn write_data_reg(&mut self, data: W);
596+
}
597+
598+
impl<SPI, PINS, const BIDI: bool, W, OPERATION> ReadWriteReg<W>
599+
for Spi<SPI, PINS, BIDI, W, OPERATION>
600+
where
601+
SPI: Instance,
602+
W: FrameSize,
603+
{
604+
fn read_data_reg(&mut self) -> W {
605+
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
606+
// reading a half-word)
607+
unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const W) }
584608
}
585609

610+
fn write_data_reg(&mut self, data: W) {
611+
// NOTE(write_volatile) see note above
612+
unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut W, data) }
613+
}
614+
}
615+
616+
impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize, OPERATION>
617+
Spi<SPI, PINS, BIDI, W, OPERATION>
618+
{
586619
#[inline(always)]
587-
fn check_read(&mut self) -> nb::Result<FrameSize, Error> {
620+
fn check_read(&mut self) -> nb::Result<W, Error> {
588621
let sr = self.spi.sr.read();
589622

590623
Err(if sr.ovr().bit_is_set() {
@@ -601,7 +634,7 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
601634
}
602635

603636
#[inline(always)]
604-
fn check_send(&mut self, byte: FrameSize) -> nb::Result<(), Error> {
637+
fn check_send(&mut self, byte: W) -> nb::Result<(), Error> {
605638
let sr = self.spi.sr.read();
606639

607640
Err(if sr.ovr().bit_is_set() {
@@ -628,26 +661,11 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
628661
}
629662
}
630663

631-
pub trait ReadWriteReg<T> {
632-
fn read_data_reg(&mut self) -> T;
633-
fn write_data_reg(&mut self, data: T);
634-
}
635-
636-
impl<SPI, REMAP, PINS, const BIDI: bool, OPERATION, FrameSize> SpiReadWrite<FrameSize>
637-
for Spi<SPI, REMAP, PINS, FrameSize, OPERATION>
638-
where
639-
SPI: Instance,
640-
FrameSize: Copy,
641-
{
642-
fn read_data_reg(&mut self) -> FrameSize {
643-
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
644-
// reading a half-word)
645-
unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const FrameSize) }
646-
}
664+
// Spi DMA
647665

648-
fn write_data_reg(&mut self, data: FrameSize) {
649-
// NOTE(write_volatile) see note above
650-
unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut FrameSize, data) }
666+
impl<SPI: Instance, PINS, const BIDI: bool> Spi<SPI, PINS, BIDI, u8, Master> {
667+
pub fn use_dma(self) -> DmaBuilder<SPI> {
668+
DmaBuilder { spi: self.spi }
651669
}
652670
}
653671

0 commit comments

Comments
 (0)