Dependencies:   mbed

Revision:
1:e4af215fb689
Parent:
0:da9d848449ef
Child:
2:e3dd9a5cefa0
--- a/main.cpp	Sun Nov 22 11:10:42 2009 +0000
+++ b/main.cpp	Sun Nov 22 18:31:52 2009 +0000
@@ -1,211 +1,51 @@
 #include "mbed.h"
 
-DigitalOut PSclock(p21);
-DigitalIn PSdata(p22);
-DigitalIn PSack(p23);
-DigitalOut PScommand(p24);
-DigitalOut PSattention(p25);
+SPI spi(p24, p22, p21);   // mosi, miso, sclk (or "command", "data", "clock")
+DigitalOut cs(p25);       // chip select (or "attention")
 
-Serial pc(USBTX, USBRX); // tx, rx
-int temp, data0, data1, data2, data3, data4, data5, i ,debounceSelect;
+// setup the controller in to analog mode
+void ps2_analog_mode() {
+    const char enter_config_mode[5]  = {0x01, 0x43, 0x00, 0x01, 0x00};
+    const char enable_analog_mode[9] = {0x01, 0x44, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00};
+    const char exit_config_mode[9]   = {0x01, 0x43, 0x00, 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A};
 
-// enable interupts
-
-int _BV(int bit) {
-    return 1 << bit;
-}
+    cs = 0;
+    for (int i=0; i<5; i++) {
+        spi.write(enter_config_mode[i]);
+    }
+    cs = 1;
 
-// 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
+    wait_us(1);
+
+    cs = 0;
+    for (int i=0; i<9; i++) {
+        spi.write(enable_analog_mode[i]);
     }
-    PScommand = 1;
+    cs = 1;
+
+    wait_us(1);
 
-    wait(0.00002);                             // wait for ACK to pass.
-
-    return data;
+    cs = 0;
+    for (int i=0; i<9; i++) {
+        spi.write(exit_config_mode[i]);
+    }
+    cs = 1;
 }
 
-
-//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);
+int main() {
+    ps2_analog_mode();
 
-        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;
+    while (1) {
+        const char poll_command[9] = {0x01, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+        char response[9];
 
-        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);
+        cs = 0;
+        for (int i=0; i<9; i++) {
+            response[i] = spi.write(poll_command[i]);
+        }
+        cs = 1;
 
-        // 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;
-        }
+        printf("Digital %02X %02X   Analog %02X %02X %02X %02X\n", response[3], response[4], response[5], response[6], response[7], response[8]);
     }
 }
 
-
-// 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();
-    }
-}