]> patrickod personal git archive - keywing-rs.git/blob - keywing/src/main.rs
Add a readme
[keywing-rs.git] / keywing / src / main.rs
1 #![no_std]
2 #![no_main]
3
4 // Panic provider crate
5 use panic_persist;
6 use cortex_m;
7
8 // Used to set the program entry point
9 use cortex_m_rt::entry;
10
11 // Provides definitions for our development board
12 use nrf52840_hal::{
13     prelude::*,
14     target::{Peripherals, CorePeripherals},
15     Timer,
16     Rng,
17     Spim,
18     spim::{
19         Pins as SpimPins,
20         Frequency as SpimFrequency,
21         MODE_0,
22     },
23     gpio::{
24         p0::Parts as P0Parts,
25         p1::Parts as P1Parts,
26         Level,
27     },
28     Clocks,
29 };
30
31 use rtt_target::{
32     rprint, rprintln,
33     rtt_init_print,
34 };
35
36 use embedded_graphics::{
37     fonts::{Font8x16, Text},
38     pixelcolor::Rgb565,
39     prelude::*,
40     style::{TextStyle, TextStyleBuilder},
41 };
42
43 mod buffer;
44
45 use ili9341::{Ili9341, Orientation};
46
47 const TEXT_SAMPLE: &[&str] = &[
48     "for x in 0..10 {",
49     "  for y in 0..10 {",
50     "    let rand: u16 = rng.random_u16();",
51     "    buffy.iter_mut().for_each(|px| {",
52     "      *px = swap(rand)",
53     "    });",
54     "    lcd.draw_raw(",
55     "      32 * x,",
56     "      24 * y,",
57     "      (32 * (x + 1)) - 1,",
58     "      (24 * (y + 1)) - 1,",
59     "      &buffy,",
60     "    ).unwrap();",
61     "  }",
62     "}",
63 ];
64
65 const TEXT_SAMPLE2: &[&[(i32, Rgb565, &str)]] = &[
66     // "for x in 0..10 {",
67     &[(0, Rgb565::RED, "for "), (4, Rgb565::WHITE, "x "), (6, Rgb565::RED, "in "), (9, Rgb565::MAGENTA, "0"), (10, Rgb565::RED, ".."), (12, Rgb565::MAGENTA, "10"), (14, Rgb565::WHITE, " {")],
68     // "  for y in 0..10 {",
69     &[(2, Rgb565::RED, "for "), (6, Rgb565::WHITE, "y "), (8, Rgb565::RED, "in "), (11, Rgb565::MAGENTA, "0"), (12, Rgb565::RED, ".."), (14, Rgb565::MAGENTA, "10"), (16, Rgb565::WHITE, " {")],
70     // "    let rand: u16 = rng.random_u16();",
71     &[(4, Rgb565::CYAN, "let "), (8, Rgb565::WHITE, "rand: "), (14, Rgb565::CYAN, "u16 "), (18, Rgb565::RED, "= "), (20, Rgb565::WHITE, "rng."), (24, Rgb565::CYAN, "random_u16"), (34, Rgb565::WHITE, "();")],
72     // "    buffy.iter_mut().for_each(|px| {",
73     &[(4, Rgb565::WHITE, "buffy."), (10, Rgb565::CYAN, "iter_mut"), (18, Rgb565::WHITE, "()."), (21, Rgb565::CYAN, "for_each"), (29, Rgb565::WHITE, "(|"), (31, Rgb565::YELLOW, "px"), (33, Rgb565::WHITE, "| {")],
74     // "      *px = swap(rand)",
75     &[(6, Rgb565::RED, "*"), (7, Rgb565::WHITE, "px "), (10, Rgb565::RED, "= "), (12, Rgb565::CYAN, "swap"), (16, Rgb565::WHITE, "(rand)")],
76     // "    });",
77     &[(4, Rgb565::WHITE, "});")],
78     // "    lcd.draw_raw(",
79     &[(4, Rgb565::WHITE, "lcd."), (8, Rgb565::CYAN, "draw_raw"), (16, Rgb565::WHITE, "(")],
80     // "      32 * x,",
81     &[(6, Rgb565::MAGENTA, "32 "), (9, Rgb565::RED, "* "), (11, Rgb565::WHITE, "x,")],
82     // "      24 * y,",
83     &[(6, Rgb565::MAGENTA, "24 "), (9, Rgb565::RED, "* "), (11, Rgb565::WHITE, "y,")],
84     // "      (32 * (x + 1)) - 1,",
85     &[(6, Rgb565::WHITE, "("), (7, Rgb565::MAGENTA,"32 "), (10, Rgb565::RED, "* "), (12, Rgb565::WHITE, "(x "), (15, Rgb565::RED, "+ "), (17, Rgb565::MAGENTA, "1"), (18, Rgb565::WHITE, ")) "), (21, Rgb565::RED, "- "), (23, Rgb565::MAGENTA, "1"), (24, Rgb565::WHITE, ",")],
86     // "      (24 * (y + 1)) - 1,",
87     &[(6, Rgb565::WHITE, "("), (7, Rgb565::MAGENTA,"24 "), (10, Rgb565::RED, "* "), (12, Rgb565::WHITE, "(y "), (15, Rgb565::RED, "+ "), (17, Rgb565::MAGENTA, "1"), (18, Rgb565::WHITE, ")) "), (21, Rgb565::RED, "- "), (23, Rgb565::MAGENTA, "1"), (24, Rgb565::WHITE, ",")],
88     // "      &buffy,",
89     &[(6, Rgb565::RED, "&"), (7, Rgb565::WHITE, "buffy,")],
90     // "    ).unwrap();",
91     &[(4, Rgb565::WHITE, ")."), (6, Rgb565::CYAN, "unwrap"), (12, Rgb565::WHITE, "();")],
92     // "  }",
93     &[(2, Rgb565::WHITE, "}")],
94     // "}",
95     &[(0, Rgb565::WHITE, "}")],
96 ];
97
98 #[entry]
99 fn main() -> ! {
100     match inner_main() {
101         Ok(()) => cortex_m::peripheral::SCB::sys_reset(),
102         Err(e) => panic!(e),
103     }
104 }
105
106 fn inner_main() -> Result<(), &'static str> {
107     let mut board = Peripherals::take().ok_or("Error getting board!")?;
108     let mut corep = CorePeripherals::take().ok_or("Error")?;
109     let mut timer = Timer::new(board.TIMER0);
110     let mut delay = Timer::new(board.TIMER1);
111     let mut rng = Rng::new(board.RNG);
112     let mut toggle = false;
113     let _clocks = Clocks::new(board.CLOCK).enable_ext_hfosc();
114
115     // use ChannelMode::NoBlockS
116     rtt_init_print!(NoBlockSkip, 4096);
117
118     if let Some(msg) = panic_persist::get_panic_message_utf8() {
119         rprintln!("{}", msg);
120     } else {
121         rprintln!("Clean boot!");
122     }
123
124
125     let p0 = P0Parts::new(board.P0);
126     let p1 = P1Parts::new(board.P1);
127
128     let kbd_lcd_reset = p1.p1_08; // GPIO5, D5
129     let stm_cs = p0.p0_07; // GPIO6, D6,
130     let lcd_cs = p0.p0_26; // GPIO9, D9,
131     let lcd_dc = p0.p0_27; // GPIO10, D10
132
133     // Pull the neopixel line low so noise doesn't make it turn on spuriously
134     let keywing_neopixel = p0.p0_06.into_push_pull_output(Level::Low); // GPIO11, D11
135
136     let spim = Spim::new(
137         board.SPIM3,
138         SpimPins {
139             sck: p0.p0_14.into_push_pull_output(Level::Low).degrade(),
140             miso: Some(p0.p0_15.into_floating_input().degrade()),
141             mosi: Some(p0.p0_13.into_push_pull_output(Level::Low).degrade()),
142         },
143         SpimFrequency::M32,
144         MODE_0,
145         0x00,
146     );
147
148     let mut lcd = Ili9341::new_spi(
149         spim,
150         lcd_cs.into_push_pull_output(Level::High),
151         lcd_dc.into_push_pull_output(Level::High),
152         kbd_lcd_reset.into_push_pull_output(Level::High),
153         &mut delay,
154     ).unwrap();
155
156     lcd.set_orientation(Orientation::Landscape).unwrap();
157
158     let mut buffy = [0u16; 24 * 32];
159     let mut buffy2 = [[0u16; 320]; 240];
160
161     let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2);
162
163     // //                                     rrrrr gggggg bbbbb
164     // buffy.iter_mut().for_each(|px| *px = 0b11111_000000_00000);
165
166     let style = TextStyleBuilder::new(Font8x16)
167         .text_color(Rgb565::WHITE)
168         .background_color(Rgb565::BLACK)
169         .build();
170
171     loop {
172
173         rprintln!("Start colors raw");
174
175         for x in 0..10 {
176             for y in 0..10 {
177                 let rand: u16 = rng.random_u16();
178                 buffy.iter_mut().for_each(|px| {
179                     *px = swap(rand)
180                 });
181
182                 lcd.draw_raw(
183                     32 * x,
184                     24 * y,
185                     (32 * (x + 1)) - 1,
186                     (24 * (y + 1)) - 1,
187                     &buffy,
188                 ).unwrap();
189             }
190         }
191
192         rprintln!("Done.\n");
193
194         timer.delay_ms(1000u16);
195
196         rprintln!("Start colors raw");
197
198         for x in 0..10 {
199             for y in 0..10 {
200                 let rand: u16 = 0;
201                 buffy.iter_mut().for_each(|px| {
202                     *px = swap(rand)
203                 });
204
205                 lcd.draw_raw(
206                     32 * x,
207                     24 * y,
208                     (32 * (x + 1)) - 1,
209                     (24 * (y + 1)) - 1,
210                     &buffy,
211                 ).unwrap();
212             }
213         }
214
215         rprintln!("Done.\n");
216
217
218         timer.delay_ms(1000u16);
219
220         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000));
221         // rprintln!("Start black");
222         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
223         // rprintln!("Done.\n");
224
225         rprintln!("text start");
226
227         for row in 0..15 {
228             Text::new(
229                 TEXT_SAMPLE[row as usize],
230                 Point::new(0, row * 16)
231             ).into_styled(style)
232             .draw(&mut lcd)
233             .unwrap();
234         }
235
236         rprintln!("text done");
237
238         timer.delay_ms(3000u16);
239
240         rprintln!("Start colors raw");
241
242         for x in 0..10 {
243             for y in 0..10 {
244                 let rand: u16 = 0;
245                 buffy.iter_mut().for_each(|px| {
246                     *px = swap(rand)
247                 });
248
249                 lcd.draw_raw(
250                     32 * x,
251                     24 * y,
252                     (32 * (x + 1)) - 1,
253                     (24 * (y + 1)) - 1,
254                     &buffy,
255                 ).unwrap();
256             }
257         }
258
259         rprintln!("Done.\n");
260
261
262         timer.delay_ms(1000u16);
263
264         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000));
265         // rprintln!("Start black");
266         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
267         // rprintln!("Done.\n");
268
269         rprintln!("text2 start");
270
271         for (i, row) in TEXT_SAMPLE2.iter().enumerate() {
272             for (offset, color, text) in row.iter() {
273                 let styled = TextStyleBuilder::new(Font8x16)
274                     .text_color(*color)
275                     .background_color(Rgb565::BLACK)
276                     .build();
277
278                 Text::new(
279                     text,
280                     Point::new(*offset * 8, i as i32 * 16)
281                 ).into_styled(styled)
282                 .draw(&mut lcd)
283                 .unwrap();
284             }
285         }
286
287         rprintln!("text2 done");
288
289         timer.delay_ms(3000u16);
290
291         rprintln!("Start colors raw");
292
293         for x in 0..10 {
294             for y in 0..10 {
295                 let rand: u16 = 0;
296                 buffy.iter_mut().for_each(|px| {
297                     *px = swap(rand)
298                 });
299
300                 lcd.draw_raw(
301                     32 * x,
302                     24 * y,
303                     (32 * (x + 1)) - 1,
304                     (24 * (y + 1)) - 1,
305                     &buffy,
306                 ).unwrap();
307             }
308         }
309
310         rprintln!("Done.\n");
311
312         timer.delay_ms(1000u16);
313
314         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000));
315         // rprintln!("Start black");
316         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
317         // rprintln!("Done.\n");
318
319         timer.start(1_000_000u32);
320
321         let start: u32 = timer.read();
322
323         for row in 0..15 {
324             Text::new(
325                 TEXT_SAMPLE[row as usize],
326                 Point::new(0, row * 16)
327             ).into_styled(style)
328             .draw(&mut fbuffy)
329             .unwrap();
330         }
331
332         let middle: u32 = timer.read();
333
334         lcd.draw_raw(0, 0, 319, 239, fbuffy.inner()).unwrap();
335
336         let end: u32 = timer.read();
337
338         rprintln!("text buffered done");
339         rprintln!("start: 0x{:08X}, middle: 0x{:08X}, end: 0x{:08X}", start, middle, end);
340         rprintln!("render: {} cycs", middle - start);
341         rprintln!("draw:   {} cycs", end - middle);
342
343
344
345
346
347         timer.delay_ms(3000u16);
348
349         rprintln!("Start colors raw");
350
351         for x in 0..10 {
352             for y in 0..10 {
353                 let rand: u16 = 0;
354                 buffy.iter_mut().for_each(|px| {
355                     *px = swap(rand)
356                 });
357
358                 lcd.draw_raw(
359                     32 * x,
360                     24 * y,
361                     (32 * (x + 1)) - 1,
362                     (24 * (y + 1)) - 1,
363                     &buffy,
364                 ).unwrap();
365             }
366         }
367
368         rprintln!("Done.\n");
369
370
371         timer.delay_ms(1000u16);
372
373         rprintln!("text2 buffered middle");
374
375         for (i, row) in TEXT_SAMPLE2.iter().enumerate() {
376             for (offset, color, text) in row.iter() {
377                 let styled = TextStyleBuilder::new(Font8x16)
378                     .text_color(*color)
379                     .background_color(Rgb565::BLACK)
380                     .build();
381
382                 Text::new(
383                     text,
384                     Point::new(*offset * 8, i as i32 * 16)
385                 ).into_styled(styled)
386                 .draw(&mut fbuffy)
387                 .unwrap();
388             }
389         }
390
391         rprintln!("text2 buffered middle");
392
393         lcd.draw_raw(0, 0, 319, 239, fbuffy.inner()).unwrap();
394
395         rprintln!("text2 buffered done");
396
397         timer.delay_ms(3000u16);
398
399         continue;
400
401
402         // // SHOULD BE
403         // //                                      rrrrr gggggg bbbbb
404         // buffy2.iter_mut().for_each(|px| *px = swap(0b11111_000000_00000));
405         // rprintln!("Start red");
406         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
407         // rprintln!("Done.\n");
408
409         // timer.delay_ms(250u16);
410
411         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_111111_00000));
412         // rprintln!("Start green");
413         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
414         // rprintln!("Done.\n");
415
416         // timer.delay_ms(250u16);
417
418         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_11111));
419         // rprintln!("Start blue");
420         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
421         // rprintln!("Done.\n");
422
423         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000));
424         // rprintln!("Start black");
425         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
426         // rprintln!("Done.\n");
427
428         // 240 / 16: 15
429         // 320 /  8: 40
430
431         let text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
432
433         let mut textiter = text.chars().cycle();
434
435         for row in 0..15 {
436             for col in 0..40 {
437                 let mut buf = [0u8; 4];
438                 let txt = textiter.next().unwrap().encode_utf8(&mut buf);
439                 Text::new(
440                     txt,
441                     Point::new(col * 8, row * 16)
442                 ).into_styled(style)
443                 .draw(&mut lcd)
444                 .unwrap();
445             }
446             timer.delay_ms(500u16);
447         }
448
449         timer.delay_ms(1000u16);
450
451
452         // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000));
453         // rprintln!("Start black");
454         // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap();
455         // rprintln!("Done.\n");
456
457         rprintln!("Starting Text Fill...");
458
459         let mut text = Text::new(
460             "1234567890123456789012345678901234567890",
461             Point::new(0, 0)
462         ).into_styled(style);
463
464         for _y in 0..15 {
465             text.draw(&mut lcd).unwrap();
466             text = text.translate(Point::new(0, 16));
467         }
468
469         rprintln!("Finished Text Fill.");
470
471
472         timer.delay_ms(1000u16);
473
474
475     }
476
477     Ok(())
478 }
479
480 const fn swap(inp: u16) -> u16 {
481     (inp & 0x00FF) << 8 |
482     (inp & 0xFF00) >> 8
483 }