Programação de periféricos
Seminário - Porta Paralela

Hugo Schmitt



Introdução

As portas paralelas foram originalmente desenvolvidas pela IBM para conectar uma impressora no PC. Quando a IBM estava projetando o PC, queria um modo de fazer com que o computador funcionasse com as impressoras oferecidas pela Centronics, que era um dos maiores fabricantes de impressoras na época. No entanto, a IBM decidiu não usar a mesma interface no computador que a Centronics usava na impressora.
Os engenheiros da IBM então uniram um conector de 25 pinos (DB-25) com o conector Centronics de 36 pinos criando um cabo especial para conectar a impressora no computador.
Quando a IBM lançou o PC, em 1981, a porta paralela foi incluída como uma alternativa para a porta serial (que era então mais lenta), para que se pudesse aproveitar melhor as impressoras matriciais de última geração. A vantagem desta é que pode transmitir 8 bits enquanto a porta serial transmitia apenas um. 




A figura abaixo mostra a pinagem da porta paralela original da IBM (conector fêmea)




São 5 pínos de status, 4 pinos de controle e 8 pinos de dados. Os outros pinos estão todos em GND (aterrados).

- Os pinos de Controle são usadas para controle (!!!) e sinais de handshake do PC para impressora.
- Os pinos de Status são usados para sinais de handshake e para indicar eventos como falta de papel, impressora ocupada ou outros erros.
- Os pinos de Dados são usados para transmitir dados, somente do PC para a impressora, originalmente.

Endereços das portas

A IBM definiu três endereços padrão para as portas (no espaço de endereçamento de I/O 80x86)

A porta paralela possui três endereços que são normalmente usados. 

    3BCh - 3BFh
    378h - 37Fh
    278h - 27Fh
O endereço 3BCh foi originalmente criado para portas paralelas das primeiras placas de vídeo.
Este endereço sumiu por um tempo, quando as portas paralelas foram removidas das placas de vídeo, e depois reapareceu como uma opção para portas paralelas integradas na placa mãe, de modo que a sua configuração pode ser mudada na BIOS.
Normalmente, o LPT1 é determinado com endereço-base 378h, e LPT2 em 278h.
Antes de tentar escrever nestes endereços, convém checá-los na BIOS se é assim mesmo que estão definidos.


Transferência de dados


Centronics handshake


A maioria das impressoras usa este handshake para transferir dados. Ele é normalmente implementado usando uma SPP com controle via software.
    Obs: Como com o tempo várias versões melhoradas apareceram - PS/2 (
1987), EPP, ECP - então a porta original é referida com SPP  (Standard Parallel Port).
Um pino ligado, ou em 1, significa que tem uma tensão de 2.8 a 5 volts. Um pino desligado, ou em 0, tem uma tensão de 0 a 0.6 volts.

Abaixo está um diagrama simplificado do protocolo:

Os dados são escritos nos pinos de 2 a 9.  O servidor então checa se a impressora não está ocupada. O software então seta o strobe para 1, espera no mínimo de 1 microsegundo, e então seta-o para 0.
Os dados normalmente são lidos pela impressora/periférico na borda de subida do strobe.
A impressora então indicará que está ocupada pelo pino de Busy. Tendo aceitado o dado, a impressora irá confirmar o byte com um pulso de aproximadamente 5 microsegudos no pino nAck.
Note que frequentemente o servidor irá ignorar o sinal nAck para ganhar tempo.

As portas ECP e EPP transferem dados cada uma de um modo diferente, com seus próprios handshakes etc.

Nas portas ECP, haverá o Fast Centronics Mode, que permite que o hardware faça todo o handshaking "automaticamente": tudo que o programador tem que fazer é escrever um byte de dados na porta de I/O. O hardware irá checar se a impressora está ocupada e gerar o strobe. Este modo normalmente também não checa o nAck.

EPP & ECP

A Enhanced Parallel Port (EPP) foi criada pela Intel, Xircom e Zenith em 1991. A EPP permite que muito mais dados, 500 kilobytes a 2 megabytes, sejam transferidos a cada segundo. Foi projetada tendo em vista periféricos que não a impressora, como por exemplo, dispositivos de armazenamento de alta performance.


Pouco tempo após a criação da ECP, a Microsoft e a Hewlett Packard juntamente anunciaram uma especificação chamada Extended Capabilities Port (ECP) em 1992. Enquanto que a EPP era apropriada para outros dispositivos, a ECP foi planejada para possibilitar velocidade e funcionalidades melhoradas às impressoras.

Padronização

Em 1991 houve uma reunião entre os fabricantes de impressoras (IBM, Lexmark, Texas...) para discutir um novo padrão para controlar impressoras via rede. Esses fabricantes formaram a Network Printing Alliance (NPA), que definiu uma série de parâmetros que, quando implementados tanto na impressora como no servidor, permitiriam controle total das aplicações e tarefas de impressão.
Enquanto procediam com este trabalho, logo ficou aparente que para implementar completamente este padrão, necessitariam de uma conexão bi-direcional de alta performance com o PC. O modo mais comum de conexão, a Porta Paralela, não tinha as capacidades necessárias para isto.
A NPA então submeteu uma proposta ao IEEE para a criação de um comitê para desenvolver uma nova porta paralela, bi-direcional e de alta performance. Era requerimento que o novo padrão fosse totalmente compatível com a porta original, mas iria aumentar a velocidade de transferência para valores maiores que 1mb/s, tanto de entrada como de saída (half-duplex, pois só há um conjunto de linhas de dados).
Este comitê tornou-se o comitê IEEE 1284.

Com o IEEE 1284 standard são definidos 5 modos de operação, que são os seguintes,

    1. Compatibility Mode ou Centronics Mode.
    2. Nibble Mode.
    3. Byte Mode.
    4. EPP Mode (Enhanced Parallel Port).
    5. ECP Mode (Extended Capabilities Mode).

Os modos Compatibility, Nibble e Byte usam apenas o hardware padrão que os cartões de Porta Paralela originalmente possuiam, enquanto que os modos ECP e EPP requerem hardware adicional que funcione a velocidades mais altas, sem perder a compatibilidade com a SPP.

O modo de compatibilidade ou "Centronics mode" como é conhecido, só pode enviar dados numa velocidade típica de 50 kb/s, podendo chegar a até 150kb/s. Para poder receber dados, deve-se mudar para o modo Nibble ou Byte. O modo Nibble pode receber um nibble (4 bits) no sentindo reverso, i.e., do dispositivo para o computador. O modo Byte precisa de um cartão que suporte transmissões bi-direcionais para receber um byte.

As portas EPP e ECP usam hardware adicional para gerar e controlar o handshaking.
Como vimos acima, para enviar um byte para uma impressora usando o modo de compatibilidade, o software precisa,
    1. Escrever na Porta de Dados
    2. Checar se a impressora está ocupada. Se estiver ocupada não irá aceitar nennhum dado e o dado será perdido.
    3. Colocar o Strobe (Pino 1) em 0 (TTL low).  Isto indica a impressora de que há um dado válido nas linhas de dados (Pinos 2-9).
    4. Colocar o Strobe em 1 (TTL high) de novo,  5 microsegundos após ter setado para zero. (Passo 3)

Isto limita a velocidade da porta. O que as portas ECP & EPP fazem para contornar este problema é permitir que o hardware cheque se a impressora está ocupada e gerar o Strobe (ou outro handshake apropriado). Isso significa que apenas uma instrução precisa ser realizada, aumentando a velocidade. Estas portas podem enviar de 1-2 megas por segundo. A porta ECP ainda possui a vantagem de usar os canais de DMA e os buffers FIFO, então dados podem ser movidos sem usar instruções de I/O.




Exemplo de aplicação

Programação básica da PP

