banging a printer port

Any idea about the rate we could bit-bang write to a printer port under Linux?

I tried a PowerBasic (DOS) loop on Windows and got a bit over 500 KHz, but I don't know if my OUT instructions are actually working, or if Windows is trapping the calls and emulating. Under Linux, we'll be doing real OUTs.

I'm thinking of configuring a Xilinx FPGA from a parallel (printer) connector. Bit-banging would only take 3 wires (prog_b, cclk, data) and two writes per bit, but with 4M bits to bang, I wouldn't like it to take too too long.

John

Reply to
John Larkin
Loading thread data ...

On a sunny day (Wed, 15 Jul 2009 12:26:30 -0700) it happened John Larkin wrote in :

If you want to write directly to the port, first do: # free parport for test program: killall -KILL lpd rmmod lp rmmod parport_pc rmmod parport

Then compile this program:

#include #include #include // iopl()

#define PAR_PORT 0x378

int main(int argc, char**argv) { int i;

/* set io permissions */ iopl(3); //ioperm(0x40, 0x3bf, 1);

for(i = 0; i < 100000; i++) { register char a; a = inb(PAR_PORT); a |= 16; /* set bit 4 (d4 on pin 6)*/ outb(a, PAR_PORT); }

exit(0); } /* end function main */

#include // iopl()

#define PAR_PORT 0x378

int main(int argc, char**argv) { int i;

/* set io permissions */ iopl(3); //ioperm(0x40, 0x3bf, 1);

// make loop bigger then 100000 for betetr timing. for(i = 0; i < 100000; i++) { register char a; a = inb(PAR_PORT); a |= 16; /* set bit 4 (d4 on pin 6)*/ outb(a, PAR_PORT); }

exit(0); } /* end function main */

Compile command: gcc -Wall -o test20 test20.c

Run it, time it date ; ./test20 ; date

Make the 'i' in the loop a lot bigger to get usable results :-)

Reply to
Jan Panteltje

Something messed up in cut and paste, this should be, more clear:

If you want to write directly to the port, first do: # free parport for test program: killall -KILL lpd rmmod lp rmmod parport_pc rmmod parport

Then compile this program:

#include #include #include // iopl()

#define PAR_PORT 0x378

int main(int argc, char**argv) { int i;

/* set io permissions */ iopl(3); //ioperm(0x40, 0x3bf, 1);

for(i = 0; i < 100000; i++) { register char a; a = inb(PAR_PORT); a |= 16; /* set bit 4 (d4 on pin 6)*/ outb(a, PAR_PORT); }

exit(0); } /* end function main */

Compile command: gcc -Wall -o test20 test20.c

Run it, time it date ; ./test20 ; date

Make the 'i' in the loop a lot bigger to get usable results :-)

Reply to
Jan Panteltje

thats how the xilinx programming cable works (older one, new one is usb), there's even a schematic somewhere on their site.

think it is about 200KHz but I haven't checked

-Lasse

Reply to
langwadt

On a sunny day (Wed, 15 Jul 2009 13:31:24 -0700 (PDT)) it happened " snipped-for-privacy@fonz.dk" wrote in :

And here is the Linuxi open source I wrote to btbang that::

formatting link
formatting link

I modified a version that used the /dev/ interface for direct I/O, so mine should be faster.

Reply to
Jan Panteltje

Do you have any serial port programming examples? Say wiggling an handshake line or maybe reading the frequency of a handshake line being toggled.

Also, aren't their tricks to make linux more real time? I know this is done for low latency in the sound card.

Reply to
miso

On a sunny day (Wed, 15 Jul 2009 14:54:29 -0700 (PDT)) it happened " snipped-for-privacy@sushi.com" wrote in :

#include #include #include // iopl()

#define COM1BASE 0x3f8 #define COM2BASE 0x2f8 #define COM3BASE 0x3e8 #define COM4BASE 0x2e8

#define DTR 0 #define RTS 1

int combase;

void set_dtr(int state) /* sets DTR to on or off */ { int a;

a = inb(combase + 4);

// /* bit is inverted */ if(state == 1) a |= (1

Reply to
Jan Panteltje

John "prog_b" and "cclk" implies a Xilinx FPGA. You might want to consider using the "Slave Parallel" download mode on the FPGA and use all eight printer port data lines. There are plenty of other control lines on a printer port for prog_b and cclk.

Of course this assumes you have not already dedicated the FPGA pins for a parallel download to the FPGA application.

BTW: I used Slave Parallel and an FTDI FT245 when I had the same problem to solve. The nice thing is that the USB host interface is available to my application after the code download. Please see

formatting link

Bob Smith

Reply to
Bob Smith

That's "preemptible":

config PREEMPT bool "Preemptible Kernel (Low-Latency Desktop)"

Apart from using a preemptible kernel, you need to use sched_setscheduler() to make the process run with real-time priority.

mlockall() may be useful to prevent delays due to demand-paging.

With a single-core CPU, a busy loop at high priority will block all other processes, yet you would still get periodic context switches for the kernel's interrupt handling. A dual-core processor should allow you to have one process run continually without interruption.

Reply to
Nobody

Bob,

I replied to your email, but it bounced.

John

Reply to
John Larkin

Shame on you - OUTing a printer!!!

Reply to
Robert Baer

Fundamentally, aren't you limited by the bus speed?

Now what I'm not sure about is, my parallel port for instance is a PCI device. So does it run at the 33MHz PCI bus rate, or is it clocked down to the 8MHz ISA bus it originally came from?

And if it is 8MHz, what is the processor doing for the average 62.5ns when it's not ready? Does it just stall on I/O, or do they have I/O caching these days?

In either case, you get a much higher bitrate with a proper 50MHz JTAG bus, and you can get a USB bridge for $20, so who cares anyway.

FYI: serial port access (&H3F8, etc.) appears to be available in Windows, at least inside NTVDM. But parallel isn't, for some bizarre reason. You can load a dumb parallel port driver, like inpout32, to take care of that -- at least for Win32 apps. Trivial to call in PowerBasic I'm sure (hell, it's only about ten lines in C).

Tim

--
Deep Friar: a very philosophical monk.
Website: http://webpages.charter.net/dawill/tmoranwms
Reply to
Tim Williams

ge

n to

n

s,

at

u can

at

's

You can write directly to the ports in windows by using a kernel mode driver. For all preemptive operating system you will have potential latency issues but if timing is not absolutely critical it will be ok.

There are several programs out there that will work. There is one program that can give your program access to using the ports directly (so it doesn't create a fault) and there are ones that you can use in your code. InOut32 is one simple program.

Reply to
bob.jones5400

e).

ve'.

Thanks to both you and Jan. I'm not going to change the kernal on a working box (I'm crazy, but not that crazy.) However, I will try that code on my quad core.

Reply to
miso

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.