mouse.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #include "mouse.h"
  2. #include "../interrupt/apic/apic.h"
  3. #include "../../mm/mm.h"
  4. #include "../../mm/slab.h"
  5. #include "../../common/printk.h"
  6. #include "../../common/kprint.h"
  7. static struct mouse_input_buffer *mouse_buf_ptr = NULL;
  8. static int c = 0;
  9. struct apic_IO_APIC_RTE_entry entry;
  10. static unsigned char mouse_id = 0;
  11. /**
  12. * @brief 清空缓冲区
  13. *
  14. */
  15. static void mouse_clear_buf()
  16. {
  17. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  18. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  19. mouse_buf_ptr->count = 0;
  20. memset(mouse_buf_ptr->buffer, 0, mouse_buffer_size);
  21. }
  22. /**
  23. * @brief 从缓冲队列中获取鼠标数据字节
  24. * @return 鼠标数据包的字节
  25. * 若缓冲队列为空则返回-1024
  26. */
  27. static int mouse_get_scancode()
  28. {
  29. // 缓冲队列为空
  30. if (mouse_buf_ptr->count == 0)
  31. while (!mouse_buf_ptr->count)
  32. nop();
  33. if (mouse_buf_ptr->ptr_tail == mouse_buf_ptr->buffer + mouse_buffer_size)
  34. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  35. int ret = (int)((char)(*(mouse_buf_ptr->ptr_tail)));
  36. --(mouse_buf_ptr->count);
  37. ++(mouse_buf_ptr->ptr_tail);
  38. // printk("count=%d", mouse_buf_ptr->count);
  39. return ret;
  40. }
  41. /**
  42. * @brief 鼠标中断处理函数(中断上半部)
  43. * 将数据存入缓冲区
  44. * @param irq_num 中断向量号
  45. * @param param 参数
  46. * @param regs 寄存器信息
  47. */
  48. void mouse_handler(ul irq_num, ul param, struct pt_regs *regs)
  49. {
  50. // 读取鼠标输入的信息
  51. unsigned char x = io_in8(PORT_KEYBOARD_DATA);
  52. // 当头指针越过界时,恢复指向数组头部
  53. if (mouse_buf_ptr->ptr_head == mouse_buf_ptr->buffer + mouse_buffer_size)
  54. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  55. if (mouse_buf_ptr->count >= mouse_buffer_size)
  56. {
  57. // kwarn("mouse input buffer is full.");
  58. // return;
  59. }
  60. *mouse_buf_ptr->ptr_head = x;
  61. ++(mouse_buf_ptr->count);
  62. ++(mouse_buf_ptr->ptr_head);
  63. printk("c=%d\n", ++c);
  64. }
  65. hardware_intr_controller mouse_intr_controller =
  66. {
  67. .enable = apic_ioapic_enable,
  68. .disable = apic_ioapic_disable,
  69. .install = apic_ioapic_install,
  70. .uninstall = apic_ioapic_uninstall,
  71. .ack = apic_ioapic_edge_ack,
  72. };
  73. /**
  74. * @brief 从键盘控制器读取mouse id
  75. *
  76. * @return unsigned char 鼠标id
  77. */
  78. static unsigned char mouse_get_mouse_ID()
  79. {
  80. // 读取鼠标的ID
  81. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  82. wait_keyboard_write();
  83. io_out8(PORT_KEYBOARD_DATA, MOUSE_GET_ID);
  84. wait_keyboard_write();
  85. mouse_id = io_in8(PORT_KEYBOARD_DATA);
  86. return mouse_id;
  87. }
  88. /**
  89. * @brief 设置鼠标采样率
  90. *
  91. * @param hz 采样率
  92. */
  93. int mouse_set_sample_rate(unsigned int hz)
  94. {
  95. switch (hz)
  96. {
  97. case 10:
  98. case 20:
  99. case 40:
  100. case 60:
  101. case 80:
  102. case 100:
  103. case 200:
  104. wait_keyboard_write();
  105. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  106. wait_keyboard_write();
  107. io_out8(PORT_KEYBOARD_DATA, MOUSE_SET_SAMPLING_RATE);
  108. wait_keyboard_write();
  109. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  110. wait_keyboard_write();
  111. io_out8(PORT_KEYBOARD_DATA, hz);
  112. wait_keyboard_write();
  113. break;
  114. default:
  115. return EINVALID_ARGUMENT;
  116. break;
  117. }
  118. return SUCCESS;
  119. }
  120. /**
  121. * @brief 使鼠标支持滚轮
  122. * 该模式下,鼠标ID=3
  123. */
  124. static int mouse_enable_scroll_wheel()
  125. {
  126. if (mouse_id == 3)
  127. return SUCCESS;
  128. mouse_set_sample_rate(200);
  129. mouse_set_sample_rate(100);
  130. mouse_set_sample_rate(80);
  131. if (mouse_get_mouse_ID() != 3)
  132. {
  133. kerror("Cannot set mouse ID to 3");
  134. return EFAIL;
  135. }
  136. // 清空缓冲区,防止解析时产生错误
  137. mouse_clear_buf();
  138. return SUCCESS;
  139. }
  140. /**
  141. * @brief 使鼠标支持5键
  142. * 该模式下ID=4
  143. */
  144. static int mouse_enable_5keys()
  145. {
  146. if (mouse_id == 4)
  147. return SUCCESS;
  148. // 根据规范,应当先启用ID=3
  149. mouse_enable_scroll_wheel();
  150. mouse_set_sample_rate(200);
  151. mouse_set_sample_rate(200);
  152. mouse_set_sample_rate(80);
  153. if (mouse_get_mouse_ID() != 4)
  154. {
  155. kerror("Cannot set mouse ID to 4");
  156. return EFAIL;
  157. }
  158. // 清空缓冲区,防止解析时产生错误
  159. mouse_clear_buf();
  160. return SUCCESS;
  161. }
  162. /**
  163. * @brief 初始化鼠标驱动程序
  164. *
  165. */
  166. void mouse_init()
  167. {
  168. // 初始化鼠标读入队列缓冲区
  169. mouse_buf_ptr = (struct mouse_input_buffer *)kmalloc(sizeof(struct mouse_input_buffer), 0);
  170. mouse_buf_ptr->ptr_head = mouse_buf_ptr->buffer;
  171. mouse_buf_ptr->ptr_tail = mouse_buf_ptr->buffer;
  172. mouse_buf_ptr->count = 0;
  173. memset(mouse_buf_ptr->buffer, 0, mouse_buffer_size);
  174. // ======== 初始化中断RTE entry ==========
  175. entry.vector = MOUSE_INTR_VECTOR; // 设置中断向量号
  176. entry.deliver_mode = IO_APIC_FIXED; // 投递模式:混合
  177. entry.dest_mode = DEST_PHYSICAL; // 物理模式投递中断
  178. entry.deliver_status = IDLE;
  179. entry.trigger_mode = EDGE_TRIGGER; // 设置边沿触发
  180. entry.polarity = POLARITY_HIGH; // 高电平触发
  181. entry.remote_IRR = IRR_RESET;
  182. entry.mask = MASKED;
  183. entry.reserved = 0;
  184. entry.destination.physical.reserved1 = 0;
  185. entry.destination.physical.reserved2 = 0;
  186. entry.destination.physical.phy_dest = 0; // 设置投递到BSP处理器
  187. // 注册中断处理程序
  188. irq_register(MOUSE_INTR_VECTOR, &entry, &mouse_handler, (ul)mouse_buf_ptr, &mouse_intr_controller, "ps/2 mouse");
  189. wait_keyboard_write();
  190. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_ENABLE_MOUSE_PORT); // 开启鼠标端口
  191. wait_keyboard_write();
  192. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_SEND_TO_MOUSE);
  193. wait_keyboard_write();
  194. io_out8(PORT_KEYBOARD_DATA, MOUSE_ENABLE); // 允许鼠标设备发送数据包
  195. wait_keyboard_write();
  196. io_out8(PORT_KEYBOARD_CONTROL, KEYBOARD_COMMAND_WRITE);
  197. wait_keyboard_write();
  198. io_out8(PORT_KEYBOARD_DATA, KEYBOARD_PARAM_INIT); // 设置键盘控制器
  199. wait_keyboard_write();
  200. //mouse_enable_5keys();
  201. mouse_get_mouse_ID();
  202. kdebug("mouse ID:%d", mouse_id);
  203. c = 0;
  204. }
  205. /**
  206. * @brief 卸载鼠标驱动程序
  207. *
  208. */
  209. void mouse_exit()
  210. {
  211. irq_unregister(MOUSE_INTR_VECTOR);
  212. kfree((ul *)mouse_buf_ptr);
  213. }
  214. /**
  215. * @brief 获取鼠标数据包
  216. *
  217. * @param packet 数据包的返回值
  218. * @return int 错误码
  219. */
  220. int mouse_get_packet(void *packet)
  221. {
  222. if (mouse_buf_ptr->count != 0)
  223. kdebug("at get packet: count=%d", mouse_buf_ptr->count);
  224. int code = 0;
  225. switch (mouse_id)
  226. {
  227. case 0: // 3bytes 数据包
  228. if (mouse_buf_ptr->count < 3)
  229. return EFAIL;
  230. do
  231. {
  232. code = mouse_get_scancode();
  233. ((struct mouse_packet_3bytes *)packet)->byte0 = (unsigned char)code;
  234. } while (code == -1024);
  235. do
  236. {
  237. code = mouse_get_scancode();
  238. ((struct mouse_packet_3bytes *)packet)->movement_x = (char)code;
  239. } while (code == -1024);
  240. do
  241. {
  242. code = mouse_get_scancode();
  243. ((struct mouse_packet_3bytes *)packet)->movement_y = (char)code;
  244. } while (code == -1024);
  245. return SUCCESS;
  246. break;
  247. case 3: // 4bytes数据包
  248. case 4:
  249. if (mouse_buf_ptr->count < 4)
  250. return EFAIL;
  251. do
  252. {
  253. code = mouse_get_scancode();
  254. ((struct mouse_packet_4bytes *)packet)->byte0 = (unsigned char)code;
  255. } while (code == -1024);
  256. do
  257. {
  258. code = mouse_get_scancode();
  259. ((struct mouse_packet_4bytes *)packet)->movement_x = (char)code;
  260. } while (code == -1024);
  261. do
  262. {
  263. code = mouse_get_scancode();
  264. ((struct mouse_packet_4bytes *)packet)->movement_y = (char)code;
  265. } while (code == -1024);
  266. do
  267. {
  268. code = mouse_get_scancode();
  269. ((struct mouse_packet_4bytes *)packet)->byte3 = (char)code;
  270. } while (code == -1024);
  271. return SUCCESS;
  272. break;
  273. default: // Should not reach here
  274. kBUG("mouse_get_packet(): Invalid mouse_id!");
  275. return EFAIL;
  276. break;
  277. }
  278. return SUCCESS;
  279. }