2  * Generic uart / rs232/ serial port library 
   4  * Copyright (c) 2013, Roel Verdult 
   7  * Redistribution and use in source and binary forms, with or without 
   8  * modification, are permitted provided that the following conditions are met: 
   9  * 1. Redistributions of source code must retain the above copyright 
  10  * notice, this list of conditions and the following disclaimer. 
  11  * 2. Redistributions in binary form must reproduce the above copyright 
  12  * notice, this list of conditions and the following disclaimer in the 
  13  * documentation and/or other materials provided with the distribution. 
  14  * 3. Neither the name of the copyright holders nor the 
  15  * names of its contributors may be used to endorse or promote products 
  16  * derived from this software without specific prior written permission. 
  18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 
  19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  21  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 
  22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
  25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
  27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  31  * Note: the win32 version of this library has also been seen under the GPLv3+ 
  32  * license as part of the libnfc project, which appears to have additional 
  35  * This version of the library has functionality removed which was not used by 
  41 // The windows serial port implementation 
  46   HANDLE hPort
;     // Serial port handle 
  47   DCB dcb
;          // Device control settings 
  48   COMMTIMEOUTS ct
;  // Serial port time-out configuration 
  49 } serial_port_windows
; 
  51 void upcase(char *p
) { 
  53     if(*p 
>= 97 && *p 
<= 122) { 
  60 serial_port 
uart_open(const char* pcPortName
) { 
  62   serial_port_windows
* sp 
= malloc(sizeof(serial_port_windows
)); 
  64   // Copy the input "com?" to "\\.\COM?" format 
  65   sprintf(acPortName
,"\\\\.\\%s",pcPortName
); 
  68   // Try to open the serial port 
  69   sp
->hPort 
= CreateFileA(acPortName
,GENERIC_READ
|GENERIC_WRITE
,0,NULL
,OPEN_EXISTING
,0,NULL
); 
  70   if (sp
->hPort 
== INVALID_HANDLE_VALUE
) { 
  72     return INVALID_SERIAL_PORT
; 
  75   // Prepare the device control 
  76   memset(&sp
->dcb
, 0, sizeof(DCB
)); 
  77   sp
->dcb
.DCBlength 
= sizeof(DCB
); 
  78   if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp
->dcb
)) { 
  80     return INVALID_SERIAL_PORT
; 
  83   // Update the active serial port 
  84   if(!SetCommState(sp
->hPort
,&sp
->dcb
)) { 
  86     return INVALID_SERIAL_PORT
; 
  89   sp
->ct
.ReadIntervalTimeout         
= 0; 
  90   sp
->ct
.ReadTotalTimeoutMultiplier  
= 0; 
  91   sp
->ct
.ReadTotalTimeoutConstant    
= 30; 
  92   sp
->ct
.WriteTotalTimeoutMultiplier 
= 0; 
  93   sp
->ct
.WriteTotalTimeoutConstant   
= 30; 
  95   if(!SetCommTimeouts(sp
->hPort
,&sp
->ct
)) { 
  97     return INVALID_SERIAL_PORT
; 
 100   PurgeComm(sp
->hPort
, PURGE_RXABORT 
| PURGE_RXCLEAR
); 
 105 void uart_close(const serial_port sp
) { 
 106   CloseHandle(((serial_port_windows
*)sp
)->hPort
); 
 110 bool uart_receive(const serial_port sp
, uint8_t *pbtRx
, size_t pszMaxRxLen
, size_t *pszRxLen
) { 
 111   return ReadFile(((serial_port_windows
*)sp
)->hPort
, pbtRx
, pszMaxRxLen
, (LPDWORD
)pszRxLen
, NULL
); 
 114 bool uart_send(const serial_port sp
, const uint8_t* pbtTx
, const size_t szTxLen
) { 
 116   return WriteFile(((serial_port_windows
*)sp
)->hPort
, pbtTx
, szTxLen
, &dwTxLen
, NULL
); 
 119 bool uart_set_speed(serial_port sp
, const uint32_t uiPortSpeed
) { 
 120   serial_port_windows
* spw
; 
 121   spw 
= (serial_port_windows
*)sp
; 
 122   spw
->dcb
.BaudRate 
= uiPortSpeed
; 
 123   return SetCommState(spw
->hPort
, &spw
->dcb
); 
 126 uint32_t uart_get_speed(const serial_port sp
) { 
 127   const serial_port_windows
* spw 
= (serial_port_windows
*)sp
; 
 128   if (!GetCommState(spw
->hPort
, (serial_port
)&spw
->dcb
)) { 
 129     return spw
->dcb
.BaudRate
;