-// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the
-// distribution.
-// * All advertising materials mentioning features or use of this
-// software must display the following acknowledgement: This product
-// includes software developed by tm3d.de and its contributors.
-// * Neither the name of tm3d.de nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <time.h>
-#include <termios.h>
-#include <errno.h>
-#include <sys/time.h>
-#include "owARDUINOInterface.h"
-
-#define MODE_DATA 0xE1
-#define MODE_COMMAND 0xE3
-
-// Baud rate bits
-#define PARMSET_9600 0x00
-#define PARMSET_19200 0x02
-#define PARMSET_57600 0x04
-#define PARMSET_115200 0x06
-
-
-
-#define COM_IDENTIFER 1
-#define COM_RESET 2
-#define COM_SEARCH_INIT 3
-#define COM_SEARCH_NEXT 4
-#define COM_BLOCK 5
-#define COM_SBYTE 6
-#define COM_RBYTE 7
-#define COM_SBIT 8
-#define COM_RBIT 9
-
-//---------------------------------------------------------------------------
-// Description:
-// 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 owARDUINOInterface::FlushCOM() {
- tcflush(fd, TCIOFLUSH);
-}
-
-
-int owARDUINOInterface::OpenCOM(uint8_t comnr) {
- struct termios t; // see man termios - declared as above
- int rc;
- //int fd;
- char port_zstr[100];
- if (com_init) return fd;
-
- sprintf(port_zstr,"/dev/ttyUSB%i",comnr);
-
- fd = open(port_zstr, O_RDWR|O_NONBLOCK| O_NOCTTY );
- if (fd<0)
- {
- log->set(OWLOG_ERROR,"ERROR open Com %s return %i",port_zstr,fd);
- return fd;
- }
- rc = tcgetattr (fd, &t);
- if (rc < 0)
- {
- int tmp;
- tmp = errno;
- close(fd);
- errno = tmp;
- log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr);
- return rc; // changed (2.00), used to return rc;
- }
-
- cfsetospeed(&t, B9600);
- cfsetispeed (&t, B9600);
-
- // Get terminal parameters. (2.00) removed raw
- tcgetattr(fd,&t);
- // Save original settings.
- origterm = t;
-
- t.c_cflag &= ~PARENB; // Make 8n1
- t.c_cflag &= ~CSTOPB;
- t.c_cflag &= ~CSIZE;
- t.c_cflag |= CS8;
-
- t.c_cflag &= ~CRTSCTS; // no flow control
- t.c_cc[VMIN] = 1; // read doesn't block
- t.c_cc[VTIME] = 5; // 0.5 seconds read timeout
- t.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
- t.c_cflag &= ~CRTSCTS; // no flow control
- t.c_iflag &= ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl
-/* Make raw */
- cfmakeraw(&t);
- tcflush(fd,TCIOFLUSH);
-
- rc = tcsetattr(fd, TCSAFLUSH, &t);
-
- if (rc < 0)
- {
- int tmp;
- tmp = errno;
- close(fd);
- errno = tmp;
- log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr);
- return rc; // changed (2.00), used to return rc;
- }
- com_init=1;
- return fd; // changed (2.00), used to return fd;
-}
-
-
-//---------------------------------------------------------------------------
-// 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 owARDUINOInterface::CloseCOM()
-{
- // restore tty settings
- tcsetattr(fd, TCSAFLUSH, &origterm);
- FlushCOM();
- close(fd);
- com_init=0;
-
-}
-
-
-//--------------------------------------------------------------------------
-// Write 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 provided will
-// be used to indicate the port number desired when calling
-// all other functions in this library.
-// Returns 1 for success and 0 for failure
-//
-int owARDUINOInterface::WriteCOM( int outlen, uint8_t *outbuf)
-{
- long count = outlen;
- int i=0;
- for (int k=0;k<outlen;k++) {
- i+= write(fd, outbuf+k, 1);
-// sleep(1);
- }
-
- tcdrain(fd);
- 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.
-// 'outlen' - number of bytes to write to COM port
-// 'outbuf' - pointer ot an array of bytes to write
-//
-// Returns: TRUE(1) - success
-// FALSE(0) - failure
-//
-int owARDUINOInterface::ReadCOM( int inlen, uint8_t *inbuf)
-{
- fd_set filedescr;
- struct timeval tval;
- int cnt;
-
- // loop to wait until each byte is available and read it
- for (cnt = 0; cnt < inlen; cnt++)
- {
- // set a descriptor to wait for a character available
- FD_ZERO(&filedescr);
- FD_SET(fd,&filedescr);
- // set timeout to 10ms
- tval.tv_sec = 10;
- tval.tv_usec = 10000;
-
- // if byte available read or return bytes read
- if (select(fd+1,&filedescr,NULL,NULL,&tval) != 0)
- {
- if (read(fd,&inbuf[cnt],1) != 1) {
- log->set(OWLOG_ERROR,"Read Error on Serial");
-
- return cnt;
- }
- }
- else {
- log->set(OWLOG_ERROR,"Read Error on Serial (select)");
- return cnt;
- }
- }
-
-
- // success, so return desired length
- return inlen;
-}
-
-
-
-
-//--------------------------------------------------------------------------
-// Description:
-// 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 owARDUINOInterface::BreakCOM()
-{
- int duration = 0; // see man termios break may be
- tcsendbreak(fd, 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 owARDUINOInterface::SetBaudCOM( uint8_t new_baud)
-{
- struct termios t;
- int rc;
- speed_t baud;
-
- // read the attribute structure
- rc = tcgetattr(fd, &t);
- if (rc < 0)
- {
- close(fd);
- log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)");
-
- return;
- }
-
- // convert parameter to linux baud rate
- switch(new_baud)
- {
- case PARMSET_9600:
- baud = B9600;
- break;
- case PARMSET_19200:
- baud = B19200;
- break;
- case PARMSET_57600:
- baud = B57600;
- break;
- case PARMSET_115200:
- baud = B115200;
- break;
- default:
- baud = B9600;
- break;
- }
-
- // set baud in structure
- cfsetospeed(&t, baud);
- cfsetispeed(&t, baud);
-
- // change baud on port
- rc = tcsetattr(fd, TCSAFLUSH, &t);
- if (rc < 0) {
- log->set(OWLOG_ERROR,"Error on Serial (set Boudrate)");
-
- close(fd);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-int owARDUINOInterface::InitAdapter(uint8_t nr) {
- // attempt to open the communications port
- if ((fd = OpenCOM(nr)) < 0)
- {
- log->set(OWLOG_ERROR,"OWERROR_OPENCOM_FAILED");
- return -1;
- }
- sleep(2);
- uint8_t readbuffer[20],sendpacket[20];
- uint8_t sendlen=0;
- sendpacket[sendlen++]=0x01;
- sendpacket[sendlen++]=0x00;
- sendpacket[sendlen++]=0x03;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(3,readbuffer)) == 3) {
-
- // printf("%02X %02X %02X\n",readbuffer[0],readbuffer[1],readbuffer[2] );
-
-
-
- } else {
- //printf("%i\n",sendlen);
- log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED");
- }
- } else log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED");
-
- com_init=1;
-
-
- return 1;
-}
-
-
-int owARDUINOInterface::owFirst() {
- uint8_t readbuffer[20],sendpacket[20];
- uint8_t sendlen=0;
- sendpacket[sendlen++]=0x03;
- sendpacket[sendlen++]=0x00;
- sendpacket[sendlen++]=0x08;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(8,readbuffer)) == 8) {
- if (readbuffer[0]!=0) {
- for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i];
- return 1;
- }
- }
- }
- return 0;
-
-}
-int owARDUINOInterface::owNext() {
- uint8_t readbuffer[20],sendpacket[20];
- uint8_t sendlen=0;
- sendpacket[sendlen++]=0x04;
- sendpacket[sendlen++]=0x00;
- sendpacket[sendlen++]=0x08;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(8,readbuffer)) == 8) {
- if (readbuffer[0]!=0) {
- for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i];
- return 1;
- }
- }
- }
- return 0;
-
-}
-
-
-void owARDUINOInterface::ReleaseAdapter() {
- CloseCOM();
-}
-
-
-int owARDUINOInterface::Reset() {
- uint8_t readbuffer[5],sendpacket[5];
- uint8_t sendlen=0;
- /* size_t l;
-
- if ((l=read(fd,readbuffer,5))>0) {
- printf("in buf %i bytes %02X %02X %02X %02X %02X\n",l,readbuffer[0],readbuffer[1],readbuffer[2],readbuffer[3],readbuffer[4]);
- }*/
- sendlen=0;
- sendpacket[sendlen++]=0x02;
- sendpacket[sendlen++]=0x00;
- sendpacket[sendlen++]=0x01;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(1,readbuffer)) == 1) {
- // printf("Reset %i\n",readbuffer[0]);
- if (readbuffer[0]) return 1;
-
- }
- }
-
- return 0;
-}
-
-
-uint8_t owARDUINOInterface::sendrecivByte(uint8_t byte) {
-
- uint8_t readbuffer[5],sendpacket[5];
- uint8_t sendlen=0;
-/* size_t l;
- if ((l=read(fd,readbuffer,5))>0) {
- printf("in buf %i bytes %02X %02X %02X %02X %02X\n",l,readbuffer[0],readbuffer[1],readbuffer[2],readbuffer[3],readbuffer[4]);
- }*/
- if (byte!=0xFF) {
- sendlen=0;
- sendpacket[sendlen++]=COM_SBYTE;
- sendpacket[sendlen++]=0x01;
- sendpacket[sendlen++]=0x01;
- sendpacket[sendlen++]=byte;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(1,readbuffer)) == 1) {
- // printf("Send %02X %02X \n",byte,readbuffer[0]);
-
- return byte;
- }
- }
- } else {
- sendlen=0;
- sendpacket[sendlen++]=COM_RBYTE;
- sendpacket[sendlen++]=0x00;
- sendpacket[sendlen++]=0x01;
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(1,readbuffer)) == 1) {
- // printf("Recive %02X\n",readbuffer[0]);
- return readbuffer[0];
- }
- }
-
- }
-
- return 0;
-}
-uint8_t owARDUINOInterface::sendrecivBit(uint8_t bit) {
- return 0;
-}
-
-int owARDUINOInterface::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {
- int i=0;
- data->resize(scount);
- uint8_t readbuffer[128],sendpacket[128+3];
- uint8_t sendlen=0;
- sendpacket[sendlen++]=COM_BLOCK;
- sendpacket[sendlen++]=scount;
- sendpacket[sendlen++]=rcount;
- for(uint8_t v:*data) {
- sendpacket[sendlen++]=v;
- (*data)[i]=v;i++;
- }
- if (WriteCOM(sendlen,sendpacket)) {
- if ((sendlen=ReadCOM(rcount,readbuffer)) == rcount) {
- for(i=0;i<rcount;i++) {
- //printf("%02X ",readbuffer[i]);
- data->push_back(readbuffer[i]);
- }
- //printf("\n");
- }
- }
-
-
- return 0;
-}
-
+// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are\r
+// met:\r
+//\r
+// * Redistributions of source code must retain the above copyright\r
+// notice, this list of conditions and the following disclaimer.\r
+// * Redistributions in binary form must reproduce the above copyright\r
+// notice, this list of conditions and the following disclaimer in the\r
+// documentation and/or other materials provided with the\r
+// distribution.\r
+// * All advertising materials mentioning features or use of this\r
+// software must display the following acknowledgement: This product\r
+// includes software developed by tm3d.de and its contributors.\r
+// * Neither the name of tm3d.de nor the names of its contributors may\r
+// be used to endorse or promote products derived from this software\r
+// without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+#ifdef LINUX\r
+#include <unistd.h>\r
+#include <sys/select.h>\r
+#include <sys/ioctl.h>\r
+#include <termios.h>\r
+#include <sys/time.h>\r
+#endif\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <time.h>\r
+#include <errno.h>\r
+#include "owARDUINOInterface.h"\r
+\r
+\r
+#define COM_IDENTIFER 1\r
+#define COM_RESET 2\r
+#define COM_SEARCH_INIT 3\r
+#define COM_SEARCH_NEXT 4\r
+#define COM_BLOCK 5\r
+#define COM_SBYTE 6\r
+#define COM_RBYTE 7\r
+#define COM_SBIT 8\r
+#define COM_RBIT 9\r
+\r
+//---------------------------------------------------------------------------\r
+// Description:\r
+// flush the rx and tx buffers\r
+//\r
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to\r
+// OpenCOM to indicate the port number.\r
+//\r
+void owARDUINOInterface::FlushCOM() {\r
+#ifdef LINUX\r
+ tcflush(fd, TCIOFLUSH);\r
+#endif \r
+#ifdef WIN\r
+ PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT |\r
+ PURGE_TXCLEAR | PURGE_RXCLEAR);\r
+#endif\r
+}\r
+\r
+#ifdef LINUX\r
+int \r
+#endif\r
+#ifdef WIN\r
+HANDLE \r
+#endif\r
+owARDUINOInterface::OpenCOM(uint8_t comnr)\r
+{\r
+ char port_zstr[100];\r
+#ifdef LINUX\r
+ struct termios t; // see man termios - declared as above\r
+ int rc;\r
+ //int fd;\r
+ \r
+ if (com_init) return fd;\r
+\r
+ sprintf(port_zstr,"/dev/ttyUSB%i",comnr);\r
+\r
+ fd = open(port_zstr, O_RDWR|O_NONBLOCK| O_NOCTTY );\r
+ if (fd<0)\r
+ {\r
+ log->set(OWLOG_ERROR,"ERROR open Com %s return %i",port_zstr,fd);\r
+ return fd;\r
+ }\r
+ rc = tcgetattr (fd, &t);\r
+ if (rc < 0)\r
+ {\r
+ int tmp;\r
+ tmp = errno;\r
+ close(fd);\r
+ errno = tmp;\r
+ log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr);\r
+ return rc; // changed (2.00), used to return rc;\r
+ }\r
+\r
+ cfsetospeed(&t, B9600);\r
+ cfsetispeed (&t, B9600);\r
+\r
+ // Get terminal parameters. (2.00) removed raw\r
+ tcgetattr(fd,&t);\r
+ // Save original settings.\r
+ origterm = t;\r
+\r
+ t.c_cflag &= ~PARENB; // Make 8n1\r
+ t.c_cflag &= ~CSTOPB;\r
+ t.c_cflag &= ~CSIZE;\r
+ t.c_cflag |= CS8;\r
+\r
+ t.c_cflag &= ~CRTSCTS; // no flow control\r
+ t.c_cc[VMIN] = 1; // read doesn't block\r
+ t.c_cc[VTIME] = 5; // 0.5 seconds read timeout\r
+ t.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines\r
+ t.c_cflag &= ~CRTSCTS; // no flow control\r
+ t.c_iflag &= ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl\r
+/* Make raw */\r
+ cfmakeraw(&t);\r
+ tcflush(fd,TCIOFLUSH);\r
+\r
+ rc = tcsetattr(fd, TCSAFLUSH, &t);\r
+ \r
+ if (rc < 0)\r
+ {\r
+ int tmp;\r
+ tmp = errno;\r
+ close(fd);\r
+ errno = tmp;\r
+ log->set(OWLOG_ERROR,"OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s",port_zstr);\r
+ return rc; // changed (2.00), used to return rc;\r
+ }\r
+ com_init=1;\r
+ return fd; // changed (2.00), used to return fd;\r
+#endif\r
+#ifdef WIN\r
+ short fRetVal;\r
+ COMMTIMEOUTS CommTimeOuts;\r
+ DCB dcb;\r
+ int comnr1 = comnr;\r
+ sprintf_s(port_zstr,100, "COM%d", comnr1);\r
+ if (fd <= 0) {\r
+ if ((fd = CreateFileA(port_zstr, GENERIC_READ | GENERIC_WRITE,\r
+ 0,\r
+ NULL, // no security attrs\r
+ OPEN_EXISTING,\r
+ FILE_FLAG_OVERLAPPED, // overlapped I/O\r
+ NULL)) == (HANDLE)-1) {\r
+ fd = 0;\r
+ log->set(OWLOG_ERROR, "ERROR open Com %s return %i", port_zstr, fd);\r
+ return (FALSE);\r
+ } else {\r
+ // get any early notifications\r
+ SetCommMask(fd, EV_RXCHAR | EV_TXEMPTY | EV_ERR | EV_BREAK);\r
+ SetupComm(fd, 2048, 2048);\r
+ // purge any information in the buffer\r
+ PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);\r
+ // set up for overlapped non-blocking I/O\r
+ CommTimeOuts.ReadIntervalTimeout = 0;\r
+ CommTimeOuts.ReadTotalTimeoutMultiplier = 20;\r
+ CommTimeOuts.ReadTotalTimeoutConstant = 40;\r
+ CommTimeOuts.WriteTotalTimeoutMultiplier = 20;\r
+ CommTimeOuts.WriteTotalTimeoutConstant = 40;\r
+ SetCommTimeouts(fd, &CommTimeOuts);\r
+ // setup the com port\r
+ GetCommState(fd, &dcb);\r
+ dcb.BaudRate = CBR_9600; // current baud rate\r
+ dcb.fBinary = TRUE; // binary mode, no EOF check\r
+ dcb.fParity = FALSE; // enable parity checking\r
+ dcb.fOutxCtsFlow = FALSE; // CTS output flow control\r
+ dcb.fOutxDsrFlow = FALSE; // DSR output flow control\r
+ dcb.fDtrControl = FALSE; // DTR flow control type\r
+ dcb.fDsrSensitivity = FALSE; // DSR sensitivity\r
+ dcb.fTXContinueOnXoff = FALSE; // XOFF continues Tx\r
+ dcb.fOutX = FALSE; // XON/XOFF out flow control\r
+ dcb.fInX = FALSE; // XON/XOFF in flow control\r
+ dcb.fErrorChar = FALSE; // enable error replacement\r
+ dcb.fNull = FALSE; // enable null stripping\r
+ dcb.fRtsControl = FALSE; // RTS flow control\r
+ dcb.fAbortOnError = FALSE; // abort reads/writes on error\r
+ dcb.XonLim = 0; // transmit XON threshold\r
+ dcb.XoffLim = 0; // transmit XOFF threshold\r
+ dcb.ByteSize = 8; // number of bits/byte, 4-8\r
+ dcb.Parity = NOPARITY; // 0-4=no,odd,even,mark,space\r
+ dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2\r
+ dcb.XonChar = 0; // Tx and Rx XON character\r
+ dcb.XoffChar = 0; // Tx and Rx XOFF character\r
+ dcb.ErrorChar = 0; // error replacement character\r
+ dcb.EofChar = 0; // end of input character\r
+ dcb.EvtChar = 0; // received event character\r
+ fRetVal = SetCommState(fd, &dcb);\r
+\r
+ }\r
+ // check if successfull\r
+ if (!fRetVal) {\r
+ CloseHandle(fd);\r
+ fd = 0;\r
+ log->set(OWLOG_ERROR, "OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s", port_zstr);\r
+ }\r
+ return (fd);\r
+ }\r
+ return 0;\r
+#endif\r
+}\r
+\r
+\r
+//---------------------------------------------------------------------------\r
+// Closes the connection to the port.\r
+//\r
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to\r
+// OpenCOM to indicate the port number.\r
+//\r
+void owARDUINOInterface::CloseCOM()\r
+{\r
+#ifdef LINUX\r
+ // restore tty settings\r
+ tcsetattr(fd, TCSAFLUSH, &origterm);\r
+ FlushCOM();\r
+ close(fd);\r
+#endif\r
+#ifdef WIN\r
+ // disable event notification and wait for thread\r
+ // to halt\r
+ SetCommMask(fd, 0);\r
+\r
+ PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);\r
+ CloseHandle(fd);\r
+ fd = 0;\r
+#endif\r
+ com_init = 0;\r
+\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------\r
+// Write an array of bytes to the COM port, verify that it was\r
+// sent out. Assume that baud rate has been set.\r
+//\r
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will\r
+// be used to indicate the port number desired when calling\r
+// all other functions in this library.\r
+// Returns 1 for success and 0 for failure\r
+//\r
+int owARDUINOInterface::WriteCOM( int outlen, uint8_t *outbuf) {\r
+#ifdef LINUX\r
+ long count = outlen;\r
+ int i=0;\r
+ for (int k=0;k<outlen;k++) {\r
+ i+= write(fd, outbuf+k, 1);\r
+// sleep(1);\r
+ }\r
+\r
+ tcdrain(fd);\r
+ return (i == count);\r
+#endif\r
+#ifdef WIN\r
+ BOOL fWriteStat;\r
+ DWORD dwBytesWritten = 0;\r
+ DWORD ler = 0, to;\r
+ OVERLAPPED osWrite = { 0 };\r
+ // calculate a timeout\r
+ to = 20 * outlen + 60;\r
+ // write the byte\r
+ osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\r
+ ResetEvent(osWrite.hEvent);\r
+ fWriteStat = WriteFile(fd, (LPSTR)&outbuf[0], outlen, &dwBytesWritten, &osWrite);\r
+ // check for an error\r
+ // Sleep(100);\r
+ if (!fWriteStat)\r
+ ler = GetLastError();\r
+ // if not done writting then wait\r
+ if (!fWriteStat && ler == ERROR_IO_PENDING) {\r
+ // log->set(OWLOG_ERROR, "SERIAL_ERROR_IO_PENDING");\r
+ WaitForSingleObject(osWrite.hEvent, to);\r
+ // verify all is written correctly\r
+\r
+ fWriteStat = GetOverlappedResult(fd, &osWrite, &dwBytesWritten, FALSE);\r
+ }\r
+ // check results of write\r
+ if (!fWriteStat || (dwBytesWritten != (DWORD)outlen))\r
+ return 0;\r
+ else\r
+ return 1;\r
+#endif\r
+}\r
+\r
+\r
+//--------------------------------------------------------------------------\r
+// Read an array of bytes to the COM port, verify that it was\r
+// sent out. Assume that baud rate has been set.\r
+//\r
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to\r
+// OpenCOM to indicate the port number.\r
+// 'outlen' - number of bytes to write to COM port\r
+// 'outbuf' - pointer ot an array of bytes to write\r
+//\r
+// Returns: TRUE(1) - success\r
+// FALSE(0) - failure\r
+//\r
+int owARDUINOInterface::ReadCOM( int inlen, uint8_t *inbuf)\r
+{\r
+#ifdef LINUX\r
+ fd_set filedescr;\r
+ struct timeval tval;\r
+ int cnt;\r
+\r
+ // loop to wait until each byte is available and read it\r
+ for (cnt = 0; cnt < inlen; cnt++)\r
+ {\r
+ // set a descriptor to wait for a character available\r
+ FD_ZERO(&filedescr);\r
+ FD_SET(fd,&filedescr);\r
+ // set timeout to 10ms\r
+ tval.tv_sec = 10;\r
+ tval.tv_usec = 10000;\r
+\r
+ // if byte available read or return bytes read\r
+ if (select(fd+1,&filedescr,NULL,NULL,&tval) != 0)\r
+ {\r
+ if (read(fd,&inbuf[cnt],1) != 1) {\r
+ log->set(OWLOG_ERROR,"Read Error on Serial");\r
+\r
+ return cnt;\r
+ }\r
+ }\r
+ else {\r
+ log->set(OWLOG_ERROR,"Read Error on Serial (select)");\r
+ return cnt;\r
+ }\r
+ }\r
+\r
+ \r
+ // success, so return desired length\r
+ return inlen;\r
+#endif\r
+#ifdef WIN\r
+ DWORD dwLength = 0;\r
+ BOOL fReadStat;\r
+ DWORD ler = 0, to;\r
+ OVERLAPPED osReader = { 0 };\r
+ // calculate a timeout\r
+ to = 20 * inlen + 60;\r
+ // read\r
+ osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\r
+ ResetEvent(osReader.hEvent);\r
+ fReadStat = ReadFile(fd, (LPSTR)&inbuf[0], inlen, &dwLength, &osReader);\r
+ //Sleep(100);\r
+ // check for an error\r
+ if (!fReadStat) {\r
+ ler = GetLastError();\r
+ // log->set(OWLOG_ERROR, "Read Error on Serial");\r
+ }\r
+ // if not done writing then wait\r
+ int e = 0;\r
+ while (!fReadStat && ler == ERROR_IO_PENDING) {\r
+ // wait until everything is read\r
+ // log->set(OWLOG_ERROR, "Read Error on Serial");\r
+ // printf("try Read %i\n", e); e++;\r
+ WaitForSingleObject(osReader.hEvent, to);\r
+ // verify all is read correctly\r
+ fReadStat = GetOverlappedResult(fd, &osReader, &dwLength, FALSE);\r
+ //printf("%i %i\n", dwLength, inlen);\r
+ if (dwLength == inlen) break;\r
+ if (e == 3) break;\r
+ printf("repeat\n");\r
+\r
+ }\r
+ // check results\r
+ if (fReadStat)\r
+ return dwLength;\r
+ else\r
+ return 0;\r
+#endif\r
+}\r
+\r
+\r
+/*\r
+\r
+//--------------------------------------------------------------------------\r
+// Description:\r
+// Send a break on the com port for at least 2 ms\r
+//\r
+// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to\r
+// OpenCOM to indicate the port number.\r
+//\r
+void owARDUINOInterface::BreakCOM()\r
+{\r
+ int duration = 0; // see man termios break may be\r
+ tcsendbreak(fd, duration); // too long\r
+}\r
+\r
+*/\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+int owARDUINOInterface::InitAdapter(uint8_t nr) {\r
+ // attempt to open the communications port\r
+ if ((fd = OpenCOM(nr)) < 0)\r
+ {\r
+ log->set(OWLOG_ERROR,"OWERROR_OPENCOM_FAILED");\r
+ return -1;\r
+ }\r
+#ifdef WIN\r
+ Sleep(2000);\r
+#endif\r
+#ifdef LINUX\r
+ sleep(2);\r
+#endif\r
+ uint8_t readbuffer[20],sendpacket[20];\r
+ uint8_t sendlen=0;\r
+ sendpacket[sendlen++]=0x01;\r
+ sendpacket[sendlen++]=0x00;\r
+ sendpacket[sendlen++]=0x03;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(3,readbuffer)) == 3) {\r
+ // printf("%02X %02X %02X\n",readbuffer[0],readbuffer[1],readbuffer[2] );\r
+ } else {\r
+ log->set(OWLOG_ERROR,"OWERROR_READCOM_FAILED");\r
+ }\r
+ } else log->set(OWLOG_ERROR,"OWERROR_WRITECOM_FAILED"); \r
+ com_init=1;\r
+ return 1; \r
+}\r
+\r
+\r
+int owARDUINOInterface::owFirst() {\r
+ uint8_t readbuffer[20],sendpacket[20];\r
+ uint8_t sendlen=0;\r
+ sendpacket[sendlen++]=0x03;\r
+ sendpacket[sendlen++]=0x00; \r
+ sendpacket[sendlen++]=0x08;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(8,readbuffer)) == 8) {\r
+ if (readbuffer[0]!=0) {\r
+ for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i];\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+\r
+}\r
+int owARDUINOInterface::owNext() {\r
+ uint8_t readbuffer[20],sendpacket[20];\r
+ uint8_t sendlen=0;\r
+ sendpacket[sendlen++]=0x04;\r
+ sendpacket[sendlen++]=0x00; \r
+ sendpacket[sendlen++]=0x08;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(8,readbuffer)) == 8) {\r
+ if (readbuffer[0]!=0) {\r
+ for (int i=0;i<8;i++) ROM_NO[i]=readbuffer[i];\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+\r
+}\r
+\r
+\r
+void owARDUINOInterface::ReleaseAdapter() {\r
+ CloseCOM();\r
+}\r
+\r
+\r
+int owARDUINOInterface::Reset() {\r
+ uint8_t readbuffer[5],sendpacket[5];\r
+ uint8_t sendlen=0;\r
+ sendlen=0;\r
+ sendpacket[sendlen++]=0x02;\r
+ sendpacket[sendlen++]=0x00;\r
+ sendpacket[sendlen++]=0x01;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(1,readbuffer)) == 1) {\r
+ if (readbuffer[0]) return 1;\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+uint8_t owARDUINOInterface::sendrecivByte(uint8_t byte) {\r
+ \r
+ uint8_t readbuffer[5],sendpacket[5];\r
+ uint8_t sendlen=0;\r
+ if (byte!=0xFF) {\r
+ sendlen=0;\r
+ sendpacket[sendlen++]=COM_SBYTE;\r
+ sendpacket[sendlen++]=0x01;\r
+ sendpacket[sendlen++]=0x01;\r
+ sendpacket[sendlen++]=byte;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(1,readbuffer)) == 1) {\r
+ return byte;\r
+ }\r
+ }\r
+ } else {\r
+ sendlen=0;\r
+ sendpacket[sendlen++]=COM_RBYTE;\r
+ sendpacket[sendlen++]=0x00;\r
+ sendpacket[sendlen++]=0x01;\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(1,readbuffer)) == 1) {\r
+ return readbuffer[0];\r
+ }\r
+ }\r
+ \r
+ }\r
+\r
+ return 0; \r
+}\r
+uint8_t owARDUINOInterface::sendrecivBit(uint8_t bit) {\r
+ return 0;\r
+}\r
+\r
+int owARDUINOInterface::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {\r
+ int i=0;\r
+ data->resize(scount);\r
+ uint8_t readbuffer[128],sendpacket[128+3];\r
+ uint8_t sendlen=0;\r
+ sendpacket[sendlen++]=COM_BLOCK;\r
+ sendpacket[sendlen++]=scount;\r
+ sendpacket[sendlen++]=rcount;\r
+ for(uint8_t v:*data) {\r
+ sendpacket[sendlen++]=v;\r
+ (*data)[i]=v;i++;\r
+ }\r
+\r
+ if (WriteCOM(sendlen,sendpacket)) {\r
+ if ((sendlen=ReadCOM(rcount,readbuffer)) == rcount) {\r
+ for(i=0;i<rcount;i++) {\r
+ data->push_back(readbuffer[i]);\r
+ }\r
+ } else {\r
+ for (i = 0; i<rcount; i++) \r
+ data->push_back(0xFF);\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+ \r