mardi 27 décembre 2016

interface pour clavier PS/2

J'utilise régulièrement un clavier dans mes projets et comme j'utilise une variété de MCU je dois réécrire l'interface pour le clavier. J'ai donc décidé de régler ce problème une fois pour toute en créant un module d'interface clavier que je vais inséré dans tous mes projets qui utilisent un clavier. Je sauverai ainsi du temps et de l'espace de code sur le MCU principal du projet. Ce module d'interface est très économique puisqu'il utilise un petit MCU en format DIP-8 soit le PIC12F1572. Le montage est très simple.

  • 1 MCU PIC12F1572
  • 2 condensateurs céramique 100nF/16v
  • 2 résistances 15Kohm 1/4watt.
  • 1 connecteur MINI-DIN 6 broches pour le clavier. On peut aussi utiliser un connecteur USB type A
Le code source est disponible sur https://github.com/Picatout/ps2_rs232

fonctionnement

Le PIC12F1572 reçoit les codes du clavier et fait la conversion en code ASCII qu'il envoie à l'hôte via le périphérique EUSART configuré en mode asynchrone. l'envoie se fait à 9600BAUD sans parité. Ce module d'interface n’accapare donc qu'un seule broche sur le MCU principal ainsi qu'un périphérique USART pour la réception. Le code à écrire sur l'hôte est des plus simple puisqu'il s'agit simplement de recevoir les codes ASCII et lest ranger dans une file d'attente FIFO pour les besoins de l'application. Les touches d'altérations SHIFT,CTRL,ALT,CAPS,NUM sont traitées par le PIC12F1572. Les relâchement de touches sont ignorés.

quelques notes sur l'utilisation des claviers

Les claviers que j'utilise sont des claviers d'ordinateurs personnels soit de type PS/2 ou USB. Les claviers USB adoptent automatiquement l'interface PS/2 lorsque les lignes DAT+ et DAT- sont connectées à des résistances pullup. Dans ce cas DAT+ devient le signal CLOCK et DAT- devient le signal DATA.

diagramme connection interne d'un adapteur USB-A vers MINI-DIN-6.

Même si les claviers indique une alimentation de 5VDC ceux que j'ai essayés fonctionnent très bien à 3VDC. Ce n'est pas vraiment étonnant puisque le MCU qui se trouve dans le clavier est certainement en technologie CMOS, à moins qu'il s'agisse d'un très vieux clavier.

L'interface PS/2 est une interface synchrone, c'est à dire qu'il y a un signal clock et un signal data. L'hôte doit lire le bit lorsque le signal clock est à zéro volt. C'est le clavier qui contrôle le signal clock. Bien qu'il s'agisse d'une interface synchrone elle peut-être utilisée en mode asynchrone car le signal data a le mêm format qu'un signal RS-232. C'est à dire qu'il y a un start bit à 0 suivit de 8 bits de data, d'un bit de parité impaire et d'un stop bit. Tout les claviers que j'ai essayé transmettait à 12,500 BAUD (une valeur non standard). Cependant si le clavier est utilisé en mode asynchrone l'hôte ne peut lui envoyer des commandes. Car il faut savoir que l'interface PS/2 est à double sens. L'hôte peut prendre le contrôle de l'interface en bloquant la ligne clock à 0 pour une durée minimum de 100µsec. L'interface décrite ici utilise l'interface PS/2 complète, c'est à dire que le PIC12F1572 envoie des commandes au clavier, soit pour le réinitialiser soit pour contrôler les LEDs du clavier.

Autre paramètre à considérer, l'interface fonctionne en mode drain ouvert d'où l'utilisation des 2 résistances pullup. Ceci est intéressant car même si le clavier est alimenter à 5 volt et que le MCU est alimenté à 3 volt il n'y a pas de risque d'endommager le MCU. Le seul courant qui passe vers le MCU hôte passe à travers des résistances pullup qui sont de 15Kohm. Supposons que les deux entrées du MCU sont configurées en entrées. Le courant passe du 5volt à travers la résistance de 15Kohm et à travers la diode de protection d'entré du MCU vers le 3volt. Le courant qui va circulé dans cette diode est donc de (5-3)/15000=133µA. Aucun risque d'endommager la diode de protection.

Les broches du PIC12F1572 sont configurables on mode drain ouvert ce qui rend encore plus sécuritaire l'interface entre le MCU et le clavier. On peut donc alimenter le clavier et les 2 résistances en +5VDC et le MCU en +3VDC sans que ça pose problème.

codes ASCII et supplémentaire

La table ASCII standard est limitée à 128 codes. Il n'y a pas de provision pour les touches spéciales du claviers tel que les touches de fonctions, les flèches, etc. Le firmware du PIC12F1572 convertis ces codes en une série de valeurs comprises entre 128 et 255. Pour connaître la liste de ces touches consulter la page github du projet.

mise à jour 8 janvier 2017

Suite à l'intégration de cette interface dans un projet j'ai apporté des modifications au circuit et au logiciel. Sous MS-DOS lorsque la combinaison de touches <CTRL>+ <ALT>+<DEL> était enfoncée l'ordinateur redémarrait. J'ai ajouté une fonctionnalité à cette interface pour que cette même combinaison résulte en l'envoie d'une impulsion négative de 100µsec sur la broche RA5 du MCU et j'ai nommé ce signal ~REBOOT.

De cette façon l'hôte qui utilise cette interface pourra utilisé ce signal à sa guise. J'ai aussi ajoutée une résistance de 470 ohm entre le condensateur C1 et l'entrée RA3 du PIC12F1572. À la jonction de C1 et de la résistance R3 j'ai ajouté l'étiqette globale ~HRST. Ce signal permet à l'hôte de réinitialiser ce circuit.

Comme j'ai fais ces modifications après coup j'ai du ajouter un connecteur ICSP pour reprogrammer le PIC12F1572. Je l'ai indiqué sur la nouvelle version de la schématique car cet imprévu m'a rappelé qu'il est toujours utile d'inclure un tel connecteur dans un montage. On ne sais jamais quand on aura à faire une reprogrammation en circuit.

J'ai aussi indiqué sur la schématique les 2 options possibles pour le type de connecteur clavier à utiliser.

Nouvelle schématique

mercredi 21 décembre 2016

tetris pad

Il est possible de réaliser des jeux vidéo simple même sur petit MCU qui n'a qui 6 E/S et 3.5Ko de flash et 256 octets de RAM. Ce projet en est la démonstration il s'agit du célèbre jeux tetris inventé en 1986 par Alekseï Pajitnov. Au départ j'ai conçu ce jeux dans la perspective de participer à un défi organisé par http://hackaday.com, le 1KB challenge. Mais j'ai échoué à atteindre l'objectif et je n'ai donc pas soumis le projet. En effet je n'ai pas réussi à réduite la taille du programme pour qu'il réponde au critère du 1KO. Toute la documentation et le code source sont sur github. Puisque ce projet était dédié à un site anglophone exceptionnellement tous les commentaires dans le fichier source sont en anglais. Mais je vais en faire une description dans ce qui suis.

Matériel

Le tetris_pad peut-être réalisé économiquement et rapidement. il y a un minimum de composants.

  • 1 PIC12F1572
  • 1 Oscillateur à crystal de 20Mhz CTS MXO45HST
  • 1 porte pile pour pile CR2450
  • 7 mini boutons poussoir à contact momentanés. Robotshop p/n: RB-DFR-448, 5/pkg
  • 2 embase DIP 8 broches. 1 pour le MCU et l'autre pour l'oscillateur. (optionnel).
  • 1 mini commutateur SPDT. Robotshop p/n RB-SPA-155
  • 1 LED 3mm rouge.
  • 2 connecteur phono RCA
  • 1 connecteur 6 broches espacement 100mil. pour brancher le Pickit 3.
  • 1 transistor 2N700.
  • 1 condensateur électrolytique 220µF/25Volt.
  • 3 condensateurs céramique 100nF/16Volt.
  • 1 condensateur céramique 1µF/16Volt.
  • 7 résistances 1Kohm 1/8 watt.
  • 1 résistance 22Kohm 1/8 watt.
  • 1 résistance 470ohm 1/8 watt.
  • 1 résistance 330ohm 1/4 watt.
  • 1 résistance 180ohm 1/4 watt.
  • 1 résistance 10Kohm 1/8 watt.
  • 1 résistance 100Kohm 1/8 watt.
  • 1 résistance 1Mohm 1/8 watt.
  • 1 résistance 620ohm 1/4 watt.
  • 1 résistance 82ohm 1/4 watt.
  • 1 pile bouton au lithium CR2450.
  • 1 carte de prototypage en bakélite de 7cm x 9cm. Robotshop p/n: RB-ADA-229, 10/pkg

schématique

prototype

Plusieurs des composants sont invisibles sur cette photo car en format CMS et soudés directement sur les pastilles qui se trouvent sur l'autre face de la carte.

code source

Le programme est écris en assembleur et occupe 1051 mots flash (1839 octets)dans sa version actuelle. Le fichier source est tetris.asm. Au début du ficher on retrouve les 2 lignes suivantes:

#define SOUND_SUPPORT
#define ANIMATION
Si la ligne qui défini SOUND_SUPPORT est mise en commentaire le code lié à cette fonction ne sera pas assemblé.
Si le ligne qui défini ANIMATION est mise ne commentaire le code d'animation de fin de parti ne sera pas assemblé. j'espérais en supprimant ces 2 éléments optionnels pouvoir répondre au critère du 1KO mais j'en étais encore très loin à environ 1500 octets.

La majorité des constantes utilisées par le programme sont définies entre les lignes 14 et 96.

la pile des arguments

Lorsque je programme les PIC enhanced mid-range en assembleur j'utilise le registre FSR1 comme pointeur pour une pile de passage des arguments aux sous-routines ainsi que pour les variables locales. Pour faciliter l'utilisation de cette pile je cré un ensemble de macros qui se trouve entre les lignes 153 et 217 du fichier tetris.asm.

Structure du progamme

  1. rst: point d'entrée lors de la réinitialisation du MCU. Cette routine fait un saut vers init: qui s'occupe d'initialiser les périphériques.
  2. isr: point d'entrée de la routine de service des interruptions. Il n'y a qu'une seule interruption sur la minuterie du périphérique PWM responsable de générer la synchronisation vidéo. La routine isr: contient aussi un céduleur de tâches de type round robin. lorsque c'est le temps de générer le signal vidéo cette routine appelle la sous-routine video_serialize: responsable d'envoyer les pixels à l'écran.
  3. init: s'occupe de l'initialisation de tous les périphériques avant de passer à game_init:.
  4. game_init: initialise l'environnement du jeux tetris proprement dit avant de débuter la partie au point d'entrée tetris:
  5. tetris:débute la logique du jeux. le jeux s'exécute en boucle jusqu'à la fin de la partie à l'intérieur de game_loop:
  6. A la fin du fichier sont rassemblées les tables de données enregistrées en mémoire programme. On y retrouve les glyphes des chiffres 0-9 ainsi que des lettres utilisées par les labels, table digits. Les glyphes des tetriminos suivent. Les tables pour les 3 textes apparaissant à l'écran. les valeur de périodes pour la gamme tempéré et finalement la partition de la mélodie korobeiniki. Puisque ce jeux a été inventé en Russie cette mélodie qui appartient à son folklore est appropriée.

utilisation de la console

Notez la disposition des boutons. A droite les 4 boutons disposés en losange. Celui du haut fait tourner le tetrimino vers la droite. Celui du bas le fait tourner dans le sens contraire. Les boutons de gauche et de droite sont pour les déplacements horizontal du tetrimino.

Il y a 2 boutons à gauche du pad. Celui du bas s'appelle A et sert à démarrer la partie. La mélodie korobeiniki est jouée en boucle en attente d'une pression sur de bouton. Le bouton au dessus de A est le bouton B. Il a 2 fonctions. lorsque la mélodie joue ce bouton force le silence. Pendant la partie le bouton B sert à faire tomber rapidement un tetrimino lorsqu'on juge qu'il est bien positionné. On peut aussi avorter rapidement une partie en le gardant enfoncé. Lorsque le puit est plein la partie est terminée. Une animation vide le puit vers le bas avant de présenter le message PRESS A pour une nouvelle partie.

Le pointage est compté en puissance de 2. C'est à dire que faire disparaître:
1 ligne vaut 2 points.
2 lignes 4 points.
3 lignes 8 points.
4 lignes 16 points.
L'affichage indique le pointage et le nombre total de lignes qui ont été détruites durant la partie.

Démonstration

Voici un bref vidéo de démonstration de tetris_pad. A la fin on peut attendre le joueur soupiré face à sa piètre performance.