sexta-feira, 29 de dezembro de 2006

Captura de listagem

Uma forma fácil de armazenar a listagem de programas é um simples conversor paralelo-serial, composto de um microcontrolador, que aguarda o MSX baixar a linha de strobe, para receber o dado e enviá-lo via porta serial do PC. O microcontrolador faz ainda a sinalização de "busy" (ocupado) para o MSX.




O software para realizar esta implementação é muito simples. Uma possibilidade é utilizar um microcontrolador da família 8051, programado em Basic. A porta P1 recebe os dados da porta de impressora do MSX. A linha P3.2 recebe o sinal de "Strobe", e a linha P3.3 sinaliza a condição de ocupado ("busy"). A interface com o PC pode ser implementada através de um simples transistor.


' Captura porta impressora do MSX e envia
' para porta serial

'SERIAL PORT CONFIGURATION
$BAUD = 19200 'set 19200 baud rate for
$CRYSTAL = 11059000 '22.1184 MHz crystal

dim a as Byte
Reinicia:
p3.3=0 ' desabilita condição ocupado

Aguarda:
if p3.2=1 then goto Aguarda' aguarda sinal strobe

p3.3=1 ' indica ocupado
print p1; ' envia o caractere recebido na serial

' waitms 1
goto Reinicia ' aguarda proximo caractere



Versão em Assembly:


; captura listagem de impressora do MSX
; para a porta serial

$MOD51

org 0
ljmp inicio

inicio: mov a,#255
mov p1,a
setb p3.1
setb p3.2
setb p3.3

mov scon,#40h
mov pcon,#0
mov tmod,#20h
mov th1,#253
mov tl1,#253
setb tr1

reinicia: clr p3.3
aguarda: jb p3.2,aguarda
setb p3.3
mov a,p1
mov sbuf,a
jnb ti,$
clr ti
sjmp reinicia
end

O Diagrama do circuito, baseado num microcontrolador AT89C2051 encontra-se abaixo:



A alimentação do circuito pode ser retirada do conector de Joystick.

quarta-feira, 27 de dezembro de 2006

Testes do protótipo 1 no Expert

Esse Natal rendeu muitos presentes para o MSX....

O protótipo 1 foi testado com sucesso no Expert, e a interface I2C também funcionou. Novas idéias surgiram, mas agora é hora de retomar o fio da meada, ou seja o leitor de cartões SD/MMC.

O próximo passo, é montar o protótipo 2, e começar a trabalhar no software, ou seja, nas rotinas básicas de acesso ao cartão SD/MMC.

segunda-feira, 25 de dezembro de 2006

Interface SPI + I2C simplificada

Da idéia à prática:
A implementação da interface SPI + I2C, até o momento, foi um sucesso, tanto nos testes estáticos, quanto na leitura e escrita utilizando o barramento I2C. O SPI ainda não foi testado por falta de tempo e de um dispositivo que opere neste barramento.

O software de baixo nível ("driver") I2C foi adaptado a partir de uma implementação de David R Brooks que estava disponível sob licença GPL na internet, mas ainda precisa de algumas modificações para trabalhar com memorias flash (o original usa memoria RAM ferromagnetica, que nao tem latência de escrita de página). A leitura, por outro lado, já está plenamente funcional, sendo capaz de ler 16Kbytes de dados em 10 segundos, mesmo sem nenhuma otimização da rotina de leitura.

Segue abaixo um diagrama do circuito, bem como uma ilustração de como ficou a placa.





Os testes foram feitos num Expert 1.1 (soquetado), que recebeu apenas 10 fios.

Eis a foto da montagem "pendurada"



E uma foto da Tela. da TV, num "dump" de memória do "simple" assembler. A E2prom serial utilizada no teste pertencia a um velho celular Ericsson.

domingo, 24 de dezembro de 2006

Interface SPI + I2C simplificada

Com um mínimo de hardware (apenas 3 CIs) é possível implementar uma interface para suportar 2 portas SPI e mais um barramento I2C.

A interface, mapeada em I/O, utiliza um pino livre do próprio decodificador interno do MSX (IC5 no HotBit e IC29 no Expert).

As portas funcionam no modo "bitbang", mas para otimizar a velocidade, foram usados alguns artifícios:
  • Os bits de entrada estão localizados nas posições 0 e 7 da palavra lida. Assim, para ler um bit, bastam duas instruções de rotação de registrador com "carry";
  • Um "latch" endereçável de 8 registradores de 1 bit (LS259) permite escrever um bit com uma rotação e e uma soma com "Carry";
Esta interface permite ligar vários dispositivos interessantes, como:

SPI:
  • Cartões de memória de Playstation;
  • Cartões MMC/SD (em modo SPI);
  • Joysticks de Playstation;
  • Relógios de tempo Real;
  • Displays LCD de celular;
  • Relógios de tempo real (DS1302,...);
  • Memórias seriais (94x46,...);
I2C:
  • Memórias seriais (24Cxx);
  • relógios de tempo real (PCF8583);

quarta-feira, 20 de dezembro de 2006

Direto do Túnel do Tempo...

Reativei hoje, após 12 anos sem uso, meu velho gravador HB2400. Para minha felicidade ele está funcionando em perfeita ordem e para minha surpresa, a maioria das coisas que tenho em fita ainda funciona!!

Eis algumas pérolas, que não constam em nenhum catálogo de programas para MSX:

Seeräuber, ou "pirata" em alemão (ladrão dos mares). Desenvolvido em assembler no Simple. Nunca chegou a ser terminado, pois a faculdade e o namoro consumiram todo o meu tempo, naquele início de década de 90. As cores dos meus programas eram meio esdrúxulas, pois eu tinha uma TV preto e branco, e escolhia as cores simplesmente pelo contraste.
"RightSoft" era minha marca (nunca) registrada, e o nome foi escolhido por ser o único nome bacana que dava pra escrever com o restinho que me sobrara de uma cartela de "letraset" (decalques transferíveis)


Outra tela do programa. Os comandos eram navegáveis via setas de cursor. A seleção era feita por ENTER, ou ESPAÇO, e o retorno ao menu superior era através de "escape". A tela era baseada em scrren1, com caracteres redefinidos, tanto para o logotipo quanto para as letras em fundo invertido. O programa era feito para fita cassete, pois eu nao possuía "disk drive".

Este outro programa era da autoria do irmão de um amigo, com quem eu trocava um monte de programas em fita cassete. Também foi com esses amigos que eu consegui meu "simple" modificado, que tem função "Fsave/Fload", capaz de carregar/ler blocos a 2000bauds.



Outra tela do Pirata em ação, carregando um programa:



Aqui, mais um programa meu, de identificação do cabeçalho dos programas em fita. Ele identificou outro programa, que tinha apenas 30 bytes, chamado LETUDO!!



E para finalizar (por hoje) o último programa que eu havia feito para o MSX, capaz de decodificar código morse a velocidades variáveis, portado de um "paper" para o processador 8080. Havia também um "hardware" externo, que filtrava o sinal captado por um rádio e acionava a entrada de joystick, que era entendida pelo programa.



Quero ver se encontro agora os programas COPY3, cujo menu era inspirado no "PCTOOLS", e o COPY4 (na realdiade, 4.1 ), em Screen2, com janelas semelhantes ao TurboPascal, e navegação por setas de cursor, entre outros avanços introduzidos pela biblioteca de janelas que eu desenvolvi há muito tempo atrás. Esta biblioteca utilizava uma "recursividade lateral", pois recebia um "string" de tamanho variável, que poderia ter como parâmetros ponteiros para outras "strings", que quando selecionadas chamavam a mesma rotina recursivamente. Era legal!!

terça-feira, 19 de dezembro de 2006

Em time que está ganhando não se mexe

Como diz o ditado, em time que está ganhando não se mexe. Por isso, com a simplificação do circuito do sincronizador, a porta NAND que sobrou voltou ao gerador de "clock" automático, que retornou à sua configuração original, já bem testada no protótipo 1. Sobraram duas portas do LS125, que tanto podem ser utilizadas como entradas, ou como portas de saída no circuito da interface I2C, eliminando os diodos D2 e D3.

Na figura abaixo está o diagrama atual do Protótipo2.


A simplificação também permitiu diminuir 1 "jumper". Não é muito, face aos 23 "jumpers" restantes, mas a simples possibilidade de se fazer a placa de face simples já compensa o trabalho.

Simplificação no Sincronizador

Acabei de testar uma simplificação no sincronizador do protótipo 2, que vai permitir economizar uma porta lógica NAND. A porta "livre" deverá ser usada no circuito do gerador de clock automático, no lugar do inversor a transístor, ou na lógica de inibição do sinal de "clock", caso o arranjo com o buffer não funcione a contento.

diagrama do sincronizador já modificado.

segunda-feira, 18 de dezembro de 2006

Protótipo 2 a caminho

O protótipo 2, já está a caminho, e inclui mudanças resultantes dos testes efetuados com o protótipo1. O suporte a I2C já está incorporado, sem crescer a quantidade necessária de "chips". Mas como nem tudo é perfeito, ainda ficou faltando o LED :) .

Eis o circuito (clique na figura para amplicar):


e um "preview" da placa, roteada em face simples.

domingo, 17 de dezembro de 2006

Mais um desafio

Mais um desafio para o projeto do leitor de MMC. Só que desta vez é mais fácil de resolver.

Nos microcontroladores com unidade SPI, normalmente há um registro de dados, que é escrito antes de se invocar uma transmissão, e depois que a transmissão acontece, este registro é lido de volta, pois contém o byte recebido.

No circuito atual do leitor de MMC, a leitura acontece antes da trasmissão/recepção, e para saber o byte recebido, é necessário fazer outra leitura. Só que essa leitura gera automaticamente outra escrita, ou seja, oito ciclos de clock. Assim, é necessário algum mecanismo para inibir esta escrita automática quando se quer apenas ler o último byte recebido, como por exemplo após uma instrução INIR (leitura de bloco).

sábado, 16 de dezembro de 2006

Agora sem "buffer"

Realizei o mesmo test do post anterior, mas agora sem o "buffer". O circuito funciona corretamente com um 74HC595 acionando a via de dados do MSX.

sexta-feira, 15 de dezembro de 2006

Agora sim! Resultados positivos!

Já que o uso do "buffer" não matou o problema do "glitch", resolvi partir para outra solução, baseado na observação do funcionamento do gerador de "clock" automático, que era indiferente ao "glitch", por ser controlado por um flip-flop (metade do contador LS393).

Resolvi então usar um dos flip-flops da placa de protótipo original para amostrar o sinal de saída do decodificador nas bordas de subida do sinal de "clock" do z80.



Resolvi utilizar a borda de subida, para não precisar de utilizar um inversor antes do sinal de "clock". Se não funcionasse, eu experimentaria na borda de descida.

Desta vez, o circuito funcionou sem problemas.

Fiz um teste utilizando o "loop" entre a entrada e a saída, com o seguinte programa em assembler:

LD HL,0A000H
LD B,0 ; 256 bytes)
LD C,12 ; porta
INIR

Desta forma pude comprovar o perfeito funcionamento do circuito, que retornou os seguintes bytes:

A000: XX 00 FF FE FD FC FB FA
A008: F9 F8 F7 F6 F5 F4 F3 F2
A010: F1 F0 .....

O primeiro byte, XX, era o valor que foi lido por último. O segundo byte é o valor do registrador B no inicio da iteração, que vai sendo decrementado até atingir 0.

Note que a instrução INIR foi utilizada, ou seja, o circuito leu os dados na velocidade máxima que o Z80 suporta para endereçamento de I/O.

A figura abaixo contém o detalhe que foi modificado. A a porta IC7A nem precisa ser utilizada, pois o flip-flop possui uma saída /Q.




O circuito como está hoje, pode ser visto abaixo:



Agora sim, vai ser possível iniciar os testes com o conversor de tensão e com o buffer de saída, operando em 3Volts.

Mais dificuldades.

Fiz mais alguns testes. O "glitch" apareceu de novo, mesmo com o "buffer"!!

Consegui reproduzir a situação em que eu lia 255 sem dar glitch, que era um loop infinito, em Basic:

10 print inp(12)
20 goto 10

Se eu usasse essa instrução, e forçasse a entrada de dados a nível 1, conseguia ler o valor 255 sem o menor problema.

Olhando o codigo desta função (via um disassembly do basic), deu pra notar que o que ela faz é avaliar o operando que foi passado, e retornar o valor do operando no par HL. Em seguida o registrador B é carregado com H e o registrador C é carregado com L. Detalhe importante, é que o registrador B sempre vai conter 0, pois o valor da porta está entre 0 e 255

Em seguida o MSX executa a instrução

IN A,(C)

e devolve ao Basic o valor lido.

O que acontece nesse caso é que as linhas A8-A15 vão sempre conter 0 (valor de B), quando é utilizada a instrução INP do basic.

Uma segunda experiência mostrou que utilizando a instrução acima, e variando o valor de B, é possível fazer o "glitch" aparecer.

A conclusão estava na, mas eu não tinha percebido: O aparecimento do "glitch" depende do valor que aparece nas linhas A8-A15!!! Talvez por algum gato do Z80, talvez por algum gato do meu HotBit...

Mas o problema é que isso compromete todo o projeto, pois pretende-se fazer uso da instrução INIR, que usa o registrador B como contador (decremental), e internamente a instrução coloca nas linhas A8..A15 o valor atual de B

Por enquanto o problema está sem solução.

quinta-feira, 14 de dezembro de 2006

"Buffer" para o 74HC595

A placa adaptadora com o "buffer" para o 74HC595 foi concluída. Eis a disposição dos componentes. O "layour" desta placa adaptadora encontra-se neste link em formato EPS. Detalhe é que as trilhas ficam do lado de cima da placa. Os pinos marcados em azul correspondem à pinagem original do 74HC595 na placa de protótipo.



E uma foto da placa adaptadora montada sobre a placa de protótipo. Na foto não aparece, mas debaixo da placa adaptadora foi necessário colocar um soquete de 16 pinos funcionando como espaçador.


Leitor de SD/MMC: Avanços

Continuando o post anterior, para contornar o problema do "glitch", havia duas opções imediatas:

1) Utilizar um 74HCT595, compatível com a família LS
2) Utilizar um 74HCT4094


A primeira opção não foi testada, pois não foi possível encontrar um 74HCT595, nem um LS. Já o HC é encontrado com facilidade.

A segunda opção também não funcionou, ou melhor, funcionou mas apresentou o mesmo problema do "glitch" fantasma.

Uma terceira opção foi tentada então: Ligar um buffer 74LS245 (ou 244) entre a saída do registrador de deslocamento e o barramento do MSX. Como Tive dificuldade para encontrar um HCT4094 ( o que ue utilizei de testes era um "sample" da Texas), eu preferi utilizar o "buffer" em conjunto com o HC595.


Felizmente, desta vez, o circuito funcionou!!! A configuração utilizada para teste consiste num "loop" da entrada para a saída, ou seja, o byte lido corresponde ao byte escrito na iteração anterior.



A listagem dos programas de teste encontra-se abaixo. A primeira listagem é em assembly e a segunda em Basic.


A montagem em "aranha"da configuração de teste não é apropriada para um uso mais extensivo da placa de protótipos, e vai exigir, por enquanto, uma plaquinha adaptadora.



Assim que esta placa estiver pronta, os próximos passos para o teste do projeto consistirão em:

1) Teste do conversor de tensão 3V~5V
2) Leitura em "loopback" do lado onde o cartão é conectado

Após estes 2 passos terem sido completados, os primeiros testes com o cartão já poderão ser efetuados.

sexta-feira, 8 de dezembro de 2006

Registradores de deslocamento: Mais testes

Apesar do longo tempo que se passou deste a última postagem sobre o leitor de MMC, as atividades de desenvolvimento não pararam. Este tempo foi gasto na investigação de um funcionamento errático do circuito, mais especificamente do registrador de deslocamento de entrada, o 74*595.

O que acontecia é que quanto este registrador continha valores com muitos bits 1, isso bagunçava de alguma maneira o barramento do MSX, gerando um "glitch" no sinal IORQ. Este "glitch" bagunçava toda a sistemática do gerador de clock automático.

Descobrir este problema não foi tarefa fácil, e no momento ainda não tenho causa certa, mas tudo leva a crer que seja causado por incompatibilidade entre a família lógica "HC", do registrador de deslocamento, e a lógica interna do MSX, baseada em chips LS. Um mau funcionamento era até de certa forma esperado, pela mistura de famílias lógicas, mas nunca imaginei que isso fosse bagunçar o próprio barramento do Z80.

Para chegar onde cheguei, foram necessárias várias e várias horas de testes, checando suposições. A descoberta do "glitch" só foi possível por causa de uma das ferramenteas de auxílio à construção do circuito: Um contador externo. Se eu tivesse um osciloscópio talvez já tivesse detectado o problema e resolvido há mais tempo. Utilizando-se o contador, observa-se que quando o "glitch" aparece, em vez da contagem avançar de 1 em 1, ela avança de 2 em 2.

Em linhas gerais, o processo de eliminação do problema consistiu em checar se o endereçamento era feito corretamente. Foi onde se descobriu aparecimento eventual do "glitch".

Em seguida, descobriu-se uma condição específica que fazia o "glitch" aparecer, que era a leitura de um valor "FF".

Depois isolou-se o sinal que transfere os dados do registrador de deslocamento para o latch interno do 595, onde se constatou que o simples recebimento serial do valor "FF" não causava o surgimento do problema.

Depois constatou-se que o problema estava do "latch" interno do 595 para o buffer de saída.

Depois foi preciso isolar todos os circuitos restantes da linha em que o "glitch" aparecia. Tentou-se islolar o sinal de saída do segundo decodificador via um buffer, mas o "glitch" continuava aparecendo.

Em seguida foi feito um programa em assembler que desabilitava todas as outras interrupções, e fazia uma leitura na porta 12. O "loop" de atraso ("delay") é para poder acompanhar visualmente o acendimento dos LEDs do contador.
ORG 9000H
DI
LOOP: LD HL,5FFFH
IN A,(12)
DELAY:
DEC HL
LD A,L
OR H
JR NZ,DELAY
JR LOOP

Com esse programa rodando, descobriu-se que o "glitch" surgia na própria linha IORQ do Z80!

Para eliminar a possibilidade de que qualquer leitura de um valor FF pudesse proporcionar um "glitch", o programa acima foi adaptado para ler a matriz do teclado do MSX, que retorna o valor "FF" se nenhuma tecla estiver sendo pressionada (li a linha 0 do teclado). Nessa situação, o "glitch" não acontecia, o que era bom sinal.

Em seguida, o 74HC595 foi desconectado e em seu lugar foi conectado um 74LS244, cujas entradas foram conectadas a um resitor de pullup com um jumper para selecionar um valor "0" ou "FF". Com este circuito, foi possível ler (tanto o valor "0" quanto) o valor "FF" sem que o "glitch" surgisse.

Conclusão: O 74HC595 é inadequado ao circuito. Em seu lugar tenho como opções imediatas:

1) Utilizar um 74HCT595, compatível com a família LS
2) Utilizar um 74HCT4094


74LS244 em teste, no lugar do HC595

sexta-feira, 1 de dezembro de 2006

NovoCaps: Uma Caps Lock diferente para o Expert

Existem várias soluções para colocar um Led de Caps Lock no Expert, a maioria delas envolve furar o micro; outras, mais inteligentes (p.ex [1]), utilizam LEDs bicolores no lugar do LED de "power".

O Expert não tem um LED de Caps pois o conector de teclado tem apenas 13 pinos, dois quais 12 são usados pela matriz do teclado, e o 13° é utilizado pela alimentação. A malha do cabo foi utilizada para levar o sinal de terra (GND). Um LED de CAPS exigiria um pino a mais, mas este pino não estava disponível. A solução de compromisso encontrada pela gradiente foi "matar" o LED de CAPS.

Mas isso aconteceu no passado. Voltando aos dias de hoje, haveria uma maneira de colocar um LED de CAPS no teclado do Expert, sem ser necessário alterar o "hardware" existente?

Bem, para contornar uma solução de compromisso, normalmente é necessário resolver uma contradição. Eu estava então diante de um problema inventivo, e isso me lembrou o TRIZ.

Uma das ferramentas desta metodologia de resolução de problemas consiste em levantar os recursos disponíveis. Dos 13 fios do conector, apenas 2 não "trafegava informação", que eram exatamente os fios da alimentação. A partir daí, já me surgiu uma solução, mas mesmo assim, dei uma consultada breve nos 40 princípios, e deu pra encontrar mais algumas.

A solução consiste em se utilizar o fio de Vcc (pino 13) para transportar o estado do LED de CAPS, junto com a alimentação. Note que é necessário transportar "alimentação" para o teclado, e não "transportar "+5Volts". Basta então duplicar o regulador de tensão para obter já dentro do teclado, os 5Volts que eu preciso, e utilizar a tensão no fio para identificar o estado do LED.

O circuito do multiplexador e do multiplexador encontram-se abaixo. O Multiplexador é colocado entre o +12Vcc e o pino 13 do conector de teclado (que deve ser desconectado do Vcc), enquanto o demultiplexador é colocado entre o fio que vem do pino 13 e a alimentação do 7448. Um Led bicolor é colocado no lugar do LED original do Expert.


Multipexador



Demultipexador

Quando o caps não está acionado, o transistor do multiplexador fica cortado, e o pino 13 recebe 12 volts. A tensão no pino 3 do 741 é então de 3 volts, enquanto no pino 2 é de apenas 2,5 , fazendo o LED vermelho acender junto com o verde, resultando numa cor amarelo-alaranjada do LED.

Quando o CAPS é acionado, o transistor conduz, fazendo com que a tensão na linha Vcc caia para aproximadamente 7,5Volts. Nesse momento a tensão no pino 3 passa a ser de apenas 2,4Volts, apagando assim a parte vermelha do LED, que fica então na cor verde, indicando que o CAPS está ativo (tal qual o led verde de CAPS do HotBit).

Link para o circuito, diagramas, layout da placa, etc...

terça-feira, 28 de novembro de 2006

Touchpads: Primeiras investigações

Controladores Touchpad para MSX

Muito pouco se sabe sobre o funcionamento dos "touchpads" do MSX, desde a pinagem deste dispositivo ao seu protocolo de comunicação. As observações abaixo são o resultado das análises da rotina GTPAD da BIOS.

O Touchpad do MSX é composto de 2 conversores A/D, que transferem seus bits ser

Pinagem do Touchpad:


Pino Direção Nome Função
1 S SENSE Indica quando a caneta do Touchpad toca sua superfície (0=Tocando)
2 S EOC Indica fim da conversão (1=Conversão terminada)
3 S DATA Dados enviados serialmente (MSB primeiro) pelo conversor A/D
4 S BTN Botão da caneta do touchpad (0=pressionado)
5 - Vcc Alimentação +5Volts
6 E CS Inicia uma conversão A/D (0=iniciar conversão)
7 E X/Y Seleciona conversor A/D (X=0, Y=1)
8 E SCK Clock para transferência de dados
9 - GND Negativo da alimentação.


O Pino CS (Trigger A) é levado a "0" (zero) para iniciar uma conversão. O conversor A/D é selecionado pelo pino X/Y (Trigger B; 0=X, 1=Y). O MSX então aguarda até que o conversor A/D termine de realizar sua conversão, liberando a linha EOC (DOWN), fazendo com que esta seja igual a "1" (um). Em seguida o MSX libera a linha CS, que novamente assume o valor "1" (um).

A partir deste momento começa a transferência do valor do conversor A/D. O pino SCK (Pulse) é levado a "1" (um) e em seguida o sinal presente na linha DATA (LEFT) é lido e colocado no registrador L. O pino SCK (Pulse) é então levado de volta a "0" (zero). Desta forma, 8 bis são lidos e armazenados em L. O pino SENSE (UP) é amostrado a cada bit lido, porém somente o estado do pino durante o bit menos significativo é levado em consideração. Caso seja "0" (zero), o MSX assume que a caneta manteve-se em contato com o "touchpad" durante o tempo da conversão, e que portanto, a coordenada lida é válida. Caso contrário, a rotina termina retornando o valor do pino SENSE.

As coordenadas X/Y são amostradas duas vezes seguidas. Caso a diferença de valor de cada eixo seja maior do que 5 (cinco) nestas amostragens consecutivas, ou seja, caso duas leituras consecutivas resultem em posições muito diferentes, todo o processo se repete. Caso contrário, as coordenadas X e Y são armazenasdas em PADX (FC9D) e PADY (FC9C), e a rotina termina, retornando o valor do pino SENSE.



quarta-feira, 22 de novembro de 2006

Paddle Revisitado

Há um bom tempo atrás eu construí um paddle baseado nas informações do "Livro Vermelho do MSX", que chegou a ser publicado em 1994, na Revista Antenna.

Eu reformulei o layout da placa do projeto, para um "design" mais atual.

Diagrama do circuito:


"Lay-out" da placa na resolução de 300dpi:


Disposição dos componentes, e identificação dos pinos:


Foto da placa, depois de montada e corroída (e com o "lay-out" adaptado com o logotipo do HotBit).



Foto da placa montada, vista por baixo. Detalhe: O "push button" é montado no lado do cobre.


Foto da placa montada, vista por cima.


No conector DB-9 fêmea que vai ao MSX, a ligação é a seguinte:

Pino 1 do DB9 ao sinal UP da placa
Pino 5 do DB9 ao sinal VCC da placa
Pino 6 do DB9 ao sinal TRGA da placa
Pino 8 do DB9 ao sinal PULSO da placa
Pino 9 do DB9 ao sinal GND da placa

O push-button deve ser montado do lado da solda, ou seja por baixo da placa, e o eixo do potenciômetro atravessa a placa.

O potenciômetro deve ser do tipo linear, e o capacitor 'Cx' é apenas uma reserva de espaço, caso seja desejado um ajuste fino da faixa de atuação do potenciômetro.

Eis ainda um link para os arquivos em formato Eagle.

segunda-feira, 20 de novembro de 2006

Leitor de MMC/SD rápido: Mais alguns Testes dos Registradores de Deslocamento, correções e conclusões

Após o teste do registrador de saída, iniciaram-se os testes com o registrador de entrada. Para isso, os pinos 3 e 5 do 74HC125 foram conectados e os seguintes programas foram executados:

DADO: EQU 0
SPI: EQU 12

ORG 9000H
LD A,0
IN A,(14) ; ativa CS
LD A,0
IN A,(15) ; ativa 74125
LD A,0
IN A,(12)
NOP
NOP
IN A,(12)
LD (9050H),A
RET

E, em Basic

5 DEFUSR0=&H9000
10 INPUT “DADO”;D
20 POKE &H9009,D
30 A=USR0(0)
40 PRINT PEEK &H9050
50 GOTO 10

O programa em Basic simplesmente passa um parâmetro para o programa em assembler, que por sua vez, transmite à saída o dado desejado no primeiro IN, e em seguida lê o valor ecoado para o registrador de entrado, no segundo IN.

Foi notada uma instabilidade na leitura dos valores, ou seja, nem sempre o valor lido correspondia ao valor escrito.

O programa em Basic foi alterado para um loop que variava incrementalmente o valor transmidito de 0 a 255, e comparava o valor transmitido com o valor recebido, mostrando quais bits continham erros.

Esse programa produziu erros que sempre se repetiam, revelando uma natureza deterministica, descartando assim maus contatos no protótipo.

O 74HC125 foi retirado, e no lugar foi colocado uma ponte entre os pinos 2 e 6 em seu soquete, mas os erros continuavam os mesmos.

Uma nova análise revelou a origem do problema. No circuito, o mesmo sinal de clock foi utilizado em ambos os registradores de deslocamento (o de entrada e o de saída) e por isso ambos fazem “shift” dos dados na borda de subida (pois em ambos a borda de subida é a ativa).

Mas acontece que do ponto de vista do LS165, um “shift” é realmente um “shift”, mas do pondo de vista do LS595, o “shift” é um o “LATCH,” pois no momento do shift é
que o bit atual é capturado para dentro de um flip-flop. Desta forma, o registrador de entrada (LS595) estava tentando capturar um sinal (saída do LS165) enqanto este ainda estava se acomodando, gerando os erros mencionados.

É por isso que quando o “shift” era feito manualmente, os resultados eram aleatórios, pois o erro dependia da carga eletrica reminiscente nas portas no momento em que era dado o “ENTER”.

O bit 7 nunca ficava errado, porque quando o IORQ chega pela instrução 'IN A,(SPI)', o LS165 recebe o sinal da via de dados e já coloca o bit mais significativo na saída QH. Assim, quando os ciclos de clock automático começavam, o sinal já era estável, e nunca era lido errado.

A correção para o problema foi inverter o sinal de clock do LS165, de forma que o “Shift” aconteça durante a borda de descida, respeitando assim as especificações do cartão SD/MMC, em modo SPI.


De forma simplificada esta é a sequência de eventos:

Na borda de subida:
a) O LS595 captura o sinal que o cartão disponibilizou na linha DOUT
b)O Cartão captura o sinal que o LS165 disponibilizou na linha DIN

Na borda de descida: (que se torna de subida para o LS165 interno)
a)O LS165 faz shift no byte sendo transmitido ao cartão e sinal e disponibiliza o próximo bit na linha DIN
b)O cartão faz shift no byte que está sendo transmidito ao LS595 e o disponibiliza na linha DOUT

A forma de onda abaixo ilustra a operação do circuito.



Após a inicialização do cartão, quando o pino CS é levado a zero, o cartão inicializa sua saída, disponibilizando o bit mais significativo do primeiro byte a ser transmitido na linha de dados. Em seguida :

  1. O programa decodifica e executa a instrução IN
  2. O Z80 coloca nas linhas D8..D15 o dado a ser transmitido
  3. O Z80 baixa a linha IORQ
  4. O dado a ser transmitido é transferido para os flip-flops internos do LS165
  5. O bit mais significativo do byte a ser transmitido fica disponivel (valido) na saida QH do LS165
  6. O Z80 sobe a linha IORQ
  7. O gerador de clock automático é habilitado e está pronto para começar a contar a partir da próxima borda de subida
  8. O Z80 começa a executar a proxima instrução
  9. A linha SCK sobe, pois
  10. o LS595 captura para o flip flop interno, o bit mais significativo vindo do cartao, pela linha DIN
  11. o cartão captura o bit mais significativo enviado pelo pino QH do LS165
  12. A linha SCK desce
  13. A linha INV_SCK sobe simultaneamente.
  14. O LS165 coloca em sua saida QH o bit 6 do dado a ser transmitido ao cartao
  15. O cartão coloca em sua linha DOUT o bit 6 do dado a ser transmitido ao micro
  16. A linha SCK sobe...
E o processo se repete até os 8 bits terem sido transferidos.

Ao final da transferência deste byte, a linha DOUT do cartão já contém o bit mais significativo do próximo byte a ser transferido. Se houverem mais dados a serem trocados, o processo continua.

quarta-feira, 1 de novembro de 2006

Leitor de MMC/SD rápido: Teste do Registrador de Escrita

Com o auxílio de um circuito de testes baseado no 74HC595, o registrador de escrita automática foi testado com sucesso!




(este circuito foi feito inicialmente para outra finalidade, e foi utilizado por já estar pronto)

O programa de teste escrito em BASIC configura o buffer de saída, transfere o dado e pulsa a linha CS, para que o 74HC595 da placa externa possa exibir os dados que recebeu serialmente.




Eis a foto do protótipo durante o teste de transferência.


Agora faltam as seguintes etapas pra terminar o desenvolvimento do hardware:
  • Testar o registrador de entrada (com o auxilio de um HC165 externo)
  • Testar a conversão 5V-3V (74HC125)
  • Reconfigurar o circuito para a versao 1 (retirar o 74HC74 e colocar um 74HC259 e um segundo LS125)
  • Testar o dircuito reconfigurado

sábado, 28 de outubro de 2006

Leitor de MMC/SD rápido: Mais testes

A listagem abaixo contém um programa útil para fazer testes:



A imagem foi capturada diretamente do HOTBIT conectado à placa de captura de vídeo.

O pequeno programa em assembler é apenas:


9000: 3E 00 LD A,00H
9002: DB 0C IN A,(0CH)
9004: 32 10 90 LD (9010H),A
9007: C0 RET

Assim, para mudar o dado a ser escrito, basta dar um POKE no endereço &H9001. De igual forma, para mudar o endereço de acesso basta dar um POKE no endereço &H9003.

O gerador de CLOCK automático foi testado a 3,58MHz (MSX 1) e funcionou.

O próximo passo será testar os registradores de deslocamento. Em seguida o protótipo zero vai ser reconfigurado para a versão protótipo "final" e entao novos testes serão feitos, pra validar a a mudança


Após a validação do Hardware, começará a parte de software.

sexta-feira, 27 de outubro de 2006

Leitor de MMC/SD rápido: Fotos do Protótipo Zero

A foto abaixo é do protótipo "zero". Este circuito já sofreu uma atualização. O circuito publicado já é a versão atualizada, com um 74HC259 para substituir o 74HC74.



Como havia um erro na pinagem do conector utilizado inicialmente, não foi possível utilizar um Flat cable. Por isso a fiação em aranha, utilizando como conector uma velha placa de PC que foi serrada

quinta-feira, 26 de outubro de 2006

Leitor de MMC/SD rápido: Primeiros Testes

Após montar o circuito, os primeiros testes são a verificação do correto funcionamento do decodificador de I/O, ou seja, teremos que identificar o correto acionamento do circuito nos pontos de teste TP1, TP2 e TP3.




Para isso, lançaremos mão de um pequeno programa BASIC, além de um contador como o da figura abaixo:


A função deste circuito é identificar se as saídas dos decodificadores estão recebendo pulsos quando os endereços corretos estão sendo acessados.

O Programa Basic é o seguinte:

10 a=inp(&h0C)
20 for a=1 to 100:next
30 goto 10

Teste do ponto TP1:

Se analisarmos o circuito, veremos que o decodificador de endereços IC4 recebe em suas entradas os seguintes sinais:


Pino: [ G1 ][/G2A ][/G2B ][ C ][ B ][ A ]
Sinal:[ A2 ][/IORQ][ /RD ][ A3 ][ A4 ][ A5 ]


Desse modo, a saída Y4 deste CI, conectada a TP1, vai a nível baixo somente quando:


Sinal:[ A2 ][/IORQ][ /RD ][ A3 ][ A4 ][ A5 ]
Nivel:[ 1 ][ 0 ][ 0 ][ 1 ][ 0 ][ 0 ]


Ou seja, quando se acessa um endereços I/O do Z80 igual a:


Sinal:[A7][A6][A5][A4][A3][A2][A1][A0]
Nivel:[x ][x ][0 ][0 ][1 ][1 ][x ][x ]


O pino TP1 deve ser acionado, o que corresponde a acessar os endereços nas seguintes faixas:

0Ch~0Fh, 4Ch~4Fh, 8Ch~8Fh, CCh~CFh

Então para testar se o circuito está funcionando, mude o valor da linha 10 para qualquer um destes valores e execute o programa. Deverá ser possivel ver os LEDs piscando, e a contagem aumentando. O FOR-NEXT na linha 20 é necessário, pois se a contagem ocorrer rapido demais os olhos humanos percebem como se todos estivessem acesos, em vez de piscar.


Teste do ponto TP2 e TP3:

Se olharmos agora para IC8, vemos que este recebe em suas entradas os seguintes sinais:


Pino: [ G1 ][/G2A ][/G2B ][ C ][ B ][ A ]
Sinal:[ /M1 ][ Y4 ][ A6 ][ A7 ][ A1 ][ A0 ]


Desse modo, a saída Y0 deste CI, conectada a TP2, vai a nível baixo somente quando:


Sinal:[ /M1 ][ Y4 ][ A6 ][ A7 ][ A1 ][ A0 ]
Nivel:[ 1 ][ 0 ][ 0 ][ 0 ][ 0 ][ 0 ]


E a saída Y1 deste CI , conectada a TP3, vai a nível baixo somente quando:


Sinal:[ /M1 ][ Y4 ][ A6 ][ A7 ][ A1 ][ A0 ]
Nivel:[ 1 ][ 0 ][ 0 ][ 0 ][ 0 ][ 1 ]


Compondo estes endereços com os endereços anteriores, vemos que os pontos TP2 e TP3 serão acionaos nos seguintes endereços:


TP2
Sinal:[A7][A6][A5][A4][A3][A2][A1][A0]
Nivel:[0 ][0 ][0 ][0 ][1 ][1 ][0 ][0 ]

TP3
Sinal:[A7][A6][A5][A4][A3][A2][A1][A0]
Nivel:[0 ][0 ][0 ][0 ][1 ][1 ][0 ][1 ]


Ou seja, um acesso de leitura ao endereço de I/O &H0C (12 em decimal) deve levar a zero o pino TP2 e uma leitura no endereço de I/O &H0D (12 em decimal) deve levar a zero o pino TP3

Para testar o ponto TP2, rode novamente o programa acima. Verifique que enquanto o endereçco 12 é acessado, apenas a saída Y0 de IC8, e mais nenhuma outra deve mudar de estado.

Para testar o ponto TP3, mude o valor da linha 10 para &H0D (13 em decimal) e igualmente verifique que enquanto o endereçco 13 é acessado, apenas a saída Y1 de IC8, e mais nenhuma outra deve mudar de estado.

Neste Link há um pequeno filme com a imagem de como se comportam os LEDs durante a contagem.

segunda-feira, 16 de outubro de 2006

Leitor de MMC/SD rápido: Juntando as partes

Com todas as considerações feitas anteriormente, já é possível juntar as partes e obter um circuito para protótipo (já com o suporte para o "chip" de relógio de tempo real). Os chips necessários são apenas 9:

2 x 74HC138 - Decodificadores de 3 x 8
1 x 74HC165 - Registrador de deslocamento (paralelo->serial)
1 x 74HC595 - Registrador de deslocamento (serial->paralelo)
1 x 74HC393 - Duplo contador 8 bits
1 x 74HC259 - "Latch" Endereçável de 8 Bits
2 x 74HC125 - "Buffer" Quádruplo, "tri-state"
1 x 74HC00 - 4 Portas NAND

O circuito encontra-se abaixo. Note que já se trata da segunda revisão do circuito, pois a primeira carecia de alguns recursos


Clique na imagem para ampliar

O relógio de tempo real da figura é um PCF8583, escolhido por ser de baixo custo, mas pode ser qualquer outro que se comunique via barramento I2C, como o DS1307.

Este diagrama é na realidade a segunda revisão do circuito. A principal diferença da primeira versão é o "latch" endereçável (era usado um 74HC74) e o circuito que força a linha de saída de dados em nível alto.

segunda-feira, 9 de outubro de 2006

Leitor de MMC/SD rápido: Novo decodificador de I/O

O novo decodificador de I/O é essencialmente igual ao anterior. A única diferença é que em vez de termos 4 endereços de I/O, agora há apenas 2:

0Ch: SPI_DATA
0Dh: SPI_CONTROL

Ambos os registros são vistos pelo MSX como registros de apenas para leitura, porém a escrita é feita utilizando-se as linhas [A8..A15] presentes no barramento de endereços durante as intruções de entrada ("IN")

O endereço SPI_DATA permite escrever e ler nos registradores de deslocamento 74'165 e 74'595. Já o SPI_CONTROL permite escrever no registrador endereçável 74'259 e ler do seletor de dados ("mux" 8 pra 1 ) 74'251.

As funções ALT_CLOCK, CHIP_SEL e SPI_POWER se tornam então registros individualmente selecionáveis pelo valos das linhas [A8..A10] e o valor, "0" ou "'1", é dado pela linha [A15], juntamente com os sinais SCL e SDAout. para a interface I2C (provisão para o relógio de tempo real) e mais 3 linhas reserva: RSV0, RSV1, RSV2.

A leitura de dados em SPI_CONTROL é uma palavra onde apenas o BIT 0 interessa. As linhas [A8..A10] endereçam um dos 8 bits disponíveis. Temos assim os bits SDAin, RES0, RES1, RES2, RES3, RES4, RES5, RES6.

Leitor de MMC/SD rápido: Registradores de Deslocamento

Mais um detalhe importante a respeito do protocolo de comunicação com os cartões MMC/SD, é que quando um dos dispositivos (Host ou Cartão) não está enviando uma mensagem ele fica "calados", ou seja mantém a linha de dados em nível "1".

Mas da maneira como o circuito foi implementado, durante a operação INIR, o valor das linhas [A8..A15] assume o valor do registrador B no momento da iteração. Sendo assim, é necessário forçar o valor da linha de saída de dados em nível alto, durante a operação INIR. Para tal, uma porta "OU" é colocada "em série" com a linha de saída de dados. A outra entrada desta porta "OU" vai para um registrador, controlando assim se a saída de dados vai receber os bits vindos do registrador de deslocamento 74'165 ou se vai ficar em nível lógico "1".

segunda-feira, 2 de outubro de 2006

Leitor de MMC/SD rápido: Registradores de Deslocamento

Para suportar a transferência simultânea de dados numa única instrução, foi utilizado um recurso do Z80 normalmente ignorado na maioria dos projetos: O comportamento das linhas [A8..A15] durante o endereçamento de I/O.

O Manual do Z80 (ref [1]) informa que durante as operações de I/O, que utilizam normalmente as linhas [A0..A7], as linhas [A8..A15] também seguem um comportamento bem definido. Por exemplo, durante a instrução:

IN A,(C)

As linhas [A0..A7] assumem o valor definido pelo registrador C, enquanto as linhas [A8..A15] assumem o valor definido pelo registrador B.

No circuito do leitor de cartões, as linhas [A8..A15] foram utilizadas para carregar o "latch" do registrador de deslocamento, ou seja, o byte a ser enviado serialmente.

É por isso que o circuito não utiliza a linha /WR (escrita), vide diagrama de blocos abaixo.




O circuito gerador de Clock faz o resto do trabalho, enviando serialmente o byte a ser transmitido, ao mesmo tempo em que recebe o byte a ser lido na próxima instrução. O único cuidado a ser tomado é que não se efetue duas instruções "IN" seguidas, pois são necessários 8 ciclos de clock para a transferência acontecer; mas como a maioria das aplicações consiste em:
  1. ler um valor;
  2. escrever na memória;
  3. incrementar um contador;
  4. decrementar outro contador;
  5. checar se o valor chegou a zero, antes de repetir a instrução "IN";
todas estas operações dão tempo suficiente para os dados sererm transmitidos. Isso também é válido para a instrução INIR, pois apesar de ser uma única instrução, sua execução implica na realização da sequência de eventos acima, gastando, segundo o Manual do Z80 (ref [1]), 21 ciclos de clock, equivalentes a uma velocidade máxima de leitura de bloco de 170,3Kbytes/segundo de taxa máxima de leitora de bloco para um Z80 rodando a 3,578MHz.

Uma observação importante é que a implementação do circuito desta forma otimizou a operação de leitura ao mínimo possível (21 ciclos), mas obrigou a operação de escrita a utilizar instruções convencionais como o bloco abaixo:

LOOP:
LD A,(HL) [7]
IN A,(BASE) [11]
INC HL [6]
DJNZ LOOP [13]


Que totaliza 37 instruções, ou o equivalente a 96,7Kbytes/segundo de taxa máxima de escrita de bloco para um Z80 rodando a 3,578MHz.

Leitor de MMC/SD rápido: Relógio de Tempo Real e E/S Auxiliar

O Relógio de tempo real funciona de modo independente do resto do circuito, consistindo em uma interface I2C, o que possibilita o uso de um chip de relógio de baixo custo e facil de se encontrar no mercado. Este circuito é opcional, pois as interfaces de disco normalmente já possuem um relógio de tempo real, normalmente operando dentro do padrão MSX.

Para suportar o relógio de tempo real, será necessário implementar uma interface de Entrada/Saída auxiliar, composta de um registrador endereçável e de um seletor programável de 8 para 1. O regisgtrador endereçável foi escolhido em vez de um latch pela facilidade de se alterar um bit sem a necessidade de se realizar operações OR/AND num registro de memória que guardaria o valor do latch. O seletor programável opera de maneira semelhante, colocando na saída apenas o bit selecionado dentre os 8 possíveis.

Por outro lado, a inclusão desta etapa de entrada/saída auxiliar, permite simplificar um pouco o circuito, e reduzir o uso de portas de I/O para apenas 2.

O diagrama de blocos do RTC se encontra na figura abaixo: