//--------------------------------------------------------------------------- // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // // Except as contained in this notice, the name of Dallas Semiconductor // shall not be used except as stated in the Dallas Semiconductor // Branding Policy. //--------------------------------------------------------------------------- // // beoslnk.c - COM functions using BeOS to be used as a test // for DS2480 based Universal Serial Adapter 'U' // functions. // // Version: 1.01 // // History: 1.00 -> 1.01 Added support for owError library. // #include #include #include #include #include #include #include #include #include #include #include #include "ds2480.h" #include "ownet.h" // exportable functions SMALLINT OpenCOM(int, char *); void CloseCOM(int); void FlushCOM(int); SMALLINT WriteCOM(int, int, uchar *); int ReadCOM(int, int, uchar *); void BreakCOM(int); void SetBaudCOM(int, uchar); void msDelay(int); long msGettick(void); // miscellaneous functions int timepassed(struct timeval, struct timeval); // beoslnk.c globals int ComID[MAX_PORTNUM]; struct termios origterm; //--------------------------------------------------------------------------- // Attempt to open a com port. Keep the handle in ComID. // Set the starting baud rate to 9600. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will // be used to indicate the port number desired when calling // all other functions in this library. // // 'port_zstr' - zero terminate port name. For this platform // use format COMX where X is the port number. // // // Returns: TRUE(1) - success, COM port opened // FALSE(0) - failure, could not open specified port // SMALLINT OpenCOM(int portnum, char *port_zstr) { struct termios myterm; int result; speed_t baud; ComID[portnum] = open(port_zstr,O_RDWR|O_NONBLOCK); if (ComID[portnum] < 0) { ComID[portnum] = 0; OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED); return(0); } /* Get terminal parameters. */ tcgetattr(ComID[portnum],&myterm); /* Save original settings. */ origterm = myterm; /* Set to non-canonical mode, and no RTS/CTS handshaking */ myterm.c_iflag &= ~(BRKINT|ICRNL|IGNCR|INLCR|INPCK|ISTRIP|IXON|IXOFF|PARMRK); myterm.c_iflag |= IGNBRK|IGNPAR; myterm.c_oflag &= ~(OPOST); myterm.c_cflag &= ~(CRTSCTS|CSIZE|HUPCL|PARENB); myterm.c_cflag |= (CLOCAL|CS8|CREAD); myterm.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|IEXTEN|ISIG); myterm.c_cc[VMIN] = 0; myterm.c_cc[VTIME] = 3; tcsetattr(ComID[portnum],TCSANOW,&myterm); tcflush(ComID[portnum],TCIOFLUSH); /* Setting both the input and output speed since unsure if input speed HAS to be set. */ baud = B9600; cfsetispeed(&myterm,baud); cfsetospeed(&myterm,baud); /* Changing the baud rate seems to cause the DTR line to toggle. This probably allows the DCE device on the other end of the line to resync at a new baud rate. */ result = tcsetattr(ComID[portnum],TCSADRAIN,&myterm); if (result == -1) // if tcsetattr failed { tcflush (ComID[portnum], TCIOFLUSH); close(ComID[portnum]); ComID[portnum] = 0; OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); return(0); } msDelay(10); // wait 10 milliseconds return(1); } //--------------------------------------------------------------------------- // Closes the connection to the port. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // void CloseCOM(int portnum) { tcflush(ComID[portnum], TCIOFLUSH); close(ComID[portnum]); ComID[portnum] = 0; } //--------------------------------------------------------------------------- // Flush the rx and tx buffers // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // void FlushCOM(int portnum) { // purge any information in the buffer tcflush (ComID[portnum], TCIOFLUSH); } //-------------------------------------------------------------------------- // Write an array of bytes to the COM port. Assume that baud rate has been set. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'outlen' - number of bytes to write to COM port // 'outbuf' - pointer to an array of bytes to write // // Returns: TRUE(1) - success // FALSE(0) - failure // SMALLINT WriteCOM(int portnum, int outlen, uchar *outbuf) { long count = outlen; int i = write(ComID[portnum], outbuf, outlen); tcdrain(ComID[portnum]); return (i == count); } //-------------------------------------------------------------------------- // Read an array of bytes to the COM port, verify that it was // sent out. Assume that baud rate has been set. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'inlen' - number of bytes to read from COM port // 'inbuf' - pointer to a buffer to hold the incomming bytes // // Returns: number of characters read // int ReadCOM(int portnum, int inlen, uchar *inbuf) { int btotal = 0; int bread = 0; struct timeval curtime,endtime,timeout; struct timeval readtimeout; int ready; // set timeout to 10ms timeout.tv_sec = 0; timeout.tv_usec = 10000; /* Init the wait timer */ gettimeofday(&curtime,NULL); endtime.tv_usec = (curtime.tv_usec + timeout.tv_usec) % 1000000; endtime.tv_sec = curtime.tv_sec + (curtime.tv_usec + timeout.tv_usec) / 1000000; /* Loop until we fill the buffer, time out, or get a single packet */ while ((btotal < inlen) && (!timepassed(curtime,endtime))) { if ((bread = read(ComID[portnum],inbuf,inlen-btotal)) > 0) { btotal += bread; inbuf += bread; } if (bread < 0) { if (errno != EWOULDBLOCK) { return(btotal); } } gettimeofday(&curtime,NULL); } return(btotal); } //-------------------------------------------------------------------------- // Send a break on the com port for at least 2 ms // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // void BreakCOM(int portnum) { int duration = 0; // see docs on "termios"--break may be tcsendbreak(ComID[portnum], duration); // too long } //-------------------------------------------------------------------------- // Set the baud rate on the com port. // // 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to // OpenCOM to indicate the port number. // 'new_baud' - new baud rate defined as // PARMSET_9600 0x00 // PARMSET_19200 0x02 // PARMSET_57600 0x04 // PARMSET_115200 0x06 // void SetBaudCOM(int portnum, uchar new_baud) { struct termios myterm; int result; speed_t newspeed; result = tcgetattr(ComID[portnum],&myterm); if (result < 0) { tcflush(ComID[portnum], TCIOFLUSH); close(ComID[portnum]); ComID[portnum] = 0; return; } // convert parameter to baud rate switch(new_baud) { case PARMSET_9600: newspeed = B9600; break; case PARMSET_19200: newspeed = B19200; break; case PARMSET_57600: newspeed = B57600; break; case PARMSET_115200: newspeed = B115200; break; } tcflush(ComID[portnum], TCIOFLUSH); /* Should I Set an extra stop bit?? */ myterm.c_cflag |= CSTOPB; /* Set input and output speeds in structure */ cfsetispeed(&myterm,newspeed); cfsetospeed(&myterm,newspeed); /* Set baud rate on port. */ result = tcsetattr(ComID[portnum],TCSADRAIN,&myterm); if (result < 0) { tcflush(ComID[portnum], TCIOFLUSH); close(ComID[portnum]); ComID[portnum] = 0; return; } } //-------------------------------------------------------------------------- // Description: // Delay for at least 'len' milliseconds // void msDelay(int len) { bigtime_t timedelay; // in microseconds timedelay = len * 1000; snooze(timedelay); // snooze blocks the calling thread for the given number of microseconds. } //-------------------------------------------------------------------------- // Get the current millisecond tick count. Does not have to represent // an actual time, it just needs to be an incrementing timer. // long msGettick(void) { long ms; bigtime_t timetick; timetick = system_time(); // system_time() returns a value in microseconds. timetick = timetick / 1000; ms = (long) timetick; return ms; } /* Returns 1 if current time is greater than end time. */ int timepassed(struct timeval current, struct timeval end) { if (current.tv_sec > end.tv_sec) { return(1); } if (current.tv_sec == end.tv_sec) { if (current.tv_usec >= end.tv_usec) { return(1); } } return(0); }