Solved

Serial(RS232) programming under WinNT 4.0

Posted on 2003-11-10
11
1,910 Views
Last Modified: 2010-08-05
Hi all,

I need a simple self-loop test Visual 6.0 C++ program on a 9-pin D connector where pin 2 & 3 are shorted together. I have done similar thing before under Win 95/98 where outport()/inport() functions are used. But to what I understand I can't do so in WInNT where I cannot access the hardware directly. Pls help to provide some sample codes/web links so that I can jump start my project. I 'm not familiar with MFC thus need some help here ... Thanks.
0
Comment
Question by:qiang8
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 125 total points
ID: 9720384
0
 
LVL 5

Expert Comment

by:rendaduiyan
ID: 9720722
Use ActiveX control instead, quick and easy, with samples in MSDN.
0
 
LVL 4

Assisted Solution

by:havman56
havman56 earned 125 total points
ID: 9722111
i am providing the ocde for ur serial communciation just copy and use it it will run
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:havman56
ID: 9722116



/* ------------------------------------------------------------------------ --
--                                                                          --
--                        PC serial port connection object                  --
--                           for non-event-driven programs                  --
--                                                                          --
--                                                                          --
--                                                                          --
--  Copyright @ 2001          micro_mangal@yahoo.com                        --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  Filename : sertest2.cpp                                                 --
--  Author   : Mangal Dass                                           --
--  Created  : April 4th 2000                                               --
--  Modified : April 8th 2001                                               --
--  Plateform: Windows 95, 98, NT, 2000 (Win32)                             --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  This software is given without any warranty. It can be distributed      --
--  free of charge as long as this header remains, unchanged.               --
--                                                                          --
-- ------------------------------------------------------------------------ */




/* ---------------------------------------------------------------------- */
#ifndef TSERIAL_H
#define TSERIAL_H

#include <stdio.h>
#include <windows.h>


enum serial_parity  { spNONE,    spODD, spEVEN };


/* -------------------------------------------------------------------- */
/* -----------------------------  Tserial  ---------------------------- */
/* -------------------------------------------------------------------- */
class Tserial
{
    // -------------------------------------------------------- //
protected:
    char              port[10];                      // port name "com1",...
    int               rate;                          // baudrate
    serial_parity     parityMode;
    HANDLE            serial_handle;                 // ...

    // ++++++++++++++++++++++++++++++++++++++++++++++
    // .................. EXTERNAL VIEW .............
    // ++++++++++++++++++++++++++++++++++++++++++++++
public:
                  Tserial();
                 ~Tserial();
    int           connect          (char *port_arg, int rate_arg,
                                    serial_parity parity_arg);
    void          sendChar         (char c);
    void          sendArray        (char *buffer, int len);
    char          getChar          (void);
    int           getArray         (char *buffer, int len);
    int           getNbrOfBytes    (void);
    void          disconnect       (void);
};
/* -------------------------------------------------------------------- */

#endif TSERIAL_H


0
 
LVL 4

Expert Comment

by:havman56
ID: 9722118



/* ------------------------------------------------------------------------ --
--                                                                          --
--                        PC serial port connection object                  --
--                           for  event-driven programs                     --
--                                                                          --
--                                                                          --
--                                                                          --
--  Copyright @ 2001-2002      Mangal Dass                       --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  Filename : Tserial_event.cpp                                            --
--  Author   : Mangal dass                                            --
--  Created  : April 4th 2000                                               --
--  Modified : January 30th 2002                                            --
--  Plateform: Windows 95, 98, NT, 2000 (Win32)                             --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  This software is given without any warranty. It can be distributed      --
--  free of charge as long as this header remains, unchanged.               --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
-- 01.04.28      connect() function prototype modified to handle 7-bit      --
--                communication                                             --
-- 01.04.29      "ready" field added to remove a bug that occured during    --
--                 reconnect (event manager pointers cleared)               --
-- 02.01.30      Version 2.0 of the serial event object                     --
--                                                                          --
-- ------------------------------------------------------------------------ */


