lundi 31 mars 2014

LPC810, partie 2

Dans cet article j'explique le diagramme bloc des microcontrôleurs LPC81x. Mais d'abord un mot au sujet de la compagnie ARM

ARM est une compagnie d’ingénierie et ne fabrique pas de circuit intégrés. Ils conçoivent des CPU et vendent des licences au fabricants de microprocesseurs. Il y a 3 familles de produits ARM: Cortex-A, Cortex-R et Cortex-M. Le A de Cortex-A signifie application. Cette famille de processeur est celle qu'on retrouve dans les téléphones, les tablettes et les laptops. Ce sont des CPU d'usage général. le R dans Cortex-R signifie Real time. Ces CPU sont utilisés dans les microprocesseurs pour les applications temps réel. Finalement la famille qui nous intéresse ici Cortex-M, M pour microcontrôleur. Inutile de dire où on les retrouve. Il y a 5 groupes de Cortex-M, M0, M0+, M1, M3 et M4. Les M0 sont les plus économiques et les M4 les plus performants. Les M0, M0+, M1 et M3 on une architecture Von Neumann mais les M3 et M4 ont une architecture Harvard. Les M4 possèdent en plus des fonctionnalités pour le traitement numérique de signale (DSP).

Donc comme je le disais ARM vends des licences et de nombreux fabricants de circuit intégrés en possèdent. Dans le domaine des microcontrôleurs il y a de nombreuses compagnies en possession de licences Cortext-M, Texas Instruments, Atmel, NPX, FreeScale pour n'en nommer que quelques unes.

Anatomie d'un LPC81xM

Il y a 3 MCU dans ce groupe LPC810, LPC811 et LPC812. Ils partagent le même datasheet et le diagramme bloc suivant est extrait de ce document.

Le bloc marqué en gras ARM Cortex-M0+ correspond au CPU licencié par la compagnie ARM. Tout le reste est conçu par les ingénieurs de NXP. Cette licence viens avec une option hardware multiplier. Comme lorsqu'on achète une automobile il faut payer un extra pour les options. NXP a donc acheté cette option puisque les LPC81xM possèdent ce composant.

Les bus

  • private bus Il n'est pas identifié sur ce diagramme mais ce bus est interne au bloc CPU et relie le core au contrôleur d'interruption NVIC aussi interne au coeur et aux modules optionnels vendus avec le coeur Cortex-M+.
  • fast GPIO et pin interrupts/pattern match, ces 2 modules ne font pas partie du coeur mais y sont reliés directement par un bus dédié.
  • AHB Advanced High performance bus est le bus primaire qui relie les blocs mémoire, le module CRC et le module SCT au coeur.
  • APB Advanced Peripherals bus est relié au bus AHB et relie les périphériques moins prioritaires en terme de délais d'accès.

Les périphériques

  • USARTx Universal Synchronous Asynchronous Receiver Transmitter, Le diagramme en montre 3 mais le LPC810 ne possède que le USART0. Ce module sert pour les communication RS-232 et RS-422. Peut communiquer sur de longue distance.
  • SPIx Serial Peripheral interface bus, le diagramme en montre 2 mais le LPC810 ne possède que le SPI0. Utilisé en autre pour accès au carte mémoire et autre mémoire en circuit intégré mais aussi pour des affichages LCD. Communication courte distance (boitier).
  • I2C Inter Integrated Circuit bus, communication sérielle entre circuit intégrés sur une même carte ou carte voisines. Sert aussi pour les sondes de température ou autre. Communication courte distance (boitier).
  • XTAL est le module oscillateur pour l'utilisation d'un crystal. N'est pas disponible sur le LPC810.
  • SYSCON est le module de configuration du MCU, configuration de la source de l'oscillateur système, du PLL, et autres paramètres de fonctionnement du MCU.
  • Comparator, c'est le module compartateur analogique.
  • IRC C'est l'oscillateur interne de 12Mhz. C'est cet oscillateur qui est sélectionné par défaut comme horloge système.
  • WDOsc C'est l'oscillateur du Watch dog timer, ça fréquence est programmable entre 9,4Khz et 2,3Mhz.
  • BOD Brown Out Detector, ce circuit détecte les chutes de tension et génère une interruption si l'alimentation descend sous un certain niveau.
  • POR Power On Reset, ce circuit maintient le CPU en RESET lors de la mise sous tension le temps qui cette dernière est atteint un niveau suffisant.
  • Clock generation, Power Control, system functions, ce bloc contient les circuit qui contrôlent les signaux d'horloges, la gestion de l'alimentation et d'autres fonctions système.
  • always on power domain, comme les MPC81xM possèdent un gestionnaire de consommation qui permet de réduire la consommation électrique à différent niveaux. En mode deep power-down le seul bloc qui reste alimenté est celui-ci. Ce bloc contient le PMU Power Management Unit qui gère les différent niveaux, sleep, deep-sleep, power-down et deep power-down. Le Self Wake-up Timer est une minuterie qui sort le MCU du mode deep power down après un interval de temps pré-programmé.
  • Multi-rate timer est une minuterie qui peut déclencher des interruptions régulières. Cette minuterie possède 4 canaux. C'est à dire que 4 interruptions régulières peuvent-être programmées avec une fréquence différente.
  • IOCON, contrôle des Entrées/Sortie numérique. Configure les broches pour différent modes de fonctionnement: Direction, pullup/pulldown, Open-colletor, glich filter, analog mode.
  • WWDT Windowed Watchdog Timer, minuterie chien de garde avec intervalle fenêtrée.
  • CRC Cyclic Redondancy Check, ce module sert à vérifier l'intégrité d'un bloc de donnée reçu ou transmis en émettant une somme de contrôle.
  • SCT State Configuration Timer, Minuterie utilisée pour la génération de signaux PWM ou comme compteur d'événements externe ou simplement comme compteur d'intervalle.
  • Pins interrupts/pattern match, configuration des interruptions sur changement d'état des broches ou interruption sur expression booléenne.
  • High speed GPIO, le branchement direct des broches en mode numérique au coeur permet l'écriture ou la lecture en 1 seul Tcy.
  • TEST/DEBUG INTERFACE il s'agit d'une interface JTAG pour les test d'usine boundary check et SWD Single Wire Debug pour la programmation et le débogage du MCU.
  • FLASH mémoire programme permanente de 4Ko sur le LPC810.
  • RAM mémoire de données de 1Ko sur le LPC810.
  • ROM mémoire permanente en lecture seule de 8Ko contenant le boot loader avec ISP ainsi que des interfaces I2C, USART, IAP et des profiles d'alimentation.
  • switch matrix, permet d'établir les connections entre les périphériques et les broches. Si certains périphériques ne peuvent être connectés qu'à une broche prédéfinie par contre d'autres peuvent l'être à n'importe quel GPIO libre. Par exemple le RESET ne peut-être relié qu'à la broche PIO0_5 (broche 1 sur le LPC810). les signaux USART0_RX, USART0_TX peuvent l'être à n'importe quel GPIO libre, par exemple si le RESET est désactivé USART_TX0 peut-être assigné à GPIO0_5. Ces assignations se font par les registres PINASSIGNx (il y en a 9).

samedi 29 mars 2014

introduction au LPC810 (ARM M0+)

Je prends une pause du projet PICvision pour présenter le seul microcontrôleur 32 bits disponible en format PDIP-8. Le MCU LPC810 fabriqué par NXP est en effet basé sur le core ARM M0+. Pour l'avoir en format PDIP-8 il faut commander le modèle LPC810M021FN8. NXP est le seul manufacturier à offrir des MCU ARM en format PDIP et il n'y a que 2 modèles disponibles, l'autre étant le LPC1114FN28 disponible en format PDIP-28 large (600mil.).

Caractéristiques du LPC810

paramètrevaleur
coeurARM Cortex M0+
architectureVon Neumann
Freq. CPU30Mhz max.
mémoire flash4Ko
mémoire RAM1Ko
USART2
I2C1
SPI1
comparateur1
multirate timer4 canaux
systick counteroui, 24 bits
GPIO6
multiplicationhardware 32 bits, 1 cycle
boot loader en ROMoui
alimentation1,8 à 3,6 volt

Environnement de développement

NXP mais à notre disposition une version gratuite de LPCXpresso. Cet IDE est basé sur Eclipse et est disponible pour Linux, Windows et OSX. Il faut cependant créer un compte utilisateur sur le site lpcware.com pour obtenir la clé d'enregistrement.

Une fois le logiciel installé l'enregistrement se fait à partir de l'IDE dans le menu HELP - Activate - Create serial number and register...

Une fois le numéro de série créé et la clé d'activation obtenue, il faut alors aller dans HELP - Activate - Enter activation code...

La version gratuite permet de créer des programmes jusqu'à 256Ko. Il y a deux autres logiciels à télécharger. Le premier est flash magic disponible gratuitement pour windows et OSX. Flash magic permet de programmer le MCU en se servant du boot loader en ROM qui est inclus dans le MCU lors de sa fabrication. A moins que vous n'ayez un programmeur compatible supportant SWD ou JTAG vous ne pourrez pas programmer le LPC810 à partir de l'IDE. Par défaut le compilateur génère un fichier .AXF qui n'est pas supporté par flash magic. Il faut donc pour chaque projet spécifié qu'on veut un fichier .HEX.

Pour générer un fichier HEX il faut dans l'explorateur de projet, cliquer avec le bouton droit sur le nom du projet et dans le menu choisir propeties. dans C/C++ setting onglet build steps, post-build steps command: cliquez sur le bouton edit....

dans l'éditeur ajoutez la ligne suivante:
arm-none-eabi-objcopy -O ihex "${BuildArtifactFileName}"
 "${BuildArtifactFileBaseName}.hex"
Une fois cette configuration accomplie, lors de la compilation du projet un fichier .HEX sera généré.

Premier projet

Pour ce premier projet on va en importer un de Github et le modifier. Allez à https://github.com/microbuilder/LPC810_CodeBase et à droite de la page cliquez sur le dernier bouton nommé Download ZIP. Une fois téléchargé il faut maintenant l'importer dans l'explorateur de projet de LPCXpresso.

En dessous de l'explorateur de projet il y a une autre fenêtre avec plusieurs onglets. Dans Quick start panel cliquez sur import project(s). Dans le fenêtre d'importation cliquez le premier bouton browse... et allez chercher le fichier .ZIP que vous venez de télécharger. Cliquez maintenant sur le bouton Finish. Une fois le projet importé il devrait apparaitre dans l'explorateur de projet sous le nom LPC810_CodeBase.

Déployez l'arborescence de ce projet et le dossier src à l'intérieur de celui-ci. Ouvrez le fichier main.c dans l'éditeur en double-cliquant dessus.

J'ai modifié le projet pour remplacer la LED simple par une une LED RGB dont les anodes sont connectées comme suis:

  • PIO0_1 (broche 5) ANODE ROUGE
  • PIO0_2 (broche 4) ANODE BLEU
  • PIO0_3 (broche 3) ANODE VERTE
  • V-   CATHODE COMMUNE
vue montage dans Boardview:
photo du montage:
On y aperçois la petite alimentation Sparkfun 3,3/5 Volt, ainsi que adaptateur de niveaux de tension RS-232 vers TTL.

Voici le fichier main.c tel que je l'ai modifié.

Ce projet est déjà configuré pour générer un fichier .HEX il ne reste donc qu'à le compiler. Dans la barre d'outils il y a un marteau avec une petite flèche à droite qui pointe vers le bas. Cliquez sur la flèche et ensuite sur Release (Release build).

S'il n'y a pas d'erreur de compilation il devrait y avoir un fichier LPC810_CodeBase.hex dans le dossier release du projet. Dernière étape flasher ce fichier dans le LPC810.

Flash magic

Vous avez installé flash magic maintenant ouvrez le. Mais d'abord pour faire entrer le MCU en mode boot loader il faut l'éteindre et ensuite mettre PIO0_1 (broche 5) à zéro volt (voir photo, j'utilise le cavalier bleu à cet effet). On réalimente le MCU. Maintenant dans flash magic, il faut sélectionner le port sériel sur lequel est branché le MCU, indiquez la vitesse de transmission et mettre le clock à 12Mhz. Comme illustré ci-bas (le no de port ne sera pas nécessairement le même sur votre ordinateur.
Pour la programmation le LPC810 reçoit sur la broche 8 et transmet sur la broche 2.

Utilisez le bouton browse pour aller chercher le fichier LPC810_CodeBase.hex dans votre dossier de travail LPCXpresso. Lorque c'est fait on clique sur le bouton start. Si tout va bien le message Finished va apparaître après quelques secondes dans la barre d'état. On éteint l'alimentation du MCU, on enlève le cavalier sur la broche 5 de Vss et on réallume. La LED RGB allume ses 3 couleurs en alternance à intervale de 0,5 seconde.


Documents à télécharger

LPC8xM datasheet
LPC81x user manual

vendredi 28 mars 2014

PICvision, nouveau démo

Je continue à travailler sur PICvision. Dernièrement j'ai créé un splash screen, un système de menus et j'ai refais le jeux serpent en mode graphique plutôt que caractère voici un vidéo du jeux en action.

Actuellement la mémoire flash n'est utilisé qu'à 24% mais la mémoire RAM à 87%. Il y a donc de la place pour ajouter de nouveaux jeux. J'ai peur cependant de manquer de mémoire RAM avant d'avoir tout utilisé la mémoire programme.

lien github

mercredi 19 mars 2014

PICvision, module HardwareProfile

Le profil matériel (hardware profile) est utilisé pour 2 raisons. La première est pour faciliter les modifications logicielles en cas de changement du schéma électronique et la deuxième pour rendre le projet plus facile à adapter à une autre plateforme.

Entre le premier schéma que j'ai dessiné et la version finale il y a eu des modifications au niveau de l'affectation des périphériques au broches du MCU. Par exemple au départ les lignes DATA1 et DATA2 des contrôleurs SNES étaient sur RB14 et RB15 et par la suite ont été transférés sur RA0, RA1. En créant les définitions suivantes dans le fichier HardwareProfile.h

// SNES paddles i/o
#define PADDLES_DATA_PORT PORTA
#define P_PDL1_DAT LATAbits.LATA0 // paddle 1 data input
#define P_PDL1_DAT_TRIS TRISAbits.TRISA0 // paddle 1 TRIS bit
#define P_PDL1_ANDIS AD1PCFGbits.PCFG0 // disable ANx disable bit
#define P_PDL2_DAT LATAbits.LATA1 // paddle 2 data input
#define P_PDL2_ANDIS AD1PCFGbits.PCFG1 // paddle 2 ANx disable bit
#define P_PDL2_DAT_TRIS TRISAbits.TRISA1 // paddle 2 TRIS bit
#define P_PDL_CLK LATBbits.LATB0 // paddles clock output signal
#define P_PDL_CLK_TRIS TRISBbits.TRISB0 // paddles clock TRIS bit
#define P_PDL_LATCH LATBbits.LATB1 // paddles data latch output signal
#define P_PDL_LATCH_TRIS TRISBbits.TRISB1 // paddles latch TRIS bit
Je n'ai eu qu'à modifier ces définitions sans chercher ailleurs pour que la modification s'applique partout dans le projet. Ce concept de profil matériel s'avère utile dans tous les projets le moindrement complexes. De plus on peut choisir des noms plus significatifs dans le cadre du projet.

La raison pour laquelle j'ai modifié le schéma électronique initial est justement pour faciliter l'adaptation du projet à un autre microcontrôleur. Actuellement je pourrais enlever le PIC24FJ64GA002 de la carte et le remplacer par un PIC32MX150F128B sans avoir à modifier quoi que ce soit au montage électronique. Tout ce que j'aurais à faire est de modifier le hardwareProfile et faire quelques adaptation au niveau du code. Bref avec seulement quelques heures de programmation j'aurais un PICvision fonctionnant avec un MCU 32 bits avec 32Ko de RAM plutôt qu'un MCU 16 bits avec 8Ko de RAM.

Le principe du profile matériel est simple on substitue des symboles par d'autres:

#define PADDLES_DATA_PORT PORTA
Ainsi chaque fois que dans le code je veux lire les lignes DATA des contrôleurs SNES j'utilise le symbole PADDLES_DATA_PORT au lieu de PORTA et si mon montage est modifié et que c'est sur PORTB plutôt que PORTA je n'ai qu'à changer la définition:
#define PADDLES_DATA_PORT PORTB
Tout ce qui est spécifique à la configuration matériel est centralisé dans HardwareProfile.h et HardwareProfile.c sauf les bits de configurations du MCU, qui eux doivent-être dans le fichier qui contient la fonction main(). Il semble que le pré-processeur s'attend à trouver ces directives dans le fichier principal.

conclusion

La modularisation d'un projet facilite sa gestion, les modifications et l'adaptation à d'autres plateformes. Centraliser les informations spécifique à la plateforme matérielle dans un seul fichier ou groupe de fichiers est un aspect important de la modularisation.

PICvision, module snes-paddle

Les contrôleurs SNES sont intéressant pour 2 raisons, ils sont économiques et facile à trouver et deuxièmement ils sont simple à interfacer.

Le connecteur SNES a 7 broches mais n'en utilise que 5.

  1. Vdd, positif de l'alimention, fonctionne aussi bien à 5volt qu'à 3,3volt
  2. clock, sert à lire le contrôleur, bit par bit.
  3. latch, lit l'état des boutons et met le résultat dans le registre à décalage
  4. data, sortie des bits de lecture.
  5. pas de connection
  6. pas de connection
  7. gnd, 0 volt de l'alimentation.
La broche 1 est à l'extrémitée plate du connecteur.

schématiquement l'électronique du contrôleur ressemble à ceci:

Le contrôleur a 12 boutons et pour faire la lecture de ces boutons on procède comme suit.

  1. Envoie d'une impulsion sur la ligne LATCH
  2. Lecture du premier bit (bouton B) sur la ligne DATA
  3. Répéter 15 fois
    1. Envoie d'une impulsion sur la ligne CLOCK
    2. Lecture du bit sur la ligne DATA
Les lignes CLOCK et LATCH sont des sorties digitales sur le MCU et sont gardée à zéro volt. L'impulsion LATCH mets cette ligne à Vdd pour 250nsec. Cette impulsion a pour effet de lire l'état des boutons dans le registre à décalage. On obtient un instantané de l'état des boutons dans le registre après cette impulsion. Un bouton enfoncé correspond à 1 bit à zéro. Le bit du bouton B est disponible dès le latch. Il y a 12 boutons met le registre a 16 bits. Les 4 derniers bits sont toujours à 1. Après avoir lu le bit du bouton B on envoie 15 impulsions sur la ligne CLOCK pour lire les 15 bits restants. les bits sont décalés vers la sortie à la transition montante de l'impulsion clock.

snes-paddle.c

C'est très simple comme code. Il n'y a qu'une fonction dans l'interface application:

unsigned read_paddle(int paddleId)
paddleId identifie le contrôleur dont on veut faire la lecture PADDLE1 ou PADDLE2. read_paddle() utilise les fonctions latch() qui envoie l'impulsion sur la ligne LATCH et la fonction bit_shift() qui envoie l'impulsion sur la ligne CLOCK pour décaler vers la sortie DATA le bit suivant.

Les 2 contrôleurs sont lus en même temps puisque les lignes CLOCK et LATCH sont communes aux 2 contrôleurs. La ligne DATA du PADDLE1 est lue sur l'entrée digitale RA0 et la ligne PADDLE2 est lue sur l'entrée digitale RA1. Les variables p1 et p2 contiennent le résultat de la lecture respectivement pour chacun des contrôleurs. La valeur de l'argument paddleId détermine laquelle de p1 ou p2 la fonction retourne. Le masque 0xfff est appliqué pour ne retourner que les 12 premiers bits. La valeur des bits est inversée de sorte qu'un bouton enfoncé a son bit à 1. Les constantes pour sélectionner les différents bits dans l'entier sont définis dans le fichier snes-paddle.h. En fait j'ai emprunté ces définitions au projet hackvision.

Pour plus d'information sur les contrôleurs NES et SNES vous pouvez lire le document NES-controller-Hydra-Ch6All-v1.0.pdf en anglais qui se trouve dans le répertoire docs du dépôt github.

dimanche 16 mars 2014

PICvision, module TVout

Le module TVout est celui qui génère le signal vidéo composite. Contrairement au module TVout du projet HackVision il est entièrement écris en 'C'. Ceci est rendu possible grâce à l'utilisation judicieuse d'un périphérique SPI pour sérialiser les bits vidéo. De plus comme le périphérique SPI du PIC24FJ64GA002 a une mémoire tampon de 8 octets le temps passé dans l'interruption qui génère les pixels vidéo est d'autant raccourci. En effet une fois que les 8 derniers octets de la ligne vidéo sont dans la mémoire tampon SPI on peut sortir de l'interruption et laisser le périphérique faire le travail. Les concepteurs de HackVision auraient put utiliser le périphérique SPI du AtMega328 pour la même utilisation mais il ne l'on pas fait. Cependant la mémoire tampon SPI du AtMega328 n'est que de un octet. Néanmoins en utilisant le SPI comme je l'ai fait ils auraient pu écrire leur TVout entièrement 'C' et réduire le nombre de cycles machine utilisés pour le vidéo.

Comme le code source est disponible sur le dépôt Github je ne vais reproduire ici que la partie du code étudié, soit les 2 interruptions. La première est celle qui contrôle le signal de synchronisation. La deuxième est celle qui envoie le contenu de video_buffer au périphérique SPI. Il est important que ces 2 interruptions soient le plus brèves possible étant données qu'elles se répètent plus de 15,000 fois par secondes, moins on y passe de temps plus il en reste pour le programme principal où est exécuté la logique du jeux.

Interruption _VSYNC_ISR

_VSYNC_ISR est la routine de service d'interruption qui contrôle le signal de synchronisation vidéo. Dans ce but un périphérique Output compare est utilisé en mode PWM. Il s'agit simplement de générer un signal à 15735 hertz pour le NTSC et 15625 hertz pour le PAL. Ce signal est de niveau 1 sauf pour l'impulsion de synchronisation horizontale qui elle est à zéro. Le signal sur la broche 16 du MCU a donc la forme suivante:

Cependant au début de chaque cadre (frame) le signal est inversé sur les 3 premières lignes vidéo pour assuré la synchronisation verticale:
la variable frame_line_cntr sert a compter les lignes et à partir du numéro de ligne on décide quand il faut activer et désactiver l'interruption qui envoie les pixels vidéo et quand il faut générer la synchronisation verticale. En mode progressif il y a 262 ligne en NTSC et 312 en PAL par cadre. Il faut donc faire des case différent pour le NTSC et le PAL.

Interruption _VIDEO_OUT_ISR

Cette routine de service d'interruption est celle qui prend le contenu du video_buffer et via le périphérique SPI sérialise les octets vers la sortie sur la broche 14 du MCU. Il s'agit d'une interruption de type Change Notification, c'est à dire qui est déclenchée chaque fois que le niveau change sur la broche 18. Entre la fin de l'impulsion de synchronisation horizontale et le début de l'envoie des pixels vidéo il y a un délais. On pourrait attendre à l'intérieur de l'interruption _VSYNC_ISR que ce délais soit écoulé et envoyer les pixels à partir de cette interruption. Ce serait du gaspillage de cycles machine. On utilise donc un deuxième périphérique Output compare qui lui aussi génère un signal semblable au premier sauf que l'impulsion de synchronisation est plus large. Elle débute 1µsec avant l'impulsion horizontal sync mais est 2 fois plus longue.

Cette impulsion est envoyée sur l'entrée digitale broche 18 du MCU et chaque fois qu'il y a un changement d'état l'interruption _VIDEO_OUT_ISR est déclenchée. Mais la transition qui nous intéresse est la montante. C'est pourquoi au début de _VIDEO_OUT_ISR on vérifie si la broche 18 est à 1
if (PIXDLY_INP){
Si c'est le cas on commence à envoyer les pixels du video_buffer en tenant compte du frame_line_cntr. Chaque ligne du video_buffer correspond à 1 ligne horizontale à l'écran.

Ces routines sont simples, en fait le plus gros du code de ce module est dans la définition des constantes et l'initialisation des périphériques.

Interface application

L'interface application (API) de ce module ne contient que 3 fonctions.

void video_init();
void wait_n_frame(unsigned n);
void blank_out();
La première fonction se passe de commentaire. wait_n_frame() est utilisée pour faire une pause dans le programme. Cette pause est en multiple de cadre. En mode NTSC un cadre dure 16,67msec. et en PAL 20msec.

blank_out() accepte 2 valeurs VIDEO_OFF et VIDEO_ON et sert exactement à ça. Cette fonction active et désactive la sortie des pixels vidéo mais sans désactiver le signal de synchronisation. On peut l'utiliser pour faire clignoter le contenu de l'écran au complet. exemple.

// clignotement de l'écran 5 fois par seconde
int delay;
if (video_mode==NTSC_MODE) delay=6;else delay=5; 
while(1){
    blank_out(VIDEO_OFF);
    wait_n_frame(delay);
    blank_out(VIDEO_ON);
    wait_n_frame(delay);
}

jeudi 13 mars 2014

PICvision, montage de la carte

J'ai complété le montage sur carte à bande Vector modèle 8022. La carte est de dimension 3,5" x 3" soit 8,9cm x 7,6cm. J'ai effectué le montage à partir du plan suivant mais avec quelques modifications en cours de route.

J'ai commencé par couper les bandes en me fiant au plan initial. La méthode la plus efficace que j'ai trouvé pour couper les bandes est d'utiliser une mèche (foret) 3/16" (4,8mm) que je fais tourner entre mes doigts.

J'ai indiqué un endroit où la coupure de la bande est entre 2 trous et non sur un trou. J'ai aussi indiqué où j'avais oublié de couper une bande.

Ensuite les connecteurs et les fils:

C'est un travail qui demande beaucoup d'attention car lorsqu'on tourne la carte il faut tenir compte que gauche et droite sont inversés.

Les gros connecteurs c'est à dire celui de l'alimentation et les phono RCA demande un travail spécial pour leur installation. Le connecteur d'alimentation viens avec 2 languettes d'environ 3mm de largeur et distante de 200mil. J'ai simplement percé entre 2 trous pour faire une fente de largeur suffisante pour les accommoder.

Pour les connecteurs phonos je n'ai pas essayé d'entrer les languettes dans les trous. j'ai plutôt soudé de fils de grosseur 24AWG que j'ai pu entré dans les trous.

J'ai ajouter 2 remarques sur cette photo. En bas à gauche j'avais un pont entre deux bandes qu'il a fallu que j'enlève après coup. J'avais aussi oublié d'installer le pont entre les broches 15 et 18 du MCU, indiqué en blanc sur la photo.

Le montage complété sans le MCU:

Il y a 3 condensateurs CMS soudés sous la carte.

Pour bien voir il faut cliquer sur les photos pour les agrandir. Les photos sont aussi dans le dépôt github dossier KiCAD.

Vérification avant d'installer le microcontrôleur

Il est quasiment inévitable de faire quelques erreurs au montage c'est pourquoi la première chose à faire avant d'installer le microtontrôleur est de brancher l'alimentation et de vérifier si vdd est bien sur les broches où il doit-être et de même pour vss. A la première mise sous tension la LED d'alimentation n'a pas allumée! Après vérification au voltmètre j'ai constaté que le 3,3 volt était présent à la sortie du régulateur mais sur l'anode de D1 j'avais zéro volt. J'ai vérifié le montage et constaté que j'avais mis un pont où il ne fallait pas, voir la 3ième photo à ce sujet en bas à gauche.

J'ai vérifié toutes les tensions sur les broches des connecteurs et du MCU. Sur le MCU ça n'allais pas sur la broche 7. Je devais mesurer 3,3volt à cause de R2 mais j'obtenais zéro. Vérification faite, il y avait un pont d'étain accidentel entre les broches 7 et 8. Le problème a été réglé rapidement avec le fer à souder.

Autre surprise 6 volt sur la broche 16 du MCU. C'est le voltage à l'entré du régulateur de tension! J'avais oublié de faire une coupure sur une bande tel qu'indiqué sur la deuxième photo en bas.

Après ces corrections tout avait l'air en ordre. J'ai donc installé le MCU et branché la carte sur le moniteur. Whoops! pas de vidéo! Vérification de la sortie vidéo à l'oscilloscope. le signal de synchronisation était présent mais pas le vidéo. J'ai donc vérifié sur la broche 14 du MCU, aucun vidéo. J'ai vérifié sur la broche 15 et le signal video delay était présent mais pas sur la broche 18. J'avais oublié d'installer le pont entre les 2 broches. Correction faites tout est maintenant fonctionnel.

Voilà donc la console de jeux PICvision avec 1 seul contrôleur de branché. Il ne lui manque qu'un boitier.

Premier jeux

Le logiciel de base n'est pas complété mais je voulais me faire une idée de quoi ça aurait l'air j'ai donc écris un jeux de serpent (centipede). Une variante du jeux traditionnel. Il s'agit d'un jeux en mode texte les graphiques et sons sont encore très rudimentaires. Au bruit que fait le serpent en se déplaçant on pourrait penser que c'est un train à vapeur et que la souris est un morceau de charbon. Dans ma variante le serpent ne fais pas que grandir il raccourci. A chaque souris qu'il mange il gagne 20 calories et rallonge d'un segment. Mais comme tout être vivant il brûle aussi des calories. Lorsqu'il a brulé 20 calories il perd un segment et lorsqu'il arrive à zéro il meurt de faim. Le serpent peut aussi mourir s'il frappe un mur ou s'il se mort la queue. Les calories et la durée de vie du serpent sont inscris en haut de l'écran. Le but du jeux étant de survivre le plus longtemps possible.

Maintenant que la partie matérielle du projet est complétée, dans les prochains articles je vais aborder le logiciel.

lundi 10 mars 2014

project PICvision

Il y a quelques semaines je suis tombé sur le projet Hackvision. Il s'agit d'une console de jeux rétro très économique et que chacun peut fabriquer chez lui sans avoir à utiliser de technologie de montage en surface. C'est donc à la porté de tous. Elle peut aussi être achetée toute assemblée chez Robotshop. Cette console est conçu pour se brancher sur un téléviseur avec une entrée composite NTSC ou PAL. Il s'agit d'un signal monochrome.

Le AtMega328P-PU utilisé ne possède que 2Ko de RAM donc la résolution vidéo est limitée à 136x96 pixels. En voyant ça j'ai décidé de faire une console semblable mais en utilisant un MCU PIC. Mais il n'y a pas de raison de se limiter à un MCU 8 bits. Microchip offre des MCU 16 bits et 32 bits en format PDIP-28. J'ai hésité entre utiliser un PIC24F et un PIC32MX. Puisqu'en fin d'année 2013 j'ai écris quelques articles de présentation des PIC24 j'ai finalement opté pour un PIC24FJ64GA002-i/p.

Il s'agit d'un projet open source sous licence GNU GPLv3 pour le code source et Creative Commons CC BY-SA pour les autres documents . Tous les fichiers sont disponibles sur https://github.com/Picatout/PICvision

Comparaison entre Hackvision et PICvision

Comparaison des microcontrôleurs:

paramètreAtMeag328PPIC24FJ64GA002
disponible en format PDIP-28ouioui
mémoire flash32Ko64Ko
mémoire RAM2Ko8Ko
temps de cycle cpu minimum50nsec62,5nsec
minuteries2 x 8 bits, 1 x 16 bits3 x 16 bits
périphériques OC (PWM)65
périphériques SPI12
périphériques I2C12
prix unitaire (digikey.ca)3,87CAN$4,40CAN$

comparaison des consoles:

paramètreHackvisionPICvision
assemblagefacile sur carte de prototypagefacile sur carte de prototypage
résolution136x96216x216
sortie vidéocomposite NTSC/PALcomposite NTSC/PAL
sortie audiomonophonique, tonalités, et DAC PWMmonophonique, tonalités, bruit blanc, DAC PWM
contrôleursboutons sur carte
optionnel: 2 gamepads NES/SNES
optionnel: nunchuck
connecteurs pour 2 gamepads SNES
optionnel Nunchuck sur breakout I2C.
interfaces libre en breakout1 x I2C peut-être utilisé pour un Nunchuck1 x I2C peut-être utilisé pour un Nunchuck
1 x SPI peut-être utilisé pour carte SD

schématique

Le schéma électronique est simple et le montage sur carte à bandes peut-être réalisé en quelques heures. Dessiné sur KiCAD les fichiers sont disponibles sur le github. Voici un aperçu du schéma et du plan de montage sur carte à bandes VECTOR electronics modèle 8022. Il s'agit d'une carte de 3" x 3,5" (7,6cm x 8,9cm).

Le MCU fonctionne sous une tension de 3,3 volt et c'est le régulateur LDO µA78M33 qui abaisse le voltage d'entrée à ce niveau.

Le microcontrôleur fonctionne à sa vitesse maximale de 32Mhz. Le crystal est à 8Mhz mais cette fréquence est multipliée par 4 par le PLL interne du MCU. Les PIC24 ont un cycle système de la moitié de la fréquence de l'oscillateur donc ici on a 16Mhz ou 62,5nsec par cycle machine.

Le signal vidéo composite est constitué d'un signal de synchronisation dont la sortie est sur la broche 16 et d'un signal contenant la composante vidéo proprement dite sur la broche 14. Un cavalier sur la broche 23, connecteur P4, permet de sélectionner entre les formats NTSC et PAL. La présence du cavalier est détectée au démarrage il doit donc être installé avant la mise sous tension. Notez qu'en ce qui concerne le signal vidéo monochrome composite PAL et SECAM sont identiques. La sortie vidéo est sur connecteur RCA phono. En Europe il faudrait probablement utiliser un connecteur SCART.

En ce qui concerne les contrôleurs SNES les broches sont communes aux 2 contrôleurs sauf la broche data. Pour le contrôleur 1 l'entrée data est sur la broche 2 du MCU et pour le contrôleur 2 sur la broche 3 du MCU. Les connecteurs P5 et P6 font le pont entre les connecteurs SNES et la carte.

Il y a 2 broches de sortie pour l'audio. La broche 21 appelée NOISE sur le schéma est une sortie bruit blanc produite avec le générateur pseudo-hasard. La broche 17 permet soit de sortir des ondes carrées, soit d'utiliser un périphérique output compare comme convertisseur numérique/analogique par PWM. Les résistances R6 et R7 et les condensateurs C7 et C11 forme un filtre passe-bas qui coupe les fréquences au dessus de 7Khz. La sortie audio est faite sur un connecteur RCA phono.

Les résistances R3 et R5, le condensateur C4 et la bouton momentané SW2 forme le circuit de réinitialisation du microcontrôleur.

P1 est le connecteur pour brancher le programmeur du Pickit2 utilisé pour la programmation du MCU.

P2 est un connecteur breakout pour le périphérique SPI2 du MCU. Cette interface n'est pas utilisée dans cette version de PICvision. Elle pourrait servir pour interfacer une carte SD.

P3 est un connecteur breakout pour le périphérique I2C2 du MCU. Cette interface n'est pas utilisée dans cette version de PICvision mais pourrait servir pour brancher un contrôleur Nintendo Nunchuck.

Plan de montage

J'ai photographié la carte Vector electronics modèle 8022 et j'ai éditer la photo dans paint pour faire mon plan de montage. Le résultat est le suivant.


Légende:
  • Trait noir indique une coupure dans la bande.
  • trait gris pâle indique la position d'un composant ou d'un pont entre 2 bandes.
  • trait rouge indique les ponts joignant les segments de bande vdd (3,3volts).

Liste matériel

test TVout

J'ai créé un programme test pour l'unité TVout.c Il s'agit d'une anneau qui rebondi sur les bords de l'écran. Pour le développement j'utilise un petit moniteur LCD de 5 pouces qui accepte les signaux composite NTSC et PAL.

Dans le prochain article je vais détailler le montage sur la carte de prototypage.


Mise à jour 2015-09-06

Il existe maintenant une version 2 de CHIPcon. J'ai remplacé le clavier hexadécimal par un joystick. Mais le plus gros du travail a été fait au niveau logiciel aussi bien sur le firmware de la console que sur les outils de développement.

  • Plusieurs bogues ont étés corrigés.
  • La documentation a été refaite.
  • La machine virtuelle a été augmentée par l'ajout de plusieurs code machine.
  • La liste des jeux en firmware a été modifié entre autre j'ai créé un jeu appellé octopacman.