domingo, 29 de junho de 2014

PPI-Mega8 para o Hotbit - Matriz de diodos

Internamente o Hotbit possui um decodificador que converte os 4 bits da porta C da PPI para 10 linhas. A linha acionada corresponde ao valor em BCD.

Para se fazer um emulador de teclado que possa ser ligado ao conector interno de teclado do Hotbit torna-se necessário então converter de volta este valor para BCD.

Embora existam alguns chips para fazer isso, mas somente os consegui encontrar sob encomenda. Daí surge uma outra solução, que é fazer um codificador usando diodos, como o da figura abaixo, porém ele possui uma desvantagem que é a quantidade enorme de diodos necessária (21). 

Codificador Decimal para BCD com diodos
Contudo é possível simplificar esta matriz levando em conta algumas características do projeto: 

  • Apenas uma das saídas fica em nível baixo por vez. 
  • O HOTBIT usa apenas 9 sinais de seleção (em vez de 10 ou 11 como outros modelos de MSX). 
  • A porta C do ATMega8 que está sendo usado para ler a matriz do teclado ainda tem duas linhas disponíveis. 
Sendo assim, podemos simplificar a matriz de diodos do codificador de forma que ela utilize apenas 8 diodos. 
Matriz codificadora Decimal para 5 pinos.

O funcionamento da matriz é bem simples:
  • Quando o sinal Y0 é acionado, somente a linha PC0 é acionada;
  • Quando o sinal Y1 é acionado, as linhas PC0 e PC1 são acionadas; 
  • Quando o sinal Y2 é acionado, somente a linha PC1 é acionada;
  • Quando o sinal Y3 é acionado, as linhas PC1 e PC2 são acionadas;
  • ... e assim por diante. . 
E a tabela de entradas/saídas da matriz fica:


   PC4 PC3 PC2 PC1 PC0  HEXA   --------TECLAS--------
Y0  1   1   1   1   0    1E    7  6  5  4  3  2  1  0 
Y1  1   1   1   0   0    1C    Ç  ¨  ´  \  =  -  9  8 
Y2  1   1   1   0   1    1D    B  A  <  /  .  ,  [  ~
Y3  1   1   0   0   1    19    J  I  H  G  F  E  D  C
Y4  1   1   0   1   1    1B    R  Q  P  O  N  M  L  K 
Y5  1   0   0   1   1    13    Z  Y  X  W  V  U  T  S 
Y6  1   0   1   1   1    17    F3 F2 F1 C0 CA GR CT SH
Y7  0   0   1   1   1    07    RE SL BS ST TA ES F5 F4
Y8  0   1   1   1   1    0F    RT DW UP LT DE IN HO SP  

O fato de ter sido utilizada uma linha a mais implica que a matriz que guarda o estado das teclas de cada linha vai precisar ter 32 entradas.

Dessa forma, a definição da variável que armazena a matriz de teclado fica:

static volatite unsigned char keymat [32] = {
  0xff ; // 00
  0xff ; // 01
  0xff ; // 02
  0xff ; // 03

  0xff ; // 04
  0xff ; // 05
  0xff ; // 06
  0xff ; // 07  - Teclas RE SL BS ST TA ES F5 F4

  0xff ; // 08
  0xff ; // 09
  0xff ; // 0a
  0xff ; // 0b

  0xff ; // 0c
  0xff ; // 0d
  0xff ; // 0e
  0xff ; // 0f  - Teclas RT DW UP LT DE IN HO SP 

  0xff ; // 10
  0xff ; // 11
  0xff ; // 12
  0xff ; // 13  - Teclas Z  Y  X  W  V  U  T  S

  0xff ; // 14
  0xff ; // 15
  0xff ; // 16
  0xff ; // 17  - Teclas F3 F2 F1 C0 CA GR CT SH

  0xff ; // 18
  0xff ; // 19  - Teclas J  I  H  G  F  E  D  C
  0xff ; // 1a
  0xff ; // 1b  - Teclas R  Q  P  O  N  M  L  K

  0xff ; // 1c  - Teclas Ç  ¨  ´  \  =  -  9  8
  0xff ; // 1d  - Teclas B  A  <  /  .  ,  [  ~
  0xff ; // 1e  - Teclas 7  6  5  4  3  2  1  0
  0xff ; // 1f

}

Quando (por exemplo) se pressiona a tecla "A" no teclado PS/2 a função principal do programa do emulador de teclado faz o seguinte:

keymat [0x1d] &= ~(1<<6 font="">

E na rotina em assembly, as mudanças são mínimas (em relação à versão que lê direto da PPI)

ISR (PCINT1_vect, ISR_NAKED) {
  asm volatile (                    // 7 até aqui
   "in __tmp_reg__,__SREG__ \n\t"   // 1 Salva registrador de Status  
   "ldi r26,lo8(Keymap) \n\t"       // 1 Ponteiro X = endereço de Keymap
   "ldi r27,hi8(Keymap)\n\t"        // 1 
   "in r19,%0 \n\t"                 // 1 Amostra bits da porta C da PPI (PC0..PC4)
   "andi r19,0x1f \n\t"             // 1 limpa bits 5..7
   "add r26,r19 \n\t"               // 1 soma com ponteiro 
   "ld r19,X \n\t"                  // 1 lê coluna correspondente do mapa de teclas
   "out %1,r19 \n\t"                // 1 escreve na porta B da PPI
                                    // até aqui 15 instruções 
   "out __SREG__,__tmp_reg__ \n\t"  // restaura registrador de Status
   "reti \n\t" 
  
   :: "I" (_SFR_IO_ADDR(PINC)), "I" (_SFR_IO_ADDR(PORTB)) ); 
   
}

Com isso, já dá pra definir o layout da placa do adaptador. Os dois conectores têm como objetivo manter o teclado interno funcionando junto com o emulador de teclado.

Adaptador interno para o teclado do Hotbit

Nenhum comentário: