Teraz trochę informacji programistycznych dotyczących zwykłych portów które mogą być bezpośrednio użyte do operacji I/O w logice TTL (lub CMOS).
Jeśli chcesz używać tych lub innych zwykłych portów zgodnie z ich normalnym przeznaczeniem (np chcesz sterować normalną drukarką bądź modemem) powinieneś najpewniej użyć istniejących sterowników (zwykle dołączonych do jądra) zamiast programować porty bezpośrednio jak to opisuje ten dokument. Ten rozdział jest dla tych którzy chcą podłączyć do standardowych portów komputera wyświetlacze LCD, silniki krokowe lub inne niestandardowe urządzenia elektroniczne.
Jeśli chcesz sterować jakimś urżądzeniem produkowanym na rynek masowy, np. skanerem (które to urządzenie jest już na rynku jakiś czas) poszukaj raczej istniejącego sterownika Linuxowego. Dobrym miejscem aby zacząć jego poszukiwania jest Hardware-HOWTO
www.hut.fi/Misc/Electronics jest dobrym źródłem informacji dotyczących podłączania urządzeń do komputera (jak i samej elektroniki w ogóle)
Adres bazowy portu równoległego (zwany poniżej >BASE) to
0x3bc dla /dev/lp0, 0x378 dla /dev/lp1 i 0x278 dla /dev/lp2.
Jeśli chcesz sterować tylko czymś co działa jak normalna drukarka powinieneś
zapoznać się z
Printing-HOWTO.
Oprócz standardowego trybu tylko-do-zapisu opisanego powyżej, w większości portów równoległych istnieje jeszcze rozszeżony tryb dwukierunkowy. Po informacje na ten temat oraz na temat nowych trybów ECP/EPP (jak i samego standardu IEEE 1284 w ogóle) zajrzyj na http://www.fapo.com oraz na http://www.senet.com.au/~cpeacock/parallel.htm Pamiętaj, że skoro nie możesz używać DMA i IRQ w programach użytkownika, aby użyć trybów ECP/EPP będziesz prawdopodobnie musiał napisać własny sterownik do jądra. Zdaje się, że ktoś już pisze taki sterownik ale nie znam szczegółów.
Port BASE+0 (port danych) kontroluje sygnały danych portu (D0 do D7 dla bitów od 0 do 7)
Stany: 0=niski (0 V), 1=wysoki (5 V). Zapis do tego portu zatrzaskuje dane na pinach.
Odczyt zwraca ostatnio zapisaną daną w trybie normalnym bądź rozszeżonym lub dane z innego
urządzenia w rozszeżonym trybie odczytu.
Port BASE+1 (port statusu) jest tylko-do-odczytu i zwraca stan poniższych sygnałów
wejsciowych.
Port BASE+2 (Port kontrolny) jest tylko do zapisu (odczyt zwraca ostatnio zapisaną wartość)
i kontroluje poniższe sygnały kontrolne:
Rozkład wyprowadzeń. (25 pinowe żeńskie gniazdo typu D) (i=wejscie, o=wyjscie):
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
Specyfikacja IBM twierdzi że piny 1,14,16 i 17 (wyjscia kontrolne) mają otwarte kolektory podpięte do +5V przez 4.7 kiloomowe oporniki (dostarcza 20 mA, pobór 0.55 mA, wyjscie w stanie wysokim +5V minus to co podpięte) Reszta pinów pobiera 24 mA, dostarcza 15 mA a wyjscie w stanie wysokim to minimum 2.4V. Stan niski dla wszystkich to maximum 0.5V. Porty równoległe inne niż IBM prawdopodobnie odbiegają od tego standardu. Po więcej informacji na ten temat zajrzyj na http://www.hut.fi/Misc/Electronics/circuits/lptpower.html
Na koniec jeszcze ostrzeżenie: Uważaj z uziemieniem. Zepsułem już parę portów przez podłączanie się do nich gdy komputer był włączony. Dobrze jest w takim wypadku używać portów równoległych nie zintegrowanych z płytą główną (zwykle można dodać drugi port równoległy do komputera za pomocą taniej standardowej karty I/O (tzw ajołki - tłum); po prostu wyłącz porty których nie potrzebujesz i ustaw adres portu na karcie IO na jakiś wolny adres. Nie musisz się martwić o IRQ dla portu równoległego gdyż normalnie się go nie używa)
Port gier jest umieszczony pod adresami 0x200-0x207. Jeśli chcesz kontrolować normalny joystick to jest do tego specjalny sterownik w jądrze, zobacz ftp://sunsite.icm.edu.pl/sunsite/pub/Linux/kernel/patches Plik nazywa się joystick-*.
Rozkłąd wyprowadzeń od stony portu (15-pinowe żeńskie gniazdo typu D-shell):
Piny +5V zwykle są podłączane bezpośrednio do linii zasilania na płycie głównej, więc, w zależności od płyty, zasilacza i portu ,powinny dawać całkiem sporo mocy. Cyfrowe wejścia są używane dla przycisków joysticków które możesz sobie podłączyć do portu (joystick A i B, dwa przyciski każdy) Wejścia te powinny być na poziomach TTL a ich stan możesz odczytać z portu statusu (zobacz poniżej) Prawdziwy joystick zwraca stan niski (0V) kiedy przycisk jest naciśnięty a stan wysoki (+5V z pinów zasilających przez jednokiloomowy rezystor) kiedy jest zwolniony.
Tak-zwane wejścia analogowe w istocie mierzą opór. Port joysticka ma przyłączony do tych 4 wejść poczwórny multiwibrator (quad one-shot multivibrator) (scalak 558) Na każdym wejściu mamy rezystor 2.2k pomiędzy pinem a wejściem multiwibratora oraz kondensator 0.01uF pomiędzy wyjściem multiwibratora a masą. Prawdziwy joystick ma jeszcze potencjometr dla każdej z osi (X i Y) umieszczony pomiędzy +5V a właściwym pinem wejsćiowym (AX lub AY dla joysticka A oraz BX lub BY dla joysticka B)
Kiedy jest aktywny, multiwibrator ustawia swoje wyjścia w stan wysoki (5V) i oczekuje aż każdy z kondensatorów osiągnie 3.3V po czym ustawia w stan niski odpowiednie linie wyjściowe. Dlatego właśnie czas trwania okresu kiedy multivibrator jest w stanie wysokim jest proporcjonalny do oporu potencjometru joysticka. (czyli pozycji joysticka na odpowiedniej osi) Relacja wygląda tak:
R = (t - 24.2) / 0.011,gdzie R to opór potencjometru w omach a t to czas trwania stanu wysokiego w sekundach.
Wobec tego aby odczytać wejśćia analogowe musisz najpierw uaktywnić multiwibrator (za pomocą zapisu do odpowiedniego portu - patrz niżej) po czym odczytywać stan czterech osi (za pomocą następujących po sobie odczytów z portów) aż zmienią stan z wysokiego na niski po czym mierzysz czas trwania stanu wysokiego. Odczytywanie takie zużywa sporo czasu procesora, co w systemie wielozadaniowym takim jak Linux nie będącym systemem czasu rzeczywistego powoduje niedokłądność rezultatów gdyż nie można odczytywać portu stale (chyba że użyjesz sterownika niskopoziomowego i wyłączysz przerwania na czas odczytów - ale to zabiera jeszcze więcej czasu procesora). Jeśli wiesz że przejście do stanu niskiego zajmie sygnałowi dłużśzy czas (rzędu 10 ms) możesz użyć usleep() przed odczytem oddając w ten sposób czas procesora innym procesom.
Jedynym portem do którego potrzebujesz mieć dostęp to port 0x201 (inne porty zachowują się identycznie bądź nie robią nic). Każdy zapis (nie ważne czego) do tego portu uaktywnia multiwibrator. Odczyt z tego portu zwraca stan poszczególnych sygnałów wejściowych.
Jeśli urządzenie z którym się komunikujesz przypomina coś co działą jak RS-232 możęsz do tego celu użyć portu szeregowego. Linuxowy sterownik portu szeregowego powinien wystarczyć w prawie wszystkich zastosowaniach (nie powinienneś mieć potrzeby programować port bezpośrednio, a nawet jeśli chciałbyś to robić prawdopodobnie musiałbyś napisać własny moduł do jądra.) Sterownik Linuxowy jest całkiem wszechstronny a więc używanie na przykład niestandardowych prędkości portu nie powinno być problemem.
Jeśli chcesz dowiedzieć się więcej o programowaniu portu szeregowego w Linuxie
zobacz stronę termios(3) w podręczniku systemowym man, źródła sterownika (linux/drivers/char/serial.c), i
http://www.easysw.com/~mike/serial/index.html.