|
|
|||||||
| Register | Links | Tutorials | Data Center | Blogs | Gallery | FAQ | Members List | Social Groups | Calendar | Search | Today's Posts | Mark Forums Read |
| Home | Submit File | What's New | What's Popular | Search |
| Axon PS2 Controller Interface Library |
|
|
|||||||
|
|||||||
|
This is a library (.h and .c file) to interface with a PS2 controller using an Axon MCU. It should work with any AVR based MCU, though, with some minor modifications.
The low level PS2 communication code was adapted from 'Dunk's tutorial on the 'Society of Robots' website. http://www.societyofrobots.com/membe...rials/node/200 Features:
|
|||||||
| Tags: | PS2 Controller Axon AVR | ||||||
| Replies to File: Axon PS2 Controller Interface Library |
|
#1
|
|||
|
|||
|
Re: Axon PS2 Controller Interface Library
hi JadeKnight,
good work tidying up my original code. i'd always meant to go back and do that. i'd always meant to poll the acknowledge pin as well. the only other thing i meant to do was have another go at using the AVRs hardware SPI module. so, i've just tried running your code on an ATmega2561 @ 8MHz with reasonable results. you'll be glad to know your modification posted here: http://www.societyofrobots.com/robot...71284#msg71284 works for me as well. one thing i immediately noticed though was the main PollPS2Controller() function was slooooow. at 8MHz it was taking around 25ms to complete. most of this delay was taken up with the repeated 1us delay before and after setting the PS2_clock pin. if i skipped the delays altogether the controller seemed to then not drop the acknowledge pin so things just hung there instead. the solution was a shorter delay. at 8MHz i can actually skip the delay before dropping the PS2_clock pin altogether but i seem to remember it is still necessary at 16MHz... with a very short delay i can reduce the PollPS2Controller() function time to around 5ms leaving far more time for other things. (i'm using this for radio-control stuff so 25ms was far too long.) so, here's what works for me @ 8MHz. i'm guessing the 1st delay would need un-commented at the PS2_clock part for 16MHz clock speeds. also my delay might be too short at higher speeds. Code:
static short int InternalPS2GameByte(short int command)
{
short int i;
short int data = 0x00; // clear data variable to save setting low bits later.
for(i=0;i<8;i++)
{
if(command & _BV(i)) // bit bang "command" out on PS2_command wire.
pin_high(PS2_command);
else
pin_low(PS2_command);
// cheap_delay(1); // wait for output to stabilise
pin_low(PS2_clock); // CLOCK LOW
cheap_delay(1); // wait for output to stabilise
pin_high(PS2_clock); // CLOCK HIGH
if(pin_is_high(PS2_data)) // read PS2_data pin and store
sbi(data, i);
}
pin_high(PS2_command);
#ifdef PS2_acknowledge_used
for(i=0;i<20;i++)
{
if(pin_is_low(PS2_acknowledge)) // wait for ack to go low (usually within 10 loops)
{
break;
}
}
#else
delay_us(20); // wait for ack to pass
#endif
return(data);
}
// 1us is actually far longer than required.
// as this delay gets called oftain it is worth shortening it.
// this length of delay works for me on an 8MHz clock with a genuine Sony PS2 controller.
void cheap_delay(unsigned short delay_loops)
{
register unsigned short i;
// one loop takes 5 cpu cycles
for (i=0; i < delay_loops; i++) {};
}
|