aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src/spi.rs
diff options
context:
space:
mode:
authordstric-aqueduct <[email protected]>2024-10-15 11:48:54 -0400
committerDario Nieuwenhuis <[email protected]>2024-12-03 00:14:24 +0100
commitdcf228e4487982b2aef577eb914d80fcb2ecbdc3 (patch)
tree9b8f5d733823a3973b50d33957c873b0e8ff1958 /embassy-rp/src/spi.rs
parent333284588a4c2639913df47099220d2dece50834 (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/src/spi.rs')
-rw-r--r--embassy-rp/src/spi.rs52
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
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 }