Dependencies:   mbed

Committer:
vcazan
Date:
Sun Nov 22 18:03:23 2009 +0000
Revision:
0:eb315142ac34

        

Who changed what in which revision?

UserRevisionLine numberNew 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 }