Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 385

History | View | Annotate | Download (4.99 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(keyboard_done)
60
                            kbd_print_scancode(!(scancode[scancode_sz-1] & BREAK_CODE_BIT), scancode_sz, scancode);
61
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
62
                    }
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
    if (unsubscribe_interrupt(&kbc_id)) return 1;
73

    
74
    if (kbd_print_no_sysinb(sys_inb_counter)) return 1;
75

    
76
    return 0;
77
}
78

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

    
86
    if(kbc_restore_keyboard()) return 1;
87

    
88
    if(kbd_print_no_sysinb(sys_inb_counter)) return 1;
89

    
90
    return 0;
91
}
92

    
93
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
    if(subscribe_keyboard_interrupt(kbc_irq_bit, &kbc_id)) return 1;
111
    /// 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
                        if(keyboard_done) {
130
                            kbd_print_scancode(!(scancode[scancode_sz-1] & BREAK_CODE_BIT), scancode_sz, scancode);
131
                            time = 0;
132
                            no_interrupts = 0;
133
                            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
}