Project

General

Profile

Revision 58

more changes

View differences:

lab4/mouse_func.c
1
#include "mouse_func.h"
2
#include "errors.h"
3
#include "kbc.h"
4
#include "mouse.h"
5

  
6
#include <lcom/lcf.h>
7

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

  
15
int got_error_mouse_ih = 0;
16
uint8_t packet[3];
17
int counter = 0;
18

  
19
void (mouse_ih)(void) {
20
    uint8_t status = 0;
21
    got_error_mouse_ih = 0;
22

  
23
    if (util_sys_inb(STATUS_REG, &status)) {
24
        got_error_mouse_ih = 1;
25
        return;
26
    }
27

  
28
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
29
        got_error_mouse_ih = 1;
30
        return;
31
    }
32

  
33
    uint8_t byte = 0;
34

  
35
    if (util_sys_inb(OUTPUT_BUF, &byte)) {
36
        got_error_mouse_ih = 1;
37
        return;
38
    }
39

  
40
    if(counter >= 3) counter = 0;
41
    packet[counter] = byte;
42
    counter++;
43

  
44
}
45

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

  
lab4/mouse_func.h
1
#ifndef _MOUSE_FUNC_H_
2
#define _MOUSE_FUNC_H_
3

  
4
#include <stdint.h>
5

  
6
/**
7
 * @brief Subscribes Mouse Interrupts and disables Minix Default IH
8
 * @param interrupt_bit Bit of Interrupt Vector that will be set when Mouse Interrupt is pending
9
 * @param interrupt_id Mouse Interrupt ID to specify the Mouse Interrupt in other calls
10
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
11
 * @see {_ERRORS_H_::errors}
12
 */
13
int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
14

  
15
struct packet (mouse_parse_packet)(const uint8_t *packet_bytes);
16

  
17
#endif /* end of include guard: _MOUSE_FUNC_H_ */
18 0

  
lab4/Makefile
2 2
PROG=lab4
3 3

  
4 4
# source code files to be compiled
5
SRCS = lab4.c mouse_func.c utils.c kbc_func.c
5
SRCS = lab4.c mouse.c utils.c kbc.c kbd.c
6 6

  
7 7
# additional compilation flags
8 8
# "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set
lab4/kbc.h
1
#ifndef _KBC_H_
2
#define _KBC_H_
1
#ifndef _KBC_FUNC_H_
2
#define _KBC_FUNC_H_
3 3

  
4
/* KBC IRQ Line */
4
#include <stdint.h>
5 5

  
6
#define KBC_IRQ     1   /* @brief KBC Controller IRQ Line */
7
#define MOUSE_IRQ   12  /* @brief Mouse IRQ Line */
6
#define GET         0 /* @brief Argument to get counter without incrementing */
7
#define INCREMENT   1 /* @brief Argument for incrementing counter */
8 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 */
9
/**
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
14
 */
15
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
12 16

  
13
/* I/O Ports Addresses */
17
/**
18
 * @brief Unsubcribes Interrupts
19
 * @param interrupt_id Interrupt ID, value via arguments on subscription of the interrupt_id
20
 * @see subscribe_kbc_interrupt, subscribe_timer_interrupt
21
 * @return Whether operation was sucessful or not
22
 */
23
int (unsubscribe_interrupt)(int *interrupt_id);
14 24

  
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 */
25
/**
26
 * @brief KBC Interrupt Handler
27
 */
28
void (kbc_ih)(void);
18 29

  
19
#define OUTPUT_BUF  0x60 /* @brief Address of Output Buffer of KBC */
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);
20 39

  
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 */
40
/**
41
 * @brief High-level function that reads the command byte of the KBC
42
 * @param cmd Pointer to variable where command byte read from KBC will be stored
43
 * @return 0 if operation was successful, 1 otherwise
44
 */
45
int (kbc_read_cmd)(uint8_t *cmd);
32 46

  
33
/* Status Byte Masking */
47
/**
48
 * @brief High-level function that changes the command byte of the KBC
49
 * @param cmd New value for command byte of KBC
50
 * @return 0 if operation was successful, 1 otherwise
51
 */
52
int (kbc_change_cmd)(uint8_t cmd);
34 53

  
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 */
54
/**
55
 * @brief High-level function that restores KBC to normal state
56
 * High-level function that restores KBC to normal state, because lcf_start
57
 * changes the command byte of KBC. If this function is not used, there is a
58
 * chance that the keyboard and keyboard interrupts remain disabled.
59
 * @return 1 if operation was successful, 1 otherwise
60
 */
61
int (kbc_restore_kbd)();
43 62

  
44
/* Scancode Constants */
63
/**
64
 * @brief Low-level function to issue a command to keyboard
65
 * @param cmd command to be issued
66
 * @return 0 if operation was successful, 1 otherwise
67
 */
68
int (kbc_issue_cmd)(uint8_t cmd);
45 69

  
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 */
70
/**
71
 * @brief Low-level function for reading byte from keyboard
72
 * Low-level function for reading byte from keyboard. Waits until output buffer
73
 * is full
74
 * @param value Pointer to variable where byte read from keyboard will be stored
75
 * @return 0 if operation was successful, 1 otherwise
76
 */
77
int (kbc_read_byte)(uint8_t *byte);
49 78

  
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 79

  
56 80
#endif
lab4/lab4.c
3 3
#include <stdint.h>
4 4
#include <stdio.h>
5 5

  
6
#include "mouse_func.h"
7
#include "kbc_func.h"
6
#include "mouse.h"
7
#include "kbc.h"
8 8

  
9 9
int main(int argc, char *argv[]) {
10 10
  // sets the language of LCF messages (can be either EN-US or PT-PT)
......
63 63
                            cnt_now++;
64 64
                            if(cnt == cnt_now) good = 0;
65 65
                        }
66
                        /*
67
                        if (!(two_byte_scancode || got_error)) { // finished processing a scancode
68
                            if (scancode[0] == TWO_BYTE_CODE) kbd_print_scancode(!(scancode[1] & BREAK_CODE_BIT), 2, scancode);
69
                            else                              kbd_print_scancode(!(scancode[0] & BREAK_CODE_BIT), 1, scancode);
70
                        } else { break; }
71
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
72
                        */
73 66
                    }
74 67
                    break;
75 68
                default:
......
81 74
    }
82 75

  
83 76
    if (unsubscribe_interrupt(&mouse_id)) return 1;
84
    if(kbc_restore_kbd()) return 1;
85 77

  
78
    if(mouse_set_data_report(false)) return 1;
79

  
86 80
    return 0;
87 81
}
88 82

  
lab4/mouse.h
1
#ifndef _MOUSE_H_
2
#define _MOUSE_H_
1
#ifndef _MOUSE_FUNC_H_
2
#define _MOUSE_FUNC_H_
3 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
4
#include <stdint.h>
16 5

  
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 */
6
/**
7
 * @brief Subscribes Mouse Interrupts and disables Minix Default IH
8
 * @param interrupt_bit Bit of Interrupt Vector that will be set when Mouse Interrupt is pending
9
 * @param interrupt_id Mouse Interrupt ID to specify the Mouse Interrupt in other calls
10
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
11
 * @see {_ERRORS_H_::errors}
12
 */
13
int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
31 14

  
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 */
15
struct packet (mouse_parse_packet)(const uint8_t *packet_bytes);
36 16

  
37
#endif // _MOUSE_H_
17
int (mouse_set_data_report)(int on);
18

  
19
#endif /* end of include guard: _MOUSE_FUNC_H_ */

Also available in: Unified diff