forked from commanderx16/x16-smc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmouse.cpp
170 lines (150 loc) · 4.37 KB
/
mouse.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "mouse.h"
#include "ps2.h"
#include "smc_pins.h"
extern bool SYSTEM_POWERED;
extern PS2Port<PS2_KBD_CLK, PS2_KBD_DAT, 16> Keyboard;
extern PS2Port<PS2_MSE_CLK, PS2_MSE_DAT, 8> Mouse;
MOUSE_INIT_STATE_T mouse_init_state = OFF;
// Mouse initialization state machine
void MouseInitTick()
{
static bool watchdog_armed = false;
static uint16_t watchdog_timer = 1023;
static MOUSE_INIT_STATE watchdog_expire_state = OFF;
if (mouse_init_state != OFF && SYSTEM_POWERED == 0)
{
mouse_init_state = OFF;
watchdog_armed = false;
watchdog_timer = 1023;
return;
}
if (watchdog_armed) {
if (watchdog_timer == 0) {
mouse_init_state = watchdog_expire_state;
watchdog_armed = false;
}
else {
watchdog_timer--;
}
}
PS2_CMD_STATUS mstatus = Mouse.getCommandStatus();
if (mstatus == PS2_CMD_STATUS::CMD_PENDING)
{
return;
}
switch(mouse_init_state)
{
case OFF:
if (SYSTEM_POWERED != 0) {
mouse_init_state = POWERUP_BAT_WAIT;
// If we don't see the mouse respond, jump to sending it a reset.
MOUSE_WATCHDOG(START_RESET);
}
break;
case POWERUP_BAT_WAIT:
if (Mouse.available()) {
uint8_t b = Mouse.next();
if (b == BAT_OK)
{
mouse_init_state = POWERUP_ID_WAIT;
MOUSE_WATCHDOG(START_RESET); // If we don't see the mouse respond, jump to sending it a reset.
} else if (b == BAT_FAIL) {
mouse_init_state = FAILED;
}
}
break;
case POWERUP_ID_WAIT:
if (Mouse.available()) {
uint8_t b = Mouse.next();
if (b == MOUSE_ID)
{
Mouse.sendPS2Command(mouse_command::SET_SAMPLE_RATE);
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = SAMPLERATECMD_ACK_WAIT;
}
// Watchdog will eventually send us to START_RESET if we don't get MOUSE_ID
}
break;
case PRE_RESET:
mouse_init_state = START_RESET;
break;
case START_RESET:
Mouse.flush();
Mouse.sendPS2Command(mouse_command::RESET);
MOUSE_WATCHDOG(FAILED);
mouse_init_state = RESET_ACK_WAIT;
break;
case RESET_ACK_WAIT:
if (mstatus == mouse_command::ACK) {
Mouse.next();
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = RESET_BAT_WAIT;
} else {
mouse_init_state = FAILED; // Assume an error of some sort.
}
break;
case RESET_BAT_WAIT: // RECEIVE BAT_OK
// expect self test OK
if (Mouse.available()) {
uint8_t b = Mouse.next();
if ( b != mouse_command::BAT_OK ) {
mouse_init_state = FAILED;
} else {
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = RESET_ID_WAIT;
}
}
break;
case RESET_ID_WAIT: // RECEIVE MOUSE_ID, SEND SET_SAMPLE_RATE
// expect mouse ID byte (0x00)
if (Mouse.available()) {
uint8_t b = Mouse.next();
if ( b != mouse_command::MOUSE_ID ) {
mouse_init_state = FAILED;
} else {
Mouse.sendPS2Command(mouse_command::SET_SAMPLE_RATE);
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = SAMPLERATECMD_ACK_WAIT;
}
}
break;
case SAMPLERATECMD_ACK_WAIT: // RECEIVE ACK, SEND 20 updates/sec
Mouse.next();
if (mstatus != mouse_command::ACK)
mouse_init_state = PRE_RESET; // ?? Try resetting again, I guess.
else {
Mouse.sendPS2Command(60);
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = SAMPLERATE_ACK_WAIT;
}
break;
case SAMPLERATE_ACK_WAIT: // RECEIVE ACK, SEND ENABLE
Mouse.next();
if (mstatus != mouse_command::ACK)
mouse_init_state = PRE_RESET;
else {
Mouse.sendPS2Command(mouse_command::ENABLE);
MOUSE_WATCHDOG(START_RESET);
mouse_init_state = ENABLE_ACK_WAIT;
}
break;
case ENABLE_ACK_WAIT: // Receive ACK
Mouse.next();
if (mstatus != mouse_command::ACK) {
mouse_init_state = PRE_RESET;
} else {
mouse_init_state = MOUSE_INIT_DONE;
MOUSE_WATCHDOG_DISARM();
}
break;
case MOUSE_INIT_DONE:
// done
MOUSE_WATCHDOG_DISARM();
mouse_init_state = MOUSE_READY;
break;
case MOUSE_READY:
break;
default:
break;
}
}