Project

General

Profile

Revision 12

All functions working, errors dealt with

View differences:

lab3/Makefile
2 2
PROG=lab3 
3 3

  
4 4
# source code files to be compiled
5
SRCS = lab3.c keyboard.c
5
SRCS = lab3.c keyboard.c timer.c
6 6

  
7 7
# additional compilation flags
8 8
# "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set
lab3/keyboard.c
24 24
  uint8_t status_reg;
25 25

  
26 26
  if(util_sys_inb(STATUS_REG,&status_reg)!=0){ //checks if there is an error
27
    printf("Error reading status register in the keyboard interruption\n");
27 28
    return;
28 29
  }
29 30
  if(((status_reg & STAT_REG_OBF)==0) ||((status_reg&(STAT_REG_PAR|STAT_REG_TIMEOUT))!=0)|| ((status_reg&STAT_REG_AUX)!=0)){ //checks if there is a parity or timeout error (mask -> 0xC0, bit 7 and 6 set), checks if output buffer is empty and checks if there is data coming from the mouse
31
    printf("Parity/Timeout error or output buffer is empty or data coming from the mouse\n");
30 32
    return;
31 33
  }
32
  util_sys_inb(OUTPUT_BUF,&scan_code);
34
  if(util_sys_inb(OUTPUT_BUF,&scan_code)!=0){//checks if there is an error
35
    printf("Error reading output buffer in the keyboard interruption\n");
36
    return;
37
  }
