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: