Project

General

Profile

Revision 59

even more changes

View differences:

lab4/kbc.c
1
#include <lcom/lcf.h>
2

  
3
#include "kbc.h"
4

  
5
#include "kbc_macros.h"
6

  
7
int (unsubscribe_interrupt)(int *interrupt_id) {
8
    if (interrupt_id == NULL) return 1;
9
    return sys_irqrmpolicy(interrupt_id);
10
}
11

  
12
int (kbc_read_cmd)(uint8_t *cmd){
13
    if(kbc_issue_cmd(READ_KBC_CMD)) return 1;
14
    if(kbc_read_byte(cmd)) return 1;
15
    return 0;
16
}
17

  
18
int (kbc_change_cmd)(uint8_t cmd){
19
    if(kbc_issue_cmd(WRITE_KBC_CMD)) return 1;
20
    if(sys_outb(KBC_CMD_ARG, cmd)) return 1;
21
    return 0;
22
}
23

  
24
int (kbc_restore_kbd)(){
25
    uint8_t cmd = 0;
26
    if(kbc_read_cmd(&cmd)) return 1;
27
    cmd = (cmd | INT_KBD) & (~DIS_KBD) ;
28
    if(kbc_change_cmd(cmd)) return 1;
29
    return 0;
30
}
31

  
32
int (kbc_issue_cmd)(uint8_t cmd){
33
    uint8_t stat;
34
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
35
        if(util_sys_inb(STATUS_REG, &stat)) return 1;
36
        if((stat&IN_BUF_FULL) == 0){
37
            if(sys_outb(KBC_CMD, cmd)) return 1;
38
            return 0;
39
        }
40
        tickdelay(micros_to_ticks(DELAY));
41
    }
42
    return 1;
43
}
44

  
45
int (kbc_read_byte)(uint8_t *byte){
46
    uint8_t stat;
47
    while(true){
48
        if(util_sys_inb(STATUS_REG, &stat)) return 1;
49
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
50
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return 1;
51
            if(util_sys_inb(OUTPUT_BUF, byte)) return 1;
52
            else return 0;
53
        }
54
        tickdelay(micros_to_ticks(DELAY));
55
    }
56
}
0 57

  
lab4/kbc_macros.h
1
#ifndef _KBC_H_
2
#define _KBC_H_
3

  
4
/* KBC IRQ Line */
5

  
6
#define KBC_IRQ     1   /* @brief KBC Controller IRQ Line */
7
#define MOUSE_IRQ   12  /* @brief Mouse IRQ Line */
8

  
9
/* Delay for KBC */
10
#define DELAY           20000 /* @brief KBC Response Delay */
11
#define KBC_NUM_TRIES   10    /* @brief Number of tries to issue command before timeout */
12

  
13
/* I/O Ports Addresses */
14

  
15
#define KBC_CMD     0x64 /* @brief Address to send commands to KBC */
16
#define KBC_CMD_ARG 0x60 /* @brief Address to write KBC Command Arguments */
17
#define STATUS_REG  0x64 /* @brief KBC Status Register address */
18

  
19
#define OUTPUT_BUF  0x60 /* @brief Address of Output Buffer of KBC */
20

  
21
/* KBC Commands */
22
#define READ_KBC_CMD    0x20 /* @brief Read KBC Command Byte */
23
#define WRITE_KBC_CMD   0x60 /* @brief Write KBC Command Byte */
24
#define KBC_SELF_TEST   0xAA /* @brief KBC Diagnostic Tests */
25
#define KBC_INT_TEST    0xAB /* @brief Tests Keyboard Clock and Data lines */
26
#define KBC_INT_DISABLE 0xAD /* @brief Disable KBC Interface */
27
#define KBC_INT_ENABLE  0xAE /* @brief Enable KBC Interface */
28
#define MOUSE_DISABLE   0xA7 /* @brief Disable Mouse */
29
#define MOUSE_ENABLE    0xA8 /* @brief Enable Mouse */
30
#define MOUSE_INT_TEST  0xA9 /* @brief Tests Mouse data line */
31
#define MOUSE_WRITE_B   0xD4 /* @brief Write a byte directly to the mouse */
32

  
33
/* Status Byte Masking */
34

  
35
#define OUT_BUF_FUL     BIT(0) /* @brief Output Buffer State */
36
#define IN_BUF_FULL     BIT(1) /* @brief Input Buffer State */
37
#define SYS_FLAG        BIT(2) /* @brief System Flag */
38
#define DATA_CMD_WRITE  BIT(3) /* @brief Identifier of type of byte in input buffer */
39
#define INH_FLAG        BIT(4) /* @brief Keyboard inihibited */
40
#define AUX_MOUSE       BIT(5) /* @brief Mouse Data */
41
#define TIME_OUT_REC    BIT(6) /* @brief Time Out Error - Invalid Data */
42
#define PARITY_ERROR    BIT(7) /* @brief Parity Error - Invalid Data */
43

  
44
/* Scancode Constants */
45

  
46
#define ESC_BREAK_CODE  0x81    /* @brief ESC Break Code */
47
#define TWO_BYTE_CODE   0xE0    /* @brief First byte of a two byte Scancode */
48
#define BREAK_CODE_BIT  BIT(7)  /* @brief Bit to distinguish between Make code and Break code */
49

  
50
/* Command byte masks */
51
#define INT_KBD         BIT(0)  /* @brief Enable Keyboard Interrupts */
52
#define INT_MOU         BIT(1)  /* @brief Enable Mouse Interrupts */
53
#define DIS_KBD         BIT(4)  /* @brief Disable Keyboard */
54
#define DIS_MOU         BIT(5)  /* @brief Disable Mouse */
55

  
56
#endif
0 57

  
lab4/kbd.c
1
#include <lcom/lcf.h>
2

  
3
#include "kbd.h"
4

  
5
#include "kbc_macros.h"
6
#include "kbc.h"
7

  
8
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
9
    if (interrupt_id == NULL) return 1;
10
    *interrupt_id = interrupt_bit;
11
    return (sys_irqsetpolicy(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id));
12
}
13

  
14
void (kbc_ih)(void) {
15
    uint8_t status = 0;
16
    got_error = 0;
17

  
18
    if (util_sys_inb(STATUS_REG, &status)) {
19
        got_error = 1;
20
        return;
21
    }
22

  
23
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
24
        got_error = 1;
25
        return;
26
    }
27

  
28
    uint8_t byte = 0;
29

  
30
    if (util_sys_inb(OUTPUT_BUF, &byte)) {
31
        got_error = 1;
32
        return;
33
    }
34

  
35
    if (two_byte_scancode) {
36
        scancode[1] = byte;
37
        two_byte_scancode = 0;
38
    } else {
39
        scancode[0] = byte;
40
        two_byte_scancode = (byte == TWO_BYTE_CODE);
41
    }
42

  
43
}
44

  
45
int (kbd_poll)(uint8_t bytes[], uint8_t *size){
46
    if(bytes == NULL || size == NULL) return 1;
47
    uint8_t c;
48
    if(kbc_read_byte(&c)) return 1;
49
    if(c == TWO_BYTE_CODE){
50
        if(kbc_read_byte(&bytes[1])) return 1;
51
        bytes[0] = c;
52
        *size = 2;
53
    }else{
54
        bytes[1] = 0;
55
        bytes[0] = c;
56
        *size = 1;
57
    }
58
    return 0;
59
}
0 60

  
lab4/kbd.h
1
/**
2
 * This file concerns everything related to the keyboard
3
 */
4

  
5
#ifndef KBD_H_INCLUDED
6
#define KBD_H_INCLUDED
7

  
8
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
9

  
10
uint8_t scancode[2];
11
int two_byte_scancode = 0;
12
int got_error = 0;
13

  
14
void (kbc_ih)(void);
15

  
16
int (kbd_poll)(uint8_t bytes[], uint8_t *size);
17

  
18
#endif //KBD_H_INCLUDED
0 19

  
lab4/mouse.c
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
uint8_t packet[3];
19
int counter = 0;
20

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

  
26
    if (util_sys_inb(STATUS_REG, &status)) {
27
        got_error_mouse_ih = 1;
28
        return;
29
    }
30

  
31
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
32
        got_error_mouse_ih = 1;
33
        return;
34
    }
35

  
36
    uint8_t byte = 0;
37

  
38
    if (util_sys_inb(OUTPUT_BUF, &byte)) {
39
        got_error_mouse_ih = 1;
40
        return;
41
    }
42

  
43
    /// This does not run if: I was expecting the first one but what I get is definitely not the first byte
44
    if((byte & FIRST_BYTE_ID)  || counter){
45
        packet[counter] = byte;
46
        counter++;
47
    }
48
}
49

  
50
struct packet (mouse_parse_packet)(const uint8_t *packet_bytes){
51
    struct packet pp;
52
    pp.bytes[0] = packet_bytes[0];
53
    pp.bytes[1] = packet_bytes[1];
54
    pp.bytes[2] = packet_bytes[2];
55
    pp.rb       = pp.bytes[0] & RIGHT_BUTTON;
56
    pp.mb       = pp.bytes[0] & MIDDLE_BUTTON;
57
    pp.lb       = pp.bytes[0] & LEFT_BUTTON;
58
    pp.delta_x  = pp.bytes[1];
59
    pp.delta_y  = pp.bytes[2];
60
    pp.x_ov     = pp.bytes[0] & X_OVERFLOW;
61
    pp.y_ov     = pp.bytes[0] & Y_OVERFLOW;
62
    return pp;
63
}
64

  
65
int (mouse_set_data_report)(int on){
66
    int ret = 0;
67
    if((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
68
    if(sys_outb(KBC_CMD_ARG, DIS_DATA_REP)) return WRITE_ERROR;
69
    return SUCCESS;
70
}
0 71

  
lab4/mouse_macros.h
1
#ifndef _MOUSE_H_
2
#define _MOUSE_H_
3

  
4
/* Mouse Data Packet */
5
// Byte 0 - Button States
6
#define LEFT_BUTTON     BIT(0) /* @brief Left button click event*/
7
#define RIGHT_BUTTON    BIT(1) /* @brief Right button click event */
8
#define MIDDLE_BUTTON   BIT(2) /* @brief Middle button click event */
9
#define FIRST_BYTE_ID   BIT(3) /* @brief Identifier of first byte of packet CAREFUL: Not 100% accurate */
10
#define MSB_X_DELTA     BIT(4) /* @brief Most significant bit of X delta */
11
#define MSB_Y_DELTA     BIT(5) /* @brief Most significant bit of Y delta */
12
#define X_OVERFLOW      BIT(6) /* @brief X delta overflowed */
13
#define Y_OVERFLOW      BIT(7) /* @brief Y delta overflowed */
14
// Byte 1 - X delta
15
// Byte 2 - Y delta
16

  
17
/* Mouse Commands */
18
#define RESET           0xFF /* @brief Reset mouse */
19
#define RESEND          0xFE /* @brief Resend command */
20
#define DEFAULT         0xF6 /* @brief Set default values */
21
#define DIS_DATA_REP    0xF5 /* @brief Disable Data Reporting */
22
#define ENABLE_DATA_REP 0xF4 /* @brief Enable Data Reporting */
23
#define SET_SAMPLE_RT   0xF3 /* @brief Sets state sampling rate */
24
#define SET_REMOTE_MD   0xF0 /* @brief Sets Mouse on Remote Mode, data on request */
25
#define READ_DATA       0xEB /* @brief Sends data packet request */
26
#define SET_STREAM_MD   0xEA /* @brief Sets mouse on Stream Mode, data on events */
27
#define STATUS_REQUEST  0xE9 /* @brief Get mouse configuration */
28
#define SET_RESOLUTION  0xE8 /* @brief Sets resolution for mouse movement */
29
#define SCALING_ACC_MD  0xE7 /* @brief Sets scaling on acceleration mode */
30
#define SCALING_LIN_MD  0xE6 /* @brief Sets scaling on linear mode */
31

  
32
/* Mouse Controller Responses */
33
#define ACK_OK      0xFA /* @brief Operation sucessful */
34
#define ACK_INVALID 0xFE /* @brief Invalid Byte, first occurence */
35
#define ACK_ERROR   0xFC /* @brief Invalid Byte on resend */
36

  
37
#endif // _MOUSE_H_
0 38

  

Also available in: Unified diff