Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 148

History | View | Annotate | Download (4.99 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 67 up20180642
                        if(keyboard_done)
60
                            kbd_print_scancode(!(scancode[scancode_sz-1] & BREAK_CODE_BIT), scancode_sz, scancode);
61 44 up20180642
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
62 30 up20180655
                    }
63
                    break;
64
                default:
65
                    break; /* no other notifications expected: do nothing */
66
            }
67
        } else { /* received standart message, not a notification */
68
            /* no standart message expected: do nothing */
69
        }
70
    }
71
72 44 up20180642
    if (unsubscribe_interrupt(&kbc_id)) return 1;
73 30 up20180655
74 42 up20180642
    if (kbd_print_no_sysinb(sys_inb_counter)) return 1;
75 30 up20180655
76
    return 0;
77
}
78
79
int(kbd_test_poll)() {
80 36 up20180642
    uint8_t c[2]; uint8_t size;
81
    do{
82 60 up20180642
        if(keyboard_poll(c, &size)) return 1;
83 50 up20180655
        if(kbd_print_scancode((~c[size-1])&BREAK_CODE_BIT, size, c)) return 1;
84 36 up20180642
    }while(!(size == 1 && c[0] == ESC_BREAK_CODE));
85 38 up20180642
86 60 up20180642
    if(kbc_restore_keyboard()) return 1;
87 39 up20180642
88 43 up20180642
    if(kbd_print_no_sysinb(sys_inb_counter)) return 1;
89 42 up20180642
90 36 up20180642
    return 0;
91 30 up20180655
}
92
93 44 up20180642
int(kbd_test_timed_scan)(uint8_t idle) {
94
    /// loop stuff
95
    int ipc_status, r;
96
    message msg;
97
    /// Timer interrupt handling
98
    const uint32_t frequency = 60; // Frequency asummed at 60Hz
99
    uint8_t timer_irq_bit = 0;
100
    int timer_id = 0;
101
    int timer_irq = BIT(timer_irq_bit);
102
    if(subscribe_timer_interrupt(timer_irq_bit, &timer_id)) return 1;
103
104
    no_interrupts = 0;
105
    int time = 0;
106
    /// Keyboard interrupt handling
107
    uint8_t kbc_irq_bit = 1;
108
    int kbc_id = 0;
109
    int kbc_irq = BIT(kbc_irq_bit);
110 60 up20180642
    if(subscribe_keyboard_interrupt(kbc_irq_bit, &kbc_id)) return 1;
111 44 up20180642
    /// cycle
112
    int good = 1;
113
    while (good) {
114
        /* Get a request message. */
115
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
116
            printf("driver_receive failed with %d", r);
117
            continue;
118
        }
119
        if (is_ipc_notify(ipc_status)) { /* received notification */
120
            switch (_ENDPOINT_P(msg.m_source)) {
121
                case HARDWARE: /* hardware interrupt notification */
122
                    if (msg.m_notify.interrupts & timer_irq) { /* subscribed interrupt */
123
                        timer_int_handler();
124
                        if (no_interrupts%frequency == 0) time++;
125
                        if(time >= idle) good = 0;
126
                    }
127
                    if (msg.m_notify.interrupts & kbc_irq) { /// subscribed interrupt
128
                        kbc_ih();
129 67 up20180642
                        if(keyboard_done) {
130
                            kbd_print_scancode(!(scancode[scancode_sz-1] & BREAK_CODE_BIT), scancode_sz, scancode);
131 44 up20180642
                            time = 0;
132 45 up20180642
                            no_interrupts = 0;
133 44 up20180642
                            if (scancode[0] == ESC_BREAK_CODE) good = 0;
134
                        }
135
                    }
136
                    break;
137
                default:
138
                    break; /* no other notifications expected: do nothing */
139
            }
140
        } else { /* received standart message, not a notification */
141
            /* no standart message expected: do nothing */
142
        }
143
    }
144
145
    if (unsubscribe_interrupt(&kbc_id)) return 1;
146
    if (unsubscribe_interrupt(&timer_id)) return 1;
147
148
    return 0;
149 30 up20180655
}