Project

General

Profile

Statistics
| Revision:

root / lab3 / kbc_func.c @ 52

History | View | Annotate | Download (3.01 KB)

1 47 up20180642
#include "kbc_func.h"
2
#include "kbc.h"
3
4
#include <lcom/lcf.h>
5
6
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
7
    if (interrupt_id == NULL) return 1;
8
    *interrupt_id = interrupt_bit;
9
    return (sys_irqsetpolicy(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id));
10
}
11
12
int (unsubscribe_interrupt)(int *interrupt_id) {
13
    if (interrupt_id == NULL) return 1;
14
    return sys_irqrmpolicy(interrupt_id);
15
}
16
17
uint8_t scancode[2];
18
int got_error = 0;
19 49 up20180655
int done = 1;
20 48 up20180655
int sz = 1;
21 47 up20180642
22
void (kbc_ih)(void) {
23 49 up20180655
24
    if(done) sz = 1;
25
    else     sz++;
26
27 47 up20180642
    uint8_t status = 0;
28
    got_error = 0;
29
30
    if (util_sys_inb(STATUS_REG, &status)) {
31
        got_error = 1;
32
        return;
33
    }
34
35
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
36
        got_error = 1;
37
        return;
38
    }
39
40 50 up20180655
    if ((status & OUT_BUF_FUL) == 0 || (status & AUX_MOUSE) != 0) {
41
        got_error = 1;
42
        return;
43
    }
44
45 47 up20180642
    uint8_t byte = 0;
46
47
    if (util_sys_inb(OUTPUT_BUF, &byte)) {
48
        got_error = 1;
49
        return;
50
    }
51
52 49 up20180655
    scancode[sz-1] = byte;
53
    done = !(TWO_BYTE_CODE == byte);
54 47 up20180642
55
}
56
57
int (kbd_poll)(uint8_t bytes[], uint8_t *size){
58
    if(bytes == NULL || size == NULL) return 1;
59
    uint8_t c;
60
    if(kbc_read_byte(&c)) return 1;
61
    if(c == TWO_BYTE_CODE){
62
        if(kbc_read_byte(&bytes[1])) return 1;
63
        bytes[0] = c;
64
        *size = 2;
65
    }else{
66
        bytes[1] = 0;
67
        bytes[0] = c;
68
        *size = 1;
69
    }
70
    return 0;
71
}
72
73
int (kbc_read_cmd)(uint8_t *cmd){
74
    if(kbc_issue_cmd(READ_KBC_CMD)) return 1;
75
    if(kbc_read_byte(cmd)) return 1;
76
    return 0;
77
}
78
79
int (kbc_change_cmd)(uint8_t cmd){
80
    if(kbc_issue_cmd(WRITE_KBC_CMD)) return 1;
81 50 up20180655
    if(kbc_issue_arg(cmd)) return 1;
82 47 up20180642
    return 0;
83
}
84
85
int (kbc_restore_kbd)(){
86
    uint8_t cmd = 0;
87
    if(kbc_read_cmd(&cmd)) return 1;
88
    cmd = (cmd | INT_KBD) & (~DIS_KBD);
89
    if(kbc_change_cmd(cmd)) return 1;
90
    return 0;
91
}
92
93
int (kbc_issue_cmd)(uint8_t cmd){
94
    uint8_t stat;
95
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
96
        if(util_sys_inb(STATUS_REG, &stat)) return 1;
97
        if((stat&IN_BUF_FULL) == 0){
98
            if(sys_outb(KBC_CMD, cmd)) return 1;
99
            return 0;
100
        }
101
        tickdelay(micros_to_ticks(DELAY));
102
    }
103
    return 1;
104
}
105
106 50 up20180655
int (kbc_issue_arg)(uint8_t arg){
107
    uint8_t stat;
108
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
109
        if(util_sys_inb(STATUS_REG, &stat)) return 1;
110
        if((stat&IN_BUF_FULL) == 0){
111
            if(sys_outb(KBC_CMD_ARG, arg)) return 1;
112
            return 0;
113
        }
114
        tickdelay(micros_to_ticks(DELAY));
115
    }
116
    return 1;
117
}
118
119 47 up20180642
int (kbc_read_byte)(uint8_t *byte){
120
    uint8_t stat;
121
    while(true){
122
        if(util_sys_inb(STATUS_REG, &stat)) return 1;
123
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
124
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return 1;
125
            if(util_sys_inb(OUTPUT_BUF, byte)) return 1;
126
            else return 0;
127
        }
128
        tickdelay(micros_to_ticks(DELAY));
129
    }
130
}