プリンタポートを使ったパラレル入出力

FreeBSDには、ppi (General-purpose I/O "Geek Port") デバイスを通して、 プリンタポートをパラレルポートとして使う仕組みが備わっています。これを利用すると、

が、簡単にできます。

ハードウェアの仕様

コネクタは、25pin D-subコネクタが採用されています。
pini/oname
1O/STROBE
2-9I/ODATAn
10I/ACK
11IBUSY
12IPE
13OSLCTIN
14O/AUTOFEEDXT
15I/ERROR
16O/INIT
17O/SLCTIN
18-25--GND

各信号の特性を、OADGテクニカルリファレンスより、引用します。

データ信号、割込み信号、制御信号の特性を示します。
Sink Current12 mAMaximum
Source Current2 mAMaximum
High-level Output Voltage2.4 V dcMinimum
Low-level Output Voltage0.5 V dcMaximum

ピン1, 14, 16, および17はオープンドレインドライバーによってドライブされ、4.7kΩの抵抗によってDC 5Vにプルアップされています。
Sink Current10 mAMaximum
Source Current0.2 mAMaximum
High-level Output Voltage5.0 V dcMinimum
Low-level Output Voltage0.5 V dcMaximum

準備

カーネルソースを展開しておきます。
カーネルに、ppi パラレルポートインターフェースが組み込まれていることを確認します。

   device          ppc0    at isa? irq 7
   device          ppbus           # Parallel port bus (required)
   device          ppi             # Parallel port interface device

ポート

使用するポートは3つあり、それぞれ以下のようになっています。

PPIxDATA
データビットの入出力データ
PPIxCTRL
コントロールビットの出力 (SLCTIN, INIT, AUTOFEEDXT, STROBE)
PPIxSTATUS
ステータスビットの入力 (BUSY, ACK, PE, SLCT, ERROR)

PPIxCTRL
bit7bit6bit5bit4bit3bit2bit1bit0
----dirirq/SLCTININIT/AUTOFEEDXT/STROBE
dirは、データポートを入力にするか出力にするかを指定します。0で出力です。
irqは、ACK信号で割り込みをかけるための機能ですが、使わないので0を指定しておきます。
なぜか論理が、ハードウェアの仕様欄と違います。実験した結果、ソフトウェア的な0/1と実際の出力値の対応は、このようになっていました。

PPIxSTATUS
bit7bit6bit5bit4bit3bit2bit1bit0
/BUSYACKPESLCTERROR(IRQ status)----

サンプルプログラム

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <dev/ppbus/ppi.h>

int main()
{
    int fd;
    u_int8_t ct, dt, st;

    if( (fd = open( "/dev/ppi0", O_RDWR )) < 0 )
    {
        perror( "" );
        exit( 1 );
    }

    ct = 0x0b;                     /* ポートを出力に設定 */
    ioctl( fd, PPISCTRL, &ct );

    dt = 0x00;                     /* 出力データ 全ビット0 */
    ioctl( fd, PPISDATA, &dt );

    ioctl( fd, PPIGSTATUS, &st );  /* STATUS 読み込み */
    printf( "%x\n", st );

    close( fd );
    return 0;
}

サンプルハードウェア

リレー駆動回路

スイッチ入力

注意点

ポートに出力される初期値は、BIOSや OSの probeルーチンにより変わり、 電源を入れて自分のプログラムが動きはじめるまでは、 意図しない値が出力される可能性があります。
実験により安全な初期値が確認されたとしても、 たとえばマシンを入れ換えたときなどは、全く違った状態になりえます。 そのような動作が好ましくない場合(たとえば、危険を伴う場合)、 専用のパラレルIOボードを使用し、ppiの使用は控えるべきです。