aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/spi/v1.rs43
-rw-r--r--embassy-stm32/src/spi/v2.rs82
-rw-r--r--embassy-stm32/src/spi/v3.rs151
3 files changed, 213 insertions, 63 deletions
diff --git a/embassy-stm32/src/spi/v1.rs b/embassy-stm32/src/spi/v1.rs
index a464c4275..435573254 100644
--- a/embassy-stm32/src/spi/v1.rs
+++ b/embassy-stm32/src/spi/v1.rs
@@ -8,6 +8,7 @@ use core::marker::PhantomData;
8use embassy::util::Unborrow; 8use embassy::util::Unborrow;
9use embassy_extras::unborrow; 9use embassy_extras::unborrow;
10pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 10pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
11use core::ptr;
11 12
12impl WordSize { 13impl WordSize {
13 fn dff(&self) -> spi::vals::Dff { 14 fn dff(&self) -> spi::vals::Dff {
@@ -151,7 +152,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
151 // spin 152 // spin
152 } 153 }
153 unsafe { 154 unsafe {
154 regs.dr().write(|reg| reg.0 = *word as u32); 155 let dr = regs.txdr().ptr() as *mut u8;
156 ptr::write_volatile(
157 dr,
158 *word,
159 );
155 } 160 }
156 loop { 161 loop {
157 let sr = unsafe { regs.sr().read() }; 162 let sr = unsafe { regs.sr().read() };
@@ -186,12 +191,24 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
186 // spin 191 // spin
187 } 192 }
188 unsafe { 193 unsafe {
189 regs.dr().write(|reg| reg.0 = *word as u32); 194 let dr = regs.txdr().ptr() as *mut u8;
195 ptr::write_volatile(
196 dr,
197 *word,
198 );
190 } 199 }
200
191 while unsafe { !regs.sr().read().rxne() } { 201 while unsafe { !regs.sr().read().rxne() } {
192 // spin waiting for inbound to shift in. 202 // spin waiting for inbound to shift in.
193 } 203 }
194 *word = unsafe { regs.dr().read().0 as u8 }; 204
205 unsafe {
206 let dr = regs.dr().ptr() as *const u8;
207 *word = ptr::read_volatile(
208 dr
209 );
210 }
211
195 let sr = unsafe { regs.sr().read() }; 212 let sr = unsafe { regs.sr().read() };
196 if sr.fre() { 213 if sr.fre() {
197 return Err(Error::Framing); 214 return Err(Error::Framing);
@@ -220,7 +237,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
220 // spin 237 // spin
221 } 238 }
222 unsafe { 239 unsafe {
223 regs.dr().write(|reg| reg.0 = *word as u32); 240 let dr = regs.txdr().ptr() as *mut u16;
241 ptr::write_volatile(
242 dr,
243 *word,
244 );
224 } 245 }
225 loop { 246 loop {
226 let sr = unsafe { regs.sr().read() }; 247 let sr = unsafe { regs.sr().read() };
@@ -255,12 +276,22 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T>
255 // spin 276 // spin
256 } 277 }
257 unsafe { 278 unsafe {
258 regs.dr().write(|reg| reg.0 = *word as u32); 279 let dr = regs.txdr().ptr() as *mut u16;
280 ptr::write_volatile(
281 dr,
282 *word,
283 );
259 } 284 }
260 while unsafe { !regs.sr().read().rxne() } { 285 while unsafe { !regs.sr().read().rxne() } {
261 // spin waiting for inbound to shift in. 286 // spin waiting for inbound to shift in.
262 } 287 }
263 *word = unsafe { regs.dr().read().0 as u16 }; 288 unsafe {
289 let dr = regs.dr().ptr() as *const u16;
290 *word = ptr::read_volatile(
291 dr
292 );
293 }
294
264 let sr = unsafe { regs.sr().read() }; 295 let sr = unsafe { regs.sr().read() };
265 if sr.fre() { 296 if sr.fre() {
266 return Err(Error::Framing); 297 return Err(Error::Framing);
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
index 0bb5762fd..82344a5d6 100644
--- a/embassy-stm32/src/spi/v2.rs
+++ b/embassy-stm32/src/spi/v2.rs
@@ -10,6 +10,7 @@ use core::marker::PhantomData;
10use embassy::util::Unborrow; 10use embassy::util::Unborrow;
11use embassy_extras::unborrow; 11use embassy_extras::unborrow;
12pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 12pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
13use core::ptr;
13 14
14impl WordSize { 15impl WordSize {
15 fn ds(&self) -> spi::vals::Ds { 16 fn ds(&self) -> spi::vals::Ds {
@@ -61,16 +62,13 @@ impl<'d, T: Instance> Spi<'d, T> {
61 let mosi = mosi.degrade(); 62 let mosi = mosi.degrade();
62 let miso = miso.degrade(); 63 let miso = miso.degrade();
63 64
64 unsafe {
65 T::regs().cr2().write(|w| {
66 w.set_ssoe(false);
67 });
68 }
69
70 let br = Self::compute_baud_rate(pclk, freq.into()); 65 let br = Self::compute_baud_rate(pclk, freq.into());
71 66
72 unsafe { 67 unsafe {
73 T::regs().cr1().write(|w| { 68 T::regs().cr2().modify(|w| {
69 w.set_ssoe(false);
70 });
71 T::regs().cr1().modify(|w| {
74 w.set_cpha( 72 w.set_cpha(
75 match config.mode.phase == Phase::CaptureOnSecondTransition { 73 match config.mode.phase == Phase::CaptureOnSecondTransition {
76 true => spi::vals::Cpha::SECONDEDGE, 74 true => spi::vals::Cpha::SECONDEDGE,
@@ -84,7 +82,6 @@ impl<'d, T: Instance> Spi<'d, T> {
84 82
85 w.set_mstr(spi::vals::Mstr::MASTER); 83 w.set_mstr(spi::vals::Mstr::MASTER);
86 w.set_br(spi::vals::Br(br)); 84 w.set_br(spi::vals::Br(br));
87 w.set_spe(true);
88 w.set_lsbfirst(match config.byte_order { 85 w.set_lsbfirst(match config.byte_order {
89 ByteOrder::LsbFirst => spi::vals::Lsbfirst::LSBFIRST, 86 ByteOrder::LsbFirst => spi::vals::Lsbfirst::LSBFIRST,
90 ByteOrder::MsbFirst => spi::vals::Lsbfirst::MSBFIRST, 87 ByteOrder::MsbFirst => spi::vals::Lsbfirst::MSBFIRST,
@@ -93,6 +90,7 @@ impl<'d, T: Instance> Spi<'d, T> {
93 w.set_ssm(true); 90 w.set_ssm(true);
94 w.set_crcen(false); 91 w.set_crcen(false);
95 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL); 92 w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
93 w.set_spe(true);
96 }); 94 });
97 } 95 }
98 96
@@ -131,9 +129,15 @@ impl<'d, T: Instance> Spi<'d, T> {
131 129
132 fn set_word_size(word_size: WordSize) { 130 fn set_word_size(word_size: WordSize) {
133 unsafe { 131 unsafe {
134 T::regs().cr2().write(|w| { 132 T::regs().cr1().modify(|w| {
135 w.set_ds(word_size.ds()); 133 w.set_spe(false);
134 });
135 T::regs().cr2().modify(|w| {
136 w.set_frxth(word_size.frxth()); 136 w.set_frxth(word_size.frxth());
137 w.set_ds(word_size.ds());
138 });
139 T::regs().cr1().modify(|w| {
140 w.set_spe(true);
137 }); 141 });
138 } 142 }
139 } 143 }
@@ -156,12 +160,16 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
156 Self::set_word_size(WordSize::EightBit); 160 Self::set_word_size(WordSize::EightBit);
157 let regs = T::regs(); 161 let regs = T::regs();
158 162
159 for word in words.iter() { 163 for (i, word) in words.iter().enumerate() {
160 while unsafe { !regs.sr().read().txe() } { 164 while unsafe { !regs.sr().read().txe() } {
161 // spin 165 // spin
162 } 166 }
163 unsafe { 167 unsafe {
164 regs.dr().write(|reg| reg.0 = *word as u32); 168 let dr = regs.dr().ptr() as *mut u8;
169 ptr::write_volatile(
170 dr,
171 *word,
172 );
165 } 173 }
166 loop { 174 loop {
167 let sr = unsafe { regs.sr().read() }; 175 let sr = unsafe { regs.sr().read() };
@@ -191,17 +199,38 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
191 Self::set_word_size(WordSize::EightBit); 199 Self::set_word_size(WordSize::EightBit);
192 let regs = T::regs(); 200 let regs = T::regs();
193 201
194 for word in words.iter_mut() { 202 for (i, word) in words.iter_mut().enumerate() {
195 while unsafe { !regs.sr().read().txe() } { 203 while unsafe { !regs.sr().read().txe() } {
196 // spin 204 // spin
197 } 205 }
198 unsafe { 206 unsafe {
199 regs.dr().write(|reg| reg.0 = *word as u32); 207 let dr = regs.dr().ptr() as *mut u8;
208 ptr::write_volatile(
209 dr,
210 *word,
211 );
200 } 212 }
201 while unsafe { !regs.sr().read().rxne() } { 213 loop {
202 // spin waiting for inbound to shift in. 214 let sr = unsafe { regs.sr().read() };
215 if sr.rxne() {
216 break;
217 }
218 if sr.fre() {
219 return Err(Error::Framing);
220 }
221 if sr.ovr() {
222 return Err(Error::Overrun);
223 }
224 if sr.crcerr() {
225 return Err(Error::Crc);
226 }
227 }
228 unsafe {
229 let dr = regs.rxdr().ptr() as *const u8;
230 *word = ptr::read_volatile(
231 dr
232 );
203 } 233 }
204 *word = unsafe { regs.dr().read().0 as u8 };
205 let sr = unsafe { regs.sr().read() }; 234 let sr = unsafe { regs.sr().read() };
206 if sr.fre() { 235 if sr.fre() {
207 return Err(Error::Framing); 236 return Err(Error::Framing);
@@ -230,7 +259,11 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
230 // spin 259 // spin
231 } 260 }
232 unsafe { 261 unsafe {
233 regs.dr().write(|reg| reg.0 = *word as u32); 262 let dr = regs.dr().ptr() as *mut u16;
263 ptr::write_volatile(
264 dr,
265 *word,
266 );
234 } 267 }
235 loop { 268 loop {
236 let sr = unsafe { regs.sr().read() }; 269 let sr = unsafe { regs.sr().read() };
@@ -265,12 +298,21 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T>
265 // spin 298 // spin
266 } 299 }
267 unsafe { 300 unsafe {
268 regs.dr().write(|reg| reg.0 = *word as u32); 301 let dr = regs.dr().ptr() as *mut u16;
302 ptr::write_volatile(
303 dr,
304 *word,
305 );
269 } 306 }
270 while unsafe { !regs.sr().read().rxne() } { 307 while unsafe { !regs.sr().read().rxne() } {
271 // spin waiting for inbound to shift in. 308 // spin waiting for inbound to shift in.
272 } 309 }
273 *word = unsafe { regs.dr().read().0 as u16 }; 310 unsafe {
311 let dr = regs.rxdr().ptr() as *const u16;
312 *word = ptr::read_volatile(
313 dr
314 );
315 }
274 let sr = unsafe { regs.sr().read() }; 316 let sr = unsafe { regs.sr().read() };
275 if sr.fre() { 317 if sr.fre() {
276 return Err(Error::Framing); 318 return Err(Error::Framing);
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs
index 6f81f9dd2..e30d479ee 100644
--- a/embassy-stm32/src/spi/v3.rs
+++ b/embassy-stm32/src/spi/v3.rs
@@ -10,6 +10,8 @@ use core::marker::PhantomData;
10use embassy::util::Unborrow; 10use embassy::util::Unborrow;
11use embassy_extras::unborrow; 11use embassy_extras::unborrow;
12pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 12pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
13use core::ptr;
14
13 15
14impl WordSize { 16impl WordSize {
15 fn dsize(&self) -> u8 { 17 fn dsize(&self) -> u8 {
@@ -21,8 +23,8 @@ impl WordSize {
21 23
22 fn frxth(&self) -> spi::vals::Fthlv { 24 fn frxth(&self) -> spi::vals::Fthlv {
23 match self { 25 match self {
24 WordSize::EightBit => spi::vals::Fthlv::FOURFRAMES, 26 WordSize::EightBit => spi::vals::Fthlv::ONEFRAME,
25 WordSize::SixteenBit => spi::vals::Fthlv::EIGHTFRAMES, 27 WordSize::SixteenBit => spi::vals::Fthlv::ONEFRAME,
26 } 28 }
27 } 29 }
28} 30}
@@ -38,22 +40,24 @@ pub struct Spi<'d, T: Instance> {
38impl<'d, T: Instance> Spi<'d, T> { 40impl<'d, T: Instance> Spi<'d, T> {
39 pub fn new<F>( 41 pub fn new<F>(
40 pclk: Hertz, 42 pclk: Hertz,
41 peri: impl Unborrow<Target = T> + 'd, 43 peri: impl Unborrow<Target=T> + 'd,
42 sck: impl Unborrow<Target = impl SckPin<T>>, 44 sck: impl Unborrow<Target=impl SckPin<T>>,
43 mosi: impl Unborrow<Target = impl MosiPin<T>>, 45 mosi: impl Unborrow<Target=impl MosiPin<T>>,
44 miso: impl Unborrow<Target = impl MisoPin<T>>, 46 miso: impl Unborrow<Target=impl MisoPin<T>>,
45 freq: F, 47 freq: F,
46 config: Config, 48 config: Config,
47 ) -> Self 49 ) -> Self
48 where 50 where
49 F: Into<Hertz>, 51 F: Into<Hertz>,
50 { 52 {
51 unborrow!(peri); 53 unborrow!(peri);
52 unborrow!(sck, mosi, miso); 54 unborrow!(sck, mosi, miso);
53 55
54 unsafe { 56 unsafe {
55 Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num()); 57 Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num());
58 //sck.block().otyper().modify(|w| w.set_ot(sck.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL));
56 Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num()); 59 Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num());
60 //mosi.block().otyper().modify(|w| w.set_ot(mosi.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL));
57 Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num()); 61 Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num());
58 } 62 }
59 63
@@ -61,8 +65,13 @@ impl<'d, T: Instance> Spi<'d, T> {
61 let mosi = mosi.degrade(); 65 let mosi = mosi.degrade();
62 let miso = miso.degrade(); 66 let miso = miso.degrade();
63 67
68 let br = Self::compute_baud_rate(pclk, freq.into());
64 unsafe { 69 unsafe {
65 T::regs().cfg2().write(|w| { 70 T::regs().ifcr().write(|w| {
71 w.0 = 0xffff_ffff
72 });
73 T::regs().cfg2().modify(|w| {
74 //w.set_ssoe(true);
66 w.set_ssoe(false); 75 w.set_ssoe(false);
67 w.set_cpha( 76 w.set_cpha(
68 match config.mode.phase == Phase::CaptureOnSecondTransition { 77 match config.mode.phase == Phase::CaptureOnSecondTransition {
@@ -74,30 +83,32 @@ impl<'d, T: Instance> Spi<'d, T> {
74 true => spi::vals::Cpol::IDLEHIGH, 83 true => spi::vals::Cpol::IDLEHIGH,
75 false => spi::vals::Cpol::IDLELOW, 84 false => spi::vals::Cpol::IDLELOW,
76 }); 85 });
77 });
78 }
79
80 let br = Self::compute_baud_rate(pclk, freq.into());
81
82 unsafe {
83 T::regs().cfg2().write(|w| {
84 w.set_lsbfrst(match config.byte_order { 86 w.set_lsbfrst(match config.byte_order {
85 ByteOrder::LsbFirst => spi::vals::Lsbfrst::LSBFIRST, 87 ByteOrder::LsbFirst => spi::vals::Lsbfrst::LSBFIRST,
86 ByteOrder::MsbFirst => spi::vals::Lsbfrst::MSBFIRST, 88 ByteOrder::MsbFirst => spi::vals::Lsbfrst::MSBFIRST,
87 }); 89 });
88 w.set_ssm(true); 90 w.set_ssm(true);
89 w.set_master(spi::vals::Master::MASTER); 91 w.set_master(spi::vals::Master::MASTER);
92 w.set_comm(spi::vals::Comm::FULLDUPLEX);
93 w.set_ssom(spi::vals::Ssom::ASSERTED);
94 w.set_midi(0);
95 w.set_mssi(0);
96 w.set_afcntr(spi::vals::Afcntr::CONTROLLED);
97 w.set_ssiop(spi::vals::Ssiop::ACTIVEHIGH);
90 }); 98 });
91 T::regs().cfg1().write(|w| { 99 T::regs().cfg1().modify(|w| {
92 w.set_crcen(false); 100 w.set_crcen(false);
93 w.set_mbr(spi::vals::Mbr(br)); 101 w.set_mbr(spi::vals::Mbr(br));
94 w.set_dsize(WordSize::EightBit.dsize()); 102 w.set_dsize(WordSize::EightBit.dsize());
95 w.set_fthlv(WordSize::EightBit.frxth()); 103 //w.set_fthlv(WordSize::EightBit.frxth());
96 }); 104 });
97 T::regs().cr1().write(|w| { 105 T::regs().cr2().modify(|w| {
98 w.set_ssi(true); 106 w.set_tsize(0);
107 w.set_tser(0);
108 });
109 T::regs().cr1().modify(|w| {
110 w.set_ssi(false);
99 w.set_spe(true); 111 w.set_spe(true);
100 //w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
101 }); 112 });
102 } 113 }
103 114
@@ -114,6 +125,7 @@ impl<'d, T: Instance> Spi<'d, T> {
114 let (afr, n_af) = if pin < 8 { (0, pin) } else { (1, pin - 8) }; 125 let (afr, n_af) = if pin < 8 { (0, pin) } else { (1, pin - 8) };
115 block.moder().modify(|w| w.set_moder(pin, Moder::ALTERNATE)); 126 block.moder().modify(|w| w.set_moder(pin, Moder::ALTERNATE));
116 block.afr(afr).modify(|w| w.set_afr(n_af, Afr(af_num))); 127 block.afr(afr).modify(|w| w.set_afr(n_af, Afr(af_num)));
128 block.ospeedr().modify(|w| w.set_ospeedr(pin, crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED));
117 } 129 }
118 130
119 unsafe fn unconfigure_pin(block: Gpio, pin: usize) { 131 unsafe fn unconfigure_pin(block: Gpio, pin: usize) {
@@ -136,14 +148,17 @@ impl<'d, T: Instance> Spi<'d, T> {
136 148
137 fn set_word_size(word_size: WordSize) { 149 fn set_word_size(word_size: WordSize) {
138 unsafe { 150 unsafe {
139 T::regs().cr1().write(|w| { 151 T::regs().cr1().modify(|w| {
152 w.set_csusp(true);
153 });
154 while T::regs().sr().read().eot() {}
155 T::regs().cr1().modify(|w| {
140 w.set_spe(false); 156 w.set_spe(false);
141 }); 157 });
142 T::regs().cfg1().write(|w| { 158 T::regs().cfg1().modify(|w| {
143 w.set_dsize(word_size.dsize()); 159 w.set_dsize(word_size.dsize());
144 w.set_fthlv(word_size.frxth());
145 }); 160 });
146 T::regs().cr1().write(|w| { 161 T::regs().cr1().modify(|w| {
147 w.set_spe(true); 162 w.set_spe(true);
148 }); 163 });
149 } 164 }
@@ -172,8 +187,12 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
172 // spin 187 // spin
173 } 188 }
174 unsafe { 189 unsafe {
175 //regs.dr().write(|reg| reg.0 = *word as u32); 190 let txdr = regs.txdr().ptr() as *mut u8;
176 regs.txdr().write(|reg| reg.0 = *word as u32); 191 ptr::write_volatile(
192 txdr,
193 *word,
194 );
195 regs.cr1().modify(|reg| reg.set_cstart(true));
177 } 196 }
178 loop { 197 loop {
179 let sr = unsafe { regs.sr().read() }; 198 let sr = unsafe { regs.sr().read() };
@@ -203,17 +222,45 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
203 Self::set_word_size(WordSize::EightBit); 222 Self::set_word_size(WordSize::EightBit);
204 let regs = T::regs(); 223 let regs = T::regs();
205 224
206 for word in words.iter_mut() { 225 for (i, word) in words.iter_mut().enumerate() {
226 unsafe {
227 regs.cr1().modify(|reg| {
228 reg.set_ssi(false);
229 });
230 }
207 while unsafe { !regs.sr().read().txp() } { 231 while unsafe { !regs.sr().read().txp() } {
208 // spin 232 // spin
209 } 233 }
210 unsafe { 234 unsafe {
211 regs.txdr().write(|reg| reg.0 = *word as u32); 235 let txdr = regs.txdr().ptr() as *mut u8;
236 ptr::write_volatile(
237 txdr,
238 *word,
239 );
240 regs.cr1().modify(|reg| reg.set_cstart(true));
212 } 241 }
213 while unsafe { !regs.sr().read().rxp() } { 242 loop {
214 // spin waiting for inbound to shift in. 243 let sr = unsafe { regs.sr().read() };
244
245 if sr.rxp() {
246 break;
247 }
248 if sr.tifre() {
249 return Err(Error::Framing);
250 }
251 if sr.ovr() {
252 return Err(Error::Overrun);
253 }
254 if sr.crce() {
255 return Err(Error::Crc);
256 }
257 }
258 unsafe {
259 let rxdr = regs.rxdr().ptr() as *const u8;
260 *word = ptr::read_volatile(
261 rxdr
262 );
215 } 263 }
216 *word = unsafe { regs.rxdr().read().0 as u8 };
217 let sr = unsafe { regs.sr().read() }; 264 let sr = unsafe { regs.sr().read() };
218 if sr.tifre() { 265 if sr.tifre() {
219 return Err(Error::Framing); 266 return Err(Error::Framing);
@@ -242,7 +289,12 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
242 // spin 289 // spin
243 } 290 }
244 unsafe { 291 unsafe {
245 regs.txdr().write(|reg| reg.0 = *word as u32); 292 let txdr = regs.txdr().ptr() as *mut u16;
293 ptr::write_volatile(
294 txdr,
295 *word,
296 );
297 regs.cr1().modify(|reg| reg.set_cstart(true));
246 } 298 }
247 loop { 299 loop {
248 let sr = unsafe { regs.sr().read() }; 300 let sr = unsafe { regs.sr().read() };
@@ -277,12 +329,37 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T>
277 // spin 329 // spin
278 } 330 }
279 unsafe { 331 unsafe {
280 regs.txdr().write(|reg| reg.0 = *word as u32); 332 let txdr = regs.txdr().ptr() as *mut u16;
333 ptr::write_volatile(
334 txdr,
335 *word,
336 );
337 regs.cr1().modify(|reg| reg.set_cstart(true));
338 }
339
340 loop {
341 let sr = unsafe { regs.sr().read() };
342
343 if sr.rxp() {
344 break;
345 }
346 if sr.tifre() {
347 return Err(Error::Framing);
348 }
349 if sr.ovr() {
350 return Err(Error::Overrun);
351 }
352 if sr.crce() {
353 return Err(Error::Crc);
354 }
281 } 355 }
282 while unsafe { !regs.sr().read().rxp() } { 356
283 // spin waiting for inbound to shift in. 357 unsafe {
358 let rxdr = regs.rxdr().ptr() as *const u16;
359 *word = ptr::read_volatile(
360 rxdr
361 );
284 } 362 }
285 *word = unsafe { regs.rxdr().read().0 as u16 };
286 let sr = unsafe { regs.sr().read() }; 363 let sr = unsafe { regs.sr().read() };
287 if sr.tifre() { 364 if sr.tifre() {
288 return Err(Error::Framing); 365 return Err(Error::Framing);