#ifndef TSERIAL_EVENT_H
#define TSERIAL_EVENT_H

#include <stdio.h>
#include <windows.h>


#define SERIAL_PARITY_NONE 0
#define SERIAL_PARITY_ODD  1
#define SERIAL_PARITY_EVEN 2

#define SERIAL_CONNECTED         0
#define SERIAL_DISCONNECTED      1
#define SERIAL_DATA_SENT         2
#define SERIAL_DATA_ARRIVAL      3
#define SERIAL_RING              4
#define SERIAL_CD_ON             5
#define SERIAL_CD_OFF            6

typedef unsigned long uint32;
typedef void (*type_myCallBack) (uint32 object, uint32 event);

#ifndef __BORLANDC__
#define bool  BOOL
#define true  TRUE
#define false FALSE
#endif


#define SERIAL_SIGNAL_NBR 7         // number of events in the thread
//#define SERIAL_MAX_RX     256       // Input buffer max size

#define SERIAL_MAX_RX  1024


//#define SERIAL_MAX_TX     256       // output buffer max size

//#define SERIAL_MAX_TX     3000
#define SERIAL_MAX_TX     4000




/* -------------------------------------------------------------------- */
/* -----------------------------  Tserial  ---------------------------- */
/* -------------------------------------------------------------------- */
class Tserial_event
{
    // -------------------------------------------------------- //
protected:
    bool          ready;
    bool          check_modem;
    char          port[10];                          // port name "com1",...
    int           rate;                              // baudrate
    int           parityMode;

    HANDLE        serial_events[SERIAL_SIGNAL_NBR];  // events to wait on
    unsigned int  threadid;                          // ...
    HANDLE        serial_handle;                     // ...
    OVERLAPPED    ovReader;                          // Overlapped structure for ReadFile
    OVERLAPPED    ovWriter;                          // Overlapped structure for WriteFile
    OVERLAPPED    ovWaitEvent;                       // Overlapped structure for WaitCommEvent
    char          tx_in_progress;                    // BOOL indicating if a WriteFile is
                                                     // in progress
    char          rx_in_progress;                    // BOOL indicating if a ReadFile is
                                                     // in progress
    char          WaitCommEventInProgress;
    char          rxBuffer[SERIAL_MAX_RX];
    int           max_rx_size;
    int           received_size;
    char          txBuffer[SERIAL_MAX_TX];
    int           tx_size;
    DWORD         dwCommEvent;                       // to store the result of the wait

    type_myCallBack manager;

    // ............................................................
    void          OnCharArrival    (char c);
    void          OnEvent          (unsigned long events);


    // ++++++++++++++++++++++++++++++++++++++++++++++
    // .................. EXTERNAL VIEW .............
    // ++++++++++++++++++++++++++++++++++++++++++++++
public:
    void          run          (void);
                  Tserial_event();
                 ~Tserial_event();
    int           connect          (char *port, int rate, int parity,
                                    char ByteSize, bool modem_events);

    void          setManager       (type_myCallBack manager);
    void          setRxSize        (int size);
    void          sendData         (char *buffer, int size);
    int           getNbrOfBytes    (void);
    int           getDataInSize    (void);
    char *        getDataInBuffer  (void);
    void          dataHasBeenRead  (void);
    void          disconnect       (void);
};
/* -------------------------------------------------------------------- */

/*mangal */


#endif TSERIAL_EVENT_H


0
 
LVL 4

Expert Comment

by:havman56
ID: 9722120



/* ------------------------------------------------------------------------ --
--                                                                          --
--                  Application example for using Tserial_event             --
--                                                                          --
--                                                                          --
--                                                                          --
--  Copyright @ 2001-2002     Mangal dass                             --
--                                                    --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--  Filename : serialtest.cpp                                               --
--  Author   : Mangal Dass                                           --
--  Plateform: Windows 95, 98, NT, 2000 (Win32)                             --
-- ------------------------------------------------------------------------ --
--                                                                          --
--
--                                                                          --
-- ------------------------------------------------------------------------ */




/* ---------------------------------------------------------------------- */
#ifdef __BORLANDC__
#pragma hdrstop             // borland specific
#include <condefs.h>
#pragma argsused
USEUNIT("Tserial_event.cpp");
//---------------------------------------------------------------------------
#endif

//---------------------------------------------------------------------------
#include "conio.h"
#include "Tserial_event.h"





/* ======================================================== */
/* ===============  OnCharArrival     ===================== */
/* ======================================================== */
void OnDataArrival(int size, char *buffer)
{
    if ((size>0) && (buffer!=0))
    {
        buffer[size] = 0;
     //   printf("OnDataArrival: %s ",buffer);
            printf("%s",buffer);
    }
}

/* ======================================================== */
/* ===============  OnCharArrival     ===================== */
/* ======================================================== */
void SerialEventManager(uint32 object, uint32 event)
{
    char *buffer;
    int   size;
    Tserial_event *com;

    com = (Tserial_event *) object;
    if (com!=0)
    {
        switch(event)
        {
            case  SERIAL_CONNECTED  :
                                        printf("Connected ! \n");
                                        break;
            case  SERIAL_DISCONNECTED  :
                                        printf("Disonnected ! \n");
                                        break;
            case  SERIAL_DATA_SENT  :
                                        printf("Data sent ! \n");
                                        break;
            case  SERIAL_RING       :
                                        printf("DRING ! \n");
                                        break;
            case  SERIAL_CD_ON      :
                                        printf("Carrier Detected ! \n");
                                        break;
            case  SERIAL_CD_OFF     :
                                        printf("No more carrier ! \n");
                                        break;
            case  SERIAL_DATA_ARRIVAL  :
                                        size   = com->getDataInSize();
                                        buffer = com->getDataInBuffer();
                                        OnDataArrival(size, buffer);
                                        com->dataHasBeenRead();
                                        break;
        }
    }
}
/* ======================================================== */
/* ========================   main  ======================= */
/* ======================================================== */
int main(int argc, char* argv[])
{
    int            c;
    int            erreur;
    char           txt[32];
    Tserial_event *com;
      int size;


    com = new Tserial_event();
    if (com!=0)
    {
        com->setManager(SerialEventManager);
        erreur = com->connect("COM1", 38400, SERIAL_PARITY_NONE, 8, true);
        if (!erreur)
        {
                   com->sendData("Hello World",11);
                  //com->sendData("10$8$",5);
                  
             
                  com->setRxSize(1);


            // ------------------
            do
            {
                c = getch();
                printf("_%c",c);
                txt[0] = c;
               com->sendData(txt, 1);
                com->setRxSize(1);
            }
            while (c!=32);

        }
        else
            printf("ERROR : com->connect (%ld)\n",erreur);
        // ------------------
        com->disconnect();

        // ------------------
        delete com;
        com = 0;
    }
    return 0;
}

0
 
LVL 4

Expert Comment

by:havman56
ID: 9722127



/* ------------------------------------------------------------------------ --
--                                                                          --
--                        PC serial port connection object                  --
--                           for  event-driven programs                     --
--                                                                          --
--                                                                          --
--                                                                          --
--  Copyright @ 2001-2002     Mangal Dass                           --
--                            micro_mangal@yahoo.com                        --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--

--                                                                          --
-- 01.04.24      Comments added                                             --
-- 01.04.28      Bug 010427 corrected. OnDisconnectedManager was not        --
--                initialized                                               --
-- 01.04.28      connect() function prototype modified to handle 7-bit      --
--                communication                                             --
-- 01.04.29      "ready" field added to remove a bug that occured during    --
--                 reconnect (event manager pointers cleared)               --
--                 I removed the "delete" in Tserial_event_thread_start     --
--                 because it was destroying the object even if we would    --
--                 use it again                                             --
--                                                                          --
-- 02.01.30      Version 2.0 of the serial event object                     --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ --
--                                                                          --
--    Note to Visual C++ users:  Don't forget to compile with the           --
--     "Multithreaded" option in your project settings                      --
--                                                                          --
--         See   Project settings                                           --
--                   |                                                      --
--                   *--- C/C++                                             --
--                          |                                               --
--                          *--- Code generation                            --
--                                       |                                  --
--                                       *---- Use run-time library         --
--                                                     |                    --
--                                                     *---- Multithreaded  --
--                                                                          --
--                                                                          --
--                                                                          --
-- ------------------------------------------------------------------------ */




/* ---------------------------------------------------------------------- */

#define STRICT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <windows.h>


#include "Tserial_event.h"

#define SIG_POWER_DOWN     0
#define SIG_READER         1
#define SIG_READ_DONE      2    // data received has been read
#define SIG_WRITER         3
#define SIG_DATA_TO_TX     4    // data waiting to be sent
#define SIG_MODEM_EVENTS   5
#define SIG_MODEM_CHECKED  6

void Tserial_event_thread_start(void *arg);

typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC) (LPVOID lpThreadParameter);
typedef unsigned *PBEGINTHREADEX_THREADID;

/* ---------------------------------------------------------------------- */
/* ---------------------  Tserial_event_thread_start  ------------------- */
/* ---------------------------------------------------------------------- */
/**
    This function is not part of the Tserial_event object. It is simply used
    to start the thread from an external point of the object.
*/
void Tserial_event_thread_start(void *arg)
{
    class Tserial_event *serial_unit;

    serial_unit = (Tserial_event *) arg;
   
    if (serial_unit!=0)
        serial_unit->run();
}

/* -------------------------------------------------------------------- */
/* -------------------------    Tserial_event ------------------------- */
/* -------------------------------------------------------------------- */
Tserial_event::Tserial_event()
{
    int i;

    ready            = false;
    parityMode       = SERIAL_PARITY_NONE;
    port[0]          = 0;
    rate             = 0;
    threadid         = 0;
    serial_handle    = INVALID_HANDLE_VALUE;
    tx_in_progress   = 0;
    rx_in_progress   = 0;
    max_rx_size      = 1;
    tx_size          = 0;
    received_size    = 0;
    check_modem      = false;

    manager          = 0;

    /* -------------------------------------------------------------- */
    // creating Events for the different sources
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)
    {
        if ((i==SIG_READER) || (i==SIG_WRITER) || (i==SIG_MODEM_EVENTS))
            serial_events[i] = CreateEvent(NULL, TRUE, FALSE, NULL);  // Manual Reset
        else
            serial_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL); // Auto reset
    }
}

