RS232 code rewrote: now we can use it on Windows.
This commit is contained in:
parent
645796d0b2
commit
b110b5b5a9
1 changed files with 64 additions and 147 deletions
211
src/rs232.c
211
src/rs232.c
|
@ -24,7 +24,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include "rs232.h"
|
#include "rs232.h"
|
||||||
|
|
||||||
#ifndef _WIN32 /* Linux */
|
// Test if we are dealing with unix operating systems
|
||||||
|
#ifndef _WIN32
|
||||||
|
|
||||||
typedef struct termios term_info;
|
typedef struct termios term_info;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -136,169 +137,85 @@ bool rs232_send(const serial_port sp, const byte* pbtTx, const uint32_t uiTxLen)
|
||||||
return (iResult >= 0);
|
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];
|
serial_port rs232_open(const char* pcPortName)
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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");
|
rs232_close(sp);
|
||||||
return(1);
|
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);
|
rs232_close(sp);
|
||||||
/*
|
return INVALID_SERIAL_PORT;
|
||||||
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;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cport[comport_number] = CreateFileA(comports[comport_number],
|
// Update the active serial port
|
||||||
GENERIC_READ|GENERIC_WRITE,
|
if(!SetCommState(sp->hPort,&sp->dcb))
|
||||||
0, /* no share */
|
|
||||||
NULL, /* no security */
|
|
||||||
OPEN_EXISTING,
|
|
||||||
0, /* no threads */
|
|
||||||
NULL); /* no templates */
|
|
||||||
|
|
||||||
if(Cport[comport_number]==INVALID_HANDLE_VALUE)
|
|
||||||
{
|
{
|
||||||
printf("unable to open comport\n");
|
rs232_close(sp);
|
||||||
return(1);
|
return INVALID_SERIAL_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
DCB port_settings;
|
sp->ct.ReadIntervalTimeout = 30;
|
||||||
memset(&port_settings, 0, sizeof(port_settings)); /* clear the new struct */
|
sp->ct.ReadTotalTimeoutMultiplier = 0;
|
||||||
port_settings.DCBlength = sizeof(port_settings);
|
sp->ct.ReadTotalTimeoutConstant = 0;
|
||||||
|
sp->ct.WriteTotalTimeoutMultiplier = 0;
|
||||||
if(!BuildCommDCBA(baudr, &port_settings))
|
sp->ct.WriteTotalTimeoutConstant = 0;
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
GetCommModemStatus(Cport[comport_number], (LPDWORD)((void *)&status));
|
if(!SetCommTimeouts(sp->hPort,&sp->ct))
|
||||||
|
{
|
||||||
if(status&MS_CTS_ON) return(1);
|
rs232_close(sp);
|
||||||
else return(0);
|
return INVALID_SERIAL_PORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rs232_close(const serial_port sp)
|
||||||
void CloseComport(int comport_number)
|
|
||||||
{
|
{
|
||||||
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue