Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- simon
- Date:
- 2009-11-22
- Revision:
- 0:da9d848449ef
- Child:
- 1:e4af215fb689
File content as of revision 0:da9d848449ef:
#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();
}
}