Project

General

Profile

Revision 78

fixed ack reading issue. added statemachine, still not working

View differences:

lab4/Makefile
2 2
PROG=lab4
3 3

  
4 4
# source code files to be compiled
5
SRCS = lab4.c mouse.c utils.c kbc.c keyboard.c timer.c
5
SRCS = lab4.c mouse.c utils.c kbc.c keyboard.c timer.c state_machine.c
6 6

  
7 7
# additional compilation flags
8 8
# "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set
lab4/errors.h
11 11
    WRITE_ERROR,        /* @brief Error on Writing to Port */
12 12
    TIMEOUT_ERROR,      /* @brief Timeout error */
13 13
    INVALID_COMMAND,    /* @brief Invalid Command issued */
14
    INVALID_STATE,      /* @brief State machine reached an invalid state */
14 15
    OTHER_ERROR,        /* @brief Unspecified error */
15 16
};
16 17

  
lab4/kbc.c
67 67
    int ret = 0;
68 68
    uint8_t stat;
69 69
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
70
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;//printf("kbc.c,L71\n");
71
        printf("%x %d %d\n", stat, (stat&OUT_BUF_FUL), (stat&AUX_MOUSE));
72
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){//printf("kbc.c,L72\n");
73
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;//printf("kbc.c,L73\n");
70
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
71
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
72
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
74 73
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
75 74
            else return SUCCESS;
76 75
        }
lab4/lab4.c
7 7
#include "kbc.h"
8 8
#include "errors.h"
9 9
#include "mouse_macros.h"
10
#include "kbc_macros.h"
10 11
#include "timer.h"
12
#include "state_machine.h"
11 13

  
12 14
int main(int argc, char *argv[]) {
13 15
  // sets the language of LCF messages (can be either EN-US or PT-PT)
......
95 97
    // return value
96 98
    int ret;
97 99

  
100
    if ((ret = mouse_issue_cmd(SET_REMOTE_MD))) return ret;
101

  
102
    if ((ret = mouse_set_data_report(true))) return ret;
103

  
104
    uint8_t cmd = 0;
105
    if ((ret = kbc_read_cmd(&cmd))) return ret;
106

  
98 107
    while (good) {
99 108

  
100 109
        if ((ret = mouse_read_data(&data))) return ret;
......
103 112
            packet[sz] = data;
104 113
            sz++;
105 114
        }
106

  
107 115
        if (sz == 3) {
108 116
            struct packet pp = mouse_parse_packet(packet);
109 117
            mouse_print_packet(&pp);
......
111 119
            sz = 0;
112 120
            if (packetCounter == cnt) good = 0;
113 121
        }
114

  
115 122
        tickdelay(micros_to_ticks(period*1e3));
116 123
    }
117 124

  
......
119 126
    if ((ret = mouse_issue_cmd(SET_STREAM_MD))) return ret;
120 127
    // Disable data reporting
121 128
    if ((ret = mouse_set_data_report(false))) return ret;
122

  
123 129
    uint8_t cmd_byte = minix_get_dflt_kbc_cmd_byte();
124 130
    if ((ret = kbc_change_cmd(cmd_byte))) return ret;
125 131

  
......
188 194
    return 0;
189 195
}
190 196

  
191
enum state{
192
    STATE_NEUTRAL,
193
    STATE_FIRST,
194
    STATE_MID,
195
    STATE_SECOND
196
};
197

  
198 197
int (mouse_test_gesture)(uint8_t x_len, uint8_t tolerance) {
199
    int ret = 0;
200 198
    /// loop stuff
201 199
    int ipc_status, r;
202 200
    message msg;
......
205 203
    int mouse_id = 0;
206 204
    int mouse_irq = BIT(mouse_irq_bit);
207 205
    //if ((ret = mouse_set_data_report(true))) return ret;
208
    if ((ret = mouse_enable_data_reporting())) return ret;
206
    if (mouse_enable_data_reporting()) return 1;
209 207

  
210 208
    if (subscribe_mouse_interrupt(mouse_irq_bit, &mouse_id)) return 1;
211 209
    /// cycle
212 210
    int good = 1;
213
    //int st = STATE_NEUTRAL;
214
    //int16_t dx, dy;
211

  
212
    // mouse event gesture
213
    struct mouse_ev *event;
214
    struct packet pp;
215
    int response;
216

  
215 217
    while (good) {
216 218
        /* Get a request message. */
217 219
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
......
223 225
                case HARDWARE: /* hardware interrupt notification */
224 226
                    if (msg.m_notify.interrupts & mouse_irq) { /* subscribed interrupt */
225 227
                        mouse_ih();
226
                        if(counter >= 3){
227
                            struct packet pp = mouse_parse_packet(packet);
228
                            mouse_print_packet(&pp);/*
229
                            switch(st){
230
                                case STATE_NEUTRAL:
231
                                    if(pp.lb == 1 && pp.mb == 0 && pp.rb == 0){
232
                                        st = STATE_FIRST;
233
                                        dx = 0;
234
                                        dy = 0;
235
                                    }
236
                                    break;
237
                                case STATE_FIRST:
238
                                    if(pp.lb == 1){
239
                                        if(pp.delta_x >= -tolerance && pp.delta_y >= -tolerance){
240
                                            dx += pp.delta_x;
241
                                            dy += pp.delta_y;
242
                                        }else{
243
                                            st = STATE_NEUTRAL;
244
                                        }
245
                                    }else{
246
                                        if(abs(dx) < abs(dy) && dx > 0 && dy > 0){
247
                                            st = STATE_MID;
248
                                        }else{
249
                                            st = STATE_NEUTRAL;
250
                                        }
251
                                    }
252
                                    break;
253
                                case STATE_MID:
254
                                    if(pp.lb == 0 && pp.mb == 0 && pp.rb == 1){
255
                                        st = STATE_SECOND;
256
                                        dx = 0;
257
                                        dy = 0;
258
                                    }else{
259
                                        st = STATE_NEUTRAL;
260
                                    }
261
                                    break;
262
                                case STATE_SECOND:
263
                                    if(pp.rb == 1){
264
                                        if(pp.delta_x >= -tolerance && pp.delta_y <= tolerance){
265
                                            dx += pp.delta_x;
266
                                            dy += pp.delta_y;
267
                                        }else{
268
                                            st = STATE_NEUTRAL;
269
                                        }
270
                                    }else{
271
                                        if(abs(dx) < abs(dy) && dx > 0 && dy < 0){
272
                                            st = STATE_NEUTRAL;
273
                                            good = false;
274
                                        }else{
275
                                            st = STATE_NEUTRAL;
276
                                        }
277
                                    }
278
                                    break;
279
                                default:
280
                                    return OTHER_ERROR;
281
                                    break;
282
                            }*/
228
                        if(counter >= 3) {
229
                            pp = mouse_parse_packet(packet);
230
                            //mouse_print_packet(&pp);
231
                            event = mouse_get_event(&pp);
232

  
233
                            response = state_machine(event, x_len, tolerance);
234

  
235
                            if (response == SUCCESS)
236
                                good = 0;
237
                            else if (response == INVALID_STATE)
238
                                return response;
283 239
                        }
284 240
                    }
285 241
                    break;
lab4/mouse.c
81 81
int (mouse_issue_cmd)(uint32_t cmd) {
82 82
    int ret;
83 83
    uint8_t ack = 0;
84
    if ((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
85
    if ((ret = kbc_issue_arg(cmd))) return ret;
86
    if ((ret = mouse_read_ack(&ack))) return ret;
87
    if (ack == ACK_OK) return SUCCESS;
88
    if (ack == ACK_ERROR) return INVALID_COMMAND;
89
    return OTHER_ERROR;
84
    for (unsigned int i = 0; i < KBC_NUM_TRIES; i++) {
85
        if ((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
86
        if ((ret = kbc_issue_arg(cmd))) return ret;
87
        if ((ret = mouse_read_ack(&ack))) return ret;
88

  
89
        if (ack == ACK_OK) return SUCCESS;
90
        if (ack == ACK_ERROR) return INVALID_COMMAND;
91
        tickdelay(micros_to_ticks(DELAY));
92
    }
93
    return TIMEOUT_ERROR;
90 94
}
91 95

  
92 96
int (mouse_read_byte)(uint8_t *byte) {
lab4/state_machine.c
1
#include <lcom/lcf.h>
2

  
3
#include "state_machine.h"
4
#include "mouse_macros.h"
5
#include "mouse.h"
6
#include "errors.h"
7

  
8
struct mouse_ev* mouse_get_event(struct packet *pp) {
9

  
10
    static struct mouse_ev event;
11
    static struct packet last; // compare consecutive events
12
    static int aux = 1; // first iteration
13

  
14
    if (pp == NULL)
15
        return &event;
16

  
17
    // current packet
18
    uint8_t lb_press = pp->bytes[0] & LEFT_BUTTON;
19
    uint8_t rb_press = pp->bytes[0] & RIGHT_BUTTON;
20
    uint8_t mb_press = pp->bytes[0] & MIDDLE_BUTTON;
21
    int16_t delta_x = sign_extend_byte(pp->bytes[0] & MSB_X_DELTA, pp->bytes[1]);
22
    int16_t delta_y = sign_extend_byte(pp->bytes[0] & MSB_Y_DELTA, pp->bytes[2]);
23

  
24
    if (aux) { // first event detected
25
        if (lb_press && (rb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0)
26
            event.type = LB_PRESSED;
27
        else if (rb_press && (lb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0)
28
            event.type = RB_PRESSED;
29
        else if ((delta_x || delta_y) && (lb_press | rb_press | mb_press) == 0) {
30
            event.type = MOUSE_MOV;
31
            event.delta_x = delta_x;
32
            event.delta_y = delta_y;
33
        } else
34
            event.type = BUTTON_EV;
35
        aux = 0;
36
    } else {
37
        // last packet
38
        uint8_t last_lb_press = last.bytes[0] & LEFT_BUTTON;
39
        uint8_t last_rb_press = last.bytes[0] & RIGHT_BUTTON;
40
        uint8_t last_mb_press = last.bytes[0] & MIDDLE_BUTTON;
41

  
42
        if (lb_press && (rb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0 && last_lb_press == 0)
43
            event.type = LB_PRESSED;
44
        else if (rb_press && (lb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0 && last_rb_press == 0)
45
            event.type = RB_PRESSED;
46
        else if ((lb_press | rb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0 && last_lb_press)
47
            event.type = LB_RELEASED;
48
        else if ((lb_press | rb_press | mb_press) == 0 && delta_x == 0 && delta_y == 0 && last_rb_press)
49
            event.type = RB_RELEASED;
50
        else if ((delta_x || delta_y) && (lb_press | rb_press | mb_press) == (last_lb_press | last_rb_press | last_mb_press)) {
51
            event.type = MOUSE_MOV;
52
            event.delta_x = delta_x;
53
            event.delta_y = delta_y;
54
        } else
55
            event.type = BUTTON_EV;
56
    }
57

  
58
    // update last packet for comparison
59
    last = *pp;
60

  
61
    return &event;
62
}
63

  
64
int state_machine(struct mouse_ev* event, uint8_t x_len, uint8_t tolerance) {
65

  
66
    static enum states state = INITIAL;
67
    static int response = OTHER_ERROR;
68
    static int x_length = 0;
69
    static int y_length = 0;
70

  
71
    if (event == NULL)
72
        return response;
73

  
74
    switch (state) {
75
        case INITIAL:
76
            if (event->type == LB_PRESSED)
77
                state = DRAG_UP;
78
            break;
79
        case DRAG_UP:
80
            if (event->type == MOUSE_MOV) {
81
                if (abs(event->delta_x) > tolerance || abs(event->delta_y) > tolerance) {
82
                    state = INITIAL;
83
                    x_length = 0;
84
                    y_length = 0;
85
                    break;
86
                }
87

  
88
                x_length += event->delta_x;
89
                y_length += event->delta_y;
90
            } else if (event->type == LB_RELEASED) {
91
                if (x_length == 0 || y_length == 0) {
92
                    state = INITIAL;
93
                    break;
94
                }
95

  
96
                int slope = y_length / x_length;
97

  
98
                if (slope <= 1 || x_length < x_len) {
99
                    state = INITIAL;
100
                    x_length = 0;
101
                    y_length = 0;
102
                    break;
103
                }
104

  
105
                state = VERTEX;
106
                x_length = 0;
107
                y_length = 0;
108
            } else {
109
                state = INITIAL;
110
                x_length = 0;
111
                y_length = 0;
112
            }
113
            break;
114
        case VERTEX:
115
            if (event->type == MOUSE_MOV) {
116
                if (abs(event->delta_x) > tolerance || abs(event->delta_y) > tolerance)
117
                    state = INITIAL;
118
            } else if (event->type == RB_PRESSED) {
119
                state = DRAG_DOWN;
120
            } else if (event->type == LB_PRESSED) {
121
                state = DRAG_UP;
122
            } else
123
                state = INITIAL;
124
            break;
125
        case DRAG_DOWN:
126
            if (event->type == MOUSE_MOV) {
127
                if (abs(event->delta_x) > tolerance || abs(event->delta_y) > tolerance) {
128
                    state = INITIAL;
129
                    x_length = 0;
130
                    y_length = 0;
131
                    break;
132
                }
133

  
134
                x_length += event->delta_x;
135
                y_length += event->delta_y;
136
            } else if (event->type == RB_RELEASED) {
137
                if (x_length == 0 || y_length == 0) {
138
                    state = INITIAL;
139
                    break;
140
                }
141

  
142
                int slope = y_length / x_length;
143

  
144
                if (slope >= -1 || x_length < x_len) {
145
                    state = INITIAL;
146
                    x_length = 0;
147
                    y_length = 0;
148
                    break;
149
                }
150

  
151
                state = FINAL;
152
                x_length = 0;
153
                y_length = 0;
154
            } else {
155
                state = INITIAL;
156
                x_length = 0;
157
                y_length = 0;
158
            }
159
            break;
160
        case FINAL: // acception state
161
            response = SUCCESS;
162
        default: // invalid state / dead state
163
            response = INVALID_STATE;
164
    }
165
    return response;
166
}
0 167

  
lab4/state_machine.h
1
#ifndef _STATE_MACHINE_H_
2
#define _STATE_MACHINE_H_
3

  
4
/**
5
 * @brief States of state machine
6
 */
7
enum states {
8
    INITIAL,
9
    DRAG_UP,
10
    VERTEX,
11
    DRAG_DOWN,
12
    FINAL
13
};
14

  
15
/**
16
 *
17
 */
18
struct mouse_ev* mouse_get_event(struct packet *pp);
19

  
20
/**
21
 *
22
 */
23
int state_machine(struct mouse_ev* event, uint8_t x_len, uint8_t tolerance);
24

  
25
#endif /* end of include guard: _STATE_MACHINE_H_ */
0 26

  

Also available in: Unified diff