aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/spi.rs52
-rw-r--r--examples/rp23/src/bin/spi_sdmmc.rs2
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
249impl<'d, T: Instance> Spi<'d, T, Blocking> { 273impl<'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.