aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-12-11 15:37:06 +0000
committerGitHub <[email protected]>2025-12-11 15:37:06 +0000
commitba04de6f56f837eafce6b9ccd754c51e5302649f (patch)
treeea77e21d71d9c0c835407c3770782598531cbd0a
parentf650afc33b2d6b39116f27c6545c5f2d9e3c7d06 (diff)
parent3bc913b77572e91e38709071f7f7bb8777847ccf (diff)
Merge pull request #5039 from plorefice/stm32-spi-config-ss-polarity
STM32: make SPI SS signal polarity configurable
-rw-r--r--embassy-stm32/src/spi/mod.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index c90e0cef4..af51b79b4 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -64,6 +64,16 @@ pub enum Direction {
64 Receive, 64 Receive,
65} 65}
66 66
67/// Slave Select (SS) pin polarity.
68#[derive(Debug, PartialEq, Eq, Clone, Copy)]
69#[cfg_attr(feature = "defmt", derive(defmt::Format))]
70pub enum SlaveSelectPolarity {
71 /// SS active high
72 ActiveHigh,
73 /// SS active low
74 ActiveLow,
75}
76
67/// SPI configuration. 77/// SPI configuration.
68#[non_exhaustive] 78#[non_exhaustive]
69#[derive(Copy, Clone)] 79#[derive(Copy, Clone)]
@@ -86,6 +96,9 @@ pub struct Config {
86 /// NSS output enabled (SSM = 0, SSOE = 1): The NSS signal is driven low when the master starts the communication and is kept low until the SPI is disabled. 96 /// NSS output enabled (SSM = 0, SSOE = 1): The NSS signal is driven low when the master starts the communication and is kept low until the SPI is disabled.
87 /// NSS output disabled (SSM = 0, SSOE = 0): For devices set as slave, the NSS pin acts as a classical NSS input: the slave is selected when NSS is low and deselected when NSS high. 97 /// NSS output disabled (SSM = 0, SSOE = 0): For devices set as slave, the NSS pin acts as a classical NSS input: the slave is selected when NSS is low and deselected when NSS high.
88 pub nss_output_disable: bool, 98 pub nss_output_disable: bool,
99 /// Slave Select (SS) pin polarity.
100 #[cfg(any(spi_v4, spi_v5, spi_v6))]
101 pub nss_polarity: SlaveSelectPolarity,
89} 102}
90 103
91impl Default for Config { 104impl Default for Config {
@@ -97,6 +110,8 @@ impl Default for Config {
97 miso_pull: Pull::None, 110 miso_pull: Pull::None,
98 gpio_speed: Speed::VeryHigh, 111 gpio_speed: Speed::VeryHigh,
99 nss_output_disable: false, 112 nss_output_disable: false,
113 #[cfg(any(spi_v4, spi_v5, spi_v6))]
114 nss_polarity: SlaveSelectPolarity::ActiveHigh,
100 } 115 }
101 } 116 }
102} 117}
@@ -123,6 +138,14 @@ impl Config {
123 } 138 }
124 } 139 }
125 140
141 #[cfg(any(spi_v4, spi_v5, spi_v6))]
142 fn raw_nss_polarity(&self) -> vals::Ssiop {
143 match self.nss_polarity {
144 SlaveSelectPolarity::ActiveHigh => vals::Ssiop::ACTIVE_HIGH,
145 SlaveSelectPolarity::ActiveLow => vals::Ssiop::ACTIVE_LOW,
146 }
147 }
148
126 #[cfg(gpio_v1)] 149 #[cfg(gpio_v1)]
127 fn sck_af(&self) -> AfType { 150 fn sck_af(&self) -> AfType {
128 AfType::output(OutputType::PushPull, self.gpio_speed) 151 AfType::output(OutputType::PushPull, self.gpio_speed)
@@ -305,6 +328,7 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
305 #[cfg(any(spi_v4, spi_v5, spi_v6))] 328 #[cfg(any(spi_v4, spi_v5, spi_v6))]
306 { 329 {
307 let ssoe = CM::MASTER == vals::Master::MASTER && !config.nss_output_disable; 330 let ssoe = CM::MASTER == vals::Master::MASTER && !config.nss_output_disable;
331 let ssiop = config.raw_nss_polarity();
308 regs.ifcr().write(|w| w.0 = 0xffff_ffff); 332 regs.ifcr().write(|w| w.0 = 0xffff_ffff);
309 regs.cfg2().modify(|w| { 333 regs.cfg2().modify(|w| {
310 w.set_ssoe(ssoe); 334 w.set_ssoe(ssoe);
@@ -318,7 +342,7 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
318 w.set_midi(0); 342 w.set_midi(0);
319 w.set_mssi(0); 343 w.set_mssi(0);
320 w.set_afcntr(true); 344 w.set_afcntr(true);
321 w.set_ssiop(vals::Ssiop::ACTIVE_HIGH); 345 w.set_ssiop(ssiop);
322 }); 346 });
323 regs.cfg1().modify(|w| { 347 regs.cfg1().modify(|w| {
324 w.set_crcen(false); 348 w.set_crcen(false);
@@ -366,6 +390,8 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
366 390
367 #[cfg(any(spi_v4, spi_v5, spi_v6))] 391 #[cfg(any(spi_v4, spi_v5, spi_v6))]
368 { 392 {
393 let ssiop = config.raw_nss_polarity();
394
369 self.info.regs.cr1().modify(|w| { 395 self.info.regs.cr1().modify(|w| {
370 w.set_spe(false); 396 w.set_spe(false);
371 }); 397 });
@@ -374,6 +400,7 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
374 w.set_cpha(cpha); 400 w.set_cpha(cpha);
375 w.set_cpol(cpol); 401 w.set_cpol(cpol);
376 w.set_lsbfirst(lsbfirst); 402 w.set_lsbfirst(lsbfirst);
403 w.set_ssiop(ssiop);
377 }); 404 });
378 self.info.regs.cfg1().modify(|w| { 405 self.info.regs.cfg1().modify(|w| {
379 w.set_mbr(br); 406 w.set_mbr(br);
@@ -446,6 +473,13 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
446 // NSS output disabled if SSOE=0 or if SSM=1 software slave management enabled 473 // NSS output disabled if SSOE=0 or if SSM=1 software slave management enabled
447 let nss_output_disable = !ssoe || cfg.ssm(); 474 let nss_output_disable = !ssoe || cfg.ssm();
448 475
476 #[cfg(any(spi_v4, spi_v5, spi_v6))]
477 let nss_polarity = if cfg.ssiop() == vals::Ssiop::ACTIVE_LOW {
478 SlaveSelectPolarity::ActiveLow
479 } else {
480 SlaveSelectPolarity::ActiveHigh
481 };
482
449 Config { 483 Config {
450 mode: Mode { polarity, phase }, 484 mode: Mode { polarity, phase },
451 bit_order, 485 bit_order,
@@ -453,6 +487,8 @@ impl<'d, M: PeriMode, CM: CommunicationMode> Spi<'d, M, CM> {
453 miso_pull, 487 miso_pull,
454 gpio_speed: self.gpio_speed, 488 gpio_speed: self.gpio_speed,
455 nss_output_disable, 489 nss_output_disable,
490 #[cfg(any(spi_v4, spi_v5, spi_v6))]
491 nss_polarity,
456 } 492 }
457 } 493 }
458 494
@@ -769,7 +805,7 @@ impl<'d> Spi<'d, Async, Master> {
769 ) 805 )
770 } 806 }
771 807
772 /// Create a new SPI driver, in bidirectional mode, specifically in tranmit mode 808 /// Create a new SPI driver, in bidirectional mode, specifically in tranmit mode
773 #[cfg(any(spi_v1, spi_v2, spi_v3))] 809 #[cfg(any(spi_v1, spi_v2, spi_v3))]
774 pub fn new_bidi<T: Instance, #[cfg(afio)] A>( 810 pub fn new_bidi<T: Instance, #[cfg(afio)] A>(
775 peri: Peri<'d, T>, 811 peri: Peri<'d, T>,