Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <minix/syslib.h>
- #include <minix/drivers.h>
- #include <minix/com.h>
- #include "keyboard.h"
- #include "timer.h"
- #include "i8042.h"
- #include "i8254.h"
- int hood_id_kbd = KBD_IRQ;
- int hook_id_mouse = TIMER0_IRQ;
- unsigned short status = 0;
- int kbd_subscribe() {
- int tmp = hood_id_kbd;
- //"Use not only the IRQ_REENABLE but also the IRQ_EXCLUSIVE policy"
- if (sys_irqsetpolicy(KBD_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, &hood_id_kbd)
- != OK) {
- printf("\n sys_irqsetpolicy() failed \n");
- return -1;
- }
- if (sys_irqenable(&hood_id_kbd) == OK)
- return BIT(tmp);
- else {
- printf("\n sys_irqenable() failed \n");
- return -1;
- }
- }
- int kbd_unsubscribe() {
- if (sys_irqdisable(&hood_id_kbd) != OK) {
- printf("\n sys_irqdisable failed \n");
- return -1;
- }
- if (sys_irqrmpolicy(&hood_id_kbd) == OK) {
- return 0;
- } else {
- printf("\n sys_irqrmpolicy() failed \n");
- return -1;
- }
- }
- int kbd_int_handler() {
- unsigned long stat, data, i = 0;
- while (i < NR_TRIES) {
- if (sys_inb(STAT_REG, &stat) != OK) {
- printf("sys_inb() STAT_REG has failed");
- return -1;
- }
- if (stat & OBF) {
- if (sys_inb(OUT_BUF, &data) != OK) {
- printf("sys_inb() OUT_BUF has failed");
- return -1;
- }
- if ((stat & (PAR_ERR | TO_ERR)) == 0)
- return data;
- else {
- printf("Error related to parity/timeout /n");
- return -1;
- }
- }
- tickdelay(micros_to_ticks(DELAY_US));
- i++;
- }
- return -1;
- }
- int kbd_driver(unsigned long irq_set) {
- unsigned long data;
- int ipc_status;
- message msg;
- int i = 0;
- while (i != 3) {
- if (driver_receive(ANY, &msg, &ipc_status) != 0) {
- printf("driver_receive failed with: %d",
- driver_receive(ANY, &msg, &ipc_status));
- continue;
- }
- if (is_ipc_notify(ipc_status)) { /*received notification*/
- switch (_ENDPOINT_P(msg.m_source)) {
- case HARDWARE: /*hardware interrupt notification*/
- if (msg.NOTIFY_ARG & irq_set) { /*subscribed interrupt*/
- data = kbd_int_handler();
- int msb = data & 0x80;
- if (data == TWO_BYTE_SCANCODE) {
- int aux = kbd_int_handler();
- data = (data << 8) | aux;
- }
- return data;
- }
- break;
- default:
- break;/*no other notifications expected: do nothing*/
- }
- }
- i++;
- }
- }
- int kbd_display_scancode() {
- unsigned long irq_set;
- if ((irq_set = kbd_subscribe()) == -1)
- return -1;
- int data;
- while (data != ESC_CODE) {
- data = kbd_driver(irq_set);
- int msb = data & 0x80; //"difference between the make and the break codes of a key is in the MSB"
- int aux = data >> 8;
- if (aux == TWO_BYTE_SCANCODE) {
- if (msb == 0) {
- printf("\n\nMakecode: 0x");
- printf("%04X", data);
- }
- else {
- printf("\n Breakcode: 0x");
- printf("%04X", data);
- }
- }
- if (aux == 0) {
- if (msb == 0) {
- printf("\n\nMakecode: 0x");
- printf("%02X", data);
- }
- else {
- printf("\n Breakcode: 0x");
- printf("%02X", data);
- }
- }
- }
- if (kbd_unsubscribe() == -1)
- return -1;
- }
- int kbd_set_leds(unsigned short n, unsigned short *leds) {
- int ipc_status;
- message msg;
- 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
- int freq = 60;
- int time_past = 0; //reset
- int i = 0;
- if (irq_set == -1) {
- printf("Error subscribing.\n");
- return -1;
- }
- while (time_past < n * freq) { //can't go beyond the set time interval
- // Get a request message.
- int r = driver_receive(ANY, &msg, &ipc_status);
- if (r != 0) {
- printf("driver_receive failed with: %d", r);
- continue;
- }
- if (is_ipc_notify(ipc_status)) { // received notification
- switch (_ENDPOINT_P(msg.m_source)) {
- case HARDWARE: // hardware interrupt notification
- if (msg.NOTIFY_ARG & irq_set) { // subscribed interrupt
- time_past++; //"a device only uses one interrupt line"->"call the interrupt handler"-time_past incremented
- if (time_past % freq == 0) {
- if (i == n)
- break;
- if (kbd_set_single_led(leds[i]) == -1) {
- printf("Error.\n");
- }
- i++;
- }
- }
- break;
- default:
- break; /* no other notifications expected: do nothing */
- }
- } else { /* received a standard message, not a notification */
- /* no standard messages expected: do nothing */
- }
- }
- unsigned long stat;
- sys_inb(STAT_REG, &stat);
- if (timer_unsubscribe_int() == -1) {
- printf("Error unsubscribing.\n");
- return -1;
- }
- sys_inb(STAT_REG, &stat);
- return 0;
- }
- int kbd_set_single_led(unsigned short led) {
- unsigned long data = 0;
- int i = 0;
- status ^= BIT(led);
- printf("status: %x\n", status);
- do {
- write_command(ENABLE_LEDS);
- data = read_from_kbc();
- printf("enable leds - data: %d\n", data);
- i++;
- } while ((data != ACK) && i < NR_TRIES);
- if (i >= NR_TRIES)
- return -1;
- i = 0;
- do {
- write_command(status);
- data = read_from_kbc();
- printf("argument - data: %d\n", data);
- i++;
- } while ((data != ACK) && i < NR_TRIES);
- if (i >= NR_TRIES)
- return -1;
- printf("Acabei led %d.\n", led);
- return 0;
- }
- int write_command(unsigned long cmd) {
- unsigned long stat;
- int i = 0;
- while (i < NR_TRIES) {
- if (sys_inb(STAT_REG, &stat) != OK){
- printf("write_command: sys_inb failed.\n");
- return -1;
- }
- if ((stat & IBF) == 0) {
- if (sys_outb(IN_BUF, cmd) != OK){
- printf("write_command: sys_inb inbuf failed.\n");
- return -1;
- }
- else{
- printf("Wrote command to inbuf.\n");
- return 0;
- }
- }
- tickdelay(micros_to_ticks(5 * DELAY_US));
- i++;
- }
- return -1;
- }
- int read_from_kbc() {
- unsigned long stat, data;
- int i = 0;
- while (i < NR_TRIES) {
- if (sys_inb(STAT_REG, &stat) != OK){
- printf("read_from_kbc: sys_inb failed.\n");
- return -1;
- }
- if (stat & OBF) {
- if (sys_inb(OUT_BUF, &data) != OK){
- printf("read_from_kbc: sys_inb outbuf failed.\n");
- return -1;
- }
- if ((stat & (PAR_ERR | TO_ERR)) == 0){
- printf(" %02x ", data);
- return data;
- }
- else
- return -1;
- }
- tickdelay(micros_to_ticks(5 * DELAY_US));
- i++;
- }
- //service run /home/lcom/lab3/lab3 -args "leds 1 2"
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement