diff options
| -rw-r--r-- | embassy-stm32/src/spi/v1.rs | 43 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v2.rs | 82 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 151 |
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; | |||
| 8 | use embassy::util::Unborrow; | 8 | use embassy::util::Unborrow; |
| 9 | use embassy_extras::unborrow; | 9 | use embassy_extras::unborrow; |
| 10 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 10 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 11 | use core::ptr; | ||
| 11 | 12 | ||
| 12 | impl WordSize { | 13 | impl 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; | |||
| 10 | use embassy::util::Unborrow; | 10 | use embassy::util::Unborrow; |
| 11 | use embassy_extras::unborrow; | 11 | use embassy_extras::unborrow; |
| 12 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 12 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 13 | use core::ptr; | ||
| 13 | 14 | ||
| 14 | impl WordSize { | 15 | impl 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; | |||
| 10 | use embassy::util::Unborrow; | 10 | use embassy::util::Unborrow; |
| 11 | use embassy_extras::unborrow; | 11 | use embassy_extras::unborrow; |
| 12 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 12 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 13 | use core::ptr; | ||
| 14 | |||
| 13 | 15 | ||
| 14 | impl WordSize { | 16 | impl 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> { | |||
| 38 | impl<'d, T: Instance> Spi<'d, T> { | 40 | impl<'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); |
