From b110b5b5a904fc48db27edc7d71569e5fe17acd7 Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Thu, 25 Jun 2009 15:17:00 +0000 Subject: [PATCH] RS232 code rewrote: now we can use it on Windows. --- src/rs232.c | 211 ++++++++++++++++------------------------------------ 1 file changed, 64 insertions(+), 147 deletions(-) diff --git a/src/rs232.c b/src/rs232.c index 533c2f1..e53a7c2 100644 --- a/src/rs232.c +++ b/src/rs232.c @@ -24,7 +24,8 @@ along with this program. If not, see . #include "rs232.h" -#ifndef _WIN32 /* Linux */ +// Test if we are dealing with unix operating systems +#ifndef _WIN32 typedef struct termios term_info; typedef struct { @@ -136,169 +137,85 @@ bool rs232_send(const serial_port sp, const byte* pbtTx, const uint32_t uiTxLen) return (iResult >= 0); } -#else /* windows */ +#else +// The windows serial port implementation +typedef struct { + HANDLE hPort; // Serial port handle + DCB dcb; // Device control settings + COMMTIMEOUTS ct; // Serial port time-out configuration +} serial_port_windows; -HANDLE Cport[16]; - - -char comports[16][10]={"\\\\.\\COM1", "\\\\.\\COM2", "\\\\.\\COM3", "\\\\.\\COM4", - "\\\\.\\COM5", "\\\\.\\COM6", "\\\\.\\COM7", "\\\\.\\COM8", - "\\\\.\\COM9", "\\\\.\\COM10", "\\\\.\\COM11", "\\\\.\\COM12", - "\\\\.\\COM13", "\\\\.\\COM14", "\\\\.\\COM15", "\\\\.\\COM16"}; - -char baudr[64]; - - -int OpenComport(int comport_number, int baudrate) +serial_port rs232_open(const char* pcPortName) { - if((comport_number>15)||(comport_number<0)) + char acPortName[255]; + serial_port_windows* sp = malloc(sizeof(serial_port_windows)); + + // Copy the input "com?" to "\\.\COM?" format + sprintf(acPortName,"\\\\.\\%s",pcPortName); + _strupr(acPortName); + + // Try to open the serial port + sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,NULL,NULL); + if (sp->hPort == INVALID_HANDLE_VALUE) { - printf("illegal comport number\n"); - return(1); + rs232_close(sp); + return INVALID_SERIAL_PORT; } - switch(baudrate) + // Prepare the device control + memset(&sp->dcb, 0, sizeof(DCB)); + sp->dcb.DCBlength = sizeof(DCB); + if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) { - sscanf(baudr,"baud=%d data=8 parity=N stop=1",baudrate); -/* - case 110 : strcpy(baudr, "baud=110 data=8 parity=N stop=1"); - break; - case 300 : strcpy(baudr, "baud=300 data=8 parity=N stop=1"); - break; - case 600 : strcpy(baudr, "baud=600 data=8 parity=N stop=1"); - break; - case 1200 : strcpy(baudr, "baud=1200 data=8 parity=N stop=1"); - break; - case 2400 : strcpy(baudr, "baud=2400 data=8 parity=N stop=1"); - break; - case 4800 : strcpy(baudr, "baud=4800 data=8 parity=N stop=1"); - break; - case 9600 : strcpy(baudr, "baud=9600 data=8 parity=N stop=1"); - break; - case 19200 : strcpy(baudr, "baud=19200 data=8 parity=N stop=1"); - break; - case 38400 : strcpy(baudr, "baud=38400 data=8 parity=N stop=1"); - break; - case 57600 : strcpy(baudr, "baud=57600 data=8 parity=N stop=1"); - break; - case 115200 : strcpy(baudr, "baud=115200 data=8 parity=N stop=1"); - break; - case 128000 : strcpy(baudr, "baud=128000 data=8 parity=N stop=1"); - break; - case 256000 : strcpy(baudr, "baud=256000 data=8 parity=N stop=1"); - break; - default : printf("invalid baudrate\n"); - return(1); - break; -*/ + rs232_close(sp); + return INVALID_SERIAL_PORT; } - Cport[comport_number] = CreateFileA(comports[comport_number], - GENERIC_READ|GENERIC_WRITE, - 0, /* no share */ - NULL, /* no security */ - OPEN_EXISTING, - 0, /* no threads */ - NULL); /* no templates */ - - if(Cport[comport_number]==INVALID_HANDLE_VALUE) + // Update the active serial port + if(!SetCommState(sp->hPort,&sp->dcb)) { - printf("unable to open comport\n"); - return(1); + rs232_close(sp); + return INVALID_SERIAL_PORT; } - DCB port_settings; - memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */ - port_settings.DCBlength = sizeof(port_settings); - - if(!BuildCommDCBA(baudr, &port_settings)) - { - printf("unable to set comport dcb settings\n"); - CloseHandle(Cport[comport_number]); - return(1); - } - - if(!SetCommState(Cport[comport_number], &port_settings)) - { - printf("unable to set comport cfg settings\n"); - CloseHandle(Cport[comport_number]); - return(1); - } - - COMMTIMEOUTS Cptimeouts; - - Cptimeouts.ReadIntervalTimeout = MAXDWORD; - Cptimeouts.ReadTotalTimeoutMultiplier = 0; - Cptimeouts.ReadTotalTimeoutConstant = 0; - Cptimeouts.WriteTotalTimeoutMultiplier = 0; - Cptimeouts.WriteTotalTimeoutConstant = 0; - - if(!SetCommTimeouts(Cport[comport_number], &Cptimeouts)) - { - printf("unable to set comport time-out settings\n"); - CloseHandle(Cport[comport_number]); - return(1); - } - - return(0); -} - - -int PollComport(int comport_number, unsigned char *buf, int size) -{ - int n; - - if(size>4096) size = 4096; - -/* added the void pointer cast, otherwise gcc will complain about */ -/* "warning: dereferencing type-punned pointer will break strict aliasing rules" */ - - ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL); - - return(n); -} - - -int SendByte(int comport_number, unsigned char byte) -{ - int n; - - WriteFile(Cport[comport_number], &byte, 1, (LPDWORD)((void *)&n), NULL); - - if(n<0) return(1); - - return(0); -} - - -int SendBuf(int comport_number, unsigned char *buf, int size) -{ - int n; - - if(WriteFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)) - { - return(n); - } - - return(-1); -} - -bool rs232_cts(const serial_port sp); -{ - int status; + sp->ct.ReadIntervalTimeout = 30; + sp->ct.ReadTotalTimeoutMultiplier = 0; + sp->ct.ReadTotalTimeoutConstant = 0; + sp->ct.WriteTotalTimeoutMultiplier = 0; + sp->ct.WriteTotalTimeoutConstant = 0; - GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status)); - - if(status&MS_CTS_ON) return(1); - else return(0); + if(!SetCommTimeouts(sp->hPort,&sp->ct)) + { + rs232_close(sp); + return INVALID_SERIAL_PORT; + } + + return sp; } - -void CloseComport(int comport_number) +void rs232_close(const serial_port sp) { - CloseHandle(Cport[comport_number]); + CloseHandle(((serial_port_windows*)sp)->hPort); + free(sp); } +bool rs232_cts(const serial_port sp) +{ + DWORD dwStatus; + if (GetCommModemStatus(((serial_port_windows*)sp)->hPort,&dwStatus) == NULL) return false; + return (dwStatus & MS_CTS_ON); +} + +bool rs232_receive(const serial_port sp, byte* pbtRx, uint32_t* puiRxLen) +{ + return (ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*puiRxLen,(LPDWORD)puiRxLen,NULL) != NULL); +} + +bool rs232_send(const serial_port sp, const byte* pbtTx, const uint32_t uiTxLen) +{ + DWORD dwTxLen; + return (WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,uiTxLen,&dwTxLen,NULL) != NULL); +} #endif