Simon Ford
/
PlayStationController
Diff: main.cpp
- Revision:
- 0:da9d848449ef
- Child:
- 1:e4af215fb689
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Nov 22 11:10:42 2009 +0000 @@ -0,0 +1,211 @@ +#include "mbed.h" + +DigitalOut PSclock(p21); +DigitalIn PSdata(p22); +DigitalIn PSack(p23); +DigitalOut PScommand(p24); +DigitalOut PSattention(p25); + +Serial pc(USBTX, USBRX); // tx, rx +int temp, data0, data1, data2, data3, data4, data5, i ,debounceSelect; + +// enable interupts + +int _BV(int bit) { + return 1 << bit; +} + +// PSx controller communication function. +// send a byte on the command line and receive one on the data line. +// needs Attention pin to have gone low before called to activate controller. +char gameByte (char command) { + wait(0.000001); + char data = 0x00; // clear data variable to save setting low bits later. + for(int i=0; i<8; i++) { + if (command & _BV(i)) { + PScommand=1; // bit bang "command" out on PScommand wire. + } else { + PScommand = 0; + } + PSclock = 0; // CLOCK LOW + wait_us(20); // wait for output to stabilise + //if ((PIND & _BV(PSdata)))_SFR_BYTE(data) |= _BV(i); // read PSdata pin and store + //else cbi(data, i); + PSclock = 1; // CLOCK HIGH + } + PScommand = 1; + + wait(0.00002); // wait for ACK to pass. + + return data; +} + + +//sei(); + +// this loop continues to put PSx controller into analouge mode untill the +// controller responds with 0x73 in the 2nd byte. +// (PS2 controller responds with 0x73 when in analouge mode.) +// the status LEDs will continue to count upwards untill a controller is found. +// if everything is working correctly this should happen on the first pass of +// this loop but occasionally errors occur and a 2nd or 3rd itteration happen. +int chk_ana = 0, cnt = 0; + +void startup() { + + while (chk_ana != 0x73) { + // put controller in config mode + PScommand = 1; + PSclock = 1; + PSattention =0; + + gameByte(0x01); + gameByte(0x43); + gameByte(0x00); + gameByte(0x01); + gameByte(0x00); + + PScommand = 1; + wait(0.000001); + PSattention=1; + + wait(0.00001); + + // put controller in analog mode + PScommand = 1; + PSclock =1; + PSattention =1;; + + gameByte(0x01); + gameByte(0x44); + gameByte(0x00); + gameByte(0x01); + gameByte(0x03); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + + PScommand = 1; + wait(0.000001); + PSattention =1; + + wait(0.00001); + + // exit config mode + PScommand = 1; + PSclock = 1; + PSattention = 1; + + gameByte(0x01); + gameByte(0x43); + gameByte(0x00); + gameByte(0x00); + gameByte(0x5A); + gameByte(0x5A); + gameByte(0x5A); + gameByte(0x5A); + gameByte(0x5A); + + PScommand = 1; + wait(0.000001); + PSattention = 1; + + wait(0.00001); + + // poll controller and check in analouge mode. + PScommand = 1; + PSclock=1; + PSattention=0; + + gameByte(0x01); + chk_ana = gameByte(0x42); // the 2nd byte to be returned from the controller should = 0x73 for "red" analouge controller. + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + gameByte(0x00); + + PScommand = 1; + wait(1); + PSattention =1; + + wait(0.00001); + + + // keep increasing counter to be dispalyed untill PSx controller confirms it's in analouge mode. + pc.putc(cnt++); + if (cnt > 254) { + cnt=0; + } + } +} + + +// main program loop: +void loop () { + + PScommand=1; + PSclock=1; + PSattention = 0; + + gameByte(0x01); // bite 0. header. + temp = gameByte(0x42); // bite 1. header. (should possibly put test on this byte to detect unplugging of controller.) + gameByte(0x00); // bite 2. header. + + data0 = gameByte(0x00); // bite 3. first data bite. + data1 = gameByte(0x00); // bite 4. + data2 = gameByte(0x00); // bite 5. + data3 = gameByte(0x00); // bite 6. + data4 = gameByte(0x00); // bite 7. + data5 = gameByte(0x00); // bite 8. + + wait(0.000001); + PScommand = 1; // close communication with PSx controller + wait(0.000001); + PSattention = 1; // all done. + + + + if (!(data0 & _BV(0)) && !debounceSelect) { // capture one unique press of the "select" button + debounceSelect = 1; + } else if ((data0 & _BV(0)) && debounceSelect) { + if (i++ >= 5) i=0; + debounceSelect = 0; + } + + + // this switch decides which data register to show on status LEDs depending on how many times + // the "select" button on the PS2 controller has been pressed. + switch (i) { + case 0: + pc.printf("case 0: %d\n", data0); + break; + case 1: + pc.printf("case 1: %d\n", data1); + break; + case 2: + pc.printf("case 2: %d\n", data2); + break; + case 3: + pc.printf("case 3: %d\n", data3); + break; + case 4: + pc.printf("case 4: %d\n", data4); + break; + case 5: + pc.printf("case 5: %d\n", data5); + } + + +} //void loop + + +int main() { + startup(); + while(1) { + loop(); + } +}