Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 60

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