Revision 68
working decently
lab4/errors.h | ||
---|---|---|
1 |
#ifndef _ERRORS_H_
|
|
2 |
#define _ERRORS_H_
|
|
1 |
#ifndef ERRORS_H_INCLUDED
|
|
2 |
#define ERRORS_H_INCLUDED
|
|
3 | 3 |
|
4 | 4 |
enum errors { |
5 | 5 |
SUCCESS = 0, /* @brief Sucessful */ |
6 | 6 |
NULL_PTR, /* @brief Null Pointer Error */ |
7 | 7 |
LCF_ERROR, /* @brief Error originated on LCF */ |
8 | 8 |
SBCR_ERROR, /* @brief Error on Subscribing Interrupt */ |
9 |
UNSBCR_ERROR, /* @brief Error on Unsubscring Interrupt*/
|
|
9 |
UNSBCR_ERROR, /* @brief Error on Unsubscring Interrupt*/ |
|
10 | 10 |
READ_ERROR, /* @brief Error on Reading from Port */ |
11 | 11 |
WRITE_ERROR, /* @brief Error on Writing to Port */ |
12 |
TIMEOUT_ERROR, /* @brief Timeout error */ |
|
13 |
OTHER_ERROR, /* @brief Unspecified error */ |
|
12 | 14 |
}; |
13 | 15 |
|
14 |
#endif /* end of include guard: _ERRORS_H_ */ |
|
16 |
#endif //ERRORS_H_INCLUDED |
lab4/kbc.c | ||
---|---|---|
3 | 3 |
#include "kbc.h" |
4 | 4 |
|
5 | 5 |
#include "kbc_macros.h" |
6 |
#include "utils.h" |
|
7 |
#include "errors.h" |
|
6 | 8 |
|
7 | 9 |
int (unsubscribe_interrupt)(int *interrupt_id) { |
8 |
if (interrupt_id == NULL) return 1; |
|
9 |
return sys_irqrmpolicy(interrupt_id); |
|
10 |
if (interrupt_id == NULL) return NULL_PTR; |
|
11 |
if(sys_irqrmpolicy(interrupt_id)) return UNSBCR_ERROR; |
|
12 |
return SUCCESS; |
|
10 | 13 |
} |
11 | 14 |
|
12 | 15 |
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 |
int ret = 0; |
|
17 |
if((ret = kbc_issue_cmd(READ_KBC_CMD))) return ret; |
|
18 |
if((ret = kbc_read_byte(cmd))) return ret; |
|
19 |
return SUCCESS; |
|
16 | 20 |
} |
17 | 21 |
|
18 | 22 |
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; |
|
23 |
int ret = 0; |
|
24 |
if((ret = kbc_issue_cmd(WRITE_KBC_CMD))) return ret; |
|
25 |
if((ret = kbc_issue_arg(cmd))) return ret; |
|
26 |
return SUCCESS; |
|
22 | 27 |
} |
23 | 28 |
|
24 | 29 |
int (kbc_restore_kbd)(){ |
30 |
int ret = 0; |
|
25 | 31 |
uint8_t cmd = 0; |
26 |
if(kbc_read_cmd(&cmd)) return 1;
|
|
32 |
if((ret = kbc_read_cmd(&cmd))) return ret;
|
|
27 | 33 |
cmd = (cmd | INT_KBD) & (~DIS_KBD) ; |
28 |
if(kbc_change_cmd(cmd)) return 1;
|
|
29 |
return 0;
|
|
34 |
if((ret = kbc_change_cmd(cmd))) return ret;
|
|
35 |
return SUCCESS;
|
|
30 | 36 |
} |
31 | 37 |
|
32 | 38 |
int (kbc_issue_cmd)(uint8_t cmd){ |
39 |
int ret = 0; |
|
33 | 40 |
uint8_t stat; |
34 | 41 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
35 |
if(util_sys_inb(STATUS_REG, &stat)) return 1;
|
|
42 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
|
|
36 | 43 |
if((stat&IN_BUF_FULL) == 0){ |
37 |
if(sys_outb(KBC_CMD, cmd)) return 1;
|
|
38 |
return 0;
|
|
44 |
if(sys_outb(KBC_CMD, cmd)) return WRITE_ERROR;
|
|
45 |
return SUCCESS;
|
|
39 | 46 |
} |
40 | 47 |
tickdelay(micros_to_ticks(DELAY)); |
41 | 48 |
} |
42 |
return 1;
|
|
49 |
return TIMEOUT_ERROR;
|
|
43 | 50 |
} |
44 | 51 |
|
52 |
int (kbc_issue_arg)(uint8_t arg){ |
|
53 |
int ret = 0; |
|
54 |
uint8_t stat; |
|
55 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
|
56 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
57 |
if((stat&IN_BUF_FULL) == 0){ |
|
58 |
if(sys_outb(KBC_CMD_ARG, arg)) return WRITE_ERROR; |
|
59 |
return SUCCESS; |
|
60 |
} |
|
61 |
tickdelay(micros_to_ticks(DELAY)); |
|
62 |
} |
|
63 |
return TIMEOUT_ERROR; |
|
64 |
} |
|
65 |
|
|
45 | 66 |
int (kbc_read_byte)(uint8_t *byte){ |
67 |
int ret = 0; |
|
46 | 68 |
uint8_t stat; |
47 |
while(true){
|
|
48 |
if(util_sys_inb(STATUS_REG, &stat)) return 1;
|
|
69 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){
|
|
70 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
|
|
49 | 71 |
if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){ |
50 | 72 |
if(stat & (PARITY_ERROR | TIME_OUT_REC)) return 1; |
51 |
if(util_sys_inb(OUTPUT_BUF, byte)) return 1;
|
|
52 |
else return 0;
|
|
73 |
if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
|
|
74 |
else return SUCCESS;
|
|
53 | 75 |
} |
54 | 76 |
tickdelay(micros_to_ticks(DELAY)); |
55 | 77 |
} |
78 |
return TIMEOUT_ERROR; |
|
56 | 79 |
} |
lab4/kbc.h | ||
---|---|---|
1 |
#ifndef _KBC_FUNC_H_ |
|
2 |
#define _KBC_FUNC_H_ |
|
3 |
|
|
4 |
#include <stdint.h> |
|
5 |
|
|
6 |
#define GET 0 /* @brief Argument to get counter without incrementing */ |
|
7 |
#define INCREMENT 1 /* @brief Argument for incrementing counter */ |
|
8 |
|
|
9 | 1 |
/** |
10 |
* @brief Subscribes KBC Interrupts and disables Minix Default Keyboard IH |
|
11 |
* @param interrupt_bit Bit of Interrupt Vector that will be set when KBC Interrupt is pending |
|
12 |
* @param interrupt_id KBC Interrupt ID to specify the KBC Interrupt in other calls |
|
13 |
* @return Whether operation was sucessful or not |
|
2 |
* This file concerns everything related to the KBC (KeyBoard Controller, which |
|
3 |
* actually also manages the mouse) |
|
14 | 4 |
*/ |
15 |
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id); |
|
16 | 5 |
|
6 |
#ifndef KBC_H_INCLUDED |
|
7 |
#define KBC_H_INCLUDED |
|
8 |
|
|
17 | 9 |
/** |
18 | 10 |
* @brief Unsubcribes Interrupts |
19 | 11 |
* @param interrupt_id Interrupt ID, value via arguments on subscription of the interrupt_id |
... | ... | |
23 | 15 |
int (unsubscribe_interrupt)(int *interrupt_id); |
24 | 16 |
|
25 | 17 |
/** |
26 |
* @brief KBC Interrupt Handler |
|
27 |
*/ |
|
28 |
void (kbc_ih)(void); |
|
29 |
|
|
30 |
/** |
|
31 |
* @brief High-level function that polls keyboard for scancode |
|
32 |
* High-level function that polls keyboard for scancode of up to 2 bytes. If |
|
33 |
* scancode has only 1 byte, the second byte is set to 0x00. |
|
34 |
* @param bytes Array of at least 2 bytes to store scancode |
|
35 |
* @param size Size of scancode in bytes |
|
36 |
* @return 0 if operation was successful, 1 otherwise |
|
37 |
*/ |
|
38 |
int (kbd_poll)(uint8_t bytes[], uint8_t *size); |
|
39 |
|
|
40 |
/** |
|
41 | 18 |
* @brief High-level function that reads the command byte of the KBC |
42 | 19 |
* @param cmd Pointer to variable where command byte read from KBC will be stored |
43 | 20 |
* @return 0 if operation was successful, 1 otherwise |
... | ... | |
58 | 35 |
* chance that the keyboard and keyboard interrupts remain disabled. |
59 | 36 |
* @return 1 if operation was successful, 1 otherwise |
60 | 37 |
*/ |
61 |
int (kbc_restore_kbd)();
|
|
38 |
int (kbc_restore_keyboard)();
|
|
62 | 39 |
|
63 | 40 |
/** |
64 | 41 |
* @brief Low-level function to issue a command to keyboard |
... | ... | |
68 | 45 |
int (kbc_issue_cmd)(uint8_t cmd); |
69 | 46 |
|
70 | 47 |
/** |
48 |
* @brief Low-level function to issue an argument of a command |
|
49 |
* @param cmd argument to be issued |
|
50 |
* @return 0 if operation was successful, 1 otherwise |
|
51 |
*/ |
|
52 |
int (kbc_issue_arg)(uint8_t arg); |
|
53 |
|
|
54 |
/** |
|
71 | 55 |
* @brief Low-level function for reading byte from keyboard |
72 | 56 |
* Low-level function for reading byte from keyboard. Waits until output buffer |
73 | 57 |
* is full |
... | ... | |
76 | 60 |
*/ |
77 | 61 |
int (kbc_read_byte)(uint8_t *byte); |
78 | 62 |
|
79 |
|
|
80 |
#endif |
|
63 |
#endif //KBC_H_INCLUDED |
lab4/kbc_macros.h | ||
---|---|---|
1 |
#ifndef _KBC_H_
|
|
2 |
#define _KBC_H_
|
|
1 |
#ifndef KBC_MACROS_H_INCLUDED
|
|
2 |
#define KBC_MACROS_H_INCLUDED
|
|
3 | 3 |
|
4 | 4 |
/* KBC IRQ Line */ |
5 | 5 |
|
... | ... | |
53 | 53 |
#define DIS_KBD BIT(4) /* @brief Disable Keyboard */ |
54 | 54 |
#define DIS_MOU BIT(5) /* @brief Disable Mouse */ |
55 | 55 |
|
56 |
#endif |
|
56 |
#endif //KBC_MACROS_H_INCLUDED |
lab4/keyboard.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "keyboard.h" |
|
4 |
|
|
5 |
#include "kbc.h" |
|
6 |
#include "kbc_macros.h" |
|
7 |
#include "utils.h" |
|
8 |
#include "errors.h" |
|
9 |
|
|
10 |
int (subscribe_kbc_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(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR; |
|
14 |
return SUCCESS; |
|
15 |
} |
|
16 |
|
|
17 |
int done = 1; |
|
18 |
int sz = 1; |
|
19 |
int got_error_keyboard = SUCCESS; |
|
20 |
|
|
21 |
void (kbc_ih)(void) { |
|
22 |
if(done) sz = 1; |
|
23 |
else sz++; |
|
24 |
uint8_t status = 0; |
|
25 |
got_error_keyboard = SUCCESS; |
|
26 |
if ((got_error_keyboard = util_sys_inb(STATUS_REG, &status))) return; |
|
27 |
if (status & (TIME_OUT_REC | PARITY_ERROR)) { |
|
28 |
got_error_keyboard = 1; |
|
29 |
return; |
|
30 |
} |
|
31 |
if ((status & OUT_BUF_FUL) == 0 || (status & AUX_MOUSE) != 0) { |
|
32 |
got_error_keyboard = OTHER_ERROR; |
|
33 |
return; |
|
34 |
} |
|
35 |
uint8_t byte = 0; |
|
36 |
if ((got_error_keyboard = util_sys_inb(OUTPUT_BUF, &byte))) return; |
|
37 |
|
|
38 |
scancode[sz-1] = byte; |
|
39 |
done = !(TWO_BYTE_CODE == byte); |
|
40 |
} |
|
41 |
|
|
42 |
int (keyboard_poll)(uint8_t bytes[], uint8_t *size){ |
|
43 |
int ret = 0; |
|
44 |
if(bytes == NULL || size == NULL) return NULL_PTR; |
|
45 |
uint8_t c; |
|
46 |
if((ret = kbc_read_byte(&c))) return ret; |
|
47 |
if(c == TWO_BYTE_CODE){ |
|
48 |
if((ret = kbc_read_byte(&bytes[1]))) return ret; |
|
49 |
bytes[0] = c; |
|
50 |
*size = 2; |
|
51 |
}else{ |
|
52 |
bytes[1] = 0; |
|
53 |
bytes[0] = c; |
|
54 |
*size = 1; |
|
55 |
} |
|
56 |
return SUCCESS; |
|
57 |
} |
|
0 | 58 |
lab4/keyboard.h | ||
---|---|---|
1 |
/** |
|
2 |
* This file concerns everything related to the keyboard |
|
3 |
*/ |
|
4 |
|
|
5 |
#ifndef KEYBOARD_H_INCLUDED |
|
6 |
#define KEYBOARD_H_INCLUDED |
|
7 |
|
|
8 |
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id); |
|
9 |
|
|
10 |
uint8_t scancode[2]; |
|
11 |
int done; |
|
12 |
int sz; |
|
13 |
int got_error_keyboard; |
|
14 |
|
|
15 |
void (kbc_ih)(void); |
|
16 |
|
|
17 |
int (keyboard_poll)(uint8_t bytes[], uint8_t *size); |
|
18 |
|
|
19 |
#endif //KEYBOARD_H_INCLUDED |
|
0 | 20 |
lab4/mouse.c | ||
---|---|---|
23 | 23 |
got_error_mouse_ih = 0; |
24 | 24 |
if(counter >= 3) counter = 0; |
25 | 25 |
|
26 |
if (util_sys_inb(STATUS_REG, &status)) { |
|
27 |
got_error_mouse_ih = 1; |
|
28 |
return; |
|
29 |
} |
|
26 |
if ((got_error_mouse_ih = util_sys_inb(STATUS_REG, &status))) return; |
|
30 | 27 |
|
31 | 28 |
if (status & (TIME_OUT_REC | PARITY_ERROR)) { |
32 |
got_error_mouse_ih = 1;
|
|
29 |
got_error_mouse_ih = OTHER_ERROR;
|
|
33 | 30 |
return; |
34 | 31 |
} |
35 | 32 |
|
36 | 33 |
uint8_t byte = 0; |
37 | 34 |
|
38 |
if (util_sys_inb(OUTPUT_BUF, &byte)) { |
|
39 |
got_error_mouse_ih = 1; |
|
40 |
return; |
|
41 |
} |
|
35 |
if ((got_error_mouse_ih = util_sys_inb(OUTPUT_BUF, &byte))) return; |
|
42 | 36 |
|
43 | 37 |
/// This does not run if: I was expecting the first one but what I get is definitely not the first byte |
44 | 38 |
if((byte & FIRST_BYTE_ID) || counter){ |
... | ... | |
65 | 59 |
int (mouse_set_data_report)(int on){ |
66 | 60 |
int ret = 0; |
67 | 61 |
if((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret; |
68 |
if(sys_outb(KBC_CMD_ARG, DIS_DATA_REP)) return WRITE_ERROR;
|
|
62 |
if((ret = kbc_issue_arg(DIS_DATA_REP))) return ret;
|
|
69 | 63 |
return SUCCESS; |
70 | 64 |
} |
lab4/mouse.h | ||
---|---|---|
1 |
#ifndef _MOUSE_FUNC_H_
|
|
2 |
#define _MOUSE_FUNC_H_
|
|
1 |
#ifndef MOUSE_H_INCLUDED
|
|
2 |
#define MOUSE_H_INCLUDED
|
|
3 | 3 |
|
4 | 4 |
#include <stdint.h> |
5 | 5 |
|
... | ... | |
16 | 16 |
|
17 | 17 |
int (mouse_set_data_report)(int on); |
18 | 18 |
|
19 |
#endif /* end of include guard: _MOUSE_FUNC_H_ */ |
|
19 |
#endif //MOUSE_H_INCLUDED |
lab4/mouse_macros.h | ||
---|---|---|
1 |
#ifndef _MOUSE_H_
|
|
2 |
#define _MOUSE_H_
|
|
1 |
#ifndef MOUSE_MACROS_H_INCLUDED
|
|
2 |
#define MOUSE_MACROS_H_INCLUDED
|
|
3 | 3 |
|
4 | 4 |
/* Mouse Data Packet */ |
5 | 5 |
// Byte 0 - Button States |
... | ... | |
34 | 34 |
#define ACK_INVALID 0xFE /* @brief Invalid Byte, first occurence */ |
35 | 35 |
#define ACK_ERROR 0xFC /* @brief Invalid Byte on resend */ |
36 | 36 |
|
37 |
#endif // _MOUSE_H_ |
|
37 |
#endif // MOUSE_MACROS_H_INCLUDED |
lab4/utils.c | ||
---|---|---|
1 | 1 |
#include <lcom/lcf.h> |
2 | 2 |
|
3 |
#include "utils.h" |
|
4 |
|
|
3 | 5 |
#include <stdint.h> |
6 |
#include "errors.h" |
|
4 | 7 |
|
5 | 8 |
int(util_get_LSB)(uint16_t val, uint8_t *lsb) { |
6 |
if (lsb == NULL) return 1;
|
|
9 |
if (lsb == NULL) return NULL_PTR;
|
|
7 | 10 |
*lsb = val; |
8 |
return 0;
|
|
11 |
return SUCCESS;
|
|
9 | 12 |
} |
10 | 13 |
|
11 | 14 |
int(util_get_MSB)(uint16_t val, uint8_t *msb) { |
12 |
if (msb == NULL) return 1;
|
|
15 |
if (msb == NULL) return NULL_PTR;
|
|
13 | 16 |
*msb = (val >> 8); |
14 |
return 0;
|
|
17 |
return SUCCESS;
|
|
15 | 18 |
} |
16 | 19 |
|
17 | 20 |
#ifdef LAB3 |
... | ... | |
19 | 22 |
#endif |
20 | 23 |
|
21 | 24 |
int (util_sys_inb)(int port, uint8_t *value) { |
22 |
if(value == NULL) return 1;
|
|
25 |
if(value == NULL) return NULL_PTR;
|
|
23 | 26 |
uint32_t n = 0; |
24 |
if(sys_inb(port, &n)) return 1;
|
|
27 |
if(sys_inb(port, &n)) return READ_ERROR;
|
|
25 | 28 |
*value = n; |
26 | 29 |
#ifdef LAB3 |
27 | 30 |
++sys_inb_counter; |
28 | 31 |
#endif |
29 |
return 0;
|
|
32 |
return SUCCESS;
|
|
30 | 33 |
} |
lab4/utils.h | ||
---|---|---|
1 |
#ifndef UTILS_H_INCLUDED |
|
2 |
#define UTILS_H_INCLUDED |
|
3 |
|
|
4 |
int(util_get_LSB)(uint16_t val, uint8_t *lsb); |
|
5 |
|
|
6 |
int(util_get_MSB)(uint16_t val, uint8_t *msb); |
|
7 |
|
|
8 |
#ifdef LAB3 |
|
9 |
uint32_t sys_inb_counter; |
|
10 |
#endif |
|
11 |
|
|
12 |
int (util_sys_inb)(int port, uint8_t *value); |
|
13 |
|
|
14 |
#endif //UTILS_H_INCLUDED |
|
0 | 15 |
Also available in: Unified diff