00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 typedef struct {
00027 HANDLE hPort;
00028 DCB dcb;
00029 COMMTIMEOUTS ct;
00030 } serial_port_windows;
00031
00032 serial_port
00033 uart_open (const char *pcPortName)
00034 {
00035 char acPortName[255];
00036 serial_port_windows *sp = malloc (sizeof (serial_port_windows));
00037
00038
00039 sprintf (acPortName, "\\\\.\\%s", pcPortName);
00040 _strupr (acPortName);
00041
00042
00043 sp->hPort = CreateFileA (acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
00044 if (sp->hPort == INVALID_HANDLE_VALUE) {
00045 uart_close (sp);
00046 return INVALID_SERIAL_PORT;
00047 }
00048
00049 memset (&sp->dcb, 0, sizeof (DCB));
00050 sp->dcb.DCBlength = sizeof (DCB);
00051 if (!BuildCommDCBA ("baud=9600 data=8 parity=N stop=1", &sp->dcb)) {
00052 uart_close (sp);
00053 return INVALID_SERIAL_PORT;
00054 }
00055
00056 if (!SetCommState (sp->hPort, &sp->dcb)) {
00057 uart_close (sp);
00058 return INVALID_SERIAL_PORT;
00059 }
00060
00061 sp->ct.ReadIntervalTimeout = 30;
00062 sp->ct.ReadTotalTimeoutMultiplier = 0;
00063 sp->ct.ReadTotalTimeoutConstant = 30;
00064 sp->ct.WriteTotalTimeoutMultiplier = 30;
00065 sp->ct.WriteTotalTimeoutConstant = 0;
00066
00067 if (!SetCommTimeouts (sp->hPort, &sp->ct)) {
00068 uart_close (sp);
00069 return INVALID_SERIAL_PORT;
00070 }
00071
00072 PurgeComm (sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
00073
00074 return sp;
00075 }
00076
00077 void
00078 uart_close (const serial_port sp)
00079 {
00080 if (((serial_port_windows *) sp)->hPort != INVALID_HANDLE_VALUE) {
00081 CloseHandle (((serial_port_windows *) sp)->hPort);
00082 }
00083 free (sp);
00084 }
00085
00086
00087 void
00088 uart_set_speed (serial_port sp, const uint32_t uiPortSpeed)
00089 {
00090 serial_port_windows *spw;
00091
00092 DBG ("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
00093
00094 switch (uiPortSpeed) {
00095 case 9600:
00096 case 19200:
00097 case 38400:
00098 case 57600:
00099 case 115200:
00100 case 230400:
00101 case 460800:
00102 break;
00103 default:
00104 ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
00105 return;
00106 };
00107 spw = (serial_port_windows *) sp;
00108
00109
00110
00111 int iTimeout = 200;
00112 spw->ct.ReadIntervalTimeout = 2;
00113 spw->ct.ReadTotalTimeoutMultiplier = 0;
00114 spw->ct.ReadTotalTimeoutConstant = iTimeout;
00115 spw->ct.WriteTotalTimeoutMultiplier = iTimeout;
00116 spw->ct.WriteTotalTimeoutConstant = 0;
00117
00118 if (!SetCommTimeouts (spw->hPort, &spw->ct)) {
00119 ERR ("Unable to apply new timeout settings.");
00120 return;
00121 }
00122
00123
00124 spw->dcb.BaudRate = uiPortSpeed;
00125 if (!SetCommState (spw->hPort, &spw->dcb)) {
00126 ERR ("Unable to apply new speed settings.");
00127 return;
00128 }
00129 PurgeComm (spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
00130 }
00131
00132 uint32_t
00133 uart_get_speed (const serial_port sp)
00134 {
00135 const serial_port_windows *spw = (serial_port_windows *) sp;
00136 if (!GetCommState (spw->hPort, (serial_port) & spw->dcb))
00137 return spw->dcb.BaudRate;
00138
00139 return 0;
00140 }
00141
00142 int
00143 uart_receive (serial_port sp, byte_t * pbtRx, size_t * pszRx)
00144 {
00145 if (!ReadFile (((serial_port_windows *) sp)->hPort, pbtRx, (DWORD)(*pszRx), (LPDWORD) pszRx, NULL)) {
00146 return DEIO;
00147 }
00148 if (!*pszRx)
00149 return DEIO;
00150 return 0;
00151 }
00152
00153 int
00154 uart_send (serial_port sp, const byte_t * pbtTx, const size_t szTx)
00155 {
00156 DWORD dwTxLen = 0;
00157 if (!WriteFile (((serial_port_windows *) sp)->hPort, pbtTx, szTx, &dwTxLen, NULL)) {
00158 return DEIO;
00159 }
00160 if (!dwTxLen)
00161 return DEIO;
00162 return 0;
00163 }
00164