There recently was a thread regarding direct hardware port access
http://smorgasbordet.com/phpBB2/viewtopic.php?t=494
and some proposed the WinIO library as solution.
I also have done several projects accessing hardware ports directly and
i found the InpOut32 library more useful than the WinIO stuff.
Download the Inpout32 original files from http://www.logix4u.net
there you get also the source code for all drivers and libraries
This library is incredible, under XP it works not only with administrator rights,
it works also when logged on as a normal user wihout any special permissions.
If someone is interested, in the attachement you can find the PellesC
sample projects ready to use InpOut32, one project (test) is from the original supplied samples,
the other version (testlib) uses an import library and header file.
try it out it's really esay to use, when using the import library version.
--tiwag
nice ! this could be pretty useful, thx !
Hi tiwag,
I have tested InpOut32 and it is really very easy to handle. The bad news is that it doesn't seem to work on serial ports. Is that a fact or am I doing something wrong? Best regards
Hi sven
as far as i have tested and know InpOut32 works with all known
IO mapped hardware registers and addresses,
i think you should be able to access the uart registers in the same way
as you access the parallel port registers, but i haven't tried this.
anyhow, the serial port is much more convenient to handle
with win api function calls ... see the following sample
/********************************************************************/
/* */
/* Terminal.cpp: Sample UART Loopback Terminal Program */
/* */
/* This is a sample terminal emulator for the UART based serial */
/* communications card. Please view the file abstract.txt for */
/* more information. */
/* */
/* (c)Copyright Sealevel Systems, Inc., 1999 */
/* */
/* SEALEVEL SYSTEMS INCORPORATED. */
/* 155 Technology Place */
/* P.O. Box 830 */
/* Liberty, SC 29657 USA */
/* (864) 843-4343 */
/* (864) 843-3067 FAX */
/* */
/********************************************************************/
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define TIMEOUT_CONSTANT 50
#define ESC 27
int main(int argc, char* argv[])
{
int key_pressed = 0;
char outchar = 0;
char inchar = 0;
DWORD bytes_written = 0; // Number of bytes written to port
DWORD bytes_read = 0; // Number of bytes read from port
COMMTIMEOUTS tempComTimeouts; // Our temporary time-outs for COM1
COMMTIMEOUTS savedComTimeouts; // Stores the original time-outs
HANDLE comport = NULL; // Handle for COM port
DCB comSettings; // Contains various port settings
printf("Sample UART Loopback Terminal Program v1.00.\n");
printf("(c)Copyright Sealevel Systems, Inc., 1999.\n\n");
// Open COM port
if ((comport =
CreateFile("COM1",
GENERIC_READ | GENERIC_WRITE, // for reading and writing
0, // exclusive access
NULL, // no security attributes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
printf("Unable to open COM1.\n\n");
printf("Press any key to exit.");
getch();
return(1);
}
printf("COM1 opened.\n\n");
// Save time-out parameters for COM1
GetCommTimeouts(comport,&savedComTimeouts);
// Set our time-outs
tempComTimeouts.ReadIntervalTimeout = TIMEOUT_CONSTANT;
tempComTimeouts.ReadTotalTimeoutMultiplier = TIMEOUT_CONSTANT;
tempComTimeouts.ReadTotalTimeoutConstant = TIMEOUT_CONSTANT;
tempComTimeouts.WriteTotalTimeoutMultiplier = TIMEOUT_CONSTANT;
tempComTimeouts.WriteTotalTimeoutConstant = TIMEOUT_CONSTANT;
SetCommTimeouts(comport,&tempComTimeouts);
// Set Port parameters.
// We make a call to GetCommState() first in order to fill
// the comSettings structure with all the necessary values.
// Then we change the ones we want and call SetCommState().
GetCommState(comport, &comSettings);
comSettings.BaudRate = 9600;
comSettings.StopBits = ONESTOPBIT;
comSettings.ByteSize = 8;
comSettings.Parity = NOPARITY;
comSettings.fParity = FALSE;
SetCommState(comport, &comSettings);
printf("Ready to send/receive data. Hit ESC to exit.\n\n");
while(key_pressed != ESC)
{
if (kbhit())
{
key_pressed = getch();
outchar = (char)key_pressed;
if (key_pressed != ESC)
{
// Send data. if succesful, WriteFile() returns non-zero
WriteFile(comport, // Handle
&outchar, // Outgoing data
1, // Number of bytes to write
&bytes_written, // Number of bytes written
NULL);
}
}
// Read data. if succesful, ReadFile() returns non-zero
ReadFile(comport, // Handle
&inchar, // Incoming data
1, // Number of bytes to read
&bytes_read, // Number of bytes read
NULL);
if (bytes_read == 1)
if (inchar == 13)
printf("\n");
else
printf("%c", inchar);
}
// Restore time-out parameters
SetCommTimeouts(comport,&savedComTimeouts);
CloseHandle(comport);
printf("\n");
return(0);
}
-tiwag
InpOut32 is fine for reading/writing ports,
but it uses DeviceIoControl API for that in NT ( not _inp()/_out() ).
But reading memory with that isn't supported, I think.
That's why in Andrew's case, it's needed something like WinIO.
Quote from: "Timppa"InpOut32 is fine for reading/writing ports,
...
exactly, thats what i've done with InpOut32,
access to user-defined hardware by means of
IO mapped registers (ports) ...
Quote from: "Timppa"...That's why in Andrew's case, it's needed something like WinIO.
i don't think so,
in respect of Andrew's first posting, he want's to access
the IO mapped ports (registers) of a parallel port.
QuoteWhere these registers are usually ?
In an IBM PC, these registers are IO mapped and will have unique address. We have to find these addresses to to work with parallel port. For a typical PC , the base address of LPT1 is 0x378 and of LPT2 is 0x278. The data register resides at this base address , status register at baseaddress + 1 and the control register is at baseaddress + 2. So once we have the base address , we can calculate the address of each registers in this manner. The table below shows the register addresses of LPT1 and LPT2
Register LPT1 LPT2
data registar(baseaddress + 0) 0x378 0x278
status register (baseaddress + 1) 0x379 0x279
control register (baseaddress + 2) 0x37a 0x27a
and this can be done with InpOut32 with ease
see samples
but i know what you mean, you can't
get the base address of the IO port with this functions.
InpOut32 two functions are identically with
WinIO's functions GetPortVal and SetPortVal
but WinIO additionally has functions to
access direct hardware memory addresses too.
hi guys,
I have tested WinIo and inpout32 and both ways seems to work nicely but I still can't get any reaction from my com ports registers, they read FF no matter what I try to write . Has anybody any idea what's wrong? I also tried the UART loopback program but the compiler broke down, don't I have the rignt windows library ? I am greatful for any suggestions.
Sven
Loopback program Terminal, as PellesC project
Quote from: "sven"I also tried the UART loopback program but the compiler broke down, don't I have the rignt windows library ?
Can you explain "broke down"?!
Pelle
Hi Sven,
In my experience if you read 0xFF from an I/O this simply means that there is no device there!
I'm sure you are not trying to access serial ports on an USB dock, but on some PC there are new serial devices that are not legacy compliant (means that they don't respect the standard I/O mapping and/or registers and programming). So I would suggest you to check that the device you are trying to access is a classic one (why don't boot old glorious DOS and check with a standard program?) :wink: .
Hello Pelle,
So sorry for my sloppy language, the compiler didn't break down ofcourse,
it only reached more than 100 warnings and faults and stopped.
Later I tried to compile the UART loopback program with the lcc compiler and it worked fine so I guess it has to do with libraries, question is how ? Anyway, now I am able to manipulate the comSettings with the SetCommState command and the next step is to find out the structure of the CommMask which is what I really wanted to utilize.
But still I am curious about why I can't access the serial port regs with _imp/_out
Best regards Sven
Quote from: "sven"
... it only reached more than 100 warnings and faults and stopped...
rule of thumb for this behaviour :
check compiler option "Enable Micro$oft Extensions" --> -Ze
ad uart registers:
of course one can access these register with inpout,
but to do something meaningful with it is a pain,
beside reading the hardware manual for the actually implemented uart on your mainboard, you have to regard 25+ other important things,
you have to download 5+ versions (if available) to find the last bug fixed versions of the datasheet and application notes documents, and so on ...
use the winAPI instead and don't reinvent the wheel.
inpout is mainly used to access hardware, which is user-defined built
and connected to your pci bus and has IO-mapped registers to control this hardware. i do such things in my office and it works really !
-tiwag
QuoteI guess it has to do with libraries, question is how ?
Check compiler option "Define compatibility name" -> Go
Quote from: "tiwag"Quote from: "sven"
... it only reached more than 100 warnings and faults and stopped...
rule of thumb for this behaviour :
check compiler option "Enable Micro$oft Extensions" --> -Ze
-tiwag
of course, typical beginner's misstake. I downloded Pelle's latest version the other day and forgot to tick those boxes. Now it works " som ett spjut " - like a spear. Thank you. Now my next step in this daVinci puzzle is to find out how to handle the CommMask. Where can I find info about that ?
Quote from: "sven"
of course, typical beginner's mistake...
we all started this way,
what's a compiler ? linker ? preprocessor ? 150+ unknown important things....
don't worry, take it easy, continue learning
Quote from: "sven"
Now my next step in this daVinci puzzle is to find out how to handle the CommMask. Where can I find info about that ?
start here:
http://msdn.microsoft.com/library/default.asp
and use the
search field 8)
or
download & install the Win32 SDK
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
good start !
-tiwag
Tried various COM listings to read from the port - nuffing!
Well, not quite, on my old PC there is COM1 & COM2, COM2 works but not COM1. On my new PC there is only COM1 which does not show any chars read form the port.
Any information about why this is ?
John
Quote from: "JohnF"Tried various COM listings to read from the port - nuffing!
Well, not quite, on my old PC there is COM1 & COM2, COM2 works but not COM1. On my new PC there is only COM1 which does not show any chars read form the port.
Any information about why this is ?
John
Which version of windows are you on John?
Win 32 versions, especially NT and it's descendents (2000, XP, 2003, Win64...) actively block direct access to IO devices, requiring you to go through the OS drivers instead.
Check the Platform SDK for CreateFile, SetCommState and DeviceIOControl functions. I think you'll find that it's actually a rather simple matter to treat a serial IO port as though it were a file. You can open the Serial port with a CreateFile call, and send and receive in the same manner as reading or writing a disk file using ReadFile and WriteFile. Settings and initialization is handled by SetCommState. I used to do this with receipt printers all the time.
Here's the general info from MSDN...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devio/base/communications_resources.asp
You'll likely find it a lot easer than trying to do an end run around Windows.
Quote from: "JohnF"Tried various COM listings to read from the port - nuffing!
Well, not quite, on my old PC there is COM1 & COM2, COM2 works but not COM1. On my new PC there is only COM1 which does not show any chars read form the port.
Any information about why this is ?
John
Hi John
from my experience, this is what i can say :
InpOut32 is working absolutely reliable for acces of all kind of IO mapped registers.
i used it for parallel port reading / writing
and for some self designed hardware projects.
i did not and will not do any serial port stuff with it,
i won't write an interrupt handler for the serial port for win32,
cause this is already done by M$ and known as working...
see CreateFile("COM1", ...) stuff
what exactly is your need ?
if you want to set the level of handshake lines of the RS232,
it can easily be done with win32 API
if you remember, i have sent you a few (i guess 2) years ago an M$ sample
called mttty (multy threaded tty) which i ported to lccwin32
and improoved a little bit.
There you can look how to access all kinds of serial IO stuff.
best regards,
tiwag
Quote from: "ldblake"
Which version of windows are you on John?
WinXP
Quote
Win 32 versions, especially NT and it's descendents (2000, XP, 2003, Win64...) actively block direct access to IO devices, requiring you to go through the OS drivers instead.
Although COM2 works on my old machine. (WinXP)
Quote
Check the Platform SDK for CreateFile, SetCommState and DeviceIOControl functions. I think you'll find that it's actually a rather simple matter to treat a serial IO port as though it were a file. You can open the Serial port with a CreateFile call, and send and receive in the same manner as reading or writing a disk file using ReadFile and WriteFile. Settings and initialization is handled by SetCommState. I used to do this with receipt printers all the time.
Yes am using CreateFile, etc.
John
Quote from: "tiwag"
if you remember, i have sent you a few (i guess 2) years ago an M$ sample called mttty (multy threaded tty) which i ported to lccwin32
and improoved a little bit.
There you can look how to access all kinds of serial IO stuff.
best regards,
tiwag
I will find it and take a look, will let you know...
Some time later - that mttty works on COM2 but will not work on COM1 on my old machine. This is the same result as using other listings. If no doubt it will behave like that on my new machine. (COM1)
John
Quote from: "JohnF"
...Some time later - that mttty works on COM2 but will not work on COM1 on my old machine. This is the same result as using other listings. If no doubt it will behave like that on my new machine. (COM1)
John
one com port works - the other not ??!? mysterious !!??!
i don't know how i can help you further
-tiwag
Quote from: "tiwag"Quote from: "JohnF"
...Some time later - that mttty works on COM2 but will not work on COM1 on my old machine. This is the same result as using other listings. If no doubt it will behave like that on my new machine. (COM1)
John
one com port works - the other not ??!? mysterious !!??!
i don't know how i can help you further
-tiwag
Ok, thanks anyway.
John
Quote from: "JohnF"
Although COM2 works on my old machine. (WinXP)
From what you say I'd bet it's hardware not sofware that's messing you up...
1) Are you shure your new machine has 2 ports?
2) Is it configured as a serial port in the bios? (some set COM2 for Infrared by default)
3) Check in hardware manager... is it set up correctly?
4) Have you tried hardware diagnostics with a loopback plug?
Quote from: "ldblake"Quote from: "JohnF"
Although COM2 works on my old machine. (WinXP)
From what you say I'd bet it's hardware not sofware that's messing you up...
1) Are you shure your new machine has 2 ports?
2) Is it configured as a serial port in the bios? (some set COM2 for Infrared by default)
3) Check in hardware manager... is it set up correctly?
4) Have you tried hardware diagnostics with a loopback plug?
I don't have a loopback plug but Device Manager says the port is working properly.
John
Quote from: "JohnF"I don't have a loopback plug but Device Manager says the port is working properly.
:( And it always tells me my camera dock is working correctly too... except that I don't have a dockable camera...
Check your bios settings (hit DEL during boot up...) it is quite likely it's working properly, but not as expcected... It could be configured as an IR (InfraRed) device port instead of as a standard serial port, or it could simply be disabled. In that case the back panel connector will be dead as a door nail. Some BIOS's do this by default, and it annoys me to no end :wink:
Loopback is very easy, all you need is the correct plug and a little bit of solder. You can also purchase them pre-wired, but at about 5x the price of making one yourself. The specs (and a wealth of other stuff) is here... http://www.beyondlogic.org/serial/serial.htm#2
Quote from: "ldblake"Quote from: "JohnF"I don't have a loopback plug but Device Manager says the port is working properly.
:( And it always tells me my camera dock is working correctly too... except that I don't have a dockable camera...
Check your bios settings (hit DEL during boot up...) it is quite likely it's working properly, but not as expcected... It could be configured as an IR (InfraRed) device port instead of as a standard serial port, or it could simply be disabled. In that case the back panel connector will be dead as a door nail. Some BIOS's do this by default, and it annoys me to no end :wink:
Ok checked that, the bios had the serial port just as AUTO so I made it COM1, still no go though.
EDIT: Addition info. I have a DELL with it's own diagnostic partition which one can boot - it says that the serial port 1 passed all tests.
John
Quote from: "JohnF"Ok checked that, the bios had the serial port just as AUTO so I made it COM1, still no go though.
EDIT: Addition info. I have a DELL with it's own diagnostic partition which one can boot - it says that the serial port 1 passed all tests.
Ok, now that you've changed the BIOS settings, you'll most likely have to go through the Device Manager settings again and reconfigure it there.
BTW... If you enabled the IRQs in the bios, please be aware that they are bassackwards... Com1 is irq4, Com2 is irq3.
Take a look inside the case of your computer. See what CPU board is in there (Odds are it's MSI but not always). You can always try replacing the drivers with the ones from the CPU board manufacturer. (They're usually a lot less buggy than the Dell ones.)
FWIW... I have a couple of friends who bought Dell... took them a while to get everything working right. Dell has a production version of XP that's installed by an unattended script. It's not the same as the version on the CD you got... and since it is licenced in a certain state, it's not likely to have the most up to date drivers.
Quote from: "ldblake"
Ok, now that you've changed the BIOS settings, you'll most likely have to go through the Device Manager settings again and reconfigure it there.
BTW... If you enabled the IRQs in the bios, please be aware that they are bassackwards... Com1 is irq4, Com2 is irq3.
Take a look inside the case of your computer. See what CPU board is in there (Odds are it's MSI but not always). You can always try replacing the drivers with the ones from the CPU board manufacturer. (They're usually a lot less buggy than the Dell ones.)
FWIW... I have a couple of friends who bought Dell... took them a while to get everything working right. Dell has a production version of XP that's installed by an unattended script. It's not the same as the version on the CD you got... and since it is licenced in a certain state, it's not likely to have the most up to date drivers.
I have reinstalled it, XP that is.
The IRQ is set as 4. The best thing is to find another driver, thanks for your input.
John
Quote from: "JohnF"
... The best thing is to find another driver, thanks for your input...
if they are from M$, named
serenum.sys and
serial.sys
and have a description which correlates to the installed XP Sservice pack
(here i have XP SP2 and the drivers are of version (xpsp_sp2_rtm.040803-2158))
then let them as they are!
2nd)
have you tried to disable the FIFO settings in "advanced port setting" ?
just slide completely to the left or uncheck the option, if there is a checkbox.
-tiwag
Quote from: "tiwag"
have you tried to disable the FIFO settings in "advanced port setting" ?
just slide completely to the left or uncheck the option, if there is a checkbox.
Ummm... I hadn't thought of that, but what effect would this have?
(aside from the obvious disabling of the on-chip buffers, that is)
Quote from: "ldblake"Quote from: "tiwag"
have you tried to disable the FIFO settings in "advanced port setting" ?
just slide completely to the left or uncheck the option, if there is a checkbox.
Ummm... I hadn't thought of that, but what effect would this have?
(aside from the obvious disabling of the on-chip buffers, that is)
sometimes it works afterwards :P
Quote from: "tiwag"Quote from: "JohnF"
... The best thing is to find another driver, thanks for your input...
if they are from M$, named
serenum.sys and
serial.sys
and have a description which correlates to the installed XP Sservice pack
(here i have XP SP2 and the drivers are of version (xpsp_sp2_rtm.040803-2158))
then let them as they are!
2nd)
have you tried to disable the FIFO settings in "advanced port setting" ?
just slide completely to the left or uncheck the option, if there is a checkbox.
-tiwag
Yes, I've tried it disabled and enabled.
I have sp1
sernum.sys 5.1.2600.0(XPClient 010817-11-48
serial.sys 5.1.2600.1106 (xpsp1.020828-1920)
John
Quote from: "JohnF"Yes, I've tried it disabled and enabled.
I have sp1
sernum.sys 5.1.2600.0(XPClient 010817-11-48
serial.sys 5.1.2600.1106 (xpsp1.020828-1920)
John
interesting, i have both drivers from the same version,
maybe this produces troubles at your side.
tiwag
Quote from: "tiwag"Quote from: "JohnF"Yes, I've tried it disabled and enabled.
I have sp1
sernum.sys 5.1.2600.0(XPClient 010817-11-48
serial.sys 5.1.2600.1106 (xpsp1.020828-1920)
John
interesting, i have both drivers from the same version,
maybe this produces troubles at your side.
tiwag
It's strange that both the Device Manager and DELL diagnostics say the port is ok. Btw, on my old machine where COM1 is not working with the termial app and COM 2 does work, both ports have FIFO enabled.
I'll forget it for now, there does not seem to be an obvious solution.
John
Quote from: "JohnF"
I'll forget it for now, there does not seem to be an obvious solution.
It does seem a little odd. These days the comports are integrated into the chipsets, seems to me that if one works both should... and it's really odd that you have two machines and the same problem on both.
If you ever do get it sorted can you let us know what you did... Might be handy info at some point in time.