@@ -19,10 +19,19 @@ use zerocopy::IntoBytes;
19
19
const FIFO_SIZE : usize = 32 ;
20
20
const FIFO_THRESH : usize = 16 ;
21
21
22
+ // In a perfect world we would use quad read everywhere because it is fast.
23
+ // We've seen some inconsistency with the quad read command on some targets
24
+ // so limit its use to targets where we've confirmed.
25
+ pub enum ReadSetting {
26
+ Single ,
27
+ Quad ,
28
+ }
29
+
22
30
/// Wrapper for a reference to the register block.
23
31
pub struct Qspi {
24
32
reg : & ' static device:: quadspi:: RegisterBlock ,
25
33
interrupt : u32 ,
34
+ read_command : Command ,
26
35
}
27
36
28
37
pub enum QspiError {
@@ -35,8 +44,16 @@ impl Qspi {
35
44
pub fn new (
36
45
reg : & ' static device:: quadspi:: RegisterBlock ,
37
46
interrupt : u32 ,
47
+ read : ReadSetting ,
38
48
) -> Self {
39
- Self { reg, interrupt }
49
+ Self {
50
+ reg,
51
+ interrupt,
52
+ read_command : match read {
53
+ ReadSetting :: Single => Command :: Read ,
54
+ ReadSetting :: Quad => Command :: QuadRead ,
55
+ } ,
56
+ }
40
57
}
41
58
42
59
/// Sets up the QSPI controller with some canned settings.
@@ -94,7 +111,7 @@ impl Qspi {
94
111
address : u32 ,
95
112
data : & mut [ u8 ] ,
96
113
) -> Result < ( ) , QspiError > {
97
- self . read_impl ( Command :: Read , Some ( address) , data)
114
+ self . read_impl ( self . read_command , Some ( address) , data)
98
115
}
99
116
100
117
/// Sets the Write Enable Latch on the flash chip, allowing a write/erase
@@ -311,22 +328,32 @@ impl Qspi {
311
328
// hanging around from some previous transfer -- ensure this:
312
329
self . reg . fcr . write ( |w| w. ctcf ( ) . set_bit ( ) ) ;
313
330
331
+ let ( quad_setting, ddr_setting) = match command {
332
+ Command :: QuadRead => ( true , false ) ,
333
+ Command :: QuadDdrRead => ( true , true ) ,
334
+ Command :: DdrRead => ( false , true ) ,
335
+ _ => ( false , false ) ,
336
+ } ;
337
+
314
338
#[ rustfmt:: skip]
315
339
#[ allow( clippy:: bool_to_int_with_if) ]
316
340
self . reg . ccr . write ( |w| unsafe {
317
341
w
342
+ // Set DDR mode if quad read
343
+ . ddrm ( ) . bit ( ddr_setting)
344
+ . dhhc ( ) . bit ( ddr_setting)
318
345
// Indirect read
319
346
. fmode ( ) . bits ( 0b01 )
320
- // Data on single line, or no data
321
- . dmode ( ) . bits ( if out. is_empty ( ) { 0b00 } else { 0b01 } )
322
- // Dummy cycles = 0 for this
323
- . dcyc ( ) . bits ( 0 )
347
+ // Data on single line, 4 lines if quad or no line
348
+ . dmode ( ) . bits ( if out. is_empty ( ) { 0b00 } else if quad_setting { 0b11 } else { 0b01 } )
349
+ // Dummy cycles = 0 for single read, 8 for quad
350
+ . dcyc ( ) . bits ( if quad_setting { 8 } else { 0 } )
324
351
// No alternate bytes
325
352
. abmode ( ) . bits ( 0 )
326
353
// 32-bit address if present.
327
354
. adsize ( ) . bits ( if addr. is_some ( ) { 0b11 } else { 0b00 } )
328
- // ...on one line for now, if present.
329
- . admode ( ) . bits ( if addr. is_some ( ) { 0b01 } else { 0b00 } )
355
+ // ...on one line for now (or 4 for the DDR command) , if present.
356
+ . admode ( ) . bits ( if addr. is_some ( ) { if ddr_setting { 0b11 } else { 0b01 } } else { 0b00 } )
330
357
// Instruction on single line
331
358
. imode ( ) . bits ( 0b01 )
332
359
// And, the op
0 commit comments