QSPY
com.c
00001 /*****************************************************************************
00002 * Product: Quantum Spy -- Serial communication HAL
00003 * Last Updated for Version: 4.5.00
00004 * Date of the Last Update:  May 22, 2012
00005 *
00006 *                    Q u a n t u m     L e a P s
00007 *                    ---------------------------
00008 *                    innovating embedded systems
00009 *
00010 * Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved.
00011 *
00012 * This program is open source software: you can redistribute it and/or
00013 * modify it under the terms of the GNU General Public License as published
00014 * by the Free Software Foundation, either version 2 of the License, or
00015 * (at your option) any later version.
00016 *
00017 * Alternatively, this program may be distributed and modified under the
00018 * terms of Quantum Leaps commercial licenses, which expressly supersede
00019 * the GNU General Public License and are specifically designed for
00020 * licensees interested in retaining the proprietary status of their code.
00021 *
00022 * This program is distributed in the hope that it will be useful,
00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00025 * GNU General Public License for more details.
00026 *
00027 * You should have received a copy of the GNU General Public License
00028 * along with this program. If not, see <http://www.gnu.org/licenses/>.
00029 *
00030 * Contact information:
00031 * Quantum Leaps Web sites: http://www.quantum-leaps.com
00032 *                          http://www.state-machine.com
00033 * e-mail:                  info@quantum-leaps.com
00034 *****************************************************************************/
00035 #include <string.h>                                           /* for size_t */
00036 #include <stdint.h>
00037 #include "hal.h"
00038 #include "qspy.h"
00039 
00040 #include <windows.h>         /* for Windows serial communication facilities */
00041 #include <stdio.h>
00042 #include <conio.h>
00043 
00044 /*..........................................................................*/
00045 static HANDLE l_com;
00046 static COMMTIMEOUTS l_timeouts;
00047 
00048 #define BUF_SIZE 1024
00049 #define COM_SETTINGS \
00050     "baud=%d parity=N data=8 stop=1 odsr=off dtr=on octs=off rts=on"
00051 
00052 /*..........................................................................*/
00053 int HAL_comOpen(char const *comName, int baudRate) {
00054     DCB dcb = {0};
00055     char comPortName[40];
00056     char comSettings[120];
00057 
00058     l_com = 0;
00059     snprintf(comPortName, sizeof(comPortName),
00060              "\\\\.\\%s", comName);
00061     snprintf(comSettings, sizeof(comSettings),
00062              COM_SETTINGS,
00063              baudRate);
00064 
00065     l_com = CreateFile(comPortName,
00066                        GENERIC_READ | GENERIC_WRITE,
00067                        0,                               /* exclusive access */
00068                        NULL,                           /* no security attrs */
00069                        OPEN_EXISTING,
00070                        0,                  /* standard (not-overlapped) I/O */
00071                        NULL);
00072 
00073     if (l_com == INVALID_HANDLE_VALUE) {
00074         printf("Error by opening the COM port: %s at the baud rate %d\n",
00075                comName, baudRate);
00076         return 0;
00077     }
00078 
00079     dcb.DCBlength = sizeof(DCB);
00080     if (!GetCommState(l_com, &dcb)) {
00081         printf("Error by retreiving port settings\n");
00082         return 0;
00083     }
00084 
00085     dcb.fAbortOnError = 0;                          /* don't abort on error */
00086     /* Fill in the DCB */
00087     if (!BuildCommDCB(comSettings, &dcb)) {
00088         printf("Error by parsing command line parameters\n");
00089         return 0;
00090     }
00091 
00092     if (!SetCommState(l_com, &dcb)) {
00093         printf("Error setting up the port\n");
00094         return 0;
00095     }
00096 
00097     SetupComm(l_com, BUF_SIZE, BUF_SIZE);     /* setup the device buffers */
00098 
00099     /* purge any information in the buffers */
00100     PurgeComm(l_com, PURGE_TXABORT | PURGE_RXABORT |
00101                      PURGE_TXCLEAR | PURGE_RXCLEAR);
00102 
00103     /* the timeouts for the serial communication are set accorging to the
00104     * following remark from the Win32 help documentation:
00105     *
00106     * If an application sets ReadIntervalTimeout and
00107     * ReadTotalTimeoutMultiplier to MAXDWORD and sets
00108     * ReadTotalTimeoutConstant to a value greater than zero and less than
00109     * MAXDWORD, one of the following occurs when the ReadFile function
00110     * is called:
00111     * 1. If there are any characters in the input buffer, ReadFile
00112     * returns immediately with the characters in the buffer.
00113     * 2. If there are no characters in the input buffer, ReadFile waits
00114     * until a character arrives and then returns immediately.
00115     * 3. If no character arrives within the time specified by
00116     * ReadTotalTimeoutConstant, ReadFile times out.
00117     */
00118     l_timeouts.ReadIntervalTimeout = MAXDWORD;
00119     l_timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
00120     l_timeouts.ReadTotalTimeoutConstant = 50;
00121     l_timeouts.WriteTotalTimeoutMultiplier = 0;
00122     l_timeouts.WriteTotalTimeoutConstant = 50;
00123     SetCommTimeouts(l_com, &l_timeouts);
00124 
00125     return 1;                                                    /* success */
00126 }
00127 /*..........................................................................*/
00128 void HAL_comClose(void) {
00129     CloseHandle(l_com);
00130 }
00131 /*..........................................................................*/
00132 int HAL_comRead(unsigned char *buf, size_t size) {
00133     DWORD n;
00134     if (!ReadFile(l_com, buf, (DWORD)size, &n, NULL)) {
00135         COMSTAT comstat;
00136         DWORD errors;
00137 
00138         printf("*** Reading serial port failed; GetLastError=%ld\n",
00139                GetLastError());
00140         ClearCommError(l_com, &errors, &comstat);
00141     }
00142     if (_kbhit()) {
00143         return -1;                                             /* terminate */
00144     }
00145     return (int)n;
00146 }