]> patrickod personal git archive - keywing-rs.git/blob - keywing/src/main.rs
2021 nix flake updates & some minor cleanup
[keywing-rs.git] / keywing / src / main.rs
1 #![no_std]
2 #![no_main]
3
4 // Panic provider crate
5 use panic_persist as _;
6
7 // Used to set the program entry point
8 use cortex_m_rt::entry;
9
10 extern crate feather_m4 as hal;
11
12 use hal::prelude::*;
13 use hal::clock::GenericClockController;
14 use hal::pac::{CorePeripherals,Peripherals};
15 use hal::trng::Trng;
16 use hal::delay::Delay;
17 use hal::Pins;
18 use hal::{i2c_master,spi_master};
19 use hal::time::U32Ext;
20
21 use rtt_target::{rprintln, rtt_init_print};
22
23 use embedded_graphics::{
24     fonts::{Font8x16, Text},
25     pixelcolor::Rgb565,
26     prelude::*,
27     style::TextStyleBuilder,
28 };
29
30 use bbq10kbd::{Bbq10Kbd, KeyRaw};
31
32 mod buffer;
33
34 use ili9341::{Ili9341, Orientation};
35
36 #[entry]
37 fn main() -> ! {
38     match inner_main() {
39         Ok(()) => cortex_m::peripheral::SCB::sys_reset(),
40         Err(e) => panic!(e),
41     }
42 }
43
44 fn inner_main() -> Result<(), &'static str> {
45     let mut peripherals = Peripherals::take().ok_or("Error getting board!")?;
46     let mut _pins = Pins::new(peripherals.PORT);
47     let _core = CorePeripherals::take().unwrap();
48
49     let mut _rng: Trng = Trng::new(&mut peripherals.MCLK, peripherals.TRNG);
50     let mut _clocks = GenericClockController::with_external_32kosc(
51         peripherals.GCLK,
52         &mut peripherals.MCLK,
53         &mut peripherals.OSC32KCTRL,
54         &mut peripherals.OSCCTRL,
55         &mut peripherals.NVMCTRL,
56     );
57     let mut delay = Delay::new(_core.SYST, &mut _clocks);
58
59     // set pins low to prevent floating values read as data by the pixels
60     let mut front_neopixel_pin = _pins.d11.into_push_pull_output(&mut _pins.port);
61     let mut rear_neopixel_pin = _pins.neopixel.into_push_pull_output(&mut _pins.port);
62     front_neopixel_pin.set_low().unwrap();
63     rear_neopixel_pin.set_high().unwrap();
64
65     // use ChannelMode::NoBlockS
66     rtt_init_print!(NoBlockSkip, 4096);
67
68     if let Some(msg) = panic_persist::get_panic_message_utf8() {
69         rprintln!("{}", msg);
70     } else {
71         rprintln!("Clean boot!");
72     }
73
74     let kbd_lcd_reset = _pins.d5;
75     let _stm_cs = _pins.d6;
76     let lcd_cs = _pins.d9;
77     let lcd_dc = _pins.d10;
78
79     // i2c keyboard interface
80     // kbd SDA = D12
81     // kbd SCL = D11
82     // FREQ 100KHZ
83     let kbd_i2c = i2c_master(
84         &mut _clocks,
85         100u32.khz(),
86         peripherals.SERCOM2,
87         &mut peripherals.MCLK,
88         _pins.sda,
89         _pins.scl,
90         &mut _pins.port
91     );
92
93     let mut kbd = Bbq10Kbd::new(kbd_i2c);
94
95     let lcd_spi = spi_master(
96         &mut _clocks,
97         32u32.mhz(),
98         peripherals.SERCOM1,
99         &mut peripherals.MCLK,
100         _pins.sck,
101         _pins.mosi,
102         _pins.miso,
103         &mut _pins.port
104     );
105
106     let mut lcd = Ili9341::new_spi(
107         lcd_spi,
108         lcd_cs.into_push_pull_output(&mut _pins.port),
109         lcd_dc.into_push_pull_output(&mut _pins.port),
110         kbd_lcd_reset.into_push_pull_output(&mut _pins.port),
111         &mut delay,
112     ).unwrap();
113
114     lcd.set_orientation(Orientation::Landscape).unwrap();
115
116     let mut buffy2 = [[0u16; 320]; 240];
117
118     let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2);
119
120     let mut style = TextStyleBuilder::new(Font8x16)
121         .text_color(Rgb565::WHITE)
122         .background_color(Rgb565::BLACK)
123         .build();
124
125     kbd.set_backlight(255).unwrap();
126
127     let vers = kbd.get_version().unwrap();
128
129     rprintln!("Vers: {:?}", vers);
130
131     kbd.sw_reset().unwrap();
132     delay.delay_ms(10u8);
133
134     let vers = kbd.get_version().unwrap();
135
136     rprintln!("Vers: {:?}", vers);
137
138     let mut cursor = Cursor { x: 0, y: 0 };
139
140     lcd.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
141     fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
142
143     loop {
144         let key = kbd.get_fifo_key_raw().map_err(|_| "bad fifo")?;
145
146         match key {
147             // LL
148             KeyRaw::Pressed(6) => {
149                 style = TextStyleBuilder::new(Font8x16)
150                     .text_color(Rgb565::WHITE)
151                     .background_color(Rgb565::BLACK)
152                     .build();
153             }
154             // LR
155             KeyRaw::Pressed(17) => {
156                 style = TextStyleBuilder::new(Font8x16)
157                     .text_color(Rgb565::RED)
158                     .background_color(Rgb565::BLACK)
159                     .build();
160             }
161             // RL
162             KeyRaw::Pressed(7) => {
163                 style = TextStyleBuilder::new(Font8x16)
164                     .text_color(Rgb565::GREEN)
165                     .background_color(Rgb565::BLACK)
166                     .build();
167             }
168             // RR
169             KeyRaw::Pressed(18) => {
170                 style = TextStyleBuilder::new(Font8x16)
171                     .text_color(Rgb565::BLUE)
172                     .background_color(Rgb565::BLACK)
173                     .build();
174             }
175             // Up
176             KeyRaw::Pressed(1) => {
177                 cursor.up();
178             }
179             // Down
180             KeyRaw::Pressed(2) => {
181                 cursor.down();
182             }
183             // Left
184             KeyRaw::Pressed(3) => {
185                 cursor.left();
186             }
187             // Right
188             KeyRaw::Pressed(4) => {
189                 cursor.right();
190             }
191             // Center
192             KeyRaw::Pressed(5) => {
193                 kbd.sw_reset().unwrap();
194                 cursor = Cursor { x: 0, y: 0 };
195                 fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
196             }
197             // Backspace
198             KeyRaw::Pressed(8) => {
199                 cursor.left();
200                 Text::new(" ", cursor.pos())
201                     .into_styled(style)
202                     .draw(&mut fbuffy)
203                     .map_err(|_| "bad lcd")?;
204             }
205             // Enter
206             KeyRaw::Pressed(10) => {
207                 cursor.enter();
208             }
209             KeyRaw::Pressed(k) => {
210                 rprintln!("Got key {}", k);
211                 if let Ok(s) = core::str::from_utf8(&[k]) {
212                     Text::new(s, cursor.pos())
213                         .into_styled(style)
214                         .draw(&mut fbuffy)
215                         .map_err(|_| "bad lcd")?;
216
217                     cursor.right();
218                 }
219             }
220             KeyRaw::Invalid => {
221                 if let Some(buf) = fbuffy.inner() {
222                     // timer.start(1_000_000u32);
223                     lcd.draw_raw(0, 0, 319, 239, buf).map_err(|_| "bad buffy")?;
224                     // let done = timer.read();
225                     // rprintln!("Drew in {}ms.", done / 1000);
226                 } else {
227                     delay.delay_ms(38u8);
228                 }
229             }
230             _ => {}
231         }
232     }
233 }
234
235 struct Cursor {
236     x: i32,
237     y: i32,
238 }
239
240 impl Cursor {
241     fn up(&mut self) {
242         self.y -= 1;
243         if self.y < 0 {
244             self.y = 0;
245         }
246     }
247
248     fn down(&mut self) {
249         self.y += 1;
250         if self.y >= 15 {
251             self.y = 14;
252         }
253     }
254
255     fn left(&mut self) {
256         self.x -= 1;
257         if self.x < 0 {
258             if self.y != 0 {
259                 self.x = 39;
260                 self.up();
261             } else {
262                 self.x = 0;
263             }
264         }
265     }
266
267     fn right(&mut self) {
268         self.x += 1;
269         if self.x >= 40 {
270             self.x = 0;
271             self.down();
272         }
273     }
274
275     fn enter(&mut self) {
276         if self.y != 14 {
277             self.x = 0;
278             self.down();
279         }
280     }
281
282     fn pos(&self) -> Point {
283         Point::new(self.x * 8, self.y * 16)
284     }
285 }