Advertisement
Guest User

Untitled

a guest
Oct 26th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.34 KB | None | 0 0
  1. #include <minix/syslib.h>
  2. #include <minix/drivers.h>
  3. #include <minix/com.h>
  4. #include "keyboard.h"
  5. #include "timer.h"
  6. #include "i8042.h"
  7. #include "i8254.h"
  8.  
  9. int hood_id_kbd = KBD_IRQ;
  10. int hook_id_mouse = TIMER0_IRQ;
  11.  
  12. unsigned short status = 0;
  13.  
  14.  
  15. int kbd_subscribe() {
  16.  
  17. int tmp = hood_id_kbd;
  18. //"Use not only the IRQ_REENABLE but also the IRQ_EXCLUSIVE policy"
  19. if (sys_irqsetpolicy(KBD_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, &hood_id_kbd)
  20. != OK) {
  21.  
  22. printf("\n sys_irqsetpolicy() failed \n");
  23.  
  24. return -1;
  25.  
  26. }
  27.  
  28. if (sys_irqenable(&hood_id_kbd) == OK)
  29.  
  30. return BIT(tmp);
  31.  
  32. else {
  33.  
  34. printf("\n sys_irqenable() failed \n");
  35.  
  36. return -1;
  37.  
  38. }
  39.  
  40. }
  41.  
  42. int kbd_unsubscribe() {
  43.  
  44. if (sys_irqdisable(&hood_id_kbd) != OK) {
  45.  
  46. printf("\n sys_irqdisable failed \n");
  47.  
  48. return -1;
  49.  
  50. }
  51.  
  52. if (sys_irqrmpolicy(&hood_id_kbd) == OK) {
  53.  
  54. return 0;
  55.  
  56. } else {
  57.  
  58. printf("\n sys_irqrmpolicy() failed \n");
  59.  
  60. return -1;
  61.  
  62. }
  63.  
  64. }
  65.  
  66. int kbd_int_handler() {
  67. unsigned long stat, data, i = 0;
  68.  
  69. while (i < NR_TRIES) {
  70.  
  71. if (sys_inb(STAT_REG, &stat) != OK) {
  72. printf("sys_inb() STAT_REG has failed");
  73. return -1;
  74. }
  75.  
  76. if (stat & OBF) {
  77.  
  78. if (sys_inb(OUT_BUF, &data) != OK) {
  79. printf("sys_inb() OUT_BUF has failed");
  80. return -1;
  81. }
  82.  
  83. if ((stat & (PAR_ERR | TO_ERR)) == 0)
  84. return data;
  85.  
  86. else {
  87. printf("Error related to parity/timeout /n");
  88. return -1;
  89. }
  90.  
  91. }
  92.  
  93. tickdelay(micros_to_ticks(DELAY_US));
  94.  
  95. i++;
  96.  
  97. }
  98.  
  99. return -1;
  100.  
  101. }
  102.  
  103. int kbd_driver(unsigned long irq_set) {
  104. unsigned long data;
  105.  
  106. int ipc_status;
  107.  
  108. message msg;
  109.  
  110. int i = 0;
  111.  
  112. while (i != 3) {
  113.  
  114. if (driver_receive(ANY, &msg, &ipc_status) != 0) {
  115.  
  116. printf("driver_receive failed with: %d",
  117. driver_receive(ANY, &msg, &ipc_status));
  118. continue;
  119.  
  120. }
  121.  
  122. if (is_ipc_notify(ipc_status)) { /*received notification*/
  123.  
  124. switch (_ENDPOINT_P(msg.m_source)) {
  125.  
  126. case HARDWARE: /*hardware interrupt notification*/
  127.  
  128. if (msg.NOTIFY_ARG & irq_set) { /*subscribed interrupt*/
  129.  
  130. data = kbd_int_handler();
  131.  
  132. int msb = data & 0x80;
  133.  
  134. if (data == TWO_BYTE_SCANCODE) {
  135.  
  136. int aux = kbd_int_handler();
  137.  
  138. data = (data << 8) | aux;
  139.  
  140. }
  141.  
  142. return data;
  143. }
  144.  
  145. break;
  146.  
  147. default:
  148.  
  149. break;/*no other notifications expected: do nothing*/
  150.  
  151. }
  152.  
  153. }
  154.  
  155. i++;
  156.  
  157. }
  158.  
  159. }
  160.  
  161. int kbd_display_scancode() {
  162. unsigned long irq_set;
  163.  
  164. if ((irq_set = kbd_subscribe()) == -1)
  165. return -1;
  166.  
  167. int data;
  168.  
  169. while (data != ESC_CODE) {
  170. data = kbd_driver(irq_set);
  171.  
  172. int msb = data & 0x80; //"difference between the make and the break codes of a key is in the MSB"
  173.  
  174. int aux = data >> 8;
  175.  
  176. if (aux == TWO_BYTE_SCANCODE) {
  177. if (msb == 0) {
  178.  
  179. printf("\n\nMakecode: 0x");
  180. printf("%04X", data);
  181. }
  182.  
  183. else {
  184. printf("\n Breakcode: 0x");
  185. printf("%04X", data);
  186. }
  187. }
  188.  
  189. if (aux == 0) {
  190. if (msb == 0) {
  191.  
  192. printf("\n\nMakecode: 0x");
  193. printf("%02X", data);
  194. }
  195.  
  196. else {
  197. printf("\n Breakcode: 0x");
  198. printf("%02X", data);
  199. }
  200. }
  201. }
  202.  
  203. if (kbd_unsubscribe() == -1)
  204. return -1;
  205.  
  206. }
  207.  
  208. int kbd_set_leds(unsigned short n, unsigned short *leds) {
  209.  
  210. int ipc_status;
  211. message msg;
  212. unsigned long irq_set = timer_subscribe_int(); //variable irq_set should be a bitmask with the bits corresponding to the hook_id values used in the sys_irqsetpolicy() set to 1
  213.  
  214. int freq = 60;
  215. int time_past = 0; //reset
  216. int i = 0;
  217.  
  218. if (irq_set == -1) {
  219. printf("Error subscribing.\n");
  220. return -1;
  221. }
  222.  
  223. while (time_past < n * freq) { //can't go beyond the set time interval
  224. // Get a request message.
  225. int r = driver_receive(ANY, &msg, &ipc_status);
  226. if (r != 0) {
  227. printf("driver_receive failed with: %d", r);
  228. continue;
  229. }
  230. if (is_ipc_notify(ipc_status)) { // received notification
  231. switch (_ENDPOINT_P(msg.m_source)) {
  232. case HARDWARE: // hardware interrupt notification
  233. if (msg.NOTIFY_ARG & irq_set) { // subscribed interrupt
  234. time_past++; //"a device only uses one interrupt line"->"call the interrupt handler"-time_past incremented
  235. if (time_past % freq == 0) {
  236. if (i == n)
  237. break;
  238.  
  239. if (kbd_set_single_led(leds[i]) == -1) {
  240. printf("Error.\n");
  241. }
  242. i++;
  243.  
  244. }
  245. }
  246. break;
  247. default:
  248. break; /* no other notifications expected: do nothing */
  249. }
  250. } else { /* received a standard message, not a notification */
  251. /* no standard messages expected: do nothing */
  252. }
  253. }
  254.  
  255. unsigned long stat;
  256. sys_inb(STAT_REG, &stat);
  257.  
  258. if (timer_unsubscribe_int() == -1) {
  259. printf("Error unsubscribing.\n");
  260. return -1;
  261. }
  262.  
  263. sys_inb(STAT_REG, &stat);
  264.  
  265. return 0;
  266. }
  267.  
  268. int kbd_set_single_led(unsigned short led) {
  269.  
  270. unsigned long data = 0;
  271. int i = 0;
  272.  
  273. status ^= BIT(led);
  274. printf("status: %x\n", status);
  275. do {
  276. write_command(ENABLE_LEDS);
  277.  
  278. data = read_from_kbc();
  279. printf("enable leds - data: %d\n", data);
  280. i++;
  281.  
  282. } while ((data != ACK) && i < NR_TRIES);
  283.  
  284. if (i >= NR_TRIES)
  285. return -1;
  286.  
  287. i = 0;
  288. do {
  289. write_command(status);
  290.  
  291. data = read_from_kbc();
  292. printf("argument - data: %d\n", data);
  293. i++;
  294.  
  295. } while ((data != ACK) && i < NR_TRIES);
  296.  
  297. if (i >= NR_TRIES)
  298. return -1;
  299.  
  300. printf("Acabei led %d.\n", led);
  301. return 0;
  302.  
  303. }
  304.  
  305. int write_command(unsigned long cmd) {
  306.  
  307. unsigned long stat;
  308. int i = 0;
  309.  
  310. while (i < NR_TRIES) {
  311. if (sys_inb(STAT_REG, &stat) != OK){
  312. printf("write_command: sys_inb failed.\n");
  313. return -1;
  314. }
  315.  
  316. if ((stat & IBF) == 0) {
  317. if (sys_outb(IN_BUF, cmd) != OK){
  318. printf("write_command: sys_inb inbuf failed.\n");
  319. return -1;
  320. }
  321. else{
  322. printf("Wrote command to inbuf.\n");
  323. return 0;
  324. }
  325. }
  326. tickdelay(micros_to_ticks(5 * DELAY_US));
  327. i++;
  328. }
  329.  
  330. return -1;
  331.  
  332. }
  333.  
  334. int read_from_kbc() {
  335.  
  336. unsigned long stat, data;
  337. int i = 0;
  338.  
  339. while (i < NR_TRIES) {
  340.  
  341. if (sys_inb(STAT_REG, &stat) != OK){
  342. printf("read_from_kbc: sys_inb failed.\n");
  343. return -1;
  344. }
  345.  
  346. if (stat & OBF) {
  347. if (sys_inb(OUT_BUF, &data) != OK){
  348. printf("read_from_kbc: sys_inb outbuf failed.\n");
  349. return -1;
  350. }
  351.  
  352. if ((stat & (PAR_ERR | TO_ERR)) == 0){
  353. printf(" %02x ", data);
  354. return data;
  355. }
  356. else
  357. return -1;
  358. }
  359. tickdelay(micros_to_ticks(5 * DELAY_US));
  360. i++;
  361.  
  362. }
  363. //service run /home/lcom/lab3/lab3 -args "leds 1 2"
  364.  
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement