@@ -44,7 +44,7 @@ pub mod vga;
4444// -----------------------------------------------------------------------------
4545
4646// Standard Library Stuff
47- use core:: fmt:: Write ;
47+ use core:: { fmt:: Write , sync :: atomic :: AtomicBool } ;
4848
4949// Third Party Stuff
5050use cortex_m_rt:: entry;
@@ -89,6 +89,26 @@ struct Hardware {
8989 debug_leds : u8 ,
9090 /// The last CS pin we selected
9191 last_cs : u8 ,
92+ /// Our keyboard decoder
93+ keyboard : pc_keyboard:: Keyboard < pc_keyboard:: layouts:: Uk105Key , pc_keyboard:: ScancodeSet2 > ,
94+ /// Our queue of HID events
95+ event_queue : heapless:: Deque < neotron_common_bios:: hid:: HidEvent , 16 > ,
96+ }
97+
98+ /// Flips between true and false so we always send a unique read request
99+ struct UseAlt ( AtomicBool ) ;
100+
101+ impl UseAlt {
102+ const fn new ( ) -> UseAlt {
103+ UseAlt ( AtomicBool :: new ( false ) )
104+ }
105+
106+ fn get ( & self ) -> bool {
107+ let use_alt = self . 0 . load ( core:: sync:: atomic:: Ordering :: Relaxed ) ;
108+ self . 0
109+ . store ( !use_alt, core:: sync:: atomic:: Ordering :: Relaxed ) ;
110+ use_alt
111+ }
92112}
93113
94114/// All the pins we use on the Pico, in the right mode.
@@ -134,6 +154,9 @@ struct Pins {
134154/// The BIOS version string
135155static BIOS_VERSION : & str = concat ! ( "Neotron Pico BIOS version " , env!( "BIOS_VERSION" ) , "\0 " ) ;
136156
157+ /// Ensures we always send a unique read request
158+ static USE_ALT : UseAlt = UseAlt :: new ( ) ;
159+
137160/// Our global hardware object.
138161///
139162/// You need to grab this to do anything with the hardware.
@@ -517,6 +540,8 @@ impl Hardware {
517540 delay,
518541 debug_leds : 0 ,
519542 last_cs : 0 ,
543+ keyboard : pc_keyboard:: Keyboard :: new ( pc_keyboard:: HandleControl :: Ignore ) ,
544+ event_queue : heapless:: Deque :: new ( ) ,
520545 }
521546 }
522547
@@ -720,48 +745,57 @@ impl Hardware {
720745 /// Read the BMC PS/2 keyboard FIFO.
721746 ///
722747 /// We ask for 8 bytes of data. We get `1` byte of 'length', then `N` bytes of valid data, and `32 - (N + 1)` bytes of padding.
723- fn bmc_read_ps2_keyboard_fifo ( & mut self , buffer : & mut [ u8 ] ) -> Result < usize , ( ) > {
724- let req = neotron_bmc_protocol:: Request :: new_read ( false , 0x40 , 8 ) ;
725- let mut buffer = [ 0xFF ; 42 ] ;
726- buffer[ 0 ..=3 ] . copy_from_slice ( & req. as_bytes ( ) ) ;
727- self . with_bus_cs ( 0 , |spi| {
728- spi. transfer ( & mut buffer) . unwrap ( ) ;
729- } ) ;
730- defmt:: info!( "buffer: {=[u8]:x}" , buffer) ;
731- let mut result = & buffer[ ..] ;
732- let mut latency = 0 ;
733- while result. len ( ) > 0 && result[ 0 ] == 0xFF {
734- latency += 1 ;
735- result = & result[ 1 ..] ;
736- }
737- defmt:: info!( "latency: {}" , latency) ;
738- // 8 bytes of data requested, plus one bytes of response code and one byte of CRC
739- if result. len ( ) >= 10 {
740- match neotron_bmc_protocol:: Response :: from_bytes ( & result[ 0 ..10 ] ) {
741- Ok ( res) => {
742- if res. result == neotron_bmc_protocol:: ResponseResult :: Ok && res. data . len ( ) == 8
743- {
744- defmt:: info!( "Got PS/2 bytes {=[u8]:x}" , res. data) ;
745- return Ok ( 0 ) ;
746- } else {
748+ fn bmc_read_ps2_keyboard_fifo ( & mut self , out_buffer : & mut [ u8 ; 8 ] ) -> Result < usize , ( ) > {
749+ let req = neotron_bmc_protocol:: Request :: new_read ( USE_ALT . get ( ) , 0x40 , 8 ) ;
750+ for _retry in 0 ..4 {
751+ let mut buffer = [ 0xFF ; 42 ] ;
752+ buffer[ 0 ..=3 ] . copy_from_slice ( & req. as_bytes ( ) ) ;
753+ self . with_bus_cs ( 0 , |spi| {
754+ spi. transfer ( & mut buffer) . unwrap ( ) ;
755+ } ) ;
756+ defmt:: trace!( "buffer: {=[u8]:x}" , buffer) ;
757+ let mut result = & buffer[ ..] ;
758+ let mut latency = 0 ;
759+ while result. len ( ) > 0 && result[ 0 ] == 0xFF {
760+ latency += 1 ;
761+ result = & result[ 1 ..] ;
762+ }
763+ defmt:: trace!( "latency: {}" , latency) ;
764+ // 8 bytes of data requested, plus one bytes of response code and one byte of CRC
765+ if result. len ( ) >= 10 {
766+ match neotron_bmc_protocol:: Response :: from_bytes ( & result[ 0 ..10 ] ) {
767+ Ok ( res) => {
768+ if res. result == neotron_bmc_protocol:: ResponseResult :: Ok
769+ && res. data . len ( ) == 8
770+ {
771+ if res. data [ 0 ] == 0 {
772+ defmt:: trace!( "Got no PS/2 bytes" ) ;
773+ } else {
774+ defmt:: debug!( "Got PS/2 bytes {=[u8]:x}" , res. data) ;
775+ }
776+ for ( dest, src) in out_buffer. iter_mut ( ) . zip ( res. data . iter ( ) . skip ( 1 ) ) {
777+ * dest = * src;
778+ }
779+ return Ok ( res. data [ 0 ] as usize ) ;
780+ } else {
781+ defmt:: warn!(
782+ "Error getting keyboard bytes: Error from BMC {:?} {=[u8]:x}" ,
783+ res. result,
784+ res. data
785+ ) ;
786+ }
787+ }
788+ Err ( e) => {
747789 defmt:: warn!(
748- "Error getting keyboard bytes: Error from BMC {:?} {=[u8]:x}" ,
749- res . result ,
750- res . data
790+ "Error getting BMC keyboard bytes: Decoding Error {:?} {=[u8]:x}" ,
791+ e ,
792+ result
751793 ) ;
752794 }
753795 }
754- Err ( e) => {
755- defmt:: warn!(
756- "Error getting BMC keyboard bytes: Decoding Error {:?} {=[u8]:x}" ,
757- e,
758- result
759- ) ;
760- }
761796 }
762797 }
763-
764- Err ( ( ) )
798+ panic ! ( "KB retry timeout" ) ;
765799 }
766800}
767801
@@ -1043,12 +1077,206 @@ pub extern "C" fn memory_get_region(region: u8) -> common::Option<common::Memory
10431077///
10441078/// This function doesn't block. It will return `Ok(None)` if there is no event ready.
10451079pub extern "C" fn hid_get_event ( ) -> common:: Result < common:: Option < common:: hid:: HidEvent > > {
1046- // todo: call bmc_read_ps2_keyboard_fifo()
1047- // todo: decode the PS/2 bytes we receive into HidEvents
1048- // todo: cache all the bytes that don't make up a full HID event
1080+ let mut buffer = [ 0u8 ; 8 ] ;
10491081
1050- // TODO: Support some HID events
1051- common:: Result :: Ok ( common:: Option :: None )
1082+ critical_section:: with ( |cs| {
1083+ let mut lock = HARDWARE . borrow_ref_mut ( cs) ;
1084+ let hw = lock. as_mut ( ) . unwrap ( ) ;
1085+
1086+ if let Some ( ev) = hw. event_queue . pop_front ( ) {
1087+ // Queued data available, so short-cut
1088+ return common:: Result :: Ok ( common:: Option :: Some ( ev) ) ;
1089+ }
1090+
1091+ match hw. bmc_read_ps2_keyboard_fifo ( & mut buffer) {
1092+ Ok ( n) if n > 0 => {
1093+ let slice = if n >= 8 { & buffer } else { & buffer[ 0 ..n] } ;
1094+ defmt:: info!( "{} bytes in KB FIFO, got: {=[u8]:x}" , n, & slice) ;
1095+ for b in slice. iter ( ) {
1096+ match hw. keyboard . add_byte ( * b) {
1097+ Ok ( Some ( key_event) ) => {
1098+ convert_hid_event ( key_event, & mut hw. event_queue ) ;
1099+ }
1100+ Ok ( None ) => {
1101+ // Need more data
1102+ }
1103+ Err ( e) => {
1104+ panic ! ( "Keyboard decode error!" ) ;
1105+ }
1106+ }
1107+ }
1108+ }
1109+ Ok ( _) => {
1110+ // Say nothing - FIFO is empty
1111+ }
1112+ Err ( e) => {
1113+ defmt:: warn!( "Read KB error: {:?}" , e) ;
1114+ }
1115+ }
1116+
1117+ if let Some ( ev) = hw. event_queue . pop_front ( ) {
1118+ // Queued data available, so short-cut
1119+ common:: Result :: Ok ( common:: Option :: Some ( ev) )
1120+ } else {
1121+ common:: Result :: Ok ( common:: Option :: None )
1122+ }
1123+ } )
1124+ }
1125+
1126+ fn convert_hid_event (
1127+ pc_keyboard_ev : pc_keyboard:: KeyEvent ,
1128+ ev_queue : & mut heapless:: Deque < common:: hid:: HidEvent , 16 > ,
1129+ ) {
1130+ match pc_keyboard_ev. state {
1131+ pc_keyboard:: KeyState :: Down => {
1132+ ev_queue
1133+ . push_back ( common:: hid:: HidEvent :: KeyPress ( convert_hid_code (
1134+ pc_keyboard_ev. code ,
1135+ ) ) )
1136+ . unwrap ( ) ;
1137+ }
1138+ pc_keyboard:: KeyState :: Up => {
1139+ ev_queue
1140+ . push_back ( common:: hid:: HidEvent :: KeyRelease ( convert_hid_code (
1141+ pc_keyboard_ev. code ,
1142+ ) ) )
1143+ . unwrap ( ) ;
1144+ }
1145+ pc_keyboard:: KeyState :: SingleShot => {
1146+ ev_queue
1147+ . push_back ( common:: hid:: HidEvent :: KeyPress ( convert_hid_code (
1148+ pc_keyboard_ev. code ,
1149+ ) ) )
1150+ . unwrap ( ) ;
1151+ ev_queue
1152+ . push_back ( common:: hid:: HidEvent :: KeyRelease ( convert_hid_code (
1153+ pc_keyboard_ev. code ,
1154+ ) ) )
1155+ . unwrap ( ) ;
1156+ }
1157+ }
1158+ }
1159+
1160+ fn convert_hid_code ( pc_code : pc_keyboard:: KeyCode ) -> common:: hid:: KeyCode {
1161+ match pc_code {
1162+ pc_keyboard:: KeyCode :: AltLeft => common:: hid:: KeyCode :: AltLeft ,
1163+ pc_keyboard:: KeyCode :: AltRight => common:: hid:: KeyCode :: AltRight ,
1164+ pc_keyboard:: KeyCode :: ArrowDown => common:: hid:: KeyCode :: ArrowDown ,
1165+ pc_keyboard:: KeyCode :: ArrowLeft => common:: hid:: KeyCode :: ArrowLeft ,
1166+ pc_keyboard:: KeyCode :: ArrowRight => common:: hid:: KeyCode :: ArrowRight ,
1167+ pc_keyboard:: KeyCode :: ArrowUp => common:: hid:: KeyCode :: ArrowUp ,
1168+ pc_keyboard:: KeyCode :: BackSlash => common:: hid:: KeyCode :: BackSlash ,
1169+ pc_keyboard:: KeyCode :: Backspace => common:: hid:: KeyCode :: Backspace ,
1170+ pc_keyboard:: KeyCode :: BackTick => common:: hid:: KeyCode :: BackTick ,
1171+ pc_keyboard:: KeyCode :: BracketSquareLeft => common:: hid:: KeyCode :: BracketSquareLeft ,
1172+ pc_keyboard:: KeyCode :: BracketSquareRight => common:: hid:: KeyCode :: BracketSquareRight ,
1173+ pc_keyboard:: KeyCode :: Break => common:: hid:: KeyCode :: PauseBreak ,
1174+ pc_keyboard:: KeyCode :: CapsLock => common:: hid:: KeyCode :: CapsLock ,
1175+ pc_keyboard:: KeyCode :: Comma => common:: hid:: KeyCode :: Comma ,
1176+ pc_keyboard:: KeyCode :: ControlLeft => common:: hid:: KeyCode :: ControlLeft ,
1177+ pc_keyboard:: KeyCode :: ControlRight => common:: hid:: KeyCode :: ControlRight ,
1178+ pc_keyboard:: KeyCode :: Delete => common:: hid:: KeyCode :: Delete ,
1179+ pc_keyboard:: KeyCode :: End => common:: hid:: KeyCode :: End ,
1180+ pc_keyboard:: KeyCode :: Enter => common:: hid:: KeyCode :: Enter ,
1181+ pc_keyboard:: KeyCode :: Escape => common:: hid:: KeyCode :: Escape ,
1182+ pc_keyboard:: KeyCode :: Equals => common:: hid:: KeyCode :: Equals ,
1183+ pc_keyboard:: KeyCode :: F1 => common:: hid:: KeyCode :: F1 ,
1184+ pc_keyboard:: KeyCode :: F2 => common:: hid:: KeyCode :: F2 ,
1185+ pc_keyboard:: KeyCode :: F3 => common:: hid:: KeyCode :: F3 ,
1186+ pc_keyboard:: KeyCode :: F4 => common:: hid:: KeyCode :: F4 ,
1187+ pc_keyboard:: KeyCode :: F5 => common:: hid:: KeyCode :: F5 ,
1188+ pc_keyboard:: KeyCode :: F6 => common:: hid:: KeyCode :: F6 ,
1189+ pc_keyboard:: KeyCode :: F7 => common:: hid:: KeyCode :: F7 ,
1190+ pc_keyboard:: KeyCode :: F8 => common:: hid:: KeyCode :: F8 ,
1191+ pc_keyboard:: KeyCode :: F9 => common:: hid:: KeyCode :: F9 ,
1192+ pc_keyboard:: KeyCode :: F10 => common:: hid:: KeyCode :: F10 ,
1193+ pc_keyboard:: KeyCode :: F11 => common:: hid:: KeyCode :: F11 ,
1194+ pc_keyboard:: KeyCode :: F12 => common:: hid:: KeyCode :: F12 ,
1195+ pc_keyboard:: KeyCode :: Fullstop => common:: hid:: KeyCode :: Fullstop ,
1196+ pc_keyboard:: KeyCode :: Home => common:: hid:: KeyCode :: Home ,
1197+ pc_keyboard:: KeyCode :: Insert => common:: hid:: KeyCode :: Insert ,
1198+ pc_keyboard:: KeyCode :: Key1 => common:: hid:: KeyCode :: Key1 ,
1199+ pc_keyboard:: KeyCode :: Key2 => common:: hid:: KeyCode :: Key2 ,
1200+ pc_keyboard:: KeyCode :: Key3 => common:: hid:: KeyCode :: Key3 ,
1201+ pc_keyboard:: KeyCode :: Key4 => common:: hid:: KeyCode :: Key4 ,
1202+ pc_keyboard:: KeyCode :: Key5 => common:: hid:: KeyCode :: Key5 ,
1203+ pc_keyboard:: KeyCode :: Key6 => common:: hid:: KeyCode :: Key6 ,
1204+ pc_keyboard:: KeyCode :: Key7 => common:: hid:: KeyCode :: Key7 ,
1205+ pc_keyboard:: KeyCode :: Key8 => common:: hid:: KeyCode :: Key8 ,
1206+ pc_keyboard:: KeyCode :: Key9 => common:: hid:: KeyCode :: Key9 ,
1207+ pc_keyboard:: KeyCode :: Key0 => common:: hid:: KeyCode :: Key0 ,
1208+ pc_keyboard:: KeyCode :: Menus => common:: hid:: KeyCode :: Menus ,
1209+ pc_keyboard:: KeyCode :: Minus => common:: hid:: KeyCode :: Minus ,
1210+ pc_keyboard:: KeyCode :: Numpad0 => common:: hid:: KeyCode :: Numpad0 ,
1211+ pc_keyboard:: KeyCode :: Numpad1 => common:: hid:: KeyCode :: Numpad1 ,
1212+ pc_keyboard:: KeyCode :: Numpad2 => common:: hid:: KeyCode :: Numpad2 ,
1213+ pc_keyboard:: KeyCode :: Numpad3 => common:: hid:: KeyCode :: Numpad3 ,
1214+ pc_keyboard:: KeyCode :: Numpad4 => common:: hid:: KeyCode :: Numpad4 ,
1215+ pc_keyboard:: KeyCode :: Numpad5 => common:: hid:: KeyCode :: Numpad5 ,
1216+ pc_keyboard:: KeyCode :: Numpad6 => common:: hid:: KeyCode :: Numpad6 ,
1217+ pc_keyboard:: KeyCode :: Numpad7 => common:: hid:: KeyCode :: Numpad7 ,
1218+ pc_keyboard:: KeyCode :: Numpad8 => common:: hid:: KeyCode :: Numpad8 ,
1219+ pc_keyboard:: KeyCode :: Numpad9 => common:: hid:: KeyCode :: Numpad9 ,
1220+ pc_keyboard:: KeyCode :: NumpadEnter => common:: hid:: KeyCode :: NumpadEnter ,
1221+ pc_keyboard:: KeyCode :: NumpadLock => common:: hid:: KeyCode :: NumpadLock ,
1222+ pc_keyboard:: KeyCode :: NumpadSlash => common:: hid:: KeyCode :: NumpadSlash ,
1223+ pc_keyboard:: KeyCode :: NumpadStar => common:: hid:: KeyCode :: NumpadStar ,
1224+ pc_keyboard:: KeyCode :: NumpadMinus => common:: hid:: KeyCode :: NumpadMinus ,
1225+ pc_keyboard:: KeyCode :: NumpadPeriod => common:: hid:: KeyCode :: NumpadPeriod ,
1226+ pc_keyboard:: KeyCode :: NumpadPlus => common:: hid:: KeyCode :: NumpadPlus ,
1227+ pc_keyboard:: KeyCode :: PageDown => common:: hid:: KeyCode :: PageDown ,
1228+ pc_keyboard:: KeyCode :: PageUp => common:: hid:: KeyCode :: PageUp ,
1229+ pc_keyboard:: KeyCode :: PauseBreak => common:: hid:: KeyCode :: PauseBreak ,
1230+ pc_keyboard:: KeyCode :: PrintScreen => common:: hid:: KeyCode :: PrintScreen ,
1231+ pc_keyboard:: KeyCode :: ScrollLock => common:: hid:: KeyCode :: ScrollLock ,
1232+ pc_keyboard:: KeyCode :: SemiColon => common:: hid:: KeyCode :: SemiColon ,
1233+ pc_keyboard:: KeyCode :: ShiftLeft => common:: hid:: KeyCode :: ShiftLeft ,
1234+ pc_keyboard:: KeyCode :: ShiftRight => common:: hid:: KeyCode :: ShiftRight ,
1235+ pc_keyboard:: KeyCode :: Slash => common:: hid:: KeyCode :: Slash ,
1236+ pc_keyboard:: KeyCode :: Spacebar => common:: hid:: KeyCode :: Spacebar ,
1237+ pc_keyboard:: KeyCode :: Tab => common:: hid:: KeyCode :: Tab ,
1238+ pc_keyboard:: KeyCode :: Quote => common:: hid:: KeyCode :: Quote ,
1239+ pc_keyboard:: KeyCode :: WindowsLeft => common:: hid:: KeyCode :: WindowsLeft ,
1240+ pc_keyboard:: KeyCode :: WindowsRight => common:: hid:: KeyCode :: WindowsRight ,
1241+ pc_keyboard:: KeyCode :: A => common:: hid:: KeyCode :: A ,
1242+ pc_keyboard:: KeyCode :: B => common:: hid:: KeyCode :: B ,
1243+ pc_keyboard:: KeyCode :: C => common:: hid:: KeyCode :: C ,
1244+ pc_keyboard:: KeyCode :: D => common:: hid:: KeyCode :: D ,
1245+ pc_keyboard:: KeyCode :: E => common:: hid:: KeyCode :: E ,
1246+ pc_keyboard:: KeyCode :: F => common:: hid:: KeyCode :: F ,
1247+ pc_keyboard:: KeyCode :: G => common:: hid:: KeyCode :: G ,
1248+ pc_keyboard:: KeyCode :: H => common:: hid:: KeyCode :: H ,
1249+ pc_keyboard:: KeyCode :: I => common:: hid:: KeyCode :: I ,
1250+ pc_keyboard:: KeyCode :: J => common:: hid:: KeyCode :: J ,
1251+ pc_keyboard:: KeyCode :: K => common:: hid:: KeyCode :: K ,
1252+ pc_keyboard:: KeyCode :: L => common:: hid:: KeyCode :: L ,
1253+ pc_keyboard:: KeyCode :: M => common:: hid:: KeyCode :: M ,
1254+ pc_keyboard:: KeyCode :: N => common:: hid:: KeyCode :: N ,
1255+ pc_keyboard:: KeyCode :: O => common:: hid:: KeyCode :: O ,
1256+ pc_keyboard:: KeyCode :: P => common:: hid:: KeyCode :: P ,
1257+ pc_keyboard:: KeyCode :: Q => common:: hid:: KeyCode :: Q ,
1258+ pc_keyboard:: KeyCode :: R => common:: hid:: KeyCode :: R ,
1259+ pc_keyboard:: KeyCode :: S => common:: hid:: KeyCode :: S ,
1260+ pc_keyboard:: KeyCode :: T => common:: hid:: KeyCode :: T ,
1261+ pc_keyboard:: KeyCode :: U => common:: hid:: KeyCode :: U ,
1262+ pc_keyboard:: KeyCode :: V => common:: hid:: KeyCode :: V ,
1263+ pc_keyboard:: KeyCode :: W => common:: hid:: KeyCode :: W ,
1264+ pc_keyboard:: KeyCode :: X => common:: hid:: KeyCode :: X ,
1265+ pc_keyboard:: KeyCode :: Y => common:: hid:: KeyCode :: Y ,
1266+ pc_keyboard:: KeyCode :: Z => common:: hid:: KeyCode :: Z ,
1267+ pc_keyboard:: KeyCode :: HashTilde => common:: hid:: KeyCode :: HashTilde ,
1268+ pc_keyboard:: KeyCode :: PrevTrack => common:: hid:: KeyCode :: PrevTrack ,
1269+ pc_keyboard:: KeyCode :: NextTrack => common:: hid:: KeyCode :: NextTrack ,
1270+ pc_keyboard:: KeyCode :: Mute => common:: hid:: KeyCode :: Mute ,
1271+ pc_keyboard:: KeyCode :: Calculator => common:: hid:: KeyCode :: Calculator ,
1272+ pc_keyboard:: KeyCode :: Play => common:: hid:: KeyCode :: Play ,
1273+ pc_keyboard:: KeyCode :: Stop => common:: hid:: KeyCode :: Stop ,
1274+ pc_keyboard:: KeyCode :: VolumeDown => common:: hid:: KeyCode :: VolumeDown ,
1275+ pc_keyboard:: KeyCode :: VolumeUp => common:: hid:: KeyCode :: VolumeUp ,
1276+ pc_keyboard:: KeyCode :: WWWHome => common:: hid:: KeyCode :: WWWHome ,
1277+ pc_keyboard:: KeyCode :: PowerOnTestOk => common:: hid:: KeyCode :: PowerOnTestOk ,
1278+ _ => common:: hid:: KeyCode :: X ,
1279+ }
10521280}
10531281
10541282/// Control the keyboard LEDs.
@@ -1292,7 +1520,8 @@ extern "C" fn block_dev_eject(dev_id: u8) -> common::Result<()> {
12921520
12931521/// Sleep the CPU until the next interrupt.
12941522extern "C" fn power_idle ( ) {
1295- cortex_m:: asm:: wfe ( ) ;
1523+ // cortex_m::asm::wfe();
1524+ cortex_m:: asm:: delay ( 10_000_000 ) ;
12961525}
12971526
12981527/// TODO: Get the monotonic run-time of the system from SysTick.
0 commit comments