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