Código fonte: position.c
, read.c
Compilar com: gcc -O2 -o position position.c
Uso do programa:
Para setar o bit 1:
./position s1
Para baixar o bit 1:
./position c1
Para trocar (se desligado, liga; se ligado, desliga) o bit 1:
./position x1


No código fonte basicamente há dois comandos para acessar a porta paralela.
O primeiro é o ioperm que seta as permissões de entrada e saída de uma porta.
O segundo é o outb, que escreve nos 8 bits de saida da Porta Paralela (ou qualquer outra porta).
Ainda aparece o inb que lê os 8 bits.

Notar que se realizam aqui as operações de I/O em modo direto, direct I/O. 
Há outras maneiras de escrever na porta paralela, como por exemplo usando o PPDEV generic parallel port driver.

Obs: BASEPORT foi definido como 0x378 , o endereço da porta paralela.

No começo da main temos:

  if (ioperm(BASEPORT,3,1)) {perror("ioperm");exit(1);}

Estamos setando para TRUE a permissão para realizar operações de I/O nos 3 bytes após 0x378 (BASEPORT).

No fim da main temos:

  if (ioperm(BASEPORT,3,0)) {perror("ioperm");exit(1);}

Estamos setando para FALSE a permissão para realizar operações de I/O nos 3 bytes após 0x378 (BASEPORT).

Na função SET(int bit) temos:

        status = inb(BASEPORT);
        outb((status | power2(bit)),BASEPORT);

O comando enviará para a porta o resultado de um OU entre dois bytes: o status atual da porta e o novo bit que queremos setar.
A função power2 faz a conversão entre um número de pino de 1 a 8 para o seu valor em inteiro correspondente ao pino que será setado, isto é:

Pino
Porta recebe
Inteiro
1 0000 0001 1
2
0000 0010 2
3
0000 0100 4
4
0000 1000 8
5
0001 0000 16
6
0010 0000 32
7
0100 0000 64
8
1000 0000 128


Por ex. , se status = 00000010  (apenas o pino 2 está setado) e bit = 3 (que convertido dá 0000 0100):

        00000010 - status OU
        00000100 - bit
        00000110  - resultado

Ligando agora os pinos 2 e 3.

Esquemático

Este exemplo foi retirado do site Project LinuxGURU, que propõe usar o Linux (e um PC 386 talvez) para criar um sistema barato para domótica (automação residencial).
A parte que seria controlada pela Porta Paralela é a de acionamento das luzes pelo computador.

Para ativar um relé eletromecânico (comum!)  usaremos uma  fonte externa de  5V que ativará o relé quando a porta paralela liberar corrente para a base do transistor.
Um diodo é usado para evitar que as variações na tensão do relé quando este é aberto passem para o circuito.
Os autores informam que se forem usados relés SSR (relés de estado sólido), estes podem ser ligados diretamente na porta paralela, não necessitam do diodo (pois não são mecânicos, etc - mas são muito mais caros e difíceis de encontrar.




Poderiamos repetir este circuito 8 vezes, pois há somente 8 saídas. No entanto, usando um mux conseguimos controlar até 64 periféricos.
Embora no esquemático apareça uma lâmpada, este sistema serve para ligar qualquer aparelho que possa ser ligado/desligado com um interruptor.
Por exemplo, podemos usá-lo para ligar o ar-condicionado via internet, programar as lâmpadas da casa para serem ligadas em certos horários durante um fim de semana por questões de segurança ou abrir os portões de casa pelo telefone celular.
Observar que, embora o relé isole fisicamente o circuito 120V do computador,
o circuito talvez tenha que ser alterarado para que ele possa operar aparelhos que "puxem" muita corrente.

Links
Interfacing the Standard Parallel Port
Interfacing the Enhanced Parallel Port
Interfacing the Extended Capabilities Port
Project LinuxGURU
Warp nine engineering - The IEEE 1284 experts
How Parallel Ports Work
Linux Parallel Port Home Page
The Linux 2.4 Parallel Port Subsystem
The Linux Parallel Port Programming HOWTO
IBM Parallel Port FAQ/Tutorial