*** empty log message ***

svn path=/trunk/externals/iem/comport/; revision=5253
This commit is contained in:
Martin Peach 2006-06-18 19:20:48 +00:00
parent 44e9f1bc1a
commit 5b5d56d168

View file

@ -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);