| User | Revision | Line number | New contents of line |
| vcazan |
0:eb315142ac34
|
1
|
#include "mbed.h"
|
| vcazan |
0:eb315142ac34
|
2
|
|
| vcazan |
0:eb315142ac34
|
3
|
DigitalOut PSclock(p21);
|
| vcazan |
0:eb315142ac34
|
4
|
DigitalIn PSdata(p22);
|
| vcazan |
0:eb315142ac34
|
5
|
DigitalIn PSack(p23);
|
| vcazan |
0:eb315142ac34
|
6
|
DigitalOut PScommand(p24);
|
| vcazan |
0:eb315142ac34
|
7
|
DigitalOut PSattention(p25);
|
| vcazan |
0:eb315142ac34
|
8
|
|
| vcazan |
0:eb315142ac34
|
9
|
Serial pc(USBTX, USBRX); // tx, rx
|
| vcazan |
0:eb315142ac34
|
10
|
int temp, data0, data1, data2, data3, data4, data5, i ,debounceSelect;
|
| vcazan |
0:eb315142ac34
|
11
|
|
| vcazan |
0:eb315142ac34
|
12
|
// enable interupts
|
| vcazan |
0:eb315142ac34
|
13
|
|
| vcazan |
0:eb315142ac34
|
14
|
int _BV(int bit) {
|
| vcazan |
0:eb315142ac34
|
15
|
return 1 << bit;
|
| vcazan |
0:eb315142ac34
|
16
|
}
|
| vcazan |
0:eb315142ac34
|
17
|
|
| vcazan |
0:eb315142ac34
|
18
|
// PSx controller communication function.
|
| vcazan |
0:eb315142ac34
|
19
|
// send a byte on the command line and receive one on the data line.
|
| vcazan |
0:eb315142ac34
|
20
|
// needs Attention pin to have gone low before called to activate controller.
|
| vcazan |
0:eb315142ac34
|
21
|
char gameByte (char command) {
|
| vcazan |
0:eb315142ac34
|
22
|
wait_us(1);
|
| vcazan |
0:eb315142ac34
|
23
|
char data = 0x00; // clear data variable to save setting low bits later.
|
| vcazan |
0:eb315142ac34
|
24
|
for (int i=0; i<8; i++) {
|
| vcazan |
0:eb315142ac34
|
25
|
if (command & _BV(i)) {
|
| vcazan |
0:eb315142ac34
|
26
|
PScommand=1; // bit bang "command" out on PScommand wire.
|
| vcazan |
0:eb315142ac34
|
27
|
} else {
|
| vcazan |
0:eb315142ac34
|
28
|
PScommand = 0;
|
| vcazan |
0:eb315142ac34
|
29
|
}
|
| vcazan |
0:eb315142ac34
|
30
|
PSclock = 0; // CLOCK LOW
|
| vcazan |
0:eb315142ac34
|
31
|
wait_us(20); // wait for output to stabilise
|
| vcazan |
0:eb315142ac34
|
32
|
//if ((PIND & _BV(PSdata)))_SFR_BYTE(data) |= _BV(i); // read PSdata pin and store
|
| vcazan |
0:eb315142ac34
|
33
|
//else cbi(data, i);
|
| vcazan |
0:eb315142ac34
|
34
|
PSclock = 1; // CLOCK HIGH
|
| vcazan |
0:eb315142ac34
|
35
|
}
|
| vcazan |
0:eb315142ac34
|
36
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
37
|
|
| vcazan |
0:eb315142ac34
|
38
|
wait_us(20); // wait for ACK to pass.
|
| vcazan |
0:eb315142ac34
|
39
|
|
| vcazan |
0:eb315142ac34
|
40
|
return data;
|
| vcazan |
0:eb315142ac34
|
41
|
}
|
| vcazan |
0:eb315142ac34
|
42
|
|
| vcazan |
0:eb315142ac34
|
43
|
|
| vcazan |
0:eb315142ac34
|
44
|
//sei();
|
| vcazan |
0:eb315142ac34
|
45
|
|
| vcazan |
0:eb315142ac34
|
46
|
// this loop continues to put PSx controller into analouge mode untill the
|
| vcazan |
0:eb315142ac34
|
47
|
// controller responds with 0x73 in the 2nd byte.
|
| vcazan |
0:eb315142ac34
|
48
|
// (PS2 controller responds with 0x73 when in analouge mode.)
|
| vcazan |
0:eb315142ac34
|
49
|
// the status LEDs will continue to count upwards untill a controller is found.
|
| vcazan |
0:eb315142ac34
|
50
|
// if everything is working correctly this should happen on the first pass of
|
| vcazan |
0:eb315142ac34
|
51
|
// this loop but occasionally errors occur and a 2nd or 3rd itteration happen.
|
| vcazan |
0:eb315142ac34
|
52
|
int chk_ana = 0, cnt = 0;
|
| vcazan |
0:eb315142ac34
|
53
|
|
| vcazan |
0:eb315142ac34
|
54
|
void startup() {
|
| vcazan |
0:eb315142ac34
|
55
|
|
| vcazan |
0:eb315142ac34
|
56
|
while (chk_ana != 0x73) {
|
| vcazan |
0:eb315142ac34
|
57
|
// put controller in config mode
|
| vcazan |
0:eb315142ac34
|
58
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
59
|
PSclock = 1;
|
| vcazan |
0:eb315142ac34
|
60
|
PSattention =0;
|
| vcazan |
0:eb315142ac34
|
61
|
|
| vcazan |
0:eb315142ac34
|
62
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
63
|
gameByte(0x43);
|
| vcazan |
0:eb315142ac34
|
64
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
65
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
66
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
67
|
|
| vcazan |
0:eb315142ac34
|
68
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
69
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
70
|
PSattention=1;
|
| vcazan |
0:eb315142ac34
|
71
|
|
| vcazan |
0:eb315142ac34
|
72
|
wait_ms(10);
|
| vcazan |
0:eb315142ac34
|
73
|
|
| vcazan |
0:eb315142ac34
|
74
|
// put controller in analog mode
|
| vcazan |
0:eb315142ac34
|
75
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
76
|
PSclock =1;
|
| vcazan |
0:eb315142ac34
|
77
|
PSattention =1;;
|
| vcazan |
0:eb315142ac34
|
78
|
|
| vcazan |
0:eb315142ac34
|
79
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
80
|
gameByte(0x44);
|
| vcazan |
0:eb315142ac34
|
81
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
82
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
83
|
gameByte(0x03);
|
| vcazan |
0:eb315142ac34
|
84
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
85
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
86
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
87
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
88
|
|
| vcazan |
0:eb315142ac34
|
89
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
90
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
91
|
PSattention =1;
|
| vcazan |
0:eb315142ac34
|
92
|
|
| vcazan |
0:eb315142ac34
|
93
|
wait_ms(10);
|
| vcazan |
0:eb315142ac34
|
94
|
|
| vcazan |
0:eb315142ac34
|
95
|
// exit config mode
|
| vcazan |
0:eb315142ac34
|
96
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
97
|
PSclock = 1;
|
| vcazan |
0:eb315142ac34
|
98
|
PSattention = 1;
|
| vcazan |
0:eb315142ac34
|
99
|
|
| vcazan |
0:eb315142ac34
|
100
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
101
|
gameByte(0x43);
|
| vcazan |
0:eb315142ac34
|
102
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
103
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
104
|
gameByte(0x5A);
|
| vcazan |
0:eb315142ac34
|
105
|
gameByte(0x5A);
|
| vcazan |
0:eb315142ac34
|
106
|
gameByte(0x5A);
|
| vcazan |
0:eb315142ac34
|
107
|
gameByte(0x5A);
|
| vcazan |
0:eb315142ac34
|
108
|
gameByte(0x5A);
|
| vcazan |
0:eb315142ac34
|
109
|
|
| vcazan |
0:eb315142ac34
|
110
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
111
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
112
|
PSattention = 1;
|
| vcazan |
0:eb315142ac34
|
113
|
|
| vcazan |
0:eb315142ac34
|
114
|
wait_ms(10);
|
| vcazan |
0:eb315142ac34
|
115
|
// poll controller and check in analouge mode.
|
| vcazan |
0:eb315142ac34
|
116
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
117
|
PSclock=1;
|
| vcazan |
0:eb315142ac34
|
118
|
PSattention=0;
|
| vcazan |
0:eb315142ac34
|
119
|
|
| vcazan |
0:eb315142ac34
|
120
|
gameByte(0x01);
|
| vcazan |
0:eb315142ac34
|
121
|
chk_ana = gameByte(0x42); // the 2nd byte to be returned from the controller should = 0x73 for "red" analouge controller.
|
| vcazan |
0:eb315142ac34
|
122
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
123
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
124
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
125
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
126
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
127
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
128
|
gameByte(0x00);
|
| vcazan |
0:eb315142ac34
|
129
|
|
| vcazan |
0:eb315142ac34
|
130
|
PScommand = 1;
|
| vcazan |
0:eb315142ac34
|
131
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
132
|
PSattention =1;
|
| vcazan |
0:eb315142ac34
|
133
|
|
| vcazan |
0:eb315142ac34
|
134
|
wait_ms(10);
|
| vcazan |
0:eb315142ac34
|
135
|
|
| vcazan |
0:eb315142ac34
|
136
|
|
| vcazan |
0:eb315142ac34
|
137
|
// keep increasing counter to be dispalyed untill PSx controller confirms it's in analouge mode.
|
| vcazan |
0:eb315142ac34
|
138
|
pc.putc(cnt++);
|
| vcazan |
0:eb315142ac34
|
139
|
if (cnt > 254) {
|
| vcazan |
0:eb315142ac34
|
140
|
cnt=0;
|
| vcazan |
0:eb315142ac34
|
141
|
}
|
| vcazan |
0:eb315142ac34
|
142
|
}
|
| vcazan |
0:eb315142ac34
|
143
|
}
|
| vcazan |
0:eb315142ac34
|
144
|
|
| vcazan |
0:eb315142ac34
|
145
|
|
| vcazan |
0:eb315142ac34
|
146
|
// main program loop:
|
| vcazan |
0:eb315142ac34
|
147
|
void loop () {
|
| vcazan |
0:eb315142ac34
|
148
|
|
| vcazan |
0:eb315142ac34
|
149
|
PScommand=1;
|
| vcazan |
0:eb315142ac34
|
150
|
PSclock=1;
|
| vcazan |
0:eb315142ac34
|
151
|
PSattention = 0;
|
| vcazan |
0:eb315142ac34
|
152
|
|
| vcazan |
0:eb315142ac34
|
153
|
gameByte(0x01); // bite 0. header.
|
| vcazan |
0:eb315142ac34
|
154
|
temp = gameByte(0x42); // bite 1. header. (should possibly put test on this byte to detect unplugging of controller.)
|
| vcazan |
0:eb315142ac34
|
155
|
gameByte(0x00); // bite 2. header.
|
| vcazan |
0:eb315142ac34
|
156
|
|
| vcazan |
0:eb315142ac34
|
157
|
data0 = gameByte(0x00); // bite 3. first data bite.
|
| vcazan |
0:eb315142ac34
|
158
|
data1 = gameByte(0x00); // bite 4.
|
| vcazan |
0:eb315142ac34
|
159
|
data2 = gameByte(0x00); // bite 5.
|
| vcazan |
0:eb315142ac34
|
160
|
data3 = gameByte(0x00); // bite 6.
|
| vcazan |
0:eb315142ac34
|
161
|
data4 = gameByte(0x00); // bite 7.
|
| vcazan |
0:eb315142ac34
|
162
|
data5 = gameByte(0x00); // bite 8.
|
| vcazan |
0:eb315142ac34
|
163
|
|
| vcazan |
0:eb315142ac34
|
164
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
165
|
PScommand = 1; // close communication with PSx controller
|
| vcazan |
0:eb315142ac34
|
166
|
wait_ms(1);
|
| vcazan |
0:eb315142ac34
|
167
|
PSattention = 1; // all done.
|
| vcazan |
0:eb315142ac34
|
168
|
|
| vcazan |
0:eb315142ac34
|
169
|
|
| vcazan |
0:eb315142ac34
|
170
|
|
| vcazan |
0:eb315142ac34
|
171
|
if (!(data0 & _BV(0)) && !debounceSelect) { // capture one unique press of the "select" button
|
| vcazan |
0:eb315142ac34
|
172
|
debounceSelect = 1;
|
| vcazan |
0:eb315142ac34
|
173
|
} else if ((data0 & _BV(0)) && debounceSelect) {
|
| vcazan |
0:eb315142ac34
|
174
|
if (i++ >= 5) i=0;
|
| vcazan |
0:eb315142ac34
|
175
|
debounceSelect = 0;
|
| vcazan |
0:eb315142ac34
|
176
|
}
|
| vcazan |
0:eb315142ac34
|
177
|
|
| vcazan |
0:eb315142ac34
|
178
|
|
| vcazan |
0:eb315142ac34
|
179
|
// this switch decides which data register to show on status LEDs depending on how many times
|
| vcazan |
0:eb315142ac34
|
180
|
// the "select" button on the PS2 controller has been pressed.
|
| vcazan |
0:eb315142ac34
|
181
|
switch (i) {
|
| vcazan |
0:eb315142ac34
|
182
|
case 0:
|
| vcazan |
0:eb315142ac34
|
183
|
pc.printf("case 0: %d\n", data0);
|
| vcazan |
0:eb315142ac34
|
184
|
break;
|
| vcazan |
0:eb315142ac34
|
185
|
case 1:
|
| vcazan |
0:eb315142ac34
|
186
|
pc.printf("case 1: %d\n", data1);
|
| vcazan |
0:eb315142ac34
|
187
|
break;
|
| vcazan |
0:eb315142ac34
|
188
|
case 2:
|
| vcazan |
0:eb315142ac34
|
189
|
pc.printf("case 2: %d\n", data2);
|
| vcazan |
0:eb315142ac34
|
190
|
break;
|
| vcazan |
0:eb315142ac34
|
191
|
case 3:
|
| vcazan |
0:eb315142ac34
|
192
|
pc.printf("case 3: %d\n", data3);
|
| vcazan |
0:eb315142ac34
|
193
|
break;
|
| vcazan |
0:eb315142ac34
|
194
|
case 4:
|
| vcazan |
0:eb315142ac34
|
195
|
pc.printf("case 4: %d\n", data4);
|
| vcazan |
0:eb315142ac34
|
196
|
break;
|
| vcazan |
0:eb315142ac34
|
197
|
case 5:
|
| vcazan |
0:eb315142ac34
|
198
|
pc.printf("case 5: %d\n", data5);
|
| vcazan |
0:eb315142ac34
|
199
|
}
|
| vcazan |
0:eb315142ac34
|
200
|
|
| vcazan |
0:eb315142ac34
|
201
|
pc.printf("$d\n",data1);
|
| vcazan |
0:eb315142ac34
|
202
|
} //void loop
|
| vcazan |
0:eb315142ac34
|
203
|
|
| vcazan |
0:eb315142ac34
|
204
|
|
| vcazan |
0:eb315142ac34
|
205
|
int main() {
|
| vcazan |
0:eb315142ac34
|
206
|
startup();
|
| vcazan |
0:eb315142ac34
|
207
|
while (1) {
|
| vcazan |
0:eb315142ac34
|
208
|
loop();
|
| vcazan |
0:eb315142ac34
|
209
|
}
|
| vcazan |
0:eb315142ac34
|
210
|
}
|