Vengono ora fornite delle informazioni per la programmazione delle porte più comuni che possono essere usate per l'I/O delle logiche TTL (o CMOS) per scopi generici.
Se si vogliono usare queste o altre porte per il loro scopo originale (cioè controllare una normale stampante o un modem), sarebbe meglio usare i driver esistenti (che, di solito, sono inclusi nel kernel), piuttosto che programmare direttamente le porte come descritto in questo HOWTO. Questa sezione è indirizzata a quelli che vogliono connettere alle porte standard di un PC degli schermi LCD, dei motori passo passo, o altri componenti specifici.
Se si desidera controllare un dispositivo di largo uso, come uno scanner (che è sul mercato già da un pò), cercate se c'è già un driver di Linux che lo riconosce. L' Hardware-HOWTO è un buon posto da cui iniziare la ricerca.
http://www.hut.fi/Misc/Electronics/ è una buona fonte di informazioni sulla connessione di dispositivi ai computer (e sull'elettronica in generale).
L'indirizzo base della porta parallela (detto "BASE
" nel seguito)
è 0x3bc per /dev/lp0
, 0x378 per /dev/lp1
e 0x278 per
/dev/lp2
. Per controllare qualcosa che si comporta come una
normale stampante, vedere il
Printing-HOWTO.
Nella maggior parte delle porte parallele, oltre al modo standard di sola scrittura descritto di seguito, esiste un modo bidirezionale "esteso". Per maggiori informazioni su tale argomento e sui nuovi modi ECP/EPP, vedere http://www.fapo.com/ e http://www.senet.com.au/~cpeacock/parallel.htm. Ricordare che poiché non è possibile usare gli IRQ o il DMA in un programma che gira in modo utente, per usare ECP/EPP probabilmente sarà necessario scrivere un driver per il kernel. Credo che qualcuno stia già scrivendo un tale driver, ma non conosco i dettagli della cosa.
La porta BASE+0
(porta dati) controlla i segnali dei dati della porta
(da D0 a D7 per i bit da 0 a 7, rispettivamente; stati: 0 = basso (0 V),
1 = alto (5 V)). Una scrittura su tale porta fissa i dati sui pin. Una
lettura restituisce i dati che sono stati scritti per ultimi, in modo
standard (oppure esteso), oppure restituisce i dati provenienti dai pin di
un altro dispositivo che lavora in modalità di lettura estesa.
La porta BASE+1
(porta di Stato) è di sola lettura e restituisce
lo stato dei seguenti segnali d'ingresso:
La porta BASE+2
(porta di Controllo) è di sola scrittura (una
lettura restituisce l'ultimo dato scritto) e controlla i seguenti segnali
di stato:
Configurazione dei pin (connettore a "D" femmina a 25-pin sulla porta) (i = input, ingresso; o = output, uscita):
1io -STROBE, 2io D0, 3io D1, 4io D2, 5io D3, 6io D4, 7io D5, 8io D6,
9io D7, 10i ACK, 11i -BUSY, 12i PE, 13i SLCT, 14o -AUTO_FD_XT,
15i ERROR, 16o INIT, 17o -SLCT_IN, 18-25 Ground
Le specifiche IBM dicono che i pin 1, 14, 16 e 17 (le uscite di controllo) hanno i driver dei collettori aperti connessi a 5 V attraverso resistori da 4.7 kohm (pozzo 20 mA, fonte 0.55 mA, uscita a livello alto pari a 0.5 V meno il pullup). I rimanenti pin hanno il pozzo a 24 mA, la fonte a 15 mA, e la loro uscita a livello alto è di 2.4 V (minimo). Per entrambi, lo stato basso è di 0.5 V (massimo). Le porte parallele non IBM probabilmente si discostano da questo standard. Per maggiori informazioni a tal riguardo vedere http://www.hut.fi/Misc/Electronics/circuits/lptpower.html.
In ultimo un avvertimento: attenzione con i collegamenti a massa. Personalmente ho rotto diverse porte parallele collegandoci qualcosa mentre il computer era acceso. Per giochetti del genere sarebbe buona cosa usare una porta parallela che non sia integrata sulla piastra madre. (Di solito è possibile ottenere una seconda porta parallela, per la propria macchina, tramite una economica e standard scheda "multi-I/O"; basta disabilitare le porte di cui non si ha bisogno e impostare l'indirizzo I/O della porta parallela sulla scheda ad un indirizzo libero. Non è necessario conoscere l'IRQ della porta parallela se non lo si usa.)
La porta giochi è situata agli indirizzi 0x200-0x207. Per controllare i normali joystick è probabilmente meglio usare i driver distribuiti con il kernel di Linux.
Configurazione dei pin (connettore a "D" femmina a 15 pin):
I pin +5 V sembra che siano spesso collegati direttamente alle linee di alimentazione sulla scheda madre, quindi dovrebbero poter fornire un bel pò di potenza, a seconda della scheda madre, dell'alimentatore e della porta giochi.
Gli ingressi digitali sono usati per i pulsanti dei due joystick (joystick A e joystick B, con due pulsanti ciascuno) collegabili alla porta. Dovrebbero usare i normali livelli d'ingresso TTL ed è possibile leggerne lo stato direttamente dalla porta di stato (vedere sotto). Quando il pulsante è premuto, il joystick restituisce uno stato basso (0 V), altrimenti restituisce uno stato alto (i 5 V del pin dell'alimentazione attraverso un resistore di 1 kohm).
I cosìdetti ingressi analogici in effetti misurano una resistenza. La porta giochi ha un quadruplo multivibratore monostabile (un chip 558) collegato ai quattro ingressi. Ad ogni ingresso, fra il pin di ingresso e l'uscita del multivibratore, c'è un resistore da 2.2 kohm e, fra l'uscita del multivibratore e la massa, c'è un condensatore di temporizzazione pari a 0.01 uF. Il joystick è dotato di un potenziometro per ogni asse (X e Y), connesso fra +5 V e l'appropriato pin d'ingresso (AX o AY per il joystick A, oppure BX o BY per il joystick B).
Il multivibratore, quando attivato, imposta alte (5 V) le sue linee di uscita ed aspetta che ogni condensatore di temporizzazione raggiunga i 3.3 V prima di abbassare le rispettive linee di uscita. Così facendo, la durata dello stato alto del multivibratore sarà proporzionale alla resistenza del potenziometro nel joystick (cioè alla posizione della leva sull'asse corrispondente), secondo la relazione:
R = (t - 24.2) / 0.011,dove R è la resistenza (in ohm) del potenziometro e t la durata dello stato alto (in microsecondi).
Quindi, per leggere gli ingressi analogici, bisogna prima attivare il multivibratore (con una scrittura sulla porta; vedere sotto), poi controllare (con letture ripetute della porta) lo stato dei quattro assi finché non scendono dallo stato alto a quello basso, e quindi misurare la durata del loro stato alto. Tale controllo richiede abbastanza tempo di CPU e, su di un sistema multitasking non in real time come Linux (in modo utente normale), il risultato non è molto preciso perché non è possibile controllare costantemente la porta (a meno che si usi un driver a livello di kernel e si disabilitino gli interrupt durante il controllo; ma così si spreca ancor più tempo di CPU). Se si sa che il segnale impiegherà parecchio tempo (decine di ms) per tornare basso, si può chiamare usleep() prima di cominciare il controllo, regalando così quel tempo di CPU ad altri processi.
La sola porta di I/O a cui serve di accedere è la porta 0x201 (le altre porte o si comportano allo stesso modo, o non fanno nulla). Qualsiasi scrittura su questa porta (non importa cosa si scrive) attiva il multivibratore. Una lettura da questa porta restituisce lo stato dei segnali di ingresso:
Se il dispositivo d'interesse supporta qualcosa che somiglia alla RS-232, dovrebbe essere possibile usare la porta seriale per comunicare con esso. Il driver di Linux per le porte seriali dovrebbe andar bene per la maggior parte delle applicazioni (non è necessario programmare direttamente la porta seriale, per farlo, probabilmente, bisognerebbe scrivere un driver per il kernel); è piuttosto versatile e quindi, usando velocità di trasmissione (b/s) non standard, o cose del genere, non dovrebbero esserci problemi.
Per maggiori informazioni sulla programmazione delle porte seriali sui
sistemi Unix, vedere la pagina di man di termios(3)
, il codice
sorgente del driver per la porta seriale
(linux/drivers/char/serial.c
) e
http://www.easysw.com/~mike/serial/.