logo

Objectif
A première vue
Le schéma
L'alimentation
Le microcontrôleur
Le synthétiseur
Les ROMs
Code et memory map
Cartouche AVR
Cartouche CPLD
Convertir les sons
Créer le ROM
Circuits imprimés
Cartouche AVR + EEPROM série

Je savais désormais que ne connaître que la memory map des cartouches ne suffirait pas. Il faut aussi simuler le fonctionnement de ces ROMs si spéciaux.

Sachant que les fréquences de lecture n'allaient pas dépasser 160kHz, j'ai décidé de réaliser mon premier essai avec un ATTiny2313 et sa flash interne. J'ai utilisé un câble FTDI USB vers RS232 TTL pour debugger et d'abord essayer de récupérer les adressages. Pour faire la pire adaptation en tension possible, j'ai utilise des résistances en séries sur les broches de l'AVR et l'ai alimenté en 5V.

N'ayant pas fait attention à l'histoire de l'asynchronisme sur M0, j'ai d'abord câblé ROMCLK sur INT0 afin d'avoir une interruption sur ses fronts descendants. Malheureusement, pour une raison qui m'échappe, le déclenchement de l'interruption se faisait après un délai variable et je ne parvenais pas à récupérer une adresse valide à tous les coups.

J'ai ensuite choisi de simplement ignorer ROMCLK et d'utiliser les Pin Change Interrupts pour avoir une interruption sur les fronts montants de M0 et M1. J'arrivais à obtenir une lecture valide des adresses à ce niveau la (0x800C quand j'appuyais sur la touche Module select, le microcontrôleur essayait de lire les magic bytes).

Après ce résultat encourageant, je devais réussir à répondre aux magic bytes (0xAAAA) sur ADD8. Après avoir ajouté le code pour ignorer le dummy read, je me suis simplement servi du registre DDRB pour configurer ADD8 comme une sortie dès le front montant de M0 (première erreur). J'ai tout de même réussi de cette manière à faire reconnaître l'AVR par la dictée, mais pas toujours, environ une fois sur 5.

J'ai d'abord cru que c'était un problème de tension, car l'AVR ne pouvait répondre que du 0V ou 5V (en réalité du 0.3V et du 6V, car ADD8 est tiré haut par la dictée). L'état bas à 0.3V au lieu de -3.5V pouvait alors poser problème. J'ai alors dédoublé la ligne ADD8, d'un coté servant comme entrée sur l'AVR, et de l'autre sur un transistor NPN piloté par l'AVR pour en faire une sortie collecteur ouvert.

Malheureusement, même avec un niveau bas à -3V, la dictée ne reconnaissait pas toujours l'AVR.

En regardant de plus près l'oscilloscope, je me suis aperçu que la réponse se faisait après des délais variables, tout comme la réaction à l'INT0. Pour rendre l'AVR plus réactif, j'ai réorganisé mon code pour faire une sorte de "prefetch" du prochain bit à sortir, pour ainsi gagner quelques microsecondes, avec succès ! Ainsi, le dummy read a finalement pris tout son sens, en me permettant de charger le premier bit, et les suivants sont chargés après chaque lecture (au lieu d'avant).

Avec ce même code simulant le ROM, j'ai pu faire charger l'orthographe d'un mot correctement et ainsi confirmer en partie la memory map du ROM.

Voici une copie du download Projet AVRStudio et de la source en C a cette étape.

Jusqu'à présent, j'utilisais la flash interne de l'AVR via la fonction C "pgm_read_byte". Voulant tester la lecture de données vocales nécessitant quelques kilooctets (plus que les 1ko restants sur les 2 du Tiny2313), je suis passé à l'utilisation d'une EEPROM i2c 24AA256, n'ayant que ça sous la main.

Après avoir passé un petit moment à écrire des fonctions de bitbang pour parler à l'EEPROM, j'ai pu à nouveau faire reconnaître l'AVR et le mot avec ses données. L'audio donnait par contre n'importe quoi. Sachant que la lecture du ROM par le microcontrôleur fonctionnait, je savais que c'était uniquement un problème avec la lecture par le synthétiseur.

Je me suis rendu compte que le microcontrôleur lisait toujours par groupes de 4 bits espacés de plusieurs microsecondes. Ceci permettait en fait à mon code d'avoir le temps de lire les octets de l'EEPROM sans problème. Par contre, lorsque le synthétiseur se mettait à parler, il lisait les bits par blocs de différentes tailles, à une vitesse doublée. Forcément, car si on se rappelle des trames LPC, on a 4 bits d'énergie, 1 de répétition, 5 de pitch, ...

Imaginons alors que le synthétiseur veuille lire la première trame non silencieuse :
4 bits, 1 bit, 5 bits... Les 4+1 premiers bits passaient car ils faisaient tous partie du même octet chargé pendant le dummy read. Mais lorsque le prochain bloc de 5 bits était lu, mon code n'avait pas le temps de récupérer le deuxième octet au bit #3 depuis l'EEPROM et fatalement, le synthétiseur perdait les pédales.

Je me suis donc souvenu rapidement que l'i2c ne permettait pas de dépasser les 400kHz, il était donc impossible de récupérer les données à temps, même avec du prefetch plus large. Après avoir déjà passé plusieurs heures sur ce premier essai et n'ayant pas d'EEPROM SPI, je pensais que le projet aller s'arrêter la.

Mais c'était sans compter sur une petite pépite que [Grapsus] m'avait envoyée quelques jours auparavant, et qui traînait là, sous mon nez !...

footer
symbol symbol symbol symbol symbol