Doble teclado en ZXUNO

Dudas, cuestiones, sugerencias y peticiones en general sobre el proyecto / Questions and requests about the project
Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: Doble teclado en ZXUNO

Mensaje por spark2k06 » 30 Jul 2017, 10:19

Continuando con las pruebas, puedo confirmar y confirmo que no se trata de problemas de timings ni de inicialización de teclado. He reducido el código a la mínima expresión, dejando únicamente un bucle infinito de pulsaciones de la tecla 'A' cada segundo, tras una espera inicial de 20 segundos... y me extraña que en el GO+ con el código de neuro funcione bien, porque la función SendPS2 es calcada y se puede encontrar en diversos proyectos de comunicacion PS/2 por internet. Ya la única diferencia con respecto a Joy2PS2 es que en mi caso estoy utilizando un atmega168 y el creo que lo usa en un 328.

A continuación un vídeo de prueba con este código, para que observéis el efecto:

phpBB [media]


Sin teclado físico conectado al mismo tiempo siempre funciona bien, y con éste conectado parece que va bien al principio, pero al cabo de un tiempo comienzan a suceder los efectos extraños... incluso se reinicializa el teclado físico él sólo como se puede apreciar por el apagado y encendido de luces del mismo.

Lo que sí he observado es que sin embargo, en el core de PC/XT, utilizando scancodes del set 1 va perfecto, el tiempo que lo he probado claro. Puede ser debido a que éste set es más simple que el 2, ya que no se utiliza el scancode 0xF0 para liberar la pulsación.

Aquí dejo el código dummy listo para compilar y subir desde el mismo entorno IDE de Arduino, por si lo puede probar alguien que tenga un teclado gomas con arduino o el propio ZXGO+, y un teclado físico al mismo tiempo sin Joy2PS2 de por medio:

Código: Seleccionar todo

#define HI 1
#define LO 0
#define CK1 4
#define CK2 8
#define PS2_PORT  PORTC
#define PS2_DDR   DDRC
#define PS2_PIN   PINC

#define PS2_DAT   PC3
#define PS2_CLK   PC2

void ps2Mode(uint8_t pin, uint8_t mode)
{
  if (mode) { //high
    PS2_DDR &= ~_BV(pin); //input (Truco DDR. Como input sin estado, se pone en modo Hi-Z)
  }
  else { //low
    PS2_DDR |= _BV(pin); //output (Truco DDR. Como output, se pone a 0v)
  }
}

void ps2Init()
{
  //ponemos en alto ambas señales
  PS2_PORT &= ~_BV(PS2_DAT); //A 0
  PS2_PORT &= ~_BV(PS2_CLK); //A 0
  ps2Mode(PS2_DAT, HI);
  ps2Mode(PS2_CLK, HI);
}
uint8_t ps2Stat()
{
  if (!(PS2_PIN & (1 << PS2_CLK)))
    return 1;
  if (!(PS2_PIN & (1 << PS2_DAT)))
    return 1;

  return 0;
}

void sendPS2(unsigned char code)
{
  //Para continuar las líneas deben estar en alto  
  while (ps2Stat());

  unsigned char parity = 1;
  uint8_t i = 0;

  //iniciamos transmisión
  ps2Mode(PS2_DAT, LO);
  _delay_us(CK1);

  ps2Mode(PS2_CLK, LO); //bit de comienzo
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);
  //enviamos datos
  for (i = 0; i < 8; ++i)
  {
    if (code & (1 << i))
    {
      ps2Mode(PS2_DAT, HI);
      parity = parity ^ 1;
    }
    else
      ps2Mode(PS2_DAT, LO);

    _delay_us(CK1);
    ps2Mode(PS2_CLK, LO);
    _delay_us(CK2);
    ps2Mode(PS2_CLK, HI);
    _delay_us(CK1);
  }

  // Enviamos bit de paridad
  if (parity)
    ps2Mode(PS2_DAT, HI);
  else
    ps2Mode(PS2_DAT, LO);

  _delay_us(CK1);
  ps2Mode(PS2_CLK, LO);
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);

  //Bit de parada
  ps2Mode(PS2_DAT, HI);
  _delay_us(CK1);
  ps2Mode(PS2_CLK, LO);
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);

  _delay_us(50);
  
}

void setup() {
  // put your setup code here, to run once:
  ps2Init();
  delay(20000);
}

void loop() {
  // put your main code here, to run repeatedly:
    sendPS2(0x1C); // Key A
    delay(100);
    sendPS2(0xF0); // Release   
    sendPS2(0x1C); // Key A
    delay(1000);
}
Edito:

Para probarlo con el ZXGo+ o teclado arduino basado en el código de neuro, cambiar estos defines por el valor correspondiente:

Código: Seleccionar todo

#define PS2_DAT		PC4
#define PS2_CLK		PC5
Última edición por spark2k06 el 30 Jul 2017, 10:46, editado 3 veces en total.

Avatar de Usuario
neuro_999
Mensajes: 692
Registrado: 06 Oct 2015, 10:14

Re: RE: Re: Doble teclado en ZXUNO

Mensaje por neuro_999 » 30 Jul 2017, 10:35

spark2k06 escribió:Continuando con las pruebas, puedo confirmar y confirmo que no se trata de problemas de timings ni de inicialización de teclado. He reducido el código a la mínima expresión, dejando únicamente un bucle infinito de pulsaciones de la tecla 'A' cada segundo, tras una espera inicial de 20 segundos... y me extraña que en el GO+ con el código de neuro funcione bien, porque la función SendPS2 es calcada y se puede encontrar en diversos proyectos de comunicacion PS/2 por internet. Ya la única diferencia con respecto a Joy2PS2 es que en mi caso estoy utilizando un atmega168 y el creo que lo usa en un 328.

A continuación un vídeo de prueba con este código, para que observéis el efecto:

phpBB [media]


Sin teclado físico conectado al mismo tiempo siempre funciona bien, y con éste conectado parece que va bien al principio, pero al cabo de un tiempo comienzan a suceder los efectos extraños... incluso se reinicializa el teclado físico él sólo como se puede apreciar por el apagado y encendido de luces del mismo.

Lo que sí he observado es que sin embargo, en el core de PC/XT, utilizando scancodes del set 1 va perfecto, el tiempo que lo he probado claro. Puede ser debido a que éste set es más simple que el 2, ya que no se utiliza el scancode 0xF0 para liberar la pulsación.

Aquí dejo el código dummy listo para compilar y subir desde el mismo entorno IDE de Arduino, por si lo puede probar alguien que tenga un teclado gomas con arduino o el propio ZXGO+, y un teclado físico al mismo tiempo sin Joy2PS2 de por medio:

Código: Seleccionar todo

#define HI 1
#define LO 0
#define CK1 4
#define CK2 8
#define PS2_PORT  PORTC
#define PS2_DDR   DDRC
#define PS2_PIN   PINC

#define PS2_DAT   PC3
#define PS2_CLK   PC2

void ps2Mode(uint8_t pin, uint8_t mode)
{
  if (mode) { //high
    PS2_DDR &= ~_BV(pin); //input (Truco DDR&#46; Como input sin estado, se pone en modo Hi-Z)
  }
  else { //low
    PS2_DDR |= _BV(pin); //output (Truco DDR&#46; Como output, se pone a 0v)
  }
}

void ps2Init()
{
  //ponemos en alto ambas señales
  PS2_PORT &= ~_BV(PS2_DAT); //A 0
  PS2_PORT &= ~_BV(PS2_CLK); //A 0
  ps2Mode(PS2_DAT, HI);
  ps2Mode(PS2_CLK, HI);
}
uint8_t ps2Stat()
{
  if (!(PS2_PIN & (1 << PS2_CLK)))
    return 1;
  if (!(PS2_PIN & (1 << PS2_DAT)))
    return 1;

  return 0;
}

void sendPS2(unsigned char code)
{
  //Para continuar las líneas deben estar en alto  
  while (ps2Stat());

  unsigned char parity = 1;
  uint8_t i = 0;

  //iniciamos transmisión
  ps2Mode(PS2_DAT, LO);
  _delay_us(CK1);

  ps2Mode(PS2_CLK, LO); //bit de comienzo
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);
  //enviamos datos
  for (i = 0; i < 8; ++i)
  {
    if (code & (1 << i))
    {
      ps2Mode(PS2_DAT, HI);
      parity = parity ^ 1;
    }
    else
      ps2Mode(PS2_DAT, LO);

    _delay_us(CK1);
    ps2Mode(PS2_CLK, LO);
    _delay_us(CK2);
    ps2Mode(PS2_CLK, HI);
    _delay_us(CK1);
  }

  // Enviamos bit de paridad
  if (parity)
    ps2Mode(PS2_DAT, HI);
  else
    ps2Mode(PS2_DAT, LO);

  _delay_us(CK1);
  ps2Mode(PS2_CLK, LO);
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);

  //Bit de parada
  ps2Mode(PS2_DAT, HI);
  _delay_us(CK1);
  ps2Mode(PS2_CLK, LO);
  _delay_us(CK2);
  ps2Mode(PS2_CLK, HI);
  _delay_us(CK1);

  _delay_us(50);
  
}

void setup() {
  // put your setup code here, to run once&#58;
  ps2Init();
  delay(20000);
}

void loop() {
  // put your main code here, to run repeatedly&#58;
    sendPS2(0x1C); // Key A
    delay(100);
    sendPS2(0xF0); // Release   
    sendPS2(0x1C); // Key A
    delay(1000);
}
Yo te lo pruebo en cuanto saque un rato el lunes a ver que hace en el go+ si no ha hecho la prueba nadie antes. [emoji2]

Enviado desde mi ONE A2003 mediante Tapatalk

Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: RE: Re: Doble teclado en ZXUNO

Mensaje por spark2k06 » 30 Jul 2017, 10:38

neuro_999 escribió:Yo te lo pruebo en cuanto saque un rato el lunes a ver que hace en el go+ si no ha hecho la prueba nadie antes. [emoji2]

Enviado desde mi ONE A2003 mediante Tapatalk
Perfecto, gracias. Para tu proyecto no olvides cambiar los defines de CLK y DAT por los pines adecuados, tal como comento en la edición que he realizado:

Código: Seleccionar todo

#define PS2_DAT		PC4
#define PS2_CLK		PC5

enkonsierto
Mensajes: 80
Registrado: 25 Oct 2015, 07:49

Re: Doble teclado en ZXUNO

Mensaje por enkonsierto » 30 Jul 2017, 12:17

spark2k06 escribió: Sin teclado físico conectado al mismo tiempo siempre funciona bien, y con éste conectado parece que va bien al principio, pero al cabo de un tiempo comienzan a suceder los efectos extraños... incluso se reinicializa el teclado físico él sólo como se puede apreciar por el apagado y encendido de luces del mismo.
Ese reinicio del que hablas también me ocurre a mí. Bueno, de hecho el comportamiento que se muestra en el video es justo lo que me pasa.

Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: Doble teclado en ZXUNO

Mensaje por spark2k06 » 31 Jul 2017, 06:41

enkonsierto escribió: ¿Poniendo diodos entre ambos ps/2 y así evitar que se interfieran?.
Buena idea :okidoki; , aunque he probado a poner un diodo sólo en un conector y en la línea DATA, porque el efecto directo que tiene es que el teclado conectado al mismo no puede recibir comandos:

Imagen

Un efecto colateral es que no podrás utilizar teclados externos en dicho puerto para el core de PC/XT, el único que requiere inicialización y cambio al set 1 de instrucciones, pero lo demás funciona bien, eso sí en el teclado ACER que véis a continuación:

phpBB [media]


Tengo otro teclado que sigue dando problemas, he probado a ponerle dos diodos en lugar de uno, en la linea DATA y en la linea CLK, los resultados mejoran muchísimo, aunque algunas veces falla... quizá sea por el tipo de diodo utilizado que no sea el más adecuado.

En definitiva, que el tema de los diodos puede ser una solución, a falta de probar con mas teclados y ver cuales son los diodos mas adecuados (mas eficientes?). Y por otro lado, siendo conscientes de la perdida que se tiene debido al capado de la escucha de comandos (pero solo para el teclado externo).

Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: Doble teclado en ZXUNO

Mensaje por spark2k06 » 31 Jul 2017, 09:11

Vale, con un solo diodo en la línea DATA es suficiente y con la limitación comentada del core de PC para el teclado externo, seria tal como se ve en la fotografía. El otro conflicto era debido a que mantengo activa la escucha de comandos en Joy2PS2 por defecto, pero si se desactiva (en modo SHIFT, B1+LEFT) ya funciona siempre bien. Actualizaré el firmware para que por defecto, la escucha se encuentre inactiva. (Habría que activarla solo para entrar al core de PC y que el gamepad funcione bien en éste)

Tema resuelto por tanto, al menos para Joy2PS2. Habrá que probarlo exhaustivamente no obstante.

Enviado desde mi Thor mediante Tapatalk

enkonsierto
Mensajes: 80
Registrado: 25 Oct 2015, 07:49

Re: Doble teclado en ZXUNO

Mensaje por enkonsierto » 31 Jul 2017, 11:52

Voy a probar a poner el diodo en la linea data en el teclado gomas a ver si también se soluciona. Informaré por aquí.


Avatar de Usuario
spark2k06
Mensajes: 1188
Registrado: 12 Feb 2016, 13:58

Re: Doble teclado en ZXUNO

Mensaje por spark2k06 » 31 Jul 2017, 15:36

enkonsierto escribió:Voy a probar a poner el diodo en la linea data en el teclado gomas a ver si también se soluciona. Informaré por aquí.
Firmware de Joy2PS2 actualizado, si vas a probarlo con éste, hazlo con la versión que adjunto.

Mas información en el hilo de novedades.
Adjuntos
joy2ps2_release_5.zip
(8.25 KiB) Descargado 199 veces

enkonsierto
Mensajes: 80
Registrado: 25 Oct 2015, 07:49

Re: Doble teclado en ZXUNO

Mensaje por enkonsierto » 31 Jul 2017, 16:48

lo descargo y lo pruebo.

Responder