]> patrickod personal git archive - keywing-rs.git/blob - keywing/src/main.rs
Working little text editor
[keywing-rs.git] / keywing / src / main.rs
1 #![no_std]
2 #![no_main]
3
4 // Panic provider crate
5 use cortex_m;
6 use panic_persist;
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     gpio::{p0::Parts as P0Parts, p1::Parts as P1Parts, Level},
14     prelude::*,
15     spim::{Frequency as SpimFrequency, Pins as SpimPins, MODE_0},
16     target::{CorePeripherals, Peripherals},
17     twim::{Frequency as TwimFrequency, Pins as TwimPins},
18     Clocks, Rng, Spim, Timer, Twim,
19 };
20
21 use rtt_target::{rprint, rprintln, rtt_init_print};
22
23 use embedded_graphics::{
24     fonts::{Font8x16, Text},
25     pixelcolor::Rgb565,
26     prelude::*,
27     style::{TextStyle, TextStyleBuilder},
28 };
29
30 use bbq10kbd::{Bbq10Kbd, KeyRaw};
31
32 mod buffer;
33
34 use ili9341::{Ili9341, Orientation};
35
36 const TEXT_SAMPLE: &[&str] = &[
37     "for x in 0..10 {",
38     "  for y in 0..10 {",
39     "    let rand: u16 = rng.random_u16();",
40     "    buffy.iter_mut().for_each(|px| {",
41     "      *px = swap(rand)",
42     "    });",
43     "    lcd.draw_raw(",
44     "      32 * x,",
45     "      24 * y,",
46     "      (32 * (x + 1)) - 1,",
47     "      (24 * (y + 1)) - 1,",
48     "      &buffy,",
49     "    ).unwrap();",
50     "  }",
51     "}",
52 ];
53
54 const TEXT_SAMPLE2: &[&[(i32, Rgb565, &str)]] = &[
55     // "for x in 0..10 {",
56     &[
57         (0, Rgb565::RED, "for "),
58         (4, Rgb565::WHITE, "x "),
59         (6, Rgb565::RED, "in "),
60         (9, Rgb565::MAGENTA, "0"),
61         (10, Rgb565::RED, ".."),
62         (12, Rgb565::MAGENTA, "10"),
63         (14, Rgb565::WHITE, " {"),
64     ],
65     // "  for y in 0..10 {",
66     &[
67         (2, Rgb565::RED, "for "),
68         (6, Rgb565::WHITE, "y "),
69         (8, Rgb565::RED, "in "),
70         (11, Rgb565::MAGENTA, "0"),
71         (12, Rgb565::RED, ".."),
72         (14, Rgb565::MAGENTA, "10"),
73         (16, Rgb565::WHITE, " {"),
74     ],
75     // "    let rand: u16 = rng.random_u16();",
76     &[
77         (4, Rgb565::CYAN, "let "),
78         (8, Rgb565::WHITE, "rand: "),
79         (14, Rgb565::CYAN, "u16 "),
80         (18, Rgb565::RED, "= "),
81         (20, Rgb565::WHITE, "rng."),
82         (24, Rgb565::CYAN, "random_u16"),
83         (34, Rgb565::WHITE, "();"),
84     ],
85     // "    buffy.iter_mut().for_each(|px| {",
86     &[
87         (4, Rgb565::WHITE, "buffy."),
88         (10, Rgb565::CYAN, "iter_mut"),
89         (18, Rgb565::WHITE, "()."),
90         (21, Rgb565::CYAN, "for_each"),
91         (29, Rgb565::WHITE, "(|"),
92         (31, Rgb565::YELLOW, "px"),
93         (33, Rgb565::WHITE, "| {"),
94     ],
95     // "      *px = swap(rand)",
96     &[
97         (6, Rgb565::RED, "*"),
98         (7, Rgb565::WHITE, "px "),
99         (10, Rgb565::RED, "= "),
100         (12, Rgb565::CYAN, "swap"),
101         (16, Rgb565::WHITE, "(rand)"),
102     ],
103     // "    });",
104     &[(4, Rgb565::WHITE, "});")],
105     // "    lcd.draw_raw(",
106     &[
107         (4, Rgb565::WHITE, "lcd."),
108         (8, Rgb565::CYAN, "draw_raw"),
109         (16, Rgb565::WHITE, "("),
110     ],
111     // "      32 * x,",
112     &[
113         (6, Rgb565::MAGENTA, "32 "),
114         (9, Rgb565::RED, "* "),
115         (11, Rgb565::WHITE, "x,"),
116     ],
117     // "      24 * y,",
118     &[
119         (6, Rgb565::MAGENTA, "24 "),
120         (9, Rgb565::RED, "* "),
121         (11, Rgb565::WHITE, "y,"),
122     ],
123     // "      (32 * (x + 1)) - 1,",
124     &[
125         (6, Rgb565::WHITE, "("),
126         (7, Rgb565::MAGENTA, "32 "),
127         (10, Rgb565::RED, "* "),
128         (12, Rgb565::WHITE, "(x "),
129         (15, Rgb565::RED, "+ "),
130         (17, Rgb565::MAGENTA, "1"),
131         (18, Rgb565::WHITE, ")) "),
132         (21, Rgb565::RED, "- "),
133         (23, Rgb565::MAGENTA, "1"),
134         (24, Rgb565::WHITE, ","),
135     ],
136     // "      (24 * (y + 1)) - 1,",
137     &[
138         (6, Rgb565::WHITE, "("),
139         (7, Rgb565::MAGENTA, "24 "),
140         (10, Rgb565::RED, "* "),
141         (12, Rgb565::WHITE, "(y "),
142         (15, Rgb565::RED, "+ "),
143         (17, Rgb565::MAGENTA, "1"),
144         (18, Rgb565::WHITE, ")) "),
145         (21, Rgb565::RED, "- "),
146         (23, Rgb565::MAGENTA, "1"),
147         (24, Rgb565::WHITE, ","),
148     ],
149     // "      &buffy,",
150     &[(6, Rgb565::RED, "&"), (7, Rgb565::WHITE, "buffy,")],
151     // "    ).unwrap();",
152     &[
153         (4, Rgb565::WHITE, ")."),
154         (6, Rgb565::CYAN, "unwrap"),
155         (12, Rgb565::WHITE, "();"),
156     ],
157     // "  }",
158     &[(2, Rgb565::WHITE, "}")],
159     // "}",
160     &[(0, Rgb565::WHITE, "}")],
161 ];
162
163 #[entry]
164 fn main() -> ! {
165     match inner_main() {
166         Ok(()) => cortex_m::peripheral::SCB::sys_reset(),
167         Err(e) => panic!(e),
168     }
169 }
170
171 fn inner_main() -> Result<(), &'static str> {
172     let mut board = Peripherals::take().ok_or("Error getting board!")?;
173     let mut corep = CorePeripherals::take().ok_or("Error")?;
174     let mut timer = Timer::new(board.TIMER0);
175     let mut delay = Timer::new(board.TIMER1);
176     let mut rng = Rng::new(board.RNG);
177     let mut toggle = false;
178     let _clocks = Clocks::new(board.CLOCK).enable_ext_hfosc();
179
180     // use ChannelMode::NoBlockS
181     rtt_init_print!(NoBlockSkip, 4096);
182
183     if let Some(msg) = panic_persist::get_panic_message_utf8() {
184         rprintln!("{}", msg);
185     } else {
186         rprintln!("Clean boot!");
187     }
188
189     let p0 = P0Parts::new(board.P0);
190     let p1 = P1Parts::new(board.P1);
191
192     let kbd_lcd_reset = p1.p1_08; // GPIO5, D5
193     let stm_cs = p0.p0_07; // GPIO6, D6,
194     let lcd_cs = p0.p0_26; // GPIO9, D9,
195     let lcd_dc = p0.p0_27; // GPIO10, D10
196
197     let kbd_sda = p0.p0_12.into_floating_input().degrade();
198     let kbd_scl = p0.p0_11.into_floating_input().degrade();
199
200     let kbd_i2c = Twim::new(
201         board.TWIM0,
202         TwimPins {
203             sda: kbd_sda,
204             scl: kbd_scl,
205         },
206         TwimFrequency::K100,
207     );
208
209     let mut kbd = Bbq10Kbd::new(kbd_i2c);
210
211     // Pull the neopixel lines low so noise doesn't make it turn on spuriously
212     let keywing_neopixel = p0.p0_06.into_push_pull_output(Level::Low); // GPIO11, D11
213     let feather_neopixel = p0.p0_16.into_push_pull_output(Level::Low);
214
215     let spim = Spim::new(
216         board.SPIM3,
217         SpimPins {
218             sck: p0.p0_14.into_push_pull_output(Level::Low).degrade(),
219             miso: Some(p0.p0_15.into_floating_input().degrade()),
220             mosi: Some(p0.p0_13.into_push_pull_output(Level::Low).degrade()),
221         },
222         SpimFrequency::M32,
223         MODE_0,
224         0x00,
225     );
226
227     let mut lcd = Ili9341::new_spi(
228         spim,
229         lcd_cs.into_push_pull_output(Level::High),
230         lcd_dc.into_push_pull_output(Level::High),
231         kbd_lcd_reset.into_push_pull_output(Level::High),
232         &mut delay,
233     )
234     .unwrap();
235
236     lcd.set_orientation(Orientation::Landscape).unwrap();
237
238     let mut _buffy = [0u16; 24 * 32];
239     let mut buffy2 = [[0u16; 320]; 240];
240
241     let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2);
242
243     // //                                     rrrrr gggggg bbbbb
244     // buffy.iter_mut().for_each(|px| *px = 0b11111_000000_00000);
245
246     let mut style = TextStyleBuilder::new(Font8x16)
247         .text_color(Rgb565::WHITE)
248         .background_color(Rgb565::BLACK)
249         .build();
250
251     let mut ctr: u8 = 0;
252     kbd.set_backlight(ctr).unwrap();
253
254     let vers = kbd.get_version().unwrap();
255
256     rprintln!("Vers: {:?}", vers);
257
258     kbd.sw_reset().unwrap();
259     timer.delay_ms(10u8);
260
261     let vers = kbd.get_version().unwrap();
262
263     rprintln!("Vers: {:?}", vers);
264
265     let mut cursor_y = 0;
266     let mut cursor_x = 0;
267
268     let mut cursor = Cursor { x: 0, y: 0 };
269
270     lcd.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
271     fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
272
273     loop {
274         let key = kbd.get_fifo_key_raw().map_err(|_| "bad fifo")?;
275
276         match key {
277             // LL
278             KeyRaw::Pressed(6) => {
279                 style = TextStyleBuilder::new(Font8x16)
280                     .text_color(Rgb565::WHITE)
281                     .background_color(Rgb565::BLACK)
282                     .build();
283             }
284             // LR
285             KeyRaw::Pressed(17) => {
286                 style = TextStyleBuilder::new(Font8x16)
287                     .text_color(Rgb565::RED)
288                     .background_color(Rgb565::BLACK)
289                     .build();
290             }
291             // RL
292             KeyRaw::Pressed(7) => {
293                 style = TextStyleBuilder::new(Font8x16)
294                     .text_color(Rgb565::GREEN)
295                     .background_color(Rgb565::BLACK)
296                     .build();
297             }
298             // RR
299             KeyRaw::Pressed(18) => {
300                 style = TextStyleBuilder::new(Font8x16)
301                     .text_color(Rgb565::BLUE)
302                     .background_color(Rgb565::BLACK)
303                     .build();
304             }
305             // Up
306             KeyRaw::Pressed(1) => {
307                 cursor.up();
308             }
309             // Down
310             KeyRaw::Pressed(2) => {
311                 cursor.down();
312             }
313             // Left
314             KeyRaw::Pressed(3) => {
315                 cursor.left();
316             }
317             // Right
318             KeyRaw::Pressed(4) => {
319                 cursor.right();
320             }
321             // Center
322             KeyRaw::Pressed(5) => {
323                 kbd.sw_reset().unwrap();
324                 cursor = Cursor { x: 0, y: 0 };
325                 fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
326             }
327             // Backspace
328             KeyRaw::Pressed(8) => {
329                 cursor.left();
330                 Text::new(" ", cursor.pos())
331                     .into_styled(style)
332                     .draw(&mut fbuffy)
333                     .map_err(|_| "bad lcd")?;
334             }
335             // Enter
336             KeyRaw::Pressed(10) => {
337                 cursor.enter();
338             }
339             KeyRaw::Pressed(k) => {
340                 rprintln!("Got key {}", k);
341                 if let Ok(s) = core::str::from_utf8(&[k]) {
342                     Text::new(s, cursor.pos())
343                         .into_styled(style)
344                         .draw(&mut fbuffy)
345                         .map_err(|_| "bad lcd")?;
346
347                     cursor.right();
348                 }
349             }
350             KeyRaw::Invalid => {
351                 if let Some(buf) = fbuffy.inner() {
352                     timer.start(1_000_000u32);
353                     lcd.draw_raw(
354                         0, 0,
355                         319, 239,
356                         buf
357                     ).map_err(|_| "bad buffy")?;
358                     let done = timer.read();
359                     rprintln!("Drew in {}ms.", done / 1000);
360                 } else {
361                     timer.delay_ms(38u8);
362                 }
363
364             }
365             _ => {}
366         }
367     }
368
369     Ok(())
370 }
371
372 struct Cursor {
373     x: i32,
374     y: i32,
375 }
376
377 impl Cursor {
378     fn up(&mut self) {
379         self.y -= 1;
380         if self.y < 0 {
381             self.y = 0;
382         }
383     }
384
385     fn down(&mut self) {
386         self.y += 1;
387         if self.y >= 15 {
388             self.y = 14;
389         }
390     }
391
392     fn left(&mut self) {
393         self.x -= 1;
394         if self.x < 0 {
395             if self.y != 0 {
396                 self.x = 39;
397                 self.up();
398             } else {
399                 self.x = 0;
400             }
401         }
402     }
403
404     fn right(&mut self) {
405         self.x += 1;
406         if self.x >= 40 {
407             self.x = 0;
408             self.down();
409         }
410     }
411
412     fn enter(&mut self) {
413         if self.y != 14 {
414             self.x = 0;
415             self.down();
416         }
417     }
418
419     fn pos(&self) -> Point {
420         Point::new(self.x * 8, self.y * 16)
421     }
422 }
423
424 // let key_raw = kbd.get_fifo_key_raw().unwrap();
425
426 // match key_raw {
427 //     KeyRaw::Invalid => {
428 //         timer.delay_ms(1000u16);
429 //         let state = kbd.get_key_status().unwrap();
430 //         rprintln!("Key Status: {:?}", state);
431 //     }
432 //     key @ _ => {
433 //         ctr = ctr.wrapping_add(5);
434 //         rprintln!("Key: {:?} - {}", key, ctr);
435 //         kbd.set_backlight(ctr).unwrap();
436 //         assert_eq!(kbd.get_backlight().unwrap(), ctr);
437 //     }
438 // }
439
440 // Special keys
441 // LL: 6
442 // LR: 17
443 // RL: 7
444 // RR: 18
445 //
446 // D-L: 3
447 // D-U: 1
448 // D-R: 4
449 // D-D: 2
450 // D-C: 5