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