@@ -142,6 +142,9 @@ impl Qspi {
142
142
}
143
143
144
144
/// Helper for error paths.
145
+ ///
146
+ /// Disables FIFO Threshold, Transfer Complete, Transfer Error, and Timeout
147
+ /// interrupts.
145
148
fn disable_all_interrupts ( & self ) {
146
149
self . reg . cr . modify ( |_, w| {
147
150
w. ftie ( )
@@ -155,6 +158,49 @@ impl Qspi {
155
158
} ) ;
156
159
}
157
160
161
+ /// Returns the number of valid bytes being held in the FIFO queue if a
162
+ /// QSPI timeout or transfer error hasn't occurred.
163
+ fn get_fifo_level ( & self ) -> Result < usize , QspiError > {
164
+ let sr = self . reg . sr . read ( ) ;
165
+
166
+ // Check timeout bit.
167
+ if sr. tof ( ) . bit_is_set ( ) {
168
+ // Clear timeout bit and return.
169
+ self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
170
+ return Err ( QspiError :: Timeout ) ;
171
+ }
172
+ // Check transfer error bit.
173
+ if sr. tef ( ) . bit_is_set ( ) {
174
+ // Clear transfer error bit and return.
175
+ self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
176
+ return Err ( QspiError :: TransferError ) ;
177
+ }
178
+ // Re-enable transfer error and timeout interrupts to make sure we
179
+ // catch any future errors.
180
+ self . reg
181
+ . cr
182
+ . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
183
+ Ok ( usize:: from ( sr. flevel ( ) . bits ( ) ) )
184
+ }
185
+
186
+ /// Wait for the Transfer Complete flag to get set.
187
+ ///
188
+ /// Note: this function returning does not guarantee that the BUSY flag is
189
+ /// clear.
190
+ fn wait_for_transfer_complete ( & self ) {
191
+ // Disable FIFO threshold interrupt, and enable transfer complete
192
+ // interrupts.
193
+ self . reg
194
+ . cr
195
+ . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
196
+ while self . transfer_not_complete ( ) {
197
+ // Unmask our interrupt.
198
+ sys_irq_control ( self . interrupt , true ) ;
199
+ // And wait for it to arrive.
200
+ sys_recv_notification ( self . interrupt ) ;
201
+ }
202
+ }
203
+
158
204
fn write_impl (
159
205
& self ,
160
206
command : Command ,
@@ -213,24 +259,10 @@ impl Qspi {
213
259
// off the front.
214
260
let mut data = data;
215
261
while !data. is_empty ( ) {
216
- let sr = self . reg . sr . read ( ) ;
217
-
218
- if sr. tof ( ) . bit_is_set ( ) {
219
- self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
220
- return Err ( QspiError :: Timeout ) ;
221
- }
222
- if sr. tef ( ) . bit_is_set ( ) {
223
- self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
224
- return Err ( QspiError :: TransferError ) ;
225
- }
226
-
227
- // Make sure our errors are enabled
228
- self . reg
229
- . cr
230
- . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
262
+ // Check for any errors
263
+ let fl = self . get_fifo_level ( ) ?;
231
264
232
265
// How much space is in the FIFO?
233
- let fl = usize:: from ( sr. flevel ( ) . bits ( ) ) ;
234
266
let ffree = FIFO_SIZE - fl;
235
267
if ffree >= FIFO_THRESH . min ( data. len ( ) ) {
236
268
// Calculate the write size. Note that this may be bigger than
@@ -268,18 +300,11 @@ impl Qspi {
268
300
}
269
301
270
302
// We're now interested in transfer complete, not FIFO ready.
271
- self . reg
272
- . cr
273
- . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
274
- while self . transfer_not_complete ( ) {
275
- // Unmask our interrupt.
276
- sys_irq_control ( self . interrupt , true ) ;
277
- // And wait for it to arrive.
278
- sys_recv_notification ( self . interrupt ) ;
279
- }
280
- self . reg . cr . modify ( |_, w| {
281
- w. tcie ( ) . clear_bit ( ) . teie ( ) . clear_bit ( ) . toie ( ) . clear_bit ( )
282
- } ) ;
303
+ self . wait_for_transfer_complete ( ) ;
304
+
305
+ // Clean up by disabling our interrupt sources.
306
+ self . disable_all_interrupts ( ) ;
307
+
283
308
Ok ( ( ) )
284
309
}
285
310
@@ -340,22 +365,10 @@ impl Qspi {
340
365
// perform transfers.
341
366
let mut out = out;
342
367
while !out. is_empty ( ) {
343
- let sr = self . reg . sr . read ( ) ;
368
+ // Get the FIFO level if no errors have occurred.
369
+ let fl = self . get_fifo_level ( ) ?;
344
370
345
- if sr. tof ( ) . bit_is_set ( ) {
346
- self . reg . fcr . modify ( |_, w| w. ctof ( ) . set_bit ( ) ) ;
347
- return Err ( QspiError :: Timeout ) ;
348
- }
349
- if sr. tef ( ) . bit_is_set ( ) {
350
- self . reg . fcr . modify ( |_, w| w. ctef ( ) . set_bit ( ) ) ;
351
- return Err ( QspiError :: TransferError ) ;
352
- }
353
- // Make sure our errors are enabled
354
- self . reg
355
- . cr
356
- . modify ( |_, w| w. teie ( ) . set_bit ( ) . toie ( ) . set_bit ( ) ) ;
357
371
// Is there enough to read that we want to bother with it?
358
- let fl = usize:: from ( sr. flevel ( ) . bits ( ) ) ;
359
372
if fl < FIFO_THRESH . min ( out. len ( ) ) {
360
373
// Nope! Let's wait for more bytes.
361
374
@@ -403,27 +416,11 @@ impl Qspi {
403
416
// necessarily imply the BUSY flag is clear, but since commands are
404
417
// issued into a FIFO, we can issue the next command even while BUSY is
405
418
// set, it appears.
406
- self . reg
407
- . cr
408
- . modify ( |_, w| w. ftie ( ) . clear_bit ( ) . tcie ( ) . set_bit ( ) ) ;
409
- while self . transfer_not_complete ( ) {
410
- // Unmask our interrupt.
411
- sys_irq_control ( self . interrupt , true ) ;
412
- // And wait for it to arrive.
413
- sys_recv_notification ( self . interrupt ) ;
414
- }
419
+ self . wait_for_transfer_complete ( ) ;
415
420
416
421
// Clean up by disabling our interrupt sources.
417
- self . reg . cr . modify ( |_, w| {
418
- w. ftie ( )
419
- . clear_bit ( )
420
- . tcie ( )
421
- . clear_bit ( )
422
- . teie ( )
423
- . clear_bit ( )
424
- . toie ( )
425
- . clear_bit ( )
426
- } ) ;
422
+ self . disable_all_interrupts ( ) ;
423
+
427
424
Ok ( ( ) )
428
425
}
429
426
0 commit comments