@@ -65,7 +65,7 @@ mod timing;
65
65
66
66
use core:: marker:: PhantomData ;
67
67
68
- pub use self :: pins:: { AddressPins , ChipSelectPins , DataPins , DataPins16 , LcdPins , Pins } ;
68
+ pub use self :: pins:: { AddressPins , ChipSelectPins , DataPins , DataPins16 , DataPins8 , LcdPins , Pins } ;
69
69
pub use self :: timing:: { AccessMode , Timing } ;
70
70
71
71
use crate :: rcc:: { Enable , Reset } ;
@@ -108,14 +108,26 @@ impl sealed::SealedSubBank for SubBank4 {
108
108
impl SubBank for SubBank4 { }
109
109
110
110
/// An FMC or FSMC configured as an LCD interface
111
- pub struct FsmcLcd < PINS > {
111
+ pub struct FsmcLcd < PINS , WORD : Word = u16 > {
112
112
pins : PINS ,
113
113
fsmc : FSMC ,
114
+ _word : PhantomData < WORD > ,
114
115
}
115
116
116
- impl < PINS > FsmcLcd < PINS >
117
+ pub trait Word {
118
+ const MWID : fsmc:: bcr1:: MWID_A ;
119
+ }
120
+
121
+ impl Word for u8 {
122
+ const MWID : fsmc:: bcr1:: MWID_A = fsmc:: bcr1:: MWID_A :: Bits8 ;
123
+ }
124
+ impl Word for u16 {
125
+ const MWID : fsmc:: bcr1:: MWID_A = fsmc:: bcr1:: MWID_A :: Bits8 ;
126
+ }
127
+
128
+ impl < PINS , WORD : Word > FsmcLcd < PINS , WORD >
117
129
where
118
- PINS : Pins ,
130
+ PINS : Pins < WORD > ,
119
131
{
120
132
/// Configures the FSMC/FMC to interface with an LCD using the provided pins
121
133
///
@@ -213,7 +225,7 @@ where
213
225
// and sub-banks of bank 1. This driver uses addresses in the different sub-banks of
214
226
// bank 1. The configuration registers for "bank x" (like FMC_BCRx) actually refer to
215
227
// sub-banks, not banks. We need to configure and enable all four of them.
216
- configure_bcr1 ( & fsmc. bcr1 ) ;
228
+ configure_bcr1 :: < WORD > ( & fsmc. bcr1 ) ;
217
229
configure_bcr ( & fsmc. bcr2 ) ;
218
230
configure_bcr ( & fsmc. bcr3 ) ;
219
231
configure_bcr ( & fsmc. bcr4 ) ;
@@ -226,7 +238,14 @@ where
226
238
configure_bwtr ( & fsmc. bwtr3 , write_timing) ;
227
239
configure_bwtr ( & fsmc. bwtr4 , write_timing) ;
228
240
229
- ( FsmcLcd { pins, fsmc } , PINS :: Lcds :: conjure ( ) )
241
+ (
242
+ FsmcLcd {
243
+ pins,
244
+ fsmc,
245
+ _word : PhantomData ,
246
+ } ,
247
+ PINS :: Lcds :: conjure ( ) ,
248
+ )
230
249
}
231
250
232
251
/// Reunites this FsmcLcd and all its associated LCDs, and returns the FSMC and pins for other
@@ -246,54 +265,39 @@ where
246
265
}
247
266
248
267
/// Configures an SRAM/NOR-Flash chip-select control register for LCD interface use
249
- fn configure_bcr1 ( bcr : & fsmc:: BCR1 ) {
268
+ fn configure_bcr1 < WORD : Word > ( bcr : & fsmc:: BCR1 ) {
250
269
bcr. write ( |w| {
251
- w
252
- // The write fifo and WFDIS bit are missing from some models.
253
- // Where present, the FIFO is enabled by default.
254
- // ------------
255
- // Disable synchronous writes
256
- . cburstrw ( )
257
- . disabled ( )
258
- // Don't split burst transactions (doesn't matter for LCD mode)
259
- . cpsize ( )
260
- . no_burst_split ( )
261
- // Ignore wait signal (asynchronous mode)
262
- . asyncwait ( )
263
- . disabled ( )
264
- // Enable extended mode, for different read and write timings
265
- . extmod ( )
266
- . enabled ( )
267
- // Ignore wait signal (synchronous mode)
268
- . waiten ( )
269
- . disabled ( )
270
- // Allow write operations
271
- . wren ( )
272
- . enabled ( )
273
- // Default wait timing
274
- . waitcfg ( )
275
- . before_wait_state ( )
276
- // Default wait polarity
277
- . waitpol ( )
278
- . active_low ( )
279
- // Disable burst reads
280
- . bursten ( )
281
- . disabled ( )
282
- // Enable NOR flash operations
283
- . faccen ( )
284
- . enabled ( )
285
- // 16-bit bus width
286
- . mwid ( )
287
- . bits16 ( )
288
- // NOR flash mode (compatible with LCD controllers)
289
- . mtyp ( )
290
- . flash ( )
291
- // Address and data not multiplexed
292
- . muxen ( )
293
- . disabled ( )
294
- // Enable this memory bank
295
- . mbken ( )
296
- . enabled ( )
270
+ // The write fifo and WFDIS bit are missing from some models.
271
+ // Where present, the FIFO is enabled by default.
272
+ // ------------
273
+ // Disable synchronous writes
274
+ w. cburstrw ( ) . disabled ( ) ;
275
+ // Don't split burst transactions (doesn't matter for LCD mode)
276
+ w. cpsize ( ) . no_burst_split ( ) ;
277
+ // Ignore wait signal (asynchronous mode)
278
+ w. asyncwait ( ) . disabled ( ) ;
279
+ // Enable extended mode, for different read and write timings
280
+ w. extmod ( ) . enabled ( ) ;
281
+ // Ignore wait signal (synchronous mode)
282
+ w. waiten ( ) . disabled ( ) ;
283
+ // Allow write operations
284
+ w. wren ( ) . enabled ( ) ;
285
+ // Default wait timing
286
+ w. waitcfg ( ) . before_wait_state ( ) ;
287
+ // Default wait polarity
288
+ w. waitpol ( ) . active_low ( ) ;
289
+ // Disable burst reads
290
+ w. bursten ( ) . disabled ( ) ;
291
+ // Enable NOR flash operations
292
+ w. faccen ( ) . enabled ( ) ;
293
+ // 8/16-bit bus width
294
+ w. mwid ( ) . variant ( WORD :: MWID ) ;
295
+ // NOR flash mode (compatible with LCD controllers)
296
+ w. mtyp ( ) . flash ( ) ;
297
+ // Address and data not multiplexed
298
+ w. muxen ( ) . disabled ( ) ;
299
+ // Enable this memory bank
300
+ w. mbken ( ) . enabled ( )
297
301
} )
298
302
}
299
303
@@ -384,45 +388,45 @@ fn configure_bwtr(bwtr: &fsmc::BWTR, write_timing: &Timing) {
384
388
///
385
389
/// This struct provides low-level read and write commands that can be used to implement
386
390
/// drivers for LCD controllers. Each function corresponds to exactly one transaction on the bus.
387
- pub struct Lcd < S > {
391
+ pub struct Lcd < S , WORD > {
388
392
/// Phantom S
389
393
///
390
394
/// S determines the chip select signal to use, and the addresses used with that signal.
391
- _sub_bank : PhantomData < S > ,
395
+ _sub_bank : PhantomData < ( S , WORD ) > ,
392
396
}
393
- impl < S > Lcd < S > {
397
+ impl < S , WORD : Word > Lcd < S , WORD > {
394
398
fn new ( ) -> Self {
395
399
Self {
396
400
_sub_bank : PhantomData ,
397
401
}
398
402
}
399
403
}
400
404
401
- impl < S > Lcd < S >
405
+ impl < S , WORD : Word > Lcd < S , WORD >
402
406
where
403
407
S : SubBank ,
404
408
{
405
409
/// Writes a value with the data/command (address) signals set high
406
- pub fn write_data ( & mut self , value : u16 ) {
410
+ pub fn write_data ( & mut self , value : WORD ) {
407
411
unsafe {
408
- core:: ptr:: write_volatile ( S :: DATA_ADDRESS as * mut u16 , value) ;
412
+ core:: ptr:: write_volatile ( S :: DATA_ADDRESS as * mut WORD , value) ;
409
413
}
410
414
}
411
415
412
416
/// Writes a value with the data/command (address) signals set low
413
- pub fn write_command ( & mut self , value : u16 ) {
417
+ pub fn write_command ( & mut self , value : WORD ) {
414
418
unsafe {
415
- core:: ptr:: write_volatile ( S :: COMMAND_ADDRESS as * mut u16 , value) ;
419
+ core:: ptr:: write_volatile ( S :: COMMAND_ADDRESS as * mut WORD , value) ;
416
420
}
417
421
}
418
422
419
423
/// Reads a value with the data/command (address) signals set high
420
- pub fn read_data ( & self ) -> u16 {
421
- unsafe { core:: ptr:: read_volatile ( S :: DATA_ADDRESS as * const u16 ) }
424
+ pub fn read_data ( & self ) -> WORD {
425
+ unsafe { core:: ptr:: read_volatile ( S :: DATA_ADDRESS as * const WORD ) }
422
426
}
423
427
424
428
/// Reads a value with the data/command (address) signals set low
425
- pub fn read_command ( & self ) -> u16 {
426
- unsafe { core:: ptr:: read_volatile ( S :: COMMAND_ADDRESS as * const u16 ) }
429
+ pub fn read_command ( & self ) -> WORD {
430
+ unsafe { core:: ptr:: read_volatile ( S :: COMMAND_ADDRESS as * const WORD ) }
427
431
}
428
432
}
0 commit comments