Project

General

Profile

Revision 278

organizing stuff

View differences:

proj/include/mouse.h
1
#ifndef MOUSE_H_INCLUDED
2
#define MOUSE_H_INCLUDED
3

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

  
13
//These have to do with mouse_ih
14
int got_error_mouse_ih;
15
uint8_t packet_mouse_ih[3];
16
int counter_mouse_ih;
17

  
18
/**
19
 * @brief   Parse 3 bytes and returns it as a parsed, struct packet.
20
 * @param   packet_bytes    array of bytes to parse
21
 * @param   pp              Pointer to packet to store the information.
22
 */
23
void (mouse_parse_packet)(const uint8_t *packet_bytes, struct packet *pp);
24

  
25
/**
26
 * @brief Polls mouse for data. Blocks execution until a valid mouse packet is obtained.
27
 * @param   pp      pointer to packet struct in which the result will be stored
28
 * @param   period  time (in milliseconds) the poller should wait between pollings of bytes
29
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
30
 */
31
int mouse_poll(struct packet *pp, uint16_t period);
32

  
33
/**
34
 * @brief Sets data report mode for mouse
35
 * @param   on  zero to disable data report, any other value to enable data report
36
 * @return  ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
37
 */
38
int (mouse_set_data_report)(int on);
39

  
40
/**
41
 * @brief Reads data byte from mouse
42
 * <summary>
43
 * Polls the mouse till data is available for reading
44
 * </summary>
45
 * @param data Pointer to variable where byte read from mouse will be stored
46
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
47
 * @see {_ERRORS_H_::errors}
48
 */
49
int (mouse_read_data)(uint8_t *data, uint16_t period);
50

  
51
/**
52
 * @brief Issues command to mouse
53
 * <summary>
54
 * Issues command to mouse, returns error after two consecutive errors reported by the acknowledgment byte
55
 * </summary>
56
 * @param cmd Command to be issued
57
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
58
 * @see {_ERRORS_H_::errors}
59
 */
60
int (mouse_issue_cmd)(uint32_t cmd);
61

  
62
/**
63
 * @brief Reads byte from mouse
64
 * <summary>
65
 * Reads byte from mouse, giving error if exceeds number of tries to read
66
 * </summary>
67
 * @param byte Pointer to variable where byte read from mouse will be stored
68
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
69
 * @see {_ERRORS_H_::errors}
70
 */
71
int (mouse_read_byte)(uint8_t *byte);
72

  
73
/**
74
 * @brief Polls OUT_BUF for byte coming from mouse.
75
 * @param   byte    pointer to byte read from OUT_BUF
76
 * @param   period  time (in milliseconds) the poller should wait between pollings of bytes
77
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
78
 */
79
int (mouse_poll_byte)(uint8_t *byte, uint16_t period);
80

  
81
/**
82
 * @brief Converts 9-bit number to 16-bit with sign extension
83
 * @param sign_bit  Sign bit identifiying the signal of the number
84
 * @param byte      Least significant byte that will be extended
85
 * @return Extended 9-bit number
86
 */
87
int16_t (sign_extend_byte)(uint8_t sign_bit, uint8_t byte);
88

  
89
#endif //MOUSE_H_INCLUDED
90 0

  
proj/include/kbc.h
1
/**
2
 * This file concerns everything related to the KBC (KeyBoard Controller, which
3
 * actually also manages the mouse)
4
 */
5

  
6
#ifndef KBC_H_INCLUDED
7
#define KBC_H_INCLUDED
8

  
9
/* KBC IRQ Line */
10

  
11
#define KBC_IRQ     1   /* @brief KBC Controller IRQ Line */
12
#define MOUSE_IRQ   12  /* @brief Mouse IRQ Line */
13

  
14
/* Delay for KBC */
15
#define DELAY           20000 /* @brief KBC Response Delay */
16
#define KBC_NUM_TRIES   20    /* @brief Number of tries to issue command before timeout */
17

  
18
/* I/O Ports Addresses */
19

  
20
#define KBC_CMD     0x64 /* @brief Address to send commands to KBC */
21
#define KBC_CMD_ARG 0x60 /* @brief Address to write KBC Command Arguments */
22
#define STATUS_REG  0x64 /* @brief KBC Status Register address */
23

  
24
#define OUTPUT_BUF  0x60 /* @brief Address of Output Buffer of KBC */
25

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

  
38
/* Status Byte Masking */
39

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

  
49
/* Scancode Constants */
50

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

  
55
/* Command byte masks */
56
#define INT_KBD         BIT(0)  /* @brief Enable Keyboard Interrupts */
57
#define INT_MOU         BIT(1)  /* @brief Enable Mouse Interrupts */
58
#define DIS_KBD         BIT(4)  /* @brief Disable Keyboard */
59
#define DIS_MOU         BIT(5)  /* @brief Disable Mouse */
60

  
61
/**
62
 * @brief High-level function that reads the command byte of the KBC
63
 * @param cmd Pointer to variable where command byte read from KBC will be stored
64
 * @return 0 if operation was successful, 1 otherwise
65
 */
66
int (kbc_read_cmd)(uint8_t *cmd);
67

  
68
/**
69
 * @brief High-level function that changes the command byte of the KBC
70
 * @param cmd New value for command byte of KBC
71
 * @return 0 if operation was successful, 1 otherwise
72
 */
73
int (kbc_change_cmd)(uint8_t cmd);
74

  
75
/**
76
 * @brief High-level function that restores KBC to normal state
77
 * High-level function that restores KBC to normal state, because lcf_start
78
 * changes the command byte of KBC. If this function is not used, there is a
79
 * chance that the keyboard and keyboard interrupts remain disabled.
80
 * @return 0 if operation was successful, 1 otherwise
81
 */
82
int (kbc_restore_keyboard)();
83

  
84
/**
85
 * @brief Low-level function to issue a command to keyboard
86
 * @param cmd command to be issued
87
 * @return 0 if operation was successful, 1 otherwise
88
 */
89
int (kbc_issue_cmd)(uint8_t cmd);
90

  
91
/**
92
 * @brief Low-level function to issue an argument of a command
93
 * @param cmd argument to be issued
94
 * @return 0 if operation was successful, 1 otherwise
95
 */
