1 /*-------------------------------------------------------------------------
2 Serial library functions for the Windows OS (95-XP)
3 Tested with different versions of MS Visual Studio (C ad C++)
5 Written by - Bela Torok / www.torok.info & www.belatorok.com (February 2006)
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License (http://www.gnu.org/licenses/gpl.txt).
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 In other words, you are welcome to use, share and improve this program.
18 You are forbidden to forbid anyone else to use, share and improve
19 what you give them. Help stamp out software-hoarding!
20 -------------------------------------------------------------------------*/
26 #define ASCII_XON 0x11
27 #define ASCII_XOFF 0x13
29 HANDLE SerialInit(char *ComPortName, DWORD BaudRate, int ByteSize, int StopBit, char ParityChar, char Protocol, int RxTimeOut, int TxTimeOut, int RxBufSize, int TxBufSize)
34 COMMTIMEOUTS CommTimeouts;
51 return NULL; // illegal parameter !
60 StopBit = TWOSTOPBITS;
63 return NULL; // illegal parameter !
66 hCom = CreateFile( ComPortName,
67 GENERIC_READ | GENERIC_WRITE,
68 0, // exclusive access
71 0, // no overlapped I/O
72 NULL); // null template
74 if(hCom == INVALID_HANDLE_VALUE) return NULL;
76 bPortReady = SetupComm(hCom, RxBufSize, TxBufSize); // set Rx and Tx buffer sizes
78 // Port settings are specified in a Data Communication Block (DCB).
80 bPortReady = GetCommState(hCom, &dcb);
82 dcb.BaudRate = BaudRate;
83 dcb.ByteSize = ByteSize;
85 dcb.StopBits = StopBit;
86 dcb.fAbortOnError = TRUE;
95 dcb.fOutxCtsFlow = FALSE;
96 dcb.fRtsControl = RTS_CONTROL_DISABLE;
98 dcb.fOutxDsrFlow = TRUE;
99 dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
107 dcb.fOutxCtsFlow = TRUE;
108 dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
110 dcb.fOutxDsrFlow = FALSE;
111 dcb.fDtrControl = DTR_CONTROL_DISABLE;
113 case 'X': // XON/XOFF
118 dcb.fTXContinueOnXoff = TRUE;
119 dcb.XoffChar = ASCII_XOFF;
120 dcb.XoffLim = RxBufSize - (RxBufSize / 4);
121 dcb.XonChar = ASCII_XON;
122 dcb.XonLim = RxBufSize - (RxBufSize / 2);
124 dcb.fOutxCtsFlow = FALSE;
125 dcb.fRtsControl = RTS_CONTROL_DISABLE;
127 dcb.fOutxDsrFlow = FALSE;
128 dcb.fDtrControl = DTR_CONTROL_DISABLE;
130 case 'N': // NOPROTOCOL
137 dcb.fOutxCtsFlow = FALSE;
138 dcb.fRtsControl = RTS_CONTROL_DISABLE;
140 dcb.fOutxDsrFlow = FALSE;
141 dcb.fDtrControl = DTR_CONTROL_DISABLE;
145 bPortReady = SetCommState(hCom, &dcb);
148 CommTimeouts.ReadIntervalTimeout = RxTimeOut;
149 CommTimeouts.ReadTotalTimeoutMultiplier = 0;
150 CommTimeouts.ReadTotalTimeoutConstant = RxTimeOut;
152 CommTimeouts.WriteTotalTimeoutMultiplier = 0;
153 CommTimeouts.WriteTotalTimeoutConstant = TxTimeOut;
155 bPortReady = SetCommTimeouts(hCom, &CommTimeouts);
160 void SerialClose(HANDLE hSerial) {
161 CloseHandle(hSerial);
164 int SerialGetc(HANDLE hSerial)
166 unsigned char rxchar;
168 static DWORD iBytesRead, dwError;
170 if(hSerial == NULL) return 0;
172 bReadRC = ReadFile(hSerial, &rxchar, 1, &iBytesRead, NULL);
174 if(bReadRC == FALSE) { // error
176 ClearCommError(hSerial, &dwError, NULL);
178 // PurgeComm(hSerial, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
179 // PurgeComm(hSerial, PURGE_RXCLEAR | PURGE_TXCLEAR);
181 if(dwError == 0) return TIMEOUT; // no error, iBytesRead is probably == 0
182 if(dwError & CE_BREAK) return BREAK; // break detected
183 if(dwError & CE_FRAME) return BREAK; // framing error
185 /* One, or a combination of the following conditions:
186 CE_IOE -> 0x0400 I/O error during communication with the device
187 CE_OVERRUN -> 0x0002 character-buffer overrun, the next character is lost
188 CE_RXOVER -> 0x0001 input buffer overflow, no room in the input buffer,
189 or a character was received after the EOF character
190 CE_RXPARITY -> 0x0004 parity error
191 CE_TXFULL -> 0x0100 transmit buffer is full
193 if(dwError & CE_IOE) printf("SerialGetc() I/O error during communication with the device!\n");
194 if(dwError & CE_OVERRUN) printf("SerialGetc() Character-buffer overrun, the next character is lost!\n");
195 if(dwError & CE_RXOVER) printf("SerialGetc() Input buffer overflow!\n");
196 if(dwError & CE_RXPARITY) printf("SerialGetc() Parity error!\n");
197 if(dwError & CE_TXFULL) printf("SerialGetc() Transmit buffer is full!\n");
201 if(iBytesRead == 0) return TIMEOUT; // Timeout occured
207 int SerialPutc(HANDLE hCom, char txchar)
210 static DWORD iBytesWritten;
212 if(hCom == NULL) return -255;
214 bWriteRC = WriteFile(hCom, &txchar, 1, &iBytesWritten,NULL);
216 if(iBytesWritten = 1) return 0;
221 char SerialGets(char *rxstring, int MaxNumberOfCharsToRead, HANDLE hCom)
225 unsigned char success = 0; // set to error
227 if(hCom == NULL) return success; // Error!
229 while(pos <= MaxNumberOfCharsToRead) {
230 c = SerialGetc(hCom);
232 if(c == TIMEOUT) return success; // Error
234 if(c != '\r') rxstring[pos++] = (char) c; // discard carriage return
240 return success; // No errors
243 void SerialPuts(HANDLE hCom, char *txstring)
246 static DWORD iBytesWritten;
248 if(hCom == NULL) return;
250 bWriteRC = WriteFile(hCom, txstring, (DWORD) strlen(txstring), &iBytesWritten,NULL);
253 int SerialGetModemStatus(HANDLE hCom, int Mask)
255 // The value for Mask must be one of the following definitions:
261 GetCommModemStatus(hCom, &ModemStat);
267 if((ModemStat & Mask) != 0) {
277 void SerialClearRxBuffer(HANDLE hCom)
279 PurgeComm(hCom, PURGE_RXCLEAR);