roboforum.ru

Технический форум по робототехнике.

Подключение геймпада PS2 к ARM'у

Подключение геймпада PS2 к ARM'у

hudbrog » 27 окт 2008, 00:19

Собственно, не то, чтобы достижение, но все же )
Седня съездил на Юнону, купил себе подарков - всякого железного хлама. Экспонат номер один - джойстик для плейстейшн 2 за 50 рублей =) Давно уже была идея, что надо сделать внешний контроллер какой-нить удобный для экспериментов всяких.. а тут оно под руку подвернулось так удачно.
Как оказалось, у пс2 простейший протокол, прекрасно описанный в интернете... написал прошивку под арм, на процессинге накатал простенькую утилитку - рисовалку контроллера/обработчик данных. Вот такая вот фигня получилась:
pscprocessing.jpg

(там на экране видно, что нажата одна кнопка и джойстик отклонен вправо)
psxarm.jpg


А вот кусок кода под арм(единственная особенность - для ноги PS_DATA надо включить пулап) :
Код: Выделить всёРазвернуть
unsigned char psx_byte(unsigned char psbyte){
unsigned char psdata=0;
int i=0;
   for(i=0;i<8;i++){
      AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PS_CLK);
      if(psbyte & (1<<i))   AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PS_CMD);
      else AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PS_CMD);
      wait(1);
      if(AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, PS_DATA)) setbit(psdata, i);
      AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PS_CLK);
      wait(1);
   }
   AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PS_CMD);
   wait(1);
   return psdata;
}

void psx_poll(int cnt){
int i=0;
   for(i=0;i<18;i++){
      psx_data[i]=0;
   }
   AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PS_CMD|PS_CLK);
   AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, PS_ATT);
   wait(1);
   psx_byte(0x01);
   psx_byte(0x42);
   psx_byte(0x00);
   for(i=0;i<cnt;i++){
      psx_data[i] = psx_byte(0x00);
   }
   AT91F_PIO_SetOutput(AT91C_BASE_PIOA, PS_ATT);
}

Re: Подключение геймпада PS2 к ARM'у

Сергей » 27 окт 2008, 00:26

Я заметил у тебя там ЖТАГ подключен? И не понял что именно ты написал на процессинге

Re: Подключение геймпада PS2 к ARM'у

hudbrog » 27 окт 2008, 00:33

Да, подключен.
На процессинге написал то, что видно на экране (вдалеке за геймпадом) на первой фотке. Программка, которая рисует на экране контроллер, раз в какое-то время забирает с микроконтроллера статус-байты геймпада (прямо в том виде, в котором они были с него получены), эти байты парсит и рисует на джойстике его состояние - подсвечивает кнопки, для аналоговых стиков - рисует в какоую сторону и как сильно он наклонен. Это просто заделка на будущее... последнее время все что делаю - стараюсь делать управляемым через ПК, теперь, в частности, со всяких тулзов на процессинге... вот это что-то вроде библиотеки для будущих использований джойстика.

Re: Подключение геймпада PS2 к ARM'у

Сергей » 27 окт 2008, 00:48

Покажи хотябы кусок кода на процессинге для отображения джойстика, просто интересно

Re: Подключение геймпада PS2 к ARM'у

hudbrog » 27 окт 2008, 01:01

Вот код всей софтины. Ничего интересного на самом деле. При желании можно было сделать интереснее - загрузить svg'шку джойстика и подсвечивать объекты в ней... но у меня нету svg'шки такой =)
Код: Выделить всёРазвернуть
import processing.serial.*;

Serial myPort;
String inString;
Integer[] psx_data;
color color_pressed;
color color_unpressed;

void setup(){
  size(640,480);
  psx_data = new Integer[18];
  for(int i=0;i<18;i++)psx_data[i]=0;
  color_unpressed = color(0, 100, 250);
  color_pressed = color(0, 250, 100);
  inString = "";
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 115200);
  myPort.write(97);
  strokeWeight(5);
}

void draw(){
  background(0);
  draw_psx(200,350);
  myPort.write(99);
  delay(10);
}



void draw_psx(int x, int y){
  rectMode(CORNER);
  stroke(120);
  fill(120);
  rect(x,y, 240, 100);
  rectMode(CENTER);
  stroke(0);
  if((psx_data[1] & 16) != 0) fill(color_pressed);
  else fill(color_unpressed);
  ellipse( x + 205, y + 20, 20, 20);
  if((psx_data[1] & 128) != 0) fill(color_pressed);
  else fill(color_unpressed);
  ellipse( x + 185, y + 40, 20, 20);
  if((psx_data[1] & 32) != 0) fill(color_pressed);
  else fill(color_unpressed);
  ellipse( x + 225, y + 40, 20, 20);
  if((psx_data[1] & 64) != 0) fill(color_pressed);
  else fill(color_unpressed);
  ellipse( x + 205, y + 60, 20, 20);
  fill(color_unpressed);
  ellipse( x + 155, y + 70, 40, 40);
  ellipse( x + 85, y + 70, 40, 40);
  stroke(color_pressed);
  line( x + 155, y + 70, x + 155+int(map(~psx_data[2], 0, 255, -20,20)),y + 70+int(map(~psx_data[3], 0, 255, -20,20)));
  line( x + 85, y + 70, x + 85+int(map(~psx_data[4], 0, 255, -20,20)),y + 70+int(map(~psx_data[5], 0, 255, -20,20)));
  stroke(0);
 
  if((psx_data[0] & 16) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 35, y + 20, 20, 20);
  if((psx_data[0] & 128) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 15, y + 40, 20, 20);
  if((psx_data[0] & 32) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 55, y + 40, 20, 20);
  if((psx_data[0] & 64) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 35, y + 60, 20, 20);
 
  if((psx_data[0] & 1) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 95, y + 35, 20, 10);
  if((psx_data[0] & 8) != 0) fill(color_pressed);
  else fill(color_unpressed);
  rect(x + 145, y + 35, 20, 10);
}

void serialEvent(Serial port){
  char ch = port.readChar();
  if(ch != 13)
    inString = inString + ch;
  else if(ch == 13){
    println(inString);
    String []p = splitTokens(inString, ", ");
    for(int i=0; (i< p.length && i<18); i++)
      psx_data[i] = ~Integer.parseInt(p[i]);
    inString = "";
  }
}



Rambler\'s Top100 Mail.ru counter