ps2_keyboard.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #pragma once
  2. #include "../../common/glib.h"
  3. #define PS2_KEYBOARD_INTR_VECTOR 0x21 // 键盘的中断向量号
  4. // 定义键盘循环队列缓冲区大小为100bytes
  5. #define ps2_keyboard_buffer_size 100
  6. /**
  7. * @brief 键盘循环队列缓冲区结构体
  8. *
  9. */
  10. struct ps2_keyboard_input_buffer
  11. {
  12. unsigned char *ptr_head;
  13. unsigned char *ptr_tail;
  14. int count;
  15. unsigned char buffer[ps2_keyboard_buffer_size];
  16. };
  17. #define PORT_PS2_KEYBOARD_DATA 0x60
  18. #define PORT_PS2_KEYBOARD_STATUS 0x64
  19. #define PORT_PS2_KEYBOARD_CONTROL 0x64
  20. #define PS2_KEYBOARD_COMMAND_WRITE 0x60 // 向键盘发送配置命令
  21. #define PS2_KEYBOARD_COMMAND_READ 0x20 // 读取键盘的配置值
  22. #define PS2_KEYBOARD_PARAM_INIT 0x47 // 初始化键盘控制器的配置值
  23. // ========= 检测键盘控制器输入/输出缓冲区是否已满
  24. #define PS2_KEYBOARD_FLAG_OUTBUF_FULL 0x01 // 键盘的输出缓冲区已满标志位
  25. #define PS2_KEYBOARD_FLAG_INBUF_FULL 0x02 // 键盘的输入缓冲区已满标志位
  26. // 等待向键盘控制器写入信息完成
  27. #define wait_ps2_keyboard_write() while (io_in8(PORT_PS2_KEYBOARD_STATUS) & PS2_KEYBOARD_FLAG_INBUF_FULL)
  28. // 等待从键盘控制器读取信息完成
  29. #define wait_ps2_keyboard_read() while (io_in8(PORT_PS2_KEYBOARD_STATUS) & PS2_KEYBOARD_FLAG_OUTBUF_FULL)
  30. // 128个按键, 每个按键包含普通按键和shift+普通按键两种状态
  31. #define NUM_SCAN_CODES 0x80
  32. #define MAP_COLS 2
  33. #define PAUSE_BREAK 1
  34. #define PRINT_SCREEN 2
  35. #define OTHER_KEY 4 // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
  36. #define FLAG_BREAK 0X80
  37. // 键盘扫描码有三种:
  38. // 0xE1开头的PauseBreak键
  39. // 0xE0开头的功能键
  40. // 1byte的普通按键
  41. // pause break键的扫描码,没错,它就是这么长
  42. unsigned char pause_break_scan_code[] = {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5};
  43. // 第一套键盘扫描码 及其对应的字符
  44. uint keycode_map_normal[NUM_SCAN_CODES*MAP_COLS] =
  45. {
  46. /*scan-code unShift Shift */
  47. /*--------------------------------------------------------------*/
  48. /*0x00*/ 0, 0,
  49. /*0x01*/ 0, 0, //ESC
  50. /*0x02*/ '1', '!',
  51. /*0x03*/ '2', '@',
  52. /*0x04*/ '3', '#',
  53. /*0x05*/ '4', '$',
  54. /*0x06*/ '5', '%',
  55. /*0x07*/ '6', '^',
  56. /*0x08*/ '7', '&',
  57. /*0x09*/ '8', '*',
  58. /*0x0a*/ '9', '(',
  59. /*0x0b*/ '0', ')',
  60. /*0x0c*/ '-', '_',
  61. /*0x0d*/ '=', '+',
  62. /*0x0e*/ '\b', '\b', //BACKSPACE
  63. /*0x0f*/ '\t', '\t', //TAB
  64. /*0x10*/ 'q', 'Q',
  65. /*0x11*/ 'w', 'W',
  66. /*0x12*/ 'e', 'E',
  67. /*0x13*/ 'r', 'R',
  68. /*0x14*/ 't', 'T',
  69. /*0x15*/ 'y', 'Y',
  70. /*0x16*/ 'u', 'U',
  71. /*0x17*/ 'i', 'I',
  72. /*0x18*/ 'o', 'O',
  73. /*0x19*/ 'p', 'P',
  74. /*0x1a*/ '[', '{',
  75. /*0x1b*/ ']', '}',
  76. /*0x1c*/ '\n', '\n', //ENTER
  77. /*0x1d*/ 0x1d, 0x1d, //CTRL Left
  78. /*0x1e*/ 'a', 'A',
  79. /*0x1f*/ 's', 'S',
  80. /*0x20*/ 'd', 'D',
  81. /*0x21*/ 'f', 'F',
  82. /*0x22*/ 'g', 'G',
  83. /*0x23*/ 'h', 'H',
  84. /*0x24*/ 'j', 'J',
  85. /*0x25*/ 'k', 'K',
  86. /*0x26*/ 'l', 'L',
  87. /*0x27*/ ';', ':',
  88. /*0x28*/ '\'', '"',
  89. /*0x29*/ '`', '~',
  90. /*0x2a*/ 0x2a, 0x2a, //SHIFT Left
  91. /*0x2b*/ '\\', '|',
  92. /*0x2c*/ 'z', 'Z',
  93. /*0x2d*/ 'x', 'X',
  94. /*0x2e*/ 'c', 'C',
  95. /*0x2f*/ 'v', 'V',
  96. /*0x30*/ 'b', 'B',
  97. /*0x31*/ 'n', 'N',
  98. /*0x32*/ 'm', 'M',
  99. /*0x33*/ ',', '<',
  100. /*0x34*/ '.', '>',
  101. /*0x35*/ '/', '?',
  102. /*0x36*/ 0x36, 0x36, //SHIFT Right
  103. /*0x37*/ '*', '*',
  104. /*0x38*/ 0x38, 0x38, //ALT Left
  105. /*0x39*/ ' ', ' ',
  106. /*0x3a*/ 0, 0, //CAPS LOCK
  107. /*0x3b*/ 0, 0, //F1
  108. /*0x3c*/ 0, 0, //F2
  109. /*0x3d*/ 0, 0, //F3
  110. /*0x3e*/ 0, 0, //F4
  111. /*0x3f*/ 0, 0, //F5
  112. /*0x40*/ 0, 0, //F6
  113. /*0x41*/ 0, 0, //F7
  114. /*0x42*/ 0, 0, //F8
  115. /*0x43*/ 0, 0, //F9
  116. /*0x44*/ 0, 0, //F10
  117. /*0x45*/ 0, 0, //NUM LOCK
  118. /*0x46*/ 0, 0, //SCROLL LOCK
  119. /*0x47*/ '7', 0, /*PAD HONE*/
  120. /*0x48*/ '8', 0, /*PAD UP*/
  121. /*0x49*/ '9', 0, /*PAD PAGEUP*/
  122. /*0x4a*/ '-', 0, /*PAD MINUS*/
  123. /*0x4b*/ '4', 0, /*PAD LEFT*/
  124. /*0x4c*/ '5', 0, /*PAD MID*/
  125. /*0x4d*/ '6', 0, /*PAD RIGHT*/
  126. /*0x4e*/ '+', 0, /*PAD PLUS*/
  127. /*0x4f*/ '1', 0, /*PAD END*/
  128. /*0x50*/ '2', 0, /*PAD DOWN*/
  129. /*0x51*/ '3', 0, /*PAD PAGEDOWN*/
  130. /*0x52*/ '0', 0, /*PAD INS*/
  131. /*0x53*/ '.', 0, /*PAD DOT*/
  132. /*0x54*/ 0, 0,
  133. /*0x55*/ 0, 0,
  134. /*0x56*/ 0, 0,
  135. /*0x57*/ 0, 0, //F11
  136. /*0x58*/ 0, 0, //F12
  137. /*0x59*/ 0, 0,
  138. /*0x5a*/ 0, 0,
  139. /*0x5b*/ 0, 0,
  140. /*0x5c*/ 0, 0,
  141. /*0x5d*/ 0, 0,
  142. /*0x5e*/ 0, 0,
  143. /*0x5f*/ 0, 0,
  144. /*0x60*/ 0, 0,
  145. /*0x61*/ 0, 0,
  146. /*0x62*/ 0, 0,
  147. /*0x63*/ 0, 0,
  148. /*0x64*/ 0, 0,
  149. /*0x65*/ 0, 0,
  150. /*0x66*/ 0, 0,
  151. /*0x67*/ 0, 0,
  152. /*0x68*/ 0, 0,
  153. /*0x69*/ 0, 0,
  154. /*0x6a*/ 0, 0,
  155. /*0x6b*/ 0, 0,
  156. /*0x6c*/ 0, 0,
  157. /*0x6d*/ 0, 0,
  158. /*0x6e*/ 0, 0,
  159. /*0x6f*/ 0, 0,
  160. /*0x70*/ 0, 0,
  161. /*0x71*/ 0, 0,
  162. /*0x72*/ 0, 0,
  163. /*0x73*/ 0, 0,
  164. /*0x74*/ 0, 0,
  165. /*0x75*/ 0, 0,
  166. /*0x76*/ 0, 0,
  167. /*0x77*/ 0, 0,
  168. /*0x78*/ 0, 0,
  169. /*0x79*/ 0, 0,
  170. /*0x7a*/ 0, 0,
  171. /*0x7b*/ 0, 0,
  172. /*0x7c*/ 0, 0,
  173. /*0x7d*/ 0, 0,
  174. /*0x7e*/ 0, 0,
  175. /*0x7f*/ 0, 0,
  176. };
  177. /**
  178. * @brief 初始化键盘驱动程序的函数
  179. *
  180. */
  181. void ps2_keyboard_init();
  182. /**
  183. * @brief 键盘驱动卸载函数
  184. *
  185. */
  186. void ps2_keyboard_exit();
  187. /**
  188. * @brief 解析键盘扫描码
  189. *
  190. */
  191. void ps2_keyboard_analyze_keycode();
  192. /**
  193. * @brief 从缓冲队列中获取键盘扫描码
  194. * @return 键盘扫描码
  195. * 若缓冲队列为空则返回-1
  196. */
  197. int ps2_keyboard_get_scancode();