]> patrickod personal git archive - keywing-rs.git/blob - keywing/src/main.rs
28841c15c79ac518989ed4f1c5c24fff83eba6c4
[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     // use ChannelMode::NoBlockS
60     rtt_init_print!(NoBlockSkip, 4096);
61
62     if let Some(msg) = panic_persist::get_panic_message_utf8() {
63         rprintln!("{}", msg);
64     } else {
65         rprintln!("Clean boot!");
66     }
67
68     let kbd_lcd_reset = _pins.d5;
69     let _stm_cs = _pins.d6;
70     let lcd_cs = _pins.d9;
71     let lcd_dc = _pins.d10;
72
73     // i2c keyboard interface
74     // kbd SDA = D12
75     // kbd SCL = D11
76     // FREQ 100KHZ
77     let kbd_i2c = i2c_master(
78         &mut _clocks,
79         100u32.khz(),
80         peripherals.SERCOM2,
81         &mut peripherals.MCLK,
82         _pins.sda,
83         _pins.scl,
84         &mut _pins.port
85     );
86
87     let mut kbd = Bbq10Kbd::new(kbd_i2c);
88
89     let lcd_spi = spi_master(
90         &mut _clocks,
91         32u32.mhz(),
92         peripherals.SERCOM1,
93         &mut peripherals.MCLK,
94         _pins.sck,
95         _pins.mosi,
96         _pins.miso,
97         &mut _pins.port
98     );
99
100     let mut lcd = Ili9341::new_spi(
101         lcd_spi,
102         lcd_cs.into_push_pull_output(&mut _pins.port),
103         lcd_dc.into_push_pull_output(&mut _pins.port),
104         kbd_lcd_reset.into_push_pull_output(&mut _pins.port),
105         &mut delay,
106     ).unwrap();
107
108     lcd.set_orientation(Orientation::Landscape).unwrap();
109
110     let mut _buffy = [0u16; 24 * 32];
111     let mut buffy2 = [[0u16; 320]; 240];
112
113     let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2);
114
115     // //                                     rrrrr gggggg bbbbb
116     // buffy.iter_mut().for_each(|px| *px = 0b11111_000000_00000);
117
118     let mut style = TextStyleBuilder::new(Font8x16)
119         .text_color(Rgb565::WHITE)
120         .background_color(Rgb565::BLACK)
121         .build();
122
123     kbd.set_backlight(255).unwrap();
124
125     let vers = kbd.get_version().unwrap();
126
127     rprintln!("Vers: {:?}", vers);
128
129     kbd.sw_reset().unwrap();
130     delay.delay_ms(10u8);
131
132     let vers = kbd.get_version().unwrap();
133
134     rprintln!("Vers: {:?}", vers);
135
136     let mut cursor = Cursor { x: 0, y: 0 };
137
138     lcd.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
139     fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
140
141     loop {
142         let key = kbd.get_fifo_key_raw().map_err(|_| "bad fifo")?;
143
144         match key {
145             // LL
146             KeyRaw::Pressed(6) => {
147                 style = TextStyleBuilder::new(Font8x16)
148                     .text_color(Rgb565::WHITE)
149                     .background_color(Rgb565::BLACK)
150                     .build();
151             }
152             // LR
153             KeyRaw::Pressed(17) => {
154                 style = TextStyleBuilder::new(Font8x16)
155                     .text_color(Rgb565::RED)
156                     .background_color(Rgb565::BLACK)
157                     .build();
158             }
159             // RL
160             KeyRaw::Pressed(7) => {
161                 style = TextStyleBuilder::new(Font8x16)
162                     .text_color(Rgb565::GREEN)
163                     .background_color(Rgb565::BLACK)
164                     .build();
165             }
166             // RR
167             KeyRaw::Pressed(18) => {
168                 style = TextStyleBuilder::new(Font8x16)
169                     .text_color(Rgb565::BLUE)
170                     .background_color(Rgb565::BLACK)
171                     .build();
172             }
173             // Up
174             KeyRaw::Pressed(1) => {
175                 cursor.up();
176             }
177             // Down
178             KeyRaw::Pressed(2) => {
179                 cursor.down();
180             }
181             // Left
182             KeyRaw::Pressed(3) => {
183                 cursor.left();
184             }
185             // Right
186             KeyRaw::Pressed(4) => {
187                 cursor.right();
188             }
189             // Center
190             KeyRaw::Pressed(5) => {
191                 kbd.sw_reset().unwrap();
192                 cursor = Cursor { x: 0, y: 0 };
193                 fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
194             }
195             // Backspace
196             KeyRaw::Pressed(8) => {
197                 cursor.left();
198                 Text::new(" ", cursor.pos())
199                     .into_styled(style)
200                     .draw(&mut fbuffy)
201                     .map_err(|_| "bad lcd")?;
202             }
203             // Enter
204             KeyRaw::Pressed(10) => {
205                 cursor.enter();
206             }
207             KeyRaw::Pressed(k) => {
208                 rprintln!("Got key {}", k);
209                 if let Ok(s) = core::str::from_utf8(&[k]) {
210                     Text::new(s, cursor.pos())
211                         .into_styled(style)
212                         .draw(&mut fbuffy)
213                         .map_err(|_| "bad lcd")?;
214
215                     cursor.right();
216                 }
217             }
218             KeyRaw::Invalid => {
219                 if let Some(buf) = fbuffy.inner() {
220                     // timer.start(1_000_000u32);
221                     lcd.draw_raw(0, 0, 319, 239, buf).map_err(|_| "bad buffy")?;
222                     // let done = timer.read();
223                     // rprintln!("Drew in {}ms.", done / 1000);
224                 } else {
225                     delay.delay_ms(38u8);
226                 }
227             }
228             _ => {}
229         }
230     }
231 }
232
233 struct Cursor {
234     x: i32,
235     y: i32,
236 }
237
238 impl Cursor {
239     fn up(&mut self) {
240         self.y -= 1;
241         if self.y < 0 {
242             self.y = 0;
243         }
244     }
245
246     fn down(&mut self) {
247         self.y += 1;
248         if self.y >= 15 {
249             self.y = 14;
250         }
251     }
252
253     fn left(&mut self) {
254         self.x -= 1;
255         if self.x < 0 {
256             if self.y != 0 {
257                 self.x = 39;
258                 self.up();
259             } else {
260                 self.x = 0;
261             }
262         }
263     }
264
265     fn right(&mut self) {
266         self.x += 1;
267         if self.x >= 40 {
268             self.x = 0;
269             self.down();
270         }
271     }
272
273     fn enter(&mut self) {
274         if self.y != 14 {
275             self.x = 0;
276             self.down();
277         }
278     }
279
280     fn pos(&self) -> Point {
281         Point::new(self.x * 8, self.y * 16)
282     }
283 }