Neste trecho falarei do meu projeto, que é o controle emissor e o receptor.
Controle Emissor:
O Controle tem por função ler uma matriz de teclas, gerenciar os dados e emiti-los atravez de um protocolo via infravermelho.
A quantidade de teclas do controle SCPH-1008 são :
4 - Direcionais (Up, Down, Left, Right)
4 - Triangulo, Quadrado, X e Circulo
2 - Start e Menu
4 - R1 e R2, L1 e L2
Total = 14 teclas.
A linha de comunicação do controle emite o os dados via MSB primeiro e os dados assim:
7 6 5 4 3 2 1 0
D0 = Lf Dw Rg Up St 01 01 Sl
D1 = Sq X Ci Tr R1 L1 R2 L2
Portanto, para facilitar o uso dos circuitos e programação, fiz a matriz igual a aos dados do envio:
7 6 5 4 3 2 1 0
M1 - Lf Dw Rg Up St 01 01 Sl
M2 - Sq X Ci Tr R1 L1 R2 L2
(Até pode ser invertido, mas isso sera inerente, pois o resultado vai ser o mesmo ao enviar.)
O diferencial neste esquema é que o sistema reconhece uma tecla como ativa estando o sinal em LOW.
A leitura consiste em ativar a linha M1, mover os dados da PORTA para W, complementar através do operando COMF, e move-lo para a variável D0.
A segunda parte consiste no mesmo processo, só que ao invés de M1 é M2, e D0 é D1.
O próximo passo é uma das partes mais chatinhas, que é o fato de transmitir os dados via infravermelho.
Verifiquei vários métodos e protocolos dos fabricantes, acabei que optando por fazer um protocolo meu e transmitindo por pulsos.
Como funciona esse protocolo?
A frequência de transmissão é de 40Khz ou 25 us. O uso desta frequência se deve o fato de vários demoduladores no mercado trabalharem nesta frequência.
Os pacotes de transmissões são:
1 - Start_Transmission
2 - ID
3 - D0
4 - D1
O sinal de transmissão Start_Transmission consiste num pulso de comprimento 15us Ativo e 10us Inativo. (ou como chamo escala 6 por 4, por que é 60% ativo + 40% inativo do período 25us)
Como todo os dispositivos remotos, necessita de uma identificação, até porque se farei mais de um controle, é vital que os dois não entre em conflito. Usarei um byte (8 bits) no qual somente pode endereçar 255 dispositivos (valores entre 0x01 a 0xFF).
Para a emissão destes valores, usarei a escala 6x4 para sinal de valor 1 e 4x6 para sinal de valor 0, isto é,
quando o bit é 1, 15us ativo e 10us inativo, quando o bit é 0, 10us ativo e 16us inativo.
A emissão de D0 e D1 é o mesmo principio de ID, a transmissão de 1 byte por variável por escala 6x4 ou 4x6.
Os dados, são enviado do LSB primeiro. O receptor que ira interpretar e inverter o byte no recebimento.
Entre as transmissões, não se tem o Acknowledge, pois somente há a transmissão do controle e recepção do dispositivo.
O controle por si só ja esta bem funcional, porem há itens a ressaltar, o controle nao ira enviar os dados constantemente, tem debounce, economia de energia (pois sera usado pilhas ou bateria) e outros.
Função Extra 1: Modo Sleep
Para economizar a pilha ou bateria, é necessário colocar o aparelho em um estado menos consumível possível, para isso deve-se colocar o PIC em modo Sleep.
Sera colocado um botao no pino RB0. Este pino tem como função ser um gerador de interrupção, com isso ele ira acionar o vetor 0x04 no PIC no qual havera uma instrução de Sleep.
Para retornar do modo Sleep, basta apertar qualquer tecla.
Função Extra 2: Auto ShutOff
Em uma forma preguiçosa de não ter que ficar apertando o botão Sleep, haveria uma instrução usando o timmer 1 para contar o tempo apos nenhuma tecla ser pressionada, ocorrido o tempo, entraria em modo Sleep.
Para retornar. bastaria apertar qualquer tecla.
O tempo sera de 1 min (60s), pois dificilmente há carregamentos de jogos tao lentos, e caso haja passara deste tempo e ao retornar bastaria apertar qualquer tecla.
O timer 1 tem um registrador de 16 bits, isto é, conta de 0x0000 a 0xFFFF, com prescaler de 1/1 a 1/8.
Usando o prescaler 1/8 o tempo de estouro do con tador com um clock de 1Mhz (4Mhz/4) é de 0,524288s.
Fora isto, é necessario ter mais 1 contador, gerenciado via software, para que incremente 115 vezes para que o valor chegue a 60,29s. Apos isto o software entra em vetor de interrupção.
Função Extra 3: Debounce
Toda interface humana necessita de um atraso, pois o microcontroladores trabalham muito mais rapidamente que nossos pulsos nervosos, caso nao tivesse esta instrução num pressionar de tecla o controle iria reconhecer centenas de vezes como a tecla tivesse pressionada enquanto para nos era so um clique.
O diferencial entre um pressionamento e outro é de 20ms.
A matriz é lida, verificada se tem alguma tecla pressionada e mantida numa variavel, tem-se um delay de 20ms e é re-lido a matriz, caso seja igual os valores os dados sao enviado a uma variavel de transmissão, ao contrario são descartados.
Função Extra 4: Brown-Out-Reset
O PIC tem uma função muito boa que é o Brown Out Reset, ele consiste em auto-reiniciar o aparelho na queda de energia (para proteger o circuito).
Ela é bastante útil se tratando de pilhas. A ideia é o seguinte, quando a bateria baixa a tensão (quando tiver descarregada), o PIC reinicia automaticamente e seta o bit responsável, ao retornar do reinicio, verifica-se se o bit foi setado, caso sim, o MCU desativa a opção de interrupção das teclas (Para não ter que ligar novamente), emite um sinal de escala 4x6 via infravermelho e entra em modo Sleep.
O sinal 4x6 enviado para o receptor via indicar que o controle esta sendo desligado (modo sleep), e o receptor ira passar ao Playstation através do corte do sinal ACK (lembra que ele depois de 60us da como controle inexistente??), fazendo com que o playstation exiba a imagem "Controller Not Found" (isto varia de jogo) e passando ao jogador a informação de que o controle não está ativo.
Função Extra 5:
O receptor ira reter os dados até que um novo dado seja recebido, para isto o dado é verificado se é igual ao anterior, caso for ele retorna ao inicio da instrução, contrario ele emite os dados para o receptor.
O Receptor
Já foi visto no tópico anterior sobre como o controle se comunica com o Playstation.
A comunicação com o Playstation tem o maior privilégio, pois se cortar comunicação com ele, o mesmo dara como inexistente.
A marcação dos pinos fica por assim:
DAT = Serial Data Out = Pino RC5
CMD = Seria Data In = Pino RC4
CLK = Serial Clock = Pino RC3
ATT = Slave Select = Pino RA5
Um dos problemas aqui é que o PIC envia os dados sendo LSB primeiro. mas isto será demonstrado na parte em que falarei do recebimento do dados Infravermelho.
O envio do dados aqui é simples, é só esperar o pino SS estiver setado, ativar o clock e emitir o valor 0x01 (que o PIC vai receber como 0x80).
Ele vai comparar o valor e confirmar que é pra ele mesmo (o playstation usa a mesma via para o Memory Card). Caso seja pra ele mesmo, emitira o sinal ACK.
Em seguida o PS1 vai enviar o dado 0x42 ( 0x42) e o PIC vai enviar o dado 0x41 (0x82) indicando que é um controle D-PAD, e emitir o sinal ACK.
Vai emitir o dado 0x5A (0x5A) e o sinal ACK.
Agora ele vai emitir os recebidos pelo infravermelho D0 e emitir o sinal ACK, e depois somente envia o dado D1.
Na parte do recebimento infravermelho, o PIC deverá ficar numa rotina esperando o sinal ficar ativo em uma das portas.
Caso setado, ele move o valor para o timer0 e cronometa o tempo de 10us ativo, se concluido é porque tem de cortar a comunicação com o PS1, maior que 11us (15us), se prepara para receber o ID.
O recebimento dos dados é por comprimento de sinal, para que isso seja feito a rotina tera de esperar o momento que ira ativar a porta e o tempo minimo (11us) para identificar o tipo de dado. Em seguida, tem de ser feito a rotação do byte para incrementar o bit recebido, se a saida do dados do controle for MSB primeiro, a rotação segue a esquerda, ao contrario para a direita.
Se o valor do ID for diferente do registrador no receptor, ignora-se os valores recebidos (recebe-se da mesma maneira), ao contrário sera movido os valores para um registrador proprio.
Este é como deve funcionar o projeto... rsrs