Project

General

Profile

Statistics
| Revision:

root / proj / src / mouse.c @ 252

History | View | Annotate | Download (4.12 KB)

1
#include <lcom/lcf.h>
2

    
3
#include "mouse.h"
4

    
5
#include "errors.h"
6
#include "kbc_macros.h"
7
#include "mouse_macros.h"
8
#include "kbc.h"
9

    
10
int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
11
    if (interrupt_id == NULL) return NULL_PTR;
12
    *interrupt_id = interrupt_bit;
13
    if (sys_irqsetpolicy(MOUSE_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR;
14
    return SUCCESS;
15
}
16

    
17
int got_error_mouse_ih = 0;
18
int counter_mouse_ih = 0;
19

    
20
void (mouse_ih)(void) {
21
    uint8_t status = 0;
22
    got_error_mouse_ih = 0;
23
    if(counter_mouse_ih >= 3) counter_mouse_ih = 0;
24

    
25
    if ((got_error_mouse_ih = util_sys_inb(STATUS_REG, &status))) return;
26

    
27
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
28
        got_error_mouse_ih = OTHER_ERROR;
29
        return;
30
    }
31
    if (((status & AUX_MOUSE) == 0) || ((status & OUT_BUF_FUL) == 0)) {
32
        got_error_mouse_ih = READ_ERROR;
33
        return;
34
    }
35

    
36
    uint8_t byte = 0;
37

    
38
    if ((got_error_mouse_ih = util_sys_inb(OUTPUT_BUF, &byte))) return;
39

    
40
    /// This does not run if: I was expecting the first one but what I get is definitely not the first byte
41
    if((byte & FIRST_BYTE_ID)  || counter_mouse_ih){
42
        packet_mouse_ih[counter_mouse_ih++] = byte;
43
    }
44
}
45

    
46
void (mouse_parse_packet)(const uint8_t *packet_bytes, struct packet *pp){
47
    pp->bytes[0] = packet_bytes[0];
48
    pp->bytes[1] = packet_bytes[1];
49
    pp->bytes[2] = packet_bytes[2];
50
    pp->rb       = pp->bytes[0] & RIGHT_BUTTON;
51
    pp->mb       = pp->bytes[0] & MIDDLE_BUTTON;
52
    pp->lb       = pp->bytes[0] & LEFT_BUTTON;
53
    pp->delta_x  = sign_extend_byte((packet_bytes[0] & MSB_X_DELTA) != 0, pp->bytes[1]);
54
    pp->delta_y  = sign_extend_byte((packet_bytes[0] & MSB_Y_DELTA) != 0, pp->bytes[2]);
55
    pp->x_ov     = pp->bytes[0] & X_OVERFLOW;
56
    pp->y_ov     = pp->bytes[0] & Y_OVERFLOW;
57
}
58

    
59
int mouse_poll(struct packet *pp, uint16_t period){
60
    int ret = 0;
61

    
62
    uint8_t packet[3];
63
    uint8_t byte;
64
    if ((ret = mouse_issue_cmd(READ_DATA))) return ret;
65
    for(unsigned i = 0; i < 3; ++i){
66
        if((ret = mouse_poll_byte(&byte, period))) return ret;
67
        packet[i] = byte;
68
    }
69
    mouse_parse_packet(packet, pp);
70
    return SUCCESS;
71
}
72

    
73
int (mouse_set_data_report)(int on){
74
    if(on) return mouse_issue_cmd(ENABLE_DATA_REP);
75
    else   return mouse_issue_cmd(   DIS_DATA_REP);
76
}
77

    
78
int (mouse_read_data)(uint8_t *data, uint16_t period) {
79
    int ret;
80
    if ((ret = mouse_issue_cmd(READ_DATA))) return ret;
81
    if ((ret = mouse_poll_byte(data, period))) return ret;
82
    return SUCCESS;
83
}
84

    
85
int (mouse_issue_cmd)(uint32_t cmd) {
86
    int ret;
87
    uint8_t ack = 0;
88
    for (unsigned int i = 0; i < KBC_NUM_TRIES; i++) {
89
        if ((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
90
        if ((ret = kbc_issue_arg(cmd))) return ret;
91
        if ((ret = mouse_read_byte(&ack))) return ret;
92

    
93
        if (ack == ACK_OK) return SUCCESS;
94
        if (ack == ACK_ERROR) return INVALID_COMMAND;
95
        tickdelay(micros_to_ticks(DELAY));
96
    }
97
    return TIMEOUT_ERROR;
98
}
99

    
100
int (mouse_read_byte)(uint8_t *byte) {
101
    int ret = 0;
102
    uint8_t stat;
103
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
104
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
105
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) {
106
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
107
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
108
            else return SUCCESS;
109
        }
110
        tickdelay(micros_to_ticks(DELAY));
111
    }
112
    return TIMEOUT_ERROR;
113
}
114

    
115
int (mouse_poll_byte)(uint8_t *byte, uint16_t period) {
116
    int ret = 0;
117
    uint8_t stat;
118
    while(true){
119
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
120
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) {
121
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
122
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
123
            else return SUCCESS;
124
        }
125
        tickdelay(micros_to_ticks(DELAY));
126
    }
127
}
128

    
129
int16_t (sign_extend_byte)(uint8_t sign_bit, uint8_t byte) {
130
    return (int16_t)(((0xFF * sign_bit)<<8) | byte);
131
}