aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-12-07 04:45:14 +0000
committerGitHub <[email protected]>2021-12-07 04:45:14 +0000
commit2e6c3b22b887f5fc377b1549c1a36cf24ac4acf8 (patch)
tree949a05f9ba37d8974973c67a2a1a42f38b483dbb
parent15a324a42a581fe1b38a7c439b87f36e19296d77 (diff)
parent7c78247be32007686d0d253b8ec14fb6806b2452 (diff)
Merge #518
518: Incrementally merge STM32 SPI versions, Part 1 r=Dirbaio a=GrantM11235 Co-authored-by: Grant Miller <[email protected]>
-rw-r--r--embassy-stm32/src/spi/mod.rs354
-rw-r--r--embassy-stm32/src/spi/v1.rs191
-rw-r--r--embassy-stm32/src/spi/v2.rs189
-rw-r--r--embassy-stm32/src/spi/v3.rs219
4 files changed, 398 insertions, 555 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index e881a5235..80a05aac6 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -1,15 +1,23 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma;
4use crate::gpio::sealed::{AFType, Pin};
5use crate::gpio::{AnyPin, NoPin, OptionalPin};
6use crate::pac::spi::vals;
7use crate::peripherals;
8use crate::rcc::RccPeripheral;
9use crate::time::Hertz;
10use core::marker::PhantomData;
11use embassy::util::Unborrow;
12use embassy_hal_common::unborrow;
13
3#[cfg_attr(spi_v1, path = "v1.rs")] 14#[cfg_attr(spi_v1, path = "v1.rs")]
4#[cfg_attr(spi_f1, path = "v1.rs")] 15#[cfg_attr(spi_f1, path = "v1.rs")]
5#[cfg_attr(spi_v2, path = "v2.rs")] 16#[cfg_attr(spi_v2, path = "v2.rs")]
6#[cfg_attr(spi_v3, path = "v3.rs")] 17#[cfg_attr(spi_v3, path = "v3.rs")]
7mod _version; 18mod _version;
8use crate::{dma, peripherals, rcc::RccPeripheral};
9pub use _version::*; 19pub use _version::*;
10 20
11use crate::gpio::OptionalPin;
12
13#[derive(Debug)] 21#[derive(Debug)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))] 22#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum Error { 23pub enum Error {
@@ -31,6 +39,48 @@ enum WordSize {
31 SixteenBit, 39 SixteenBit,
32} 40}
33 41
42impl WordSize {
43 #[cfg(any(spi_v1, spi_f1))]
44 fn dff(&self) -> vals::Dff {
45 match self {
46 WordSize::EightBit => vals::Dff::EIGHTBIT,
47 WordSize::SixteenBit => vals::Dff::SIXTEENBIT,
48 }
49 }
50
51 #[cfg(spi_v2)]
52 fn ds(&self) -> vals::Ds {
53 match self {
54 WordSize::EightBit => vals::Ds::EIGHTBIT,
55 WordSize::SixteenBit => vals::Ds::SIXTEENBIT,
56 }
57 }
58
59 #[cfg(spi_v2)]
60 fn frxth(&self) -> vals::Frxth {
61 match self {
62 WordSize::EightBit => vals::Frxth::QUARTER,
63 WordSize::SixteenBit => vals::Frxth::HALF,
64 }
65 }
66
67 #[cfg(spi_v3)]
68 fn dsize(&self) -> u8 {
69 match self {
70 WordSize::EightBit => 0b0111,
71 WordSize::SixteenBit => 0b1111,
72 }
73 }
74
75 #[cfg(spi_v3)]
76 fn _frxth(&self) -> vals::Fthlv {
77 match self {
78 WordSize::EightBit => vals::Fthlv::ONEFRAME,
79 WordSize::SixteenBit => vals::Fthlv::ONEFRAME,
80 }
81 }
82}
83
34#[non_exhaustive] 84#[non_exhaustive]
35pub struct Config { 85pub struct Config {
36 pub mode: Mode, 86 pub mode: Mode,
@@ -46,6 +96,284 @@ impl Default for Config {
46 } 96 }
47} 97}
48 98
99pub struct Spi<'d, T: Instance, Tx, Rx> {
100 sck: Option<AnyPin>,
101 mosi: Option<AnyPin>,
102 miso: Option<AnyPin>,
103 txdma: Tx,
104 rxdma: Rx,
105 current_word_size: WordSize,
106 phantom: PhantomData<&'d mut T>,
107}
108
109impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
110 pub fn new<F>(
111 _peri: impl Unborrow<Target = T> + 'd,
112 sck: impl Unborrow<Target = impl SckPin<T>>,
113 mosi: impl Unborrow<Target = impl MosiPin<T>>,
114 miso: impl Unborrow<Target = impl MisoPin<T>>,
115 txdma: impl Unborrow<Target = Tx>,
116 rxdma: impl Unborrow<Target = Rx>,
117 freq: F,
118 config: Config,
119 ) -> Self
120 where
121 F: Into<Hertz>,
122 {
123 unborrow!(sck, mosi, miso, txdma, rxdma);
124
125 let sck_af = sck.af_num();
126 let mosi_af = mosi.af_num();
127 let miso_af = miso.af_num();
128 let sck = sck.degrade_optional();
129 let mosi = mosi.degrade_optional();
130 let miso = miso.degrade_optional();
131
132 unsafe {
133 sck.as_ref().map(|x| {
134 x.set_as_af(sck_af, AFType::OutputPushPull);
135 #[cfg(any(spi_v2, spi_v3))]
136 x.set_speed(crate::gpio::Speed::VeryHigh);
137 });
138 mosi.as_ref().map(|x| {
139 x.set_as_af(mosi_af, AFType::OutputPushPull);
140 #[cfg(any(spi_v2, spi_v3))]
141 x.set_speed(crate::gpio::Speed::VeryHigh);
142 });
143 miso.as_ref().map(|x| {
144 x.set_as_af(miso_af, AFType::Input);
145 #[cfg(any(spi_v2, spi_v3))]
146 x.set_speed(crate::gpio::Speed::VeryHigh);
147 });
148 }
149
150 let pclk = T::frequency();
151 let br = Self::compute_baud_rate(pclk, freq.into());
152
153 #[cfg(any(spi_v1, spi_f1))]
154 unsafe {
155 T::enable();
156 T::reset();
157 T::regs().cr2().modify(|w| {
158 w.set_ssoe(false);
159 });
160 T::regs().cr1().modify(|w| {
161 w.set_cpha(
162 match config.mode.phase == Phase::CaptureOnSecondTransition {
163 true => vals::Cpha::SECONDEDGE,
164 false => vals::Cpha::FIRSTEDGE,
165 },
166 );
167 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
168 true => vals::Cpol::IDLEHIGH,
169 false => vals::Cpol::IDLELOW,
170 });
171
172 w.set_mstr(vals::Mstr::MASTER);
173 w.set_br(vals::Br(br));
174 w.set_spe(true);
175 w.set_lsbfirst(match config.byte_order {
176 ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
177 ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
178 });
179 w.set_ssi(true);
180 w.set_ssm(true);
181 w.set_crcen(false);
182 w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL);
183 if mosi.is_none() {
184 w.set_rxonly(vals::Rxonly::OUTPUTDISABLED);
185 }
186 w.set_dff(WordSize::EightBit.dff())
187 });
188 }
189 #[cfg(spi_v2)]
190 unsafe {
191 T::enable();
192 T::reset();
193 T::regs().cr2().modify(|w| {
194 w.set_frxth(WordSize::EightBit.frxth());
195 w.set_ds(WordSize::EightBit.ds());
196 w.set_ssoe(false);
197 });
198 T::regs().cr1().modify(|w| {
199 w.set_cpha(
200 match config.mode.phase == Phase::CaptureOnSecondTransition {
201 true => vals::Cpha::SECONDEDGE,
202 false => vals::Cpha::FIRSTEDGE,
203 },
204 );
205 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
206 true => vals::Cpol::IDLEHIGH,
207 false => vals::Cpol::IDLELOW,
208 });
209
210 w.set_mstr(vals::Mstr::MASTER);
211 w.set_br(vals::Br(br));
212 w.set_lsbfirst(match config.byte_order {
213 ByteOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
214 ByteOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
215 });
216 w.set_ssi(true);
217 w.set_ssm(true);
218 w.set_crcen(false);
219 w.set_bidimode(vals::Bidimode::UNIDIRECTIONAL);
220 w.set_spe(true);
221 });
222 }
223 #[cfg(spi_v3)]
224 unsafe {
225 T::enable();
226 T::reset();
227 T::regs().ifcr().write(|w| w.0 = 0xffff_ffff);
228 T::regs().cfg2().modify(|w| {
229 //w.set_ssoe(true);
230 w.set_ssoe(false);
231 w.set_cpha(
232 match config.mode.phase == Phase::CaptureOnSecondTransition {
233 true => vals::Cpha::SECONDEDGE,
234 false => vals::Cpha::FIRSTEDGE,
235 },
236 );
237 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
238 true => vals::Cpol::IDLEHIGH,
239 false => vals::Cpol::IDLELOW,
240 });
241 w.set_lsbfrst(match config.byte_order {
242 ByteOrder::LsbFirst => vals::Lsbfrst::LSBFIRST,
243 ByteOrder::MsbFirst => vals::Lsbfrst::MSBFIRST,
244 });
245 w.set_ssm(true);
246 w.set_master(vals::Master::MASTER);
247 w.set_comm(vals::Comm::FULLDUPLEX);
248 w.set_ssom(vals::Ssom::ASSERTED);
249 w.set_midi(0);
250 w.set_mssi(0);
251 w.set_afcntr(vals::Afcntr::CONTROLLED);
252 w.set_ssiop(vals::Ssiop::ACTIVEHIGH);
253 });
254 T::regs().cfg1().modify(|w| {
255 w.set_crcen(false);
256 w.set_mbr(vals::Mbr(br));
257 w.set_dsize(WordSize::EightBit.dsize());
258 });
259 T::regs().cr2().modify(|w| {
260 w.set_tsize(0);
261 w.set_tser(0);
262 });
263 T::regs().cr1().modify(|w| {
264 w.set_ssi(false);
265 w.set_spe(true);
266 });
267 }
268
269 Self {
270 sck,
271 mosi,
272 miso,
273 txdma,
274 rxdma,
275 current_word_size: WordSize::EightBit,
276 phantom: PhantomData,
277 }
278 }
279
280 fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 {
281 match clocks.0 / freq.0 {
282 0 => unreachable!(),
283 1..=2 => 0b000,
284 3..=5 => 0b001,
285 6..=11 => 0b010,
286 12..=23 => 0b011,
287 24..=39 => 0b100,
288 40..=95 => 0b101,
289 96..=191 => 0b110,
290 _ => 0b111,
291 }
292 }
293
294 fn set_word_size(&mut self, word_size: WordSize) {
295 if self.current_word_size == word_size {
296 return;
297 }
298
299 #[cfg(any(spi_v1, spi_f1))]
300 unsafe {
301 T::regs().cr1().modify(|reg| {
302 reg.set_spe(false);
303 reg.set_dff(word_size.dff())
304 });
305 T::regs().cr1().modify(|reg| {
306 reg.set_spe(true);
307 });
308 }
309 #[cfg(spi_v2)]
310 unsafe {
311 T::regs().cr1().modify(|w| {
312 w.set_spe(false);
313 });
314 T::regs().cr2().modify(|w| {
315 w.set_frxth(word_size.frxth());
316 w.set_ds(word_size.ds());
317 });
318 T::regs().cr1().modify(|w| {
319 w.set_spe(true);
320 });
321 }
322 #[cfg(spi_v3)]
323 unsafe {
324 T::regs().cr1().modify(|w| {
325 w.set_csusp(true);
326 });
327 while T::regs().sr().read().eot() {}
328 T::regs().cr1().modify(|w| {
329 w.set_spe(false);
330 });
331 T::regs().cfg1().modify(|w| {
332 w.set_dsize(word_size.dsize());
333 });
334 T::regs().cr1().modify(|w| {
335 w.set_csusp(false);
336 w.set_spe(true);
337 });
338 }
339
340 self.current_word_size = word_size;
341 }
342}
343
344impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
345 fn drop(&mut self) {
346 unsafe {
347 self.sck.as_ref().map(|x| x.set_as_analog());
348 self.mosi.as_ref().map(|x| x.set_as_analog());
349 self.miso.as_ref().map(|x| x.set_as_analog());
350 }
351 }
352}
353
354trait RegsExt {
355 fn tx_ptr<W>(&self) -> *mut W;
356 fn rx_ptr<W>(&self) -> *mut W;
357}
358
359impl RegsExt for crate::pac::spi::Spi {
360 fn tx_ptr<W>(&self) -> *mut W {
361 #[cfg(not(spi_v3))]
362 let dr = self.dr();
363 #[cfg(spi_v3)]
364 let dr = self.txdr();
365 dr.ptr() as *mut W
366 }
367
368 fn rx_ptr<W>(&self) -> *mut W {
369 #[cfg(not(spi_v3))]
370 let dr = self.dr();
371 #[cfg(spi_v3)]
372 let dr = self.rxdr();
373 dr.ptr() as *mut W
374 }
375}
376
49pub(crate) mod sealed { 377pub(crate) mod sealed {
50 use super::*; 378 use super::*;
51 379
@@ -135,6 +463,26 @@ crate::pac::peripheral_pins!(
135 }; 463 };
136); 464);
137 465
466macro_rules! impl_nopin {
467 ($inst:ident, $signal:ident) => {
468 impl $signal<peripherals::$inst> for NoPin {}
469
470 impl sealed::$signal<peripherals::$inst> for NoPin {
471 fn af_num(&self) -> u8 {
472 0
473 }
474 }
475 };
476}
477
478crate::pac::peripherals!(
479 (spi, $inst:ident) => {
480 impl_nopin!($inst, SckPin);
481 impl_nopin!($inst, MosiPin);
482 impl_nopin!($inst, MisoPin);
483 };
484);
485
138macro_rules! impl_dma { 486macro_rules! impl_dma {
139 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => { 487 ($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
140 impl<T> sealed::$signal<peripherals::$inst> for T 488 impl<T> sealed::$signal<peripherals::$inst> for T
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
index b727f2008..255bd950a 100644
--- a/embassy-stm32/src/spi/v1.rs
+++ b/embassy-stm32/src/spi/v1.rs
@@ -1,178 +1,17 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::gpio::sealed::AFType; 4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize};
5use crate::gpio::sealed::Pin;
6use crate::gpio::{AnyPin, NoPin};
7use crate::pac::spi;
8use crate::peripherals;
9use crate::spi::{
10 ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
11 WordSize,
12};
13use crate::time::Hertz;
14use core::future::Future; 5use core::future::Future;
15use core::marker::PhantomData;
16use core::ptr; 6use core::ptr;
17use embassy::util::Unborrow;
18use embassy_hal_common::unborrow;
19use embassy_traits::spi as traits; 7use embassy_traits::spi as traits;
20pub use embedded_hal::blocking; 8pub use embedded_hal::blocking;
21pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 9pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
22use futures::future::join3; 10use futures::future::join3;
23 11
24impl WordSize { 12use super::Spi;
25 fn dff(&self) -> spi::vals::Dff {
26 match self {
27 WordSize::EightBit => spi::vals::Dff::EIGHTBIT,
28 WordSize::SixteenBit => spi::vals::Dff::SIXTEENBIT,
29 }
30 }
31}
32
33macro_rules! impl_nopin {
34 ($inst:ident, $signal:ident) => {
35 impl $signal<peripherals::$inst> for NoPin {}
36
37 impl super::sealed::$signal<peripherals::$inst> for NoPin {
38 fn af_num(&self) -> u8 {
39 0
40 }
41 }
42 };
43}
44crate::pac::peripherals!(
45 (spi, $inst:ident) => {
46 impl_nopin!($inst, SckPin);
47 impl_nopin!($inst, MosiPin);
48 impl_nopin!($inst, MisoPin);
49 };
50);
51
52pub struct Spi<'d, T: Instance, Tx, Rx> {
53 sck: Option<AnyPin>,
54 mosi: Option<AnyPin>,
55 miso: Option<AnyPin>,
56 txdma: Tx,
57 rxdma: Rx,
58 current_word_size: WordSize,
59 phantom: PhantomData<&'d mut T>,
60}
61 13
62impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 14impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
63 pub fn new<F>(
64 _peri: impl Unborrow<Target = T> + 'd,
65 sck: impl Unborrow<Target = impl SckPin<T>>,
66 mosi: impl Unborrow<Target = impl MosiPin<T>>,
67 miso: impl Unborrow<Target = impl MisoPin<T>>,
68 txdma: impl Unborrow<Target = Tx>,
69 rxdma: impl Unborrow<Target = Rx>,
70 freq: F,
71 config: Config,
72 ) -> Self
73 where
74 F: Into<Hertz>,
75 {
76 unborrow!(sck, mosi, miso, txdma, rxdma);
77
78 let sck_af = sck.af_num();
79 let mosi_af = mosi.af_num();
80 let miso_af = miso.af_num();
81 let sck = sck.degrade_optional();
82 let mosi = mosi.degrade_optional();
83 let miso = miso.degrade_optional();
84
85 unsafe {
86 sck.as_ref()
87 .map(|x| x.set_as_af(sck_af, AFType::OutputPushPull));
88 mosi.as_ref()
89 .map(|x| x.set_as_af(mosi_af, AFType::OutputPushPull));
90 miso.as_ref().map(|x| x.set_as_af(miso_af, AFType::Input));
91 }
92
93 unsafe {
94 T::regs().cr2().modify(|w| {
95 w.set_ssoe(false);
96 });
97 }
98
99 let pclk = T::frequency();
100 let br = Self::compute_baud_rate(pclk, freq.into());
101
102 unsafe {
103 T::enable();
104 T::reset();
105 T::regs().cr1().modify(|w| {
106 w.set_cpha(
107 match config.mode.phase == Phase::CaptureOnSecondTransition {
108 true => spi::vals::Cpha::SECONDEDGE,
109 false => spi::vals::Cpha::FIRSTEDGE,
110 },
111 );
112 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
113 true => spi::vals::Cpol::IDLEHIGH,
114 false => spi::vals::Cpol::IDLELOW,
115 });
116
117 w.set_mstr(spi::vals::Mstr::MASTER);
118 w.set_br(spi::vals::Br(br));
119 w.set_spe(true);
120 w.set_lsbfirst(match config.byte_order {
121 ByteOrder::LsbFirst => spi::vals::Lsbfirst::LSBFIRST,
122 ByteOrder::MsbFirst => spi::vals::Lsbfirst::MSBFIRST,
123 });
124 w.set_ssi(true);
125 w.set_ssm(true);
126 w.set_crcen(false);
127 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
128 if mosi.is_none() {
129 w.set_rxonly(spi::vals::Rxonly::OUTPUTDISABLED);
130 }
131 w.set_dff(WordSize::EightBit.dff())
132 });
133 }
134
135 Self {
136 sck,
137 mosi,
138 miso,
139 txdma,
140 rxdma,
141 current_word_size: WordSize::EightBit,
142 phantom: PhantomData,
143 }
144 }
145
146 fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 {
147 match clocks.0 / freq.0 {
148 0 => unreachable!(),
149 1..=2 => 0b000,
150 3..=5 => 0b001,
151 6..=11 => 0b010,
152 12..=23 => 0b011,
153 24..=39 => 0b100,
154 40..=95 => 0b101,
155 96..=191 => 0b110,
156 _ => 0b111,
157 }
158 }
159
160 fn set_word_size(&mut self, word_size: WordSize) {
161 if self.current_word_size == word_size {
162 return;
163 }
164 unsafe {
165 T::regs().cr1().modify(|reg| {
166 reg.set_spe(false);
167 reg.set_dff(word_size.dff())
168 });
169 T::regs().cr1().modify(|reg| {
170 reg.set_spe(true);
171 });
172 self.current_word_size = word_size;
173 }
174 }
175
176 #[allow(unused)] 15 #[allow(unused)]
177 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> 16 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error>
178 where 17 where
@@ -186,7 +25,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
186 self.set_word_size(WordSize::EightBit); 25 self.set_word_size(WordSize::EightBit);
187 26
188 let request = self.txdma.request(); 27 let request = self.txdma.request();
189 let dst = T::regs().dr().ptr() as *mut u8; 28 let dst = T::regs().tx_ptr();
190 let f = self.txdma.write(request, write, dst); 29 let f = self.txdma.write(request, write, dst);
191 30
192 unsafe { 31 unsafe {
@@ -221,11 +60,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
221 let clock_byte_count = read.len(); 60 let clock_byte_count = read.len();
222 61
223 let rx_request = self.rxdma.request(); 62 let rx_request = self.rxdma.request();
224 let rx_src = T::regs().dr().ptr() as *mut u8; 63 let rx_src = T::regs().rx_ptr();
225 let rx_f = self.rxdma.read(rx_request, rx_src, read); 64 let rx_f = self.rxdma.read(rx_request, rx_src, read);
226 65
227 let tx_request = self.txdma.request(); 66 let tx_request = self.txdma.request();
228 let tx_dst = T::regs().dr().ptr() as *mut u8; 67 let tx_dst = T::regs().tx_ptr();
229 let clock_byte = 0x00; 68 let clock_byte = 0x00;
230 let tx_f = self 69 let tx_f = self
231 .txdma 70 .txdma
@@ -274,13 +113,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
274 self.set_word_size(WordSize::EightBit); 113 self.set_word_size(WordSize::EightBit);
275 114
276 let rx_request = self.rxdma.request(); 115 let rx_request = self.rxdma.request();
277 let rx_src = T::regs().dr().ptr() as *mut u8; 116 let rx_src = T::regs().rx_ptr();
278 let rx_f = self 117 let rx_f = self
279 .rxdma 118 .rxdma
280 .read(rx_request, rx_src, &mut read[0..write.len()]); 119 .read(rx_request, rx_src, &mut read[0..write.len()]);
281 120
282 let tx_request = self.txdma.request(); 121 let tx_request = self.txdma.request();
283 let tx_dst = T::regs().dr().ptr() as *mut u8; 122 let tx_dst = T::regs().tx_ptr();
284 let tx_f = self.txdma.write(tx_request, write, tx_dst); 123 let tx_f = self.txdma.write(tx_request, write, tx_dst);
285 124
286 unsafe { 125 unsafe {
@@ -316,16 +155,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
316 } 155 }
317} 156}
318 157
319impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
320 fn drop(&mut self) {
321 unsafe {
322 self.sck.as_ref().map(|x| x.set_as_analog());
323 self.mosi.as_ref().map(|x| x.set_as_analog());
324 self.miso.as_ref().map(|x| x.set_as_analog());
325 }
326 }
327}
328
329impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> { 158impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> {
330 type Error = Error; 159 type Error = Error;
331 160
@@ -452,8 +281,7 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
452 } 281 }
453 if sr.txe() { 282 if sr.txe() {
454 unsafe { 283 unsafe {
455 let dr = regs.dr().ptr() as *mut W; 284 ptr::write_volatile(regs.tx_ptr(), word);
456 ptr::write_volatile(dr, word);
457 } 285 }
458 return Ok(()); 286 return Ok(());
459 } 287 }
@@ -479,8 +307,7 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
479 } 307 }
480 if sr.rxne() { 308 if sr.rxne() {
481 unsafe { 309 unsafe {
482 let dr = regs.dr().ptr() as *const W; 310 return Ok(ptr::read_volatile(regs.rx_ptr()));
483 return Ok(ptr::read_volatile(dr));
484 } 311 }
485 } 312 }
486 } 313 }
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
index aa04fcca4..b1fae4bdc 100644
--- a/embassy-stm32/src/spi/v2.rs
+++ b/embassy-stm32/src/spi/v2.rs
@@ -1,161 +1,16 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::gpio::sealed::Pin; 4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize};
5use crate::gpio::AnyPin;
6use crate::pac::spi;
7use crate::spi::{
8 ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
9 WordSize,
10};
11use crate::time::Hertz;
12use core::future::Future; 5use core::future::Future;
13use core::marker::PhantomData;
14use core::ptr; 6use core::ptr;
15use embassy::util::Unborrow;
16use embassy_hal_common::unborrow;
17use embassy_traits::spi as traits; 7use embassy_traits::spi as traits;
18pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 8pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
19use futures::future::{join, join3}; 9use futures::future::{join, join3};
20 10
21impl WordSize { 11use super::Spi;
22 fn ds(&self) -> spi::vals::Ds {
23 match self {
24 WordSize::EightBit => spi::vals::Ds::EIGHTBIT,
25 WordSize::SixteenBit => spi::vals::Ds::SIXTEENBIT,
26 }
27 }
28
29 fn frxth(&self) -> spi::vals::Frxth {
30 match self {
31 WordSize::EightBit => spi::vals::Frxth::QUARTER,
32 WordSize::SixteenBit => spi::vals::Frxth::HALF,
33 }
34 }
35}
36
37pub struct Spi<'d, T: Instance, Tx, Rx> {
38 sck: Option<AnyPin>,
39 mosi: Option<AnyPin>,
40 miso: Option<AnyPin>,
41 txdma: Tx,
42 rxdma: Rx,
43 phantom: PhantomData<&'d mut T>,
44}
45 12
46impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 13impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
47 pub fn new<F>(
48 _peri: impl Unborrow<Target = T> + 'd,
49 sck: impl Unborrow<Target = impl SckPin<T>>,
50 mosi: impl Unborrow<Target = impl MosiPin<T>>,
51 miso: impl Unborrow<Target = impl MisoPin<T>>,
52 txdma: impl Unborrow<Target = Tx>,
53 rxdma: impl Unborrow<Target = Rx>,
54 freq: F,
55 config: Config,
56 ) -> Self
57 where
58 F: Into<Hertz>,
59 {
60 unborrow!(sck, mosi, miso, txdma, rxdma);
61
62 let sck_af = sck.af_num();
63 let mosi_af = mosi.af_num();
64 let miso_af = miso.af_num();
65 let sck = sck.degrade_optional();
66 let mosi = mosi.degrade_optional();
67 let miso = miso.degrade_optional();
68
69 unsafe {
70 sck.as_ref().map(|x| {
71 x.set_as_af(sck_af, crate::gpio::sealed::AFType::OutputPushPull);
72 x.set_speed(crate::gpio::Speed::VeryHigh);
73 });
74 mosi.as_ref().map(|x| {
75 x.set_as_af(mosi_af, crate::gpio::sealed::AFType::OutputPushPull);
76 x.set_speed(crate::gpio::Speed::VeryHigh);
77 });
78 miso.as_ref().map(|x| {
79 x.set_as_af(miso_af, crate::gpio::sealed::AFType::Input);
80 x.set_speed(crate::gpio::Speed::VeryHigh);
81 });
82 }
83
84 let pclk = T::frequency();
85 let freq = freq.into();
86 let br = Self::compute_baud_rate(pclk, freq);
87
88 unsafe {
89 T::enable();
90 T::reset();
91 T::regs().cr2().modify(|w| {
92 w.set_ssoe(false);
93 });
94 T::regs().cr1().modify(|w| {
95 w.set_cpha(
96 match config.mode.phase == Phase::CaptureOnSecondTransition {
97 true => spi::vals::Cpha::SECONDEDGE,
98 false => spi::vals::Cpha::FIRSTEDGE,
99 },
100 );
101 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
102 true => spi::vals::Cpol::IDLEHIGH,
103 false => spi::vals::Cpol::IDLELOW,
104 });
105
106 w.set_mstr(spi::vals::Mstr::MASTER);
107 w.set_br(spi::vals::Br(br));
108 w.set_lsbfirst(match config.byte_order {
109 ByteOrder::LsbFirst => spi::vals::Lsbfirst::LSBFIRST,
110 ByteOrder::MsbFirst => spi::vals::Lsbfirst::MSBFIRST,
111 });
112 w.set_ssi(true);
113 w.set_ssm(true);
114 w.set_crcen(false);
115 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
116 w.set_spe(true);
117 });
118 }
119
120 Self {
121 sck,
122 mosi,
123 miso,
124 txdma,
125 rxdma,
126 phantom: PhantomData,
127 }
128 }
129
130 fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 {
131 match clocks.0 / freq.0 {
132 0 => unreachable!(),
133 1..=2 => 0b000,
134 3..=5 => 0b001,
135 6..=11 => 0b010,
136 12..=23 => 0b011,
137 24..=39 => 0b100,
138 40..=95 => 0b101,
139 96..=191 => 0b110,
140 _ => 0b111,
141 }
142 }
143
144 fn set_word_size(word_size: WordSize) {
145 unsafe {
146 T::regs().cr1().modify(|w| {
147 w.set_spe(false);
148 });
149 T::regs().cr2().modify(|w| {
150 w.set_frxth(word_size.frxth());
151 w.set_ds(word_size.ds());
152 });
153 T::regs().cr1().modify(|w| {
154 w.set_spe(true);
155 });
156 }
157 }
158
159 #[allow(unused)] 14 #[allow(unused)]
160 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> 15 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error>
161 where 16 where
@@ -166,10 +21,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
166 w.set_spe(false); 21 w.set_spe(false);
167 }); 22 });
168 } 23 }
169 Self::set_word_size(WordSize::EightBit); 24 self.set_word_size(WordSize::EightBit);
170 25
171 let request = self.txdma.request(); 26 let request = self.txdma.request();
172 let dst = T::regs().dr().ptr() as *mut u8; 27 let dst = T::regs().tx_ptr();
173 let f = self.txdma.write(request, write, dst); 28 let f = self.txdma.write(request, write, dst);
174 29
175 unsafe { 30 unsafe {
@@ -208,16 +63,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
208 reg.set_rxdmaen(true); 63 reg.set_rxdmaen(true);
209 }); 64 });
210 } 65 }
211 Self::set_word_size(WordSize::EightBit); 66 self.set_word_size(WordSize::EightBit);
212 67
213 let clock_byte_count = read.len(); 68 let clock_byte_count = read.len();
214 69
215 let rx_request = self.rxdma.request(); 70 let rx_request = self.rxdma.request();
216 let rx_src = T::regs().dr().ptr() as *mut u8; 71 let rx_src = T::regs().rx_ptr();
217 let rx_f = self.rxdma.read(rx_request, rx_src, read); 72 let rx_f = self.rxdma.read(rx_request, rx_src, read);
218 73
219 let tx_request = self.txdma.request(); 74 let tx_request = self.txdma.request();
220 let tx_dst = T::regs().dr().ptr() as *mut u8; 75 let tx_dst = T::regs().tx_ptr();
221 let clock_byte = 0x00; 76 let clock_byte = 0x00;
222 let tx_f = self 77 let tx_f = self
223 .txdma 78 .txdma
@@ -268,16 +123,16 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
268 let _ = T::regs().dr().read(); 123 let _ = T::regs().dr().read();
269 } 124 }
270 } 125 }
271 Self::set_word_size(WordSize::EightBit); 126 self.set_word_size(WordSize::EightBit);
272 127
273 let rx_request = self.rxdma.request(); 128 let rx_request = self.rxdma.request();
274 let rx_src = T::regs().dr().ptr() as *mut u8; 129 let rx_src = T::regs().rx_ptr();
275 let rx_f = self 130 let rx_f = self
276 .rxdma 131 .rxdma
277 .read(rx_request, rx_src, &mut read[0..write.len()]); 132 .read(rx_request, rx_src, &mut read[0..write.len()]);
278 133
279 let tx_request = self.txdma.request(); 134 let tx_request = self.txdma.request();
280 let tx_dst = T::regs().dr().ptr() as *mut u8; 135 let tx_dst = T::regs().tx_ptr();
281 let tx_f = self.txdma.write(tx_request, write, tx_dst); 136 let tx_f = self.txdma.write(tx_request, write, tx_dst);
282 137
283 unsafe { 138 unsafe {
@@ -319,16 +174,6 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
319 } 174 }
320} 175}
321 176
322impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
323 fn drop(&mut self) {
324 unsafe {
325 self.sck.as_ref().map(|x| x.set_as_analog());
326 self.mosi.as_ref().map(|x| x.set_as_analog());
327 self.miso.as_ref().map(|x| x.set_as_analog());
328 }
329 }
330}
331
332trait Word {} 177trait Word {}
333 178
334impl Word for u8 {} 179impl Word for u8 {}
@@ -348,8 +193,7 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
348 return Err(Error::Crc); 193 return Err(Error::Crc);
349 } else if sr.txe() { 194 } else if sr.txe() {
350 unsafe { 195 unsafe {
351 let dr = regs.dr().ptr() as *mut W; 196 ptr::write_volatile(regs.tx_ptr(), word);
352 ptr::write_volatile(dr, word);
353 } 197 }
354 return Ok(()); 198 return Ok(());
355 } 199 }
@@ -370,8 +214,7 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
370 return Err(Error::Crc); 214 return Err(Error::Crc);
371 } else if sr.rxne() { 215 } else if sr.rxne() {
372 unsafe { 216 unsafe {
373 let dr = regs.dr().ptr() as *const W; 217 return Ok(ptr::read_volatile(regs.rx_ptr()));
374 return Ok(ptr::read_volatile(dr));
375 } 218 }
376 } 219 }
377 } 220 }
@@ -381,7 +224,7 @@ impl<'d, T: Instance, Rx> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T,
381 type Error = Error; 224 type Error = Error;
382 225
383 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 226 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
384 Self::set_word_size(WordSize::EightBit); 227 self.set_word_size(WordSize::EightBit);
385 let regs = T::regs(); 228 let regs = T::regs();
386 229
387 for word in words.iter() { 230 for word in words.iter() {
@@ -397,7 +240,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, N
397 type Error = Error; 240 type Error = Error;
398 241
399 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 242 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
400 Self::set_word_size(WordSize::EightBit); 243 self.set_word_size(WordSize::EightBit);
401 let regs = T::regs(); 244 let regs = T::regs();
402 245
403 for word in words.iter_mut() { 246 for word in words.iter_mut() {
@@ -413,7 +256,7 @@ impl<'d, T: Instance, Rx> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T,
413 type Error = Error; 256 type Error = Error;
414 257
415 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { 258 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
416 Self::set_word_size(WordSize::SixteenBit); 259 self.set_word_size(WordSize::SixteenBit);
417 let regs = T::regs(); 260 let regs = T::regs();
418 261
419 for word in words.iter() { 262 for word in words.iter() {
@@ -429,7 +272,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T,
429 type Error = Error; 272 type Error = Error;
430 273
431 fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { 274 fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
432 Self::set_word_size(WordSize::SixteenBit); 275 self.set_word_size(WordSize::SixteenBit);
433 let regs = T::regs(); 276 let regs = T::regs();
434 277
435 for word in words.iter_mut() { 278 for word in words.iter_mut() {
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs
index dbd9d78c9..052924db0 100644
--- a/embassy-stm32/src/spi/v3.rs
+++ b/embassy-stm32/src/spi/v3.rs
@@ -1,184 +1,23 @@
1#![macro_use] 1#![macro_use]
2 2
3use crate::dma::NoDma; 3use crate::dma::NoDma;
4use crate::gpio::sealed::Pin; 4use crate::spi::{Error, Instance, RegsExt, RxDmaChannel, TxDmaChannel, WordSize};
5use crate::gpio::AnyPin;
6use crate::pac::spi;
7use crate::spi::{
8 ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
9 WordSize,
10};
11use crate::time::Hertz;
12use core::future::Future; 5use core::future::Future;
13use core::marker::PhantomData;
14use core::ptr; 6use core::ptr;
15use embassy::util::Unborrow;
16use embassy_hal_common::unborrow;
17use embassy_traits::spi as traits; 7use embassy_traits::spi as traits;
18pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 8pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
19 9
20use futures::future::join3; 10use futures::future::join3;
21 11
22impl WordSize { 12use super::Spi;
23 fn dsize(&self) -> u8 {
24 match self {
25 WordSize::EightBit => 0b0111,
26 WordSize::SixteenBit => 0b1111,
27 }
28 }
29
30 fn _frxth(&self) -> spi::vals::Fthlv {
31 match self {
32 WordSize::EightBit => spi::vals::Fthlv::ONEFRAME,
33 WordSize::SixteenBit => spi::vals::Fthlv::ONEFRAME,
34 }
35 }
36}
37
38#[allow(unused)]
39pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> {
40 sck: Option<AnyPin>,
41 mosi: Option<AnyPin>,
42 miso: Option<AnyPin>,
43 txdma: Tx,
44 rxdma: Rx,
45 phantom: PhantomData<&'d mut T>,
46}
47 13
48impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { 14impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
49 pub fn new<F>(
50 _peri: impl Unborrow<Target = T> + 'd,
51 sck: impl Unborrow<Target = impl SckPin<T>>,
52 mosi: impl Unborrow<Target = impl MosiPin<T>>,
53 miso: impl Unborrow<Target = impl MisoPin<T>>,
54 txdma: impl Unborrow<Target = Tx>,
55 rxdma: impl Unborrow<Target = Rx>,
56 freq: F,
57 config: Config,
58 ) -> Self
59 where
60 F: Into<Hertz>,
61 {
62 unborrow!(sck, mosi, miso, txdma, rxdma);
63
64 let sck_af = sck.af_num();
65 let mosi_af = mosi.af_num();
66 let miso_af = miso.af_num();
67 let sck = sck.degrade_optional();
68 let mosi = mosi.degrade_optional();
69 let miso = miso.degrade_optional();
70
71 unsafe {
72 sck.as_ref().map(|x| {
73 x.set_as_af(sck_af, crate::gpio::sealed::AFType::OutputPushPull);
74 x.set_speed(crate::gpio::Speed::VeryHigh);
75 });
76 mosi.as_ref().map(|x| {
77 x.set_as_af(mosi_af, crate::gpio::sealed::AFType::OutputPushPull);
78 x.set_speed(crate::gpio::Speed::VeryHigh);
79 });
80 miso.as_ref().map(|x| {
81 x.set_as_af(miso_af, crate::gpio::sealed::AFType::Input);
82 x.set_speed(crate::gpio::Speed::VeryHigh);
83 });
84 }
85
86 let pclk = T::frequency();
87 let br = Self::compute_baud_rate(pclk, freq.into());
88 unsafe {
89 T::enable();
90 T::reset();
91 T::regs().ifcr().write(|w| w.0 = 0xffff_ffff);
92 T::regs().cfg2().modify(|w| {
93 //w.set_ssoe(true);
94 w.set_ssoe(false);
95 w.set_cpha(
96 match config.mode.phase == Phase::CaptureOnSecondTransition {
97 true => spi::vals::Cpha::SECONDEDGE,
98 false => spi::vals::Cpha::FIRSTEDGE,
99 },
100 );
101 w.set_cpol(match config.mode.polarity == Polarity::IdleHigh {
102 true => spi::vals::Cpol::IDLEHIGH,
103 false => spi::vals::Cpol::IDLELOW,
104 });
105 w.set_lsbfrst(match config.byte_order {
106 ByteOrder::LsbFirst => spi::vals::Lsbfrst::LSBFIRST,
107 ByteOrder::MsbFirst => spi::vals::Lsbfrst::MSBFIRST,
108 });
109 w.set_ssm(true);
110 w.set_master(spi::vals::Master::MASTER);
111 w.set_comm(spi::vals::Comm::FULLDUPLEX);
112 w.set_ssom(spi::vals::Ssom::ASSERTED);
113 w.set_midi(0);
114 w.set_mssi(0);
115 w.set_afcntr(spi::vals::Afcntr::CONTROLLED);
116 w.set_ssiop(spi::vals::Ssiop::ACTIVEHIGH);
117 });
118 T::regs().cfg1().modify(|w| {
119 w.set_crcen(false);
120 w.set_mbr(spi::vals::Mbr(br));
121 w.set_dsize(WordSize::EightBit.dsize());
122 });
123 T::regs().cr2().modify(|w| {
124 w.set_tsize(0);
125 w.set_tser(0);
126 });
127 T::regs().cr1().modify(|w| {
128 w.set_ssi(false);
129 w.set_spe(true);
130 });
131 }
132
133 Self {
134 sck,
135 mosi,
136 miso,
137 txdma,
138 rxdma,
139 phantom: PhantomData,
140 }
141 }
142
143 fn compute_baud_rate(clocks: Hertz, freq: Hertz) -> u8 {
144 match clocks.0 / freq.0 {
145 0 => unreachable!(),
146 1..=2 => 0b000,
147 3..=5 => 0b001,
148 6..=11 => 0b010,
149 12..=23 => 0b011,
150 24..=39 => 0b100,
151 40..=95 => 0b101,
152 96..=191 => 0b110,
153 _ => 0b111,
154 }
155 }
156
157 fn set_word_size(word_size: WordSize) {
158 unsafe {
159 T::regs().cr1().modify(|w| {
160 w.set_csusp(true);
161 });
162 while T::regs().sr().read().eot() {}
163 T::regs().cr1().modify(|w| {
164 w.set_spe(false);
165 });
166 T::regs().cfg1().modify(|w| {
167 w.set_dsize(word_size.dsize());
168 });
169 T::regs().cr1().modify(|w| {
170 w.set_csusp(false);
171 w.set_spe(true);
172 });
173 }
174 }
175
176 #[allow(unused)] 15 #[allow(unused)]
177 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> 16 async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error>
178 where 17 where
179 Tx: TxDmaChannel<T>, 18 Tx: TxDmaChannel<T>,
180 { 19 {
181 Self::set_word_size(WordSize::EightBit); 20 self.set_word_size(WordSize::EightBit);
182 unsafe { 21 unsafe {
183 T::regs().cr1().modify(|w| { 22 T::regs().cr1().modify(|w| {
184 w.set_spe(false); 23 w.set_spe(false);
@@ -186,7 +25,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
186 } 25 }
187 26
188 let request = self.txdma.request(); 27 let request = self.txdma.request();
189 let dst = T::regs().txdr().ptr() as *mut u8; 28 let dst = T::regs().tx_ptr();
190 let f = self.txdma.write(request, write, dst); 29 let f = self.txdma.write(request, write, dst);
191 30
192 unsafe { 31 unsafe {
@@ -220,7 +59,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
220 Tx: TxDmaChannel<T>, 59 Tx: TxDmaChannel<T>,
221 Rx: RxDmaChannel<T>, 60 Rx: RxDmaChannel<T>,
222 { 61 {
223 Self::set_word_size(WordSize::EightBit); 62 self.set_word_size(WordSize::EightBit);
224 unsafe { 63 unsafe {
225 T::regs().cr1().modify(|w| { 64 T::regs().cr1().modify(|w| {
226 w.set_spe(false); 65 w.set_spe(false);
@@ -233,11 +72,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
233 let clock_byte_count = read.len(); 72 let clock_byte_count = read.len();
234 73
235 let rx_request = self.rxdma.request(); 74 let rx_request = self.rxdma.request();
236 let rx_src = T::regs().rxdr().ptr() as *mut u8; 75 let rx_src = T::regs().rx_ptr();
237 let rx_f = self.rxdma.read(rx_request, rx_src, read); 76 let rx_f = self.rxdma.read(rx_request, rx_src, read);
238 77
239 let tx_request = self.txdma.request(); 78 let tx_request = self.txdma.request();
240 let tx_dst = T::regs().txdr().ptr() as *mut u8; 79 let tx_dst = T::regs().tx_ptr();
241 let clock_byte = 0x00; 80 let clock_byte = 0x00;
242 let tx_f = self 81 let tx_f = self
243 .txdma 82 .txdma
@@ -276,7 +115,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
276 { 115 {
277 assert!(read.len() >= write.len()); 116 assert!(read.len() >= write.len());
278 117
279 Self::set_word_size(WordSize::EightBit); 118 self.set_word_size(WordSize::EightBit);
280 unsafe { 119 unsafe {
281 T::regs().cr1().modify(|w| { 120 T::regs().cr1().modify(|w| {
282 w.set_spe(false); 121 w.set_spe(false);
@@ -292,13 +131,13 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
292 } 131 }
293 132
294 let rx_request = self.rxdma.request(); 133 let rx_request = self.rxdma.request();
295 let rx_src = T::regs().rxdr().ptr() as *mut u8; 134 let rx_src = T::regs().rx_ptr();
296 let rx_f = self 135 let rx_f = self
297 .rxdma 136 .rxdma
298 .read(rx_request, rx_src, &mut read[0..write.len()]); 137 .read(rx_request, rx_src, &mut read[0..write.len()]);
299 138
300 let tx_request = self.txdma.request(); 139 let tx_request = self.txdma.request();
301 let tx_dst = T::regs().txdr().ptr() as *mut u8; 140 let tx_dst = T::regs().tx_ptr();
302 let tx_f = self.txdma.write(tx_request, write, tx_dst); 141 let tx_f = self.txdma.write(tx_request, write, tx_dst);
303 142
304 unsafe { 143 unsafe {
@@ -338,21 +177,11 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
338 } 177 }
339} 178}
340 179
341impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { 180impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma, NoDma> {
342 fn drop(&mut self) {
343 unsafe {
344 self.sck.as_ref().map(|x| x.set_as_analog());
345 self.mosi.as_ref().map(|x| x.set_as_analog());
346 self.miso.as_ref().map(|x| x.set_as_analog());
347 }
348 }
349}
350
351impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDma> {
352 type Error = Error; 181 type Error = Error;
353 182
354 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { 183 fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
355 Self::set_word_size(WordSize::EightBit); 184 self.set_word_size(WordSize::EightBit);
356 let regs = T::regs(); 185 let regs = T::regs();
357 186
358 for word in words.iter() { 187 for word in words.iter() {
@@ -360,8 +189,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDm
360 // spin 189 // spin
361 } 190 }
362 unsafe { 191 unsafe {
363 let txdr = regs.txdr().ptr() as *mut u8; 192 ptr::write_volatile(regs.tx_ptr(), *word);
364 ptr::write_volatile(txdr, *word);
365 regs.cr1().modify(|reg| reg.set_cstart(true)); 193 regs.cr1().modify(|reg| reg.set_cstart(true));
366 } 194 }
367 loop { 195 loop {
@@ -382,9 +210,8 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDm
382 break; 210 break;
383 } 211 }
384 unsafe { 212 unsafe {
385 let rxdr = regs.rxdr().ptr() as *const u8;
386 // discard read to prevent pverrun. 213 // discard read to prevent pverrun.
387 let _ = ptr::read_volatile(rxdr); 214 let _: u8 = ptr::read_volatile(T::regs().rx_ptr());
388 } 215 }
389 } 216 }
390 217
@@ -396,11 +223,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T, NoDm
396 } 223 }
397} 224}
398 225
399impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma> { 226impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, NoDma, NoDma> {
400 type Error = Error; 227 type Error = Error;
401 228
402 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { 229 fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
403 Self::set_word_size(WordSize::EightBit); 230 self.set_word_size(WordSize::EightBit);
404 let regs = T::regs(); 231 let regs = T::regs();
405 232
406 for word in words.iter_mut() { 233 for word in words.iter_mut() {
@@ -413,8 +240,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, N
413 // spin 240 // spin
414 } 241 }
415 unsafe { 242 unsafe {
416 let txdr = regs.txdr().ptr() as *mut u8; 243 ptr::write_volatile(T::regs().tx_ptr(), *word);
417 ptr::write_volatile(txdr, *word);
418 regs.cr1().modify(|reg| reg.set_cstart(true)); 244 regs.cr1().modify(|reg| reg.set_cstart(true));
419 } 245 }
420 loop { 246 loop {
@@ -434,8 +260,7 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, N
434 } 260 }
435 } 261 }
436 unsafe { 262 unsafe {
437 let rxdr = regs.rxdr().ptr() as *const u8; 263 *word = ptr::read_volatile(T::regs().rx_ptr());
438 *word = ptr::read_volatile(rxdr);
439 } 264 }
440 let sr = unsafe { regs.sr().read() }; 265 let sr = unsafe { regs.sr().read() };
441 if sr.tifre() { 266 if sr.tifre() {
@@ -453,11 +278,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T, N
453 } 278 }
454} 279}
455 280
456impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma> { 281impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoDma, NoDma> {
457 type Error = Error; 282 type Error = Error;
458 283
459 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> { 284 fn write(&mut self, words: &[u16]) -> Result<(), Self::Error> {
460 Self::set_word_size(WordSize::SixteenBit); 285 self.set_word_size(WordSize::SixteenBit);
461 let regs = T::regs(); 286 let regs = T::regs();
462 287
463 for word in words.iter() { 288 for word in words.iter() {
@@ -502,11 +327,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T, NoD
502 } 327 }
503} 328}
504 329
505impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma> { 330impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T, NoDma, NoDma> {
506 type Error = Error; 331 type Error = Error;
507 332
508 fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> { 333 fn transfer<'w>(&mut self, words: &'w mut [u16]) -> Result<&'w [u16], Self::Error> {
509 Self::set_word_size(WordSize::SixteenBit); 334 self.set_word_size(WordSize::SixteenBit);
510 let regs = T::regs(); 335 let regs = T::regs();
511 336
512 for word in words.iter_mut() { 337 for word in words.iter_mut() {