You are on page 1of 17

Decoding PS2 Wired and Wireless Controller for Interfacing with PIC Microcontroller Kok Chee Khean 26 June

2011

INTRODUCTION

PS2 controller with digital pad and 2 analog joysticks is suitable to use for control in robotic projects. It is also widely available in the market. With the market available PS2 wireless controller, a project can be simply turned into wireless control.

Interfacing with microcontroller (MCU) requires a few steps of command send from microcontroller to PS2 controller and data received from PS2 controller by microcontroller in serial form. The data received can be further processed to perform certain task such as operating an electric motor or light depends on application.

TERM USED

MCU: Microcontroller Unit refers to PIC or more specific PIC16F877a which used. PS2: Play Station 2 0x: Hexadecimal 0b: Binary E.g. conversion of hexadecimal to binary and decimal value 0x09 = 0b00001001= 9, 0x0A = 0b00001010= 10, 0x0F = 0b00001111= 15, 0x19 = 0b00011001= 25, 0xFF = 0b11111111= 255,

METHODOLOGY There are several method used to identify the command and data sent and received. a. Reference from webpage This website http://store.curiousinventor.com/guides/PS2/ has the complete tutorials about Interfacing PS2 Controller. The idea of command sent and data received is based on this webpage. This source of reference includes the PS2 wireless controller, and several other brand PS2 wireless devices. (Curious Inventor, 2008)

b. Using Oscilloscope to observe the signal sent by Cytron PS2 I/O Converter PSC28A This PS2 I/O converter is proven to be working on wireless PS2 Controller. Therefore reverse engineering has been done to identify the command which is working for PS2 wireless controller.

c. Testing on PIC16F877A basic module Based on command and data obtain from the previous 2 methods, programs is prepared accordingly and tested on PS2 wired and wireless controller.

CHAPTER 1- WIRING

Figure 1: Wire colours and meaning

1. Brown - Data: Controller sends to PlayStation (MCU in this case). Representing keypad pressed. The PS2 controller is only able to give 2 conditions to this pin. a. First condition is floating (tri-state) which means nothing is connected to this pin. b. Second condition is connecting this pin to ground to give a low signal. PS2 controller is not able to give voltage to make this pin high. Thus, it requires us to pull up (10k ohm) this pin to give a high output at tri-state condition. Pull up this pin enable the output of this pin to be high and low instead of tri-state and low.

2. Orange - Command: PlayStation (MCU in this case) send signal to PS2 Controller via this pin. To initialize, communicate or configure the mode of PS2 Controller also signal to control the vibration motor.

3. Grey - Vibration Motors Power: Voltage to drive the vibration motor, run on 7.6V with starting current of 500mA and steady state current of 300mA. This pin is not available for PS2 wireless controller because the voltage to drive the vibration motor comes from the wireless controller unit itself. 4. Black Ground

5. Red - Power: work from 3-5V.

6. Yellow - Attention: This line must be clear to low before each group of bytes is sent / received, and then set high again afterwards.

7. Blue - Clock: The clock is set to high when reading the data from PS2 controller and is clear to low when sending command to PS2 controller. 8. White Not connected: For this project, this pin is ignored.

9. Green - Acknowledge: This pin must be pulled up (same reason as data pin). Leaving it high all the time will be fine.

Figure 2 : The connection of PS2 controller.

1. Ground and +5V is connected accordingly to provide power to the PS2 controller. 2. CMND, ATT, CLK is connected to output from microcontroller. These pins are controlled by microcontroller. 3. DATA is connected to microcontrollers input. This pin is read by microcontroller for signal received from PS2 Controller. 4. Notice that DATA and ACK pins are pulled up with 10K ohms resistor. 5. Notice that Vibrator pin is not connected. 6. Notice that NC pin is ignored (not in the diagram).

CHAPTER 2- INTERFACING METHOD

Figure 3:Packet data

