FreeBSDには、ppi (General-purpose I/O "Geek Port") デバイスを通して、 プリンタポートをパラレルポートとして使う仕組みが備わっています。これを利用すると、
コネクタは、25pin D-subコネクタが採用されています。
| pin | i/o | name |
|---|---|---|
| 1 | O | /STROBE |
| 2-9 | I/O | DATAn |
| 10 | I | /ACK |
| 11 | I | BUSY |
| 12 | I | PE |
| 13 | O | SLCTIN |
| 14 | O | /AUTOFEEDXT |
| 15 | I | /ERROR |
| 16 | O | /INIT |
| 17 | O | /SLCTIN |
| 18-25 | -- | GND |
各信号の特性を、OADGテクニカルリファレンスより、引用します。
データ信号、割込み信号、制御信号の特性を示します。
Sink Current 12 mA Maximum Source Current 2 mA Maximum High-level Output Voltage 2.4 V dc Minimum Low-level Output Voltage 0.5 V dc Maximum
ピン1, 14, 16, および17はオープンドレインドライバーによってドライブされ、4.7kΩの抵抗によってDC 5Vにプルアップされています。
Sink Current 10 mA Maximum Source Current 0.2 mA Maximum High-level Output Voltage 5.0 V dc Minimum Low-level Output Voltage 0.5 V dc Maximum
カーネルソースを展開しておきます。
カーネルに、ppi パラレルポートインターフェースが組み込まれていることを確認します。
device ppc0 at isa? irq 7 device ppbus # Parallel port bus (required) device ppi # Parallel port interface device
使用するポートは3つあり、それぞれ以下のようになっています。
PPIxCTRL
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
| -- | -- | dir | irq | /SLCTIN | INIT | /AUTOFEEDXT | /STROBE |
PPIxSTATUS
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
| /BUSY | ACK | PE | SLCT | ERROR | (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の使用は控えるべきです。