Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 60

History | View | Annotate | Download (5.77 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_macros.h"
9
#include "keyboard.h"
10
#include "timer.h"
11
#include "utils.h"
12

    
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
    /// loop stuff
39
    int ipc_status, r;
40
    message msg;
41
    /// Keyboard interrupt handling
42
    uint8_t kbc_irq_bit = 1;
43
    int kbc_id = 0;
44
    int kbc_irq = BIT(kbc_irq_bit);
45
    if (subscribe_keyboard_interrupt(kbc_irq_bit, &kbc_id)) return 1;
46
    /// cycle
47
    int good = 1;
48
    while (good) {
49
        /* 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
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
58
                        kbc_ih();
59
                        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
                        if(done)
64
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, scancode);
65
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
66
                    }
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
    if (unsubscribe_interrupt(&kbc_id)) return 1;
77

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

    
80
    return 0;
81
}
82

    
83
int(kbd_test_poll)() {
84
    uint8_t c[2]; uint8_t size;
85
    do{
86
        if(keyboard_poll(c, &size)) return 1;
87
        if(kbd_print_scancode((~c[size-1])&BREAK_CODE_BIT, size, c)) return 1;
88
    }while(!(size == 1 && c[0] == ESC_BREAK_CODE));
89

    
90
    if(kbc_restore_keyboard()) return 1;
91

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

    
94
    return 0;
95
}
96

    
97
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
    if(subscribe_keyboard_interrupt(kbc_irq_bit, &kbc_id)) return 1;
115
    /// 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

    
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
                        if(done) {
139
                            kbd_print_scancode(!(scancode[sz-1] & BREAK_CODE_BIT), sz, 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
}