Project

General

Profile

Statistics
| Revision:

root / lab3 / lab3.c @ 15

History | View | Annotate | Download (8.16 KB)

1 10 up20180645
2 8 up20180645
#include <lcom/lcf.h>
3
#include <lcom/lab3.h>
4
#include <stdbool.h>
5
#include <stdint.h>
6 12 up20180645
#include "timer.h"
7 9 up20180645
#include "keyboard.h"
8 10 up20180645
9
10 8 up20180645
int main(int argc, char *argv[]) {
11
  // sets the language of LCF messages (can be either EN-US or PT-PT)
12
  lcf_set_language("EN-US");
13
14
  // enables to log function invocations that are being "wrapped" by LCF
15
  // [comment this out if you don't want/need it]
16
  lcf_trace_calls("/home/lcom/labs/lab3/trace.txt");
17
18
  // enables to save the output of printf function calls on a file
19
  // [comment this out if you don't want/need it]
20
  lcf_log_output("/home/lcom/labs/lab3/output.txt");
21
22
  // handles control over to LCF
23
  // [LCF handles command line arguments and invokes the right function]
24
  if (lcf_start(argc, argv))
25
    return 1;
26
27
  // LCF clean up tasks
28
  // [must be the last statement before return]
29
  lcf_cleanup();
30
31
  return 0;
32
}
33
34 10 up20180645
extern uint8_t scan_code;
35
extern uint32_t cnt;
36 12 up20180645
extern int count;
37 9 up20180645
38 8 up20180645
int(kbd_test_scan)() {
39 12 up20180645
40 9 up20180645
  int r, ipc_status;
41 10 up20180645
  uint8_t keyboard_irq, size, bytes[2]; //size of scancode can be 2 byte long
42 9 up20180645
  message msg;
43
  bool make=false; //to check if code is make or break
44 8 up20180645
45 12 up20180645
  if(kbc_subscribe_int(&keyboard_irq)!=0){    //check if subscription worked
46 9 up20180645
    printf("Error subscribing int\n");
47
    return 1;
48
  }
49
50 12 up20180645
  while(scan_code!=ESC_BREAK){            //looping until scan_code is the breakcode of ESC key
51
52 9 up20180645
    if ((r = driver_receive(ANY, &msg, &ipc_status))==1){
53
      printf("driver_receive failed with: %d",r);
54
      continue;
55
    }
56 12 up20180645
    if (is_ipc_notify(ipc_status)){                                //received notification
57 9 up20180645
      switch (_ENDPOINT_P(msg.m_source)){
58 12 up20180645
        case HARDWARE:                                             //hardware interrupt notification
59
                if (msg.m_notify.interrupts &keyboard_irq){        // subscribed interrupt
60 9 up20180645
61
                  kbc_ih();
62
                  bytes[0]=scan_code;
63
                  bytes[1]=scan_code;
64
65
                  if(bytes[0]==TWO_BYTE_SCANCODE){
66
                    size=2;
67
                  }
68
                  else{
69
                    size=1;
70
                  }
71
72 10 up20180645
                  if (scan_code & MAKE_CODE){        //checks if code is make or break
73 12 up20180645
                      make = false;                  //is break code
74 9 up20180645
                    }
75
                  else {
76 12 up20180645
                    make = true;              //is make code
77 9 up20180645
                  }
78 11 up20180645
79 12 up20180645
                  if(kbd_print_scancode(make, size, bytes)!=0){         //prints the code
80 11 up20180645
                    printf("Error printing scan code\n");
81
                    return 1;
82
                  }
83 9 up20180645
                      }
84
               break;
85
        default:
86 12 up20180645
              break;                             //no other notifications expected: do nothing
87 9 up20180645
        }
88
    }
89 12 up20180645
    else {                                       //received a standard message, not a notification
90 9 up20180645
      //no standard messages expected: do nothing
91
    }
92
  }
93
94 12 up20180645
   if (kbc_unsubscribe_int() != 0) {            //check if unsubscription worked
95 9 up20180645
                printf("Error unsubscribing int \n");
96
                return 1;
97
        }
98
99 12 up20180645
  if(kbd_print_no_sysinb(cnt)!=0){                  //prints the number of sys calls
100 11 up20180645
    printf("Error printing number of sys used\n");
101
    return 1;
102
  }
103 10 up20180645
104 11 up20180645
  cnt=0;
105
  scan_code=0;
106
107 9 up20180645
  return 0;
108 8 up20180645
}
109
110
int(kbd_test_poll)() {
111 12 up20180645
112 11 up20180645
  uint8_t status, size, bytes[2]; //size of scancode can be 2 byte long
113
  bool make=false; //to check if code is make or break
114 8 up20180645
115 12 up20180645
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key, can't do                                     interruptions
116
117 11 up20180645
    if(util_sys_inb(STATUS_REG, &status)!=0){     //checks the status register
118
      printf("Error reading status register\n");
119
      return 1;
120
    }
121
122 12 up20180645
                if ((status & STAT_REG_OBF) && !(status & STAT_REG_AUX) && !(status & STAT_REG_PAR || status & STAT_REG_TIMEOUT)) {      //checks if there is no parity ot timeout error, if the output buffer                             is full and if there is mouse data
123 11 up20180645
124 12 up20180645
                        if(util_sys_inb(OUTPUT_BUF, &scan_code)!=0){  //reads output buffer
125 11 up20180645
        printf("Error reading output buffer\n");
126
      return 1;
127
      }
128
129
                        bytes[0]=scan_code;
130
      bytes[1]=scan_code;
131
132
      if(bytes[0]==TWO_BYTE_SCANCODE){
133
        size=2;
134
      }
135
      else{
136
        size=1;
137
      }
138
139
      if (scan_code & MAKE_CODE){                   //checks if code is make or break
140
          make = false;                             //break code
141
        }
142
      else {
143
        make = true;                         //make code
144
      }
145
146
      if(kbd_print_scancode(make, size, bytes)!=0){ //prints the code
147
        printf("Error printing scan code\n");
148
        return 1;
149
      }
150
151
                }
152
                else {                                                                                                                                                 //if the output buffer is not full wait
153
                        tickdelay(micros_to_ticks(DELAY_US));                //makes keyboard respond to a command in 20 ms
154
                }
155
  }
