Hehe, I got a very complex reply for you
If Advantech doesn't provide DOS drivers (libraries), hardly anyone else does DOS is somewhat "out" these days, at least among the hardware makers...
That said, I believe you could achieve quite a lot by way of direct hardware access to the Advantech PCI boards. They are usually fairly simple to access, and they usually have fairly good documentation of the hardware at registers level. If you try to work with them, you will likely find some grey areas, such as:
1) the documentation often mentions just a "bank of registers". To find out the base address and type of the "access window" (port IO / memory mapped IO), you have to check the card's PCI BAR's (in the config space) - which can be done by a tailormade proggie in DOS, or by
lspci -vv in Linux.
2) the precise behavior of interrupt status flags and the precise correct way of IRQ acking, but that can be solved by trial and error - the number of combinations is low enough.
Maybe it's easier to write IRQ handling code in Linux, where all the gory details of system-wide IRQ delivery and ACKing are handled by the standard IRQ super-handler. Your ISR only has to care about your own hardware. In DOS, you may have to ACK the IRQ to your PIC (not sure about the PCI level-triggered interrupts), and you won't be able to use interrupt numbers above 15 (which you can in Linux, as Linux will also set up the APIC's for you)
What do you mean by fast I/O? Is "polling access via PCI" fast enough for you? If combined with a FIFO? If this is still not fast enough, you may want to get your hands dirty with PCI DMA.
Take this board for example:
http://www.advantech.com/products/PCI-1755/mod_1-2MLHG1.aspx
It can do 80 MBps in digital I/O, using DMA transfers.
You may access it by direct polling IO, even without IRQ.
The FIFO is transparent, you won't even know that you're using it,
unless you want to.
You can use IRQ if you want, and you know how to do it.
You can also use the DMA capability, if you can set it up in DOS
(I haven't tried it yet). The DMA transfers use the same data registers (FIFO) that you can otherwise access directly.
Check out the board's manual:
http://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-1XP8VV
There's a decription of the register bank.
It may be important to note that the registers appear to be 16 bits wide, which may have some significance for the PCI DMA setup.
Note that the manual doesn't mention IRQ delivery much, and it doesn't mention DMA at all. The PCI interface is not described, but it is mentioned that it's implemented using the PLX 9056 (general-purpose PCI slave bridge).
http://www.plxtech.com/products/io/pci9056
("data book" available after a free registration)
And that is really a key pointer to IRQ delivery, DMA handling and maybe the base address (though the Base Address Registers are rather PCI-generic than PLX-specific).
In your program, you can find out the card's base address(es) and IRQ number using PCI BIOS calls. Right after that, you can directly access any Port IO windows. That can easily be done from 16bit executable code.
If the board's IO window is memory-mapped, which would make sense, considering its DMA capability (not entirely sure), you'd need memory-mapped access to PCI resources, which IMO requires protected mode access = practically the easiest way to set up the physical-to-virtual mapping is via some basic DPMI services. So you'll need DPMI.
If you haven't chosen your development environment (compiler) yet, you may want to consider DJGPP - that *requires* DPMI to run, you're automatically in protected mode, and you don't have to worry about DOS memory segmentation anymore.
Here is some example code:
http://www.fccps.cz/download/adv/frr/VGA_off.zip
(check the Geode subdirectory) that is relevant to:
- querying of PCI BIOS (finding devices, their base addresses
and IRQ numbers)
- memory mapped IO: especially the setup of physical-to-virtual mapping,
using some DPMI calls to set up (and destroy) an LDT entry
- all of that in DJGPP. Where Linux calls readl()/writel(),
DJGPP calls _farpeekl()/_farpokel()
Actually a slightly more advanced (newer) version of pci.c/pci.h is available in this ZIP file:
http://www.fccps.cz/download/adv/frr/smi.zip
This version of the "PCI library" allows to search for a list of PCI ID combinations (= hardware types) and to return a list of PCI devices found. Which may help you if you consider using multiple IO boards in a single computer.
I've never actually tried IRQ handling from djgpp, so I don't have my own source code samples - but it definitely is possible.
http://www.delorie.com/djgpp/v2faq/faq18_9.html
http://www.delorie.com/djgpp/v2faq/faq18_11.html
It's so much easier in Linux...
Same thing with PCI DMA - I'd expect that to be even a bit more complicated than IRQ handling:
http://www.delorie.com/djgpp/v2faq/faq18_13.html
I'm not sure if that topic says all there is to know about PCI DMA,
e.g. if the CPU physical address is the same as PCI bus addressing,
or if in addition you need to configure something in the PCI root bridge. Another related URL:
http://groups.google.com/group/comp.os.msdos.djgpp/browse_thread/thread/11cc2bcd8ab18670
Once you get your hands on the target address for DMA transfers,
you have to configure that into the PLX PCI9056 - see its documentation for details. That is the chip that handles the DMA. You may have to configure translation from 16bit data length on the local bus to
32bit data length on the PCI, unless Advantech has already configured that for you in the PCI9056's configuration eeprom (and unless I'm wrong about this point).
The board also contains an i8254 counter/timer, which is used as a pacer for the clocked + FIFO-buffered digital I/O.
I have a simple wrapper library for that:
http://www.fccps.cz/download/adv/frr/i8254.tgz
(Note that the board perversely maps the four bytes
of the timer chip as four dwords in PCI address space,
but that can be handled by a tiny mod to the library.)
Overall, it probably wouldn't be very useful to provide a DOS library.
What compiler + maybe DPMI environment should that be based on?
Would you want the library to hook some software interrupt,
to provide a totally compiler-independent interface?
It's perhaps more appropriate to let you roll your own library.
Some sample C source from Advantech would be nice, but... --- DOS gives me freedom to unlimited HW access. |