diff options
| author | dstric-aqueduct <[email protected]> | 2024-10-15 11:48:54 -0400 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-12-03 00:14:24 +0100 |
| commit | dcf228e4487982b2aef577eb914d80fcb2ecbdc3 (patch) | |
| tree | 9b8f5d733823a3973b50d33957c873b0e8ff1958 /embassy-rp | |
| parent | 333284588a4c2639913df47099220d2dece50834 (diff) | |
Add `set_config` method to RP SPI driver
Add a `set_config` method to `Spi` to allow reconfiguring SPI mode after creation.
The existing implementation of the `embassy-embedded-hal` trait `SetConfig` is changed to use the new method.
Existing uses of `SetConfig` trait may need to explicitly call the trait method to maintain current return type.
Diffstat (limited to 'embassy-rp')
| -rw-r--r-- | embassy-rp/src/spi.rs | 52 |
1 files changed, 34 insertions, 18 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 | } |
