Project

General

Profile

Revision 11

Added function 5.2, must check for errors

View differences:

lab3/i8042.h
24 24
#define STAT_REG_IBF	   	BIT(1)  /* Input Buffer Full */
25 25
#define STAT_REG_OBF		  BIT(0)  /* Output Buffer Full */
26 26

  
27
#define READ_COMMAND        0x20   /* Returns Command Byte */
28

  
27 29
#define OUTPUT_BUF         0x60    /* Output Buffer */
28 30
#define INPUT_BUF          0x60    /* Input Buffer */
29
#define STATUS_REG        0x64    /* Status Register */
30
#define KBC_CMD_REG     0x64    /* Command Register */
31
#define KBC_CMD_ARG     0x60    /* Command Arguments Adress */
31
#define STATUS_REG         0x64    /* Status Register */
32
#define KBC_CMD_REG        0x64    /* Command Register */
33
#define INT_ENABLE         BIT(0) /*enable interrupt on OBF, from keyboard*/
34
#define KBC_CMD_ARG        0x60    /* Command Arguments Adress */
32 35

  
33
#define ESC_BREAK      0x81
36
#define ESC_BREAK           0x81
34 37
#define TWO_BYTE_SCANCODE   0xE0  /* Two-byte long scancodes use 0xE0 as their first byte */
35
#define MAKE_CODE            BIT(7)
38
#define MAKE_CODE           BIT(7)
36 39

  
37 40
#endif /* _LCOM_I8042_H */
lab3/keyboard.c
26 26
  if(util_sys_inb(STATUS_REG,&status_reg)!=0){ //checks if there is an error
27 27
    return;
28 28
  }
29
  if(((status_reg & STAT_REG_OBF)==0) ||((status_reg&(STAT_REG_PAR|STAT_REG_TIMEOUT))!=0)){ //checks if there is a parity or timeout error (mask -> 0xC0, bit 7 and 6 set) and checks if output buffer is empty
29
  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
30 30
    return;
31 31
  }
32 32
  util_sys_inb(OUTPUT_BUF,&scan_code);
33 33

  
34 34
}
35 35

  
36

  
36 37
int (kbc_subscribe_int)(uint8_t *bit_no) {    //similar function to that of timer_subscribe_int
37 38
    *bit_no = BIT(keyboard_id);
38 39
    if(sys_irqsetpolicy(KEYBOARD_IRQ,(IRQ_REENABLE|IRQ_EXCLUSIVE),&keyboard_id)==1){      //operation to subscribe int
......
49 50
  }
50 51
  return 0;
51 52
}
53

  
54
int (enable_interrupt)()
55
{
56
  uint8_t command;
57

  
58
  if(sys_outb(STATUS_REG,READ_COMMAND)!=0){
59
    printf("Error writing read-command\n");
60
    return 1;
61
  }
62

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

  
68
  command = command | INT_ENABLE;
69

  
70
  if(sys_outb(STATUS_REG,OUTPUT_BUF)!=0){
71
    printf("Error writing output buffer\n");
72
    return 1;
73
  }
74

  
75
  if(sys_outb(OUTPUT_BUF,command)!=0){
76
    printf("Error writing new buffer status\n");
77
    return 1;
78
  }
79

  
80
  return 0;
81
}
lab3/keyboard.h
5 5
#include <lcom/lcf.h>
6 6
#include <stdbool.h>
7 7
#include <stdint.h>
8
#include <minix/syslib.h>
9
#include <minix/sysutil.h>
8 10

  
9 11
#include "i8042.h"
10 12
/**
11
* @brief Handles keyboard interrupts (C implementation)
13
* @brief Handles keyboard interrupts
12 14
*
13
* Reads the status register and the output buffer (OB).
14
* If there was some error, the byte read from the OB should be discarded.
15
* Reads the status register, the output buffer and the mouse data
16
* If there was some error, the byte read from the OB should be discarded
15 17
*
16
* All communication with other code must be done via global variables, static if possible.
18
* All communication with other code must be done via global variables, static if possible
17 19
*
18 20
* Must be defined using parenthesis around the function name:
19 21
*/
......
41 43
 * @return Return 0 upon success and non-zero otherwise
42 44
 */
43 45
int(kbc_unsubscribe_int)();
46
/**
47
 * @brief Enables interrupts (used when polling function ends)
48
 *
49
 * @return Return 0 upon success and non-zero otherwise
50
 */
51
int (enable_interrupt)();
44 52

  
45 53
#endif /*_KEYBOARD_H */
lab3/lab3.c
45 45
    return 1;
46 46
  }
47 47

  
48
  while(scan_code!=ESC_BREAK){      //looping until scann_code is the breakcode of ESC key
48
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key
49 49
    if ((r = driver_receive(ANY, &msg, &ipc_status))==1){ 
50 50
      printf("driver_receive failed with: %d",r);
51 51
      continue;
52 52
    }
53 53
    if (is_ipc_notify(ipc_status)){                             //received notification
54 54
      switch (_ENDPOINT_P(msg.m_source)){
55
        case HARDWARE:                                          //hardware interrupt notification				
55
        case HARDWARE:                                          //hardware interrupt notification
56 56
                if (msg.m_notify.interrupts &keyboard_irq){          // subscribed interrupt
57 57
                  
58 58
                  kbc_ih();
......
72 72
                  else {
73 73
                    make = true;  //make code
74 74
                  }
75
                  kbd_print_scancode(make, size, bytes); //prints the code
75

  
76
                  if(kbd_print_scancode(make, size, bytes)!=0){ //prints the code
77
                    printf("Error printing scan code\n");
78
                    return 1;
79
                  }
76 80
                      }
77 81
               break;
78 82
        default:
......
89 93
		return 1;
90 94
	}
91 95

  
92
  kbd_print_no_sysinb(cnt);
96
  if(kbd_print_no_sysinb(cnt)!=0){
97
    printf("Error printing number of sys used\n");
98
    return 1;
99
  }
93 100

  
101
  cnt=0;
102
  scan_code=0;
103

  
94 104
  return 0;
95 105
}
96 106

  
97 107
int(kbd_test_poll)() {
98
  /* To be completed by the students */
99
  printf("%s is not yet implemented!\n", __func__);
108
  uint8_t status, size, bytes[2]; //size of scancode can be 2 byte long
109
  bool make=false; //to check if code is make or break
100 110

  
101
  return 1;
111
  while(scan_code!=ESC_BREAK){      //looping until scan_code is the breakcode of ESC key, can't do interruptions
112
    if(util_sys_inb(STATUS_REG, &status)!=0){     //checks the status register
113
      printf("Error reading status register\n");
114
      return 1;
115
    }					
116

  
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
118

  
119
			if(util_sys_inb(OUTPUT_BUF, &scan_code)!=0){
120
        printf("Error reading output buffer\n");
121
      return 1;
122
      }
123

  
124
			bytes[0]=scan_code;
125
      bytes[1]=scan_code;
126

  
127
      if(bytes[0]==TWO_BYTE_SCANCODE){
128
        size=2;
129
      }
130
      else{
131
        size=1;
132
      }
133

  
134
      if (scan_code & MAKE_CODE){	           //checks if code is make or break
135
          make = false;	                     //break code
136
        }
137
      else {
138
        make = true;                         //make code
139
      }
140

  
141
      if(kbd_print_scancode(make, size, bytes)!=0){ //prints the code
142
        printf("Error printing scan code\n");
143
        return 1;
144
      }
145
	
146
		}
147
		else { 																		//if the output buffer is not full wait
148
			tickdelay(micros_to_ticks(DELAY_US));		//makes keyboard respond to a command in 20 ms
149
		}
150
  }
151

  
152
  if(kbd_print_no_sysinb(cnt)!=0){
153
    printf("Error printing number of sys used\n");
154
    return 1;
155
  }
156

  
157
  if(enable_interrupt()!=0){
158
    printf("Coulnd re-enable the interruptions\n");
159
    return 1;
160

  
161
  }
162
  cnt=0;
163
  scan_code=0;
164

  
165
   return 0;
102 166
}
103 167

  
104 168
int(kbd_test_timed_scan)(uint8_t n) {

Also available in: Unified diff