1 use alloc::sync::Arc; 2 3 use crate::driver::tty::tty_device::TtyDevice; 4 5 #[allow(dead_code)] 6 pub const NUM_SCAN_CODES: u8 = 0x80; 7 #[allow(dead_code)] 8 pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2; 9 10 #[allow(dead_code)] 11 pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下 12 13 /// 标志状态 14 #[repr(u8)] 15 #[derive(Debug, PartialEq, Eq)] 16 #[allow(dead_code)] 17 pub enum KeyFlag { 18 NoneFlag = 0 as u8, 19 PauseBreak = 1 as u8, 20 PrintScreenPress = 2 as u8, 21 PrintScreenRelease = 4 as u8, 22 OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键) 23 } 24 25 /// @brief A FSM to parse type one keyboard scan code 26 #[derive(Debug)] 27 #[allow(dead_code)] 28 pub struct TypeOneFSM { 29 status: ScanCodeStatus, 30 current_state: TypeOneFSMState, 31 tty: Arc<TtyDevice>, 32 } 33 34 impl TypeOneFSM { 35 #[allow(dead_code)] 36 pub fn new(tty: Arc<TtyDevice>) -> Self { 37 Self { 38 status: ScanCodeStatus::new(), 39 current_state: TypeOneFSMState::Start, 40 tty, 41 } 42 } 43 44 /// @brief 解析扫描码 45 #[allow(dead_code)] 46 pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState { 47 self.current_state = self 48 .current_state 49 .parse(scancode, &mut self.status, &self.tty); 50 self.current_state 51 } 52 } 53 54 /// @brief 第一类扫描码状态机的状态 55 #[derive(Debug, Copy, Clone)] 56 pub enum TypeOneFSMState { 57 /// 起始状态 58 Start, 59 /// PauseBreak 第n个扫描码 60 PauseBreak(u8), 61 /// 多扫描码功能键起始状态 62 Func0, 63 /// 第三类扫描码或字符 64 Type3, 65 66 PrtscPress(u8), 67 PrtscRelease(u8), 68 } 69 70 impl TypeOneFSMState { 71 /// @brief 状态机总控程序 72 fn parse( 73 &self, 74 scancode: u8, 75 scancode_status: &mut ScanCodeStatus, 76 tty: &Arc<TtyDevice>, 77 ) -> TypeOneFSMState { 78 // kdebug!("the code is {:#x}\n", scancode); 79 match self { 80 TypeOneFSMState::Start => { 81 return self.handle_start(scancode, scancode_status, tty); 82 } 83 TypeOneFSMState::PauseBreak(n) => { 84 return self.handle_pause_break(*n, scancode_status, tty); 85 } 86 TypeOneFSMState::Func0 => { 87 return self.handle_func0(scancode, scancode_status, tty); 88 } 89 TypeOneFSMState::Type3 => { 90 return self.handle_type3(scancode, scancode_status, tty); 91 } 92 TypeOneFSMState::PrtscPress(n) => { 93 return self.handle_prtsc_press(*n, scancode_status, tty) 94 } 95 TypeOneFSMState::PrtscRelease(n) => { 96 return self.handle_prtsc_release(*n, scancode_status, tty) 97 } 98 } 99 } 100 101 /// @brief 处理起始状态 102 fn handle_start( 103 &self, 104 scancode: u8, 105 scancode_status: &mut ScanCodeStatus, 106 tty: &Arc<TtyDevice>, 107 ) -> TypeOneFSMState { 108 //kdebug!("in handle_start the code is {:#x}\n",scancode); 109 match scancode { 110 0xe1 => { 111 return TypeOneFSMState::PauseBreak(1); 112 } 113 0xe0 => { 114 return TypeOneFSMState::Func0; 115 } 116 _ => { 117 //kdebug!("in _d the code is {:#x}\n",scancode); 118 return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status, tty); 119 } 120 } 121 } 122 123 /// @brief 处理PauseBreak状态 124 fn handle_pause_break( 125 &self, 126 scancode: u8, 127 scancode_status: &mut ScanCodeStatus, 128 tty: &Arc<TtyDevice>, 129 ) -> TypeOneFSMState { 130 static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5]; 131 let i = match self { 132 TypeOneFSMState::PauseBreak(i) => *i, 133 _ => { 134 return self.handle_type3(scancode, scancode_status, tty); 135 } 136 }; 137 if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] { 138 return self.handle_type3(scancode, scancode_status, tty); 139 } else { 140 if i == 5 { 141 // 所有Pause Break扫描码都被清除 142 return TypeOneFSMState::Start; 143 } else { 144 return TypeOneFSMState::PauseBreak(i + 1); 145 } 146 } 147 } 148 149 fn handle_func0( 150 &self, 151 scancode: u8, 152 scancode_status: &mut ScanCodeStatus, 153 tty: &Arc<TtyDevice>, 154 ) -> TypeOneFSMState { 155 //0xE0 156 match scancode { 157 0x2a => { 158 return TypeOneFSMState::PrtscPress(2); 159 } 160 0xb7 => { 161 return TypeOneFSMState::PrtscRelease(2); 162 } 163 0x1d => { 164 // 按下右边的ctrl 165 scancode_status.ctrl_r = true; 166 } 167 0x9d => { 168 // 松开右边的ctrl 169 scancode_status.ctrl_r = false; 170 } 171 0x38 => { 172 // 按下右边的alt 173 scancode_status.alt_r = true; 174 } 175 0xb8 => { 176 // 松开右边的alt 177 scancode_status.alt_r = false; 178 } 179 0x5b => { 180 scancode_status.gui_l = true; 181 } 182 0xdb => { 183 scancode_status.gui_l = false; 184 } 185 0x5c => { 186 scancode_status.gui_r = true; 187 } 188 0xdc => { 189 scancode_status.gui_r = false; 190 } 191 0x5d => { 192 scancode_status.apps = true; 193 } 194 0xdd => { 195 scancode_status.apps = false; 196 } 197 0x52 => { 198 scancode_status.insert = true; 199 } 200 0xd2 => { 201 scancode_status.insert = false; 202 } 203 0x47 => { 204 scancode_status.home = true; 205 } 206 0xc7 => { 207 scancode_status.home = false; 208 } 209 0x49 => { 210 scancode_status.pgup = true; 211 } 212 0xc9 => { 213 scancode_status.pgup = false; 214 } 215 0x53 => { 216 scancode_status.del = true; 217 Self::emit(tty, 127); 218 } 219 0xd3 => { 220 scancode_status.del = false; 221 } 222 0x4f => { 223 scancode_status.end = true; 224 } 225 0xcf => { 226 scancode_status.end = false; 227 } 228 0x51 => { 229 scancode_status.pgdn = true; 230 } 231 0xd1 => { 232 scancode_status.pgdn = false; 233 } 234 0x48 => { 235 scancode_status.arrow_u = true; 236 Self::emit(tty, 224); 237 Self::emit(tty, 72); 238 } 239 0xc8 => { 240 scancode_status.arrow_u = false; 241 } 242 0x4b => { 243 scancode_status.arrow_l = true; 244 Self::emit(tty, 224); 245 Self::emit(tty, 75); 246 } 247 0xcb => { 248 scancode_status.arrow_l = false; 249 } 250 0x50 => { 251 scancode_status.arrow_d = true; 252 Self::emit(tty, 224); 253 Self::emit(tty, 80); 254 } 255 0xd0 => { 256 scancode_status.arrow_d = false; 257 } 258 0x4d => { 259 scancode_status.arrow_r = true; 260 Self::emit(tty, 224); 261 Self::emit(tty, 77); 262 } 263 0xcd => { 264 scancode_status.arrow_r = false; 265 } 266 267 0x35 => { 268 // 数字小键盘的 / 符号 269 scancode_status.kp_forward_slash = true; 270 271 let ch = '/' as u8; 272 Self::emit(tty, ch); 273 } 274 0xb5 => { 275 scancode_status.kp_forward_slash = false; 276 } 277 0x1c => { 278 scancode_status.kp_enter = true; 279 Self::emit(tty, '\n' as u8); 280 } 281 0x9c => { 282 scancode_status.kp_enter = false; 283 } 284 _ => { 285 return TypeOneFSMState::Start; 286 } 287 } 288 return TypeOneFSMState::Start; 289 } 290 291 fn handle_type3( 292 &self, 293 scancode: u8, 294 scancode_status: &mut ScanCodeStatus, 295 tty: &Arc<TtyDevice>, 296 ) -> TypeOneFSMState { 297 // 判断按键是被按下还是抬起 298 let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 { 299 false //up 300 } else { 301 true //down 302 }; 303 304 // 计算扫描码位于码表的第几行 305 let mut col: bool = false; 306 let index = scancode & 0x7f; 307 308 //kdebug!("in type3 ch is {:#x}\n",ch); 309 let mut key = KeyFlag::OtherKey; // 可视字符 310 311 match index { 312 0x2a => { 313 scancode_status.shift_l = flag_make; 314 key = KeyFlag::NoneFlag; 315 } 316 0x36 => { 317 scancode_status.shift_r = flag_make; 318 key = KeyFlag::NoneFlag; 319 } 320 0x1d => { 321 scancode_status.ctrl_l = flag_make; 322 key = KeyFlag::NoneFlag; 323 } 324 0x38 => { 325 scancode_status.alt_r = flag_make; 326 key = KeyFlag::NoneFlag; 327 } 328 0x3A => { 329 if scancode_status.caps_lock { 330 scancode_status.caps_lock = !flag_make; 331 } 332 //if caps_lock: true, flag_make: true => cap_lock: false 333 else { 334 scancode_status.caps_lock = flag_make; 335 } //else false => cap_lock: true 336 key = KeyFlag::NoneFlag; 337 } 338 _ => { 339 if flag_make == false { 340 //kdebug!("in type3 ch is {:#x}\n",ch); 341 key = KeyFlag::NoneFlag; 342 } 343 } 344 } 345 346 // shift被按下 347 if scancode_status.shift_l || scancode_status.shift_r { 348 col = true; 349 } 350 351 if scancode_status.caps_lock { 352 if index >= 0x10 && index <= 0x19 { 353 col = !col; 354 } else if index >= 0x1e && index <= 0x26 { 355 col = !col; 356 } else if index >= 0x2c && index <= 0x32 { 357 col = !col; 358 } 359 } 360 361 let ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize]; 362 363 if key != KeyFlag::NoneFlag { 364 Self::emit(tty, ch); 365 } 366 return TypeOneFSMState::Start; 367 } 368 369 #[inline(always)] 370 fn emit(tty: &Arc<TtyDevice>, ch: u8) { 371 // 发送到tty 372 tty.input(&[ch]).ok(); 373 } 374 375 /// @brief 处理Prtsc按下事件 376 fn handle_prtsc_press( 377 &self, 378 scancode: u8, 379 scancode_status: &mut ScanCodeStatus, 380 tty: &Arc<TtyDevice>, 381 ) -> TypeOneFSMState { 382 static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37]; 383 let i = match self { 384 TypeOneFSMState::PrtscPress(i) => *i, 385 _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态 386 }; 387 if i > 3 { 388 // 解析错误,返回起始状态 389 return TypeOneFSMState::Start; 390 } 391 if scancode != PRTSC_SCAN_CODE[i as usize] { 392 return self.handle_type3(scancode, scancode_status, tty); 393 } else { 394 if i == 3 { 395 // 成功解析出PrtscPress 396 return TypeOneFSMState::Start; 397 } else { 398 // 继续解析 399 return TypeOneFSMState::PrtscPress(i + 1); 400 } 401 } 402 } 403 404 fn handle_prtsc_release( 405 &self, 406 scancode: u8, 407 scancode_status: &mut ScanCodeStatus, 408 tty: &Arc<TtyDevice>, 409 ) -> TypeOneFSMState { 410 static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa]; 411 let i = match self { 412 TypeOneFSMState::PrtscRelease(i) => *i, 413 _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态 414 }; 415 if i > 3 { 416 // 解析错误,返回起始状态 417 return TypeOneFSMState::Start; 418 } 419 if scancode != PRTSC_SCAN_CODE[i as usize] { 420 return self.handle_type3(scancode, scancode_status, tty); 421 } else { 422 if i == 3 { 423 // 成功解析出PrtscRelease 424 return TypeOneFSMState::Start; 425 } else { 426 // 继续解析 427 return TypeOneFSMState::PrtscRelease(i + 1); 428 } 429 } 430 } 431 } 432 433 /// 按键状态 434 #[derive(Debug)] 435 #[allow(dead_code)] 436 pub struct ScanCodeStatus { 437 // Shift 按键 438 shift_l: bool, 439 shift_r: bool, 440 // Ctrl 按键 441 ctrl_l: bool, 442 ctrl_r: bool, 443 // Alt 按键 444 alt_l: bool, 445 alt_r: bool, 446 // 447 gui_l: bool, 448 gui_r: bool, 449 // 450 apps: bool, 451 insert: bool, 452 // page up/down 453 pgup: bool, 454 pgdn: bool, 455 del: bool, 456 home: bool, 457 end: bool, 458 arrow_u: bool, 459 arrow_l: bool, 460 arrow_d: bool, 461 arrow_r: bool, 462 // 斜杠 463 kp_forward_slash: bool, 464 // 回车 465 kp_enter: bool, 466 caps_lock: bool, 467 } 468 469 impl ScanCodeStatus { 470 fn new() -> Self { 471 ScanCodeStatus { 472 shift_l: false, 473 shift_r: false, 474 ctrl_l: false, 475 ctrl_r: false, 476 alt_l: false, 477 alt_r: false, 478 gui_l: false, 479 gui_r: false, 480 apps: false, 481 insert: false, 482 pgup: false, 483 pgdn: false, 484 del: false, 485 home: false, 486 end: false, 487 arrow_u: false, 488 arrow_l: false, 489 arrow_d: false, 490 arrow_r: false, 491 kp_forward_slash: false, 492 kp_enter: false, 493 caps_lock: false, 494 } 495 } 496 } 497 498 const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [ 499 /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC 500 /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8, 501 /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8, 502 /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' as u8, '^' as u8, 503 /*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8, 504 /*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8, 505 /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8, 506 /*0x0e \b */ 8 as u8, 8 as u8, // BACKSPACE 507 /*0x0f*/ '\t' as u8, '\t' as u8, // TAB 508 ////////////////////////character/////////////////////////// 509 /*0x10*/ 'q' as u8, 510 'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8, /*0x12*/ 'e' as u8, 'E' as u8, 511 /*0x13*/ 'r' as u8, 'R' as u8, /*0x14*/ 't' as u8, 'T' as u8, 512 /*0x15*/ 'y' as u8, 'Y' as u8, /*0x16*/ 'u' as u8, 'U' as u8, 513 /*0x17*/ 'i' as u8, 'I' as u8, /*0x18*/ 'o' as u8, 'O' as u8, 514 /*0x19*/ 'p' as u8, 'P' as u8, 515 ////////////////////////character/////////////////////////// 516 517 /*0x1a*/ '[' as u8, 518 '{' as u8, /*0x1b*/ ']' as u8, '}' as u8, /*0x1c*/ '\n' as u8, 519 '\n' as u8, // ENTER 520 /*0x1d*/ 0x1d, 0x1d, // CTRL Left 521 ////////////////////////character/////////////////////////// 522 /*0x1e*/ 'a' as u8, 523 'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8, /*0x20*/ 'd' as u8, 'D' as u8, 524 /*0x21*/ 'f' as u8, 'F' as u8, /*0x22*/ 'g' as u8, 'G' as u8, 525 /*0x23*/ 'h' as u8, 'H' as u8, /*0x24*/ 'j' as u8, 'J' as u8, 526 /*0x25*/ 'k' as u8, 'K' as u8, /*0x26*/ 'l' as u8, 'L' as u8, 527 ////////////////////////character/////////////////////////// 528 529 /*0x27*/ ';' as u8, 530 ':' as u8, /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8, 531 /*0x2a*/ 0x2a, 0x2a, // SHIFT Left 532 /*0x2b*/ '\\' as u8, '|' as u8, 533 ////////////////////////character/////////////////////////// 534 /*0x2c*/ 'z' as u8, 535 'Z' as u8, /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8, 536 /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8, 537 /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8, 538 ////////////////////////character/////////////////////////// 539 540 /*0x33*/ ',' as u8, 541 '<' as u8, /*0x34*/ '.' as u8, '>' as u8, /*0x35*/ '/' as u8, '?' as u8, 542 /*0x36*/ 0x36, 0x36, // SHIFT Right 543 /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left 544 /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK 545 /*0x3b*/ 0, 0, // F1 546 /*0x3c*/ 0, 0, // F2 547 /*0x3d*/ 0, 0, // F3 548 /*0x3e*/ 0, 0, // F4 549 /*0x3f*/ 0, 0, // F5 550 /*0x40*/ 0, 0, // F6 551 /*0x41*/ 0, 0, // F7 552 /*0x42*/ 0, 0, // F8 553 /*0x43*/ 0, 0, // F9 554 /*0x44*/ 0, 0, // F10 555 /*0x45*/ 0, 0, // NUM LOCK 556 /*0x46*/ 0, 0, // SCROLL LOCK 557 /*0x47*/ '7' as u8, 0, /*PAD HONE*/ 558 /*0x48*/ '8' as u8, 0, /*PAD UP*/ 559 /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/ 560 /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/ 561 /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/ 562 /*0x4c*/ '5' as u8, 0, /*PAD MID*/ 563 /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/ 564 /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/ 565 /*0x4f*/ '1' as u8, 0, /*PAD END*/ 566 /*0x50*/ '2' as u8, 0, /*PAD DOWN*/ 567 /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/ 568 /*0x52*/ '0' as u8, 0, /*PAD INS*/ 569 /*0x53*/ '.' as u8, 0, /*PAD DOT*/ 570 /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11 571 /*0x58*/ 0, 0, // F12 572 /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0, 573 /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0, 574 /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0, 575 /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0, 576 /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0, 577 /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0, 578 /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0, 579 /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0, 580 /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0, 581 /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0, 582 ]; 583