1. Data are sent and receive in form of Packet. 2. There are 5 or 9 Bytes in each Packet depends on the mode. 5bytes for digital mode, 9Bytes for analogue mode and might be different for other modes. 3. There are 8bits in 1byte.

4. Every bit of Command sent by MCU will follow by a bit of Data received from PS2 controller before the MCU send command for the next bit. Command and Data sent and received alternately every bit. 5. After every 8 bit of command sent and data received, it is considered as 1 byte. 6. This happens for 5 or 9 bytes (depend on the mode) and it is considered as 1 Packet.

CHAPTER 3- MEANING VALUES FOR DATA AND COMMAND

Meaning of Command and Data in 1 Packet


Byte # 1st Byte Type Command Data Example value 0x01 0xFF Explanations 0x01 indicates starting of a new packet. Always 0x01 Always 0xFF. (However I ignored this data. PS2 dont always wait for these bytes.)

Main command: Telling PS2 controller what is the purpose of 2nd Byte Command 0x42 this packet data. 0x42 for standard Polling, 0x43 for mode configuration, etc. will be explained further down. Device mode: The PS2 controller tells what is the mode it Data 0x41 currently in. (However I ignored this data. PS2 dont always wait for these bytes.)

3rd Byte

Command Data

0x00 0x5a

Always 0x00 Always 0x5a (However I ignored this data. PS2 dont always wait for these bytes.)

4th Byte

Command Data

0x00 0xFF

Can be configure to control either vibrator motor This byte carry information on which digital button is pressed (first set of digital buttons)

5th Byte

Command Data

0x00 0xFF

Can be configure to control either vibrator motor This byte carry information on which digital button is pressed (second set of digital buttons)

6th Byte

Command Data

0x00

Always 0x00 ANALOG RIGHT X AXIS (RIGHT:0:LEFT = 0:128:255)

7th Byte

Command Data

0x00

Always 0x00 ANALOG RIGHT Y AXIS (UP:0:DOWN = 0:128:255)

8th Byte

Command Data

0x00

Always 0x00 ANALOG LEFT X AXIS (RIGHT:0:LEFT = 0:128:255)

9th Byte

Command Data

0x00

Always 0x00 ANALOG LEFT Y AXIS (UP:0:DOWN = 0:128:255)

Types of packet data

a. 0x42 Short Poll


Byte Number Command (0x) Data (0x) 1 01 FF 2 42 41 3 00 5A 4 FF FF 5 FF FF

Short Poll is a 5 bytes packet data. It is used to initialize of refresh the connection. Only focus on the command to be sent. The data is not read during short poll.

b. 0x42 Poll
Byte Number Command (0x) Data (0x) 1 01 FF 2 42 79 3 00 5A 4 WW FF 5 YY FF digital RightX 6 00 7F 7 00 7F 8 00 7F 9 00 7F

analog joystick RightY Left X Left Y

Poll is a 5 bytes packet data for digital mode and 9 bytes packet data for analog mode. This packet is looped (repeated) throughout the whole operation of the interfacing. The idea is to keep sending this command as a mean of requesting the data from the PS2 controller which represent the button pressed. If a button is pressed at this moment of polling, it will get the data as the button is pressed. When the button is released, in the next polling session, the data will be sent again this time signifying that the button is released. Polling occurs very

fast. It only took 20ms for each poll. This means about 50 times in 1 second. The 4th to 9th byte data are read to identify which button is pressed. We can send command to WW and YY to control the motors after setting it up in configuration. WW runs the small motors 0xFF turns it on and other value turns it off. YY runs the large motors value from 0x00 to 0xFF. In fact, 0x40 was the smallest value that would actually make the motor spin. (First byte command 0x80 for Logitech)

Button Mapping Recall that the data pin is initially pulled up. Thus if the bit is high represent that the button is not pressed. If the bit is low represent that the button is pressed.
4th Byte data select Bit # 0 L3 1st R3 2nd Start 3rd Up 4th Right 5th Down 6th Left 7th

