X-Git-Url: https://git.patrickod.com/tor.noisebridge.net/tree/src/App.css?a=blobdiff_plain;f=keywing%2Fsrc%2Fmain.rs;fp=keywing%2Fsrc%2Fmain.rs;h=15df83b6a085c773dc318c48a87743b1dfbc4af2;hb=fdaa0cd104dcde008b93d7dadb830508084c45c3;hp=fd713503492fd18b2c906c1443cade2fc638dd25;hpb=f0c087b3c6464eab7d19a3a7b8c8835aff3cc6c1;p=keywing-rs.git diff --git a/keywing/src/main.rs b/keywing/src/main.rs index fd71350..15df83b 100644 --- a/keywing/src/main.rs +++ b/keywing/src/main.rs @@ -2,36 +2,23 @@ #![no_main] // Panic provider crate -use panic_persist; use cortex_m; +use panic_persist; // Used to set the program entry point use cortex_m_rt::entry; // Provides definitions for our development board use nrf52840_hal::{ + gpio::{p0::Parts as P0Parts, p1::Parts as P1Parts, Level}, prelude::*, - target::{Peripherals, CorePeripherals}, - Timer, - Rng, - Spim, - spim::{ - Pins as SpimPins, - Frequency as SpimFrequency, - MODE_0, - }, - gpio::{ - p0::Parts as P0Parts, - p1::Parts as P1Parts, - Level, - }, - Clocks, + spim::{Frequency as SpimFrequency, Pins as SpimPins, MODE_0}, + target::{CorePeripherals, Peripherals}, + twim::{Frequency as TwimFrequency, Pins as TwimPins}, + Clocks, Rng, Spim, Timer, Twim, }; -use rtt_target::{ - rprint, rprintln, - rtt_init_print, -}; +use rtt_target::{rprint, rprintln, rtt_init_print}; use embedded_graphics::{ fonts::{Font8x16, Text}, @@ -40,6 +27,8 @@ use embedded_graphics::{ style::{TextStyle, TextStyleBuilder}, }; +use bbq10kbd::{Bbq10Kbd, KeyRaw}; + mod buffer; use ili9341::{Ili9341, Orientation}; @@ -64,31 +53,107 @@ const TEXT_SAMPLE: &[&str] = &[ const TEXT_SAMPLE2: &[&[(i32, Rgb565, &str)]] = &[ // "for x in 0..10 {", - &[(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, " {")], + &[ + (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, " {"), + ], // " for y in 0..10 {", - &[(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, " {")], + &[ + (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, " {"), + ], // " let rand: u16 = rng.random_u16();", - &[(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, "();")], + &[ + (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, "();"), + ], // " buffy.iter_mut().for_each(|px| {", - &[(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, "| {")], + &[ + (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, "| {"), + ], // " *px = swap(rand)", - &[(6, Rgb565::RED, "*"), (7, Rgb565::WHITE, "px "), (10, Rgb565::RED, "= "), (12, Rgb565::CYAN, "swap"), (16, Rgb565::WHITE, "(rand)")], + &[ + (6, Rgb565::RED, "*"), + (7, Rgb565::WHITE, "px "), + (10, Rgb565::RED, "= "), + (12, Rgb565::CYAN, "swap"), + (16, Rgb565::WHITE, "(rand)"), + ], // " });", &[(4, Rgb565::WHITE, "});")], // " lcd.draw_raw(", - &[(4, Rgb565::WHITE, "lcd."), (8, Rgb565::CYAN, "draw_raw"), (16, Rgb565::WHITE, "(")], + &[ + (4, Rgb565::WHITE, "lcd."), + (8, Rgb565::CYAN, "draw_raw"), + (16, Rgb565::WHITE, "("), + ], // " 32 * x,", - &[(6, Rgb565::MAGENTA, "32 "), (9, Rgb565::RED, "* "), (11, Rgb565::WHITE, "x,")], + &[ + (6, Rgb565::MAGENTA, "32 "), + (9, Rgb565::RED, "* "), + (11, Rgb565::WHITE, "x,"), + ], // " 24 * y,", - &[(6, Rgb565::MAGENTA, "24 "), (9, Rgb565::RED, "* "), (11, Rgb565::WHITE, "y,")], + &[ + (6, Rgb565::MAGENTA, "24 "), + (9, Rgb565::RED, "* "), + (11, Rgb565::WHITE, "y,"), + ], // " (32 * (x + 1)) - 1,", - &[(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, ",")], + &[ + (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, ","), + ], // " (24 * (y + 1)) - 1,", - &[(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, ",")], + &[ + (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, ","), + ], // " &buffy,", &[(6, Rgb565::RED, "&"), (7, Rgb565::WHITE, "buffy,")], // " ).unwrap();", - &[(4, Rgb565::WHITE, ")."), (6, Rgb565::CYAN, "unwrap"), (12, Rgb565::WHITE, "();")], + &[ + (4, Rgb565::WHITE, ")."), + (6, Rgb565::CYAN, "unwrap"), + (12, Rgb565::WHITE, "();"), + ], // " }", &[(2, Rgb565::WHITE, "}")], // "}", @@ -121,7 +186,6 @@ fn inner_main() -> Result<(), &'static str> { rprintln!("Clean boot!"); } - let p0 = P0Parts::new(board.P0); let p1 = P1Parts::new(board.P1); @@ -130,8 +194,23 @@ fn inner_main() -> Result<(), &'static str> { let lcd_cs = p0.p0_26; // GPIO9, D9, let lcd_dc = p0.p0_27; // GPIO10, D10 - // Pull the neopixel line low so noise doesn't make it turn on spuriously + let kbd_sda = p0.p0_12.into_floating_input().degrade(); + let kbd_scl = p0.p0_11.into_floating_input().degrade(); + + let kbd_i2c = Twim::new( + board.TWIM0, + TwimPins { + sda: kbd_sda, + scl: kbd_scl, + }, + TwimFrequency::K100, + ); + + let mut kbd = Bbq10Kbd::new(kbd_i2c); + + // Pull the neopixel lines low so noise doesn't make it turn on spuriously let keywing_neopixel = p0.p0_06.into_push_pull_output(Level::Low); // GPIO11, D11 + let feather_neopixel = p0.p0_16.into_push_pull_output(Level::Low); let spim = Spim::new( board.SPIM3, @@ -151,11 +230,12 @@ fn inner_main() -> Result<(), &'static str> { lcd_dc.into_push_pull_output(Level::High), kbd_lcd_reset.into_push_pull_output(Level::High), &mut delay, - ).unwrap(); + ) + .unwrap(); lcd.set_orientation(Orientation::Landscape).unwrap(); - let mut buffy = [0u16; 24 * 32]; + let mut _buffy = [0u16; 24 * 32]; let mut buffy2 = [[0u16; 320]; 240]; let mut fbuffy = buffer::FrameBuffer::new(&mut buffy2); @@ -163,321 +243,208 @@ fn inner_main() -> Result<(), &'static str> { // // rrrrr gggggg bbbbb // buffy.iter_mut().for_each(|px| *px = 0b11111_000000_00000); - let style = TextStyleBuilder::new(Font8x16) + let mut style = TextStyleBuilder::new(Font8x16) .text_color(Rgb565::WHITE) .background_color(Rgb565::BLACK) .build(); - loop { + let mut ctr: u8 = 0; + kbd.set_backlight(ctr).unwrap(); - rprintln!("Start colors raw"); - - for x in 0..10 { - for y in 0..10 { - let rand: u16 = rng.random_u16(); - buffy.iter_mut().for_each(|px| { - *px = swap(rand) - }); - - lcd.draw_raw( - 32 * x, - 24 * y, - (32 * (x + 1)) - 1, - (24 * (y + 1)) - 1, - &buffy, - ).unwrap(); - } - } + let vers = kbd.get_version().unwrap(); - rprintln!("Done.\n"); + rprintln!("Vers: {:?}", vers); - timer.delay_ms(1000u16); + kbd.sw_reset().unwrap(); + timer.delay_ms(10u8); - rprintln!("Start colors raw"); + let vers = kbd.get_version().unwrap(); - for x in 0..10 { - for y in 0..10 { - let rand: u16 = 0; - buffy.iter_mut().for_each(|px| { - *px = swap(rand) - }); + rprintln!("Vers: {:?}", vers); - lcd.draw_raw( - 32 * x, - 24 * y, - (32 * (x + 1)) - 1, - (24 * (y + 1)) - 1, - &buffy, - ).unwrap(); - } - } - - rprintln!("Done.\n"); - - - timer.delay_ms(1000u16); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000)); - // rprintln!("Start black"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - rprintln!("text start"); - - for row in 0..15 { - Text::new( - TEXT_SAMPLE[row as usize], - Point::new(0, row * 16) - ).into_styled(style) - .draw(&mut lcd) - .unwrap(); - } - - rprintln!("text done"); - - timer.delay_ms(3000u16); - - rprintln!("Start colors raw"); + let mut cursor_y = 0; + let mut cursor_x = 0; - for x in 0..10 { - for y in 0..10 { - let rand: u16 = 0; - buffy.iter_mut().for_each(|px| { - *px = swap(rand) - }); - - lcd.draw_raw( - 32 * x, - 24 * y, - (32 * (x + 1)) - 1, - (24 * (y + 1)) - 1, - &buffy, - ).unwrap(); - } - } + let mut cursor = Cursor { x: 0, y: 0 }; - rprintln!("Done.\n"); + lcd.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?; + fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?; + loop { + let key = kbd.get_fifo_key_raw().map_err(|_| "bad fifo")?; - timer.delay_ms(1000u16); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000)); - // rprintln!("Start black"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - rprintln!("text2 start"); - - for (i, row) in TEXT_SAMPLE2.iter().enumerate() { - for (offset, color, text) in row.iter() { - let styled = TextStyleBuilder::new(Font8x16) - .text_color(*color) + match key { + // LL + KeyRaw::Pressed(6) => { + style = TextStyleBuilder::new(Font8x16) + .text_color(Rgb565::WHITE) .background_color(Rgb565::BLACK) .build(); - - Text::new( - text, - Point::new(*offset * 8, i as i32 * 16) - ).into_styled(styled) - .draw(&mut lcd) - .unwrap(); } - } - - rprintln!("text2 done"); - - timer.delay_ms(3000u16); - - rprintln!("Start colors raw"); - - for x in 0..10 { - for y in 0..10 { - let rand: u16 = 0; - buffy.iter_mut().for_each(|px| { - *px = swap(rand) - }); - - lcd.draw_raw( - 32 * x, - 24 * y, - (32 * (x + 1)) - 1, - (24 * (y + 1)) - 1, - &buffy, - ).unwrap(); + // LR + KeyRaw::Pressed(17) => { + style = TextStyleBuilder::new(Font8x16) + .text_color(Rgb565::RED) + .background_color(Rgb565::BLACK) + .build(); } - } - - rprintln!("Done.\n"); - - timer.delay_ms(1000u16); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000)); - // rprintln!("Start black"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - timer.start(1_000_000u32); - - let start: u32 = timer.read(); - - for row in 0..15 { - Text::new( - TEXT_SAMPLE[row as usize], - Point::new(0, row * 16) - ).into_styled(style) - .draw(&mut fbuffy) - .unwrap(); - } - - let middle: u32 = timer.read(); - - lcd.draw_raw(0, 0, 319, 239, fbuffy.inner()).unwrap(); - - let end: u32 = timer.read(); - - rprintln!("text buffered done"); - rprintln!("start: 0x{:08X}, middle: 0x{:08X}, end: 0x{:08X}", start, middle, end); - rprintln!("render: {} cycs", middle - start); - rprintln!("draw: {} cycs", end - middle); - - - - - - timer.delay_ms(3000u16); - - rprintln!("Start colors raw"); - - for x in 0..10 { - for y in 0..10 { - let rand: u16 = 0; - buffy.iter_mut().for_each(|px| { - *px = swap(rand) - }); - - lcd.draw_raw( - 32 * x, - 24 * y, - (32 * (x + 1)) - 1, - (24 * (y + 1)) - 1, - &buffy, - ).unwrap(); + // RL + KeyRaw::Pressed(7) => { + style = TextStyleBuilder::new(Font8x16) + .text_color(Rgb565::GREEN) + .background_color(Rgb565::BLACK) + .build(); } - } - - rprintln!("Done.\n"); - - - timer.delay_ms(1000u16); - - rprintln!("text2 buffered middle"); - - for (i, row) in TEXT_SAMPLE2.iter().enumerate() { - for (offset, color, text) in row.iter() { - let styled = TextStyleBuilder::new(Font8x16) - .text_color(*color) + // RR + KeyRaw::Pressed(18) => { + style = TextStyleBuilder::new(Font8x16) + .text_color(Rgb565::BLUE) .background_color(Rgb565::BLACK) .build(); + } + // Up + KeyRaw::Pressed(1) => { + cursor.up(); + } + // Down + KeyRaw::Pressed(2) => { + cursor.down(); + } + // Left + KeyRaw::Pressed(3) => { + cursor.left(); + } + // Right + KeyRaw::Pressed(4) => { + cursor.right(); + } + // Center + KeyRaw::Pressed(5) => { + kbd.sw_reset().unwrap(); + cursor = Cursor { x: 0, y: 0 }; + fbuffy.clear(Rgb565::BLACK).map_err(|_| "Fade to error")?; + } + // Backspace + KeyRaw::Pressed(8) => { + cursor.left(); + Text::new(" ", cursor.pos()) + .into_styled(style) + .draw(&mut fbuffy) + .map_err(|_| "bad lcd")?; + } + // Enter + KeyRaw::Pressed(10) => { + cursor.enter(); + } + KeyRaw::Pressed(k) => { + rprintln!("Got key {}", k); + if let Ok(s) = core::str::from_utf8(&[k]) { + Text::new(s, cursor.pos()) + .into_styled(style) + .draw(&mut fbuffy) + .map_err(|_| "bad lcd")?; + + cursor.right(); + } + } + KeyRaw::Invalid => { + if let Some(buf) = fbuffy.inner() { + timer.start(1_000_000u32); + lcd.draw_raw( + 0, 0, + 319, 239, + buf + ).map_err(|_| "bad buffy")?; + let done = timer.read(); + rprintln!("Drew in {}ms.", done / 1000); + } else { + timer.delay_ms(38u8); + } - Text::new( - text, - Point::new(*offset * 8, i as i32 * 16) - ).into_styled(styled) - .draw(&mut fbuffy) - .unwrap(); } + _ => {} } + } - rprintln!("text2 buffered middle"); - - lcd.draw_raw(0, 0, 319, 239, fbuffy.inner()).unwrap(); - - rprintln!("text2 buffered done"); - - timer.delay_ms(3000u16); - - continue; - - - // // SHOULD BE - // // rrrrr gggggg bbbbb - // buffy2.iter_mut().for_each(|px| *px = swap(0b11111_000000_00000)); - // rprintln!("Start red"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - // timer.delay_ms(250u16); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_111111_00000)); - // rprintln!("Start green"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - // timer.delay_ms(250u16); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_11111)); - // rprintln!("Start blue"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000)); - // rprintln!("Start black"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); + Ok(()) +} - // 240 / 16: 15 - // 320 / 8: 40 +struct Cursor { + x: i32, + y: i32, +} - let text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; +impl Cursor { + fn up(&mut self) { + self.y -= 1; + if self.y < 0 { + self.y = 0; + } + } - let mut textiter = text.chars().cycle(); + fn down(&mut self) { + self.y += 1; + if self.y >= 15 { + self.y = 14; + } + } - for row in 0..15 { - for col in 0..40 { - let mut buf = [0u8; 4]; - let txt = textiter.next().unwrap().encode_utf8(&mut buf); - Text::new( - txt, - Point::new(col * 8, row * 16) - ).into_styled(style) - .draw(&mut lcd) - .unwrap(); + fn left(&mut self) { + self.x -= 1; + if self.x < 0 { + if self.y != 0 { + self.x = 39; + self.up(); + } else { + self.x = 0; } - timer.delay_ms(500u16); } + } - timer.delay_ms(1000u16); - - - // buffy2.iter_mut().for_each(|px| *px = swap(0b00000_000000_00000)); - // rprintln!("Start black"); - // lcd.draw_raw(0, 0, 319, 239, &buffy2).unwrap(); - // rprintln!("Done.\n"); - - rprintln!("Starting Text Fill..."); - - let mut text = Text::new( - "1234567890123456789012345678901234567890", - Point::new(0, 0) - ).into_styled(style); - - for _y in 0..15 { - text.draw(&mut lcd).unwrap(); - text = text.translate(Point::new(0, 16)); + fn right(&mut self) { + self.x += 1; + if self.x >= 40 { + self.x = 0; + self.down(); } + } - rprintln!("Finished Text Fill."); - - - timer.delay_ms(1000u16); - - + fn enter(&mut self) { + if self.y != 14 { + self.x = 0; + self.down(); + } } - Ok(()) + fn pos(&self) -> Point { + Point::new(self.x * 8, self.y * 16) + } } -const fn swap(inp: u16) -> u16 { - (inp & 0x00FF) << 8 | - (inp & 0xFF00) >> 8 -} +// let key_raw = kbd.get_fifo_key_raw().unwrap(); + +// match key_raw { +// KeyRaw::Invalid => { +// timer.delay_ms(1000u16); +// let state = kbd.get_key_status().unwrap(); +// rprintln!("Key Status: {:?}", state); +// } +// key @ _ => { +// ctr = ctr.wrapping_add(5); +// rprintln!("Key: {:?} - {}", key, ctr); +// kbd.set_backlight(ctr).unwrap(); +// assert_eq!(kbd.get_backlight().unwrap(), ctr); +// } +// } + +// Special keys +// LL: 6 +// LR: 17 +// RL: 7 +// RR: 18 +// +// D-L: 3 +// D-U: 1 +// D-R: 4 +// D-D: 2 +// D-C: 5