96
int (kbc_issue_arg)(uint8_t arg);
97

  
98
/**
99
 * @brief Low-level function for reading byte from keyboard
100
 * Low-level function for reading byte from keyboard. Waits until output buffer
101
 * is full
102
 * @param value Pointer to variable where byte read from keyboard will be stored
103
 * @return 0 if operation was successful, 1 otherwise
104
 */
105
int (kbc_read_byte)(uint8_t *byte);
106

  
107
#endif //KBC_H_INCLUDED
108 0

  
proj/include/uart.h
1
#ifndef UART_H_INCLUDED
2
#define UART_H_INCLUDED
3

  
4
#define COM1_ADDR           0x3F8
5
#define COM2_ADDR           0x2F8
6
#define COM1_IRQ            4
7
#define COM2_IRQ            3
8
#define COM1_VECTOR         0x0C
9
#define COM2_VECTOR         0x0B
10

  
11
typedef enum {
12
    uart_parity_none = 0x0,
13
    uart_parity_odd  = 0x1,
14
    uart_parity_even = 0x3,
15
    uart_parity_par1 = 0x5,
16
    uart_parity_par0 = 0x7
17
} uart_parity;
18

  
19
typedef struct {
20
    int     base_addr               ;
21
    uint8_t lcr                     ;
22
    uint8_t dll                     ;
23
    uint8_t dlm                     ;
24
    uint8_t bits_per_char           ;
25
    uint8_t stop_bits               ;
26
    uart_parity parity              ;
27
    uint8_t break_control         :1;
28
    uint8_t dlab                  :1;
29
    uint16_t divisor_latch          ;
30
    uint8_t ier                     ;
31
    uint8_t received_data_int     :1;
32
    uint8_t transmitter_empty_int :1;
33
    uint8_t receiver_line_stat_int:1;
34
    uint8_t modem_stat_int        :1;
35
} uart_config;
36

  
37
int (subscribe_uart_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
38

  
39
int uart_get_config(int base_addr, uart_config *config);
40
void uart_print_config(uart_config config);
41

  
42
int uart_set_bits_per_character(int base_addr, uint8_t     bits_per_char);
43
int uart_set_stop_bits         (int base_addr, uint8_t     stop         );
44
int uart_set_parity            (int base_addr, uart_parity par          );
45
int uart_set_bit_rate          (int base_addr, float       bit_rate     );
46

  
47
int uart_enable_int_rx (int base_addr);
48
int uart_disable_int_rx(int base_addr);
49
int uart_enable_int_tx (int base_addr);
50
int uart_disable_int_tx(int base_addr);
51

  
52
#endif //UART_H_INCLUDED
53 0

  
proj/include/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
#include "kbc.h"
9

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

  
19
uint8_t scancode[2];
20
int done;
21
int sz;
22
int got_error_keyboard;
23

  
24
void (kbc_ih)(void);
25

  
26
int (keyboard_poll)(uint8_t bytes[], uint8_t *size);
27

  
28
#endif //KEYBOARD_H_INCLUDED
29 0

  
proj/include/rtc.h
1
#ifndef RTC_H_INCLUDED
2
#define RTC_H_INCLUDED
3

  
4
#include <stdint.h>
5

  
6
/**
7
 * @brief Subscribes RTC Interrupts
8
 * @param interrupt_bit Bit of Interrupt Vector that will be set when RTC Interrupt is pending
9
 * @param interrupt_id RTC Interrupt ID to specify the RTC 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_rtc_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
14

  
15
int (rtc_read_register)(uint32_t reg, uint8_t *data);
16

  
17
int (rtc_write_register)(uint32_t reg, uint8_t data);
18

  
19
/**
20
 * @brief Checks if there's an update in progress.
21
 * @return  The value of the flag UIP, or ERROR_CODE if error occurs.
22
 */
23
int (rtc_check_update)(void);
24

  
25
/**
26
 * @brief Enables/Disables updates of time/date registers.
27
 * @param   on  zero to disable, any other value to enable
28
 * @return  ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
29
 */
30
int (rtc_set_updates)(int on);
31

  
32
/**
33
 * @brief Reads time from RTC.
34
 * @param   time  Pointer to array of 3 bytes to store the information about time (hours, minutes, seconds)
35
 * @return  ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
36
 */
37
int (rtc_read_time)(uint8_t *time);
38

  
39
/**
40
 * @brief Reads date from RTC.
41
 * @param   date  Pointer to array of 4 bytes to store the information about date (year, month, day, weekday)
42
 * @return  ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
43
 */
44
int (rtc_read_date)(uint8_t *date);
45

  
46
#endif /* end of include guard: RTC_H_INCLUDED */
47 0

  
proj/include/timer.h
1
/**
2
 * This file concerns everything related to the timer
3
 */
4

  
5
#ifndef TIMER_H_INCLUDED
6
#define TIMER_H_INCLUDED
7

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

  
10
uint32_t no_interrupts;
11

  
12
#endif //TIMER_H_INCLUDED
13 0

  
proj/include/list.h
1
#ifndef LIST_H_INCLUDED
2
#define LIST_H_INCLUDED
3

  
4
struct list_node;
5
typedef struct list_node list_node_t;
6

  
7
list_node_t* (list_node_ctor)(list_node_t *p, list_node_t *n, void *val);
8
void         (list_node_dtor)(list_node_t *p);
9
list_node_t* (list_node_next)(const list_node_t *p);
10
list_node_t* (list_node_prev)(const list_node_t *p);
11
void**       (list_node_val )(list_node_t *p);
12

  
13
struct list;
14
typedef struct list list_t;
15

  
16
list_t* (list_ctor)(void);
17
int     (list_dtor)(list_t *l);
18
list_node_t* (list_begin )(list_t *l);
19
list_node_t* (list_end   )(list_t *l);
20
size_t       (list_size  )(const list_t *l);
21
int          (list_empty )(const list_t *l);
22
list_node_t* (list_insert)(list_t *l, list_node_t *position, void *val);
23
void*        (list_erase )(list_t *l, list_node_t *position);
24
void         (list_push_back)(list_t *l, void *val);
25
void**       (list_front)(list_t *l);
26
void         (list_pop_front)(list_t *l);
27

  
28
#endif //LIST_H_INCLUDED
29 0

  
proj/include/queue.h
1
#ifndef QUEUE_H_INCLUDED
2
#define QUEUE_H_INCLUDED
3

  
4
struct queue;
5
typedef struct queue queue_t;
6

  
7
const size_t queue_max_size;
8

  
9
queue_t* (queue_ctor )(void);
10
int      (queue_dtor )(queue_t *q);
11
size_t   (queue_size )(const queue_t *q);
12
int      (queue_empty)(const queue_t *q);
13
void     (queue_push )(queue_t *q, void *val);
14
void*    (queue_top  )(const queue_t *q);
15
void     (queue_pop  )(queue_t *q);
16

  
17
#endif //QUEUE_H_INCLUDED
18 0

  
proj/src/keyboard.c
1
#include <lcom/lcf.h>
2

  
3
#include "keyboard.h"
4

  
5
#include "kbc.h"
6
#include "utils.h"
7
#include "errors.h"
8
#include "proj_func.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 = READ_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
    if (done) update_key_presses();
42

  
43
}
44

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

  
proj/src/rtc.c
1
#include <lcom/lcf.h>
2

  
3
#include "rtc.h"
4

  
5
#include "utils.h"
6
#include "errors.h"
7

  
8
// RTC IRQ Line
9

  
10
#define KBC_IRQ   8  /* @brief KBC IRQ Line */
11

  
12
// RTC Ports
13

  
14
#define RTC_ADDR_REG        0x70
15
#define RTC_DATA_REG        0x71
16

  
17
// RTC Registers (Byte)
18

  
19
#define RTC_SEC             0
20
#define RTC_SEC_ALARM       1
21
#define RTC_MIN             2
22
#define RTC_MIN_ALARM       3
23
#define RTC_HOUR            4
24
#define RTC_HOUR_ALARM      5
25
#define RTC_WEEK_DAY        6
26
#define RTC_MONTH_DAY       7
27
#define RTC_MONTH           8
28
#define RTC_YEAR            9
29
#define RTC_REG_A           10
30
#define RTC_REG_B           11
31
#define RTC_REG_C           12
32
#define RTC_REG_D           13
33

  
34
// Register A
35

  
36
#define RS0     BIT(0)  /** @brief Rate selector */
37
#define RS1     BIT(1)  /** @brief Rate selector */
38
#define RS2     BIT(2)  /** @brief Rate selector */
39
#define RS3     BIT(3)  /** @brief Rate selector */
40
#define UIP     BIT(7)  /** @brief Update in progress */
41

  
42
// Register B
43

  
44
#define DSE             BIT(0)  /** @brief Enable Daylight Saving Time */
45
#define HOUR_FORM       BIT(1)  /** @brief Set to 1 for 24h format (0-23), 0 to 12h format (1-12) */
46
#define DM              BIT(2)  /** @brief Set to 1 if registers are in binary, 0 if in BCD */
47
#define SQWE            BIT(3)  /** @brief Enable square wave generation */
48
#define UIE             BIT(4)  /** @brief Enable Update interrupts */
49
#define AIE             BIT(5)  /** @brief Enable alarm interrupts */
50
#define PIE             BIT(6)  /** @brief Enable periodic interrupts */
51
#define SET             BIT(7)  /** @brief Set to 1 to inhibit updates of time/date registers */
52

  
53
// Register C
54

  
55
#define UF      BIT(4)  /** @brief Update Interrupt Pending */
56
#define AF      BIT(5)  /** @brief Alarm Interrupt Pending */
57
#define PF      BIT(6)  /** @brief Periodic Interrupt Pending */
58
#define IRQF    BIT(7)  /** @brief IRQ Line Active */
59

  
60
// Register D
61

  
62
#define VRT     BIT(7)  /** @brief Valid RAM/time - If set to 0 RTC reading aren't valid */
63

  
64
int (subscribe_rtc_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
65
    if (interrupt_id == NULL) return NULL_PTR;
66
    *interrupt_id = interrupt_bit;
67
    if (sys_irqsetpolicy(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR;
68
    return SUCCESS;
69
}
70

  
71
int (rtc_read_register)(uint32_t reg, uint8_t *data) {
72
    if (sys_outb(RTC_ADDR_REG, reg)) return WRITE_ERROR;
73

  
74
    if (util_sys_inb(RTC_DATA_REG, data)) return READ_ERROR;
75

  
76
    return SUCCESS;
77
}
78

  
79
int (rtc_write_register)(uint32_t reg, uint8_t data) {
80
    if (sys_outb(RTC_ADDR_REG, reg)) return WRITE_ERROR;
81

  
82
    if (sys_outb(RTC_DATA_REG, data)) return WRITE_ERROR;
83

  
84
    return SUCCESS;
85
}
86

  
87
int (rtc_check_update)(void) {
88
    uint8_t data;
89
    int r;
90

  
91
    if ((r = rtc_read_register(RTC_REG_A, &data))) return r;
92

  
93
    return (data & UIP) != 0;
94
}
95

  
96
int (rtc_set_updates)(int on) {
97
    uint8_t data;
98
    int r;
99
    if (on) {
100
        if ((r = rtc_read_register(RTC_REG_B, &data))) return r;
101

  
102
        data &= ~SET;
103

  
104
        if ((r = rtc_write_register(RTC_REG_B, data))) return r;
105

  
106
    } else {
107
        while (rtc_check_update());
108

  
109
        if ((r = rtc_read_register(RTC_REG_B, &data))) return r;
110

  
111
        data |= SET;
112

  
113
        if ((r = rtc_write_register(RTC_REG_B, data))) return r;
114
    }
115
    return SUCCESS;
116
}
117

  
118
int (rtc_read_time)(uint8_t *time) {
119

  
120
    int r;
121
    //if ((r = rtc_set_updates(false))) return r;
122
    while (rtc_check_update());
123

  
124
    uint8_t hour, min, sec;
125

  
126
    if ((r = rtc_read_register(RTC_SEC, &sec)))    return r;
127
    if ((r = rtc_read_register(RTC_MIN, &min)))    return r;
128
    if ((r = rtc_read_register(RTC_HOUR, &hour)))  return r;
129

  
130
    //if ((r = rtc_set_updates(true))) return r;
131

  
132
    time[0] = BCD_FIRST(sec)*10   + BCD_SECOND(sec);
133
    time[1] = BCD_FIRST(min)*10   + BCD_SECOND(min);
134
    time[2] = BCD_FIRST(hour)*10  + BCD_SECOND(hour);
135

  
136
    return SUCCESS;
137
}
138

  
139
int (rtc_read_date)(uint8_t *date) {
140
    int r;
141
    //if ((r = rtc_set_updates(false))) return r;
142
    while (rtc_check_update());
143

  
144
    uint8_t year, month, day, weekday;
145

  
146
    if ((r = rtc_read_register(RTC_WEEK_DAY,    &weekday)))     return r;
147
    if ((r = rtc_read_register(RTC_MONTH_DAY,   &day)))         return r;
148
    if ((r = rtc_read_register(RTC_MONTH,       &month)))       return r;
149
    if ((r = rtc_read_register(RTC_YEAR,        &year)))        return r;
150

  
151
    //if ((r = rtc_set_updates(true))) return r;
152

  
153
    date[0] = weekday;
154
    date[1] = BCD_FIRST(day)*10     + BCD_SECOND(day);
155
    date[2] = BCD_FIRST(month)*10   + BCD_SECOND(month);
156
    date[3] = BCD_FIRST(year)*10    + BCD_SECOND(year);
157

  
158
    return SUCCESS;
159
}
160 0

  
proj/src/timer.c
1
#include <lcom/lcf.h>
2

  
3
#include "timer.h"
4
#include "graph.h"
5
#include "sprite.h"
6

  
7
#include "i8254.h"
8

  
9
int (subscribe_timer_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
10
    if (interrupt_id == NULL) return 1;
11
    *interrupt_id = interrupt_bit;
12
    return (sys_irqsetpolicy(TIMER0_IRQ, IRQ_REENABLE, interrupt_id));
13
}
14

  
15
uint32_t no_interrupts = 0;
16
void (timer_int_handler)() {
17
    no_interrupts++;
18
}
19 0

  
proj/src/list.c
1
#include <lcom/lcf.h>
2

  
3
#include "list.h"
4

  
5
struct list_node{
6
    list_node_t *p, *n;
7
    void *val;
8
};
9
list_node_t* (list_node_ctor)(list_node_t *p, list_node_t *n, void *val){
10
    list_node_t *ret = malloc(sizeof(list_node_t));
11
    if(ret == NULL) return NULL;
12
    ret->p = p;
13
    ret->n = n;
14
    ret->val = val;
15
    return ret;
16
}
17
void (list_node_dtor)(list_node_t *p){
18
    free(p);
19
}
20
list_node_t* (list_node_next)(const list_node_t *p){ return p->n; }
21
list_node_t* (list_node_prev)(const list_node_t *p){ return p->p; }
22
void**       (list_node_val )(list_node_t *p){ return &p->val; }
23

  
24
struct list{
25
    list_node_t *begin_;
26
    list_node_t *end_;
27
    size_t sz;
28
};
29
list_t* (list_ctor)(void){
30
    list_t *ret = malloc(sizeof(list_t));
31
    if(ret == NULL) return NULL;
32
    ret->sz = 0;
33
    ret->begin_ = NULL; ret->end_ = NULL;
34
    ret->begin_ = list_node_ctor(NULL, NULL, NULL);
35
    ret->end_   = list_node_ctor(NULL, NULL, NULL);
36
    if(ret->begin_ == NULL || ret->end_ == NULL){
37
        list_dtor(ret);
38
        return NULL;
39
    }
40
    ret->begin_->n = ret->end_  ;
41
    ret->end_  ->p = ret->begin_;
42
    return ret;
43
}
44
int (list_dtor)(list_t *l){
45
    if(l == NULL) return 0;
46
    if(list_size(l) > 0) return 1;
47
    list_node_dtor(l->begin_);
48
    list_node_dtor(l->end_);
49
    free(l);
50
    return 0;
51
}
52
list_node_t* (list_begin )(      list_t *l){ return l->begin_->n; }
53
list_node_t* (list_end   )(      list_t *l){ return l->end_; }
54
size_t       (list_size  )(const list_t *l){ return l->sz; }
55
int          (list_empty )(const list_t *l){ return !(l->sz); }
56
list_node_t* (list_insert)(list_t *l, list_node_t *position, void *val){
57
    list_node_t *node = list_node_ctor(position->p, position, val);
58
    position->p->n = node;
59
    position->p    = node;
60
    ++l->sz;
61
    return node;
62
}
63
void*        (list_erase )(list_t *l, list_node_t *position){
64
    position->p->n = position->n;
65
    position->n->p = position->p;
66
    void *ret = position->val;
67
    list_node_dtor(position);
68
    --l->sz;
69
    return ret;
70
}
71
void         (list_push_back)(list_t *l, void *val){
72
    list_insert(l, list_end(l), val);
73
}
74
void**       (list_front)(list_t *l){
75
    return list_node_val(list_begin(l));
76
}
77
void         (list_pop_front)(list_t *l){
78
    list_erase(l, list_begin(l));
79
}
80 0

  
proj/src/queue.c
1
#include <lcom/lcf.h>
2

  
3
#include "queue.h"
4

  
5
#include "list.h"
6
#include "errors.h"
7

  
8
const size_t queue_max_size = UINT_MAX;
9

  
10
struct queue{
11
    list_t *l;
12
};
13

  
14
queue_t* (queue_ctor )(void){
15
    queue_t *ret = malloc(sizeof(queue_t));
16
    if(ret == NULL) return NULL;
17
    ret->l = list_ctor();
18
    if(ret->l == NULL){
19
        queue_dtor(ret);
20
        return NULL;
21
    }
22
    return ret;
23
}
24
int      (queue_dtor )(queue_t *q){
25
    int r;
26
    if((r = list_dtor(q->l))) return r;
27
    free(q);
28
    return SUCCESS;
29
}
30
size_t   (queue_size )(const queue_t *q           ){ return list_size (q->l); }
31
int      (queue_empty)(const queue_t *q           ){ return list_empty(q->l); }
32
void     (queue_push )(      queue_t *q, void *val){ list_push_back(q->l, val); }
33
void*    (queue_top  )(const queue_t *q           ){ return *list_front(q->l); }
34
void     (queue_pop  )(      queue_t *q           ){ list_pop_front(q->l); }
35 0

  
proj/src/mouse.c
1
#include <lcom/lcf.h>
2

  
3
#include "mouse.h"
4

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

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

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

  
36
/* Mouse Controller Responses */
37
#define ACK_OK      0xFA /* @brief Operation sucessful */
38
#define ACK_INVALID 0xFE /* @brief Invalid Byte, first occurence */
39
#define ACK_ERROR   0xFC /* @brief Invalid Byte on resend */
40

  
41
int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
42
    if (interrupt_id == NULL) return NULL_PTR;
43
    *interrupt_id = interrupt_bit;
44
    if (sys_irqsetpolicy(MOUSE_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR;
45
    return SUCCESS;
46
}
47

  
48
int got_error_mouse_ih = 0;
49
int counter_mouse_ih = 0;
50

  
51
void (mouse_ih)(void) {
52
    uint8_t status = 0;
53
    got_error_mouse_ih = 0;
54
    if(counter_mouse_ih >= 3) counter_mouse_ih = 0;
55

  
56
    if ((got_error_mouse_ih = util_sys_inb(STATUS_REG, &status))) return;
57

  
58
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
59
        got_error_mouse_ih = OTHER_ERROR;
60
        return;
61
    }
62
    if (((status & AUX_MOUSE) == 0) || ((status & OUT_BUF_FUL) == 0)) {
63
        got_error_mouse_ih = READ_ERROR;
64
        return;
65
    }
66

  
67
    uint8_t byte = 0;
68

  
69
    if ((got_error_mouse_ih = util_sys_inb(OUTPUT_BUF, &byte))) return;
70

  
71
    /// This does not run if: I was expecting the first one but what I get is definitely not the first byte
72
    if((byte & FIRST_BYTE_ID)  || counter_mouse_ih){
73
        packet_mouse_ih[counter_mouse_ih++] = byte;
74
    }
75
}
76

  
77
void (mouse_parse_packet)(const uint8_t *packet_bytes, struct packet *pp){
78
    pp->bytes[0] = packet_bytes[0];
79
    pp->bytes[1] = packet_bytes[1];
80
    pp->bytes[2] = packet_bytes[2];
81
    pp->rb       = pp->bytes[0] & RIGHT_BUTTON;
82
    pp->mb       = pp->bytes[0] & MIDDLE_BUTTON;
83
    pp->lb       = pp->bytes[0] & LEFT_BUTTON;
84
    pp->delta_x  = sign_extend_byte((packet_bytes[0] & MSB_X_DELTA) != 0, pp->bytes[1]);
85
    pp->delta_y  = sign_extend_byte((packet_bytes[0] & MSB_Y_DELTA) != 0, pp->bytes[2]);
86
    pp->x_ov     = pp->bytes[0] & X_OVERFLOW;
87
    pp->y_ov     = pp->bytes[0] & Y_OVERFLOW;
88
}
89

  
90
int mouse_poll(struct packet *pp, uint16_t period){
91
    int ret = 0;
92

  
93
    uint8_t packet[3];
94
    uint8_t byte;
95
    if ((ret = mouse_issue_cmd(READ_DATA))) return ret;
96
    for(unsigned i = 0; i < 3; ++i){
97
        if((ret = mouse_poll_byte(&byte, period))) return ret;
98
        packet[i] = byte;
99
    }
100
    mouse_parse_packet(packet, pp);
101
    return SUCCESS;
102
}
103

  
104
int (mouse_set_data_report)(int on){
105
    if(on) return mouse_issue_cmd(ENABLE_DATA_REP);
106
    else   return mouse_issue_cmd(   DIS_DATA_REP);
107
}
108

  
109
int (mouse_read_data)(uint8_t *data, uint16_t period) {
110
    int ret;
111
    if ((ret = mouse_issue_cmd(READ_DATA))) return ret;
112
    if ((ret = mouse_poll_byte(data, period))) return ret;
113
    return SUCCESS;
114
}
115

  
116
int (mouse_issue_cmd)(uint32_t cmd) {
117
    int ret;
118
    uint8_t ack = 0;
119
    for (unsigned int i = 0; i < KBC_NUM_TRIES; i++) {
120
        if ((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
121
        if ((ret = kbc_issue_arg(cmd))) return ret;
122
        if ((ret = mouse_read_byte(&ack))) return ret;
123

  
124
        if (ack == ACK_OK) return SUCCESS;
125
        if (ack == ACK_ERROR) return INVALID_COMMAND;
126
        tickdelay(micros_to_ticks(DELAY));
127
    }
128
    return TIMEOUT_ERROR;
129
}
130

  
131
int (mouse_read_byte)(uint8_t *byte) {
132
    int ret = 0;
133
    uint8_t stat;
134
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
135
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
136
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) {
137
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
138
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
139
            else return SUCCESS;
140
        }
141
        tickdelay(micros_to_ticks(DELAY));
142
    }
143
    return TIMEOUT_ERROR;
144
}
145

  
146
int (mouse_poll_byte)(uint8_t *byte, uint16_t period) {
147
    int ret = 0;
148
    uint8_t stat;
149
    while(true){
150
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
151
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) {
152
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
153
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
154
            else return SUCCESS;
155
        }
156
        tickdelay(micros_to_ticks(DELAY));
157
    }
158
}
159

  
160
int16_t (sign_extend_byte)(uint8_t sign_bit, uint8_t byte) {
161
    return (int16_t)(((0xFF * sign_bit)<<8) | byte);
162
}
163 0

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

  
3
#include "kbc.h"
4

  
5
#include "utils.h"
6
#include "errors.h"
7

  
8
int (kbc_read_cmd)(uint8_t *cmd){
9
    int ret = 0;
10
    if((ret = kbc_issue_cmd(READ_KBC_CMD))) return ret;
11
    if((ret = kbc_read_byte(cmd))) return ret;
12
    return SUCCESS;
13
}
14

  
15
int (kbc_change_cmd)(uint8_t cmd){
16
    int ret = 0;
17
    if((ret = kbc_issue_cmd(WRITE_KBC_CMD))) return ret;
18
    if((ret = kbc_issue_arg(cmd))) return ret;
19
    return SUCCESS;
20
}
21

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

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

  
45
int (kbc_issue_arg)(uint8_t arg){
46
    int ret = 0;
47
    uint8_t stat;
48
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
49
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
50
        if((stat&IN_BUF_FULL) == 0){
51
            if(sys_outb(KBC_CMD_ARG, arg)) return WRITE_ERROR;
52
            return SUCCESS;
53
        }
54
        tickdelay(micros_to_ticks(DELAY));
55
    }
56
    return TIMEOUT_ERROR;
57
}
58

  
59
int (kbc_read_byte)(uint8_t *byte){
60
    int ret = 0;
61
    uint8_t stat;
62
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
63
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
64
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
65
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
66
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
67
            else return SUCCESS;
68
        }