33 38

  
34 39
}
35 40

  
36 41

  
37 42
int (kbc_subscribe_int)(uint8_t *bit_no) {    //similar function to that of timer_subscribe_int
38 43
    *bit_no = BIT(keyboard_id);
39
    if(sys_irqsetpolicy(KEYBOARD_IRQ,(IRQ_REENABLE|IRQ_EXCLUSIVE),&keyboard_id)==1){      //operation to subscribe int
44
    if(sys_irqsetpolicy(KEYBOARD_IRQ,(IRQ_REENABLE|IRQ_EXCLUSIVE),&keyboard_id)==1){  //operation to subscribe int
40 45
        printf("Error subscribing int\n");
41 46
        return 1;
42 47
    }
......
51 56
  return 0;
52 57
}
53 58

  
54
int (enable_interrupt)()
59
int (reenable_interrupt)()
55 60
{
56 61
  uint8_t command;
57 62

  
......
61 66
  }
62 67

  
63 68
  if(util_sys_inb(OUTPUT_BUF, &command)!=0){
64
    printf("Error reading output buffer\n");
69
    printf("Error reading output buffer in enable_interrupt\n");
65 70
    return 1;
66 71
  }
67 72

  
lab3/keyboard.h
48 48
 *
49 49
 * @return Return 0 upon success and non-zero otherwise
50 50
 */
51
int (enable_interrupt)();
51
int (reenable_interrupt)();
52 52

  
53 53
#endif /*_KEYBOARD_H */
lab3/lab3.c
3 3
#include <lcom/lab3.h>
4 4
#include <stdbool.h>
5 5
#include <stdint.h>
6

  
6
#include "timer.h"
7 7
#include "keyboard.h"
8 8

  
9 9

  
......
33 33

  
34 34
extern uint8_t scan_code;
35 35
extern uint32_t cnt;
36
extern int count;
36 37

  
37 38
int(kbd_test_scan)() {
39

  
38 40
  int r, ipc_status;
39 41
  uint8_t keyboard_irq, size, bytes[2]; //size of scancode can be 2 byte long
40 42
  message msg;
41 43
  bool make=false; //to check if code is make or break
42 44

  
43
  if(kbc_subscribe_int(&keyboard_irq)==1){
45
  if(kbc_subscribe_int(&keyboard_irq)!=0){    //check if subscription worked
44 46
    printf("Error subscribing int\n");
45 47
    return 1;
46 48
  }
47 49

  
48
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key
50
  while(scan_code!=ESC_BREAK){            //looping until scan_code is the breakcode of ESC key
51

  
49 52
    if ((r = driver_receive(ANY, &msg, &ipc_status))==1){ 
50 53
      printf("driver_receive failed with: %d",r);
51 54
      continue;
52 55
    }
53
    if (is_ipc_notify(ipc_status)){                             //received notification
56
    if (is_ipc_notify(ipc_status)){                                //received notification
54 57
      switch (_ENDPOINT_P(msg.m_source)){
55
        case HARDWARE:                                          //hardware interrupt notification
56
                if (msg.m_notify.interrupts &keyboard_irq){          // subscribed interrupt
58
        case HARDWARE:                                             //hardware interrupt notification
59
                if (msg.m_notify.interrupts &keyboard_irq){        // subscribed interrupt
57 60
                  
58 61
                  kbc_ih();
59 62
                  bytes[0]=scan_code;
......
67 70
                  }
68 71

  
69 72
                  if (scan_code & MAKE_CODE){	//checks if code is make or break
70
                      make = false;	//break code
73
                      make = false;	          //is break code
71 74
                    }
72 75
                  else {
73
                    make = true;  //make code
76
                    make = true;              //is make code
74 77
                  }
75 78

  
76
                  if(kbd_print_scancode(make, size, bytes)!=0){ //prints the code
79
                  if(kbd_print_scancode(make, size, bytes)!=0){         //prints the code
77 80
                    printf("Error printing scan code\n");
78 81
                    return 1;
79 82
                  }
80 83
                      }
81 84
               break;
82 85
        default:
83
              break;                                            //no other notifications expected: do nothing	
86
              break;                             //no other notifications expected: do nothing	
84 87
        }
85 88
    } 
86
    else {                                                      //received a standard message, not a notification
89
    else {                                       //received a standard message, not a notification
87 90
      //no standard messages expected: do nothing
88 91
    }
89 92
  }
90 93

  
91
   if (kbc_unsubscribe_int() != 0) { // Check if subscription worked
94
   if (kbc_unsubscribe_int() != 0) {            //check if unsubscription worked
92 95
		printf("Error unsubscribing int \n");
93 96
		return 1;
94 97
	}
95 98

  
96
  if(kbd_print_no_sysinb(cnt)!=0){
99
  if(kbd_print_no_sysinb(cnt)!=0){                  //prints the number of sys calls
97 100
    printf("Error printing number of sys used\n");
98 101
    return 1;
99 102
  }
......
105 108
}
106 109

  
107 110
int(kbd_test_poll)() {
111

  
108 112
  uint8_t status, size, bytes[2]; //size of scancode can be 2 byte long
109 113
  bool make=false; //to check if code is make or break
110 114

  
111
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key, can't do interruptions
115
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key, can't do                                     interruptions
116

  
112 117
    if(util_sys_inb(STATUS_REG, &status)!=0){     //checks the status register
113 118
      printf("Error reading status register\n");
114 119
      return 1;
115 120
    }					
116 121

  
117
		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
122
		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
118 123

  
119
			if(util_sys_inb(OUTPUT_BUF, &scan_code)!=0){
124
			if(util_sys_inb(OUTPUT_BUF, &scan_code)!=0){  //reads output buffer
120 125
        printf("Error reading output buffer\n");
121 126
      return 1;
122 127
      }
......
149 154
		}
150 155
  }
151 156

  
152
  if(kbd_print_no_sysinb(cnt)!=0){
157
  if(kbd_print_no_sysinb(cnt)!=0){                      //prints the number of sys calls
153 158
    printf("Error printing number of sys used\n");
154 159
    return 1;
155 160
  }
156 161

  
157
  if(enable_interrupt()!=0){
158
    printf("Coulnd re-enable the interruptions\n");
162
  if(reenable_interrupt()!=0){                          //re-enables interruptions
163
    printf("Couldn't re-enable the interruptions\n");
159 164
    return 1;
160 165

  
161 166
  }
......
165 170
   return 0;
166 171
}
167 172

  
168
int(kbd_test_timed_scan)(uint8_t n) {
169
  /* To be completed by the students */
170
  printf("%s is not yet implemented!\n", __func__);
171 173

  
172
  return 1;
174
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;
173 262
}

Also available in: Unified diff