Hola. El protocolo de la PSX es bastante simple, o bastante complicado, dependiendo de como lo miremos.
JDATA EQU 0 ;(MARRON)
COMMAND EQU 1 ;(NARANJA)
ATTENTION EQU 2 ;(AZUL)
CLOCK EQU 3 ;(BLANCO)
ACKNOWLEDGE EQU 4 ;(VERDE)
JDATA: Esta es una linea que proviene del joystick e ingresa al pic(entrada).Es la que nos enviara todos los valores del joystick.
NECESITA pull up externa(ya que la PSX tiene una dentro y en este caso, nosotros somos la PSX
)
COMMAND: Esta es una linea que proviene del PIC y va hacia el joystick(salida). Es con la que daremos las instrucciones necesarias al joystick(mas tarde comento esto).
ATTENTION: Esta linea proviene del PIC y va hacia el joystick(salida). Antes y durante la transmicion de datos, esta linea debe ponerce en bajo(0). Sirve para indicarle al joystick que queremos obtener data del mismo o bien escribir datos en el mismo(por ejemplo, cuando queremos que vibre si tiene ramble pack).
CLOCK:esta es una linea que proviene del PIC y va hacia el joystick(salida).El PIC genera el clock, y mediante este leeremos o escribiremos los datos en el joystick.
ACKNOWLEDGE: Esta linea proviene del joystick y va hacia el PIC(entrada).Es muy parecido al ACKNOWLEDGE en comunicaciones I2C. Luego de cada byte que enviamos o recibimos, el joystick debe enviarnos una señal de acknowledge para verificar que lo que estamos leyendo o escribiendo es correcto y la comunicacion esta funcionando.Destaco que el ultimo byte que leamos/escribamos NO enviara acknowledge(idem comunicaciones I2C).
NECESITA pull up externa(ya que la PSX tiene una dentro y en este caso, nosotros somos la PSX
)
Volviendo al clock. La info que tome de la web(veo si encuentro las paginas) no se ponen de acuerdo. Encontre paginas que decian que los datos deben ser escritos/leidos en cada ALTO del clock, mientras que otras paginas decian que debian escribirse/leerse en los BAJOS del clock.
Mi experiencia personal, probando ambos metodos, es que en ALTO funciona.Asi que prueben en ALTO, ya que logre hacerlo funcionar.
El protocolo es asi:
Inicializamos el CLOCK y el ATTENTION en ALTO.Respeten esto!.Dejen pasar un tiempo, y luego:ponemos en BAJO el ATTENTION.
Luego procedemos a enviar 0x01 al joystick.
Se vería asi:
CLOCK: -----____-----____-----____-----____-----____-----____-----____-----____----------
1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit
ATTENTION:_____________________________________________________________(dejenlo en bajo)
COMMAND:____--------_______________________________________________
Envio 0x01 mediante la linea command.
ACK: ---------------------------------------------------------------------------------------___-----
Si no recuerdo mal, la transmicion y recepcion se hace comenzando con el bit menos significativo primero.
Respeten los tiempos! Cada bit a cargar en COMMAND, debe ser cargado durante los BAJOS del CLOCK y mantenidos durante los ALTOS.
NO JUEGUEN CON EL CLOCK! una vez finalizado los 8 clocks por cada byte de comunicacion, DEJENLO EN ALTO(como deberia quedar al finalizar de cada byte)hasta que necesiten nuevamente volver a cambiarlo.
Luego de enviado el 0x01, inmediatamente debemos recibir un pulso bajo de ACKNOWLEDGE. Si no lo reciben, hay algo mal.
Ahora, procedemos a pedirle que se identifique. Esta parte de la comunicacion es BIDIRECCIONAL, o sea que mientras enviamos el byte, debemos leer el otro: el ID.
El ID es un byte que nos envia el periferico con un valor preestablecido para cada tipo.
Si tenemos conectado un joystick digital recibiremos 0X41.
Si tenemos conectado un joystick analogico que enciende luz roja recibiremos 0X73.
Si tenemos conectado un joystick analogico que enciende luz verde recibiremos 0X53.
Hay otros identificadores para el resto de perifericos(memory cards, etc) pero bueno...no los recuerdo
.
Entonces, lo que debemos hacer es enviar el valor 0x42, y a la vez, leer el ID del periferico:
CLOCK: -----____-----____-----____-----____-----____-----____-----____-----____----------
1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit
ATTENTION:_____________________________________________________________(dejenlo en bajo)
COMMAND:____________---------_______________________________---------___________
Envio 0x42 por la linea command como se ve arriba.
JDATA: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit
Leo en cada ALTO del clock esta linea(JDATA) para obtener el ID del periferico conectado.
ACK: --------------------------------------------------------------------------------------___-----
Otra vez deberemos recibir el ACKNOWLEDGE(ACK). Si no lo reciben, hay algo mal...
Bien, tercer paso de la comunicacion:
Simplemente ahora DEBEMOS recibir el valor 0x5A del joystick. Este valor es siempre el mismo(al menos en los perifericos que yo probe)
Entonces, simplemente esta vez, generamos el clock y leemos el JDATA.
CLOCK: -----____-----____-----____-----____-----____-----____-----____-----____----------
1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit
ATTENTION:_____________________________________________________________(dejenlo en bajo)
COMMAND: -noimporta-noimporta-noimporta-noimporta-noimporta-noimporta-noimporta-noimporta
JDATA: ______________---------________---------------------________----------__________
1bit 2bit 3bit 4bit 5bit 6bit 7bit 8bit
Leo en cada ALTO del clock esta linea(JDATA) para obtener 0x5A. Si obtienen otro valor, algo esta mal
ACK: ---------------------------------------------------------------------------------------___-----
Otra vez deberemos recibir el ACKNOWLEDGE(ACK). Si no lo reciben, hay algo mal...
Una vez obtenido el 0x5A. Finalmente comenzaremos a obtener los valores de los pulsadores y direcciones del PAD.
Esto se hace de manera similar a la obtencion del 0x5A. Solo generamos el clock y vamos leyendo los datos.
NOTA: Tanto el mando que es solo digital(ya casi ni se usa), como los mandos analogicos EN MODO DIGITAL, nos enviaran un ID 0x41.
En este modo, el PAD enviara 2 bytes de datos. Entonces, generamos 16 clock(2 bytes) y leemos los 2 bytes recibidos.
Cada bit corresponde a un pulsador.En modo digital, son 16 en total:
NO ESTAN EN ORDEN PERO SON: Circulo,Cuadrado,Rectangulo,Triangulo,L1,L2,R1,R2,Up,Down,Left,Right,Select,Start y......una aclaracion para los 2 pulsadores restantes:
Los mandos analogicos de PSX NO originales envian igualmente estando en modo digital los valores de los dos pulsadores "OCULTOS".Estos pulsadores son los que se encuentran al presionar hacia abajo las palancas analogicas(poseen 2 palancas los de PSX).
No ocurre lo mismo en los mandos analogicos originales de PSX, los cuales NO envian los valores de estos dos pulsadores si estan en modo DIGITAL.
Bien, entonces. Dije que con estos mandos, recibiremos 2 bytes. Luego de recibido el primer byte, nos fijaremos en recibir SI o SI el ACKNOWLEDGE. En el caso del segundo byte, como he dicho antes, por ser el ultimo byte de la comunicacion, NO RECIBIREMOS EL ACKNOWLEDGE. POR LO TANTO! Cuidado! no se queden esperando a este ACKNOWLEDGE porque nunca les llegara.
Luego de recibidos los dos bytes, procedemos a poner en ALTO(1) la linea ATTENTION. De esta manera, permitimos al PAD que se encargue de hacer sus otras obligaciones(volver a checkear los valores de los pulsadores para poder actualizar los datos).
Bien, y por ultimo en modo analogico.
En lugar de recibir 2 bytes, recibiremos 6.
Por lo tanto, necesitaremos generar 48 pulsos de CLOCK e ir leyendo cada byte para obtener los valores.
Los 3 primeros bytes que leamos, son identicos a los 2 que recibimos en modo digital.
Hay una diferencia. Sí recibiremos un ACKNOWLEDGE al final del segundo byte, ya que, en este modo, NO ES EL ULTIMO BYTE de la comunicacion.
Entonces, quedan 4 bytes restantes. Estos corresponden a los valores analogicos de las 2 palancas.
No recuerdo el orden, pero creo que era:
Byte3: Eje X Palanca analogica Izquierda
Byte4:Eje Y Palanca analogica Izquierda
Byte5: Eje X Palanca analogica Derecha
Byte6: Eje Y Palanca analogica Derecha(recordemos, que por ser ultimo byte, el pad no enviara ACKNOWLEDGE)
Las palancas poseen una resolucion de 1 byte por eje. Esto es lo mismo que decir 256 posiciones para el eje X y 256 para el Y. Esto nos da un total de 256*256 = 65536 posiciones posibles para cada palanca analogica.
En este caso, al ATTENTION recien lo ponemos en ALTO(1) una vez recibidos los 6 bytes.
Cada vez que deseen obtener los datos, simplemente vuelven a hacer todo lo dicho. Y es TODO! no intenten esquivar ningun paso xq no van a lograr que funcione....
Y RECUERDEN EL ATTENTION:
Lo ponen en BAJO(0) ANTEs de iniciar una peticion al mando, y hasta DESPUES de obtenerla.
Una vez obtenida, lo ponen en ALTO hasta la proxima peticion
Una cosa mas a tener en cuenta: Entre cada comunicacion, dejen un tiempo de descanso para el PAD, asi le permiten poder refrescar internamente los valores de los pulsadores.
El programa que publique anteriormente, es para mando en modo digital. Si lo ven, hace exactamente lo que he desarrollado en este post.
Espero que tenga exito(especialmente con los tan tercos mandos originales de PSX).
Exitos!