Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 45

History | View | Annotate | Download (5.57 KB)

1 30 up20180655
#include <lcom/lcf.h>
2
#include <lcom/lab3.h>
3
4
#include <stdbool.h>
5
#include <stdint.h>
6
7
#include "kbc.h"
8
#include "kbc_func.h"
9 44 up20180642
#include "timer_func.h"
10 30 up20180655
11
int main(int argc, char *argv[]) {
12
  // sets the language of LCF messages (can be either EN-US or PT-PT)
13
  lcf_set_language("EN-US");
14
15
  // enables to log function invocations that are being "wrapped" by LCF
16
  // [comment this out if you don't want/need it]
17
  lcf_trace_calls("/home/lcom/labs/lab3/trace.txt");
18
19
  // enables to save the output of printf function calls on a file
20
  // [comment this out if you don't want/need it]
21
  lcf_log_output("/home/lcom/labs/lab3/output.txt");
22
23
  // handles control over to LCF
24
  // [LCF handles command line arguments and invokes the right function]
25
  if (lcf_start(argc, argv))
26
    return 1;
27
28
  // LCF clean up tasks
29
  // [must be the last statement before return]
30
  lcf_cleanup();
31
32
  return 0;
33
}
34
35
extern uint8_t scancode[2];
36
extern int two_byte_scancode;
37 31 up20180655
extern int got_error;
38 42 up20180642
extern uint32_t sys_inb_counter;
39 30 up20180655
40
int(kbd_test_scan)() {
41 44 up20180642
    /// loop stuff
42 30 up20180655
    int ipc_status, r;
43
    message msg;
44 44 up20180642
    /// Keyboard interrupt handling
45 37 up20180655
    uint8_t kbc_irq_bit = 1;
46 30 up20180655
    int kbc_id = 0;
47 37 up20180655
    int kbc_irq = BIT(kbc_irq_bit);
48 30 up20180655
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) return 1;
49 44 up20180642
    /// cycle
50
    int good = 1;
51
    while (good) {
52 30 up20180655
        /* Get a request message. */
53
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
54
            printf("driver_receive failed with %d", r);
55
            continue;
56
        }
57
        if (is_ipc_notify(ipc_status)) { /* received notification */
58
            switch (_ENDPOINT_P(msg.m_source)) {
59
                case HARDWARE: /* hardware interrupt notification */
60 37 up20180655
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
61 30 up20180655
                        kbc_ih();
62 31 up20180655
                        if (!(two_byte_scancode || got_error)) { /* finished processing a scancode */
63 44 up20180642
                            if (scancode[0] == TWO_BYTE_CODE) kbd_print_scancode(!(scancode[1] & BREAK_CODE_BIT), 2, scancode);
64
                            else                              kbd_print_scancode(!(scancode[0] & BREAK_CODE_BIT), 1, scancode);
65
                        } else { break; }
66
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
67 30 up20180655
                    }
68
                    break;
69
                default:
70
                    break; /* no other notifications expected: do nothing */
71
            }
72
        } else { /* received standart message, not a notification */
73
            /* no standart message expected: do nothing */
74
        }
75
    }
76
77 44 up20180642
    if (unsubscribe_interrupt(&kbc_id)) return 1;
78 30 up20180655
79 42 up20180642
    if (kbd_print_no_sysinb(sys_inb_counter)) return 1;
80 30 up20180655
81
    return 0;
82
}
83
84
int(kbd_test_poll)() {
85 36 up20180642
    uint8_t c[2]; uint8_t size;
86
    do{
87
        if(kbd_poll(c, &size)) return 1;
88
        if(kbd_print_scancode((~c[0])&BREAK_CODE_BIT, size, c)) return 1;
89
    }while(!(size == 1 && c[0] == ESC_BREAK_CODE));
90 38 up20180642
91 43 up20180642
    if(kbc_restore_kbd()) return 1;
92 39 up20180642
93 43 up20180642
    if(kbd_print_no_sysinb(sys_inb_counter)) return 1;
94 42 up20180642
95 36 up20180642
    return 0;
96 30 up20180655
}
97
98 44 up20180642
extern int no_interrupts;
99 30 up20180655
100 44 up20180642
int(kbd_test_timed_scan)(uint8_t idle) {
101
    /// loop stuff
102
    int ipc_status, r;
103
    message msg;
104
    /// Timer interrupt handling
105
    const uint32_t frequency = 60; // Frequency asummed at 60Hz
106
    uint8_t timer_irq_bit = 0;
107
    int timer_id = 0;
108
    int timer_irq = BIT(timer_irq_bit);
109
    if(subscribe_timer_interrupt(timer_irq_bit, &timer_id)) return 1;
110
111
    no_interrupts = 0;
112
    int time = 0;
113
    /// Keyboard interrupt handling
114
    uint8_t kbc_irq_bit = 1;
115
    int kbc_id = 0;
116
    int kbc_irq = BIT(kbc_irq_bit);
117
    if(subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) return 1;
118
    /// cycle
119
    int good = 1;
120
    while (good) {
121
        /* Get a request message. */
122
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
123
            printf("driver_receive failed with %d", r);
124
            continue;
125
        }
126
        if (is_ipc_notify(ipc_status)) { /* received notification */
127
            switch (_ENDPOINT_P(msg.m_source)) {
128
                case HARDWARE: /* hardware interrupt notification */
129
                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
130
                        timer_int_handler();
131
                        //printf("no_interrupts: %d\n", no_interrupts);
132
                        if (no_interrupts%frequency == 0) time++;
133
                        if(time >= idle) good = 0;
134
                    }
135
                    if (msg.m_notify.interrupts & kbc_irq) { /// subscribed interrupt
136
                        kbc_ih();
137
                        if (!(two_byte_scancode || got_error)) { /// finished processing a scancode
138
                            if (scancode[0] == TWO_BYTE_CODE) kbd_print_scancode(!(scancode[1] & BREAK_CODE_BIT), 2, scancode);
139
                            else                              kbd_print_scancode(!(scancode[0] & BREAK_CODE_BIT), 1, scancode);
140
                            time = 0;
141 45 up20180642
                            no_interrupts = 0;
142 44 up20180642
                            if (scancode[0] == ESC_BREAK_CODE) good = 0;
143
                        }
144
                    }
145
                    break;
146
                default:
147
                    break; /* no other notifications expected: do nothing */
148
            }
149
        } else { /* received standart message, not a notification */
150
            /* no standart message expected: do nothing */
151
        }
152
    }
153
154
    if (unsubscribe_interrupt(&kbc_id)) return 1;
155
    if (unsubscribe_interrupt(&timer_id)) return 1;
156
157
    return 0;
158 30 up20180655
}