5th Byte data L2 Bit # 0 R2 1st L1 2nd R1 3rd Triangle 4th O 5th X 6th Square 7th

6th Byte 7th Byte 8th Byte 9th Byte

ANALOG RIGHT X AXIS (RIGHT:0:LEFT = 0:128:255) ANALOG RIGHT Y AXIS (UP:0:DOWN = 0:128:255) ANALOG LEFT X AXIS (RIGHT:0:LEFT = 0:128:255) ANALOG LEFT Y AXIS (UP:0:DOWN = 0:128:255)

Examples a) If 4th Byte is 0x11 = 0b00010001. The 0th and 4th bits are high. The rest is low. This means L3, R3, start, right, down and left button is pressed simultaneously. b) If 4th Byte is 0xFF = 0b11111111. All bits are high. This means no button is pressed. c) Similarly to 5th Byte d) 6th to 9th Byte if data is 0x80 = 0b1000000 = 128, the joystick is at the middle. e) If data is 0xFF= 0b11111111= 255, the joystick at left side or down side (depend on the axis). f) If data is 0x00= 0b00000000= 0, the joystick at the right or upside (depend on the axis).

c. 0x43 Enter Configuration mode (optional)


Byte Number Command (0x) Data (0x) 1 01 FF 2 43 41 3 00 5A 4 01 FF 5 00 FF

This packet is used to get in to configuration mode before setting up the controller to analogue mode or setup for the vibration motor. The following is the command need to be sent to get into configuration mode. Only focus on the command to be sent. The data is not read during enter configuration mode.

d. 0x44 Mode selection between digital and analogue (optional)


Effective after enter into configuration mode 0x43 Byte Number Command (0x) Data (0x) 1 01 FF 2 44 F3 3 00 5A 4 01 00 5 03 00

This packet allows the PS2 controller to select mode. The 4th byte command is to set mode (analog= 0x01 and digital= 0x00). The 5th byte command 0x03 is to lock the controller to the mode specify in 4th byte. This means users are unable to toggle digital and analog mode with the button on the PS2 controller. Any other value in 5th byte will not lock the mode. Only focus on the command to be sent. The data is not read.

e. 0x4D Setting up vibration motors (optional)


Effective after enter into configuration mode 0x43 Byte Number Command (0x) Data (0x) 1 01 FF 2 4D F3 3 00 5A 4 00 00 5 01 00

This packet is to setup the vibration motors function. 0x00 maps the corresponding byte in 0x42 to control the small motor. 0x01 maps the corresponding byte in 0x42 to control the large motor. 0xFF disables, and is the default value when the controller is first connected. Only focus on the command to be sent. The data is not read.

f. 0x43 Exit Configuration Mode (optional)


Effective after enter into configuration mode 0x43 Byte Number Command (0x) Data (0x) 1 01 FF 2 43 F3 3 00 5A 4 00 00 5 5A 00 6 5A 00 7 5A 00 8 5A 00 9 5A 00

This command exits the configuration mode.

For typical analogue mode, the following is the recommended packet of data should be sent. The order follows the sequence a. Short Poll (three times for initiation and refresh) b. Enter configuration mode c. Switch to analog mode and lock the analog mode d. Setup vibration motor (optional) e. Exit configuration mode f. Poll (loop this forever)

CHAPTER 4- PIN CONTROL 1. Clock (CLK) Clock is clear to low when sending Command to PS2 controller and is set to high when receiving Data from PS2 controller. Since Command and Data are sent and received alternately within each bit, the clock is set to high and low alternately every bit. The following diagram shows the Clock signal which is high and low alternately displayed on an oscilloscope. The time interval time for each high and low is 2s and the interval of every byte sent is 16s.

2. Data (DATA) Data is the signal received from PS2 controller. The first 3 bytes of data which is the header data represent the establishment. However, these 3 bytes are ignore and assumed to be the correct data receive. During polling, the 4th and 5th Bytes represent the digital button pressed while 6th to 9th bytes represent the analog joystick. These Data are read by the microcontroller and could be further processed to perform the desire task such as controlling motors or actuators.

3. Command (CMND) Command is the signal sent from microcontroller. Correct command has to be sent to PS2 controller to establish connection. Each command represents different configuration and mode as describe in previous section.

4. Attention (ATT) Attention is commonly held high. It is held low when sending a packet of data and set to high again representing the sending of packet has ended.

5. Acknowledge (ACK) This pin is pulled up and therefore it is always high. It is not connected to microcontroller and therefore it is not being controlled. It is left being always high.

CHAPTER 5- EXPLANATION OF EACH PROGRAM FUNCTION

a. Write Read function


/*-------------------------READ WRITE FOR EACH BIT----------------------------*/ void ReadWrite() { { for(i=0;i<8;i++) PSX_CLOCK=0; if(bit_test(PSX_WRITE,i)){PSX_CMND=1;} else PSX_CMND=0; PSX_CLOCK=1; if(PSX_DATA==1) {bit_set(PSX_READ,i);} else bit_clear(PSX_READ,i); } delay_us(16); } /*-----------------------------------------------------------------------------*/ //DELAY 16S AFTER EVERY BYTE delay_us(2); delay_us(2); //CLEAR CLOCK TO LOW //SEND CMND BIT BY BIT //DELAY 2S INTERVAL //SET CLOCK TO HIGH //READ DATA BIT BY BIT //DELAY 2S INTERVAL

The purpose of write read function is to perform the task of transferring the Command and Data value of each byte, bit by bit (in serial form). This function will do the following sequence. (ith bit refers to the digit of the value in binary) a. Set the clock low tells the PS2 controller that command is coming.

b. Check the 0th bit of PSX_WRITE (this is the variable that we set the value before calling this function). c. If the 0th bit is high (bit_test signify the bit is high), it will set the PSX_CMND (refers to the pin in MCU that we set initially) high. If the 0th bit is low, it will set the PSX_CMND pin to low. d. Delay of 2s is held for the signal to sustain long enough for the PS2 controller to receive. Write of 0th bit is end here. e. Clock is set to high telling the PS2 controller that MCU is reading the data from it. f. If the PSX_DATA (refers to the input pin of MCU) is high, the program store the value of 1 to be the 0th digit of the variable PSX_READ. If the PSX_DATA is low, the program will store the value of 0 to the 0th digit (binary) of the variable PSX_READ. g. Delay of 2s is held for the signal to sustain long enough for the MCU to read the value. Read of 0th bit is end here. h. This will loop 8 times from 0th 7th bit to complete the 1byte of command sending and data receiving. i. After every 1 byte of transferring data and command, there is a 16 s interval.

Example Command= PSX_WRITE = 0x13 = 0b00010011 Data = PSX_READ= 0x34 = 0b00110100 *Here the clock set or clear is skipped. Remind that clock must be low during command sending and clock must be high when receiving data. Also the delay of 2s is skipped here. The 0th bit of PSX_WRITE is 1, thus MCU set PSX_CMND pin to be high. MCU is reading the PSX_DATA pin, the pin is low, and so the 0th digit of PSX_READ is 0. The 1st bit of PSX_WRITE is high, thus MCU set PSX_CMND pin to be high. MCU is reading the PSX_DATA pin, the pin is low, and so the 1st digit of PSX_READ is 1. The 2nd bit of PSX_WRITE is low, thus MCU set PSX_CMND pin to be low. MCU is reading the PSX_DATA pin, the pin is high, and so the 2nd digit of PSX_READ is 1. And so on. After the loop completed, PSX_READ = 0b00110100. Recalling, the data send from PS2 controller is bit by bit (in serial) and it is storing the number bit by bit and forming an 8 bit number. This 8 bit number represents the information of the keypad pressed.

