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.
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 :-)
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
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.
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
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.
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.
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.