@@ -167,6 +167,9 @@ impl Qspi {
167167 }
168168
169169 /// Helper for error paths.
170+ ///
171+ /// Disables FIFO Threshold, Transfer Complete, Transfer Error, and Timeout
172+ /// interrupts.
170173 fn disable_all_interrupts ( & self ) {
171174 self . reg . cr . modify ( |_, w| {
172175 w. ftie ( )
@@ -180,6 +183,51 @@ impl Qspi {
180183 } ) ;
181184 }
182185
186+ /// Returns the number of valid bytes being held in the FIFO queue if a
187+ /// QSPI timeout or transfer error hasn't occurred.
188+ #[ inline( always) ]
189+ fn get_fifo_level ( & self ) -> Result < usize , QspiError > {
190+ let sr = self . reg . sr . read ( ) ;
191+
192+ // Check timeout bit.
193+ if sr. tof ( ) . bit_is_set ( ) {
194+ // Clear timeout bit and return.
195+ self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
196+ return Err ( QspiError :: Timeout ) ;
197+ }
198+ // Check transfer error bit.
199+ if sr. tef ( ) . bit_is_set ( ) {
200+ // Clear transfer error bit and return.
201+ self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
202+ return Err ( QspiError :: TransferError ) ;
203+ }
204+ // Re-enable transfer error and timeout interrupts to make sure we
205+ // catch any future errors.
206+ self . reg
207+ . cr
208+ . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
209+ Ok ( usize:: from ( sr. flevel ( ) . bits ( ) ) )
210+ }
211+
212+ /// Wait for the Transfer Complete flag to get set.
213+ ///
214+ /// Note: this function returning does not guarantee that the BUSY flag is
215+ /// clear.
216+ #[ inline( always) ]
217+ fn wait_for_transfer_complete ( & self ) {
218+ // Disable FIFO threshold interrupt, and enable transfer complete
219+ // interrupts.
220+ self . reg
221+ . cr
222+ . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
223+ while self . transfer_not_complete ( ) {
224+ // Unmask our interrupt.
225+ sys_irq_control ( self . interrupt , true ) ;
226+ // And wait for it to arrive.
227+ sys_recv_notification ( self . interrupt ) ;
228+ }
229+ }
230+
183231 fn write_impl (
184232 & self ,
185233 command : Command ,
@@ -238,24 +286,10 @@ impl Qspi {
238286 // off the front.
239287 let mut data = data;
240288 while !data. is_empty ( ) {
241- let sr = self . reg . sr . read ( ) ;
242-
243- if sr. tof ( ) . bit_is_set ( ) {
244- self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
245- return Err ( QspiError :: Timeout ) ;
246- }
247- if sr. tef ( ) . bit_is_set ( ) {
248- self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
249- return Err ( QspiError :: TransferError ) ;
250- }
251-
252- // Make sure our errors are enabled
253- self . reg
254- . cr
255- . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
289+ // Check for any errors
290+ let fl = self . get_fifo_level ( ) ?;
256291
257292 // How much space is in the FIFO?
258- let fl = usize:: from ( sr. flevel ( ) . bits ( ) ) ;
259293 let ffree = FIFO_SIZE - fl;
260294 if ffree >= FIFO_THRESH . min ( data. len ( ) ) {
261295 // Calculate the write size. Note that this may be bigger than
@@ -293,18 +327,11 @@ impl Qspi {
293327 }
294328
295329 // We're now interested in transfer complete, not FIFO ready.
296- self . reg
297- . cr
298- . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
299- while self . transfer_not_complete ( ) {
300- // Unmask our interrupt.
301- sys_irq_control ( self . interrupt , true ) ;
302- // And wait for it to arrive.
303- sys_recv_notification ( self . interrupt ) ;
304- }
305- self . reg . cr . modify ( |_, w| {
306- w. tcie ( ) . clear_bit ( ) . teie ( ) . clear_bit ( ) . toie ( ) . clear_bit ( )
307- } ) ;
330+ self . wait_for_transfer_complete ( ) ;
331+
332+ // Clean up by disabling our interrupt sources.
333+ self . disable_all_interrupts ( ) ;
334+
308335 Ok ( ( ) )
309336 }
310337
@@ -375,22 +402,10 @@ impl Qspi {
375402 // perform transfers.
376403 let mut out = out;
377404 while !out. is_empty ( ) {
378- let sr = self . reg . sr . read ( ) ;
405+ // Get the FIFO level if no errors have occurred.
406+ let fl = self . get_fifo_level ( ) ?;
379407
380- if sr. tof ( ) . bit_is_set ( ) {
381- self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
382- return Err ( QspiError :: Timeout ) ;
383- }
384- if sr. tef ( ) . bit_is_set ( ) {
385- self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
386- return Err ( QspiError :: TransferError ) ;
387- }
388- // Make sure our errors are enabled
389- self . reg
390- . cr
391- . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
392408 // Is there enough to read that we want to bother with it?
393- let fl = usize:: from ( sr. flevel ( ) . bits ( ) ) ;
394409 if fl < FIFO_THRESH . min ( out. len ( ) ) {
395410 // Nope! Let's wait for more bytes.
396411
@@ -438,27 +453,11 @@ impl Qspi {
438453 // necessarily imply the BUSY flag is clear, but since commands are
439454 // issued into a FIFO, we can issue the next command even while BUSY is
440455 // set, it appears.
441- self . reg
442- . cr
443- . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
444- while self . transfer_not_complete ( ) {
445- // Unmask our interrupt.
446- sys_irq_control ( self . interrupt , true ) ;
447- // And wait for it to arrive.
448- sys_recv_notification ( self . interrupt ) ;
449- }
456+ self . wait_for_transfer_complete ( ) ;
450457
451458 // Clean up by disabling our interrupt sources.
452- self . reg . cr . modify ( |_, w| {
453- w. ftie ( )
454- . clear_bit ( )
455- . tcie ( )
456- . clear_bit ( )
457- . teie ( )
458- . clear_bit ( )
459- . toie ( )
460- . clear_bit ( )
461- } ) ;
459+ self . disable_all_interrupts ( ) ;
460+
462461 Ok ( ( ) )
463462 }
464463
0 commit comments