diff options
| -rw-r--r-- | embassy-rp/src/spi.rs | 52 | ||||
| -rw-r--r-- | examples/rp23/src/bin/spi_sdmmc.rs | 2 |
2 files changed, 35 insertions, 19 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/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. |