156
157 12 up20180645
  if(kbd_print_no_sysinb(cnt)!=0){                      //prints the number of sys calls
158 11 up20180645
    printf("Error printing number of sys used\n");
159
    return 1;
160
  }
161
162 12 up20180645
  if(reenable_interrupt()!=0){                          //re-enables interruptions
163
    printf("Couldn't re-enable the interruptions\n");
164 11 up20180645
    return 1;
165
166
  }
167
  cnt=0;
168
  scan_code=0;
169
170
   return 0;
171 8 up20180645
}
172
173
174 12 up20180645
int(kbd_test_timed_scan)(uint8_t n) { //similar function to that of test_time_scan but with timer interruptions
175
176
  if(n<0){                    //checks if n is a valid input
177
    printf("Invalid time\n");
178
    return 1;
179
  }
180
181
  int r, ipc_status;
182
  uint8_t keyboard_irq, size, bytes[2], timer_irq;  //size of scancode can be 2 byte long
183
  message msg;
184
  bool make=false;                                  //to check if code is make or break
185
186
  if(timer_subscribe_int(&timer_irq)!=0){
187
    printf("Error subscribing int (timer)\n");
188
    return 1;
189
  }
190
191
  if(kbc_subscribe_int(&keyboard_irq)!=0){
192
    printf("Error subscribing int (keyboard)\n");
193
    return 1;
194
  }
195
196
  while((scan_code!=ESC_BREAK)&&(count/sys_hz()<n)){      //looping until scan_code is the breakcode of ESC key or until a command is issued within the time interval
197
    if ((r = driver_receive(ANY, &msg, &ipc_status))==1){
198
      printf("driver_receive failed with: %d",r);
199
      continue;
200
    }
201
    if (is_ipc_notify(ipc_status)){                             //received notification
202
      switch (_ENDPOINT_P(msg.m_source)){
203
        case HARDWARE:                                          //hardware interrupt notification
204
                if (msg.m_notify.interrupts &keyboard_irq){     // subscribed interrupt (keyboard)
205
206
                  kbc_ih();
207
                  bytes[0]=scan_code;
208
                  bytes[1]=scan_code;
209
210
                  if(bytes[0]==TWO_BYTE_SCANCODE){
211
                    size=2;
212
                  }
213
                  else{
214
                    size=1;
215
                  }
216
217
                  if (scan_code & MAKE_CODE){        //checks if code is make or break
218
                      make = false;        //break code
219
                    }
220
                  else {
221
                    make = true;  //make code
222
                  }
223
224
                  if(kbd_print_scancode(make, size, bytes)!=0){  //prints the code
225
                    printf("Error printing scan code\n");
226
                    return 1;
227
                  }
228
                  count=0;                                      //resets counter, since a keyboard                                                  interruption has ocurred
229
                }
230
                else if (msg.m_notify.interrupts &timer_irq) {  // subscribed interrupt (timer)
231
                  timer_int_handler();              //if a timer interruption occurs increment timer
232
                                        }
233
               break;
234
        default:
235
              break;                                     //no other notifications expected: do nothing
236
        }
237
    }
238
    else {                                         //received a standard message, not a notification
239
      //no standard messages expected: do nothing
240
    }
241
  }
242
243
   if (kbc_unsubscribe_int() != 0) {        //check if unsubscription worked
244
                printf("Error unsubscribing int \n");
245
                return 1;
246
        }
247
248
  if(timer_unsubscribe_int()!=0){           //check if unsubscription worked
249
    printf("Error unsubscribing int\n");
250
    return 1;
251
  }
252
253
  if(kbd_print_no_sysinb(cnt)!=0){                  //prints the number of sys calls
254
    printf("Error printing number of sys used\n");
255
    return 1;
256
  }
257
258
  cnt=0;
259
  scan_code=0;
260
261
  return 0;
262 8 up20180645
}