Kurs AVR-GCC. Gamepad od Sony PlayStation
Zwykle na płytkach startowych przeznaczonych do nauki programowania mikrokontrolerów wlutowuje się kilka miniaturowych przycisków. Spotyka się również płytki z klawiaturą zrobioną z przycisków wlutowanych w kilu rzędach . Jest to wygodne, bo można uruchamiać proste programy. Jednak obsługa w programie wielu przycisków okazuje się nieco uciążliwa, a dodatkowo występuje problem drgań styków przycisków. Zamiast walczyć z przyciskami polecam przyłączyć do płytki gamepad od konsoli Sony PlayStation2, w ten sposób temat przycisków zostanie prosto i elegancko rozwiązany.
Na fotografii poniżej wydać gamepad do PS2, który kosztował tylko kilkanaście zł. Nie jest to oryginalny pad PlayStation, ale za to ma "bajerancką" obudowę z przezroczystego tworzywa i jest podświetlany niebieskimi diodami LED. Jest to tzw. "analogowy" pad, bo w odróżnieniu od wcześniejszych modeli ("cyfrowych"), posiada obok przycisków dodatkowo dwa analogowe dżojstiki. Co ciekawe, z analogowego pada odczytywać można nie tylko które przyciski są wciśnięte, ale także siłę nacisku na przyciski. Pad wyposażony został również w silniki z niesymetrycznymi ciężarkami na osi do generowania wibracji -można sterować prędkością silnika. A to jeszcze nie wszystko, bo są dostępne wersję bezprzewodowe pada dla playstation2, które kosztują niewiele więcej niż modele z kablem.
Playstation komunikuje się padem magistralą szeregową, my możemy przyłączyć pada do sprzętowego interfejsu SPI AVRa atmega. Wtyk na końcu przewodu pada ma dziewięć wyprowadzeń:
Pin | Oznaczenie i kolor przewodu | Opis |
---|---|---|
1 | DATA | Tą linią kontroler przesyła dane do playstation |
2 | CMD | Linią plastation przesyła komendy do kontrolera |
8 | MPWR | Zasilanie silników generujących wibracje pada 7-9V |
4 | GND | Masa |
5 | VCC | Zasilanie 3.3-5V |
6 | ATT | Niskim stanem niskim na tej linii playstation sygnalizuje rozpoczęcie transmisji |
7 | CLK | Sygnał zegara, taktujący dane na liniach DATA i CMD, generowany przez playstation |
8 | NC. | Nie podłączony |
9 | ACK | Pad potwierdza odbiór jednego bajtu danych ustawiając tę linię w stan niski |
Konsola playstation rozpoczyna komunikację z padem ustawiając stan niski na linii ATT . Transmisja danych odbywa się jednocześnie w dwóch kierunkach. Linią CMD playstation przesyła komendy do pada, a w tym samym czasie linią DATA gamepad przesyła do playstation informacje o stanie przycisków, dżojstików oraz inne dodatkowe informacje. Na linii CLK playstation generuje sygnał zegara taktujący dane na obu liniach danych CMD i DATA. Normalnym stanem początkowym sygnału zegara to stan wysoki. Próbkowanie linii danych (CMD i DATA) następuje po narastającym zboczu sygnału CLK. Dodatkowo gamepad potwierdza odebranie kolejnych bajtów danych ustawieniem linii ACK w stan niski( z wyjątkiem ostatniego bajtu). Bity w bajcie przesyłane są w kolejności od najmłodszego do najstarszego.
Poniżej wkleiłem funkcję "pad_byte", która wysyła/odbiera jeden bajt z/do gamepada.
unsigned char pad_byte(unsigned char byte) { unsigned char i,r=0; for(i=0; i<8; i++, byte>>=1) { CLK_CLR; if(byte & 0x01) CMD_SET; else CMD_CLR; CLK_SET; r>>=1; if(DATA_IN) r|=0x80; } CMD_SET; _delay_us(20); return r; }
Możemy również przyłączyć pad poprzez sprzętowy interfejs SPI AVRa, poniżej mamy drugą wersję funkcji "pad_byte", która właśnie wykorzystuje sprzętowy SPI mikrokontrolera atmega.
// Konfiguracja SPI AVRa SPCR =(1<<SPE)|(1<<MSTR) // Włącza SPI AVRa w trybie MASTER |(1<<DORD) // LSB wysyłany pierwszy |(1<<CPOL) // SCK normalnie w stanie wysokim |(1<<CPHA) // Próbkowanie po wznoszącym zboczu SCK |(1<<SPR0)|(1<<SPR1); // Częstotliwość sygnału SCK fosc/128 // Wysyła jeden bajt poprzez SPI unsigned char pad_byte(unsigned char byte) { SPDR = byte; while(!(SPSR & (1<<SPIF))); _delay_us(20); return SPDR; }
Gamepad potwierdza odbiór bajtu danych ustawiając na chwilkę linię ACK w stan niski, lecz w zamieszczonych tutaj przykładach nie będzie to wykorzystywane, linię ACK pozostawiłem niepodłączoną.
Rozmowa mikrokontrolera z gamepadem odbywa się w następujący sposób: Najpierw mikrokontroler ustawia linię ATT w stan niski, co aktywuje interfejs gamepada. Dalej, wywołując wielokrotnie funkcję "pad_byte", mikrokontroler wysyła do gamepada ciąg bajtów zawierający zakodowaną komendę wraz z parametrami. Jednocześnie wywoływana wielokrotnie funkcja "pad_byte" zwraca ciąg bajtów odczytany z gamepada, który zawiera informację o stanie przycisków, dżojstików itd.
Przykładowo, żeby odczytać stan przycisków gamepada i stopień wychylenia drążka dżojstików analogowych wyślemy do gamepada dziewięć bajtów zawierających komendę: 0x42-"Controller poll", jak w tablicy poniżej.
Nr | Bajt wysłany | Bajt odebrany |
---|---|---|
1 | 0x01 | 0x0xff |
2 | 0x42 | 0x73 |
3 | 0x00 | 0x5A |
4 | 0x00 | dane |
5 | 0x00 | dane |
6 | 0x00 | dane |
7 | 0x00 | dane |
8 | 0x00 | dane |
9 | 0x00 | dane |
Odczytane z gamepada bajty numer 4 i 5 zawierają informacje o stanie przycisków, wartość bitu 0 oznacza, że przycisk jest wciśnięty; a bajty numer 6..9 zawierają informację o stopniu wychylenia gałek dżojstików analogowych.
Bit 0 | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 | |
---|---|---|---|---|---|---|---|---|
Bajt nr 4 | SELECT | JOYR | JOYL | START | UP | RIGHT | DOWN | LEFT |
Bajt nr 5 | L2 | R2 | L1 | R1 | trójkąt | kółko | krzyżyk | kwadrat |
Bajt nr 6 | dżojstik prawy, wychylenie w kierunku lewo-prawo, 0x00 - max. w lewo, 0xff-max. w prawo | |||||||
Bajt nr 7 | dżojstik prawy, wychylenie w kierunku góra-dół, 0x00 - max. w górę, 0xff-max. w dół | |||||||
Bajt nr 8 | dżojstik lewy, wychylenie w kierunku lewo-prawo, 0x00 - max. w lewo, 0xff-max. w prawo | |||||||
Bajt nr 9 | dżojstik lewy, wychylenie w kierunku góra-dół, 0x00 - max. w górę, 0xff-max. w dół |
Przykładowy programik
Przykładowy program był testowany na mikrokontrolerze atmega8 z częstotliwością pracy 8MHz. Obok gamepada ps2, dołączyłem do portów we/wy AVRa osiem diod LED i cztery przełączniki. Z użyciem przełączników wybieramy numer bajtu (0-8) odczytanego z pada, którego wartość ma być pokazany na ośmiu diodach LED.
Program przeznaczony jest dla uC ATMEGA taktowanego zegarem 8MHz, jeśli mikrokontroler ma pracować z większą częstotliwością, to program może wymagać drobnego dopasowania.
Katalog z plikami źródłowymi projektu można pobrać klikając w link ps2_pad.zip.
Jeśli nie wiesz jak skompilować i uruchomić przykład, to polecam artykuł "Szybki start z WinAVR"
Na zakończenie podpowiem, że aby odczytać z gamepada informacje o sile nacisku na przyciski i mieć możliwość sterowania silnikami wibracji, potrzeba wcześniej te funkcje aktywować, wysyłając do pada odpowiednie komendy konfiguracyjne. Listę komend kontrolera playstation2 można znaleźć w dokumencie: Playstation 2 controller protocol notes