X-Git-Url: http://git.smho.de/gw/?p=owTools.git;a=blobdiff_plain;f=src%2FowARDUINOInterface.cpp;fp=src%2FowARDUINOInterface.cpp;h=33d2814db817d6abf02f9d5810cb4989eff19ac3;hp=0000000000000000000000000000000000000000;hb=039b202e5c68834801d23e22eecc7cae2879ea83;hpb=c7cb52d06aae49ba200634f348af90414d78cfac diff --git a/src/owARDUINOInterface.cpp b/src/owARDUINOInterface.cpp new file mode 100644 index 0000000..33d2814 --- /dev/null +++ b/src/owARDUINOInterface.cpp @@ -0,0 +1,489 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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;kset(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 *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;ipush_back(readbuffer[i]); + } + //printf("\n"); + } + } + + + return 0; +} +