aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatous Hybl <[email protected]>2022-01-10 19:37:15 +0100
committerMatous Hybl <[email protected]>2022-01-14 12:50:58 +0100
commit66e46d8012a74c1207ccc37e96bdaf1d3eef0e9e (patch)
tree0dd5bb42e0109b0e93c5350479bbf42d160f44ee
parent167af012114cca8747e65d0dc5157f066bb2ed5d (diff)
Add the possibility to reconfigure Spi mode and bit order configuration on the fly.
-rw-r--r--embassy-stm32/src/spi/mod.rs107
-rw-r--r--embassy-stm32/src/subghz/mod.rs4
2 files changed, 88 insertions, 23 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 4ae45a9be..f83ef7852 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -34,7 +34,8 @@ pub enum Error {
34} 34}
35 35
36// TODO move upwards in the tree 36// TODO move upwards in the tree
37pub enum ByteOrder { 37#[derive(Copy, Clone)]
38pub enum BitOrder {
38 LsbFirst, 39 LsbFirst,
39 MsbFirst, 40 MsbFirst,
40} 41}
@@ -88,16 +89,40 @@ impl WordSize {
88} 89}
89 90
90#[non_exhaustive] 91#[non_exhaustive]
92#[derive(Copy, Clone)]
91pub struct Config { 93pub struct Config {
92 pub mode: Mode, 94 pub mode: Mode,
93 pub byte_order: ByteOrder, 95 pub bit_order: BitOrder,
94} 96}
95 97
96impl Default for Config { 98impl Default for Config {
97 fn default() -> Self { 99 fn default() -> Self {
98 Self { 100 Self {
99 mode: MODE_0, 101 mode: MODE_0,
100 byte_order: ByteOrder::MsbFirst, 102 bit_order: BitOrder::MsbFirst,
103 }
104 }
105}
106
107impl Config {
108 fn raw_phase(&self) -> vals::Cpha {
109 match self.mode.phase {
110 Phase::CaptureOnSecondTransition => vals::Cpha::SECONDEDGE,
111 Phase::CaptureOnFirstTransition => vals::Cpha::FIRSTEDGE,
112 }
113 }
114
115 fn raw_polarity(&self) -> vals::Cpol {
116 match self.mode.polarity {
117 Polarity::IdleHigh => vals::Cpol::IDLEHIGH,
118 Polarity::IdleLow => vals::Cpol::IDLELOW,
119 }
120 }
121
122 fn raw_byte_order(&self) -> vals::Lsbfirst {
123 match self.bit_order {
124 BitOrder::LsbFirst => vals::Lsbfirst::LSBFIRST,
125 BitOrder::MsbFirst => vals::Lsbfirst::MSBFIRST,
101 } 126 }
102 } 127 }
103} 128}
@@ -156,24 +181,10 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
156 let pclk = T::frequency(); 181 let pclk = T::frequency();
157 let br = compute_baud_rate(pclk, freq.into()); 182 let br = compute_baud_rate(pclk, freq.into());
158 183
159 let cpha = match config.mode.phase { 184 let cpha = config.raw_phase();
160 Phase::CaptureOnSecondTransition => vals::Cpha::SECONDEDGE, 185 let cpol = config.raw_polarity();
161 Phase::CaptureOnFirstTransition => vals::Cpha::FIRSTEDGE,
162 };
163 let cpol = match config.mode.polarity {
164 Polarity::IdleHigh => vals::Cpol::IDLEHIGH,
165 Polarity::IdleLow => vals::Cpol::IDLELOW,
166 };
167 186
168 #[cfg(not(spi_v3))] 187 let lsbfirst = config.raw_byte_order();
169 use vals::Lsbfirst;
170 #[cfg(spi_v3)]
171 use vals::Lsbfrst as Lsbfirst;
172
173 let lsbfirst = match config.byte_order {
174 ByteOrder::LsbFirst => Lsbfirst::LSBFIRST,
175 ByteOrder::MsbFirst => Lsbfirst::MSBFIRST,
176 };
177 188
178 T::enable(); 189 T::enable();
179 T::reset(); 190 T::reset();
@@ -230,7 +241,7 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
230 w.set_ssoe(false); 241 w.set_ssoe(false);
231 w.set_cpha(cpha); 242 w.set_cpha(cpha);
232 w.set_cpol(cpol); 243 w.set_cpol(cpol);
233 w.set_lsbfrst(lsbfirst); 244 w.set_lsbfirst(lsbfirst);
234 w.set_ssm(true); 245 w.set_ssm(true);
235 w.set_master(vals::Master::MASTER); 246 w.set_master(vals::Master::MASTER);
236 w.set_comm(vals::Comm::FULLDUPLEX); 247 w.set_comm(vals::Comm::FULLDUPLEX);
@@ -266,6 +277,60 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
266 } 277 }
267 } 278 }
268 279
280 /// Reconfigures it with the supplied config.
281 pub fn reconfigure(&mut self, config: Config) {
282 let cpha = config.raw_phase();
283 let cpol = config.raw_polarity();
284
285 let lsbfirst = config.raw_byte_order();
286
287 #[cfg(any(spi_v1, spi_f1, spi_v2))]
288 unsafe {
289 T::regs().cr1().modify(|w| {
290 w.set_cpha(cpha);
291 w.set_cpol(cpol);
292 w.set_lsbfirst(lsbfirst);
293 });
294 }
295
296 #[cfg(spi_v3)]
297 unsafe {
298 T::regs().cfg2().modify(|w| {
299 w.set_cpha(cpha);
300 w.set_cpol(cpol);
301 w.set_lsbfirst(lsbfirst);
302 });
303 }
304 }
305
306 pub fn get_current_config(&self) -> Config {
307 #[cfg(any(spi_v1, spi_f1, spi_v2))]
308 let cfg = unsafe { T::regs().cr1().read() };
309 #[cfg(spi_v3)]
310 let cfg = unsafe { T::regs().cfg2().read() };
311 let polarity = if cfg.cpol() == vals::Cpol::IDLELOW {
312 Polarity::IdleLow
313 } else {
314 Polarity::IdleHigh
315 };
316 let phase = if cfg.cpha() == vals::Cpha::FIRSTEDGE {
317 Phase::CaptureOnFirstTransition
318 } else {
319 Phase::CaptureOnSecondTransition
320 };
321
322 let bit_order = if cfg.lsbfirst() == vals::Lsbfirst::LSBFIRST {
323 BitOrder::LsbFirst
324 } else {
325 BitOrder::MsbFirst
326 };
327
328 Config {
329 mode: Mode { polarity, phase },
330 bit_order,
331 }
332 }
333
269 fn set_word_size(&mut self, word_size: WordSize) { 334 fn set_word_size(&mut self, word_size: WordSize) {
270 if self.current_word_size == word_size { 335 if self.current_word_size == word_size {
271 return; 336 return;
diff --git a/embassy-stm32/src/subghz/mod.rs b/embassy-stm32/src/subghz/mod.rs
index ba333c70d..7d74569f3 100644
--- a/embassy-stm32/src/subghz/mod.rs
+++ b/embassy-stm32/src/subghz/mod.rs
@@ -82,7 +82,7 @@ use crate::{
82 pac, 82 pac,
83 peripherals::SUBGHZSPI, 83 peripherals::SUBGHZSPI,
84 rcc::sealed::RccPeripheral, 84 rcc::sealed::RccPeripheral,
85 spi::{ByteOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi}, 85 spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi},
86 time::Hertz, 86 time::Hertz,
87}; 87};
88use embassy::util::Unborrow; 88use embassy::util::Unborrow;
@@ -233,7 +233,7 @@ impl<'d, Tx, Rx> SubGhz<'d, Tx, Rx> {
233 let clk = Hertz(core::cmp::min(SUBGHZSPI::frequency().0 / 2, 16_000_000)); 233 let clk = Hertz(core::cmp::min(SUBGHZSPI::frequency().0 / 2, 16_000_000));
234 let mut config = SpiConfig::default(); 234 let mut config = SpiConfig::default();
235 config.mode = MODE_0; 235 config.mode = MODE_0;
236 config.byte_order = ByteOrder::MsbFirst; 236 config.bit_order = BitOrder::MsbFirst;
237 let spi = Spi::new(peri, sck, mosi, miso, txdma, rxdma, clk, config); 237 let spi = Spi::new(peri, sck, mosi, miso, txdma, rxdma, clk, config);
238 238
239 unsafe { wakeup() }; 239 unsafe { wakeup() };