aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-05-27 23:43:52 +0200
committerGitHub <[email protected]>2021-05-27 23:43:52 +0200
commit6898ec73182618f72c05c44f59f61b38660474c1 (patch)
treeeb5d5f1619ecd897227d5882abfe553fd940e6bf
parentc4ea7427faf08a69762bb81f329638ef90d12dc1 (diff)
parentedec5833b3288d38469598e5e606750f5ed42b91 (diff)
Merge pull request #210 from lulf/spiv2-fix
Refactor SPI and fix write bug
-rw-r--r--embassy-stm32/src/spi/mod.rs1
-rw-r--r--embassy-stm32/src/spi/v2.rs164
2 files changed, 59 insertions, 106 deletions
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index 9bb8fb60f..72276535f 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -12,6 +12,7 @@ use crate::gpio::Pin;
12pub enum Error { 12pub enum Error {
13 Framing, 13 Framing,
14 Crc, 14 Crc,
15 ModeFault,
15 Overrun, 16 Overrun,
16} 17}
17 18
diff --git a/embassy-stm32/src/spi/v2.rs b/embassy-stm32/src/spi/v2.rs
index 393adc4e9..1c10ab1b5 100644
--- a/embassy-stm32/src/spi/v2.rs
+++ b/embassy-stm32/src/spi/v2.rs
@@ -153,6 +153,54 @@ impl<'d, T: Instance> Drop for Spi<'d, T> {
153 } 153 }
154} 154}
155 155
156trait Word {}
157
158impl Word for u8 {}
159impl Word for u16 {}
160
161/// Write a single word blocking. Assumes word size have already been set.
162fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(), Error> {
163 loop {
164 let sr = unsafe { regs.sr().read() };
165 if sr.ovr() {
166 return Err(Error::Overrun);
167 } else if sr.fre() {
168 return Err(Error::Framing);
169 } else if sr.modf() {
170 return Err(Error::ModeFault);
171 } else if sr.crcerr() {
172 return Err(Error::Crc);
173 } else if sr.txe() {
174 unsafe {
175 let dr = regs.dr().ptr() as *mut W;
176 ptr::write_volatile(dr, word);
177 }
178 return Ok(());
179 }
180 }
181}
182
183/// Read a single word blocking. Assumes word size have already been set.
184fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
185 loop {
186 let sr = unsafe { regs.sr().read() };
187 if sr.ovr() {
188 return Err(Error::Overrun);
189 } else if sr.modf() {
190 return Err(Error::ModeFault);
191 } else if sr.fre() {
192 return Err(Error::Framing);
193 } else if sr.crcerr() {
194 return Err(Error::Crc);
195 } else if sr.rxne() {
196 unsafe {
197 let dr = regs.dr().ptr() as *const W;
198 return Ok(ptr::read_volatile(dr));
199 }
200 }
201 }
202}
203
156impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> { 204impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
157 type Error = Error; 205 type Error = Error;
158 206
@@ -160,29 +208,9 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u8> for Spi<'d, T> {
160 Self::set_word_size(WordSize::EightBit); 208 Self::set_word_size(WordSize::EightBit);
161 let regs = T::regs(); 209 let regs = T::regs();
162 210
163 for (i, word) in words.iter().enumerate() { 211 for word in words.iter() {
164 while unsafe { !regs.sr().read().txe() } { 212 write_word(regs, *word)?;
165 // spin 213 let _: u8 = read_word(regs)?;
166 }
167 unsafe {
168 let dr = regs.dr().ptr() as *mut u8;
169 ptr::write_volatile(dr, *word);
170 }
171 loop {
172 let sr = unsafe { regs.sr().read() };
173 if sr.fre() {
174 return Err(Error::Framing);
175 }
176 if sr.ovr() {
177 return Err(Error::Overrun);
178 }
179 if sr.crcerr() {
180 return Err(Error::Crc);
181 }
182 if !sr.txe() {
183 // loop waiting for TXE
184 }
185 }
186 } 214 }
187 215
188 Ok(()) 216 Ok(())
@@ -196,43 +224,9 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u8> for Spi<'d, T> {
196 Self::set_word_size(WordSize::EightBit); 224 Self::set_word_size(WordSize::EightBit);
197 let regs = T::regs(); 225 let regs = T::regs();
198 226
199 for (i, word) in words.iter_mut().enumerate() { 227 for word in words.iter_mut() {
200 while unsafe { !regs.sr().read().txe() } { 228 write_word(regs, *word)?;
201 // spin 229 *word = read_word(regs)?;
202 }
203 unsafe {
204 let dr = regs.dr().ptr() as *mut u8;
205 ptr::write_volatile(dr, *word);
206 }
207 loop {
208 let sr = unsafe { regs.sr().read() };
209 if sr.rxne() {
210 break;
211 }
212 if sr.fre() {
213 return Err(Error::Framing);
214 }
215 if sr.ovr() {
216 return Err(Error::Overrun);
217 }
218 if sr.crcerr() {
219 return Err(Error::Crc);
220 }
221 }
222 unsafe {
223 let dr = regs.dr().ptr() as *const u8;
224 *word = ptr::read_volatile(dr);
225 }
226 let sr = unsafe { regs.sr().read() };
227 if sr.fre() {
228 return Err(Error::Framing);
229 }
230 if sr.ovr() {
231 return Err(Error::Overrun);
232 }
233 if sr.crcerr() {
234 return Err(Error::Crc);
235 }
236 } 230 }
237 231
238 Ok(words) 232 Ok(words)
@@ -247,28 +241,8 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Write<u16> for Spi<'d, T> {
247 let regs = T::regs(); 241 let regs = T::regs();
248 242
249 for word in words.iter() { 243 for word in words.iter() {
250 while unsafe { !regs.sr().read().txe() } { 244 write_word(regs, *word)?;
251 // spin 245 let _: u16 = read_word(regs)?;
252 }
253 unsafe {
254 let dr = regs.dr().ptr() as *mut u16;
255 ptr::write_volatile(dr, *word);
256 }
257 loop {
258 let sr = unsafe { regs.sr().read() };
259 if sr.fre() {
260 return Err(Error::Framing);
261 }
262 if sr.ovr() {
263 return Err(Error::Overrun);
264 }
265 if sr.crcerr() {
266 return Err(Error::Crc);
267 }
268 if !sr.txe() {
269 // loop waiting for TXE
270 }
271 }
272 } 246 }
273 247
274 Ok(()) 248 Ok(())
@@ -283,30 +257,8 @@ impl<'d, T: Instance> embedded_hal::blocking::spi::Transfer<u16> for Spi<'d, T>
283 let regs = T::regs(); 257 let regs = T::regs();
284 258
285 for word in words.iter_mut() { 259 for word in words.iter_mut() {
286 while unsafe { !regs.sr().read().txe() } { 260 write_word(regs, *word)?;
287 // spin 261 *word = read_word(regs)?;
288 }
289 unsafe {
290 let dr = regs.dr().ptr() as *mut u16;
291 ptr::write_volatile(dr, *word);
292 }
293 while unsafe { !regs.sr().read().rxne() } {
294 // spin waiting for inbound to shift in.
295 }
296 unsafe {
297 let dr = regs.dr().ptr() as *const u16;
298 *word = ptr::read_volatile(dr);
299 }
300 let sr = unsafe { regs.sr().read() };
301 if sr.fre() {
302 return Err(Error::Framing);
303 }
304 if sr.ovr() {
305 return Err(Error::Overrun);
306 }
307 if sr.crcerr() {
308 return Err(Error::Crc);
309 }
310 } 262 }
311 263
312 Ok(words) 264 Ok(words)