diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-12-02 23:37:57 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-12-02 23:37:57 +0000 |
| commit | a5ee98c402126808d07dab5121332455ee0214c0 (patch) | |
| tree | 806ce87ae5d006a036be09c70da686b0b76c75f5 | |
| parent | 4b901f9a5b6706841c01dfea149504bc8abf33eb (diff) | |
| parent | 0138bc5dd8d0c49c86b01668b0af8a2e8dca699c (diff) | |
Merge pull request #3600 from embassy-rs/patch-1
Add set_config method to RP SPI driver (rebased #3419)
| -rw-r--r-- | embassy-rp/src/spi.rs | 52 | ||||
| -rw-r--r-- | examples/rp/src/bin/spi_sdmmc.rs | 3 | ||||
| -rw-r--r-- | examples/rp23/src/bin/spi_sdmmc.rs | 2 |
3 files changed, 36 insertions, 21 deletions
diff --git a/embassy-rp/src/spi.rs b/embassy-rp/src/spi.rs index a8f4e72c7..c48b5c54f 100644 --- a/embassy-rp/src/spi.rs +++ b/embassy-rp/src/spi.rs | |||
| @@ -84,16 +84,9 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 84 | ) -> Self { | 84 | ) -> Self { |
| 85 | into_ref!(inner); | 85 | into_ref!(inner); |
| 86 | 86 | ||
| 87 | let p = inner.regs(); | 87 | Self::apply_config(&inner, &config); |
| 88 | let (presc, postdiv) = calc_prescs(config.frequency); | ||
| 89 | 88 | ||
| 90 | p.cpsr().write(|w| w.set_cpsdvsr(presc)); | 89 | let p = inner.regs(); |
| 91 | p.cr0().write(|w| { | ||
| 92 | w.set_dss(0b0111); // 8bit | ||
| 93 | w.set_spo(config.polarity == Polarity::IdleHigh); | ||
| 94 | w.set_sph(config.phase == Phase::CaptureOnSecondTransition); | ||
| 95 | w.set_scr(postdiv); | ||
| 96 | }); | ||
| 97 | 90 | ||
| 98 | // Always enable DREQ signals -- harmless if DMA is not listening | 91 | // Always enable DREQ signals -- harmless if DMA is not listening |
| 99 | p.dmacr().write(|reg| { | 92 | p.dmacr().write(|reg| { |
| @@ -164,6 +157,23 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 164 | } | 157 | } |
| 165 | } | 158 | } |
| 166 | 159 | ||
| 160 | /// Private function to apply SPI configuration (phase, polarity, frequency) settings. | ||
| 161 | /// | ||
| 162 | /// Driver should be disabled before making changes and reenabled after the modifications | ||
| 163 | /// are applied. | ||
| 164 | fn apply_config(inner: &PeripheralRef<'d, T>, config: &Config) { | ||
| 165 | let p = inner.regs(); | ||
| 166 | let (presc, postdiv) = calc_prescs(config.frequency); | ||
| 167 | |||
| 168 | p.cpsr().write(|w| w.set_cpsdvsr(presc)); | ||
| 169 | p.cr0().write(|w| { | ||
| 170 | w.set_dss(0b0111); // 8bit | ||
| 171 | w.set_spo(config.polarity == Polarity::IdleHigh); | ||
| 172 | w.set_sph(config.phase == Phase::CaptureOnSecondTransition); | ||
| 173 | w.set_scr(postdiv); | ||
| 174 | }); | ||
| 175 | } | ||
| 176 | |||
| 167 | /// Write data to SPI blocking execution until done. | 177 | /// Write data to SPI blocking execution until done. |
| 168 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { | 178 | pub fn blocking_write(&mut self, data: &[u8]) -> Result<(), Error> { |
| 169 | let p = self.inner.regs(); | 179 | let p = self.inner.regs(); |
| @@ -244,6 +254,20 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> { | |||
| 244 | // enable | 254 | // enable |
| 245 | p.cr1().write(|w| w.set_sse(true)); | 255 | p.cr1().write(|w| w.set_sse(true)); |
| 246 | } | 256 | } |
| 257 | |||
| 258 | /// Set SPI config. | ||
| 259 | pub fn set_config(&mut self, config: &Config) { | ||
| 260 | let p = self.inner.regs(); | ||
| 261 | |||
| 262 | // disable | ||
| 263 | p.cr1().write(|w| w.set_sse(false)); | ||
| 264 | |||
| 265 | // change stuff | ||
| 266 | Self::apply_config(&self.inner, config); | ||
| 267 | |||
| 268 | // enable | ||
| 269 | p.cr1().write(|w| w.set_sse(true)); | ||
| 270 | } | ||
| 247 | } | 271 | } |
| 248 | 272 | ||
| 249 | impl<'d, T: Instance> Spi<'d, T, Blocking> { | 273 | impl<'d, T: Instance> Spi<'d, T, Blocking> { |
| @@ -697,15 +721,7 @@ impl<'d, T: Instance, M: Mode> SetConfig for Spi<'d, T, M> { | |||
| 697 | type Config = Config; | 721 | type Config = Config; |
| 698 | type ConfigError = (); | 722 | type ConfigError = (); |
| 699 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { | 723 | fn set_config(&mut self, config: &Self::Config) -> Result<(), ()> { |
| 700 | let p = self.inner.regs(); | 724 | self.set_config(config); |
| 701 | let (presc, postdiv) = calc_prescs(config.frequency); | ||
| 702 | p.cpsr().write(|w| w.set_cpsdvsr(presc)); | ||
| 703 | p.cr0().write(|w| { | ||
| 704 | w.set_dss(0b0111); // 8bit | ||
| 705 | w.set_spo(config.polarity == Polarity::IdleHigh); | ||
| 706 | w.set_sph(config.phase == Phase::CaptureOnSecondTransition); | ||
| 707 | w.set_scr(postdiv); | ||
| 708 | }); | ||
| 709 | 725 | ||
| 710 | Ok(()) | 726 | Ok(()) |
| 711 | } | 727 | } |
diff --git a/examples/rp/src/bin/spi_sdmmc.rs b/examples/rp/src/bin/spi_sdmmc.rs index 4cbc82f7b..a60850d0f 100644 --- a/examples/rp/src/bin/spi_sdmmc.rs +++ b/examples/rp/src/bin/spi_sdmmc.rs | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | #![no_main] | 7 | #![no_main] |
| 8 | 8 | ||
| 9 | use defmt::*; | 9 | use defmt::*; |
| 10 | use embassy_embedded_hal::SetConfig; | ||
| 11 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 12 | use embassy_rp::spi::Spi; | 11 | use embassy_rp::spi::Spi; |
| 13 | use embassy_rp::{gpio, spi}; | 12 | use embassy_rp::{gpio, spi}; |
| @@ -51,7 +50,7 @@ async fn main(_spawner: Spawner) { | |||
| 51 | // Now that the card is initialized, the SPI clock can go faster | 50 | // Now that the card is initialized, the SPI clock can go faster |
| 52 | let mut config = spi::Config::default(); | 51 | let mut config = spi::Config::default(); |
| 53 | config.frequency = 16_000_000; | 52 | config.frequency = 16_000_000; |
| 54 | sdcard.spi(|dev| dev.bus_mut().set_config(&config)).ok(); | 53 | sdcard.spi(|dev| dev.bus_mut().set_config(&config)); |
| 55 | 54 | ||
| 56 | // Now let's look for volumes (also known as partitions) on our block device. | 55 | // Now let's look for volumes (also known as partitions) on our block device. |
| 57 | // To do this we need a Volume Manager. It will take ownership of the block device. | 56 | // To do this we need a Volume Manager. It will take ownership of the block device. |
diff --git a/examples/rp23/src/bin/spi_sdmmc.rs b/examples/rp23/src/bin/spi_sdmmc.rs index aa6b44ffa..cfc38dfd9 100644 --- a/examples/rp23/src/bin/spi_sdmmc.rs +++ b/examples/rp23/src/bin/spi_sdmmc.rs | |||
| @@ -56,7 +56,7 @@ async fn main(_spawner: Spawner) { | |||
| 56 | // Now that the card is initialized, the SPI clock can go faster | 56 | // Now that the card is initialized, the SPI clock can go faster |
| 57 | let mut config = spi::Config::default(); | 57 | let mut config = spi::Config::default(); |
| 58 | config.frequency = 16_000_000; | 58 | config.frequency = 16_000_000; |
| 59 | sdcard.spi(|dev| dev.bus_mut().set_config(&config)).ok(); | 59 | sdcard.spi(|dev| SetConfig::set_config(dev.bus_mut(), &config)).ok(); |
| 60 | 60 | ||
| 61 | // Now let's look for volumes (also known as partitions) on our block device. | 61 | // Now let's look for volumes (also known as partitions) on our block device. |
| 62 | // To do this we need a Volume Manager. It will take ownership of the block device. | 62 | // To do this we need a Volume Manager. It will take ownership of the block device. |
