]> patrickod personal git archive - keywing-rs.git/blob - keywing/src/main.rs
Add nix & direnv rust environment configuration
[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 // Provides definitions for our development board
11 use nrf52840_hal::{
12     gpio::{p0::Parts as P0Parts, p1::Parts as P1Parts, Level},
13     prelude::*,
14     spim::{Frequency as SpimFrequency, Pins as SpimPins, MODE_0},
15     target::Peripherals,
16     twim::{Frequency as TwimFrequency, Pins as TwimPins},
17     Clocks, Rng, Spim, Timer, Twim,
18 };
19
20 use rtt_target::{rprintln, rtt_init_print};
21
22 use embedded_graphics::{
23     fonts::{Font8x16, Text},
24     pixelcolor::Rgb565,
25     prelude::*,
26     style::TextStyleBuilder,
27 };
28
29 use bbq10kbd::{Bbq10Kbd, KeyRaw};
30
31 mod buffer;
32
33 use ili9341::{Ili9341, Orientation};
34
35 #[entry]
36 fn main() -> ! {
37     match inner_main() {
38         Ok(()) => cortex_m::peripheral::SCB::sys_reset(),
39         Err(e) => panic!(e),
40     }
41 }
42
43 fn inner_main() -> Result<(), &'static str> {
44     let board = Peripherals::take().ok_or("Error getting board!")?;
45     let mut timer = Timer::new(board.TIMER0);
46     let mut delay = Timer::new(board.TIMER1);
47     let mut _rng = Rng::new(board.RNG);
48     let _clocks = Clocks::new(board.CLOCK).enable_ext_hfosc();
49
50     // use ChannelMode::NoBlockS
51     rtt_init_print!(NoBlockSkip, 4096);
52
53     if let Some(msg) = panic_persist::get_panic_message_utf8() {
54         rprintln!("{}", msg);
55     } else {
56         rprintln!("Clean boot!");
57     }
58
59     let p0 = P0Parts::new(board.P0);
60     let p1 = P1Parts::new(board.P1);
61
62     let kbd_lcd_reset = p1.p1_08; // GPIO5, D5
63     let _stm_cs = p0.p0_07; // GPIO6, D6,
64     let lcd_cs = p0.p0_26; // GPIO9, D9,
65     let lcd_dc = p0.p0_27; // GPIO10, D10
66
67     let kbd_sda = p0.p0_12.into_floating_input().degrade();
68     let kbd_scl = p0.p0_11.into_floating_input().degrade();
69
70     let kbd_i2c = Twim::new(
71         board.TWIM0,
72         TwimPins {
73             sda: kbd_sda,
74             scl: kbd_scl,
75         },
76         TwimFrequency::K100,
77     );
78
79     let mut kbd = Bbq10Kbd::new(kbd_i2c);
80
81     // Pull the neopixel lines low so noise doesn't make it turn on spuriously
82     let _keywing_neopixel = p0.p0_06.into_push_pull_output(Level::Low); // GPIO11, D11
83     let _feather_neopixel = p0.p0_16.into_push_pull_output(Level::Low);
84
85     let spim = Spim::new(
86         board.SPIM3,
87         SpimPins {
88             sck: p0.p0_14.into_push_pull_output(Level::Low).degrade(),
89             miso: Some(p0.p0_15.into_floating_input().degrade()),
90             mosi: Some(p0.p0_13.into_push_pull_output(Level::Low).degrade()),
91         },
92         SpimFrequency::M32,
93         MODE_0,
94         0x00,
95     );
96
97     let mut lcd = Ili9341::new_spi(
98         spim,
99         lcd_cs.into_push_pull_output(Level::High),
100         lcd_dc.into_push_pull_output(Level::High),
101         kbd_lcd_reset.into_push_pull_output(Level::High),
102         &mut delay,
103     )
104     .unwrap();
105
106     lcd.set_orientation(Orientation::Landscape).unwrap();
107
108     let mut _buffy = [0u16; 24 * 32];
109     let mut buffy2 = [[0u16; 320]; 240];
110
111     let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2);
112
113     // //                                     rrrrr gggggg bbbbb
114     // buffy.iter_mut().for_each(|px| *px = 0b11111_000000_00000);
115
116     let mut style = TextStyleBuilder::new(Font8x16)
117         .text_color(Rgb565::WHITE)
118         .background_color(Rgb565::BLACK)
119         .build();
120
121     kbd.set_backlight(255).unwrap();
122
123     let vers = kbd.get_version().unwrap();
124
125     rprintln!("Vers: {:?}", vers);
126
127     kbd.sw_reset().unwrap();
128     timer.delay_ms(10u8);
129
130     let vers = kbd.get_version().unwrap();
131
132     rprintln!("Vers: {:?}", vers);
133
134     let mut cursor = Cursor { x: 0, y: 0 };
135
136     lcd.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
137     fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
138
139     loop {
140         let key = kbd.get_fifo_key_raw().map_err(|_| "bad fifo")?;
141
142         match key {
143             // LL
144             KeyRaw::Pressed(6) => {
145                 style = TextStyleBuilder::new(Font8x16)
146                     .text_color(Rgb565::WHITE)
147                     .background_color(Rgb565::BLACK)
148                     .build();
149             }
150             // LR
151             KeyRaw::Pressed(17) => {
152                 style = TextStyleBuilder::new(Font8x16)
153                     .text_color(Rgb565::RED)
154                     .background_color(Rgb565::BLACK)
155                     .build();
156             }
157             // RL
158             KeyRaw::Pressed(7) => {
159                 style = TextStyleBuilder::new(Font8x16)
160                     .text_color(Rgb565::GREEN)
161                     .background_color(Rgb565::BLACK)
162                     .build();
163             }
164             // RR
165             KeyRaw::Pressed(18) => {
166                 style = TextStyleBuilder::new(Font8x16)
167                     .text_color(Rgb565::BLUE)
168                     .background_color(Rgb565::BLACK)
169                     .build();
170             }
171             // Up
172             KeyRaw::Pressed(1) => {
173                 cursor.up();
174             }
175             // Down
176             KeyRaw::Pressed(2) => {
177                 cursor.down();
178             }
179             // Left
180             KeyRaw::Pressed(3) => {
181                 cursor.left();
182             }
183             // Right
184             KeyRaw::Pressed(4) => {
185                 cursor.right();
186             }
187             // Center
188             KeyRaw::Pressed(5) => {
189                 kbd.sw_reset().unwrap();
190                 cursor = Cursor { x: 0, y: 0 };
191                 fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?;
192             }
193             // Backspace
194             KeyRaw::Pressed(8) => {
195                 cursor.left();
196                 Text::new(" ", cursor.pos())
197                     .into_styled(style)
198                     .draw(&mut fbuffy)
199                     .map_err(|_| "bad lcd")?;
200             }
201             // Enter
202             KeyRaw::Pressed(10) => {
203                 cursor.enter();
204             }
205             KeyRaw::Pressed(k) => {
206                 rprintln!("Got key {}", k);
207                 if let Ok(s) = core::str::from_utf8(&[k]) {
208                     Text::new(s, cursor.pos())
209                         .into_styled(style)
210                         .draw(&mut fbuffy)
211                         .map_err(|_| "bad lcd")?;
212
213                     cursor.right();
214                 }
215             }
216             KeyRaw::Invalid => {
217                 if let Some(buf) = fbuffy.inner() {
218                     timer.start(1_000_000u32);
219                     lcd.draw_raw(0, 0, 319, 239, buf).map_err(|_| "bad buffy")?;
220                     let done = timer.read();
221                     rprintln!("Drew in {}ms.", done / 1000);
222                 } else {
223                     timer.delay_ms(38u8);
224                 }
225             }
226             _ => {}
227         }
228     }
229 }
230
231 struct Cursor {
232     x: i32,
233     y: i32,
234 }
235
236 impl Cursor {
237     fn up(&mut self) {
238         self.y -= 1;
239         if self.y < 0 {
240             self.y = 0;
241         }
242     }
243
244     fn down(&mut self) {
245         self.y += 1;
246         if self.y >= 15 {
247             self.y = 14;
248         }
249     }
250
251     fn left(&mut self) {
252         self.x -= 1;
253         if self.x < 0 {
254             if self.y != 0 {
255                 self.x = 39;
256                 self.up();
257             } else {
258                 self.x = 0;
259             }
260         }
261     }
262
263     fn right(&mut self) {
264         self.x += 1;
265         if self.x >= 40 {
266             self.x = 0;
267             self.down();
268         }
269     }
270
271     fn enter(&mut self) {
272         if self.y != 14 {
273             self.x = 0;
274             self.down();
275         }
276     }
277
278     fn pos(&self) -> Point {
279         Point::new(self.x * 8, self.y * 16)
280     }
281 }