Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 45

History | View | Annotate | Download (5.57 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 two_byte_scancode;
37
extern int got_error;
38
extern uint32_t sys_inb_counter;
39

    
40
int(kbd_test_scan)() {
41
    /// loop stuff
42
    int ipc_status, r;
43
    message msg;
44
    /// Keyboard interrupt handling
45
    uint8_t kbc_irq_bit = 1;
46
    int kbc_id = 0;
47
    int kbc_irq = BIT(kbc_irq_bit);
48
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) return 1;
49
    /// cycle
50
    int good = 1;
51
    while (good) {
52
        /* 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
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
61
                        kbc_ih();
62
                        if (!(two_byte_scancode || got_error)) { /* finished processing a scancode */
63
                            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
                    }
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 (!(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
                            no_interrupts = 0;
142
                            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
}