Works now with Windows Visual Studio C++ too
[owTools.git] / src / owARDUINOInterface.cpp
index 33d2814..4ec1911 100644 (file)
-// 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