diff --git a/fl16-inputmodules/src/lib.rs b/fl16-inputmodules/src/lib.rs index 7b2c45a1..9374c47c 100644 --- a/fl16-inputmodules/src/lib.rs +++ b/fl16-inputmodules/src/lib.rs @@ -8,6 +8,7 @@ pub mod games; #[cfg(feature = "ledmatrix")] pub mod led_hal; #[cfg(feature = "ledmatrix")] +#[rustfmt::skip] pub mod mapping; #[cfg(feature = "ledmatrix")] pub mod matrix; diff --git a/fl16-inputmodules/src/mapping.rs b/fl16-inputmodules/src/mapping.rs index 5c640fbe..53a98874 100644 --- a/fl16-inputmodules/src/mapping.rs +++ b/fl16-inputmodules/src/mapping.rs @@ -5,105 +5,313 @@ pub type SingleDisplayData = [u8; 8]; /// Capital letter A pub const CAP_A: SingleDisplayData = [ - 0b00111000, 0b01000100, 0b01000100, 0b01000100, 0b01111100, 0b01000100, 0b01000100, 0b01000100, + 0b00010000, + 0b00101000, + 0b00101000, + 0b01000100, + 0b01111100, + 0b01000100, + 0b01000100, + 0b01000100, ]; /// Capital letter B pub const CAP_B: SingleDisplayData = [ - 0b01111000, 0b01000100, 0b01000100, 0b01111000, 0b01000100, 0b01000100, 0b01000100, 0b01111000, + 0b01111000, + 0b01000100, + 0b01000100, + 0b01111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01111000, ]; /// Capital letter C pub const CAP_C: SingleDisplayData = [ - 0b01111100, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01000000, 0b01111100, + 0b01111100, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01111100, ]; /// Capital letter D pub const CAP_D: SingleDisplayData = [ - 0b01111000, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01111000, + 0b01111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01111000, ]; /// Capital letter E pub const CAP_E: SingleDisplayData = [ - 0b01111100, 0b01000000, 0b01000000, 0b01111100, 0b01000000, 0b01000000, 0b01000000, 0b01111100, + 0b01111100, + 0b01000000, + 0b01000000, + 0b01111100, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01111100, ]; /// Capital letter F pub const CAP_F: SingleDisplayData = [ - 0b01111100, 0b01000000, 0b01000000, 0b01111100, 0b01000000, 0b01000000, 0b01000000, 0b01000000, + 0b01111100, + 0b01000000, + 0b01000000, + 0b01111100, + 0b01000000, + 0b01000000, + 0b01000000, + 0b01000000, ]; /// Capital letter G pub const CAP_G: SingleDisplayData = [ - 0b01111000, 0b11000100, 0b10000100, 0b10000000, 0b10011100, 0b10000100, 0b11000100, 0b01111100, + 0b01111000, + 0b11000100, + 0b10000100, + 0b10000000, + 0b10011100, + 0b10000100, + 0b11000100, + 0b01111100, ]; /// Capital letter H pub const CAP_H: SingleDisplayData = [ - 0b01000100, 0b01000100, 0b01000100, 0b01111100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01111100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, ]; /// Capital letter I pub const CAP_I: SingleDisplayData = [ - 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, ]; /// Capital letter J -pub const CAP_J: SingleDisplayData = [0; 8]; // TODO +pub const CAP_J: SingleDisplayData = [ + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b10010000, + 0b01100000, +]; /// Capital letter K pub const CAP_K: SingleDisplayData = [ - 0b01000100, 0b01001000, 0b01010000, 0b01100000, 0b01010000, 0b01001000, 0b01000100, 0b01000010, + 0b01000100, + 0b01001000, + 0b01010000, + 0b01100000, + 0b01010000, + 0b01001000, + 0b01000100, + 0b01000010, ]; /// Capital letter L /// I shifted it one left pub const CAP_L: SingleDisplayData = [ - 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b10000000, 0b11111000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b10000000, + 0b11111000, ]; /// Capital letter M pub const CAP_M: SingleDisplayData = [ - 0b10000010, 0b11000110, 0b10101010, 0b10111010, 0b10010010, 0b10000010, 0b10000010, 0b10000010, + 0b10000010, + 0b11000110, + 0b10101010, + 0b10111010, + 0b10010010, + 0b10000010, + 0b10000010, + 0b10000010, ]; /// Capital letter N pub const CAP_N: SingleDisplayData = [ - 0b01000100, 0b01100100, 0b01110100, 0b01010100, 0b01011100, 0b01001100, 0b01001100, 0b01000100, + 0b01000100, + 0b01100100, + 0b01110100, + 0b01010100, + 0b01011100, + 0b01001100, + 0b01001100, + 0b01000100, ]; /// Capital letter O pub const CAP_O: SingleDisplayData = [ - 0b00011000, 0b00100100, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b00100100, 0b00011000, + 0b00011000, + 0b00100100, + 0b01000010, + 0b01000010, + 0b01000010, + 0b01000010, + 0b00100100, + 0b00011000, ]; /// Capital letter P pub const CAP_P: SingleDisplayData = [ - 0b01111000, 0b01000100, 0b01000100, 0b01000100, 0b01111000, 0b01000000, 0b01000000, 0b01000000, + 0b01111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01111000, + 0b01000000, + 0b01000000, + 0b01000000, ]; /// Capital letter Q -pub const CAP_Q: SingleDisplayData = [0; 8]; // TODO +pub const CAP_Q: SingleDisplayData = [ + 0b00011000, + 0b00100100, + 0b01000010, + 0b01000010, + 0b01001010, + 0b01000110, + 0b00100110, + 0b00011001, +]; /// Capital letter R pub const CAP_R: SingleDisplayData = [ - 0b01111000, 0b01000100, 0b01000100, 0b01111000, 0b01100000, 0b01010000, 0b01001000, 0b01000100, + 0b01111000, + 0b01000100, + 0b01000100, + 0b01111000, + 0b01100000, + 0b01010000, + 0b01001000, + 0b01000100, ]; /// Capital letter S /// I shifted it one to the right pub const CAP_S: SingleDisplayData = [ - 0b00000111, 0b00001000, 0b00010000, 0b00001100, 0b00000010, 0b00000001, 0b00000001, 0b00011110, + 0b00000111, + 0b00001000, + 0b00010000, + 0b00001100, + 0b00000010, + 0b00000001, + 0b00000001, + 0b00011110, ]; /// Capital letter T pub const CAP_T: SingleDisplayData = [ - 0b11111110, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, + 0b11111110, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, ]; /// Capital letter U pub const CAP_U: SingleDisplayData = [ - 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b01000010, 0b00111100, + 0b01000010, + 0b01000010, + 0b01000010, + 0b01000010, + 0b01000010, + 0b01000010, + 0b01000010, + 0b00111100, ]; /// Capital letter V -pub const CAP_V: SingleDisplayData = [0; 8]; // TODO +pub const CAP_V: SingleDisplayData = [ + 0b10000001, + 0b10000001, + 0b10000001, + 0b10000001, + 0b10000010, + 0b01000100, + 0b00101000, + 0b00010000, +]; /// Capital letter W -pub const CAP_W: SingleDisplayData = [0; 8]; // TODO +pub const CAP_W: SingleDisplayData = [ + 0b10000010, + 0b10010010, + 0b11010110, + 0b01010100, + 0b01111100, + 0b00110000, + 0b00010000, + 0b00000000, +]; /// Capital letter X -pub const CAP_X: SingleDisplayData = [0; 8]; // TODO +pub const CAP_X: SingleDisplayData = [ + 0b00000000, + 0b10000010, + 0b01000100, + 0b00101000, + 0b00010000, + 0b00101000, + 0b01000100, + 0b10000010, +]; /// Capital letter Y -pub const CAP_Y: SingleDisplayData = [0; 8]; // TODO +pub const CAP_Y: SingleDisplayData = [ + 0b01000100, + 0b01000100, + 0b00101000, + 0b00101000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, +]; /// Capital letter Z pub const CAP_Z: SingleDisplayData = [ - 0b01111110, 0b00000010, 0b00000100, 0b00001000, 0b00010000, 0b00100000, 0b01000000, 0b01111110, + 0b01111110, + 0b00000010, + 0b00000100, + 0b00001000, + 0b00010000, + 0b00100000, + 0b01000000, + 0b01111110, ]; /// Number 0 pub const ZERO: SingleDisplayData = [ - 0b00111000, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b01000100, 0b00111000, + 0b00111000, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b01000100, + 0b00111000, ]; /// Number 1 pub const ONE: SingleDisplayData = [ - 0b00000100, 0b00011100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, 0b00000100, + 0b00000100, + 0b00011100, + 0b00000100, + 0b00000100, + 0b00000100, + 0b00000100, + 0b00000100, + 0b00000100, ]; /// " " character pub const SPACE: SingleDisplayData = [0; 8]; @@ -111,5 +319,12 @@ pub const SPACE: SingleDisplayData = [0; 8]; pub const DOT: SingleDisplayData = [0, 0, 0, 0, 0, 0, 0, 0b00010000]; /// "!" character pub const EXCLAMATION_MARK: SingleDisplayData = [ - 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0b00010000, 0, 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00010000, + 0b00000000, + 0b00010000, ]; diff --git a/ledmatrix/src/main.rs b/ledmatrix/src/main.rs index 3bdfa170..b5691977 100644 --- a/ledmatrix/src/main.rs +++ b/ledmatrix/src/main.rs @@ -31,6 +31,8 @@ enum SleepMode { /// slowly fade themm on/off const SLEEP_MODE: SleepMode = SleepMode::Fading; +const STARTUP_ANIMATION: bool = true; + const MAX_CURRENT: usize = 500; /// Maximum brightness out of 255 @@ -234,6 +236,9 @@ fn main() -> ! { let mut game_timer = timer.get_counter().ticks(); let mut startup_percentage = Some(0); + if !STARTUP_ANIMATION { + state.grid = percentage(100); + } // Detect whether the sleep pin is connected // Early revisions of the hardware didn't have it wired up, if that is the @@ -248,10 +253,17 @@ fn main() -> ! { sleep_present = true; } + let mut usb_initialized = false; + let mut usb_suspended = true; + loop { if sleep_present { // Go to sleep if the host is sleeping - let host_sleeping = sleep.is_low().unwrap(); + // Or if USB is suspended. Only if it was previously initialized, + // since the OS puts the device into suspend before it's fully + // initialized for the first time. But we don't want to show the + // sleep animation during startup. + let host_sleeping = sleep.is_low().unwrap() || (usb_suspended && usb_initialized); handle_sleep( host_sleeping, &mut state, @@ -266,7 +278,7 @@ fn main() -> ! { if matches!(state.sleeping, SleepState::Awake) && render_again { // On startup slowly turn the screen on - it's a pretty effect :) match startup_percentage { - Some(p) if p <= 100 => { + Some(p) if p <= 100 && STARTUP_ANIMATION => { state.grid = percentage(p); startup_percentage = Some(p + 5); } @@ -284,6 +296,24 @@ fn main() -> ! { // Check for new data if usb_dev.poll(&mut [&mut serial]) { + match usb_dev.state() { + // Default: Device has just been created or reset + // Addressed: Device has received an address for the host + UsbDeviceState::Default | UsbDeviceState::Addressed => { + usb_initialized = false; + usb_suspended = false; + // Must not display anything or windows cannot enumerate properly + } + // Configured and is fully operational + UsbDeviceState::Configured => { + usb_initialized = true; + usb_suspended = false; + } + // Never occurs here. Only if poll() returns false + UsbDeviceState::Suspend => { + panic!("Never occurs here. Only if poll() returns false") + } + } let mut buf = [0u8; 64]; match serial.read(&mut buf) { Err(_e) => { @@ -337,6 +367,21 @@ fn main() -> ! { } } } + } else { + match usb_dev.state() { + // No new data + UsbDeviceState::Default | UsbDeviceState::Addressed => { + usb_initialized = false; + usb_suspended = false; + } + UsbDeviceState::Configured => { + usb_initialized = true; + usb_suspended = false; + } + UsbDeviceState::Suspend => { + usb_suspended = true; + } + } } // Handle game state