/* -------------------------------------------------------------------- */
/* --------------------------    ~Tserial_event ----------------------- */
/* -------------------------------------------------------------------- */
Tserial_event::~Tserial_event()
{
    int i;

    /* -------------------------------------------------------- */
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)         // deleting the events
    {
        if (serial_events[i]!=INVALID_HANDLE_VALUE)
            CloseHandle(serial_events[i]);
        serial_events[i] = INVALID_HANDLE_VALUE;
    }

    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;
}
/* -------------------------------------------------------------------- */
/* --------------------------    disconnect   ------------------------- */
/* -------------------------------------------------------------------- */
void Tserial_event::disconnect(void)
{
    ready = false;
    SetEvent(serial_events[SIG_POWER_DOWN]);
}
/* -------------------------------------------------------------------- */
/* --------------------------    connect      ------------------------- */
/* -------------------------------------------------------------------- */
/**
     Serial port, file and overlapped structures initialization
*/
int  Tserial_event::connect (char *port_arg, int  rate_arg,  int parity_arg,
                             char ByteSize , bool modem_events)
{
    int  erreur;
    DCB  dcb;
    int  i;
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };

    /* --------------------------------------------- */
    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;

    if (port_arg!=0)
    {
        strncpy(port, port_arg, 10);
        rate        = rate_arg;
        parityMode  = parity_arg;
        check_modem = modem_events;

        erreur      = 0;
        ZeroMemory(&ovReader   ,sizeof(ovReader)   );  // clearing the overlapped
        ZeroMemory(&ovWriter   ,sizeof(ovWriter)   );
        ZeroMemory(&ovWaitEvent,sizeof(ovWaitEvent));
        memset(&dcb,0,sizeof(dcb));

        /* -------------------------------------------------------------------- */
        // set DCB to configure the serial port
        dcb.DCBlength       = sizeof(dcb);                  
       
        /* ---------- Serial Port Config ------- */
        dcb.BaudRate        = rate;

        switch(parityMode)
        {
            case SERIAL_PARITY_NONE:
                            dcb.Parity      = NOPARITY;
                            dcb.fParity     = 0;
                            break;
            case SERIAL_PARITY_EVEN:
                            dcb.Parity      = EVENPARITY;
                            dcb.fParity     = 1;
                            break;
            case SERIAL_PARITY_ODD:
                            dcb.Parity      = ODDPARITY;
                            dcb.fParity     = 1;
                            break;
        }


        dcb.StopBits        = ONESTOPBIT;
        dcb.ByteSize        = (BYTE) ByteSize;

        dcb.fOutxCtsFlow    = 0;
        dcb.fOutxDsrFlow    = 0;
        dcb.fDtrControl     = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity = 0;
        dcb.fRtsControl     = RTS_CONTROL_DISABLE;
        dcb.fOutX           = 0;
        dcb.fInX            = 0;
       
        /* ----------------- misc parameters ----- */
        dcb.fErrorChar      = 0;
        dcb.fBinary         = 1;
        dcb.fNull           = 0;
        dcb.fAbortOnError   = 0;
        dcb.wReserved       = 0;
        dcb.XonLim          = 2;
        dcb.XoffLim         = 4;
        dcb.XonChar         = 0x13;
        dcb.XoffChar        = 0x19;
        dcb.EvtChar         = 0;
       
        /* -------------------------------------------------------------------- */
        serial_handle    = CreateFile(port, GENERIC_READ | GENERIC_WRITE,
                   0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
                   // opening serial port

        ovReader.hEvent    = serial_events[SIG_READER];
        ovWriter.hEvent    = serial_events[SIG_WRITER];
        ovWaitEvent.hEvent = serial_events[SIG_MODEM_EVENTS];

        if (serial_handle    != INVALID_HANDLE_VALUE)
        {
            if (check_modem)
            {
                if(!SetCommMask(serial_handle, EV_RING | EV_RLSD))
                    erreur = 1;
            }
            else
            {
                if(!SetCommMask(serial_handle, 0))
                    erreur = 1;
            }

               
            // set timeouts
            if(!SetCommTimeouts(serial_handle,&cto))
                erreur = 2;

            // set DCB
            if(!SetCommState(serial_handle,&dcb))
                erreur = 4;
        }
        else
            erreur = 8;
    }
    else
        erreur = 16;


    /* --------------------------------------------- */
    for (i=0; i<SERIAL_SIGNAL_NBR; i++)
    {
        if (serial_events[i]==INVALID_HANDLE_VALUE)
            erreur = 32;
    }

    /* --------------------------------------------- */
    if (erreur!=0)
    {
        CloseHandle(serial_handle);
        serial_handle = INVALID_HANDLE_VALUE;
    }
    else
    {
        // start thread
        _beginthreadex(NULL,0,(PBEGINTHREADEX_THREADFUNC) Tserial_event_thread_start,
                  (void *) this, 0, &threadid);
    }

    /* --------------------------------------------- */
    return(erreur);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
void         Tserial_event::setManager(type_myCallBack manager_arg)
{
        manager = manager_arg;
}
/* -------------------------------------------------------------------- */
/* ---------------------           setRxSize      --------------------- */
/* -------------------------------------------------------------------- */
void         Tserial_event::setRxSize(int size)
{
        max_rx_size = size;
        if (max_rx_size>SERIAL_MAX_RX)
            max_rx_size = SERIAL_MAX_RX;
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
char *      Tserial_event::getDataInBuffer(void)
{
    return(rxBuffer);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
int      Tserial_event::getDataInSize(void)
{
    return(received_size);
}
/* -------------------------------------------------------------------- */
/* ---------------------           setManager     --------------------- */
/* -------------------------------------------------------------------- */
void   Tserial_event::dataHasBeenRead(void)
{
    SetEvent(serial_events[SIG_READ_DONE]);
}
/* -------------------------------------------------------------------- */
/* -----------------------   getNbrOfBytes  --------------------------- */
/* -------------------------------------------------------------------- */
int Tserial_event::getNbrOfBytes    (void)
{
    struct _COMSTAT status;
    int             n;
    unsigned long   etat;

    n = 0;

    if (serial_handle!=INVALID_HANDLE_VALUE)
    {
        ClearCommError(serial_handle, &etat, &status);
        n = status.cbInQue;
    }
    return(n);
}
/* -------------------------------------------------------------------- */
/* --------------------------    sendData     ------------------------- */
/* -------------------------------------------------------------------- */
void Tserial_event::sendData (char *buffer, int size)
{
    if ((!tx_in_progress) && (size<SERIAL_MAX_TX) && (buffer!=0))
    {
        tx_in_progress = 1;
        memcpy(txBuffer, buffer, size);
        tx_size = size;
        SetEvent(serial_events[SIG_DATA_TO_TX]);
        // indicating data to be sent
    }
}
/* -------------------------------------------------------------------- */
/* --------------------------    OnEvent      ------------------------- */
/* -------------------------------------------------------------------- */
void Tserial_event::OnEvent (unsigned long events)
{
    unsigned long ModemStat;

    GetCommModemStatus(serial_handle, &ModemStat);

    if ((events & EV_RING)!=0)
    {
        if ((ModemStat &  MS_RING_ON)!= 0)
        {
            if (manager!=0)
                manager((uint32) this, SERIAL_RING);
        }
    }

    if ((events & EV_RLSD)!=0)
    {
        if ((ModemStat &  MS_RLSD_ON)!= 0)
        {
            if (manager!=0)
                manager((uint32) this, SERIAL_CD_ON);
        }
        else
        {
            if (manager!=0)
                manager((uint32) this, SERIAL_CD_OFF);
        }
    }
}
/* -------------------------------------------------------------------- */
/* --------------------------       run       ------------------------- */
/* -------------------------------------------------------------------- */

/**
 this function is the main loop of the Tserial object. There is a
 do while() loop executed until either an error or a PowerDown is
 received.
 this is not a busy wait since we use the WaitForMultipleObject function
*/

/* * /
#define DEBUG_EVENTS
/* */

void Tserial_event::run(void)
{
    bool          done;
    long          status;
    unsigned long read_nbr, result_nbr;
    char          success;

    ready                   = true;
    done                    = false;
    tx_in_progress          = 0;
    rx_in_progress          = 0;
    WaitCommEventInProgress = 0;

    if (manager!=0)
        manager((uint32) this, SERIAL_CONNECTED);

    GetLastError();               // just to clear any pending error
    SetEvent(serial_events[SIG_READ_DONE]);
    if (check_modem)
        SetEvent(serial_events[SIG_MODEM_CHECKED]);

    /* ----------------------------------------------------------- */
    while(!done)
    {
        /* ------------------------------------------------------------------ */
        /*                                                                    */
        /*                                                                    */
        /*                                                                    */
        /*                          Waiting  for signals                      */
        /*                                                                    */
        /*                                                                    */
        /*                                                                    */
        /* ------------------------------------------------------------------ */
        // Main wait function. Waiting for something to happen.
        // This may be either the completion of a Read or a Write or
        // the reception of modem events, Power Down, new Tx
        //
        status = WaitForMultipleObjects(SERIAL_SIGNAL_NBR, serial_events,
                                        FALSE, INFINITE);

        // processing answer to filter other failures
        status = status - WAIT_OBJECT_0;
        if ((status<0) || (status>=SERIAL_SIGNAL_NBR))
            done=true;   // error
        else
        {
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
            /* ++++++++++++++++++++ EVENT DISPATCHER ++++++++++++++++++ */
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
            switch(status)
            {
                /* ######################################################## */
                case SIG_POWER_DOWN:
                    // receiving a POWER down signal. Stopping the thread
                    done = true;
                    break;
                /* ######################################################## */
                /* #                                                      # */
                /* #                                                      # */
                /* #                       RX                             # */
                /* #                                                      # */
                /* #                                                      # */
                /* ######################################################## */
                case SIG_READ_DONE:
                    // previous reading is finished
                    // I start a new one here
                    if (!rx_in_progress)
                    {
                        // locking reading
                        rx_in_progress = 1;
                        // starting a new read
                        success = (char) ReadFile(serial_handle,&rxBuffer,
                                         max_rx_size,&read_nbr,&ovReader);
                        if (!success)
                        {
                            // failure
                            if(GetLastError() != ERROR_IO_PENDING )
                            {
                                // real failure => quiting
                                done = true;
                                #ifdef DEBUG_EVENTS
                                printf("Readfile error (not pending)\n");
                                #endif DEBUG_EVENTS
                            }
                            #ifdef DEBUG_EVENTS
                            else
                                printf("ReadFile pending\n");
                            #endif DEBUG_EVENTS
                        }
                        #ifdef DEBUG_EVENTS
                        else
                        {
                            // I make nothing here since the overlapped
                            // will be signaled anyway, so I'll make
                            // the processing there
                            printf("ReadFile immediate success\n");
                        }
                        #endif
                    }
                    break;
                /* ######################################################## */
                case SIG_READER:
                    // reading the result of the terminated read
                    //BOOL GetOverlappedResult(
                    //    HANDLE hFile,      // handle of file, pipe, or communications device
                    //    LPOVERLAPPED lpOverlapped,      // address of overlapped structure
                    //    LPDWORD lpNumberOfBytesTransferred,      // address of actual bytes count
                    //    BOOL bWait       // wait flag
                    //   );
                    //
                    if (GetOverlappedResult(serial_handle, &ovReader,
                        &result_nbr, FALSE))
                    {
                        #ifdef DEBUG_EVENTS
                            printf("ReadFile => GetOverlappedResult done\n");
                        #endif DEBUG_EVENTS
                        // no error => OK
                        // Read operation completed successfully
                        ResetEvent(serial_events[SIG_READER]);
                        // Write operation completed successfully
                        received_size  = result_nbr;
                        rx_in_progress = 0; // read has ended
                        // if incoming data, I process them
                        if ((result_nbr!=0) &&(manager!=0))
                            manager((uint32) this, SERIAL_DATA_ARRIVAL);
                        // I automatically restart a new read once the
                        // previous is completed.
                        SetEvent(serial_events[SIG_READ_DONE]);

                    }
                    else
                    {
                        // GetOverlapped didn't succeed !
                        // What's the reason ?
                        if(GetLastError()!= ERROR_IO_PENDING )
                            done = 1;  // failure
                    }
                    break;
                /* ######################################################## */
                /* #                                                      # */
                /* #                                                      # */
                /* #                       TX                             # */
                /* #                                                      # */
                /* #                                                      # */
                /* ######################################################## */
                case SIG_DATA_TO_TX:
                    // Signal asserted that there is a new valid message
                    // in the "txBuffer" variable
                    // sending data to the port
                    success = (char) WriteFile(serial_handle, txBuffer, tx_size,
                                        &result_nbr, &ovWriter);
                        if (!success)
                        {
                            // ouups, failure
                            if(GetLastError() != ERROR_IO_PENDING )
                            {
                                // real failure => quiting
                                done = true;
                                #ifdef DEBUG_EVENTS
                                printf("WriteFile error (not pending)\n");
                                #endif DEBUG_EVENTS
                            }
                            #ifdef DEBUG_EVENTS
                            else
                                printf("WriteFile pending\n");
                            #endif DEBUG_EVENTS
                        }
                        #ifdef DEBUG_EVENTS
                        else
                        {
                            // I make nothing here since the overlapped
                            // will be signaled anyway, so I'll make
                            // the processing there
                            printf("WriteFile immediate success\n");
                        }
                        #endif
                    break;
                /* ######################################################## */
                case SIG_WRITER:
                    // WriteFile has terminated
                    // checking the result of the operation
                    if (GetOverlappedResult(serial_handle, &ovWriter,
                        &result_nbr, FALSE))
                    {
                        // Write operation completed successfully
                        ResetEvent(serial_events[SIG_WRITER]);
                        // further write are now allowed
                        tx_in_progress = 0;
                        // telling it to the manager
                        if (manager!=0)
                            manager((uint32) this, SERIAL_DATA_SENT);
                    }
                    else
                    {
                        // GetOverlapped didn't succeed !
                        // What's the reason ?
                        if(GetLastError() != ERROR_IO_PENDING )
                            done = 1;  // failure
                    }
                    break;
                /* ######################################################## */
                /* #                                                      # */
                /* #                                                      # */
                /* #                    MODEM_EVENTS EVENTS                      # */
                /* #                                                      # */
                /* #                                                      # */
                /* ######################################################## */
                case SIG_MODEM_CHECKED:
                    if ((!WaitCommEventInProgress) && check_modem)
                    // if no wait is in progress I start a new one
                    {            
                        WaitCommEventInProgress=1;
                        success = (char) WaitCommEvent(serial_handle,&dwCommEvent,
                                                       &ovWaitEvent);
                        // reading one byte only to have immediate answer on each byte
                        if (!success)
                        {
                            // ouups, failure
                            if(GetLastError() != ERROR_IO_PENDING )
                            {
                                // real failure => quiting
                                done = true;
                                #ifdef DEBUG_EVENTS
                                printf("WaitCommEvent error (not pending)\n");
                                #endif DEBUG_EVENTS
                            }
                            #ifdef DEBUG_EVENTS
                            else
                                printf("WaitCommEvent pending\n");
                            #endif DEBUG_EVENTS
                        }
                        #ifdef DEBUG_EVENTS
                        else
                        {
                            // I make nothing here since the overlapped
                            // will be signaled anyway, so I'll make
                            // the processing there
                            printf("WaitCommEvent immediate success\n");
                        }
                        #endif
                    }
                    break;
                /* ######################################################## */
                case SIG_MODEM_EVENTS:
                    // reading the result of the terminated wait
                    if (GetOverlappedResult(serial_handle, &ovWaitEvent,
                        &result_nbr, FALSE))
                    {
                        // Wait operation completed successfully
                        ResetEvent(serial_events[SIG_MODEM_EVENTS]);
                        WaitCommEventInProgress = 0;
                        // if incoming data, I process them
                        OnEvent(dwCommEvent);
                        // automatically starting a new check
                        SetEvent(serial_events[SIG_MODEM_CHECKED]);
                    }
                    else
                    {
                        // GetOverlapped didn't succeed !
                        // What's the reason ?
                        if(GetLastError() != ERROR_IO_PENDING )
                            done = 1;  // failure
                    }
                    break;
                /* ######################################################## */
            }
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
            /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
        }
    };

    // --------------------- Disconnecting ----------------
    ready = false;
    if (serial_handle!=INVALID_HANDLE_VALUE)
        CloseHandle(serial_handle);
    serial_handle = INVALID_HANDLE_VALUE;

    if (manager!=0)
        manager((uint32) this, SERIAL_DISCONNECTED);
}
/* -------------------------------------------------------------------- */
/* -------------------------------------------------------------------- */

0
 
LVL 4

Expert Comment

by:havman56
ID: 9722139
use it it is my gift for u .......it works pretty fine i aldready tested on lot of boards.
0
 
LVL 4

Expert Comment

by:havman56
ID: 9722151
i have not developed everything from scratch . i used some free code then i modified to get what i need.
 ;) :)
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10248878
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Split: AlexFM {http:#9720384} & havman56 {http:#9722111}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question