*** empty log message ***
svn path=/trunk/externals/iem/comport/; revision=5253
This commit is contained in:
parent
44e9f1bc1a
commit
5b5d56d168
1 changed files with 661 additions and 667 deletions
|
|
@ -4,6 +4,8 @@
|
||||||
Institute for Electronic Music - Graz
|
Institute for Electronic Music - Graz
|
||||||
|
|
||||||
V 1.0
|
V 1.0
|
||||||
|
MP 20060603 memset and memcpy arguments were backwards for Windows version. close_serial doesn't crash now.
|
||||||
|
MP 20060618 make sure name is set up in comport_new (x->serial_device = test.serial_device) so help message works.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -35,11 +37,8 @@
|
||||||
typedef struct comport
|
typedef struct comport
|
||||||
{
|
{
|
||||||
t_object x_obj;
|
t_object x_obj;
|
||||||
|
|
||||||
long n; /* the state of a last input */
|
long n; /* the state of a last input */
|
||||||
|
|
||||||
HANDLE comhandle; /* holds the comport handle */
|
HANDLE comhandle; /* holds the comport handle */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DCB dcb; /* holds the comm pars */
|
DCB dcb; /* holds the comm pars */
|
||||||
DCB dcb_old; /* holds the comm pars */
|
DCB dcb_old; /* holds the comm pars */
|
||||||
|
|
@ -50,18 +49,13 @@ typedef struct comport
|
||||||
#endif
|
#endif
|
||||||
t_symbol *serial_device;
|
t_symbol *serial_device;
|
||||||
char serial_device_name[FILENAME_MAX];
|
char serial_device_name[FILENAME_MAX];
|
||||||
|
|
||||||
short comport; /* holds the comport # */
|
short comport; /* holds the comport # */
|
||||||
t_float baud; /* holds the current baud rate */
|
t_float baud; /* holds the current baud rate */
|
||||||
|
|
||||||
short rxerrors; /* holds the rx line errors */
|
short rxerrors; /* holds the rx line errors */
|
||||||
|
|
||||||
t_clock *x_clock;
|
t_clock *x_clock;
|
||||||
int x_hit;
|
int x_hit;
|
||||||
double x_deltime;
|
double x_deltime;
|
||||||
|
|
||||||
int verbose;
|
int verbose;
|
||||||
|
|
||||||
t_outlet *x_data_outlet;
|
t_outlet *x_data_outlet;
|
||||||
t_outlet *x_status_outlet;
|
t_outlet *x_status_outlet;
|
||||||
} t_comport;
|
} t_comport;
|
||||||
|
|
@ -76,9 +70,8 @@ typedef struct comport
|
||||||
#define OFF 0
|
#define OFF 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/* Serial Port Return Values */
|
||||||
Serial Port Return Values
|
|
||||||
*/
|
|
||||||
#define NODATAAVAIL -1
|
#define NODATAAVAIL -1
|
||||||
#define RXERRORS -2
|
#define RXERRORS -2
|
||||||
#define RXBUFOVERRUN -4
|
#define RXBUFOVERRUN -4
|
||||||
|
|
@ -87,8 +80,7 @@ typedef struct comport
|
||||||
#define COMPORT_MAX 99
|
#define COMPORT_MAX 99
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static
|
static long baudspeedbittable[] =
|
||||||
long baudspeedbittable[] =
|
|
||||||
{
|
{
|
||||||
CBR_256000,
|
CBR_256000,
|
||||||
CBR_128000,
|
CBR_128000,
|
||||||
|
|
@ -154,11 +146,9 @@ struct timeval null_tv;
|
||||||
|
|
||||||
#endif /* else _WIN32 */
|
#endif /* else _WIN32 */
|
||||||
|
|
||||||
|
|
||||||
#define BAUDRATETABLE_LEN 15
|
#define BAUDRATETABLE_LEN 15
|
||||||
|
|
||||||
static
|
static long baudratetable[] =
|
||||||
long baudratetable[] =
|
|
||||||
{
|
{
|
||||||
256000L,
|
256000L,
|
||||||
128000L,
|
128000L,
|
||||||
|
|
@ -185,12 +175,12 @@ static long get_baud_ratebits(t_float *baud)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
while(i < BAUDRATETABLE_LEN && baudratetable[i] > *baud)
|
while(i < BAUDRATETABLE_LEN && baudratetable[i] > *baud) i++;
|
||||||
i++;
|
|
||||||
|
|
||||||
/* nearest Baudrate finding */
|
/* nearest Baudrate finding */
|
||||||
if(i==BAUDRATETABLE_LEN || baudspeedbittable[i] < 0){
|
if(i==BAUDRATETABLE_LEN || baudspeedbittable[i] < 0)
|
||||||
post("*Warning* The baud rate %d is not suported or out of range, using 9600\n",*baud);
|
{
|
||||||
|
post("*Warning* The baud rate %d is not supported or out of range, using 9600\n",*baud);
|
||||||
i = 7;
|
i = 7;
|
||||||
}
|
}
|
||||||
*baud = baudratetable[i];
|
*baud = baudratetable[i];
|
||||||
|
|
@ -206,11 +196,9 @@ static long get_baud_ratebits(t_float *baud)
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
|
||||||
static float set_baudrate(t_comport *x,t_float baud)
|
static float set_baudrate(t_comport *x,t_float baud)
|
||||||
{
|
{
|
||||||
x->dcb.BaudRate = get_baud_ratebits(&baud);
|
x->dcb.BaudRate = get_baud_ratebits(&baud);
|
||||||
|
|
||||||
return baud;
|
return baud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,9 +206,7 @@ static float set_baudrate(t_comport *x,t_float baud)
|
||||||
|
|
||||||
static float set_bits(t_comport *x, int nr)
|
static float set_bits(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
|
if(nr < 4 && nr > 8) nr = 8;
|
||||||
if(nr < 4 && nr > 8)
|
|
||||||
nr = 8;
|
|
||||||
|
|
||||||
/* number of bits/byte, 4-8 */
|
/* number of bits/byte, 4-8 */
|
||||||
return x->dcb.ByteSize = nr;
|
return x->dcb.ByteSize = nr;
|
||||||
|
|
@ -230,17 +216,16 @@ static float set_bits(t_comport *x, int nr)
|
||||||
/* 1 ... Parity even, -1 parity odd , 0 (default) no parity */
|
/* 1 ... Parity even, -1 parity odd , 0 (default) no parity */
|
||||||
static float set_parity(t_comport *x,int n)
|
static float set_parity(t_comport *x,int n)
|
||||||
{
|
{
|
||||||
switch(n){
|
switch(n)
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x->dcb.fParity = TRUE; /* enable parity checking */
|
x->dcb.fParity = TRUE; /* enable parity checking */
|
||||||
x->dcb.Parity = 2; /* 0-4=no,odd,even,mark,space */
|
x->dcb.Parity = 2; /* 0-4=no,odd,even,mark,space */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
x->dcb.fParity = TRUE; /* enable parity checking */
|
x->dcb.fParity = TRUE; /* enable parity checking */
|
||||||
x->dcb.Parity = 1; /* 0-4=no,odd,even,mark,space */
|
x->dcb.Parity = 1; /* 0-4=no,odd,even,mark,space */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
x->dcb.fParity = FALSE; /* enable parity checking */
|
x->dcb.fParity = FALSE; /* enable parity checking */
|
||||||
x->dcb.Parity = 0; /* 0-4=no,odd,even,mark,space */
|
x->dcb.Parity = 0; /* 0-4=no,odd,even,mark,space */
|
||||||
|
|
@ -249,23 +234,24 @@ static float set_parity(t_comport *x,int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* aktivate second stop bit with 1, 0(default)*/
|
/* activate second stop bit with 1, 0(default)*/
|
||||||
static float set_stopflag(t_comport *x, int nr)
|
static float set_stopflag(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
if(nr == 1){
|
if(nr == 1)
|
||||||
|
{
|
||||||
x->dcb.StopBits = 1; /* 0,1,2 = 1, 1.5, 2 */
|
x->dcb.StopBits = 1; /* 0,1,2 = 1, 1.5, 2 */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else x->dcb.StopBits = 0; /* 0,1,2 = 1, 1.5, 2 */
|
||||||
x->dcb.StopBits = 0; /* 0,1,2 = 1, 1.5, 2 */
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* never testet */
|
/* never tested */
|
||||||
static int set_ctsrts(t_comport *x, int nr)
|
static int set_ctsrts(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
if(nr == 1){
|
if(nr == 1)
|
||||||
|
{
|
||||||
x->dcb.fOutxCtsFlow = TRUE; /* CTS output flow control */
|
x->dcb.fOutxCtsFlow = TRUE; /* CTS output flow control */
|
||||||
x->dcb.fRtsControl = RTS_CONTROL_ENABLE; /* RTS flow control */
|
x->dcb.fRtsControl = RTS_CONTROL_ENABLE; /* RTS flow control */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -278,25 +264,20 @@ static int set_ctsrts(t_comport *x, int nr)
|
||||||
static int set_xonxoff(t_comport *x, int nr)
|
static int set_xonxoff(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
/* x->dcb.fTXContinueOnXoff = FALSE; XOFF continues Tx */
|
/* x->dcb.fTXContinueOnXoff = FALSE; XOFF continues Tx */
|
||||||
|
if(nr == 1)
|
||||||
if(nr == 1){
|
{
|
||||||
x->dcb.fOutX = TRUE; /* XON/XOFF out flow control */
|
x->dcb.fOutX = TRUE; /* XON/XOFF out flow control */
|
||||||
x->dcb.fInX = TRUE; /* XON/XOFF in flow control */
|
x->dcb.fInX = TRUE; /* XON/XOFF in flow control */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
x->dcb.fOutX = FALSE; /* XON/XOFF out flow control */
|
x->dcb.fOutX = FALSE; /* XON/XOFF out flow control */
|
||||||
x->dcb.fInX = FALSE; /* XON/XOFF in flow control */
|
x->dcb.fInX = FALSE; /* XON/XOFF in flow control */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int set_serial(t_comport *x)
|
static int set_serial(t_comport *x)
|
||||||
{
|
{
|
||||||
|
if (SetCommState(x->comhandle, &(x->dcb))) return 1;
|
||||||
if (SetCommState(x->comhandle, &(x->dcb)))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,8 +287,10 @@ static HANDLE open_serial(unsigned int com_num, t_comport *x)
|
||||||
COMMTIMEOUTS timeouts;
|
COMMTIMEOUTS timeouts;
|
||||||
char buffer[MAX_PATH];
|
char buffer[MAX_PATH];
|
||||||
float *baud = &(x->baud);
|
float *baud = &(x->baud);
|
||||||
|
DWORD dw;
|
||||||
|
|
||||||
if(com_num < 1 || com_num >= COMPORT_MAX) {
|
if(com_num < 1 || com_num >= COMPORT_MAX)
|
||||||
|
{
|
||||||
post("comport open %d, baud %d not valid (args: [portnum] [baud])",com_num,*baud);
|
post("comport open %d, baud %d not valid (args: [portnum] [baud])",com_num,*baud);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
@ -325,24 +308,26 @@ static HANDLE open_serial(unsigned int com_num, t_comport *x)
|
||||||
|
|
||||||
if(fd == INVALID_HANDLE_VALUE)
|
if(fd == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
post("** ERROR ** could not open device %s:\n failure(%d): %s\n",
|
dw = GetLastError();
|
||||||
x->serial_device->s_name,errno,strerror(errno));
|
post("** ERROR ** could not open device %s:\n failure(%d)\n",
|
||||||
|
x->serial_device->s_name,dw);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the Current Port Configuration */
|
/* Save the Current Port Configuration */
|
||||||
|
|
||||||
if (!GetCommState(fd, &(x->dcb_old))){
|
if (!GetCommState(fd, &(x->dcb_old)))
|
||||||
|
{
|
||||||
post("** ERROR ** could not get old dcb of device %s\n",
|
post("** ERROR ** could not get old dcb of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
|
|
||||||
CloseHandle(fd);
|
CloseHandle(fd);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&(x->dcb), sizeof(DCB), 0);
|
memset(&(x->dcb), 0, sizeof(DCB));
|
||||||
|
|
||||||
if (!GetCommState(fd, &(x->dcb))){
|
if (!GetCommState(fd, &(x->dcb)))
|
||||||
|
{
|
||||||
post("** ERROR ** could not get new dcb of device %s\n",
|
post("** ERROR ** could not get new dcb of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
|
|
||||||
|
|
@ -350,7 +335,6 @@ static HANDLE open_serial(unsigned int com_num, t_comport *x)
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
x->dcb.fBinary = TRUE; /* binary mode, no EOF check */
|
x->dcb.fBinary = TRUE; /* binary mode, no EOF check */
|
||||||
|
|
||||||
/* x->dcb.fOutxDsrFlow = FALSE; DSR output flow control */
|
/* x->dcb.fOutxDsrFlow = FALSE; DSR output flow control */
|
||||||
|
|
@ -369,11 +353,11 @@ static HANDLE open_serial(unsigned int com_num, t_comport *x)
|
||||||
/* char x->dcb.EofChar; end of input character */
|
/* char x->dcb.EofChar; end of input character */
|
||||||
/* char x->dcb.EvtChar; received event character */
|
/* char x->dcb.EvtChar; received event character */
|
||||||
|
|
||||||
set_bits(x,8); /* CS8 */
|
set_bits(x, 8); /* CS8 */
|
||||||
set_stopflag(x,0); /* ~CSTOPB */
|
set_stopflag(x, 0); /* ~CSTOPB */
|
||||||
set_ctsrts(x,0); /* ~CRTSCTS;*/
|
set_ctsrts(x, 0); /* ~CRTSCTS;*/
|
||||||
set_xonxoff(x,0); /* (IXON | IXOFF | IXANY) */
|
set_xonxoff(x, 0); /* (IXON | IXOFF | IXANY) */
|
||||||
set_baudrate(x,*baud);
|
set_baudrate(x, *baud);
|
||||||
|
|
||||||
x->comhandle = fd;
|
x->comhandle = fd;
|
||||||
|
|
||||||
|
|
@ -390,50 +374,49 @@ static HANDLE open_serial(unsigned int com_num, t_comport *x)
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GetCommTimeouts(fd, &(x->old_timeouts)))
|
||||||
|
{
|
||||||
if (!GetCommTimeouts(fd, &(x->old_timeouts))){
|
|
||||||
post("[comport] Couldn't get old timeouts for serial device");
|
post("[comport] Couldn't get old timeouts for serial device");
|
||||||
};
|
}
|
||||||
|
|
||||||
/* setting new timeouts for read to immidiatly return */
|
/* setting new timeouts for read to immediately return */
|
||||||
timeouts.ReadIntervalTimeout = MAXDWORD;
|
timeouts.ReadIntervalTimeout = MAXDWORD;
|
||||||
timeouts.ReadTotalTimeoutMultiplier = 0;
|
timeouts.ReadTotalTimeoutMultiplier = 0;
|
||||||
timeouts.ReadTotalTimeoutConstant = 0;
|
timeouts.ReadTotalTimeoutConstant = 0;
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
timeouts.WriteTotalTimeoutConstant = 0;
|
timeouts.WriteTotalTimeoutConstant = 0;
|
||||||
|
|
||||||
if (!SetCommTimeouts(fd, &timeouts)){
|
if (!SetCommTimeouts(fd, &timeouts))
|
||||||
|
{
|
||||||
post("Couldnt set timeouts for serial device");
|
post("Couldnt set timeouts for serial device");
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
};
|
}
|
||||||
|
|
||||||
// this causes a segfault... WHY?!?
|
// this causes a segfault... WHY?!?
|
||||||
// outlet_float(x->x_status_outlet, (t_float)com_num);
|
// outlet_float(x->x_status_outlet, (t_float)com_num);
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE close_serial(t_comport *x)
|
static HANDLE close_serial(t_comport *x)
|
||||||
{
|
{
|
||||||
if(x->comhandle != INVALID_HANDLE_VALUE){
|
if(x->comhandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
if (!SetCommState(x->comhandle, &(x->dcb_old)) )
|
if (!SetCommState(x->comhandle, &(x->dcb_old)))
|
||||||
{
|
{
|
||||||
post("[comport] ** ERROR ** could not reset params to DCB of device %s\n",
|
post("[comport] ** ERROR ** could not reset params to DCB of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
|
if (!SetCommTimeouts(x->comhandle, &(x->old_timeouts)))
|
||||||
if (!SetCommTimeouts(x->comhandle, &(x->old_timeouts))){
|
{
|
||||||
post("[comport] Couldnt reset old_timeouts for serial device");
|
post("[comport] Couldn't reset old_timeouts for serial device");
|
||||||
};
|
}
|
||||||
CloseHandle(x->comhandle);
|
CloseHandle(x->comhandle);
|
||||||
// for some reason, this causes a segfault...
|
// for some reason, this causes a segfault...
|
||||||
// post("[comport] closed %s",x->serial_device->s_name);
|
// post("[comport] closed %s",x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
// this causes a segfault... WHY?!?
|
// this causes a segfault... WHY?!?
|
||||||
// outlet_float(x->x_status_outlet, 0);
|
// outlet_float(x->x_status_outlet, 0);
|
||||||
|
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,7 +436,6 @@ static int write_serial(t_comport *x, unsigned char serial_byte)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!WriteFile(x->comhandle, &serial_byte, dwToWrite, &dwWritten, &osWrite))
|
if (!WriteFile(x->comhandle, &serial_byte, dwToWrite, &dwWritten, &osWrite))
|
||||||
{
|
{
|
||||||
dwErr = GetLastError();
|
dwErr = GetLastError();
|
||||||
|
|
@ -475,7 +457,6 @@ static int write_serial(t_comport *x, unsigned char serial_byte)
|
||||||
static float set_baudrate(t_comport *x,t_float baud)
|
static float set_baudrate(t_comport *x,t_float baud)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
|
|
||||||
long baudbits = get_baud_ratebits(&baud);
|
long baudbits = get_baud_ratebits(&baud);
|
||||||
|
|
||||||
cfsetispeed(tio, baudbits);
|
cfsetispeed(tio, baudbits);
|
||||||
|
|
@ -490,7 +471,8 @@ static float set_bits(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
tio->c_cflag &= ~CSIZE;
|
tio->c_cflag &= ~CSIZE;
|
||||||
switch(nr){
|
switch(nr)
|
||||||
|
{
|
||||||
case 5: tio->c_cflag |= CS5; return 5;
|
case 5: tio->c_cflag |= CS5; return 5;
|
||||||
case 6: tio->c_cflag |= CS6; return 6;
|
case 6: tio->c_cflag |= CS6; return 6;
|
||||||
case 7: tio->c_cflag |= CS7; return 7;
|
case 7: tio->c_cflag |= CS7; return 7;
|
||||||
|
|
@ -505,7 +487,8 @@ static float set_parity(t_comport *x,int n)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
|
|
||||||
switch(n){
|
switch(n)
|
||||||
|
{
|
||||||
case 1:
|
case 1:
|
||||||
tio->c_cflag |= PARENB; tio->c_cflag &= ~PARODD; return 1;
|
tio->c_cflag |= PARENB; tio->c_cflag &= ~PARODD; return 1;
|
||||||
case -1:
|
case -1:
|
||||||
|
|
@ -517,26 +500,28 @@ static float set_parity(t_comport *x,int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* aktivate second stop bit with 1, 0(default)*/
|
/* activate second stop bit with 1, 0(default)*/
|
||||||
static float set_stopflag(t_comport *x, int nr)
|
static float set_stopflag(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
|
|
||||||
if(nr == 1){
|
if(nr == 1)
|
||||||
|
{
|
||||||
tio->c_cflag |= CSTOPB;
|
tio->c_cflag |= CSTOPB;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else tio->c_cflag &= ~CSTOPB;
|
||||||
tio->c_cflag &= ~CSTOPB;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* never testet */
|
/* never tested */
|
||||||
static int set_ctsrts(t_comport *x, int nr)
|
static int set_ctsrts(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
|
|
||||||
if(nr == 1){
|
if(nr == 1)
|
||||||
|
{
|
||||||
tio->c_cflag |= CRTSCTS;
|
tio->c_cflag |= CRTSCTS;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -548,7 +533,8 @@ static int set_xonxoff(t_comport *x, int nr)
|
||||||
{
|
{
|
||||||
struct termios *tio = &(x->com_termio);
|
struct termios *tio = &(x->com_termio);
|
||||||
|
|
||||||
if(nr == 1){
|
if(nr == 1)
|
||||||
|
{
|
||||||
tio->c_iflag |= (IXON | IXOFF | IXANY);
|
tio->c_iflag |= (IXON | IXOFF | IXANY);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -611,17 +597,16 @@ static int open_serial(unsigned int com_num, t_comport *x)
|
||||||
fcntl(fd, F_SETFL, FNDELAY);
|
fcntl(fd, F_SETFL, FNDELAY);
|
||||||
|
|
||||||
/* Save the Current Port Configuration */
|
/* Save the Current Port Configuration */
|
||||||
if(tcgetattr(fd, old) == -1 || tcgetattr(fd, new) == -1){
|
if(tcgetattr(fd, old) == -1 || tcgetattr(fd, new) == -1)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not get termios-structure of device %s\n",
|
error("[comport] ** ERROR ** could not get termios-structure of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
close(fd);
|
close(fd);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Setup the new port configuration...NON-CANONICAL INPUT MODE
|
||||||
/* Setupt the new port configuration...NON-CANONICAL INPUT MODE
|
.. as defined in termios.h */
|
||||||
.. as defined in termios.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* enable input and ignore modem controls */
|
/* enable input and ignore modem controls */
|
||||||
new->c_cflag |= (CREAD | CLOCAL);
|
new->c_cflag |= (CREAD | CLOCAL);
|
||||||
|
|
@ -662,17 +647,16 @@ static int open_serial(unsigned int com_num, t_comport *x)
|
||||||
close(fd);
|
close(fd);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int close_serial(t_comport *x)
|
static int close_serial(t_comport *x)
|
||||||
{
|
{
|
||||||
struct termios *tios = &(x->com_termio);
|
struct termios *tios = &(x->com_termio);
|
||||||
HANDLE fd = x->comhandle;
|
HANDLE fd = x->comhandle;
|
||||||
|
|
||||||
if(fd != INVALID_HANDLE_VALUE){
|
if(fd != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
tcsetattr(fd, TCSANOW, tios);
|
tcsetattr(fd, TCSANOW, tios);
|
||||||
close(fd);
|
close(fd);
|
||||||
// for some reason, this causes a segfault...
|
// for some reason, this causes a segfault...
|
||||||
|
|
@ -683,7 +667,6 @@ static int close_serial(t_comport *x)
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int set_serial(t_comport *x)
|
static int set_serial(t_comport *x)
|
||||||
{
|
{
|
||||||
if(tcsetattr(x->comhandle, TCSAFLUSH, &(x->com_termio)) == -1)
|
if(tcsetattr(x->comhandle, TCSAFLUSH, &(x->com_termio)) == -1)
|
||||||
|
|
@ -693,21 +676,19 @@ static int set_serial(t_comport *x)
|
||||||
|
|
||||||
static int write_serial(t_comport *x, unsigned char serial_byte)
|
static int write_serial(t_comport *x, unsigned char serial_byte)
|
||||||
{
|
{
|
||||||
|
|
||||||
return write(x->comhandle,(char *) &serial_byte,1);
|
return write(x->comhandle,(char *) &serial_byte,1);
|
||||||
|
|
||||||
/* flush pending I/O chars */
|
/* flush pending I/O chars */
|
||||||
/* but nowadays discards them ;-(
|
/* but nowadays discards them ;-(
|
||||||
else{
|
else
|
||||||
|
{
|
||||||
ioctl(x->comhandle,TCFLSH,TCOFLUSH);
|
ioctl(x->comhandle,TCFLSH,TCOFLUSH);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* else NT */
|
#endif /* else NT */
|
||||||
|
|
||||||
|
|
||||||
/* ------------------- serial pd methods --------------------------- */
|
/* ------------------- serial pd methods --------------------------- */
|
||||||
static void comport_pollintervall(t_comport *x, t_floatarg g)
|
static void comport_pollintervall(t_comport *x, t_floatarg g)
|
||||||
{
|
{
|
||||||
|
|
@ -722,7 +703,6 @@ static void comport_tick(t_comport *x)
|
||||||
|
|
||||||
x->x_hit = 0;
|
x->x_hit = 0;
|
||||||
|
|
||||||
|
|
||||||
if(fd == INVALID_HANDLE_VALUE) return;
|
if(fd == INVALID_HANDLE_VALUE) return;
|
||||||
|
|
||||||
/* while there are bytes, read them and send them out, ignore errors */
|
/* while there are bytes, read them and send them out, ignore errors */
|
||||||
|
|
@ -756,26 +736,25 @@ static void comport_tick(t_comport *x)
|
||||||
{
|
{
|
||||||
unsigned char serial_byte;
|
unsigned char serial_byte;
|
||||||
fd_set com_rfds;
|
fd_set com_rfds;
|
||||||
|
|
||||||
FD_ZERO(&com_rfds);
|
FD_ZERO(&com_rfds);
|
||||||
FD_SET(fd,&com_rfds);
|
FD_SET(fd,&com_rfds);
|
||||||
|
|
||||||
while((err=select(fd+1,&com_rfds,NULL,NULL,&null_tv)) > 0) {
|
while((err=select(fd+1,&com_rfds,NULL,NULL,&null_tv)) > 0)
|
||||||
|
{
|
||||||
err = read(fd,(char *) &serial_byte,1);
|
err = read(fd,(char *) &serial_byte,1);
|
||||||
|
|
||||||
/* while( (err = read(fd,(char *) &serial_byte,1)) > 0){ */
|
/* while( (err = read(fd,(char *) &serial_byte,1)) > 0){ */
|
||||||
outlet_float(x->x_data_outlet, (t_float) serial_byte);
|
outlet_float(x->x_data_outlet, (t_float) serial_byte);
|
||||||
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(err < 0){ /* if an readerror detected */
|
if(err < 0)
|
||||||
|
{ /* if a read error detected */
|
||||||
if(x->rxerrors == 0) /* post it once */
|
if(x->rxerrors == 0) /* post it once */
|
||||||
post("RXERRORS on serial line\n");
|
post("RXERRORS on serial line\n");
|
||||||
x->rxerrors = 1; /* remember */
|
x->rxerrors = 1; /* remember */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!x->x_hit) clock_delay(x->x_clock, 1);
|
if (!x->x_hit) clock_delay(x->x_clock, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -821,17 +800,20 @@ static void *comport_new(t_floatarg com_num, t_floatarg fbaud)
|
||||||
|
|
||||||
x->comport = (short)com_num;
|
x->comport = (short)com_num;
|
||||||
strncpy(x->serial_device_name,serial_device_name,strlen(serial_device_name)+1);
|
strncpy(x->serial_device_name,serial_device_name,strlen(serial_device_name)+1);
|
||||||
|
x->serial_device = test.serial_device; /* MP: we need this so 'help' doesn't crash */
|
||||||
x->baud = test.baud;
|
x->baud = test.baud;
|
||||||
x->comhandle = fd; /* holds the comport handle */
|
x->comhandle = fd; /* holds the comport handle */
|
||||||
|
|
||||||
if(fd == INVALID_HANDLE_VALUE ){
|
if(fd == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
/* postings in open routine */
|
/* postings in open routine */
|
||||||
post("[comport] invalid handle for %s",x->serial_device_name);
|
post("[comport] invalid handle for %s",x->serial_device_name);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
memcpy(&(test.dcb_old),&(x->dcb_old),sizeof(DCB)); /* save the old com config */
|
memcpy(&(x->dcb_old), &(test.dcb_old), sizeof(DCB)); /* save the old com config */
|
||||||
memcpy(&(test.dcb),&(x->dcb),sizeof(DCB)); /* for the new com config */
|
memcpy(&(x->dcb), &(test.dcb), sizeof(DCB)); /* for the new com config */
|
||||||
#else
|
#else
|
||||||
/* save the old com and new com config */
|
/* save the old com and new com config */
|
||||||
bcopy(&(test.oldcom_termio),&(x->oldcom_termio),sizeof(struct termios));
|
bcopy(&(test.oldcom_termio),&(x->oldcom_termio),sizeof(struct termios));
|
||||||
|
|
@ -857,11 +839,9 @@ static void *comport_new(t_floatarg com_num, t_floatarg fbaud)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void comport_free(t_comport *x)
|
||||||
comport_free(t_comport *x)
|
|
||||||
{
|
{
|
||||||
post("free serial...");
|
post("free serial...");
|
||||||
|
|
||||||
clock_unset(x->x_clock);
|
clock_unset(x->x_clock);
|
||||||
clock_free(x->x_clock);
|
clock_free(x->x_clock);
|
||||||
x->comhandle = close_serial(x);
|
x->comhandle = close_serial(x);
|
||||||
|
|
@ -871,7 +851,8 @@ comport_free(t_comport *x)
|
||||||
|
|
||||||
static void comport_baud(t_comport *x,t_floatarg f)
|
static void comport_baud(t_comport *x,t_floatarg f)
|
||||||
{
|
{
|
||||||
if(f == x->baud){
|
if(f == x->baud)
|
||||||
|
{
|
||||||
post("baudrate already %f\n",x->baud);
|
post("baudrate already %f\n",x->baud);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -880,11 +861,13 @@ static void comport_baud(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set baudrate of device %s\n",
|
error("[comport] ** ERROR ** could not set baudrate of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
else post("set baudrate of %s to %f\n",x->serial_device->s_name,x->baud);
|
else if(x->verbose > 0)
|
||||||
|
post("set baudrate of %s to %f\n",x->serial_device->s_name,x->baud);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comport_bits(t_comport *x,t_floatarg f)
|
static void comport_bits(t_comport *x,t_floatarg f)
|
||||||
|
|
@ -893,11 +876,13 @@ static void comport_bits(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set bits of device %s\n",
|
error("[comport] ** ERROR ** could not set bits of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
else post("set bits of %s to %f\n",x->serial_device->s_name,f);
|
else if(x->verbose > 0)
|
||||||
|
post("set bits of %s to %f\n",x->serial_device->s_name,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -907,11 +892,13 @@ static void comport_parity(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set extra paritybit of device %s\n",
|
error("[comport] ** ERROR ** could not set extra paritybit of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
else post("[comport] set extra paritybit of %s to %f\n",x->serial_device->s_name,f);
|
else if(x->verbose > 0)
|
||||||
|
post("[comport] set extra paritybit of %s to %f\n",x->serial_device->s_name,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comport_stopbit(t_comport *x,t_floatarg f)
|
static void comport_stopbit(t_comport *x,t_floatarg f)
|
||||||
|
|
@ -920,11 +907,13 @@ static void comport_stopbit(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set extra stopbit of device %s\n",
|
error("[comport] ** ERROR ** could not set extra stopbit of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
else post("[comport] set extra stopbit of %s to %f\n",x->serial_device->s_name,f);
|
else if(x->verbose > 0)
|
||||||
|
post("[comport] set extra stopbit of %s to %f\n",x->serial_device->s_name,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comport_rtscts(t_comport *x,t_floatarg f)
|
static void comport_rtscts(t_comport *x,t_floatarg f)
|
||||||
|
|
@ -933,11 +922,13 @@ static void comport_rtscts(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set rts_cts of device %s\n",
|
error("[comport] ** ERROR ** could not set rts_cts of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
else post("[comport] set rts-cts of %s to %f\n",x->serial_device->s_name,f);
|
else if(x->verbose > 0)
|
||||||
|
post("[comport] set rts-cts of %s to %f\n",x->serial_device->s_name,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void comport_xonxoff(t_comport *x,t_floatarg f)
|
static void comport_xonxoff(t_comport *x,t_floatarg f)
|
||||||
|
|
@ -946,7 +937,8 @@ static void comport_xonxoff(t_comport *x,t_floatarg f)
|
||||||
|
|
||||||
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
if(x->comhandle == INVALID_HANDLE_VALUE)return;
|
||||||
|
|
||||||
if(set_serial(x) == 0){
|
if(set_serial(x) == 0)
|
||||||
|
{
|
||||||
error("[comport] ** ERROR ** could not set xonxoff of device %s\n",
|
error("[comport] ** ERROR ** could not set xonxoff of device %s\n",
|
||||||
x->serial_device->s_name);
|
x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
|
|
@ -987,12 +979,15 @@ static void comport_print(t_comport *x, t_symbol *s, int argc, t_atom *argv)
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
char *pch = buf;
|
char *pch = buf;
|
||||||
|
|
||||||
while(argc--) {
|
while(argc--)
|
||||||
|
{
|
||||||
atom_string(argv++, buf, 255);
|
atom_string(argv++, buf, 255);
|
||||||
while(*pch != 0) {
|
while(*pch != 0)
|
||||||
|
{
|
||||||
write_serial(x, *pch++);
|
write_serial(x, *pch++);
|
||||||
}
|
}
|
||||||
if(argc > 0) {
|
if(argc > 0)
|
||||||
|
{
|
||||||
write_serial(x, ' ');
|
write_serial(x, ' ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1001,15 +996,14 @@ static void comport_print(t_comport *x, t_symbol *s, int argc, t_atom *argv)
|
||||||
static void comport_verbose(t_comport *x, t_floatarg f)
|
static void comport_verbose(t_comport *x, t_floatarg f)
|
||||||
{
|
{
|
||||||
x->verbose = f;
|
x->verbose = f;
|
||||||
if(f > 0)
|
if(f > 0) post("[comport] verbose is on: %d", (int) f);
|
||||||
post("[comport] verbose is on: %d", (int) f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void comport_help(t_comport *x)
|
static void comport_help(t_comport *x)
|
||||||
{
|
{
|
||||||
post("[comport] serial port %d (baud %f):",x->comport,x->baud);
|
post("[comport] serial port %d (baud %f):", x->comport, x->baud);
|
||||||
if(x->comport >= 0 && x->comport < COMPORT_MAX){
|
if(x->comport >= 0 && x->comport < COMPORT_MAX)
|
||||||
|
{
|
||||||
post("\tdevicename: %s",x->serial_device->s_name);
|
post("\tdevicename: %s",x->serial_device->s_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1024,17 +1018,18 @@ static void comport_help(t_comport *x)
|
||||||
" open <num> ... open device number num\n"
|
" open <num> ... open device number num\n"
|
||||||
" devicename <d> ... set device name to s (eg. /dev/ttyS8)\n"
|
" devicename <d> ... set device name to s (eg. /dev/ttyS8)\n"
|
||||||
" print <list> ... print list of atoms on serial\n"
|
" print <list> ... print list of atoms on serial\n"
|
||||||
" pollintervall <t> ... set poll ibntervall to t ticks\n"
|
" pollintervall <t> ... set poll interval to t ticks\n"
|
||||||
" verbose <level> ... for debug set verbosity to level\n"
|
" verbose <level> ... for debug set verbosity to level\n"
|
||||||
" help ... post this help");
|
" help ... post this help");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------- SETUP OBJECTS ------------------ */
|
/* ---------------- SETUP OBJECTS ------------------ */
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
void comport_setup(void)
|
void comport_setup(void)
|
||||||
{
|
{
|
||||||
comport_class
|
comport_class = class_new(gensym("comport"), (t_newmethod)comport_new,
|
||||||
= class_new(gensym("comport"), (t_newmethod)comport_new,
|
|
||||||
(t_method)comport_free, sizeof(t_comport),
|
(t_method)comport_free, sizeof(t_comport),
|
||||||
0, A_DEFFLOAT, A_DEFFLOAT, 0);
|
0, A_DEFFLOAT, A_DEFFLOAT, 0);
|
||||||
|
|
||||||
|
|
@ -1055,7 +1050,6 @@ void comport_setup(void)
|
||||||
class_addmethod(comport_class, (t_method)comport_devicename, gensym("devicename"), A_SYMBOL, 0);
|
class_addmethod(comport_class, (t_method)comport_devicename, gensym("devicename"), A_SYMBOL, 0);
|
||||||
class_addmethod(comport_class, (t_method)comport_print, gensym("print"), A_GIMME, 0);
|
class_addmethod(comport_class, (t_method)comport_print, gensym("print"), A_GIMME, 0);
|
||||||
class_addmethod(comport_class, (t_method)comport_pollintervall, gensym("pollintervall"), A_FLOAT, 0);
|
class_addmethod(comport_class, (t_method)comport_pollintervall, gensym("pollintervall"), A_FLOAT, 0);
|
||||||
|
|
||||||
class_addmethod(comport_class, (t_method)comport_verbose, gensym("verbose"), A_FLOAT, 0);
|
class_addmethod(comport_class, (t_method)comport_verbose, gensym("verbose"), A_FLOAT, 0);
|
||||||
class_addmethod(comport_class, (t_method)comport_help, gensym("help"), 0);
|
class_addmethod(comport_class, (t_method)comport_help, gensym("help"), 0);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue