Subversion Repositories HomeAutomation

Rev

Rev 270 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. //  Serial.h - Definition of the CSerial class
  2. //
  3. //  Copyright (C) 1999-2003 Ramon de Klein (Ramon.de.Klein@ict.nl)
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; either
  8. // version 2.1 of the License, or (at your option) any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.  
  20. #ifndef __SERIAL_H
  21. #define __SERIAL_H
  22.  
  23.  
  24. //////////////////////////////////////////////////////////////////////
  25. // The SERIAL_DEFAULT_OVERLAPPED defines if the default open mode uses
  26. // overlapped I/O. When overlapped I/O is available (normal Win32
  27. // platforms) it uses overlapped I/O. Windows CE doesn't allow the use
  28. // of overlapped I/O, so it is disabled there by default.
  29.  
  30. #ifndef SERIAL_DEFAULT_OVERLAPPED
  31. #ifndef SERIAL_NO_OVERLAPPED
  32. #define SERIAL_DEFAULT_OVERLAPPED   true
  33. #else
  34. #define SERIAL_DEFAULT_OVERLAPPED   false
  35. #endif
  36. #endif
  37.  
  38.  
  39. //////////////////////////////////////////////////////////////////////
  40. //
  41. // CSerial - Win32 wrapper for serial communications
  42. //
  43. // Serial communication often causes a lot of problems. This class
  44. // tries to supply an easy to use interface to deal with serial
  45. // devices.
  46. //
  47. // The class is actually pretty ease to use. You only need to open
  48. // the COM-port, where you need to specify the basic serial
  49. // communication parameters. You can also choose to setup handshaking
  50. // and read timeout behaviour.
  51. //
  52. // The following serial classes are available:
  53. //
  54. // CSerial      - Serial communication support.
  55. // CSerialEx    - Serial communication with listener thread for events
  56. // CSerialSync  - Serial communication with synchronized event handler
  57. // CSerialWnd   - Asynchronous serial support, which uses the Win32
  58. //                message queue for event notification.
  59. // CSerialMFC   - Preferred class to use in MFC-based GUI windows.
  60. //
  61. //
  62. // Pros:
  63. // -----
  64. //  - Easy to use (hides a lot of nasty Win32 stuff)
  65. //  - Fully ANSI and Unicode aware
  66. //
  67. // Cons:
  68. // -----
  69. //  - Little less flexibility then native Win32 API, however you can
  70. //    use this API at the same time for features which are missing
  71. //    from this class.
  72. //  - Incompatible with Windows 95 or Windows NT v3.51 (or earlier),
  73. //    because CancelIo isn't support on these platforms. Define the
  74. //    SERIAL_NO_CANCELIO macro for support of these platforms as
  75. //    well. When this macro is defined, then only time-out values of
  76. //    0 or INFINITE are valid.
  77. //
  78. //
  79. // Copyright (C) 1999-2003 Ramon de Klein
  80. //                         (Ramon.de.Klein@ict.nl)
  81.  
  82. class CSerial
  83. {
  84. // Class enumerations
  85. public:
  86.     // Communication event
  87.     typedef enum
  88.     {
  89.         EEventUnknown      = -1,            // Unknown event
  90.         EEventNone         = 0,             // Event trigged without cause
  91.         EEventBreak        = EV_BREAK,      // A break was detected on input
  92.         EEventCTS          = EV_CTS,        // The CTS signal changed state
  93.         EEventDSR          = EV_DSR,        // The DSR signal changed state
  94.         EEventError        = EV_ERR,        // A line-status error occurred
  95.         EEventRing         = EV_RING,       // A ring indicator was detected
  96.         EEventRLSD         = EV_RLSD,       // The RLSD signal changed state
  97.         EEventRecv         = EV_RXCHAR,     // Data is received on input
  98.         EEventRcvEv        = EV_RXFLAG,     // Event character was received on input
  99.         EEventSend         = EV_TXEMPTY,    // Last character on output was sent
  100.         EEventPrinterError = EV_PERR,       // Printer error occured
  101.         EEventRx80Full     = EV_RX80FULL,   // Receive buffer is 80 percent full
  102.         EEventProviderEvt1 = EV_EVENT1,     // Provider specific event 1
  103.         EEventProviderEvt2 = EV_EVENT2,     // Provider specific event 2
  104.     }
  105.     EEvent;
  106.  
  107.     // Baudrate
  108.     typedef enum
  109.     {
  110.         EBaudUnknown = -1,          // Unknown
  111.         EBaud110     = CBR_110,     // 110 bits/sec
  112.         EBaud300     = CBR_300,     // 300 bits/sec
  113.         EBaud600     = CBR_600,     // 600 bits/sec
  114.         EBaud1200    = CBR_1200,    // 1200 bits/sec
  115.         EBaud2400    = CBR_2400,    // 2400 bits/sec
  116.         EBaud4800    = CBR_4800,    // 4800 bits/sec
  117.         EBaud9600    = CBR_9600,    // 9600 bits/sec
  118.         EBaud14400   = CBR_14400,   // 14400 bits/sec
  119.         EBaud19200   = CBR_19200,   // 19200 bits/sec (default)
  120.         EBaud38400   = CBR_38400,   // 38400 bits/sec
  121.         EBaud56000   = CBR_56000,   // 56000 bits/sec
  122.         EBaud57600   = CBR_57600,   // 57600 bits/sec
  123.         EBaud115200  = CBR_115200,  // 115200 bits/sec
  124.         EBaud128000  = CBR_128000,  // 128000 bits/sec
  125.         EBaud256000  = CBR_256000,  // 256000 bits/sec
  126.     }
  127.     EBaudrate;
  128.  
  129.     // Data bits (5-8)
  130.     typedef enum
  131.     {
  132.         EDataUnknown = -1,          // Unknown
  133.         EData5       =  5,          // 5 bits per byte
  134.         EData6       =  6,          // 6 bits per byte
  135.         EData7       =  7,          // 7 bits per byte
  136.         EData8       =  8           // 8 bits per byte (default)
  137.     }
  138.     EDataBits;
  139.  
  140.     // Parity scheme
  141.     typedef enum
  142.     {
  143.         EParUnknown = -1,           // Unknown
  144.         EParNone    = NOPARITY,     // No parity (default)
  145.         EParOdd     = ODDPARITY,    // Odd parity
  146.         EParEven    = EVENPARITY,   // Even parity
  147.         EParMark    = MARKPARITY,   // Mark parity
  148.         EParSpace   = SPACEPARITY   // Space parity
  149.     }
  150.     EParity;
  151.  
  152.     // Stop bits
  153.     typedef enum
  154.     {
  155.         EStopUnknown = -1,          // Unknown
  156.         EStop1       = ONESTOPBIT,  // 1 stopbit (default)
  157.         EStop1_5     = ONE5STOPBITS,// 1.5 stopbit
  158.         EStop2       = TWOSTOPBITS  // 2 stopbits
  159.     }
  160.     EStopBits;
  161.  
  162.     // Handshaking
  163.     typedef enum
  164.     {
  165.         EHandshakeUnknown       = -1,   // Unknown
  166.         EHandshakeOff           =  0,   // No handshaking
  167.         EHandshakeHardware      =  1,   // Hardware handshaking (RTS/CTS)
  168.         EHandshakeSoftware      =  2    // Software handshaking (XON/XOFF)
  169.     }
  170.     EHandshake;
  171.  
  172.     // Timeout settings
  173.     typedef enum
  174.     {
  175.         EReadTimeoutUnknown     = -1,   // Unknown
  176.         EReadTimeoutNonblocking =  0,   // Always return immediately
  177.         EReadTimeoutBlocking    =  1    // Block until everything is retrieved
  178.     }
  179.     EReadTimeout;
  180.  
  181.     // Communication errors
  182.     typedef enum
  183.     {
  184.         EErrorUnknown = 0,          // Unknown
  185.         EErrorBreak   = CE_BREAK,   // Break condition detected
  186.         EErrorFrame   = CE_FRAME,   // Framing error
  187.         EErrorIOE     = CE_IOE,     // I/O device error
  188.         EErrorMode    = CE_MODE,    // Unsupported mode
  189.         EErrorOverrun = CE_OVERRUN, // Character buffer overrun, next byte is lost
  190.         EErrorRxOver  = CE_RXOVER,  // Input buffer overflow, byte lost
  191.         EErrorParity  = CE_RXPARITY,// Input parity error
  192.         EErrorTxFull  = CE_TXFULL   // Output buffer full
  193.     }
  194.     EError;
  195.  
  196.     // Port availability
  197.     typedef enum
  198.     {
  199.         EPortUnknownError = -1,     // Unknown error occurred
  200.         EPortAvailable    =  0,     // Port is available
  201.         EPortNotAvailable =  1,     // Port is not present
  202.         EPortInUse        =  2      // Port is in use
  203.  
  204.     }
  205.     EPort;
  206.  
  207. // Construction
  208. public:
  209.     CSerial();
  210.     virtual ~CSerial();
  211.  
  212. // Operations
  213. public:
  214.     // Check if particular COM-port is available (static method).
  215.     static EPort CheckPort (LPCTSTR lpszDevice);
  216.  
  217.     // Open the serial communications for a particular COM port. You
  218.     // need to use the full devicename (i.e. "COM1") to open the port.
  219.     // It's possible to specify the size of the input/output queues.
  220.     virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 0, DWORD dwOutQueue = 0, bool fOverlapped = SERIAL_DEFAULT_OVERLAPPED);
  221.  
  222.     // Close the serial port.
  223.     virtual LONG Close (void);
  224.  
  225.     // Setup the communication settings such as baudrate, databits,
  226.     // parity and stopbits. The default settings are applied when the
  227.     // device has been opened. Call this function if these settings do
  228.     // not apply for your application. If you prefer to use integers
  229.     // instead of the enumerated types then just cast the integer to
  230.     // the required type. So the following two initializations are
  231.     // equivalent:
  232.     //
  233.     //   Setup(EBaud9600,EData8,EParNone,EStop1)
  234.     //
  235.     // or
  236.     //
  237.     //   Setup(EBaudrate(9600),EDataBits(8),EParity(NOPARITY),EStopBits(ONESTOPBIT))
  238.     //
  239.     // In the latter case, the types are not validated. So make sure
  240.     // that you specify the appropriate values.
  241.     virtual LONG Setup (EBaudrate eBaudrate = EBaud9600,
  242.                         EDataBits eDataBits = EData8,
  243.                         EParity   eParity   = EParNone,
  244.                         EStopBits eStopBits = EStop1);
  245.  
  246.     // Set/clear the event character. When this byte is being received
  247.     // on the serial port then the EEventRcvEv event is signalled,
  248.     // when the mask has been set appropriately. If the fAdjustMask flag
  249.     // has been set, then the event mask is automatically adjusted.
  250.     virtual LONG SetEventChar (BYTE bEventChar, bool fAdjustMask = true);
  251.  
  252.     // Set the event mask, which indicates what events should be
  253.     // monitored. The WaitEvent method can only monitor events that
  254.     // have been enabled. The default setting only monitors the
  255.     // error events and data events. An application may choose to
  256.     // monitor CTS. DSR, RLSD, etc as well.
  257.     virtual LONG SetMask (DWORD dwMask = EEventBreak|EEventError|EEventRecv);
  258.  
  259.     // The WaitEvent method waits for one of the events that are
  260.     // enabled (see SetMask).
  261.     virtual LONG WaitEvent (LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  262.  
  263.     // Setup the handshaking protocol. There are three forms of
  264.     // handshaking:
  265.     //
  266.     // 1) No handshaking, so data is always send even if the receiver
  267.     //    cannot handle the data anymore. This can lead to data loss,
  268.     //    when the sender is able to transmit data faster then the
  269.     //    receiver can handle.
  270.     // 2) Hardware handshaking, where the RTS/CTS lines are used to
  271.     //    indicate if data can be sent. This mode requires that both
  272.     //    ports and the cable support hardware handshaking. Hardware
  273.     //    handshaking is the most reliable and efficient form of
  274.     //    handshaking available, but is hardware dependant.
  275.     // 3) Software handshaking, where the XON/XOFF characters are used
  276.     //    to throttle the data. A major drawback of this method is that
  277.     //    these characters cannot be used for data anymore.
  278.     virtual LONG SetupHandshaking (EHandshake eHandshake);
  279.  
  280.     // Read operations can be blocking or non-blocking. You can use
  281.     // this method to setup wether to use blocking or non-blocking
  282.     // reads. Non-blocking reads is the default, which is required
  283.     // for most applications.
  284.     //
  285.     // 1) Blocking reads, which will cause the 'Read' method to block
  286.     //    until the requested number of bytes have been read. This is
  287.     //    useful if you know how many data you will receive.
  288.     // 2) Non-blocking reads, which will read as many bytes into your
  289.     //    buffer and returns almost immediately. This is often the
  290.     //    preferred setting.
  291.     virtual LONG SetupReadTimeouts (EReadTimeout eReadTimeout);
  292.  
  293.     // Obtain communication settings
  294.     virtual EBaudrate  GetBaudrate    (void);
  295.     virtual EDataBits  GetDataBits    (void);
  296.     virtual EParity    GetParity      (void);
  297.     virtual EStopBits  GetStopBits    (void);
  298.     virtual EHandshake GetHandshaking (void);
  299.     virtual DWORD      GetEventMask   (void);
  300.     virtual BYTE       GetEventChar   (void);
  301.  
  302.     // Write data to the serial port. Note that we are only able to
  303.     // send ANSI strings, because it probably doesn't make sense to
  304.     // transmit Unicode strings to an application.
  305.     virtual LONG Write (const void* pData, size_t iLen, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  306.     virtual LONG Write (LPCSTR pString, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  307.  
  308.     // Read data from the serial port. Refer to the description of
  309.     // the 'SetupReadTimeouts' for an explanation about (non) blocking
  310.     // reads and how to use this.
  311.     virtual LONG Read (void* pData, size_t iLen, DWORD* pdwRead = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  312.  
  313.     // Send a break
  314.     LONG Break (void);
  315.  
  316.     // Determine what caused the event to trigger
  317.     EEvent GetEventType (void);
  318.  
  319.     // Obtain the error
  320.     EError GetError (void);
  321.  
  322.     // Obtain the COMM and event handle
  323.     HANDLE GetCommHandle (void)     { return m_hFile; }
  324.  
  325.     // Check if com-port is opened
  326.     bool IsOpen (void) const        { return (m_hFile != 0); }
  327.  
  328.     // Obtain last error status
  329.     LONG GetLastError (void) const  { return m_lLastError; }
  330.  
  331.     // Obtain CTS/DSR/RING/RLSD settings
  332.     bool GetCTS (void);
  333.     bool GetDSR (void);
  334.     bool GetRing (void);
  335.     bool GetRLSD (void);
  336.  
  337.     // Purge all buffers
  338.     LONG Purge (void);
  339.  
  340. protected:
  341.     // Internal helper class which wraps DCB structure
  342.     class CDCB : public DCB
  343.     {
  344.     public:
  345.         CDCB() { DCBlength = sizeof(DCB); }
  346.     };
  347.  
  348. // Attributes
  349. protected:
  350.     LONG    m_lLastError;       // Last serial error
  351.     HANDLE  m_hFile;            // File handle
  352.     EEvent  m_eEvent;           // Event type
  353.     DWORD   m_dwEventMask;      // Event mask
  354.  
  355. #ifndef SERIAL_NO_OVERLAPPED
  356.     HANDLE  m_hevtOverlapped;   // Event handle for internal overlapped operations
  357. #endif
  358.  
  359. protected:
  360.     // Check the requirements
  361.     void CheckRequirements (LPOVERLAPPED lpOverlapped, DWORD dwTimeout) const;
  362.  
  363.     // CancelIo wrapper (for Win95 compatibility)
  364.     BOOL CancelCommIo (void);
  365. };
  366.  
  367. #endif  // __SERIAL_H
  368.