Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 48

History | View | Annotate | Download (5.09 KB)

1
#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
#include "timer_func.h"
10

    
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 sz;
37
extern int done;
38
extern int got_error;
39
extern uint32_t sys_inb_counter;
40

    
41
int(kbd_test_scan)() {
42
    /// loop stuff
43
    int ipc_status, r;
44
    message msg;
45
    /// Keyboard interrupt handling
46
    uint8_t kbc_irq_bit = 1;
47
    int kbc_id = 0;
48
    int kbc_irq = BIT(kbc_irq_bit);
49
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) return 1;
50
    /// cycle
51
    int good = 1;
52
    while (good) {
53
        /* 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
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
62
                        kbc_ih();
63
                        if(done)
64
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, scancode);
65

    
66
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
67
                    }
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
    if (unsubscribe_interrupt(&kbc_id)) return 1;
78

    
79
    if (kbd_print_no_sysinb(sys_inb_counter)) return 1;
80

    
81
    return 0;
82
}
83

    
84
int(kbd_test_poll)() {
85
    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

    
91
    if(kbc_restore_kbd()) return 1;
92

    
93
    if(kbd_print_no_sysinb(sys_inb_counter)) return 1;
94

    
95
    return 0;
96
}
97

    
98
extern int no_interrupts;
99

    
100
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(done) {
138
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, scancode);
139
                            time = 0;
140
                            no_interrupts = 0;
141
                            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
}