# Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/Autres projets pour ATMEL ATMega8

Nous avons l'intention de mettre dans ce chapitre une série de projets permettant de faire évoluer et de mettre en œuvre le coreATMega8. Il a été conçu par Juergen Sauermann.
* L'hébergement de mon site perso se termine le 5 septembre 2023 ! À ce jour je n'ai pas encore décidé comment je vais gérer ce problème dont je ne suis pas à l'origine. Il en résulte que l'ensemble des corrections qui utilisent mon site perso seront indisponibles à partir de cette date pour tout ce chapitre. SergeMoutou (discuter)

## Projet pour l'année universitaire 2011/2012

Étant satisfait avec le coreATMega8, nous avons décidé de poursuivre l’utilisation de ce système monopuce, et de l’utiliser pour réaliser un autre projet. La carte cible sera plus la même, elle sera réalisée autour d'un spartan3 200. Étant donné que les corrections du jeu de Pong ont été complètement publiées dans un autre chapitre, il nous faut changer de sujet. Il s'agit d'un jeu un peu similaire au jeu de Pong, à savoir un Casse-briques.

### Version de l'ATMega8

L'écriture du chapitre Programmer in Situ et déboguer nous a obligé à faire évoluer le cœur embarqué coreATMega8.
La gestion d'interruptions et l'implantation de l'instruction SPM ne sont pas nécessaires pour le projet « casse briques » de cette année, mais le simple fait de vouloir utiliser data2mem (décrit lui aussi dans Programmer in Situ et déboguer) nous oblige à utiliser la dernière version de notre processeur ! Cette version n’est pas disponible chez Opencores pour le moment mais nous la mettons à disposition dans le répertoire /AVRComplet16_S4_S4/25MHzAVR/ de notre ATMega8_pong_VGA.zip. C'est la version la plus à jour, version dans laquelle nous avons vérifié les interruptions RS232 et l'instruction SPM.

### Cahier des charges

Une seule raquette est mobile verticalement. L'autre est présente mais son déplacement est lié à celui de la balle. Donc le rebond sur cette raquette se fait toujours.
Nous présentons ci-dessus l'écran VGA pour le casse-brique dans l'hypothèse où le déplacement de la raquette liée à la balle est fait par le processeur. Si l’on compare au jeu de Pong du chapitre sur l'ATMega8, il faut 8 bits supplémentaire pour gérer ce nouveau jeu.

### Travail à réaliser

Trois phases distinctes sont à réaliser, un projet tuteuré sur environ 12 heures qui se solde par un rapport, la réalisation de la partie matérielle à partir de l'existant (c'est-à-dire le projet de pong précédent), puis le développement de la partie logicielle.

#### Projet tuteuré

Réaliser un schéma fonctionnel complet de la partie matérielle. Nous aimerions un schéma réalisé sous OpenOffice pour pouvoir le publier ici. Calculer le nombre de PORTs nécessaires pour interfacer votre écran VGA et votre processeur. À ce stade, il vous faut choisir si la liaison entre la balle et la raquette se fait à l'aide du matériel où à l'aide du logiciel.
Apprentissage du GNU C pour l'AVR. Pour cela vous partirez du répertoire /AVRComplet16_S4_S4 du fichier ATMega8_pong_VGA.zip qui contient une version améliorée du processeur, capable de gérer les interruptions et surtout capable d'exécuter une instruction qui écrit en programme mémoire. Cela permet de réaliser un bootloader ce qui facilite grandement le développement. Nous nous contenterons d’utiliser « data2mem » pour cette année car nous n'avons pas réussi jusqu'à présent à faire fonctionner notre bootloader.
La partie matérielle gère les quatre afficheurs sept segments et les LEDs à travers des PORTs :
* PORTB pour l’affichage des 7 segments
* PORTC pour les 8 LEDs
* PORTD pour la sélection des digits d'affichages
Écrire des programmes C réalisant des chenillards un compteur sur deux digits.

##### Corrections

Voici un programme C réalisant un chenillard :

#### Partie matérielle

Le chapitre Interface VGA et PS2 ou le répertoire /CorrProjet2010 du fichier ATMega8_pong_VGA.zip contiennent une correction de la partie VGA du jeu de Pong (fichier VGA_top.vhd et ses composants) Modifier ce fichier pour remplacer l’affichage du score inutile par deux rangées de 8 briques au milieu de l'écran. Il serait bon de changer la place de l’affichage des scores (plus au milieu). Pour mettre au point cette partie on travaillera sans processeur. Une fois que tout est au point on crée l'interface entre cette partie et le processeur.
Pour aider les étudiants, nous proposons les choix technologiques suivants reliant les PORTs aux signaux de commande VGA :

##### choix technologiques

    E/S module VGAE/S AVR x_rect<9:8>PORTD<1:0> x_rect<7:0>DDRD<7:0> y_rect<9:8>PORTB<1:0> y_rect<7:0>DDRB<7:0> y_raqG<7:0>PORTC<7:0> y_raqD<7:0>DDRC<7:0> ligne1<7:0>PORTA<7:0> ligne2<7:0>DDRA<7:0> scoreG<7:0>EEDR<7:0>
Le registre EEDR est normalement réservé aux données de l'EEPROM. Comme nous n'avons pas d'EEPROM dans notre cœur embarqué nous l'utilisons pour ajouter 8 bits de sorties supplémentaires. « ligne1 » et « ligne2 » gèrent le 1er mur1 et le 2eme mur de l'image ci-dessus.
C'est une caractéristique de ce cœur, cette facilité à transformer des registres en PORTs. Nous rappelons que ceci est fait avec le code VHDL :
Et voici de manière schématique ce qu’il faut faire pour interfacer notre écran VGA au processeur :
Les signes + devant des entrées ou sorties veulent dire que l’on a ajouté ces entrées ou sorties dans les entités correspondantes. On a dessiné seulement trois composants dans cette figure, mais il en existe beaucoup d'autres.
* Le composant VGATop est inclu dans le fichier io.vhd qui est renommé io2.vhd pour l’occasion.
* La connexion à l'intérieur de io2.vhd se fait avec le process vhdl qui est montré plus haut dans cette section.

#### Solution

Exercice3 question 3 du chapitre Interfaces VGA et PS2 contient une correction de la partie gestion de l'écran VGA.
Le répertoire /CorrProjet2011 du fichier ATMega8_pong_VGA.zip contient une correction complète du projet 2011/2012.

#### Partie logicielle

Programmer l’ensemble avec plusieurs niveaux de jeu :
* un premier niveau avec une rangée de briques pour lequel n’importe quel rebond sur une brique éteint cette brique
* un deuxième niveau avec une rangée de brique avec une sur deux d'allumée pour lequel n’importe quel rebond sur une brique éteint cette brique
* un troisième niveau semblable au premier niveau avec une rangée de briques mais pour lequel seule une balle provenant de votre raquette pourra éteindre une brique
* un quatrième niveau semblable au deuxième niveau avec une rangée de briques une sur deux allumée mais pour lequel seule une balle provenant de votre raquette éteindra une brique
* un cinquième de niveaux avec deux rangées de briques.
Les étudiants ont toute latitude pour accélérer les balles et trouver un algorithme de calcul des scores.
Le changement de pente pour la balle pourra se faire de manière aléatoire par la raquette qui suit la balle.
Attachez-vous à comprendre comment le C gère les briques : comment vous savez où sont les briques ? C'est fait ici grâce aux deux tableaux tabmur1 et tabmur2 qui contiennent toutes les informations de position que vous avez dans votre partie matérielle.
* Cette version gère correctement 7 niveaux de jeux : après le septième niveau tout est comme au septième.
* pour le niveau 2 et 4 on est parti du principe qu’il était plus difficile de "descendre" 4 briques que 8 ce qui est faux ! à revoir donc !
* Ce programme tient dans un peu plus de 2 ko : comme nous disposons de 8 ko, nous voyons qu’il est possible de l'améliorer nettement.
* Ce programme manque de jouabilité : quand vous avez une brique à "descendre" vous pouvez certes modifier la pente du rebond mais comme la raquette droite le fait de manière aléatoire, cela rend difficile la visée. Il faudrait peut être remettre en cause le rebond aléatoire sur la raquette de droite !!!
* On ne gère par contre aucun score : ce sera certainement réalisé l'année prochaine avec un affichage en mode caractères.

### Conclusion

Ce travail a été donné à deux étudiants pour 60 heures de projet. La partie matérielle a été réalisée en 30 heures, comme prévu à l'origine. Nous rappelons qu’il s'agissait de partir de la partie matérielle du jeu de Pong et de la modifier pour le casse briques.
La partie logicielle qu’ils ont développé gérait :
* les rebonds sur les deux raquettes
* les rebonds sur les deux murs quand la balle venait de la gauche ou de la droite avec destruction de la brique correspondante.
Aucun niveau n'était géré.
Les rebonds hauts et bas sur les briques n'ont pas été gérés.
Il manquait probablement une trentaine d'heures pour aboutir à la correction donnée dans ce chapitre, qui est celle de l'enseignant tuteur.
Du point de vue programmation, ce casse briques est devenu un peu complexe pour des étudiants de niveau L2.

## Projet casse-briques (suite) pour 2012/2013

