Skip to content

Commit ecefa90

Browse files
committed
support u16 frame size
1 parent aa10e6f commit ecefa90

File tree

4 files changed

+168
-65
lines changed

4 files changed

+168
-65
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: 99 additions & 42 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, 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<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, OPERATION = Master> =
153-
Spi<$SPI, PINS, BIDI, 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,31 +297,51 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI,
281297
}
282298
}
283299

284-
impl<SPI: Instance, PINS, 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> {
302+
self.into_mode()
303+
}
304+
}
305+
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> {
286308
self.into_mode()
287309
}
288310
}
289311

290-
impl<SPI: Instance, PINS, OPERATION: Ms> Spi<SPI, PINS, true, OPERATION> {
291-
pub fn to_normal_transfer_mode(self) -> Spi<SPI, PINS, false, OPERATION> {
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> {
292314
self.into_mode()
293315
}
294316
}
295317

296-
impl<SPI: Instance, PINS, const BIDI: bool> Spi<SPI, PINS, BIDI, Master> {
297-
pub fn to_slave_operation(self) -> Spi<SPI, PINS, BIDI, Slave> {
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> {
298320
self.into_mode()
299321
}
300322
}
301323

302-
impl<SPI: Instance, PINS, const BIDI: bool> Spi<SPI, PINS, BIDI, Slave> {
303-
pub fn to_master_operation(self) -> Spi<SPI, PINS, BIDI, Master> {
324+
impl<SPI, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI, u8, OPERATION>
325+
where
326+
SPI: Instance,
327+
{
328+
/// Converts from 8bit dataframe to 16bit.
329+
pub fn frame_size_16bit(self) -> Spi<SPI, PINS, BIDI, u16, OPERATION> {
330+
self.into_mode()
331+
}
332+
}
333+
334+
impl<SPI, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI, u16, OPERATION>
335+
where
336+
SPI: Instance,
337+
{
338+
/// Converts from 16bit dataframe to 8bit.
339+
pub fn frame_size_8bit(self) -> Spi<SPI, PINS, BIDI, u8, OPERATION> {
304340
self.into_mode()
305341
}
306342
}
307343

308-
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> {
309345
pub fn new(
310346
spi: SPI,
311347
mut pins: (SCK, MISO, MOSI),
@@ -331,7 +367,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Master>
331367
}
332368
}
333369

334-
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> {
335371
pub fn new_bidi(
336372
spi: SPI,
337373
mut pins: (SCK, MISO, MOSI),
@@ -357,7 +393,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Master> {
357393
}
358394
}
359395

360-
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> {
361397
pub fn new_slave(
362398
spi: SPI,
363399
mut pins: (SCK, MISO, MOSI),
@@ -383,7 +419,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Slave> {
383419
}
384420
}
385421

386-
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> {
387423
pub fn new_bidi_slave(
388424
spi: SPI,
389425
mut pins: (SCK, MISO, MOSI),
@@ -421,7 +457,7 @@ where
421457
}
422458
}
423459

424-
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> {
425461
fn _new(spi: SPI, pins: PINS) -> Self {
426462
Self {
427463
spi,
@@ -431,7 +467,9 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
431467
}
432468

433469
/// Convert the spi to another mode.
434-
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> {
435473
let mut spi = Spi::_new(self.spi, self.pins);
436474
spi.enable(false);
437475
spi.init()
@@ -550,13 +588,36 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
550588
pub fn is_overrun(&self) -> bool {
551589
self.spi.sr.read().ovr().bit_is_set()
552590
}
591+
}
553592

554-
pub fn use_dma(self) -> DmaBuilder<SPI> {
555-
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) }
556608
}
557609

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+
{
558619
#[inline(always)]
559-
fn check_read(&mut self) -> nb::Result<u8, Error> {
620+
fn check_read(&mut self) -> nb::Result<W, Error> {
560621
let sr = self.spi.sr.read();
561622

562623
Err(if sr.ovr().bit_is_set() {
@@ -566,14 +627,14 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
566627
} else if sr.crcerr().bit_is_set() {
567628
Error::Crc.into()
568629
} else if sr.rxne().bit_is_set() {
569-
return Ok(self.read_u8());
630+
return Ok(self.read_data_reg());
570631
} else {
571632
nb::Error::WouldBlock
572633
})
573634
}
574635

575636
#[inline(always)]
576-
fn check_send(&mut self, byte: u8) -> nb::Result<(), Error> {
637+
fn check_send(&mut self, byte: W) -> nb::Result<(), Error> {
577638
let sr = self.spi.sr.read();
578639

579640
Err(if sr.ovr().bit_is_set() {
@@ -592,23 +653,19 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
592653
});
593654
Error::Crc.into()
594655
} else if sr.txe().bit_is_set() {
595-
self.send_u8(byte);
656+
self.write_data_reg(byte);
596657
return Ok(());
597658
} else {
598659
nb::Error::WouldBlock
599660
})
600661
}
662+
}
601663

602-
#[inline(always)]
603-
fn read_u8(&mut self) -> u8 {
604-
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows reading a half-word)
605-
unsafe { ptr::read_volatile(&self.spi.dr as *const _ as *const u8) }
606-
}
664+
// Spi DMA
607665

608-
#[inline(always)]
609-
fn send_u8(&mut self, byte: u8) {
610-
// NOTE(write_volatile) see note above
611-
unsafe { ptr::write_volatile(&self.spi.dr as *const _ as *mut u8, byte) }
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 }
612669
}
613670
}
614671

0 commit comments

Comments
 (0)