aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2023-02-07 22:06:25 +0000
committerGitHub <[email protected]>2023-02-07 22:06:25 +0000
commitc4a2c62096c910f3adcfbcf5f94c36ef0eede08e (patch)
tree93b3964e762f433be630500f4d978a2d7a77fac8
parent366fab5b872e5d00fd84408f04cf00faf988d160 (diff)
parente3174d7a998ead0fbe5ddadf59914cc16a561a44 (diff)
Merge #1199
1199: STM32 SPI: Set clk-pin pull-up/-down to match spi clock polarity r=Dirbaio a=jr-oss Fixes #1094 There are some proposed solutions in #1094 > Keep the DMA transaction open across calls to read/write This may be problematic if the user changes bus settings between calls, and also the reference manual says the chip should not be placed into low power mode while SPI is enabled As already described, this is problematic and against reference manual recommendation > Set the CLK (and maybe MOSI) pins as pull-down on setup (or pull-up, depending on config - and this would need to be updated if the user modified the config) This is less good than driving the pin to the correct value, but may be better than nothing That is also my preferred solution. See below citation from reference manual. > Document this and require users fix it themselves (add a pull-up/down resistor - or configure the pins as pull-up/pull-down before passing them into SPI setup) Setting internal pull-up/-down won't work, because `sck.set_as_af()` will change the gpio pull mode to none: https://github.com/embassy-rs/embassy/blob/master/embassy-stm32/src/gpio.rs#L552-L555 > Dig around in the reference manual and determine if there is a better way to start/stop a DMA transaction while keeping active control of the clock the whole time I haven't found a better way ------ From ST reference manual RM0394 (L4) (Same note in RM0399 (H7) / RM0038 (L1) / RM0316 /F3)): 40.4.6 Communication formats ... The idle state of SCK must correspond to the polarity selected in the SPIx_CR1 register (by pulling up SCK if CPOL=1 or pulling down SCK if CPOL=0). Co-authored-by: Ralf <[email protected]>
-rw-r--r--embassy-stm32/src/spi/mod.rs10
1 files changed, 8 insertions, 2 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 5b81c791a..e5ba746e4 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -10,7 +10,7 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO
10use self::sealed::WordSize; 10use self::sealed::WordSize;
11use crate::dma::{slice_ptr_parts, Transfer}; 11use crate::dma::{slice_ptr_parts, Transfer};
12use crate::gpio::sealed::{AFType, Pin as _}; 12use crate::gpio::sealed::{AFType, Pin as _};
13use crate::gpio::AnyPin; 13use crate::gpio::{AnyPin, Pull};
14use crate::pac::spi::{regs, vals, Spi as Regs}; 14use crate::pac::spi::{regs, vals, Spi as Regs};
15use crate::rcc::RccPeripheral; 15use crate::rcc::RccPeripheral;
16use crate::time::Hertz; 16use crate::time::Hertz;
@@ -93,8 +93,14 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
93 config: Config, 93 config: Config,
94 ) -> Self { 94 ) -> Self {
95 into_ref!(peri, sck, mosi, miso); 95 into_ref!(peri, sck, mosi, miso);
96
97 let sck_pull_mode = match config.mode.polarity {
98 Polarity::IdleLow => Pull::Down,
99 Polarity::IdleHigh => Pull::Up,
100 };
101
96 unsafe { 102 unsafe {
97 sck.set_as_af(sck.af_num(), AFType::OutputPushPull); 103 sck.set_as_af_pull(sck.af_num(), AFType::OutputPushPull, sck_pull_mode);
98 sck.set_speed(crate::gpio::Speed::VeryHigh); 104 sck.set_speed(crate::gpio::Speed::VeryHigh);
99 mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull); 105 mosi.set_as_af(mosi.af_num(), AFType::OutputPushPull);
100 mosi.set_speed(crate::gpio::Speed::VeryHigh); 106 mosi.set_speed(crate::gpio::Speed::VeryHigh);