]> git.gag.com Git - fw/sdcc/blobdiff - device/examples/serialcomm/windows/serial.c
* device/examples/serialcomm/windows/serial.[ch],
[fw/sdcc] / device / examples / serialcomm / windows / serial.c
diff --git a/device/examples/serialcomm/windows/serial.c b/device/examples/serialcomm/windows/serial.c
new file mode 100755 (executable)
index 0000000..b42338d
--- /dev/null
@@ -0,0 +1,280 @@
+/*-------------------------------------------------------------------------
+   Serial library functions for the Windows OS (95-XP)
+   Tested with different versions of MS Visual Studio (C ad C++)
+
+   Written by -  Bela Torok / www.torok.info & www.belatorok.com (February 2006)
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License (http://www.gnu.org/licenses/gpl.txt).
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#include <Windows.h>
+#include <stdio.h>
+
+#include "serial.h"
+#define ASCII_XON       0x11
+#define ASCII_XOFF      0x13
+
+HANDLE SerialInit(char *ComPortName, DWORD BaudRate, int ByteSize, int StopBit, char ParityChar, char Protocol, int RxTimeOut, int TxTimeOut, int RxBufSize, int TxBufSize) 
+{
+       HANDLE                  hCom;
+       BOOL                    bPortReady;
+       DCB                             dcb;
+       COMMTIMEOUTS    CommTimeouts;
+       int                             Parity;
+
+       switch(ParityChar) {
+               case 'N':
+               case 'n':
+                       Parity = NOPARITY;
+                       break;
+               case 'E':
+               case 'e':
+                       Parity = EVENPARITY;
+                       break;
+               case 'O':
+               case 'o':
+                       Parity = ODDPARITY;
+                       break;
+               default:
+                       return NULL;    // illegal parameter !
+       }
+       
+       switch(StopBit)
+       {
+               case 1:
+                       StopBit = ONESTOPBIT;
+                       break;
+               case 2:
+                       StopBit = TWOSTOPBITS;
+                       break;
+               default:
+                       return NULL;    // illegal parameter !
+       }
+
+       hCom = CreateFile(      ComPortName, 
+                                               GENERIC_READ | GENERIC_WRITE,
+                                               0, // exclusive access
+                                               NULL, // no security
+                                               OPEN_EXISTING,
+                                               0, // no overlapped I/O
+                                               NULL); // null template 
+
+       if(hCom == INVALID_HANDLE_VALUE) return NULL;
+
+       bPortReady = SetupComm(hCom, RxBufSize, TxBufSize); // set Rx and Tx buffer sizes
+
+       // Port settings are specified in a Data Communication Block (DCB). 
+
+       bPortReady = GetCommState(hCom, &dcb);
+
+       dcb.BaudRate    = BaudRate;
+       dcb.ByteSize    = ByteSize;
+       dcb.Parity              = Parity;
+       dcb.StopBits    = StopBit;
+       dcb.fAbortOnError = TRUE;
+
+       switch(Protocol) {
+       case 'D':       // DTR/DSR
+       case 'd':
+               // set XON/XOFF
+               dcb.fOutX       = FALSE;
+               dcb.fInX        = FALSE;
+               // set RTSCTS
+               dcb.fOutxCtsFlow = FALSE;
+               dcb.fRtsControl = RTS_CONTROL_DISABLE; 
+               // set DSRDTR
+               dcb.fOutxDsrFlow = TRUE;
+               dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; 
+               break;
+       case 'R':       // RTS/CTS
+       case 'r':
+               // set XON/XOFF
+               dcb.fOutX       = FALSE;
+               dcb.fInX        = FALSE;
+               // set RTSCTS
+               dcb.fOutxCtsFlow = TRUE;
+               dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; 
+               // set DSRDTR
+               dcb.fOutxDsrFlow = FALSE;
+               dcb.fDtrControl = DTR_CONTROL_DISABLE; 
+               break;
+       case 'X':       // XON/XOFF
+       case 'x':
+               // set XON/XOFF
+               dcb.fOutX       = TRUE;
+               dcb.fInX        = TRUE;
+               dcb.fTXContinueOnXoff = TRUE;
+               dcb.XoffChar = ASCII_XOFF;
+               dcb.XoffLim = RxBufSize - (RxBufSize / 4);
+               dcb.XonChar = ASCII_XON;
+               dcb.XonLim = RxBufSize - (RxBufSize / 2);
+               // set RTSCTS
+               dcb.fOutxCtsFlow = FALSE;
+               dcb.fRtsControl = RTS_CONTROL_DISABLE; 
+               // set DSRDTR
+               dcb.fOutxDsrFlow = FALSE;
+               dcb.fDtrControl = DTR_CONTROL_DISABLE;
+               break;
+       case 'N':       // NOPROTOCOL
+       case 'n':
+       default:
+               // set XON/XOFF
+               dcb.fOutX       = FALSE;
+               dcb.fInX        = FALSE;
+               // set RTSCTS
+               dcb.fOutxCtsFlow = FALSE;
+               dcb.fRtsControl = RTS_CONTROL_DISABLE; 
+               // set DSRDTR
+               dcb.fOutxDsrFlow = FALSE;
+               dcb.fDtrControl = DTR_CONTROL_DISABLE; 
+               break;
+       }
+
+       bPortReady = SetCommState(hCom, &dcb);
+
+       // Set timeouts
+       CommTimeouts.ReadIntervalTimeout = RxTimeOut;
+       CommTimeouts.ReadTotalTimeoutMultiplier = 0;
+       CommTimeouts.ReadTotalTimeoutConstant = RxTimeOut;
+
+       CommTimeouts.WriteTotalTimeoutMultiplier = 0;
+       CommTimeouts.WriteTotalTimeoutConstant = TxTimeOut;
+
+       bPortReady = SetCommTimeouts(hCom, &CommTimeouts);
+
+       return hCom;
+}
+
+void SerialClose(HANDLE hSerial) {
+       CloseHandle(hSerial);
+}
+
+int SerialGetc(HANDLE hSerial)
+{
+       unsigned char rxchar;
+       BOOL    bReadRC;
+       static  DWORD iBytesRead, dwError;
+
+       if(hSerial == NULL) return 0;
+
+       bReadRC = ReadFile(hSerial, &rxchar, 1, &iBytesRead, NULL);
+
+       if(bReadRC == FALSE) { // error
+
+               ClearCommError(hSerial, &dwError, NULL);
+
+//             PurgeComm(hSerial,  PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
+//             PurgeComm(hSerial,  PURGE_RXCLEAR | PURGE_TXCLEAR);
+
+               if(dwError == 0) return TIMEOUT;                // no error, iBytesRead is probably == 0
+               if(dwError & CE_BREAK) return BREAK;    // break detected
+               if(dwError & CE_FRAME) return BREAK;    // framing error
+
+               /*      One, or a combination of the following conditions:
+                       CE_IOE          -> 0x0400 I/O error during communication with the device
+                       CE_OVERRUN      -> 0x0002 character-buffer overrun, the next character is lost
+                       CE_RXOVER       -> 0x0001 input buffer overflow, no room in the input buffer,
+                                             or a character was received after the EOF character
+                       CE_RXPARITY     -> 0x0004 parity error
+                       CE_TXFULL       -> 0x0100 transmit buffer is full
+               */
+               if(dwError & CE_IOE) printf("SerialGetc() I/O error during communication with the device!\n");
+               if(dwError & CE_OVERRUN) printf("SerialGetc() Character-buffer overrun, the next character is lost!\n");
+               if(dwError & CE_RXOVER) printf("SerialGetc() Input buffer overflow!\n");
+               if(dwError & CE_RXPARITY) printf("SerialGetc() Parity error!\n");
+               if(dwError & CE_TXFULL) printf("SerialGetc() Transmit buffer is full!\n");
+               return SERIAL_ERROR;
+       }
+
+       if(iBytesRead == 0) return TIMEOUT; // Timeout occured
+
+       return (int) rxchar;
+}
+
+
+int SerialPutc(HANDLE hCom, char txchar)
+{
+       BOOL    bWriteRC;
+       static  DWORD   iBytesWritten;
+
+       if(hCom == NULL) return -255;
+       
+       bWriteRC = WriteFile(hCom, &txchar, 1, &iBytesWritten,NULL);
+
+       if(iBytesWritten = 1) return 0;
+
+       return TIMEOUT;
+}
+
+char SerialGets(char *rxstring, int MaxNumberOfCharsToRead, HANDLE hCom)
+{
+       int c;
+       int pos = 0;
+       unsigned char success = 0; // set to error
+
+       if(hCom == NULL) return success; // Error!
+
+       while(pos <= MaxNumberOfCharsToRead) {
+               c = SerialGetc(hCom);
+
+               if(c == TIMEOUT) return success;  // Error
+               if(c == '\n') break;
+               if(c != '\r') rxstring[pos++] = (char) c;       // discard carriage return
+       }
+       rxstring[pos] = 0;
+
+       success = 1;
+
+       return success; // No errors
+}
+
+void SerialPuts(HANDLE hCom, char *txstring)
+{
+       BOOL    bWriteRC;
+       static  DWORD   iBytesWritten;
+
+       if(hCom == NULL) return;
+
+       bWriteRC = WriteFile(hCom, txstring, (DWORD) strlen(txstring), &iBytesWritten,NULL);
+}
+
+int SerialGetModemStatus(HANDLE hCom, int Mask)
+{
+// The value for Mask must be one of the following definitions:
+// MS_CTS_ON
+// MS_DSR_ON
+// MS_RING_ON
+       int ModemStat;
+
+       GetCommModemStatus(hCom, &ModemStat);
+
+       switch( Mask ) {
+       case MS_CTS_ON:
+       case MS_DSR_ON:
+       case MS_RING_ON:
+               if((ModemStat & Mask) != 0) {
+                       return 1;
+               } else {
+                       return 0;
+               }
+       default:
+               return -1;
+       }
+}
+
+void SerialClearRxBuffer(HANDLE hCom)
+{
+       PurgeComm(hCom, PURGE_RXCLEAR);
+}