69
        tickdelay(micros_to_ticks(DELAY));
70
    }
71
    printf("Timing out\n");
72
    return TIMEOUT_ERROR;
73
}
74 0

  
proj/src/uart.c
1
#include <lcom/lcf.h>
2

  
3
#include "uart.h"
4

  
5
#include "queue.h"
6
#include "errors.h"
7

  
8
#define UART_BITRATE                            115200
9
#define UART_WAIT                               20 //microseconds
10

  
11
#define UART_RBR                                0
12
#define UART_THR                                0
13
#define UART_IER                                1
14
#define UART_IIR                                2
15
#define UART_FCR                                2
16
#define UART_LCR                                3
17
#define UART_MCR                                4
18
#define UART_LSR                                5
19
#define UART_MSR                                6
20
#define UART_SR                                 7
21

  
22
#define UART_DLL                                0
23
#define UART_DLM                                1
24

  
25
/// LCR
26
#define UART_BITS_PER_CHAR_POS                  0
27
#define UART_STOP_BITS_POS                      2
28
#define UART_PARITY_POS                         3
29
#define UART_BREAK_CONTROL_POS                  6
30
#define UART_DLAB_POS                           7
31

  
32
#define UART_BITS_PER_CHAR                      (BIT(0) | BIT(1))
33
#define UART_STOP_BITS                          (BIT(2))
34
#define UART_PARITY                             (BIT(3) | BIT(4) | BIT(5))
35
#define UART_BREAK_CONTROL                      (BIT(6))
36
#define UART_DLAB                               (BIT(7))
37

  
38
#define UART_GET_BITS_PER_CHAR(n)               (((n)&UART_BITS_PER_CHAR) + 5)
39
#define UART_GET_STOP_BITS(n)                   (((n)&UART_STOP_BITS)? 2 : 1)
40
#define UART_GET_PARITY(n)                      (((n)&UART_PARITY       )>>UART_PARITY_POS       )
41
#define UART_GET_BREAK_CONTROL(n)               (((n)&UART_BREAK_CONTROL)>>UART_BREAK_CONTROL_POS)
42
#define UART_GET_DLAB(n)                        (((n)&UART_DLAB         )>>UART_DLAB_POS         )
43
#define UART_GET_DIV_LATCH(m,l)                 ((m)<<8 | (l))
44
#define UART_GET_DLL(n)                         ((n)&0xFF)
45
#define UART_GET_DLM(n)                         (((n)>>8)&0xFF)
46

  
47
/// IER
48
#define UART_INT_EN_RX_POS                      0
49
#define UART_INT_EN_TX_POS                      1
50
#define UART_INT_EN_RECEIVER_LINE_STAT_POS      2
51
#define UART_INT_EN_MODEM_STAT_POS              3
52

  
53
#define UART_INT_EN_RX                          (BIT(0))
54
#define UART_INT_EN_TX                          (BIT(1))
55
#define UART_INT_EN_RECEIVER_LINE_STAT          (BIT(2))
56
#define UART_INT_EN_MODEM_STAT                  (BIT(3))
57

  
58
#define UART_GET_INT_EN_RX(n)                   (((n)&UART_INT_EN_RX                )>>UART_INT_EN_RX_POS                )
59
#define UART_GET_INT_EN_TX(n)                   (((n)&UART_INT_EN_TX                )>>UART_INT_EN_TX_POS                )
60
#define UART_GET_INT_EN_RECEIVER_LINE_STAT(n)   (((n)&UART_INT_EN_RECEIVER_LINE_STAT)>>UART_INT_EN_RECEIVER_LINE_STAT_POS)
61
#define UART_GET_INT_EN_MODEM_STAT(n)           (((n)&UART_INT_EN_MODEM_STAT        )>>UART_INT_EN_MODEM_STAT_POS        )
62

  
63
/// LSR
64
#define UART_RECEIVER_READY_POS                 0
65
#define UART_OVERRUN_ERROR_POS                  1
66
#define UART_PARITY_ERROR_POS                   2
67
#define UART_FRAMING_ERROR_POS                  3
68
#define UART_TRANSMITTER_EMPTY_POS              5
69

  
70
#define UART_RECEIVER_READY                     (BIT(0))
71
#define UART_OVERRUN_ERROR                      (BIT(1))
72
#define UART_PARITY_ERROR                       (BIT(2))
73
#define UART_FRAMING_ERROR                      (BIT(3))
74
#define UART_TRANSMITTER_EMPTY                  (BIT(5))
75

  
76
#define UART_GET_RECEIVER_READY(n)              (((n)&UART_RECEIVER_READY           )>>UART_RECEIVER_READY_POS           )
77
#define UART_GET_OVERRUN_ERROR                  (((n)&UART_OVERRUN_ERROR            )>>UART_OVERRUN_ERROR_POS            )
78
#define UART_GET_PARITY_ERROR                   (((n)&UART_PARITY_ERROR             )>>UART_PARITY_ERROR_POS             )
79
#define UART_GET_FRAMING_ERROR                  (((n)&UART_FRAMING_ERROR            )>>UART_FRAMING_ERROR_POS            )
80
#define UART_GET_TRANSMITTER_EMPTY(n)           (((n)&UART_TRANSMITTER_EMPTY        )>>UART_TRANSMITTER_EMPTY_POS        )
81

  
82
/// IIR
83
#define UART_INT_PEND_POS                       1
84

  
85
#define UART_INT_PEND                           (BIT(3)|BIT(2)|BIT(1))
86

  
87
#define UART_GET_IF_INT_PEND(n)                 (!((n)&1))
88
typedef enum {
89
    uart_int_receiver_line_stat = (         BIT(1) | BIT(0)),
90
    uart_int_rx                 = (         BIT(1)         ),
91
    uart_int_char_timeout_fifo  = (BIT(2) | BIT(1)         ),
92
    uart_int_tx                 = (                  BIT(0)),
93
    uart_int_modem_stat         = (0)
94
} uart_int_code;
95
#define UART_GET_INT_PEND(n)                    ((uart_int_code)(((n)&UART_INT_PEND)>>UART_INT_PEND_POS))
96

  
97
int (subscribe_uart_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
98
    if (interrupt_id == NULL) return 1;
99
    *interrupt_id = interrupt_bit;
100
    return (sys_irqsetpolicy(COM1_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id));
101
}
102

  
103
static void uart_parse_config(uart_config *config){
104
    /// LCR
105
    config->bits_per_char          = UART_GET_BITS_PER_CHAR     (config->lcr);
106
    config->stop_bits              = UART_GET_STOP_BITS         (config->lcr);
107
    config->parity                 = UART_GET_PARITY            (config->lcr); if((config->parity & BIT(0)) == 0) config->parity = uart_parity_none;
108
    config->break_control          = UART_GET_BREAK_CONTROL     (config->lcr);
109
    config->dlab                   = UART_GET_DLAB              (config->lcr);
110
    /// IER
111
    config->received_data_int      = UART_GET_INT_EN_RX                (config->ier);
112
    config->transmitter_empty_int  = UART_GET_INT_EN_TX                (config->ier);
113
    config->receiver_line_stat_int = UART_GET_INT_EN_RECEIVER_LINE_STAT(config->ier);
114
    config->modem_stat_int         = UART_GET_INT_EN_MODEM_STAT        (config->ier);
115
    /// DIV LATCH
116
    config->divisor_latch          = UART_GET_DIV_LATCH(config->dlm, config->dll);
117
}
118

  
119
static int uart_get_lcr(int base_addr, uint8_t *p){
120
    return util_sys_inb(base_addr+UART_LCR, p);
121
}
122
static int uart_set_lcr(int base_addr, uint8_t config){
123
    if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR;
124
    return SUCCESS;
125
}
126
static int uart_get_lsr(int base_addr, uint8_t *p){
127
    return util_sys_inb(base_addr+UART_LSR, p);
128
}
129
static int uart_get_iir(int base_addr, uint8_t *p){
130
    return util_sys_inb(base_addr+UART_IIR, p);
131
}
132

  
133
static int uart_enable_divisor_latch(int base_addr){
134
    int ret = SUCCESS;
135
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
136
    return uart_set_lcr(base_addr, conf | UART_DLAB);
137
}
138
static int uart_disable_divisor_latch(int base_addr){
139
    int ret = SUCCESS;
140
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
141
    return uart_set_lcr(base_addr, conf & (~UART_DLAB));
142
}
143

  
144
static int uart_get_ier(int base_addr, uint8_t *p){
145
    int ret;
146
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
147
    return util_sys_inb(base_addr+UART_IER, p);
148
}
149
static int uart_set_ier(int base_addr, uint8_t n){
150
    int ret;
151
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
152
    if(sys_outb(base_addr+UART_IER, n)) return WRITE_ERROR;
153
    return SUCCESS;
154
}
155

  
156
int uart_get_config(int base_addr, uart_config *config){
157
    int ret = SUCCESS;
158

  
159
    config->base_addr = base_addr;
160

  
161
    if((ret = uart_get_lcr(base_addr, &config->lcr))) return ret;
162

  
163
    if((ret = uart_get_ier(base_addr, &config->ier))) return ret;
164

  
165
    if((ret = uart_enable_divisor_latch (base_addr))) return ret;
166
    if((ret = util_sys_inb(base_addr+UART_DLL, &config->dll   ))) return ret;
167
    if((ret = util_sys_inb(base_addr+UART_DLM, &config->dlm   ))) return ret;
168
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
169

  
170
    uart_parse_config(config);
171
    return ret;
172
}
173
void uart_print_config(uart_config config){
174

  
175
    printf("%s configuration:\n", (config.base_addr == COM1_ADDR ? "COM1" : "COM2"));
176
    printf("\tLCR = 0x%X: %d bits per char\t %d stop bits\t", config.lcr, config.bits_per_char, config.stop_bits);
177
    if((config.parity&BIT(0)) == 0) printf("NO parity\n");
178
    else switch(config.parity){
179
        case uart_parity_odd : printf("ODD parity\n"     ); break;
180
        case uart_parity_even: printf("EVEN parity\n"    ); break;
181
        case uart_parity_par1: printf("parity bit is 1\n"); break;
182
        case uart_parity_par0: printf("parity bit is 0\n"); break;
183
        default              : printf("invalid\n"        ); break;
184
    }
185
    printf("\tDLM = 0x%02X DLL=0x%02X: bitrate = %d bps\n", config.dlm, config.dll, UART_BITRATE/config.divisor_latch);
186
    printf("\tIER = 0x%02X: Rx interrupts: %s\tTx interrupts: %s\n", config.ier,
187
        (config.received_data_int     ? "ENABLED":"DISABLED"),
188
        (config.transmitter_empty_int ? "ENABLED":"DISABLED"));
189
}
190

  
191
int uart_set_bits_per_character(int base_addr, uint8_t bits_per_char){
192
    if(bits_per_char < 5 || bits_per_char > 8) return INVALID_ARG;
193
    int ret = SUCCESS;
194
    bits_per_char = (bits_per_char-5)&0x3;
195
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
196
    conf = (conf & (~UART_BITS_PER_CHAR)) | bits_per_char;
197
    return uart_set_lcr(base_addr, conf);
198
}
199
int uart_set_stop_bits(int base_addr, uint8_t stop){
200
    if(stop != 1 && stop != 2) return INVALID_ARG;
201
    int ret = SUCCESS;
202
    stop -= 1;
203
    stop = (stop&1)<<2;
204
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
205
    conf = (conf & (~UART_STOP_BITS)) | stop;
206
    return uart_set_lcr(base_addr, conf);
207
}
208
int uart_set_parity(int base_addr, uart_parity par){
209
    int ret = SUCCESS;
210
    uint8_t parity = par << 3;
211
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
212
    conf = (conf & (~UART_PARITY)) | parity;
213
    return uart_set_lcr(base_addr, conf);
214
}
215
int uart_set_bit_rate(int base_addr, float bit_rate){
216
    int ret = SUCCESS;
217
    uint16_t latch = UART_BITRATE/bit_rate;
218
    uint8_t dll = UART_GET_DLL(latch);
219
    uint8_t dlm = UART_GET_DLM(latch);
220
    if((ret = uart_enable_divisor_latch(base_addr))) return ret;
221
    if(sys_outb(base_addr+UART_DLL, dll)) return WRITE_ERROR;
222
    if(sys_outb(base_addr+UART_DLM, dlm)) return WRITE_ERROR;
223
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
224
    return SUCCESS;
225
}
226

  
227
static int uart_get_char(int base_addr, uint8_t *p){
228
    int ret;
229
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
230
    return util_sys_inb(base_addr+UART_RBR, p);
231
}
232
static int uart_send_char(int base_addr, uint8_t c){
233
    int ret;
234
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
235
    if(sys_outb(base_addr+UART_THR, c)) return WRITE_ERROR;
236
    return SUCCESS;
237
}
238
static int uart_receiver_ready(int base_addr){
239
    uint8_t lsr;
240
    if(uart_get_lsr(base_addr, &lsr)) return false;
241
    return UART_GET_RECEIVER_READY(lsr);
242
}
243
static int uart_transmitter_empty(int base_addr){
244
    uint8_t lsr;
245
    if(uart_get_lsr(base_addr, &lsr)) return false;
246
    return UART_GET_TRANSMITTER_EMPTY(lsr);
247
}
248

  
249
int uart_enable_int_rx(int base_addr){
250
    int ret;
251
    uint8_t ier;
252
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
253
    ier |= UART_INT_EN_RX;
254
    return uart_set_ier(base_addr, ier);
255
}
256
int uart_disable_int_rx(int base_addr){
257
    int ret;
258
    uint8_t ier;
259
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
260
    ier &= ~UART_INT_EN_RX;
261
    return uart_set_ier(base_addr, ier);
262
}
263
int uart_enable_int_tx(int base_addr){
264
    int ret;
265
    uint8_t ier;
266
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
267
    ier |= UART_INT_EN_TX;
268
    return uart_set_ier(base_addr, ier);
269
}
270
int uart_disable_int_tx(int base_addr){
271
    int ret;
272
    uint8_t ier;
273
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
274
    ier &= ~UART_INT_EN_TX;
275
    return uart_set_ier(base_addr, ier);
276
}
277

  
278
#include "nctp.h"
279

  
280
#define NCTP_START      0x80
281
#define NCTP_END        0xFF
282
#define NCTP_OK         0xFF
283
#define NCTP_NOK        0x00
284

  
285
queue_t *out = NULL;
286
queue_t *in  = NULL;
287

  
288
int nctp_init(void){
289
    out = queue_ctor(); if(out == NULL) return NULL_PTR;
290
    in  = queue_ctor(); if(in  == NULL) return NULL_PTR;
291
    return SUCCESS;
292
}
293
int nctp_free(void){
294
    while(!queue_empty(out)){
295
        free(queue_top(out));
296
        queue_pop(out);
297
    }
298
    while(!queue_empty(in)){
299
        free(queue_top(in));
300
        queue_pop(in);
301
    }
302
    return SUCCESS;
303
}
304

  
305
int nctp_send(size_t num, uint8_t* ptr[], size_t sz[]){
306
    {
307
        size_t cnt = 0;
308
        for(size_t i = 0; i < num; ++i){
309
            cnt += sz[i];
310
            if(cnt > queue_max_size) return TRANS_REFUSED;
311
        }
312
    }
313
    int ret;
314
    uint8_t *tmp;
315
    tmp = malloc(sizeof(uint8_t)); *tmp = NCTP_START; queue_push(out, tmp);
316
    for(size_t i = 0; i < num; ++i){
317
        uint8_t *p = ptr[i]; size_t s = sz[i];
318
        for(size_t j = 0; j < s; ++j, ++p){
319
            tmp = malloc(sizeof(uint8_t)); *tmp = *p; queue_push(out, tmp);
320
        }
321
    }
322
    tmp = malloc(sizeof(uint8_t)); *tmp = NCTP_END; queue_push(out, tmp);
323
    if(uart_transmitter_empty(COM1_ADDR)){
324
        if((ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out)))) return ret;
325
        queue_pop(out);
326
    }
327
    return SUCCESS;
328
}
329

  
330
static int nctp_transmit(void){
331
    if(!queue_empty(out)){
332
        int ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out));
333
        queue_pop(out);
334
        return ret;
335
    }else return SUCCESS;
336
}
337
static void process(){
338
    free(queue_top(in)); queue_pop(in);
339
    while(*(uint8_t*)queue_top(in) != NCTP_END){
340
        printf("%c", *(uint8_t*)queue_top(in));
341
        free(queue_top(in)); queue_pop(in);
342
    }
343
    free(queue_top(in)); queue_pop(in);
344
}
345
static int nctp_receive(void){
346
    int ret;
347
    uint8_t c;
348
    int num_ends = 0;
349
    while(uart_receiver_ready(COM1_ADDR)){
350
        if((ret = uart_get_char(COM1_ADDR, &c))) return ret;
351
        uint8_t *tmp = malloc(sizeof(uint8_t)); *tmp = c;
352
        queue_push(in, tmp);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff