Voici quelques informations utiles pour la programmation des ports les plus utilisés. Ces ports peuvent être directement interfacés avec une électronique logique de type TTL (ou CMOS).
Si vous avez l'intention d'utiliser ces ports ou des ports classiques en vue d'applications pour lesquels ils ont été conçus (par exemple pour contrôler une imprimante ou un modem ordinaire), vous auriez intérêt à utiliser les pilotes déjà existants (qui sont généralement inclus dans le noyau) plutôt que de programmer directement les ports comme décrit dans ce document. Cette section s'adresse principalement aux personnes désireuses de connecter aux ports d'entrée / sortie standards de leur PC des écrans à cristaux liquides, des moteurs pas-à-pas ou d'autres montages électroniques faits maison.
En revanche, si votre but est de piloter un périphérique grand public, tel qu'un scanner, disponible sur le marché depuis quelques temps déjà, essayez plutôt de savoir si un pilote a déjà été développé. Le Hardware-HOWTO est un bon point de départ pour mener cette investigation.
http://www.hut.fi/Misc/Electronics/ est également une excellente source d'information sur la connexion de périphériques à un ordinateur et sur l'électronique en générale.
L'adresse de base du port parallèle (appelée BASE ci-dessous) est 0x3bc pour /dev/lp0, 0x378 pour /dev/lp1 et 0x278 pour /dev/lp2. Si vous souhaitez piloter un matériel fonctionnant comme une imprimante classique, voyez le Printing-HOWTO.
En plus du mode standard d'écriture-seule décrit ci-dessous, il existe un mode « étendu » bidirectionnel sur la plupart des ports parallèles. Pour des informations à ce sujet ainsi que sur les récents modes ECP / EPP (et le standard IEEE 1284 en général), voici deux adresses : http://www.fapo.com/ et http://www.beyondlogic.org/. Rappelez-vous cependant que puisque vous ne pouvez pas utiliser les requêtes d'interruptions (IRQ) ou l'accès DMA dans un programme en mode utilisateur, vous serez certainement obligé d'écrire un pilote pour le noyau afin d'exploiter les modes ECP / EPP. Il me semble que quelqu'un est déjà en train de développer un tel pilote, mais je n'en sais pas plus à ce sujet.
Le port BASE+0 (port de données) contrôle les signaux de données du port (respectivement D0 à D7 pour les bits 0 à 7; états : 0 = bas (0V), 1 = haut (5V)). Une écriture sur ce port positionne l'état des broches correspondantes. La lecture retourne la dernière valeur écrite en mode standard ou étendu, sinon les données présentes sur les broches connectées à un autre périphérique en mode de lecture étendue.
Le port BASE+1 (port d'état) est en lecture seule et retourne l'état des signaux d'entrée suivants :
Bits 0 et 1 sont réservés.
Bit 2 état d'IRQ (ne correspond pas à une broche, je ne sais pas comment il fonctionne)
Bit 3 ERROR (1 = état haut)
Bit 4 SLCT (1 = état haut)
Bit 5 PE (1 = état haut)
Bit 6 ACK (1 = état haut)
Bit 7 -BUSY (0 = état haut)
Le port BASE+2 (port de contrôle) est en écriture seule (une lecture sur celui-ci retourne la dernière valeur écrite) et contrôle les signaux d'état suivants :
Bit 0 -STROBE (0 = état haut)
Bit 1 -AUTO_FD_XT (0 = état haut)
Bit 2 INIT (1 = état haut)
Bit 3 -SLCT_IN (0 = état haut)
Bit 4 active la requête d'interruption (IRQ) du port parallèle (qui survient lors d'une transition bas-vers-haut de la broche ACK) lorsqu'il est positionné à 1.
Bit 5 contrôle la direction du mode étendu (0 = écriture, 1 = lecture) et est en écriture seule (une lecture sur ce bit ne retournera pas de valeur significative).
Bits 6 et 7 sont réservés.
Brochage (d'un connecteur femelle sub-D 25 sur le port) (e = entrée, s = sortie) :
1(e/s) -STROBE, 2(e/s) D0, 3(e/s) D1, 4(e/s) D2, 5(e/s) D3, 6(e/s) D4, 7(e/s) D5, 8(e/s) D6, 9(e/s) D7, 10(e) ACK, 11(e) -BUSY, 12(e) PE, 13(e) SLCT, 14(s) -AUTO_FD_XT, 15(e) ERROR, 16(s) INIT, 17(s) -SLCT_IN, 18-25 masse |
Les spécifications données par IBM indiquent que les broches 1, 14, 16 et 17 (les sorties de contrôle) sont de type collecteur ouvert ramené à 5,0 V au moyen d'une résistance de 4,7 kohm (intensité de fuite de 20 mA, de source 0,55 mA, état haut de sortie 5,0 V moins tension de pull-up). Le reste des broches ont une intensité de fuite de 24 mA, de source de 15 mA et leur voltage à l'état haut est au minimum de 2,4 V. L'état bas pour toutes les broches est au maximum de 0,5 V. Les ports parallèles d'autres types que celui d'IBM peuvent s'écarter de ce standard. Pour plus d'informations à ce sujet, voyez l'adresse : http://www.hut.fi/Misc/Electronics/circuits/lptpower.html.
Faites très attention aux masses ! J'ai déjà grillé à plusieurs reprises des ports parallèles en les connectant alors que l'ordinateur était sous tension. Utiliser un port parallèle non intégré à la carte mère peut s'avérer une bonne solution pour éviter de trop grands désagréments. Vous pouvez obtenir un second port parallèle pour votre machine au moyen d'une carte multi-entrées / sorties à petit prix. Il vous suffit de désactiver les ports dont vous n'avez pas besoin, puis de configurer le port parallèle de la carte sur une adresse libre. Vous n'avez pas besoin de vous préoccuper de l'IRQ du port parallèle si vous n'y faites pas appel. |
Le port de manette de jeu est accessible aux adresses 0x200-0x207. Si vous souhaitez contrôler une manette de jeu ordinaire, vous serez probablement mieux servi en utilisant les pilotes distribués avec le noyau.
Brochage (pour un connecteur sub-D 15 femelle) :
1,8,9,15 : +5 V (Alimentation)
4,5,12 : masse
2,7,10,14 : entrées numériques, respectivement BA1, BA2, BB1 et BB2
3,6,11,13 : entrées « analogiques », respectivement AX, AY, BX et BY
Les broches fournissant une tension de +5 V semblent souvent être connectées directement sur l'alimentation de la carte mère, ce qui peut leur permettre d'obtenir pas mal de puissance, en fonction de la carte mère, du bloc d'alimentation et du port de manette de jeu.
Les entrées numériques sont utilisées pour les boutons des deux manettes de jeu (manette A et manette B, avec deux boutons chacune) que vous pouvez connecter au port. Ces entrées devraient être de niveau TTL classique, ainsi vous pouvez lire directement leurs valeurs sur le port d'état (voir plus bas). Une véritable manette de jeu retourne un état bas (0 V) lorsque le bouton est pressé et un état haut dans l'autre cas (une tension de 5 V des broches de d'alimentation au travers d'une résistance de 1 kohm).
Les pseudo entrées analogiques mesurent en réalité la résistance. Le port de manette de jeu comporte un quadruple monostable (une puce de type NE558) connecté aux quatre entrées. Pour chaque entrée, il y a une résistance de 2,2 kohm entre la broche d'entrée et la sortie du monostable, et un condensateur de 0,01 µF entre la sortie du monostable et la masse. Une véritable de manette de jeu a un potentiomètre pour chaque axe (X et Y), connecté entre le +5 V et la broche d'entrée appropriée (AX ou AY pour la manette A, ou BX ou BY pour la manette B).
Lorsqu'il est activé, le monostable initialise ses lignes de sortie à un état haut (5 V) et attend que chaque condensateur de temporisation atteigne une tension de 3,3 V avant de mettre la sortie correspondante à un état bas. La durée de l'état haut de la sortie du temporisateur est proportionnelle à la résistance du potentiomètre de la manette de jeu (en clair, la position du manche de la manette de jeu de l'axe approprié) comme expliqué ci-dessous :
R = (t - 24.2) / 0.011
où R est la résistance en ohm, du potentiomètre et t la durée de l'état haut de la sortie, en microsecondes.
Pour effectuer une lecture sur les entrées analogiques, vous
devez tout d'abord activer le monostable (au moyen d'une
écriture sur le port, voir plus bas), puis scruter l'état des
quatre axes au moyen de lectures répétées jusqu'à la transition
à un état bas, permettant ainsi de mesurer la durée de l'état
haut. Cette scrutation est très gourmande en temps machine. De
plus, sur un système multitâche non temps-réel tel que Linux (en
mode utilisateur normal) le résultat n'est pas très précis, du
fait de l'impossibilité de scruter le port constamment (à moins
d'utiliser un pilote noyau et de désactiver la gestion des
interruptions pendant la scrutation, mais sachez que vous
consommerez encore plus de temps machine). Si vous savez à
l'avance que le signal va mettre un certain temps (plusieurs
dizaines de millisecondes) avant de basculer, vous pouvez faire
appel à usleep()
avant de procéder à la
scrutation afin de laisser un peu de temps machine aux autres
processus.
Le seul port d'entrées / sorties auquel vous avez besoin d'accéder est le port 0x201 (les autres ports se comportent de façon identique ou ne réagissent pas). Toute écriture sur ce port, peu importe la valeur envoyée, active le temporisateur. Une lecture retourne l'état des signaux d'entrée :
Bit 0 : AX (état de la sortie du temporisateur, 1 = état haut)
Bit 1 : AY (état de la sortie du temporisateur, 1 = état haut)
Bit 2 : BX (état de la sortie du temporisateur, 1 = état haut)
Bit 3 : BY (état de la sortie du temporisateur, 1 = état haut)
Bit 4 : BA1 (entrée numérique, 1 = état haut)
Bit 5 : BA2 (entrée numérique, 1 = état haut)
Bit 6 : BB1 (entrée numérique, 1 = état haut)
Bit 7 : BB2 (entrée numérique, 1 = état haut)
Si le périphérique avec lequel vous communiquez est à peu près compatible avec le standard RS-232, vous devriez être en mesure d'utiliser pour cela le port série. Le pilote série du noyau Linux devrait suffire pour la plupart des applications (vous ne devriez pas avoir à programmer le port directement, de plus vous devriez probablement écrire un pilote pour le noyau si vous souhaitiez le faire), il est en effet très polyvalent et l'usage de débits non-standards ne devrait pas poser de problèmes particuliers.
Voyez la page de manuel de termios(3), le code source du pilote (linux/drivers/char/serial.c) ainsi que la page http://www.easysw.com/~mike/serial/ pour plus d'informations sur la programmation des ports séries des systèmes Unix.