Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 48

History | View | Annotate | Download (5.09 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 48 up20180655
extern int sz;
37
extern int done;
38 31 up20180655
extern int got_error;
39 42 up20180642
extern uint32_t sys_inb_counter;
40 30 up20180655
41
int(kbd_test_scan)() {
42 44 up20180642
    /// loop stuff
43 30 up20180655
    int ipc_status, r;
44
    message msg;
45 44 up20180642
    /// Keyboard interrupt handling
46 37 up20180655
    uint8_t kbc_irq_bit = 1;
47 30 up20180655
    int kbc_id = 0;
48 37 up20180655
    int kbc_irq = BIT(kbc_irq_bit);
49 30 up20180655
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) return 1;
50 44 up20180642
    /// cycle
51
    int good = 1;
52
    while (good) {
53 30 up20180655
        /* Get a request message. */
54
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
55
            printf("driver_receive failed with %d", r);
56
            continue;
57
        }
58
        if (is_ipc_notify(ipc_status)) { /* received notification */
59
            switch (_ENDPOINT_P(msg.m_source)) {
60
                case HARDWARE: /* hardware interrupt notification */
61 37 up20180655
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
62 30 up20180655
                        kbc_ih();
63 48 up20180655
                        if(done)
64
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, scancode);
65
66 44 up20180642
                        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 48 up20180655
                        if(done) {
138
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, scancode);
139 44 up20180642
                            time = 0;
140 45 up20180642
                            no_interrupts = 0;
141 44 up20180642
                            if (scancode[0] == ESC_BREAK_CODE) good = 0;
142
                        }
143
                    }
144
                    break;
145
                default:
146
                    break; /* no other notifications expected: do nothing */
147
            }
148
        } else { /* received standart message, not a notification */
149
            /* no standart message expected: do nothing */
150
        }
151
    }
152
153
    if (unsubscribe_interrupt(&kbc_id)) return 1;
154
    if (unsubscribe_interrupt(&timer_id)) return 1;
155
156
    return 0;
157 30 up20180655
}