Pour des raisons indépendantes de notre volonté, ce projet a du être abandonné surtout parce que nous avons décidé au dernier moment d'interfacer un téléphone portable comme outil de commande du jeu. Le mot "Android" étant alors dans le titre de ce sujet, il a attiré plus d'étudiants que prévu ce qui nous a obligé de doubler les projets Android. Ce changement profond nous oblige à :
* transformer ce sujet (voir la section suivante) puisqu'en fait nous allons réaliser un jeu de Pong sur notre FPGA avec deux commandes par téléphone portable (un par raquette),
* réaliser deux commandes par Android concurrentes et donc écrire un nouveau chapitre dédié à ce problème : Les nouvelles interfaces : de la nunchuk de Nintendo à Android.
La bonne nouvelle, quand même, c’est que nous avions fait une correction qui est donc ajoutée à la fin de cette section.
Cette section utilise les RAM spécifiques des F.P.G.A. de chez Xilinx. Il est donc pas inutile d’en rappeler la terminologie (déjà évoquée dans le chapitre Interfaces VGA et PS2).
On appellera dans la suite :
* RAMB4 un RAM/ROM de 4 kbits
* RAMB16 un RAM/ROM de 16 kbits
* RAMB16_S18 une RAMB16 avec 18 bits de données (2 ko) : 16 bits et deux bits de parité non utilisés pour nos besoins.
* RAMB16_S18_S9 une RAMB16 avec deux PORTs indépendants 18 bit de données (16 kbits) pour la partie reliée au processeur et 9 bits pour la partie reliée au FPGA.
Nous allons améliorer la partie matérielle du projet précédent de trois manières :
* affichage en mode texte dans la partie basse : score sur 4 digits et level sur deux digits.
* interfaçage au cœur AVR pour pouvoir mettre à jour ce score et ce level.
Faute de temps, nous ne voulons pas laisser les étudiants réaliser une partie matérielle trop importante : sur les 60 heures de projet, nous ne voulons en aucun cas dépasser les 30 heures de conception matérielle. Nous allons ainsi leur donner la gestion VGA toute faite. Il faudra donc réaliser l'interface avec 4 PORTs de l'AVR pour pouvoir écrire dans la mémoire et pouvoir ainsi changer les valeurs numériques.

### Peut-on gagner de la mémoire RAM ?

Nous avons déjà eu l’occasion de présenter les diverses modifications que nous avons réalisé sur la mémoire programme pour pouvoir utiliser data2mem (voir le chapitre correspondant). Cette année il nous faut réaliser un travail un peu identique sur la mémoire RAM.
La mémoire RAM de l'ATMega8 a une taille de 1 ko (celui qui est vendu par ATMEL). Dans le cœur original de chez OpenCore cette RAM est réalisée à l'aide de quatre RAMB4_S4_S4 (possédant deux PORTs de 4 bits soit 4 ko en tout). En clair nous avons plus de mémoire RAM que prévu : c’est bien. Mais est-ce que le compilateur C est capable de l’utiliser ?
D'un autre côté quel gaspillage ! Le F.P.G.A. spartan 3 utilisé ne possède que des RAMB16 mais chaque bloc de RAMB4 prend en fait un bloc de RAMB16. En clair on gaspille 16 ko pour en faire 4 ko !!! Le problème c’est que la ROM programme plus la RAM ainsi réalisée utilisent toutes les RAMB16 du spartan3 !!! Or il nous faut réaliser une ROM de caractères pour afficher notre texte.
Si l’on prend en compte les programmes déjà réalisés, on peut s'apercevoir qu’ils ne sont pas très consommateurs de RAM : ainsi l’idée consistant à remplacer 4 RAMB4 par une RAMB16 de 2 ko ne pénalisera certainement pas nos programmes. Cela libère ainsi 3 RAMB16 : une sera entièrement utilisée par notre ROM de caractères, une autre sera utilisée pour les briques et le texte à afficher. Il nous en reste une pour faire évoluer cet ensemble.
Cette modification a déjà été réalisée dans la correction du projet précédent (celui de 2011/2012 voir le répertoire /CorrProjet2011 du fichier ATMega8_pong_VGA.zip si vous utilisez le fichier vgaTopCassebrique.vhd en lieu et place de vgaTopCassebrique2.vhd)

### Travail à réaliser

Comme d'habitude ce travail se décompose en une partie matérielle et une partie logicielle.

#### Partie matérielle

La connexion de PORTs pour l'ATMega8 a déjà été évoquée dans le projet précédent. On rappelle donc que le projet 2011 a réalisé la connexion du module VGA de la manière suivante :
Nous allons présenter maintenant ce qu’il va vous falloir réaliser.
Comparez les deux figures avant de commencer quoi que ce soit. Comme d'habitude les (+) désignent des entrées ou sorties à ajouter et les (-) la même chose mais à retirer. Nous avons retiré tous les + de l'année dernière car tout est déjà prêt cette année.

##### choix technologiques

    E/S module VGAE/S AVR x_rect<9:8>PORTD<1:0> x_rect<7:0>DDRD<7:0> y_rect<9:8>PORTB<1:0> y_rect<7:0>DDRB<7:0> y_raqG<7:0>PORTC<7:0> y_raqD<7:0>DDRC<7:0> ligne1<7:0>PORTA<7:0> ligne2<7:0>DDRA<7:0> AddrL<7:0>TWAR<7:0> AddrH<7:0>TWDR<7:0> Data<7:0>ADCL<7:0> CommandBus<7:0>ADCH<7:0>
Nous avons donc choisi les tout premiers registres non utilisés. Ceci est réalisé dans le fichier io2.vhd avec :
Voila en quatre points le travail à réaliser en VHDL :
* Éventuellement, modifier le fichier vgaTopCasseBrique2.vhd pour ramener le contenu de la mémoire RAMB16_S9, qui contient le texte à afficher, en adresse 0.
* Ajouter quatre PORTs de sortie au cœur ATMega8 dans le fichier io2.vhd. Trois PORTs peuvent suffire car nous n'aurons jamais à écrire au-delà de 256 octets (8 bits d'adresse).
* Ajouter un PORT à la RAMB16_S9 en la transformant en RAMB16_S9_S9 dans le fichier vgaTopCasseBrique.vhd
* Connecter les trois ou quatre PORTs de l'ATMega8 au PORT ajouté de la RAMB16_S9_S9.
Voici le fichier io2.vhd :
Voici le fichier VGATopCassebrique.vhd :

#### Partie logicielle

En commençant par réaliser une balle qui rebondit correctement sur les raquettes, vous pourrez améliorer votre programme petit à petit pour que votre balle soit capable de rebondir sur des briques en les détruisant. Affiner ensuite vos rebonds sur les briques en particulier avec les rebonds sur les faces horizontales des briques.... Gérer ensuite l’affichage du "level" et pour finir celui du "score" à votre convenance.

## Projet Pong et téléphones portables (2012/2013)

Il s'agit de réaliser un jeu de Pong dans un FPGA avec un processeur ATMega8 comme nous l'avons décrit dans le chapitre Embarquer un Atmel ATMega8. Nous avons décidé aussi d'ajouter un chapitre qui traite, entre autres, des possibles interfaces Android/FPGA : Les nouvelles interfaces : de la Nunchuk de Nitendo à Android.

### Travail à réaliser

On vous demande de vous initier à la programmation Android. Il n’est pas difficile de la réaliser directement sur une tablette même bien plus facile que sur un PC. En effet l'installation du SDK et des machines virtuelles sur un PC est très longue.

### Réalisation matérielle et logicielle

Deux téléphones portables Android (remplaçables par des tablettes Android) vont commander deux raquettes.
* La partie Android utilisant l'USB est composée d'un PIC 24F qui gère l'USB maître. C'est donc ce PIC 24F qui devra communiquer avec le FPGA. Nous avons choisi de communiquer par la RS232 (mais en 0/3,3 V).
* La partie Andoid utilisant le bluetooth est composée par un FB155BC de chez Firmetch qui s'interface par défaut en 9600 bauds, pas de parité, 1 bit de stop (sans protocole matériel).
La conséquence immédiate est qu’il nous faut un processeur capable de gérer deux liaisons rs232. Nous n'en avons pas ! L'ATMega8 utilisé jusqu'à maintenant en possède une seule pour laquelle la vitesse est fixée à 38400 bauds. Nous allons utiliser celle-ci pour communiquer avec le PIC24F. Celle qui doit fonctionner avec le bluetooth sera ajoutée de toute pièce.

#### Liaison série dans le PIC24F

Le PIC 24F laisse la liberté d'utilisation des broches dédiées. Je m'explique.
Si vous regardez le brochage d'un PIC24F, vous ne verrez aucune broche où apparaît "RXD" ou "TXD" : vous pouvez les mettre n’importe où. C'est pratique mais c’est une chose supplémentaire qu’il faut apprendre à gérer. Nous avons eu bien du mal à trouver un exemple. Le seul livre sur le PIC24F dont nous disposions parle de la RS232 sans évoquer ce problème ! Mais comme la platine Android de chez Microchip n'utilise pas la broche rs232 standard (du kit de développement), il faut donc réaliser sa déclaration. Ceci se fait avec le code c suivant :
Le kit Android possède bien une E/S dédiée mais pas le composant. Si vous avez bien compris, vous voyez qu'on utilisera le port série numéro 1 (il y en a un deuxième) et que la transmission se fera sur la broche RP11.

#### Programme d'exemple pour la première UART

La première UART est celle que l’on a en bonus avec le cœur ATMega8.
Nous donnons pour information un programme qui gère la communication rs232 de notre ATMega8. La réception peut être gérée par interruption. Rappelons qu'ici la transmission est fixée en dur comme :
* 38400 bauds
* pas de parité
* 8 bits de données
* 2 bits de stop.
La réception sans interruption peut se faire avec quelque chose comme :
Intéressons-nous maintenant à la deuxième UART.

#### Construction matérielle de la deuxième UART

Les lecteurs qui ont suivi les projets un par un jusqu'ici sont habitués aux modifications du fichier "io.vhd" d'ailleurs transformé pour l’occasion en "io2.vhd". Mais nous nous sommes contentés jusqu'à présent d'ajouter de simples PORTs, ce qui se faisait dans un process appelé "io_wr". Ce que nous allons faire ici est un peu différent : cela se passe dans le process "io_rd" car nous avons des registres en entrée (deux pour être précis ADCH et ADCL). La gestion de la sortie est différente et se fera grâce à une équation combinatoire.
Voici comment est faite la partie matérielle d'envoi dans le fichier io2.vhd (tous les détails ne sont pas donnés) :
L'avant dernière ligne du programme VHDL ci-dessus décide qu'une écriture dans la RS232 se fera par le registre ADCL d'adresse 0x24.
Relisez Interfaces RS232 et USB pour comprendre l’utilisation des logicores Xilinx. Notez cependant que nous avons choisi les anciens logicores (8 bits au lieu de 9) pour ne pas gérer de parité. Ceci parce que ceux-ci seront connectés au module Firmtech qui ne gère pas de parité.

#### Programme d'exemple pour la deuxième UART

La deuxième UART a été réalisée avec les logicore Xilinx (avec un FIFO d'ailleurs). Pour information nous avons été obligé de renommer les entités en les préfixant par "Xilinx_" car ces entités existaient déjà dans le cœur ! Pareil pour les noms de fichier ! Sans quoi c’est la grande pagaille dans le projet !
Nous avons aussi décidé d’utiliser le registre ADCL pour cette fonction. C'est un registre, qui pour un ATMega8 de la vraie vie, est associé à la conversion analogique numérique. Nous n'en n'avons pas dans notre FPGA, il est donc libre pour en faire ce que l’on veut.
Voici un exemple en C qui envoie un caractère.
Un programme principal du genre :
peut être utilisé. Ce programme insère les caractères reçus parmi les 'A' affichés dans l'hyperterminal. Les caractères envoyés ne sont pas perdus grâce au buffer de 16 caractères qui a été gardé.

### Annexe : fichier ucf utile pour la carte Spartan3E

Voici le fichier ucf pour la carte spartan 3E. Ce fichier n’intéressant pas les utilisateurs d'autres cartes et d'autres fondeurs, nous le mettons dans une boîte déroulante.

### Éléments de solution Android

Un programme pour tablette Android a été développé. Dans un premier temps il devait présenter un écran avec deux boutons "monter" "descendre" destinés à monter et descendre la raquette par l'intermédiaire du bluettoth. Puis une version utilisant le gyroscope de la tablette a été mise en œuvre. Ces programmes ont été développés par les étudiants Benjamin EUVRARD et Thomas GRIMONT.
Voici donc sans commentaire particulier :
* le fichier manifess.xml
* le fichier MainActivity.java
* Le fichier Boutons.java
* fichier Gyroscope.java

## Projet pacman pour 2012/2013

La partie gestion d'écran pour pacman est maintenant développée, et nous allons l'interfacer à l'ATMega8. Pour le moment vous pouvez lire aussi :
* pacman dans wikipédia qui vous rappelle les règles et la terminologie associée.
* qu'appelle-t-on un sprite dans un jeu vidéo ?
* le site pacman chez opencores semble intéressant. Il s'agit d'un pacman complet, sans processeur et en verilog.
* Construction de la gestion d'écran correspondant avec un décor et des sprites dans ce livre (A LIRE ABSOLUMENT).
Commençons par quelques explications.

### Comment gérer les positions des sprites

L'écran vidéo doit être commandé par un certain nombre de PORTs et une mémoire vidéo. La mémoire vidéo étant abordée un peu plus loin nous allons nous concentrer sur ici sur la façon d’utiliser les PORTs. Il nous faut commander les choses suivantes :
* coordonnées x et y du pacman
* coordonnées x et y de l'ennemi
* le numéro de sprite
C'est donc au processeur de gérer cet ensemble de données. Le numéro de sprite est présent pour pouvoir changer de type de pacman suivant qu’il monte, descend va à gauche et à droite.
Comme d'habitude c’est le fichier "io2.vhd" qui est responsable de la gestion des PORTs. En voici un extrait assez significatif :
Vous avez assez de données dans cet extrait VHDL pour écrire des sous-programmes demandés un peu plus loin. Si vous avez été attentif vous aurez remarqué que seuls huit bits sont utilisés pour les coordonnées alors qu'en principe 9 sont nécessaires. On a effectivement décidé de laissé tomber le bit de poids faible.

### Comment interfacer notre décor

Rappelons à ce point que le décor, ce qui apparait à l'écran est dans une RAM. Il faut à tout prix que le processeur ait accès à cette mémoire en écriture et lecture pour changer le décor (quand il mange une pac_gomme par exemple).
Dans le projet précédent de cette même année, nous avons choisi d'interfacer la mémoire écran à travers des PORTs. C'est très facile à réaliser mais assez inefficace : rien que pour réaliser l'adresse il faut écrire dans deux PORTs. Pour mettre la donnée il faut écrire dans un autre PORT et ensuite écrire quelquefois dans le PORT de commande pour réaliser les bons signaux. Regardez pour vous convaincre comment se fait le changement du niveau (level en anglais) par écriture dans la RAM dans l'autre projet (Casse-briques):
Et encore on n'utilise ici qu'une adresse sur 8 bits, ce qui est impossible pour le pacman !
Il nous faut donc trouver une autre technique.

### Projeter la RAM vidéo dans la mémoire RAM du processeur

Tout d’abord quelques remarques d’usage : ce que nous allons faire dans cette section n'est absolument pas réalisable avec un processeur du commerce... enfin, en tout cas, nous ne voyons pas très bien comment faire ! Cela rend naturellement les explications qui suivent pas très faciles à suivre !

#### Limitations RAM de l'ATMega8 du commerce

Un ATMega8 du commerce possède 1 ko de RAM et cette RAM n'est absolument pas visible de l'extérieur. Si vous voulez la transférer à l'extérieur il vous faudra câbler une SRAM externe et utiliser quelques PORTs de l'ATMega8 pour y écrire des choses. Et si vous voulez qu'un circuit externe vienne lire cette mémoire, c’est là que les problèmes commencent : n'est-ce pas pour ce genre de situation que l’on a inventé l’accès direct à la mémoire (DMA) ? La bonne nouvelle c’est que nous nous passerons de cela car les mémoires des FPGA modernes peuvent avoir plusieurs ports (ce sera deux ports pour nous car nous utilisons un FPGA assez ancien (2003)).
Une autre question importante est de savoir si votre compilateur C connait les limitations RAM de votre ATMega8. Autrement dit, si vous essayez d'écrire au-delà de votre kilo octet votre compilateur vous enverra-il un message d'erreur? Quelques essais nous ont convaincu que ce n'était pas le cas pour le compilateur du GNU. C'est un bon signe pour nous.

#### Et notre cœur ATMega8

Nous avions remarqué depuis le début que la version originale du cœur contenait 4 RAMB4_S4_S4 comme RAM, ce qui fait 2 ko. C'est le double du microcontrôleur original. Nous avons même vu une version avec 4 RAMB16_S4_S4 ce qui fait 8 ko de RAM... et nous venons de voir que le compilateur savait gérer tout cela (sans aucune option de compilation d'ailleurs).
Muni de cette expérience, nous allons prendre la partie VGA développée dans un autre chapitre. Elle contient une RAMB16_S9 pour gérer le décor (le fond d'écran) qui a été étendue en RAMB16_S9_S9, c'est-à-dire qu'on lui a ajouté une interface de lecture/écriture. Et nous allons nous arranger pour que cette deuxième interface soit reliée au cœur ATMega8. Une réussite nous permet d'envisager de changer ce que l’on veut du décor en écrivant ou lisant directement dans la RAM processeur. Fini les PORTs pour modifier le contenu de la RAM vidéo, de simples variables bien gérées suffisent. Pas convaincu ? Voici comment on change le Level dans le pacman sans aucune manipulation de PORTs :
Nous devons reconnaître qu’il faut manipuler le language C avec brio pour comprendre cela. Mais l’idée générale est la suivante :
* déclarer un pointeur unsigned char *affscore;
* donner une valeur au pointeur affscore = (unsigned char *)LEVELUNIT; où LEVELUNIT est une constante qui définit l'adresse qui nous intéresse. C'est ici qu'est la subtilité.
* changer une valeur à cette adresse consiste maintenant à écrire *affscore=quelque-chose
Nous pensions dans un premier temps que tout bon compilateur n'aurait pas dû nous permettre d'écrire n’importe où dans la RAM... mais finalement trouvons cela bien pratique.
Peut être un autre détail, pourquoi décrémente-t-on l'adresse deux fois entre l'écriture des unités et celle des dizaines? Voici un schéma qui permet l'explication :
À gauche de cette figure on a représenté la RAM des micro-controleurs ATMega8. Pour une raison qui ne nous parait pas évidente, Juergen Sauermann, le concepteur du cœur ATMega8, a organisé la mémoire RAM par mot de 16 bits. Cela nous permet de l'organiser comme en partie droite : deux RAMB16_S9 côte à côte. Celle de droite correspond aux adresses paires tandis que celle de gauche correspond aux adresses impaires. Si vous voulez rester dans la partie notée décor (à droite donc, et pour les adresses hautes), il vous faut donc incrémenter les adresses de deux en deux pour les laisser paires !

### Travail à réaliser

En fait notre ATMega8 n’est pas conçu pour le genre de travail que nous cherchons à réaliser. Si vous regardez tout ce qui a été fait avec ce processeur jusqu'à présent, vous vous rendrez vite compte que l'ajout du matériel s'est toujours fait avec le fichier io.vhd où sont décrits les registres internes. Mais nous voila avec un périphérique très particulier qui contient une zone mémoire. Or la RAM interne est gérée dans un autre fichier... il faut donc faire communiquer ces deux fichiers qui sont bien sûr enfouis dans d'autres. Cela nécessite une bonne connaissance de ce cœur qu'aucun étudiant de L2 ne peut avoir. Nous avons donc décidé de vous fournir entièrement la partie matérielle toute faite. Votre travail consistera donc essentiellement à programmer, et croyez-moi, il y a beaucoup de travail. Pour que vous ayez quand même un petit peu de matériel à réaliser, on vous demande simplement d'interfacer un mini-mini joystick fourni.
Finalement le mini joystick est abandonné au profit d'une manette Nunchuk de la console Wii de Nintendo. Il s'agit d'un protocole I2C pas très difficile à mettre en œuvre. Nous avons donc ajouté un chapitre à ce livre pour l’occasion : Les nouvelles interfaces : de la Nunchuk de Nitendo à Android.
Le répertoire /pacman2012 du fichier ATMega8_pong_VGA.zip contient l’ensemble matériel de ce projet (avec la manette Nunchuk). Vous n'aurez qu’à adapter le fichier ucf correspondant pour disposer d'un pacman complet. Un coup d’œil cependant vous montrera qu’il manque l'essentiel : le programme C que nous allons présenter maintenant.

#### Développement logiciel

On vous demande de développer un certain nombre de sous-programme et de les tester au fur et à mesure. Commencez par montrer que le sous-programme "putLevel" donné plus haut fonctionne.
* Développer un sous-programme putScore sur le même principe.
* À partir de maintenant, amusez-vous à interfacer le joystick et votre pacman en laissant tomber enemy à l'aide de
Vous ne pourrez pas aller plus loin sans savoir si vous heurtez le mur ou pas.
* Compléter le sous-programme
dont l'objectif est de savoir pour toutes les positions vers quelles directions il est possible d'aller sans heurter un mur. C'est le cœur de votre travail, mais ce sous-programme est assez difficile à développer. Ce qui le rend si difficile est qu’il faut y refaire ce qui a été fait en VHDL :
* trouver le numéro de pavé à partir de x et y avec la concaténation VHDL. La difficulté et qu'ici x et y sont sur 8 bits, c'est-à-dire qu'on a perdu les deux bits de poids faibles (de pixel_x et pixel_y en VHDL). Soyez donc méthodique.
* en déduire l'adresse mémoire du pavé dans lequel nous sommes. La formule est simple mais c’est pas pour cela que vous allez la trouver du premier coup.
* en déduire si le pavé supérieur, inférieur, droite et gauche contiennent ou non des murs (code 0xO7)
Pour vous aider nous vous donnons un sous-programme qui fait les deux premiers points :
Ce sous-programme calcule d’abord les coordonnées du centre du pacman (ou de l'ennemi) puis calcule l'adresse courante en mémoire vidéo sur laquelle on se trouve. Muni de cette adresse, il n’est pas très difficile de trouver ce qui l'entoure. Pour information nous avons testé le sous-programme complet "computePossibleWays" en manipulant l’affichage du score comme ceci :
qui utilise putScore qui est la première chose que l’on vous demande de faire.
* Le reste est laissé à votre initiative. Mais gardez à l'esprit que votre premier objectif est de laisser tomber l'ennemi pour vous concentrer sur le pacman. Il ne faut pas que ce pacman puisse traverser une brique ! Après seulement, faites le manger les pac-gommes.

#### Développement matériel

On vous demande de développer une interface matérielle I2C capable de gérer la manette Nunchuk. Cela doit se réaliser en deux étapes :
* gestion de la communication avec la manette Nunchuk à partir du projet de Eli Smertenko i2c Master Slave chez Opencores.org. On utilisera éventuellement un processeur pour faire les tests,
* adaptation de la première étape à notre processeur ATMega8. Le micro-contrôleur ATMega8 gérant lui aussi l'I2C avec l'interface TWI (Two Wire Interface) nous nous attacherons à respecter du mieux que nous pourrons la documentation officielle de celui-ci.
La documentation de l'ATMega8 s’appelle "doc2486.pdf" : téléchargez-la et allez en page 169, c’est là que le travail sérieux commence...
Pour des raisons indépendantes de notre volonté nous avons été obligé de ne pas laisser les étudiants faire ce travail. Nous voulions en effet avoir le pacman fonctionnant avec la manette Nunchuk à mi-projet pour pouvoir le présenter au 40° anniversaire de notre département Génie Électrique. Nous avons cependant laissé du travail à faire pour les futures années (récupération des données accéléromètre).
Un chapitre a été ajouté à ce livre qui donne une solution pour la partie i2c. Nous n'avons pas utilisé le projet de Eli Smertenko et avons abandonné l’idée de gérer l'i2c comme dans l'ATMega8 original.

### Correction partielle

Nous allons donner la correction partielle de ce projet.

#### La partie matérielle

Rappelons que le répertoire /pacman2012 du fichier ATMega8_pong_VGA.zip contient l’ensemble matériel de ce projet (avec la manette Nunchuk). Vous n'aurez qu’à adapter le fichier ucf correspondant pour disposer d'un pacman complet.
Signalons que nous avons l'intention d'arrêter de documenter ce chapitre avec les projets des années futures :
* le fichier ATMega8_pong_VGA.zip est devenu ingérable : il contient diverses version du cœur ATMega8, ce qui fait qu'un débutant aura bien du mal à s'y retrouver.
* nous allons commencer un nouveau chapitre du cours pour gérer le futur de ce cœur en essayant de le transformer en ATMega16 ou même ATMega32.
* le pacman correspondant aura deux (ou plus) ennemis ce qui n'était pas le cas cette année.
Nous avons assez de recul maintenant pour partir d'un cœur fiable qui contient l'essentiel de ce que l’on veut et de le faire évoluer sans changer de version de cœur, en tout cas en théorie.
Voici en schématique ce qui a été réalisé :
Un coup d’œil cependant vous montrera qu’il manque l'essentiel : le programme C que nous allons présenter maintenant.

#### La partie logicielle

Pour une fois nous devons avouer que nos étudiants sont allés bien plus loin que nous dans la programmation du pacman. Nous allons donner donc les deux solutions.

##### La solution de l'enseignant tuteur

Cette version fonctionne correctement mais partiellement seulement :
* le pacman peut manger le bonus mais ne peut pas poursuivre l'ennemi pour le manger
* l'ennemi va systématiquement deux fois plus vite que le pacman ! Il y a des moyens de s'en sortir quand même mais cela demande un peu d'expérience.
* la faiblesse de la poursuite du pacman par l'ennemi se trouve dans la fonction "computeDistance"
Ce programme fait environ 400 lignes.
Les étudiants nous ont fait un programme de près de 700 lignes que nous allons présenter maintenant.

##### La solution des étudiants

Quelques remarques sur le code :
* La gestion de la poursuite du pacman par l'ennemi est gérée d'une manière originale et a été conçue sans l'aide de l'enseignant tuteur. C'est vraiment le point fort de cette solution.
* Un certain nombre d'éléments sur l'écran qui leur était proposé (par le matériel en VHDL) ont été changé pour s'adapter à leur contexte (par le logiciel).
* L'apparition de messages "GAME OVER", "YOU WIN", ... a été gérée.

### Autre ressource

Notez qu’à partir de l'année scolaire 2013/2014, ce projet sera porté sur une version ATMega16 de ce processeur (voir Projet pacman avec l'ATMega16). La ressource correspondante se trouve ici : pacman2013.zip

### Annexe section pacman : Comment connecter le Joystick provisoire sur Digilent Starter Board Spartan3

Le pacman sera dans un premier temps commandé par un Joystick provisoire (qui représente en fait 4 interrupteurs gauche, droite haut et bas). Celui-ci est branché sur le connecteur A2 de la spartan 3. Il faudra changer ceci si vous utilisez une autre carte. Nous changerons cette section entièrement quand nous aurons réussi à connecter la manette Nunchuk. Pour le moment, le fichier ucf correspondant est :
Nous utilisons les broches 1, 3, 5, 7, 9 et 11 du connecteur A2, avec la correspondance :
* 1 est GND
* 3 est Vcc
* 5 est Bas géré par I_SWITCH(6) en broche "D5" du spartan3
* 7 est Haut géré par I_SWITCH(7) en broche "D6" du spartan3
* 9 est Gauche géré par I_SWITCH(0) en broche "E7" du spartan3
* 11 est Droit géré par I_SWITCH(1) en broche "D7" du spartan3