Apesar de existirem algumas bibliotecas para leitura de teclado PS/2 disponíveis, nenhuma que achei me serviu basicamente se utilizam de interrupções para ler o teclado e pela conversão de códigos para valores ASCII usando tabelas de estados com e sem shift, etc. Outras razões são o não processamento da teclas PAUSE/BREAK que pretendo utilizar STOP, e o excesso de 'orientação ao sucesso', por desconsiderar timeouts, bits errados, caracteres inesperados, etc.
Eis o primeiro passo, o pseudo codigo para leitura de scan codes, que apesar de ser por polling, pode ser facilmente adaptado para rodar por interrupçoes.
// pseudo codigo para comunicação
// com teclado ps/2
enum estados {STARTBIT,
DATABITS,
PARITYBIT,
STOPBIT};
unsigned char estado, contador, paridade, dado, novodado, bit;
// Waitclock
boolean waitclock(void);
// retorna falso se timeout
// retorna true se detecdada borda de descida
unsigned char getbit(void);
// retorna 1 se o bit amostrado está no estado ativo
// retorna 0 se o bit amostrado está no estado inativo
// rotina de recepção
novodado=0;
estado=STARTBIT;
do {
if (!waitclock()) { // sempre que houver timeout
estado=STARTBIT; // volta a esperar o startbit
} else {
bit=getbit();
switch (estado) {
case STARTBIT: if (bit==0) { // Se o start bit for o valor correto
contador=8; // contador de bits
paridade=0; // contador para verificar paridade
estado=DATABITS;
}
break;
case DATABITS: dado <<=1; // insere bit amostrado
dado |= bit;
paridade +=bit; // incrementa contador de paridade
contador--; // decrementa contador de bits
if (contador==1) { // se recebeu ultimo bit de dados
estado=PARITYBIT // vai aguardar bit de paridade
}
break;
case PARITYBIT: paridade +=bit; // soma o bit de paridade.
if (paridade & 1) { // se a paridade está correta o resultado é impar
estado=STOPBIT
} else { // se a paridade não for correta
estado=STOPBIT; // vai aguardar novamente o bit de início
}
break;
case STOPBIT: if (bit==1) { // se o stop bit for o valor correto
novodado=1; // sinaliza novo dado recebido
}
break;
} // switch
} // else
} while (!novodado);
processa (dado);
Nenhum comentário:
Postar um comentário