1use core::marker::PhantomData;
19
20use crate::gpio::alt::fmc as alt;
21
22use super::sealed;
23use super::{Lcd, SubBank1, Word};
24use crate::fsmc_lcd::{SubBank2, SubBank3, SubBank4};
25
26pub trait AddressPins: sealed::Sealed {}
28
29impl AddressPins for alt::Address {}
31impl AddressPins for (alt::Address, alt::Address) {}
32impl sealed::Sealed for (alt::Address, alt::Address) {}
33impl AddressPins for (alt::Address, alt::Address, alt::Address) {}
34impl sealed::Sealed for (alt::Address, alt::Address, alt::Address) {}
35impl AddressPins for (alt::Address, alt::Address, alt::Address, alt::Address) {}
36impl sealed::Sealed for (alt::Address, alt::Address, alt::Address, alt::Address) {}
37
38macro_rules! conjure {
39 ($($($sb:ident),+;)+) => {
40 $(
41 #[allow(unused_parens)]
42 impl<WORD: Word> sealed::Conjure for ($(Lcd<$sb, WORD>),+) {
43 fn conjure() -> Self {
44 ($(Lcd::<$sb, WORD>::new()),+)
45 }
46 }
47 )+
48 };
49}
50
51conjure! {
53 SubBank1;
54 SubBank2;
55 SubBank3;
56 SubBank4;
57 SubBank1, SubBank2;
58 SubBank1, SubBank3;
59 SubBank1, SubBank4;
60 SubBank2, SubBank3;
61 SubBank2, SubBank4;
62 SubBank3, SubBank4;
63 SubBank1, SubBank2, SubBank3;
64 SubBank1, SubBank2, SubBank4;
65 SubBank1, SubBank3, SubBank4;
66 SubBank2, SubBank3, SubBank4;
67 SubBank1, SubBank2, SubBank3, SubBank4;
68}
69
70pub trait ChipSelectPins: sealed::Sealed {
91 type Lcds<WORD: Word>: sealed::Conjure;
94}
95
96macro_rules! chipselect {
114 ($($([$sb:ident, $Ne:ident, $i:tt]),+;)+) => {
115 $(
116 impl ChipSelectPins for ($(alt::$Ne),+) {
117 type Lcds<WORD: Word> = ($(Lcd<$sb, WORD>),+);
118 }
119 impl sealed::Sealed for ($(alt::$Ne),+) {}
120 )+
121 };
122}
123
124impl ChipSelectPins for alt::Ne1 {
125 type Lcds<WORD: Word> = Lcd<SubBank1, WORD>;
126}
127impl ChipSelectPins for alt::Ne2 {
128 type Lcds<WORD: Word> = Lcd<SubBank2, WORD>;
129}
130impl ChipSelectPins for alt::Ne3 {
131 type Lcds<WORD: Word> = Lcd<SubBank3, WORD>;
132}
133impl ChipSelectPins for alt::Ne4 {
134 type Lcds<WORD: Word> = Lcd<SubBank4, WORD>;
135}
136chipselect! {
137 [SubBank1, Ne1, 0], [SubBank2, Ne2, 1];
138 [SubBank1, Ne1, 0], [SubBank3, Ne3, 1];
139 [SubBank1, Ne1, 0], [SubBank4, Ne4, 1];
140 [SubBank2, Ne2, 0], [SubBank3, Ne3, 1];
141 [SubBank2, Ne2, 0], [SubBank4, Ne4, 1];
142 [SubBank3, Ne3, 0], [SubBank4, Ne4, 1];
143 [SubBank1, Ne1, 0], [SubBank2, Ne2, 1], [SubBank3, Ne3, 2];
144 [SubBank1, Ne1, 0], [SubBank2, Ne2, 1], [SubBank4, Ne4, 2];
145 [SubBank1, Ne1, 0], [SubBank3, Ne3, 1], [SubBank4, Ne4, 2];
146 [SubBank2, Ne2, 0], [SubBank3, Ne3, 1], [SubBank4, Ne4, 2];
147 [SubBank1, Ne1, 0], [SubBank2, Ne2, 1], [SubBank3, Ne3, 2], [SubBank4, Ne4, 3];
148}
149
150pub trait DataPins<WORD: Word>: sealed::Sealed {}
154
155#[allow(unused)]
156pub struct DataPins16 {
157 pub d0: alt::D0,
158 pub d1: alt::D1,
159 pub d2: alt::D2,
160 pub d3: alt::D3,
161 pub d4: alt::D4,
162 pub d5: alt::D5,
163 pub d6: alt::D6,
164 pub d7: alt::D7,
165 pub d8: alt::D8,
166 pub d9: alt::D9,
167 pub d10: alt::D10,
168 pub d11: alt::D11,
169 pub d12: alt::D12,
170 pub d13: alt::D13,
171 pub d14: alt::D14,
172 pub d15: alt::D15,
173}
174
175impl DataPins<u16> for DataPins16 {}
176
177impl DataPins16 {
178 #[allow(clippy::too_many_arguments)]
179 #[inline(always)]
180 pub fn new(
181 d0: impl Into<alt::D0>,
182 d1: impl Into<alt::D1>,
183 d2: impl Into<alt::D2>,
184 d3: impl Into<alt::D3>,
185 d4: impl Into<alt::D4>,
186 d5: impl Into<alt::D5>,
187 d6: impl Into<alt::D6>,
188 d7: impl Into<alt::D7>,
189 d8: impl Into<alt::D8>,
190 d9: impl Into<alt::D9>,
191 d10: impl Into<alt::D10>,
192 d11: impl Into<alt::D11>,
193 d12: impl Into<alt::D12>,
194 d13: impl Into<alt::D13>,
195 d14: impl Into<alt::D14>,
196 d15: impl Into<alt::D15>,
197 ) -> Self {
198 Self {
199 d0: d0.into(),
200 d1: d1.into(),
201 d2: d2.into(),
202 d3: d3.into(),
203 d4: d4.into(),
204 d5: d5.into(),
205 d6: d6.into(),
206 d7: d7.into(),
207 d8: d8.into(),
208 d9: d9.into(),
209 d10: d10.into(),
210 d11: d11.into(),
211 d12: d12.into(),
212 d13: d13.into(),
213 d14: d14.into(),
214 d15: d15.into(),
215 }
216 }
217}
218impl sealed::Sealed for DataPins16 {}
219
220#[allow(unused)]
221pub struct DataPins8 {
222 pub d0: alt::D0,
223 pub d1: alt::D1,
224 pub d2: alt::D2,
225 pub d3: alt::D3,
226 pub d4: alt::D4,
227 pub d5: alt::D5,
228 pub d6: alt::D6,
229 pub d7: alt::D7,
230}
231
232impl DataPins<u8> for DataPins8 {}
233
234impl DataPins8 {
235 #[allow(clippy::too_many_arguments)]
236 #[inline(always)]
237 pub fn new(
238 d0: impl Into<alt::D0>,
239 d1: impl Into<alt::D1>,
240 d2: impl Into<alt::D2>,
241 d3: impl Into<alt::D3>,
242 d4: impl Into<alt::D4>,
243 d5: impl Into<alt::D5>,
244 d6: impl Into<alt::D6>,
245 d7: impl Into<alt::D7>,
246 ) -> Self {
247 Self {
248 d0: d0.into(),
249 d1: d1.into(),
250 d2: d2.into(),
251 d3: d3.into(),
252 d4: d4.into(),
253 d5: d5.into(),
254 d6: d6.into(),
255 d7: d7.into(),
256 }
257 }
258
259 pub fn split(
260 self,
261 ) -> (
262 alt::D0,
263 alt::D1,
264 alt::D2,
265 alt::D3,
266 alt::D4,
267 alt::D5,
268 alt::D6,
269 alt::D7,
270 ) {
271 (
272 self.d0, self.d1, self.d2, self.d3, self.d4, self.d5, self.d6, self.d7,
273 )
274 }
275}
276impl sealed::Sealed for DataPins8 {}
277
278#[allow(unused)]
282pub struct LcdPins<D, AD, NE, WORD> {
283 pub data: D,
285 pub address: AD,
287 pub read_enable: alt::Noe,
289 pub write_enable: alt::Nwe,
291 pub chip_select: NE,
293 _word: PhantomData<WORD>,
294}
295
296impl<D, AD, NE, WORD> LcdPins<D, AD, NE, WORD>
297where
298 D: DataPins<WORD>,
299 AD: AddressPins,
300 NE: ChipSelectPins,
301 WORD: Word,
302{
303 pub fn new(
304 data: D,
305 address: AD,
306 read_enable: impl Into<alt::Noe>,
307 write_enable: impl Into<alt::Nwe>,
308 chip_select: NE,
309 ) -> Self {
310 Self {
311 data,
312 address,
313 read_enable: read_enable.into(),
314 write_enable: write_enable.into(),
315 chip_select,
316 _word: PhantomData,
317 }
318 }
319 pub fn split(self) -> (D, AD, alt::Noe, alt::Nwe, NE) {
320 (
321 self.data,
322 self.address,
323 self.read_enable,
324 self.write_enable,
325 self.chip_select,
326 )
327 }
328}
329
330pub trait Pins<WORD: Word>: sealed::Sealed {
336 type Lcds: sealed::Conjure;
339}
340
341impl<D, AD, NE, WORD> Pins<WORD> for LcdPins<D, AD, NE, WORD>
342where
343 D: DataPins<WORD>,
344 AD: AddressPins,
345 NE: ChipSelectPins,
346 WORD: Word,
347{
348 type Lcds = NE::Lcds<WORD>;
349}
350
351impl<D, AD, NE, WORD> sealed::Sealed for LcdPins<D, AD, NE, WORD>
352where
353 D: DataPins<WORD>,
354 AD: AddressPins,
355 NE: ChipSelectPins,
356 WORD: Word,
357{
358}