HENRY
Esta página documenta a máquina impressora de cheques HENRY, encontrada no lixo da Estação de Metareciclagem Samambaia (Distrito Federal).
Modelo da PCB: HENRY PINHAIS/PR REV.1
componentes
- CPU: 80C31
- RAM: UM62256B (RAM estática de 32k bytes)
- EEPROM 27C512 (64k bytes) Marcada com um adesivo escrito "PROT V19 Henry Equipamentos e Sistemas LTDA"
- glue logic: diversos chips TTL da família 74
- display de cristal líquido de 2x16 caracteres (HD44780)
- CHIP desconhecido na posição U2.
U2
- hipótese: DS1307: 64 x 8 Serial Real-Time Clock
esquemático
Está sendo levantado o esquemático desta placa (rev1) no repositório https://github.com/GaroaHC/HENRY no subdiretório kicad.
emulação
No repositório https://github.com/GaroaHC/HENRY no subdiretório mess há um esboço de emulador deste equipamento (já parcialmente funcional).
Em Janeiro de 2014 este driver foi incorporado oficialmente ao código fonte do projeto MESS.
Comportamento do dispositivo real
- Ao ligar, aparece a mensagem "Inicializando..."
- Logo depois, "Verificando memória..."
- E, enfim, "Ajuste a data:\n01/01/99 sex"
- botão preto superior muda de campo ciclicamente da esquerda para a direita
- botão preto inferior incrementa o campo selecionado (o dia da semana é calculado pela máquina e exibido à direita da data)
- botão azul alterna entre ajuste de data e a mensagem "PROT Vrs. R19\n 01/02/02" o que nos leva a crer que o firmware R19 é de 1.o de fevereiro de 2002.
- botão azul pressionado por algum tempo = OK, vai para próxima configuração: "Ajuste a hora" "01:14:00"
- botão azul pressionado por algum tempo = mostra "Entrando em ajustes." e logo depois "Apagar a memoria e o horario ?" + cursor piscante
- clique no botao azul = "PROTOC. A" "01:01 seg 1via"
- Ao fechar o opto de detecção de papel, a cabeça de impressão se move para a direita e depois para a esquerda e em seguida, vemos a mensagem "Dificuldades :" "Movimento motor"
ligações
display
Display LCD de 2 linhas de caracteres compatível com HITACHI HD44780. Extremamente comum.
- Pino 1 = marrom -> ligado ao pino 1 do display
- pino 2 = não usado
- pino 3 = vermelho
- e assim por diante
Os pinos 15 e 16 do display não estão ligados a nada. Apesar de se pular o pino 2 no conector, a ligação dos pinos do display é sequencial, ou seja, pino 1 = marrom, pino 2 = vermelho, etc...
teclado
- pino 1 = marrom -> botão preto de cima
- pino 2 não usado
- pino 3 = vermelho -> botão preto de baixo
- pino 4 = laranja -> botão azul
- pino 5 = amarelo -> GND: comum a todos os botões
motores
- pino 1 = amarelo
- pino 2 não usado
- pino 3 = laranja
- pino 4 não usado
impressora
- pino 1 não usado
- pino 2 = amarelo
- pino 11 = roxo
Transistores TIP122 em encapsulamento TO-220.
jumper 1
Botão liga-desliga ? Aparentemente não tem polaridade.
Olhando para o silk da placa com o texto JP1 de pé:
- pino da esquerda = marrom
- pino da direita = vermelho
sensores
- pino 1 não usado (o conector nem encaixa nesse pino)
- pino 2 = marrom (Vcc) pino 0 dum sensor optico (de leitura da presença de um cheque?)
- pino 3 não usado
- pino 4 = vermelho -> pino 1 do opto do encoder
- pino 5 = laranja -> pino 3 do opto do encoder
- pino 6 = amarelo -> pino 1 do fim de curso
- pino 7 = verde -> pino 3 do fim de curso
- pino 8 = azul -> pino 1 do sensor de cheque
- pino 9 = roxo -> pino 3 do sensor de cheque
Os pino 2 tanto do sensor do cheque e do fim de curso não é usado.
borne CN7
Olhando o silk com o texto GND, VAC, etc de pé:
- GND -> BAT - da placa da fonte
- VAC da esquerda -> BAT + da placa da fonte
- VAC da direita -> não está ligado em nada
- BAT + -> fio vermelho do soleníde
- BAT - -> aterramento (na carcaça e na fiação da tomada)
borne CN8
- C -> ligado em nada
- NA -> fio preto do solenóide
dump da EEPROM
codigo de arduino para fazer o dump
Rodamos esse código 4 vezes (uma para cada par de bits) e o resultado foram 4 arquivos de dump lidos na porta serial.
#define dado0 A0 #define dado1 A1 #define Addr0 2 #define Addr1 3 #define Addr2 4 #define Addr3 5 #define Addr4 6 #define Addr5 7 #define Addr6 8 #define Addr7 9 #define Addr8 10 #define Addr9 11 #define Addr10 12 #define Addr11 13 #define Addr12 A2 #define Addr13 A3 #define Addr14 A4 #define Addr15 A5 int endereco; void setup(){ endereco = 0; Serial.begin(9600); pinMode(Addr0, OUTPUT); pinMode(Addr1, OUTPUT); pinMode(Addr2, OUTPUT); pinMode(Addr3, OUTPUT); pinMode(Addr4, OUTPUT); pinMode(Addr5, OUTPUT); pinMode(Addr6, OUTPUT); pinMode(Addr7, OUTPUT); pinMode(Addr8, OUTPUT); pinMode(Addr9, OUTPUT); pinMode(Addr10, OUTPUT); pinMode(Addr11, OUTPUT); pinMode(Addr12, OUTPUT); pinMode(Addr13, OUTPUT); pinMode(Addr14, OUTPUT); pinMode(Addr15, OUTPUT); pinMode(dado0, INPUT); pinMode(dado1, INPUT); } void le_dado(int address){ digitalWrite(Addr0, address & (1 << 0) ? HIGH : LOW); digitalWrite(Addr1, address & (1 << 1) ? HIGH : LOW); digitalWrite(Addr2, address & (1 << 2) ? HIGH : LOW); digitalWrite(Addr3, address & (1 << 3) ? HIGH : LOW); digitalWrite(Addr4, address & (1 << 4) ? HIGH : LOW); digitalWrite(Addr5, address & (1 << 5) ? HIGH : LOW); digitalWrite(Addr6, address & (1 << 6) ? HIGH : LOW); digitalWrite(Addr7, address & (1 << 7) ? HIGH : LOW); digitalWrite(Addr8, address & (1 << 8) ? HIGH : LOW); digitalWrite(Addr9, address & (1 << 9) ? HIGH : LOW); digitalWrite(Addr10, address & (1 << 10) ? HIGH : LOW); digitalWrite(Addr11, address & (1 << 11) ? HIGH : LOW); digitalWrite(Addr12, address & (1 << 12) ? HIGH : LOW); digitalWrite(Addr13, address & (1 << 13) ? HIGH : LOW); digitalWrite(Addr14, address & (1 << 14) ? HIGH : LOW); digitalWrite(Addr15, address & (1 << 15) ? HIGH : LOW); // delay(1); Serial.write(digitalRead(dado1) ? "1" : "0"); Serial.write(digitalRead(dado0) ? "1" : "0"); } void loop(){ if (endereco<65536){ Serial.print((endereco >> 8) & 0xff, HEX); Serial.print(endereco & 0xff, HEX); Serial.write(":"); le_dado(endereco); Serial.write("\n"); endereco++; } }
script python para gerar a imagem
Depois de executar o comando
cut -d: -f2 dump0.txt > bits0.txt cut -d: -f2 dump1.txt > bits1.txt cut -d: -f2 dump2.txt > bits2.txt cut -d: -f2 dump3.txt > bits3.txt
Usamos o script python abaixo para unir os dumps de pares de bits em uma única imagem dump.bin de 64kbytes:
b0 = open("bits0.txt").readlines() b1 = open("bits1.txt").readlines() b2 = open("bits2.txt").readlines() b3 = open("bits3.txt").readlines() dump = open("dump2.bin", "wb") for i in range(0x100, 65536): valor = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip() print valor print int(valor, 2) dump.write(chr(int(valor,2)))
script para desembaralhar endereços
As 4 vias menos significativas do barramento de endereços estão embaralhadas.
Para gerar uma ROM desembaralhada, usamos o seguinte script:
b0 = open("bits0.txt").readlines() b1 = open("bits1.txt").readlines() b2 = open("bits2.txt").readlines() b3 = open("bits3.txt").readlines() dump = open("henry_protv19.bin", "wb") desobfuscado = open("henry_protv19_desobfuscado.bin", "wb") swap_rule = [7, 6, 5, 4, 0, 1, 2, 3] for addr in range(65536): i = addr value_str = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip() value = int(value_str, 2) dump.write(chr(value)) swapped_addr = addr & 0xff00 for i in range(8): swapped_addr |= ((addr>>i) & 1) << swap_rule[i] i = swapped_addr value_str = b3[i].strip() + b2[i].strip() + b1[i].strip() + b0[i].strip() value = int(value_str, 2) desobfuscado.write(chr(value)) dump.close() desobfuscado.close()