Project

General

Profile

Revision 16

added function 1 and 2, working

View differences:

lab4/lab4.c
4 4
#include <stdint.h>
5 5
#include <stdio.h>
6 6
#include "mouse.h"
7
#include "timer.h"
7 8

  
8 9
// Any header files included below this line should have been created by you
9 10

  
......
32 33
}
33 34

  
34 35
extern uint8_t byte;
36
extern int mouse_id;
35 37

  
36 38
int (mouse_test_packet)(uint32_t cnt) {
37 39
  int r, ipc_status;
38
  uint8_t mouse_irq, size=0; //size of mouse packet is 3 byte long
40
  uint8_t mouse_irq;
41
  unsigned int size=0; //size of mouse packet is 3 byte long
39 42
  message msg;
40
  uint32_t counter_copy=cnt;
43
  uint32_t counter_pp=0;
41 44

  
42 45
  struct packet pp;
43 46

  
44
  if(mouse_enable_data_reporting()!=0){     //check if disabling stream mode worked
47
  
48
  //mouse_enable_data_reporting();
49
  
50
  //sys_irqdisable(&mouse_id);
51
  if(write_cmd_mouse(0xF4)!=0){     //check if disabling stream mode worked (0xF4 is the byte to disable data report)
45 52
    printf("Error disabling stream mode\n");
46 53
    return 1;
47 54
  }
55
  //sys_irqenable(&mouse_id);
48 56

  
49
  if(mouse_subscribe_int(&kmouse_irq)!=0){    //check if subscription worked
57
  if(mouse_subscribe_int(&mouse_irq)!=0){    //check if subscription worked
50 58
    printf("Error subscribing int\n");
51 59
    return 1;
52 60
  }
61
  
53 62

  
54
  while(counter_copy>0){            //looping until counter>0
63
  while (cnt > counter_pp)
64
	{ /* ends when it has printed the number in ctn */
65
		/*Get a request message.*/
66
		if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0)
67
		{
68
			printf("ERROR: driver_receive failed with: %d", r);
69
			continue;
70
		}
71
		if (is_ipc_notify(ipc_status))
72
		{ // received notification
73
			switch (_ENDPOINT_P(msg.m_source))
74
			{
75
			case HARDWARE: // hardware interrupt notification
76
				if (msg.m_notify.interrupts & mouse_irq)
77
				{				// subscribed interrupt
78
					mouse_ih(); //must read only one byte
79
					if ((size == 0 && (BIT(3) & byte)) || size == 1 ||size ==2)
80
					{								   //access the struct bytes
81
						pp.bytes[size] = byte; // bytes 0, 1 or 2
82
						size++;				   // increments the counter to know in the next interrupt
83
					}
84
					if (size == 3)  // 3 bytes haven been read and there's no error
85
					{							
86
						size = 0;			// reset to start counting new packets
87
						parse_packet(&pp); // parses packet
88
						mouse_print_packet(&pp); // prints packet
89
						counter_pp++;			//counts the prints for the end of the loop
90
					}
91
				}
92
				break;
93
			default:
94
				break; // no other notifications expected: do nothing
95
			}
96
		}
97
		else
98
		{   // received a standard message, not a notification
99
			// no standard messages expected: do nothing
100
		}
101
	}
55 102

  
56
    if ((r = driver_receive(ANY, &msg, &ipc_status))==1){ 
57
      printf("driver_receive failed with: %d",r);
58
      continue;
103
  if (mouse_unsubscribe_int() != 0) {            //check if unsubscription worked
104
		printf("Error unsubscribing int \n");
105
		return 1;
106
	}
107

  
108
  if(write_cmd_mouse(0xF5)!=0){     //check if disabling stream mode worked (0xF5 is the byte to disable data report)
109
    printf("Error disabling stream mode\n");
110
    return 1;
111
  }
112

  
113

  
114
  byte=0;
115

  
116
  return 0;
117
}
118

  
119
int (mouse_test_remote)(uint16_t period, uint8_t cnt) {
120
  uint8_t counter_pp=0, status;
121

  
122
  struct packet pp;
123

  
124
  /*if(write_cmd_mouse(0xF5)!=0){     //check if disabling stream mode worked (0xF5 is the byte to disable data report)
125
    printf("Error disabling stream mode\n");
126
    return 1;
127
  }
128

  
129
  if(write_cmd_mouse(0xF0)!=0){     //check if enabling remote mode worked (0xF0 is the byte to enable remote mode)
130
    printf("Error disabling stream mode\n");
131
    return 1;
132
  }*/
133
  
134

  
135
  while (cnt > counter_pp)
136
	{ /* ends when it has printed the number in ctn */
137
    if(write_cmd_mouse(0xEB)!=0){     //check if enabling remote mode worked (0xF0 is the byte to enable remote mode)
138
      printf("Error disabling stream mode\n");
139
      return 1;
59 140
    }
60
    if (is_ipc_notify(ipc_status)){                                //received notification
61
      switch (_ENDPOINT_P(msg.m_source)){
62
        case HARDWARE:                                             //hardware interrupt notification
63
                if (msg.m_notify.interrupts &mouse_irq){        // subscribed interrupt
64
                  
65
                  mouse_ih();
66
                  if((size==0 && ((byte&0x08)==0x08)) || size==1 ||size==2){      //0x08 is the mask to check if the 3rd bit of the first byte is set
67
                    pp.bytes[size]=byte;
68
                    size++;
69
                  }
70
                  if(size==3){
71
                    size=0;
72
                    parse_packet(&pp);
73
                    mouse_print_packet(&pp);
74
                    counter_copy--;
75
                  }
76
                }
77
               break;
78
        default:
79
              break;                             //no other notifications expected: do nothing	
141

  
142
    if(util_sys_inb(STATUS_REG,&status)!=0){
143
      printf("Error verifying the status of buffer\n");
144
      return 1;
145
    }
146

  
147
    if((status & 0x01)==0x01){
148

  
149
      if((status & (STAT_REG_PAR|STAT_REG_TIMEOUT))==0){
150

  
151
        for(int size=0;size<3;size++){
152

  
153
          if(util_sys_inb(OUTPUT_BUF,&byte)!=0){
154
          printf("Error reading output_buf\n");
155
          return 1;
156
          }
157

  
158
          if (size == 0 && (BIT(3) & byte)){								   //    access the struct bytes
159
            pp.bytes[size] = byte; // bytes 0, 1 or 2
160
            //continue;
161
          }
162
          if(size==1){
163
            pp.bytes[size] = byte; // bytes 0, 1 or 2
164
            //continue;
165
          }
166
          if(size==2){
167
            pp.bytes[size] = byte;
168
          
169
          }
80 170
        }
81
    } 
82
    else {                                       //received a standard message, not a notification
83
      //no standard messages expected: do nothing
171
        parse_packet(&pp); // parses packet
172
        mouse_print_packet(&pp); // prints packet
173

  
174
      }
84 175
    }
85
  }
176
    counter_pp++;			//counts the prints for the end of the loop
177
    tickdelay(micros_to_ticks(period*1000));
178
  
179
	}
86 180

  
87
   if (mouse_unsubscribe_int() != 0) {            //check if unsubscription worked
181
  if (write_cmd_mouse(0xEA)!=0) {            //check if set stream mode worked (0xEA is the byte to enable)
88 182
		printf("Error unsubscribing int \n");
89 183
		return 1;
90 184
	}
91
  scan_code=0;
92 185

  
186
  if(write_cmd_mouse(0xF5)!=0){     //check if disabling data report worked (0xF5 is the byte to disable data report)
187
    printf("Error disabling stream mode\n");
188
    return 1;
189
  }
190

  
191
  if (sys_outb(0X64,0x60)!=0)
192
	{ // Sends Write Command
193
		printf("Could not reset KBC command byte to default!");
194
		return 1;
195
	}
196
  uint8_t default_cmd=minix_get_dflt_kbc_cmd_byte();
197
	if (sys_outb(0x60,default_cmd)!=0)
198
	{ // Writes Command Byte
199
		printf("Could not reset KBC command byte to default!");
200
		return 1;
201
	}
202

  
203
  byte=0;
204

  
93 205
  return 0;
94 206
}
95 207

  
96
int (mouse_test_remote)(uint16_t period, uint8_t cnt) {
97
    /* To be completed */
98
    printf("%s(%u, %u): under construction\n", __func__, period, cnt);
99
    return 1;
100
}
101

  
102 208
int (mouse_test_async)(uint8_t idle_time) {
103 209
    /* To be completed */
104 210
    printf("%s(%u): under construction\n", __func__, idle_time);
105 211
    return 1;
106 212
}
107 213

  
108
int (mouse_test_gesture)() {
214
int (mouse_test_gesture)(uint8_t x_len, uint8_t tolerance) {
109 215
    /* To be completed */
110 216
    printf("%s: under construction\n", __func__);
111 217
    return 1;
lab4/mouse.c
1
#include "mouse.c"
1
#include "mouse.h"
2
#include <lcom/lcf.h>
2 3

  
3 4
uint8_t byte;
5
int mouse_id=2; //KBD_AUX_IRQ is defined in interrupt.h in .minix-src folder
4 6

  
5 7
int (util_sys_inb)(int port, uint8_t *value) { //transform 8 bit into 32 bit
6 8

  
......
19 21
}
20 22

  
21 23
void (mouse_ih)(void){
24
  //kbc_read_out_buf(&byte);
22 25
  uint8_t status_reg;
23 26

  
24
  if(util_sys_inb(STATUS_REG,&status_reg)!=0){ //checks if there is an error
25
    printf("Error reading status register in the keyboard interruption\n");
26
    return;
27
  for(int i=0; i<10;i++){
28
    if(util_sys_inb(STATUS_REG,&status_reg)!=0){ //checks if there is an error
29
      printf("Error reading status register in the mouse interruption\n");
30
      return;
31
    }
32
    if((status_reg & OUTPUT_BUF)!=0){
33
      if((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), checks if output buffer is empty
34
      printf("Parity/Timeout error or output buffer is empty or data coming from the mouse\n");
35
      return;
36
      }
37

  
38
      if(util_sys_inb(OUTPUT_BUF,&byte)!=0){//checks if there is an error
39
      printf("Error reading output buffer in the mouse interruption\n");
40
      return;
41
      }
42

  
43
    }
44
    tickdelay(micros_to_ticks(DELAY_US));
27 45
  }
28
  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), checks if output buffer is empty
29
    printf("Parity/Timeout error or output buffer is empty or data coming from the mouse\n");
30
    return;
31
  }
32
  if(util_sys_inb(OUTPUT_BUF,&byte)!=0){//checks if there is an error
33
    printf("Error reading output buffer in the keyboard interruption\n");
34
    return;
35
  }
46
  return;
36 47

  
37 48
}
38 49

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

  
48 59
int (mouse_unsubscribe_int)() {           //similar function to that of timer_unsubscribe_int
49
  if(sys_irqrmpolicy(&keyboard_id)==1){
60
  if(sys_irqrmpolicy(&mouse_id)==1){
50 61
      printf("Error unsubscribing int\n");
51 62
      return 1;
52 63
  }
......
92 103
    pp->lb=false;
93 104
  }
94 105

  
95
  if((pp->bytes[0]&0x20)==0x20){ //it means y_delta is negative
96
    pp->delta_y=~pp->bytes[2];
97
    pp->delta_y+=1;
106
  if((pp->bytes[0] &0x10)==0x10){
107
    pp->delta_x = pp->bytes[1] -256;
108
  }
109
  else{
110
    pp->delta_x = pp->bytes[1];
111
  }
98 112

  
113
  if((pp->bytes[0]&0x20)==0x20){
114
    pp->delta_y = pp->bytes[2] -256;
99 115
  }
100 116
  else{
101
    pp->delta_y=pp->bytes[2];
117
    pp->delta_y = pp->bytes[2];
102 118
  }
103 119

  
104
  if((pp->bytes[0]&0x10)==0x10){ //it means x_delta is negative
105
    pp->delta_x=~pp->bytes[1];
106
    pp->delta_x+=1;
120
  return 0;
121
}
107 122

  
123
/*int kbc_write(int port, uint8_t cmd) {
124
	uint8_t status;
125
	int retry = 0;
126

  
127
	while (retry < 10) {
128
		if(util_sys_inb(STATUS_REG, &status)!=0){
129
      printf("Error in kbc_write");
130
      return 1;
131
    }
132

  
133
		//... Checking if IN_BUF is OK to write to
134
		if ((status & 0x02)!=0) {
135
			//.... Writing the command
136
			if (sys_outb(port, cmd)!=0) {
137
        printf("Error");
138
				return 1;
139
			}
140
			return 0;
141
		}
142

  
143
		//tickdelay(micros_to_ticks(DELAY_US));	// IF NOT EMPTY wait for IN_BUF to be empty
144
		retry++;
145
	}
146

  
147
	return 1;
148
}
149

  
150
int read_out_buf(uint8_t *content) {
151
	uint8_t status;
152
	uint8_t content8; // 8-bit content
153
	int retry = 0;
154

  
155
	while (retry < 4) {
156
		util_sys_inb(STATUS_REG, &status);
157

  
158
		//... Checking if there is any error and if the byte came from AUX
159
		if (((status_reg & STAT_REG_OBF)==0) ||((status_reg&(STAT_REG_PAR|STAT_REG_TIMEOUT))!=0)||((status_reg&STAT_REG_AUX)==0)) { // Parity or Timeout error, invalid data
160
			return 1;
161
		}
162

  
163
		//... Checking if OUT_BUF is FULL to read
164
		if (status & STAT_REG_OBF) {
165
			//... Reading the Output Buffer
166
			if (UTIL_sys_inb(OUTPUT_BUF, &content8)) {
167
				return 1;
168
			}
169
			// The information in address content now contains content32 in 8-bit
170
			*content = (uint8_t)content8;
171
			return 0;
172
		}
173

  
174
		tickdelay(micros_to_ticks(DELAY_US));	// IF NOT EMPTY wait for IN_BUF to be empty
175
		retry++;
176
	}
177

  
178
	return 1;
179
}
180

  
181

  
182
int kbc_write_mouse_command(uint8_t cmd) {
183
	uint8_t response;
184

  
185
	if(kbc_write(KBC_CMD_REG, 0xD4)!=0){
186
    printf("Error");
187
    return 1;
108 188
  }
109
  else{
110
    pp->delta_y=pp->bytes[1];
189
	if(kbc_write(INPUT_BUF, cmd)!=0){
190
    printf("Error");
191
    return 1;
111 192
  }
112
}
193
	tickdelay(micros_to_ticks(DELAY_US));
194
	if(kbc_read_out_buf(&response)!=0){
195
    printf("Error");
196
    return 1;
197
  }
198
	
199
	// Checking if invalid byte
200
	if (response != 0xFA) {
201
		// repeat process if invalid
202
		kbc_write(KBC_CTRL_REG, 0xD4);
203
		kbc_write(INPUT_BUF, cmd);
204
		tickdelay(micros_to_ticks(DELAY_US));
205
		kbc_read_out_buf(&response);
206
		// Checking if second consecutive invalid byte
207
		if (response == 0xFC){
208
			return 1;
209
    }
210
	}
211

  
212
	return 0;
213
}*/
214

  
215
int write_cmd_mouse(uint8_t cmd)
216
{
217
  uint8_t status_reg, ack;
218

  
219
  do
220
  {
221
    if (util_sys_inb(STATUS_REG, &status_reg) != 0){
222
      return 1;
223
    }
224
      
225
    if ((status_reg & STAT_REG_IBF) == 0){
226
      if (sys_outb(KBC_CMD_REG, 0xD4) != 0){ //0xD4 -> code to write byte to mouse
227
        return 1;
228
      }
229
    }
230
    else
231
      continue;
232

  
233
    if (util_sys_inb(STATUS_REG, &status_reg) != 0){
234
      return 1;
235
    }
236

  
237
    if ((status_reg & STAT_REG_IBF) == 0){
238
      if (sys_outb(OUTPUT_BUF, cmd) != 0){
239
        return 1;
240
      }
241
    }
242
    else
243
      continue;
244

  
245
    tickdelay(micros_to_ticks(DELAY_US));
246

  
247
    if (util_sys_inb(INPUT_BUF, &ack) != 0){
248
      return 1;
249
    }
250

  
251
  } while (ack != 0xFA);            // 0xFA -> mask that checks if everything is ok
252

  
253
  return 0;
254
}
lab4/mouse.h
1 1
#ifndef _MOUSE_H
2 2
#define _MOUSE_H
3 3

  
4
#include <lcom/lcf.h>
4

  
5 5
#include <stdbool.h>
6 6
#include <stdint.h>
7 7
#include <minix/syslib.h>
......
43 43
 */
44 44
int(mouse_unsubscribe_int)();
45 45
/**
46
 * @brief Sets up packet
46 47
 *
47
 *
48
 *
48
 * @return Return 0 upon success and non-zero otherwise
49 49
 */
50
int(parse_packet)(struct packet *pp);
50
int(parse_packet)(struct packet *pp);
51
/**
52
* @brief Writes commands to the mouse
53
*
54
* @return Return 0 upon success and non-zero otherwise
55
*/
56
int(write_cmd_mouse)(uint8_t cmd);
57
/**
58
*
59
*
60
*
61
*/
62
int kbc_write(int port, uint8_t cmd);
63
/**
64
*
65
*
66
*
67
*/
68
#endif /*_MOUSE_H */

Also available in: Unified diff