Pelles C forum

C language => User contributions => Topic started by: tiwag on April 16, 2005, 10:41:26 am

Title: InpOut32 for PellesC
Post by: tiwag on April 16, 2005, 10:41:26 am
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
Title: InpOut32 for PellesC
Post by: drakoh on April 17, 2005, 03:34:59 am
nice ! this could be pretty useful, thx !
Title: InpOut32
Post by: sven on April 22, 2005, 04:44:04 pm
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
Title: InpOut32 for PellesC
Post by: tiwag on April 23, 2005, 07:40:43 am
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

Code: [Select]

/********************************************************************/
/*                                                                  */
/*  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
Title: InpOut32 for PellesC
Post by: Timppa on April 23, 2005, 09:42:17 am
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.
Title: InpOut32 for PellesC
Post by: tiwag on April 23, 2005, 09:54:27 am
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) ...
Title: InpOut32 for PellesC
Post by: tiwag on April 23, 2005, 09:59:00 am
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.

Quote
Where 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.
Title: Port read/write
Post by: sven on April 27, 2005, 02:43:15 pm
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
Title: InpOut32 for PellesC
Post by: TimoVJL on April 27, 2005, 03:24:15 pm
Loopback program Terminal, as PellesC project
Title: Re: Port read/write
Post by: Pelle on April 27, 2005, 04:02:25 pm
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
Title: InpOut32 for PellesC
Post by: frankie on April 28, 2005, 01:16:38 pm
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: .
Title: Serial interface
Post by: sven on April 29, 2005, 07:50:41 am
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
Title: Re: Serial interface
Post by: tiwag on April 29, 2005, 08:07:16 am
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
Title: InpOut32 for PellesC
Post by: Timppa on April 29, 2005, 10:00:22 am
Quote
I guess it has to do with libraries, question is how ?

Check compiler option "Define compatibility name" -> Go
Title: Re: Serial interface
Post by: sven on April 29, 2005, 07:36:22 pm
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 ?
Title: Re: Serial interface
Post by: tiwag on April 29, 2005, 08:40:36 pm
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
Title: InpOut32 for PellesC
Post by: JohnF on April 30, 2005, 10:02:34 am
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
Title: InpOut32 for PellesC
Post by: Anonymous on April 30, 2005, 11:54:54 am
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.
Title: InpOut32 for PellesC
Post by: tiwag on April 30, 2005, 12:01:06 pm
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
Title: InpOut32 for PellesC
Post by: JohnF on April 30, 2005, 12:35:07 pm
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
Title: InpOut32 for PellesC
Post by: JohnF on April 30, 2005, 12:41:35 pm
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
Title: InpOut32 for PellesC
Post by: tiwag on April 30, 2005, 02:11:34 pm
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
Title: InpOut32 for PellesC
Post by: JohnF on April 30, 2005, 02:13:05 pm
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
Title: InpOut32 for PellesC
Post by: Anonymous on April 30, 2005, 05:32:15 pm
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?
Title: InpOut32 for PellesC
Post by: JohnF on April 30, 2005, 08:43:38 pm
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
Title: InpOut32 for PellesC
Post by: Anonymous on May 01, 2005, 01:46:43 am
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
Title: InpOut32 for PellesC
Post by: JohnF on May 01, 2005, 07:34:32 am
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
Title: InpOut32 for PellesC
Post by: Anonymous on May 01, 2005, 10:16:50 am
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.
Title: InpOut32 for PellesC
Post by: JohnF on May 01, 2005, 10:39:27 am
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
Title: InpOut32 for PellesC
Post by: tiwag on May 01, 2005, 11:31:09 am
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
Title: InpOut32 for PellesC
Post by: Anonymous on May 01, 2005, 11:36:06 am
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)
Title: InpOut32 for PellesC
Post by: tiwag on May 01, 2005, 11:37:03 am
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
Title: InpOut32 for PellesC
Post by: JohnF on May 01, 2005, 11:38:26 am
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
Title: InpOut32 for PellesC
Post by: tiwag on May 01, 2005, 11:40:54 am
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
Title: InpOut32 for PellesC
Post by: JohnF on May 01, 2005, 12:47:58 pm
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
Title: InpOut32 for PellesC
Post by: Anonymous on May 01, 2005, 01:14:52 pm
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.