Notice that for the Command sent, PSX_WRITE is initially an 8 bit number. Each of the digits is sent 1 by 1 (in serial) to the PS2 controller.

b. Short Poll
/*-------------------------------SHORT POLL-----------------------------------*/ void ShortPoll() { PSX_ATT=0; delay_us(16); PSX_WRITE=0x01;ReadWrite(); PSX_WRITE=0X42;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_ATT=1; delay_us(16); } /*-----------------------------------------------------------------------------*/ //SET ATT TO HIGH INDICATE END OF PACKET //INTERVAL OF 16S //CLEAR ATT TO LOW INDICATE START OF PACKET //INTERVAL OF 16S

Before transferring a packet data, the PSX_ATT (refers to Attention pin of PS2 controller) must be held low for 16s before sending first byte. The value to be sent as Command to PS2 controller is first defined. PSX_WRITE=0x01 is the first command byte. Then the ReadWrite() function is called. The ReadWrite() function will perform the data transfer bit by bit also reading data value from PS2 controller, however, the value read is not used in short poll function. This process repeated for the other bytes. After the packet data is end, the Attention pin is set to high. Delay of 16s is the interval for each packet data. The same things happens for void EnterConfig(),void TurnOnAnalogMode(), and void Exitconfig().

c. Poll
/*-----------------------------------POLL-------------------------------------*/ void Poll() { PSX_ATT=0; delay_us(16); PSX_WRITE=0X01; ReadWrite(); PSX_WRITE=0x42; ReadWrite(); PSX_WRITE=0X00; ReadWrite(); PSX_WRITE=0X00; ReadWrite(); DATA4=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA5=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA6=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA7=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA8=PSX_READ;

PSX_WRITE=0X00; ReadWrite(); DATA9=PSX_READ; PSX_ATT=1; delay_ms(16); } /*-----------------------------------------------------------------------------*/

All the byte transfer is the same as short poll. For poll, we need to extract the data value read from PS2 controller which is PSX_READ and store it into DATA4, DATA5 up to DATA9 respectively.

d. PS2 initialize
/*--------------------------------INITIALIZE----------------------------------*/ void PS2_init() { ShortPoll(); EnterConfig(); TurnOnAnalogMode(); Exitconfig(); } /*-----------------------------------------------------------------------------*/ ShortPoll(); ShortPoll();

This function is just to group all the initialize function (which runs only 1 time initially) together. Notice that the shortpoll is called 3times for the connection establishment and refresh.

e. Main function
/*-----------------------------------------------------------------------------MAIN FUNCTION ------------------------------------------------------------------------------*/ void main() { set_tris_b(0); PS2_init(); WHILE(1) { poll(); if(!bit_test(DATA4,0)) if(!bit_test(DATA4,1)) if(!bit_test(DATA4,2)) if(!bit_test(DATA4,3)) if(!bit_test(DATA4,4)) if(!bit_test(DATA4,5)) if(!bit_test(DATA4,6)) if(!bit_test(DATA4,7)) {} {} {} {} {} {} {} {} else{} else{} else{} else{} else{} else{} else{} else{} //SELECT //L3 //R3 //START //UP //RIGHT //DOWN //LEFT /*----------------------------DATA4 KEYPAD1-----------------------------------*/ // set PortB all output // establish connection and configure PS2 controller set_tris_d(0b00001000); // set PortD all output except D3 PS2 data pin as input)

/*----------------------------DATA5 KEYPAD2-----------------------------------*/ if(!bit_test(DATA5,0)) if(!bit_test(DATA5,1)) if(!bit_test(DATA5,2)) if(!bit_test(DATA5,3)) if(!bit_test(DATA5,4)) if(!bit_test(DATA5,5)) if(!bit_test(DATA5,6)) if(!bit_test(DATA5,7)) /*--------DATA6 /*--------DATA7 /*--------DATA8 /*--------DATA9 } } /*-----------------------------------------------------------------------------*/ {} {} {} {} {} {} {} {} else{} else{} else{} else{} else{} else{} else{} else{} = = = //L2 //R2 //L1 //R1 //TRIANGLE //O //X //SQUARE 0:128:255)-------------*/ 0:128:255)--------------*/ 0:128:255)---------------*/

ANALOG RIGHT X AXIS (RIGHT:0:LEFT ANALOG RIGHT Y AXIS (UP:0:DOWN ANALOG LEFT X AXIS (RIGHT:0:LEFT ANALOG LEFT Y AXIS (UP:0:DOWN =

0:128:255)----------------*/

The first part is the setting of I/O port for PIC also the call of the initialize function for the PS2 controller to establish connection and configuration of mode. The 2nd part is the do while loop which is looped forever. Inside this loop consist of poll function. As mention in earlier part, this function has to be looped forever to get the data of the keypad pressed and it is updated every loop. if(!bit_test(DATA4,0)) {}

(DATA4,0) represents the 0th bit of the value DATA4 (which extracted in poll function). !bit_testsignify the bit is low. (Recall that bit is low represent the keypad is pressed.) Thus the syntax sound like if 0th bit of DATA4 is low, then perform {}. In the braces, we can put any function that we desire. For example, turn on the pins of PIC to allow the operation of motors or actuators.

CHAPTER 6 - SAMPLE PROGRAMMING IN C LANGUAGE

This source code shows the example of how to interface PS2 controller with PIC16F877A microcontroller. The text after the // sign is comment of the syntax which is not a part of the program.

/*----------------------------------------------------------------------------TITLE : Basic PS2 interface AUTHOR : C.K. KOK DATE : 22/5/2011 DESCRIPTION : PS2 basic interfacing routines the time delay for each sub-routines interval is matching PS2 wireless controller ------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------BASIC HEADER ------------------------------------------------------------------------------*/ #include <16F877a.h> #use delay(clock=20000000) #fuses hs, noprotect, nowdt, nolvp #byte PORTA=5 #byte PORTB=6 #byte PORTC=7 #byte PORTD=8 #byte PORTE=9 /*----------------------------------------------------------------------------PS2 CONTROLLER INTERFACING ------------------------------------------------------------------------------*/ /*------------------------------DECLARATIONS----------------------------------*/ #bit PSX_DATA =PORTD.3 //DATA connected to D3 #bit PSX_CMND =PORTD.2 //CMND connected to D2 #bit PSX_ATT =PORTD.1 //ATT connected to D1 #bit PSX_CLOCK =PORTD.0 //CLK connected to D0 int i,PSX_WRITE,PSX_READ,DATA4,DATA5,DATA6,DATA7,DATA8,DATA9; /*-------------------------READ WRITE FOR EACH BIT----------------------------*/ void ReadWrite() { for(i=0;i<8;i++) { PSX_CLOCK=0; if(bit_test(PSX_WRITE,i)){PSX_CMND=1;} else PSX_CMND=0; delay_us(2); PSX_CLOCK=1; if(PSX_DATA==1) {bit_set(PSX_READ,i);} else bit_clear(PSX_READ,i); delay_us(2); } delay_us(16); } /*-------------------------------SHORT POLL-----------------------------------*/ void ShortPoll() { PSX_ATT=0; delay_us(16); PSX_WRITE=0x01;ReadWrite(); PSX_WRITE=0X42;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_ATT=1; delay_us(16); } /*--------------------------CONFIG TO ANALOG MODE-----------------------------*/ void EnterConfig() { PSX_ATT=0; delay_us(16); PSX_WRITE=0X01;ReadWrite(); PSX_WRITE=0X43;ReadWrite(); PSX_WRITE=0X00;ReadWrite();

PSX_WRITE=0X01;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_ATT=1; delay_us(16); } void TurnOnAnalogMode() { PSX_ATT=0; delay_us(16); PSX_WRITE=0X01;ReadWrite(); PSX_WRITE=0X44;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X01;ReadWrite(); PSX_WRITE=0X03;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_ATT=1; delay_us(16); } void Exitconfig() { PSX_ATT=0; delay_us(16); PSX_WRITE=0X01;ReadWrite(); PSX_WRITE=0X43;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X00;ReadWrite(); PSX_WRITE=0X5A;ReadWrite(); PSX_WRITE=0X5A;ReadWrite(); PSX_WRITE=0X5A;ReadWrite(); PSX_WRITE=0X5A;ReadWrite(); PSX_WRITE=0X5A;ReadWrite(); PSX_ATT=1; delay_us(16); } /*-----------------------------------POLL-------------------------------------*/ void Poll() { PSX_ATT=0; delay_us(16); PSX_WRITE=0X01; ReadWrite(); PSX_WRITE=0x42; ReadWrite(); PSX_WRITE=0X00; ReadWrite(); PSX_WRITE=0X00; ReadWrite(); DATA4=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA5=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA6=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA7=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA8=PSX_READ; PSX_WRITE=0X00; ReadWrite(); DATA9=PSX_READ; PSX_ATT=1; delay_ms(16); } /*--------------------------------INITIALIZE----------------------------------*/ void PS2_init() { ShortPoll(); ShortPoll(); ShortPoll(); EnterConfig(); TurnOnAnalogMode(); Exitconfig(); }

/*-----------------------------------------------------------------------------MAIN FUNCTION ------------------------------------------------------------------------------*/ void main() { set_tris_b(0); // set PortB all output set_tris_d(0b00001000); // set PortD all output except D3 PS2 data pin as input) PS2_init(); // establish connection and configure PS2 controller WHILE(1) { poll(); /*----------------------------DATA4 KEYPAD1-----------------------------------*/ if(!bit_test(DATA4,0)) {} else{} //SELECT if(!bit_test(DATA4,1)) {} else{} //L3 if(!bit_test(DATA4,2)) {} else{} //R3 if(!bit_test(DATA4,3)) {} else{} //START if(!bit_test(DATA4,4)) {} else{} //UP if(!bit_test(DATA4,5)) {} else{} //RIGHT if(!bit_test(DATA4,6)) {} else{} //DOWN if(!bit_test(DATA4,7)) {} else{} //LEFT /*----------------------------DATA5 KEYPAD2-----------------------------------*/ if(!bit_test(DATA5,0)) {} else{} //L2 if(!bit_test(DATA5,1)) {} else{} //R2 if(!bit_test(DATA5,2)) {} else{} //L1 if(!bit_test(DATA5,3)) {} else{} //R1 if(!bit_test(DATA5,4)) {} else{} //TRIANGLE if(!bit_test(DATA5,5)) {} else{} //O if(!bit_test(DATA5,6)) {} else{} //X if(!bit_test(DATA5,7)) {} else{} //SQUARE /*--------DATA6 ANALOG RIGHT X AXIS (RIGHT:0:LEFT = 0:128:255)-------------*/ /*--------DATA7 ANALOG RIGHT Y AXIS (UP:0:DOWN = 0:128:255)----------------*/ /*--------DATA8 ANALOG LEFT X AXIS (RIGHT:0:LEFT = 0:128:255)--------------*/ /*--------DATA9 ANALOG LEFT Y AXIS (UP:0:DOWN = 0:128:255)---------------*/ } } /*-----------------------------------------------------------------------------*/

CONCLUSION The PS2 controller interfacing can be further improved to make used of the extra features such as vibration motor as feedback, able to use with various different brand of PS2 wireless controller, toggle digital and analogue mode with Mode button, and turning the device on and off from the controller.

REFERENCES Curious Inventor. (2008). Retrieved October 2010, from http://store.curiousinventor.com/guides/PS2

You might also like