From 1a6465a924428af072a8eb5e75ee547c394f4d8e Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 31 Mar 2017 09:01:41 +0200 Subject: [PATCH] Works now with Windows Visual Studio C++ too --- src/hexfile.cpp | 6 +- src/main.cpp | 149 +++- src/owARDUINOInterface.cpp | 1049 +++++++++++++++------------- src/owARDUINOInterface.h | 19 +- src/owDevice.cpp | 15 +- src/owInterface.cpp | 1157 ++++++++++++++++--------------- src/owInterface.h | 23 +- src/owTMEXWIN.cpp | 122 ++++ src/owTMEXWIN.h | 63 ++ src/owTools.h | 16 +- windows/owTools/crcutil.cpp | 119 ++++ windows/owTools/ibfs32.lib | Bin 0 -> 14230 bytes windows/owTools/owTools.sln | 28 + windows/owTools/owTools.vcxproj | 181 +++++ windows/owTools/owerr.cpp | 348 ++++++++++ windows/owTools/ownet.h | 426 ++++++++++++ windows/owTools/tmexlnk.cpp | 368 ++++++++++ windows/owTools/tmexnet.cpp | 251 +++++++ windows/owTools/tmexses.cpp | 216 ++++++ windows/owTools/tmextran.cpp | 199 ++++++ 20 files changed, 3669 insertions(+), 1086 deletions(-) create mode 100644 src/owTMEXWIN.cpp create mode 100644 src/owTMEXWIN.h create mode 100644 windows/owTools/crcutil.cpp create mode 100644 windows/owTools/ibfs32.lib create mode 100644 windows/owTools/owTools.sln create mode 100644 windows/owTools/owTools.vcxproj create mode 100644 windows/owTools/owerr.cpp create mode 100644 windows/owTools/ownet.h create mode 100644 windows/owTools/tmexlnk.cpp create mode 100644 windows/owTools/tmexnet.cpp create mode 100644 windows/owTools/tmexses.cpp create mode 100644 windows/owTools/tmextran.cpp diff --git a/src/hexfile.cpp b/src/hexfile.cpp index 32ce679..df45d46 100755 --- a/src/hexfile.cpp +++ b/src/hexfile.cpp @@ -53,13 +53,13 @@ hexFile::hexFile(std::string fname) { if (line[0]==':') { //ss << std::hex << line.substr(1,2); //ss >> bc; - uint8_t bc=std::stoul( line.substr(1,2), nullptr, 16); + uint8_t bc=(uint8_t)std::stoul( line.substr(1,2), nullptr, 16); uint32_t fw=std::stoul(line.substr(3,4),nullptr, 16); - uint8_t ty=std::stoul(line.substr(7,2),nullptr,16); + uint8_t ty=(uint8_t)std::stoul(line.substr(7,2),nullptr,16); uint32_t chsm = bc + (fw >> 8) + (fw & 0xFF) + ty; for (int i = 0; i < bc; i++) { int p = 9 + i * 2; - uint8_t b = std::stoul(line.substr(p, 2),nullptr, 16); + uint8_t b = (uint8_t)std::stoul(line.substr(p, 2),nullptr, 16); chsm = chsm + b; prog.push_back(b); } diff --git a/src/main.cpp b/src/main.cpp index c36dd88..7c28e12 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,26 +30,34 @@ // (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 "owTools.h" +#ifdef LINUX #include #include "mySensorDB.h" -#include -#include -#include #include -#include /* For O_RDWR */ #include #include #include +#endif + +#ifdef WIN +#include "Windows.h" +#include "time.h" +#endif + +#include +#include +#include +#include /* For O_RDWR */ #include -#include "owTools.h" #include "hexfile.h" #include #include #include #include - +#ifdef LINUX #define RB "\e(0\x6a\e(B" // 188 Right Bottom corner #define RT "\e(0\x6b\e(B" // 187 Right Top corner @@ -63,7 +71,21 @@ #define TC "\e(0\x77\e(B" // 203 Top Cross #define VL "\e(0\x78\e(B" // 186 Vertical Line #define SP " " // space string - +#endif +#ifdef WIN +#define RB " "// 188 Right Bottom corner +#define RT " "// 187 Right Top corner +#define LT " "// 201 Left Top cornet +#define LB " "// 200 Left Bottom corner +#define MC " " // 206 Midle Cross +#define HL " "// 205 Horizontal Line +#define LC " "// 204 Left Cross +#define RC " "// 185 Right Cross +#define BC " "// 202 Bottom Cross +#define TC " "// 203 Top Cross +#define VL " "// 186 Vertical Line +#define SP " " // space string +#endif void printhelp() { printf("owTools - Programm for reading und controlling 1-Wire Devices from www.tm3d.de\n\n"); @@ -137,17 +159,17 @@ int getArgi(std::string flag) { return atoi(getArg(flag).c_str()); } - +#ifdef LINUX int database=0; mySensorDB *sdb=NULL; - - +#endif +/* snum_t getArgsnum(std::string flag) { snum_t snum; snum.num=0; return snum; } - +*/ int findCPU(std::string cpu) { std::ifstream fileInput; std::string line; @@ -192,7 +214,7 @@ void continuous(std::vector *devices,int intervall,int headline,int s for (owDevice* dev :*devices) { if (dev->configstate!=OWDCS_NONE) { for (size_t i=0;i<4;i++) { - if (dev->config->getPropertyID(i)!=0) + if (dev->config->getPropertyID((uint8_t)i)!=0) printf("\033[1;34m%02X.%02X%02X\033[0m\t",dev->getNum().byte[7],dev->getNum().byte[1],dev->getNum().byte[0]); } } @@ -201,8 +223,8 @@ void continuous(std::vector *devices,int intervall,int headline,int s for (owDevice* dev :*devices) { if (dev->configstate!=OWDCS_NONE) { for (size_t i=0;i<4;i++) { - if (dev->config->getPropertyID(i)!=0) - printf("\033[0;36m%s\033[0m\t",dev->config->getQuantity(i).substr(0,7).c_str()); + if (dev->config->getPropertyID((uint8_t)i)!=0) + printf("\033[0;36m%s\033[0m\t",dev->config->getQuantity((uint8_t)i).substr(0,7).c_str()); } } } @@ -210,10 +232,10 @@ void continuous(std::vector *devices,int intervall,int headline,int s for (owDevice* dev :*devices) { if (dev->configstate!=OWDCS_NONE) { for (size_t i=0;i<4;i++) { - if (dev->config->getPropertyID(i)!=0) { - size_t l=utf8_length(dev->config->getUnit(i)); + if (dev->config->getPropertyID((uint8_t)i)!=0) { + size_t l=utf8_length(dev->config->getUnit((uint8_t)i)); std::string ls=" "; - printf("\033[3;34m[%s]%s\033[0m\t",dev->config->getUnit(i).c_str(),ls.substr(0,5-l).c_str()); + printf("\033[3;34m[%s]%s\033[0m\t",dev->config->getUnit((uint8_t)i).c_str(),ls.substr(0,5-l).c_str()); } } } @@ -221,19 +243,26 @@ void continuous(std::vector *devices,int intervall,int headline,int s } printf("\n"); - +#ifdef LINUX if (database) { //owi->log->setLogLevel(0); for (owDevice* dev : *devices) { sdb->createDeviceTable(dev); } } +#endif } } time_t t=time(NULL); int st=(int)t; +#ifdef LINUX struct tm tm = *localtime(&t); +#endif +#ifdef WIN + struct tm tm; + localtime_s(&tm,&t); +#endif printf("%d-%02d-%02d %02d:%02d:%02d\t", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); for (owDevice* dev :*devices) { for(int k=0;kmaxrepeat;k++){ @@ -244,7 +273,7 @@ void continuous(std::vector *devices,int intervall,int headline,int s if (owi->log->last()configstate!=OWDCS_NONE) { for (size_t i=0;i<4;i++) { - if (dev->config->getPropertyID(i)!=0) { + if (dev->config->getPropertyID((int8_t)i)!=0) { if (dev->values[i]<=-10) printf("%0.2f \t",dev->values[i]); else if (dev->values[i]<0) @@ -261,9 +290,11 @@ void continuous(std::vector *devices,int intervall,int headline,int s } } } +#ifdef LINUX if (database) { sdb->insertValues(dev); } +#endif } else { owi->log->setLogLevel(OWLOG_INFO); owi->log->set(OWLOG_ERROR,"Too many errors, mybee conection is dead."); @@ -273,7 +304,14 @@ void continuous(std::vector *devices,int intervall,int headline,int s } printf("\n"); - while (((int)time(NULL))<(st+intervall)) sleep(1); + while (((int)time(NULL)) < (st + intervall)) { +#ifdef LINUX + sleep(1); +#endif +#ifdef WIN + Sleep(1000); +#endif + } } } @@ -290,14 +328,14 @@ void device_menu(owDevice* d) { printf("Values info: "); int tm3d=d->readConfig(); for (size_t i=0;i<4;i++) { - printf("%s in %s",d->config->getQuantity(i).c_str(),d->config->getUnit(i).c_str()); + printf("%s in %s",d->config->getQuantity((uint8_t)i).c_str(),d->config->getUnit((uint8_t)i).c_str()); if (i<4) printf("; "); } if (tm3d) printf(" (tm3d.de)"); else printf(" (default)"); printf("\n"); d->convertAll(); for (size_t i=0;ivalues.size();i++) { - printf("\033[1;33m%0.4f %s\033[0m ",d->values[i],d->config->getUnit(i).c_str()); + printf("\033[1;33m%0.4f %s\033[0m ",d->values[i],d->config->getUnit((uint8_t)i).c_str()); } printf("\n"); for(int i=0;i<70;i++) printf(HL);printf("\n"); @@ -405,19 +443,13 @@ int main(int argc, char *argv[]) { std::transform(adapter.begin(), adapter.end(),adapter.begin(), ::toupper); std::string s; - +#ifdef LINUX if(adapter.find("COM")!=std::string::npos) { owi=new owCOMInterface(); int port=atoi(adapter.substr(adapter.find("COM")+3).c_str()); printf("Open /dev/ttyS%i\n",port); owi->InitAdapter(port); } else - if(adapter.find("ARDUINO")!=std::string::npos) { - owi=new owARDUINOInterface(); - int port=atoi(adapter.substr(adapter.find("ARDUINO")+7).c_str()); - printf("Open /dev/ttyS%i\n",port); - owi->InitAdapter(port); - } else if(adapter.find("USB")!=std::string::npos) { owi=new owUSBInterface(); int port=atoi(adapter.substr(adapter.find("USB")+3).c_str()); @@ -443,12 +475,49 @@ int main(int argc, char *argv[]) { } else { printf("\033[1;31mGPIO works with Raspberry PI only \033[0m\n"); } - } - if (owi==NULL) { + } else +#endif + if (adapter.find("ARDUINO") != std::string::npos) { + owi = new owARDUINOInterface(); + int port = atoi(adapter.substr(adapter.find("ARDUINO") + 7).c_str()); + printf("Open /dev/ttyS%i\n", port); + owi->InitAdapter(port); + } + +#ifdef WIN + else + if (adapter.find("USB") != std::string::npos) { + printf("USB \n"); + owi = new owTMEXWIN(); + int port = atoi(adapter.substr(adapter.find("USB") + 3).c_str()); + printf("Open the %i. USB Adapter\n", port); + int err; + char cs[20]; + sprintf_s(cs, 20, "{%i,6}", port); + if ((err = owi->InitAdapter(cs))==0) { + printf("ERROR Init USB Adapter\n"); + exit(0); + } + } + else + if (adapter.find("COM") != std::string::npos) { + printf("USB \n"); + owi = new owTMEXWIN(); + int port = atoi(adapter.substr(adapter.find("COM") + 3).c_str()); + printf("Open Adapter on COM%i\n", port); + int err; + char cs[20]; + sprintf_s(cs, 20, "{%i,5}", port); + if ((err = owi->InitAdapter(cs))==0) { + printf("ERROR Init Serial Adapter\n"); + exit(0); + } + } +#endif + if (owi == NULL) { printf("No 1-Wiremaster found\n"); return 0; } - setLogMode(); @@ -466,6 +535,7 @@ int main(int argc, char *argv[]) { if ((s=getArg("p")) !="") { pause=atoi(s.c_str()); } else pause=30; +#ifdef LINUX if ((s=getArg("d")) !="") { reload=1; printf("Use Database\n"); @@ -482,7 +552,8 @@ int main(int argc, char *argv[]) { exit(1); } database=1; - } + } +#endif continuous(&(owi->devices),pause,1,reload); @@ -529,7 +600,12 @@ int main(int argc, char *argv[]) { if ((getArg("g"))=="1") { printf("get ID from Server\n"); char s[255]; +#ifdef LINUX sprintf(s,"wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt",snum.byte[0]); +#endif +#ifdef WIN + sprintf_s(s, "wget -q http://www.tm3d.de/shop99/owid.php?fam=%02X -O id.txt", snum.byte[0]); +#endif int err; if ((err=system(s))==0) { printf("OK!\n"); @@ -546,7 +622,7 @@ int main(int argc, char *argv[]) { if (c=='x') br=1; } else { if ((c==',')|(c=='}')) { - isnum.byte[i]=strtol(s, NULL, 16); + isnum.byte[i]=(uint8_t)strtol(s, NULL, 16); //printf("%x\n",strtol(s, NULL, 16)); i++; br=0; @@ -619,7 +695,12 @@ int main(int argc, char *argv[]) { colm.push_back(""); } else { char hs[50]; +#ifdef LINUX sprintf(hs,"%0.3f",dev->values[i]); +#endif +#ifdef WIN + sprintf_s(hs, "%0.3f", dev->values[i]); +#endif colm.push_back(hs); } if (max -#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; -} - +// 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. + +#ifdef LINUX +#include +#include +#include +#include +#include +#endif +#include +#include +#include +#include +#include +#include "owARDUINOInterface.h" + + +#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() { +#ifdef LINUX + tcflush(fd, TCIOFLUSH); +#endif +#ifdef WIN + PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR); +#endif +} + +#ifdef LINUX +int +#endif +#ifdef WIN +HANDLE +#endif +owARDUINOInterface::OpenCOM(uint8_t comnr) +{ + char port_zstr[100]; +#ifdef LINUX + struct termios t; // see man termios - declared as above + int rc; + //int fd; + + 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; +#endif +#ifdef WIN + short fRetVal; + COMMTIMEOUTS CommTimeOuts; + DCB dcb; + int comnr1 = comnr; + sprintf_s(port_zstr,100, "COM%d", comnr1); + if (fd <= 0) { + if ((fd = CreateFileA(port_zstr, GENERIC_READ | GENERIC_WRITE, + 0, + NULL, // no security attrs + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, // overlapped I/O + NULL)) == (HANDLE)-1) { + fd = 0; + log->set(OWLOG_ERROR, "ERROR open Com %s return %i", port_zstr, fd); + return (FALSE); + } else { + // get any early notifications + SetCommMask(fd, EV_RXCHAR | EV_TXEMPTY | EV_ERR | EV_BREAK); + SetupComm(fd, 2048, 2048); + // purge any information in the buffer + PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + // set up for overlapped non-blocking I/O + CommTimeOuts.ReadIntervalTimeout = 0; + CommTimeOuts.ReadTotalTimeoutMultiplier = 20; + CommTimeOuts.ReadTotalTimeoutConstant = 40; + CommTimeOuts.WriteTotalTimeoutMultiplier = 20; + CommTimeOuts.WriteTotalTimeoutConstant = 40; + SetCommTimeouts(fd, &CommTimeOuts); + // setup the com port + GetCommState(fd, &dcb); + dcb.BaudRate = CBR_9600; // current baud rate + dcb.fBinary = TRUE; // binary mode, no EOF check + dcb.fParity = FALSE; // enable parity checking + dcb.fOutxCtsFlow = FALSE; // CTS output flow control + dcb.fOutxDsrFlow = FALSE; // DSR output flow control + dcb.fDtrControl = FALSE; // DTR flow control type + dcb.fDsrSensitivity = FALSE; // DSR sensitivity + dcb.fTXContinueOnXoff = FALSE; // XOFF continues Tx + dcb.fOutX = FALSE; // XON/XOFF out flow control + dcb.fInX = FALSE; // XON/XOFF in flow control + dcb.fErrorChar = FALSE; // enable error replacement + dcb.fNull = FALSE; // enable null stripping + dcb.fRtsControl = FALSE; // RTS flow control + dcb.fAbortOnError = FALSE; // abort reads/writes on error + dcb.XonLim = 0; // transmit XON threshold + dcb.XoffLim = 0; // transmit XOFF threshold + dcb.ByteSize = 8; // number of bits/byte, 4-8 + dcb.Parity = NOPARITY; // 0-4=no,odd,even,mark,space + dcb.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 + dcb.XonChar = 0; // Tx and Rx XON character + dcb.XoffChar = 0; // Tx and Rx XOFF character + dcb.ErrorChar = 0; // error replacement character + dcb.EofChar = 0; // end of input character + dcb.EvtChar = 0; // received event character + fRetVal = SetCommState(fd, &dcb); + + } + // check if successfull + if (!fRetVal) { + CloseHandle(fd); + fd = 0; + log->set(OWLOG_ERROR, "OWERROR_SYSTEM_RESOURCE_INIT_FAILED %s", port_zstr); + } + return (fd); + } + return 0; +#endif +} + + +//--------------------------------------------------------------------------- +// 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() +{ +#ifdef LINUX + // restore tty settings + tcsetattr(fd, TCSAFLUSH, &origterm); + FlushCOM(); + close(fd); +#endif +#ifdef WIN + // disable event notification and wait for thread + // to halt + SetCommMask(fd, 0); + + PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + CloseHandle(fd); + fd = 0; +#endif + 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) { +#ifdef LINUX + long count = outlen; + int i=0; + for (int k=0;kset(OWLOG_ERROR, "SERIAL_ERROR_IO_PENDING"); + WaitForSingleObject(osWrite.hEvent, to); + // verify all is written correctly + + fWriteStat = GetOverlappedResult(fd, &osWrite, &dwBytesWritten, FALSE); + } + // check results of write + if (!fWriteStat || (dwBytesWritten != (DWORD)outlen)) + return 0; + else + return 1; +#endif +} + + +//-------------------------------------------------------------------------- +// 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) +{ +#ifdef LINUX + 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; +#endif +#ifdef WIN + DWORD dwLength = 0; + BOOL fReadStat; + DWORD ler = 0, to; + OVERLAPPED osReader = { 0 }; + // calculate a timeout + to = 20 * inlen + 60; + // read + osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ResetEvent(osReader.hEvent); + fReadStat = ReadFile(fd, (LPSTR)&inbuf[0], inlen, &dwLength, &osReader); + //Sleep(100); + // check for an error + if (!fReadStat) { + ler = GetLastError(); + // log->set(OWLOG_ERROR, "Read Error on Serial"); + } + // if not done writing then wait + int e = 0; + while (!fReadStat && ler == ERROR_IO_PENDING) { + // wait until everything is read + // log->set(OWLOG_ERROR, "Read Error on Serial"); + // printf("try Read %i\n", e); e++; + WaitForSingleObject(osReader.hEvent, to); + // verify all is read correctly + fReadStat = GetOverlappedResult(fd, &osReader, &dwLength, FALSE); + //printf("%i %i\n", dwLength, inlen); + if (dwLength == inlen) break; + if (e == 3) break; + printf("repeat\n"); + + } + // check results + if (fReadStat) + return dwLength; + else + return 0; +#endif +} + + +/* + +//-------------------------------------------------------------------------- +// 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 +} + +*/ + + + + + + + + + +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; + } +#ifdef WIN + Sleep(2000); +#endif +#ifdef LINUX + sleep(2); +#endif + 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 { + 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; + sendlen=0; + sendpacket[sendlen++]=0x02; + sendpacket[sendlen++]=0x00; + sendpacket[sendlen++]=0x01; + if (WriteCOM(sendlen,sendpacket)) { + if ((sendlen=ReadCOM(1,readbuffer)) == 1) { + if (readbuffer[0]) return 1; + } + } + + return 0; +} + + +uint8_t owARDUINOInterface::sendrecivByte(uint8_t byte) { + + uint8_t readbuffer[5],sendpacket[5]; + uint8_t sendlen=0; + 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) { + 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) { + 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]); + } + } else { + for (i = 0; ipush_back(0xFF); + } + } + return 0; +} + diff --git a/src/owARDUINOInterface.h b/src/owARDUINOInterface.h index 9dc72cb..14024c1 100644 --- a/src/owARDUINOInterface.h +++ b/src/owARDUINOInterface.h @@ -38,7 +38,12 @@ class owARDUINOInterface:public owInterface{ protected: +#ifdef LINUX int fd; +#endif +#ifdef WIN + HANDLE fd; +#endif int com_init; public: owARDUINOInterface():owInterface() { @@ -61,16 +66,22 @@ protected: uint8_t UMode; // current DS2480B command or data mode state uint8_t USpeed; // current DS2480B 1-Wire Net communication speed uint8_t UVersion; // current DS2480B version +#ifdef LINUX struct termios origterm; - - +#endif +#ifdef LINUX int OpenCOM(uint8_t comnr); +#endif +#ifdef WIN + HANDLE OpenCOM(uint8_t comnr); +#endif + void CloseCOM(); void FlushCOM(); int WriteCOM(int outlen, uint8_t *outbuf); int ReadCOM(int inlen, uint8_t *inbuf); - void BreakCOM(); - void SetBaudCOM(uint8_t new_baud); +// void BreakCOM(); + }; diff --git a/src/owDevice.cpp b/src/owDevice.cpp index 70fe96a..070ec40 100755 --- a/src/owDevice.cpp +++ b/src/owDevice.cpp @@ -32,8 +32,21 @@ #include "owInterface.h" +#ifdef LINUX #include - +#endif +#ifdef WIN +void usleep(int waitTime) { + __int64 time1 = 0, time2 = 0, freq = 0; + + QueryPerformanceCounter((LARGE_INTEGER *)&time1); + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + + do { + QueryPerformanceCounter((LARGE_INTEGER *)&time2); + } while ((time2 - time1) < waitTime); +} +#endif owDevice::owDevice(owInterface *owi_,snum_t num) { snum=num; owi=owi_; diff --git a/src/owInterface.cpp b/src/owInterface.cpp index 66ea440..c08ea2d 100755 --- a/src/owInterface.cpp +++ b/src/owInterface.cpp @@ -1,553 +1,604 @@ -// 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 "owInterface.h" -#include -#include -#include "hexfile.h" - -static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; -static unsigned char owi_dscrc_table[] = { - 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, - 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, - 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, - 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, - 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, - 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, - 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, - 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, - 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, - 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, - 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, - 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, - 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, - 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, - 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, - 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; - - -uint8_t owInterface::docrc8(uint8_t value) { - // See Application Note 27 - - // TEST BUILD - crc8 = owi_dscrc_table[crc8 ^ value]; - return crc8; -} - -uint16_t owInterface::docrc16(uint16_t cdata) { - cdata = (cdata ^ (crc16 & 0xff)) & 0xff; - crc16 >>= 8; - - if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) - crc16 ^= 0xc001; - - cdata <<= 6; - crc16 ^= cdata; - cdata <<= 1; - crc16 ^= cdata; - - return crc16; - - -} - -uint8_t owInterface::calcCRC8(std::vector data) { - crc8 = 0; - for(uint8_t v: data) - docrc8(v); - return crc8; //0 bei erfolg oder crc wenn crc nicht babei -} - -uint16_t owInterface::calcCRC16(std::vector data) { - crc16=0; - for(uint8_t v:data) { - docrc16(v); - } - return crc16; -} - -int owInterface::testCRC16(std::vector data) { - return calcCRC16(data)==0xB001; -} - -void owInterface::resetFlasher() { // go back from Bootloader - std::vector data; - data.push_back(0x89); - Wait_Free(); - snum_t snum; - snum.num=0xfa55aa55aa55aaa3; - MatchRom(snum); - if (log->last()==OWLOG_ERROR) {Free(); return;} - Communicate(&data, 1, 0); - - Free(); - if (log->last()==OWLOG_ERROR) return; - usleep(50); -} - -void owInterface::resetID() { - std::vector data; - data.push_back(0x8B); - Wait_Free(); - snum_t snum; - snum.num=0xfa55aa55aa55aaa3; - MatchRom(snum); - if (log->last()==OWLOG_ERROR) {Free(); return;} - Communicate(&data, 1, 0); - Free(); -} - -int owInterface::programmPage(int pagenr, std::vector page, int pagesize) { - snum_t snum; - snum.num=0xfa55aa55aa55aaa3; -// printf("programm page %i",pagenr); - - - int diff = pagesize - page.size(); - if (diff>0) { - for (int i = 0; i < (diff); i++) page.push_back(0xFF); - } - std::vector cl; - std::vector clb; //backup - cl.push_back(0x0F); //code for Flashing - cl.push_back((pagenr*pagesize) & 0xFF); //adress in byte - cl.push_back((pagenr*pagesize) >> 8); - cl.insert(cl.end(),page.begin(),page.end()); //page - clb=cl; //make backup - Wait_Free(); - MatchRom(snum); - if (log->last()==OWLOG_ERROR) {Free();return -3;} - Communicate(&cl, 3+pagesize, 0); //send (resive page) - Free(); - if (log->last()==OWLOG_ERROR) return -3; - int err=0; - for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} - Communicate(&cl, 1, 2+pagesize); // read back scratchpad - Free(); - if (log->last()==OWLOG_ERROR) return -3; - err=0; - for (int i = 0; i < pagesize+2; i++) { - if (clb[i + 1] != cl[i + 1]) { //test - usleep(50000); - err=1; - break; - } - } - if (err==0) break; - } - if (err==1) { - usleep(50000); - return -1; //error in scratchpad - } - cl.clear(); - cl.push_back(0x55);//Programm - Wait_Free(); - MatchRom(snum); - if (log->last()==OWLOG_ERROR) {Free();return -3;} - Communicate(&cl, 1, 0); - Free(); - if (log->last()==OWLOG_ERROR) return -3; - usleep(50000); - cl.clear(); - cl.push_back(0xB8);//recal programm memory to scratchpad - cl.push_back((pagenr*pagesize) & 0xFF); - cl.push_back((pagenr*pagesize) >> 8); - Wait_Free(); - MatchRom(snum); - if (log->last()==OWLOG_ERROR) {Free();return -3;} - Communicate(&cl, 3, 0); //Copy programm memory to scratch - Free(); - if (log->last()==OWLOG_ERROR) return -3; - usleep(50000); - - for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} - Communicate(&cl, 1, 2 + pagesize); //Reread scratch - Free(); - if (log->last()==OWLOG_ERROR) return -3; - err=0; - for (int i = 0; i < pagesize + 2; i++) { - if (cl[i + 1] != clb[i + 1]) { - usleep(50000); - err=1; - break; - } - } - if (err==0) break; - } - if (err==1) { - usleep(50000); - return -2; - } - - - return 0; -} - - -int owInterface::flashHEXFile(std::string filename,snum_t dev,int resetid,int progress) { - log->set(OWLOG_INFO,"Open Hex-File: %s",filename.c_str()); - hexFile *hf=new hexFile(filename); - if (hf->lastError==1) {log->set(OWLOG_ERROR,"CRC Error in HEX-File %s",filename.c_str());return -1;} - if (hf->lastError==2) {log->set(OWLOG_ERROR,"Error interpreting HEX-File %s",filename.c_str());return -2;} - if (hf->lastError==3) {log->set(OWLOG_ERROR,"File could not be opened: %s",filename.c_str());return -3;} - unsigned int blcount=hf->getBlockCount(64); - if (blcount>118) { - log->set(OWLOG_ERROR,"Code to big, max 7552 Byte allowed (118 Pages). Code has %i pages!",blcount); - return -5; - } - log->set(OWLOG_INFO,"Try to start Bootloader on device %llX",dev.num); - int r=maxrepeat+1; - int found; - do { - log->clear(); - std::vector data; - MatchRom(dev); - data.push_back(0x88); - Communicate(&data, 1, 0); - MatchRom(dev); - Communicate(&data, 1, 0); - MatchRom(dev); - Communicate(&data, 1, 0); - sleep(3); - log->set(OWLOG_INFO,"Search for Bootloader..."); - log->setLogLevel(OWLOG_WARNING); - Find(); - log->setLogLevel(OWLOG_INFO); - found=0; - for (owDevice* dev :devices) { - if (dev->getNum().num==0xfa55aa55aa55aaa3) { - found=1; - break; - } - } - if (found==0) log->set(OWLOG_WARNING,"Bootloader not found"); - r--; - } while ((found==0)&&(r>0)); - if (r==0) { - log->set(OWLOG_ERROR,"Can not start Bootloader on this device %llX",dev.num); - return -4; - } - log->set(OWLOG_INFO,"Start Programm %i Pages",blcount); - int rp=0; - int er=0; - unsigned int i =0; - for ( i= 0; i < blcount; i++) { - std::vector blk = hf->getBlock(i*64, 64); - int errc = maxrepeat*5; - while (errc != 0) { - log->clear(); - if (programmPage(i, blk, 64) >= 0) { - if (progress) {printf("#");fflush(stdout);} - break; - } - - errc -= 1; - rp++; - if (progress) {printf("\033[1;31m#\033[0m");fflush(stdout);} //printf("\033[1;33m%s\033[0m\n",s); - - } - if (errc == 0) { er++; break; } - } - if (progress) printf("\n"); - if (er != 0) { - log->set(OWLOG_ERROR,"ERROR Writing Program Memory!!!"); - if (i==0) { - log->set(OWLOG_ERROR,"If Fuse SELFPRGEN enabled?"); - } else - log->set(OWLOG_ERROR,"Maybe 1-Wire Connection is verry bad!"); - } else { - if (resetid) { - log->set(OWLOG_INFO,"Set 1-Wire ID to ID in hexfile...",blcount); - resetID(); - sleep(3); - resetID(); - sleep(3); - } - } - - log->set(OWLOG_INFO,"Back from bootloader to normal device...",blcount); - - - resetFlasher(); - sleep(1); - resetFlasher(); - sleep(3); - - Find(); - - return 1; - -} - - -int owInterface::owSearch() { - int id_bit_number; - int last_zero, rom_byte_number, search_result; - int id_bit, cmp_id_bit; - unsigned char rom_byte_mask, search_direction; - - // initialize for search - id_bit_number = 1; - last_zero = 0; - rom_byte_number = 0; - rom_byte_mask = 1; - search_result = 0; - crc8 = 0; - - // if the last call was not the last one - if (!LastDeviceFlag) { - // 1-Wire reset - Wait_Free(); - if (!Reset()) { - // reset the search - LastDiscrepancy = 0; - LastDeviceFlag = FALSE; - LastFamilyDiscrepancy = 0; - Free(); - return FALSE; - } - if (log->last()==OWLOG_ERROR) return -3; - // issue the search command - sendrecivByte(0xF0); - if (log->last()==OWLOG_ERROR) return -3; - - // loop to do the search - do { - // read a bit and its complement - id_bit = sendrecivBit(1); - cmp_id_bit = sendrecivBit(1); - // check for no devices on 1-wire - if ((id_bit == 1) && (cmp_id_bit == 1)) - break; - else { - // all devices coupled have 0 or 1 - if (id_bit != cmp_id_bit) - search_direction = id_bit; // bit write value for search - else { - // if this discrepancy if before the Last Discrepancy - // on a previous next then pick the same as last time - if (id_bit_number < LastDiscrepancy) - search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); - else - // if equal to last pick 1, if not then pick 0 - search_direction = (id_bit_number == LastDiscrepancy); - - // if 0 was picked then record its position in LastZero - if (search_direction == 0) { - last_zero = id_bit_number; - // check for Last discrepancy in family - if (last_zero < 9) - LastFamilyDiscrepancy = last_zero; - } - } - // set or clear the bit in the ROM byte rom_byte_number - // with mask rom_byte_mask - if (search_direction == 1) - ROM_NO[rom_byte_number] |= rom_byte_mask; - else - ROM_NO[rom_byte_number] &= ~rom_byte_mask; - // serial number search direction write bit - sendrecivBit(search_direction); - //usleep(50); - - // increment the byte counter id_bit_number - // and shift the mask rom_byte_mask - id_bit_number++; - rom_byte_mask <<= 1; - - // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask - if (rom_byte_mask == 0) { - docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC - rom_byte_number++; - rom_byte_mask = 1; - } - } - } - while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 - // if the search was successful then - if (!((id_bit_number < 65) || (crc8 != 0))) { - // search successful so set LastDiscrepancy,LastDeviceFlag,search_result - LastDiscrepancy = last_zero; - // check for last device - if (LastDiscrepancy == 0) - LastDeviceFlag = TRUE; - search_result = TRUE; - } else { - log->set(OWLOG_WARNING,"CRC Error on Search Rom"); - } - } - - // if no device found then reset counters so next 'search' will be like a first - if (!search_result || !ROM_NO[0]) { - LastDiscrepancy = 0; - LastDeviceFlag = FALSE; - LastFamilyDiscrepancy = 0; - search_result = FALSE; - } - Free(); - return search_result; - - -} -void owInterface::Clean() { - for (owDevice* dev :devices) { - delete dev; - } - devices.clear(); - device_nums.clear(); - devices_changed=1; -} - -int owInterface::Find() { - int rslt,i,cnt=0; - std::vector found; - for (int k=0;kclear(); - found.clear(); - rslt = owFirst(); - if (log->last()>=OWLOG_WARNING) continue; - while (rslt){ - snum_t snum; - // print device found - for (i = 7; i >= 0; i--) - snum.byte[i]=ROM_NO[i]; - //printf("%02X", ROM_NO[i]); - //printf(" %d\n",++cnt); - found.push_back(snum); - cnt++; - log->clear(); - rslt = owNext(); - if (log->last()>=OWLOG_WARNING) {rslt=-1;break;} - } - if (rslt==0) break; - - } - if (log->last()>=OWLOG_WARNING) { - log->set(OWLOG_ERROR,"To much Errors while search rom"); - //Alles so lassen wie es ist? - return 0; - } - for(snum_t snum:found) { - int snum_found=0; - //Device schon forhanden? - for(snum_t d : device_nums) { - if (snum.num==d.num) {snum_found=1;break;} - } - //nein, dann anlegen. - if (!snum_found) { - log->set(OWLOG_INFO,"new dev %llx\n",snum.num); - devices_changed=1; - device_nums.push_back(snum); - owDevice *d=NULL; - - switch (snum.byte[0]) { - case 0x28:d=new owDeviceDS18B20(this,snum);break; - case 0x26:d=new owDeviceDS2438(this,snum);break; - case 0x20:d=new owDeviceDS2450(this,snum);break; - case 0x1D:d=new owDeviceDS2423(this,snum);break; - default:d=new owDevice(this,snum); - } - devices.push_back(d); - if (d!=NULL) {d->readConfig();} - } - } - //Pruefe nach nicht mehr vorhandenen devices - int dpos=0; - for(snum_t d:device_nums) { - int snum_found=0; - for(snum_t fd:found) { - if (fd.num==d.num) {snum_found=1;break;} - } - //Device nicht gefunden, vieleicht nur Fehler? - if (!snum_found) { - devices[dpos]->lastfound++; - log->set(OWLOG_INFO,"%llx not found %i times \n",device_nums[dpos].num,devices[dpos]->lastfound); - - if (devices[dpos]->lastfound>2) { - - log->set(OWLOG_INFO,"del device %llx (pos %i)\n",device_nums[dpos].num,dpos); - - devices_changed=1; - delete devices[dpos]; - device_nums.erase(device_nums.begin()+dpos); - devices.erase(devices.begin()+dpos); - //printf("new length %i\n",devices.size()); - dpos--; - } - - } else { - devices[dpos]->lastfound=0; - } - dpos++; - - } - return cnt; -} - -int owInterface::MatchRom(snum_t snum) { - Reset(); - sendrecivByte(0x55); - usleep(20); - for(int i=0;i<8;i++) { - sendrecivByte(snum.byte[i]); - usleep(20); - } - if (log->last()>OWLOG_WARNING) return 0; - return 1; -} -int owInterface::Communicate(std::vector *data, int scount, int rcount) { - int i=0; - data->resize(scount); - for(uint8_t v:*data) { - (*data)[i]=sendrecivByte(v);i++; - usleep(20); - } - for(i=0;ipush_back(sendrecivByte(0xFF)); - usleep(20); - - } - return 0; -} - +// 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 "owInterface.h" +#ifdef LINUX +#include +#endif +#include +#include "hexfile.h" + + +#ifdef WIN +void usleep(__int64 usec) +{ + HANDLE timer; + LARGE_INTEGER ft; + + ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); +} +#endif + + +static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +static unsigned char owi_dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + + +uint8_t owInterface::docrc8(uint8_t value) { + // See Application Note 27 + + // TEST BUILD + crc8 = owi_dscrc_table[crc8 ^ value]; + return crc8; +} + +uint16_t owInterface::docrc16(uint16_t cdata) { + cdata = (cdata ^ (crc16 & 0xff)) & 0xff; + crc16 >>= 8; + + if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) + crc16 ^= 0xc001; + + cdata <<= 6; + crc16 ^= cdata; + cdata <<= 1; + crc16 ^= cdata; + + return crc16; + + +} + +uint8_t owInterface::calcCRC8(std::vector data) { + crc8 = 0; + for(uint8_t v: data) + docrc8(v); + return crc8; //0 bei erfolg oder crc wenn crc nicht babei +} + +uint16_t owInterface::calcCRC16(std::vector data) { + crc16=0; + for(uint8_t v:data) { + docrc16(v); + } + return crc16; +} + +int owInterface::testCRC16(std::vector data) { + return calcCRC16(data)==0xB001; +} + +void owInterface::resetFlasher() { // go back from Bootloader + std::vector data; + data.push_back(0x89); + Wait_Free(); + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free(); return;} + Communicate(&data, 1, 0); + + Free(); + if (log->last()==OWLOG_ERROR) return; + usleep(50); +} + +void owInterface::resetID() { + std::vector data; + data.push_back(0x8B); + Wait_Free(); + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free(); return;} + Communicate(&data, 1, 0); + Free(); +} + +int owInterface::programmPage(int pagenr, std::vector page, int pagesize) { + snum_t snum; + snum.num=0xfa55aa55aa55aaa3; +// printf("programm page %i",pagenr); + + + int diff = pagesize - page.size(); + if (diff>0) { + for (int i = 0; i < (diff); i++) page.push_back(0xFF); + } + std::vector cl; + std::vector clb; //backup + cl.push_back(0x0F); //code for Flashing + cl.push_back((pagenr*pagesize) & 0xFF); //adress in byte + cl.push_back((pagenr*pagesize) >> 8); + cl.insert(cl.end(),page.begin(),page.end()); //page + clb=cl; //make backup + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 3+pagesize, 0); //send (resive page) + Free(); + if (log->last()==OWLOG_ERROR) return -3; + int err=0; + for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 2+pagesize); // read back scratchpad + Free(); + if (log->last()==OWLOG_ERROR) return -3; + err=0; + for (int i = 0; i < pagesize+2; i++) { + if (clb[i + 1] != cl[i + 1]) { //test + usleep(50000); + err=1; + break; + } + } + if (err==0) break; + } + if (err==1) { + usleep(50000); + return -1; //error in scratchpad + } + cl.clear(); + cl.push_back(0x55);//Programm + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 0); + Free(); + if (log->last()==OWLOG_ERROR) return -3; + usleep(50000); + cl.clear(); + cl.push_back(0xB8);//recal programm memory to scratchpad + cl.push_back((pagenr*pagesize) & 0xFF); + cl.push_back((pagenr*pagesize) >> 8); + Wait_Free(); + MatchRom(snum); + if (log->last()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 3, 0); //Copy programm memory to scratch + Free(); + if (log->last()==OWLOG_ERROR) return -3; + usleep(50000); + + for(int k=0;klast()==OWLOG_ERROR) {Free();return -3;} + Communicate(&cl, 1, 2 + pagesize); //Reread scratch + Free(); + if (log->last()==OWLOG_ERROR) return -3; + err=0; + for (int i = 0; i < pagesize + 2; i++) { + if (cl[i + 1] != clb[i + 1]) { + usleep(50000); + err=1; + break; + } + } + if (err==0) break; + } + if (err==1) { + usleep(50000); + return -2; + } + + + return 0; +} + + +int owInterface::flashHEXFile(std::string filename,snum_t dev,int resetid,int progress) { + log->set(OWLOG_INFO,"Open Hex-File: %s",filename.c_str()); + hexFile *hf=new hexFile(filename); + if (hf->lastError==1) {log->set(OWLOG_ERROR,"CRC Error in HEX-File %s",filename.c_str());return -1;} + if (hf->lastError==2) {log->set(OWLOG_ERROR,"Error interpreting HEX-File %s",filename.c_str());return -2;} + if (hf->lastError==3) {log->set(OWLOG_ERROR,"File could not be opened: %s",filename.c_str());return -3;} + unsigned int blcount=hf->getBlockCount(64); + if (blcount>118) { + log->set(OWLOG_ERROR,"Code to big, max 7552 Byte allowed (118 Pages). Code has %i pages!",blcount); + return -5; + } + log->set(OWLOG_INFO,"Try to start Bootloader on device %llX",dev.num); + int r=maxrepeat+1; + int found; + do { + log->clear(); + std::vector data; + MatchRom(dev); + data.push_back(0x88); + Communicate(&data, 1, 0); + MatchRom(dev); + Communicate(&data, 1, 0); + MatchRom(dev); + Communicate(&data, 1, 0); +#ifdef LINUX + sleep(3); +#endif +#ifdef WIN + Sleep(3000); +#endif + log->set(OWLOG_INFO,"Search for Bootloader..."); + log->setLogLevel(OWLOG_WARNING); + Find(); + log->setLogLevel(OWLOG_INFO); + found=0; + for (owDevice* dev :devices) { + if (dev->getNum().num==0xfa55aa55aa55aaa3) { + found=1; + break; + } + } + if (found==0) log->set(OWLOG_WARNING,"Bootloader not found"); + r--; + } while ((found==0)&&(r>0)); + if (r==0) { + log->set(OWLOG_ERROR,"Can not start Bootloader on this device %llX",dev.num); + return -4; + } + log->set(OWLOG_INFO,"Start Programm %i Pages",blcount); + int rp=0; + int er=0; + unsigned int i =0; + for ( i= 0; i < blcount; i++) { + std::vector blk = hf->getBlock(i*64, 64); + int errc = maxrepeat*5; + while (errc != 0) { + log->clear(); + if (programmPage(i, blk, 64) >= 0) { + if (progress) {printf("#");fflush(stdout);} + break; + } + + errc -= 1; + rp++; + if (progress) {printf("\033[1;31m#\033[0m");fflush(stdout);} //printf("\033[1;33m%s\033[0m\n",s); + + } + if (errc == 0) { er++; break; } + } + if (progress) printf("\n"); + if (er != 0) { + log->set(OWLOG_ERROR,"ERROR Writing Program Memory!!!"); + if (i==0) { + log->set(OWLOG_ERROR,"If Fuse SELFPRGEN enabled?"); + } else + log->set(OWLOG_ERROR,"Maybe 1-Wire Connection is verry bad!"); + } else { + if (resetid) { + log->set(OWLOG_INFO,"Set 1-Wire ID to ID in hexfile...",blcount); + resetID(); +#ifdef LINUX + sleep(3); +#endif +#ifdef WIN + Sleep(3000); +#endif + resetID(); +#ifdef LINUX + sleep(3); +#endif +#ifdef WIN + Sleep(3000); +#endif + } + } + + log->set(OWLOG_INFO,"Back from bootloader to normal device...",blcount); + + + resetFlasher(); +#ifdef LINUX + sleep(1); +#endif +#ifdef WIN + Sleep(1000); +#endif + resetFlasher(); +#ifdef LINUX + sleep(3); +#endif +#ifdef WIN + Sleep(3000); +#endif + + Find(); + + return 1; + +} + + +int owInterface::owSearch() { + int id_bit_number; + int last_zero, rom_byte_number, search_result; + int id_bit, cmp_id_bit; + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + crc8 = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) { + // 1-Wire reset + Wait_Free(); + if (!Reset()) { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + Free(); + return FALSE; + } + if (log->last()==OWLOG_ERROR) return -3; + // issue the search command + sendrecivByte(0xF0); + if (log->last()==OWLOG_ERROR) return -3; + + // loop to do the search + do { + // read a bit and its complement + id_bit = sendrecivBit(1); + cmp_id_bit = sendrecivBit(1); + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) { + last_zero = id_bit_number; + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + // serial number search direction write bit + sendrecivBit(search_direction); + //usleep(50); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) { + docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + // if the search was successful then + if (!((id_bit_number < 65) || (crc8 != 0))) { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + search_result = TRUE; + } else { + log->set(OWLOG_WARNING,"CRC Error on Search Rom"); + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + Free(); + return search_result; + + +} +void owInterface::Clean() { + for (owDevice* dev :devices) { + delete dev; + } + devices.clear(); + device_nums.clear(); + devices_changed=1; +} + +int owInterface::Find() { + int rslt,i,cnt=0; + std::vector found; + for (int k=0;kclear(); + found.clear(); + rslt = owFirst(); + if (log->last()>=OWLOG_WARNING) continue; + while (rslt){ + snum_t snum; + // print device found + for (i = 7; i >= 0; i--) + snum.byte[i]=ROM_NO[i]; + //printf("%02X", ROM_NO[i]); + //printf(" %d\n",++cnt); + found.push_back(snum); + cnt++; + log->clear(); + rslt = owNext(); + if (log->last()>=OWLOG_WARNING) {rslt=-1;break;} + } + if (rslt==0) break; + + } + if (log->last()>=OWLOG_WARNING) { + log->set(OWLOG_ERROR,"To much Errors while search rom"); + //Alles so lassen wie es ist? + return 0; + } + for(snum_t snum:found) { + int snum_found=0; + //Device schon forhanden? + for(snum_t d : device_nums) { + if (snum.num==d.num) {snum_found=1;break;} + } + //nein, dann anlegen. + if (!snum_found) { + log->set(OWLOG_INFO,"new dev %llx\n",snum.num); + devices_changed=1; + device_nums.push_back(snum); + owDevice *d=NULL; + + switch (snum.byte[0]) { + case 0x28:d=new owDeviceDS18B20(this,snum);break; + case 0x26:d=new owDeviceDS2438(this,snum);break; + case 0x20:d=new owDeviceDS2450(this,snum);break; + case 0x1D:d=new owDeviceDS2423(this,snum);break; + default:d=new owDevice(this,snum); + } + devices.push_back(d); + if (d!=NULL) {d->readConfig();} + } + } + //Pruefe nach nicht mehr vorhandenen devices + int dpos=0; + for(snum_t d:device_nums) { + int snum_found=0; + for(snum_t fd:found) { + if (fd.num==d.num) {snum_found=1;break;} + } + //Device nicht gefunden, vieleicht nur Fehler? + if (!snum_found) { + devices[dpos]->lastfound++; + log->set(OWLOG_INFO,"%llx not found %i times \n",device_nums[dpos].num,devices[dpos]->lastfound); + + if (devices[dpos]->lastfound>2) { + + log->set(OWLOG_INFO,"del device %llx (pos %i)\n",device_nums[dpos].num,dpos); + + devices_changed=1; + delete devices[dpos]; + device_nums.erase(device_nums.begin()+dpos); + devices.erase(devices.begin()+dpos); + //printf("new length %i\n",devices.size()); + dpos--; + } + + } else { + devices[dpos]->lastfound=0; + } + dpos++; + + } + return cnt; +} + +int owInterface::MatchRom(snum_t snum) { + Reset(); +/* sendrecivByte(0x55); + usleep(20); + for(int i=0;i<8;i++) { + sendrecivByte(snum.byte[i]); + usleep(20); + } + if (log->last()>OWLOG_WARNING) return 0;*/ + std::vector cl; + cl.push_back(0x55); //code for Flashing + for (int i = 0; i<8; i++) { + cl.push_back(snum.byte[i]); + } + Communicate(&cl, 9, 0); + + return 1; +} +int owInterface::Communicate(std::vector *data, int scount, int rcount) { + int i=0; + data->resize(scount); + for(uint8_t v:*data) { + (*data)[i]=sendrecivByte(v);i++; + usleep(20); + } + for(i=0;ipush_back(sendrecivByte(0xFF)); + usleep(20); + + } + return 0; +} + diff --git a/src/owInterface.h b/src/owInterface.h index 952f3dc..0370d03 100755 --- a/src/owInterface.h +++ b/src/owInterface.h @@ -34,12 +34,28 @@ #ifndef __OWINTERFACES_H_ #define __OWINTERFACES_H_ +#if defined(WIN) || defined(LINUX) +#else +#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(WIN32) +#define WIN +#else +#define LINUX +#endif +#endif + + #include #include #include +#ifdef LINUX #include +#endif #include +#ifdef WIN +#include + +#endif class owDevice; class owDeviceConfig; @@ -48,7 +64,7 @@ class owDeviceConfig; #if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(WIN32) #define USE_WINDOWS_TIME 1 #include - #include "win32/usb.h" // libusb header + //#include "win32/usb.h" // libusb header #else #define USE_WINDOWS_TIME 0 #include @@ -84,7 +100,12 @@ public: va_list arg; int done; va_start (arg, format); +#ifdef LINUX done = vsprintf (s, format, arg); +#endif +#ifdef WIN + done = vsprintf_s(s,300, format, arg); +#endif va_end (arg); logtext=s; level=llevel; diff --git a/src/owTMEXWIN.cpp b/src/owTMEXWIN.cpp new file mode 100644 index 0000000..6905165 --- /dev/null +++ b/src/owTMEXWIN.cpp @@ -0,0 +1,122 @@ +// 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. + +#pragma once + + +#include + +#include + +#include +#include "owTMEXWIN.h" + + +int owTMEXWIN::InitAdapter(std::string s) { + // resu = owi.InitAdapter("{1,6}"); + + // int resu = owi.InitAdapter("{4,5}"); + char hs[100]; + sprintf_s(hs, 100, "%s", s.c_str()); + portnum = owAcquireEx(hs); + if (portnum > -1) { + owSpeed(portnum, 2); + return 1; + } + return 0; +} + + +int owTMEXWIN::owFirst() { + uchar SNum[8]; + int res=owFirst_(portnum, TRUE, FALSE); + if (res) { + owSerialNum(portnum, &SNum[0], TRUE); + for (int i = 0; i<8; i++) ROM_NO[i] = SNum[i]; + } + return res; + +} +int owTMEXWIN::owNext() { + uchar SNum[8]; + int res = owNext_(portnum, TRUE, FALSE); + if (res) { + owSerialNum(portnum, &SNum[0], TRUE); + for (int i = 0; i<8; i++) ROM_NO[i] = SNum[i]; + } + return res; + +} + + +void owTMEXWIN::ReleaseAdapter() { + owRelease(portnum); +} + + +int owTMEXWIN::Reset() { + return owTouchReset(portnum); +} + +int owTMEXWIN::MatchRom(snum_t snum) { + owSerialNum(portnum, snum.byte, FALSE); + return owAccess(portnum); +} +uint8_t owTMEXWIN::sendrecivByte(uint8_t byte) { + return owTouchByte(portnum, byte); + +} +uint8_t owTMEXWIN::sendrecivBit(uint8_t bit) { + return owTouchBit(portnum, bit); + +} + +int owTMEXWIN::Communicate(std::vector *data, int scount, int rcount) { + int i = 0; + uint8_t buf[400]; + data->resize(scount); + for (uint8_t v : *data) { + buf[i++] = v; + } + for (int j = 0; j < rcount; j++) { + buf[i++] = 0xFF; + } + int ret = owBlock(portnum, FALSE, buf, scount + rcount); + if (ret) { + for (int j = 0; j < rcount; j++) { + data->push_back(buf[scount + j]); + } + } + return ret; + +} + diff --git a/src/owTMEXWIN.h b/src/owTMEXWIN.h new file mode 100644 index 0000000..716766f --- /dev/null +++ b/src/owTMEXWIN.h @@ -0,0 +1,63 @@ +// 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. + + +#ifndef __OWTMEXWIN_H_ +#define __OWTMEXWIN_H_ + +#include "owInterface.h" + +class owTMEXWIN :public owInterface { +protected: + int portnum; + int com_init; +public: + owTMEXWIN():owInterface() { + portnum=-1; + com_init=0; + } + virtual int InitAdapter(std::string s); + virtual int InitAdapter(uint8_t) { return 0; }; + virtual int Reset(); + virtual uint8_t sendrecivBit(uint8_t bit); + virtual uint8_t sendrecivByte(uint8_t byte); + virtual void ReleaseAdapter(); + virtual int MatchRom(snum_t snum); + virtual int owFirst(); + virtual int owNext(); + virtual int Communicate(std::vector *data, int scount, int rcount); + + + +}; + +#endif diff --git a/src/owTools.h b/src/owTools.h index 68b5b3a..b4a942c 100755 --- a/src/owTools.h +++ b/src/owTools.h @@ -35,9 +35,23 @@ #ifndef __OWTOOLS_H_ #define __OWTOOLS_H_ +#if defined(_WINDOWS) || defined(__WINDOWS__) || defined(_WIN32) || defined(WIN32) +#define WIN +#else +#define LINUX +#endif + + + #include "owInterface.h" +#include "owARDUINOInterface.h" +#ifdef WIN +#include "owTMEXWIN.h" +#endif + +#ifdef LINUX #include "owUSBInterface.h" #include "owCOMInterface.h" #include "owPiGPioInterface.h" -#include "owARDUINOInterface.h" +#endif #endif diff --git a/windows/owTools/crcutil.cpp b/windows/owTools/crcutil.cpp new file mode 100644 index 0000000..cf1bef8 --- /dev/null +++ b/windows/owTools/crcutil.cpp @@ -0,0 +1,119 @@ +//--------------------------------------------------------------------------- +// 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. +//-------------------------------------------------------------------------- +// +// crcutil.c - Keeps track of the CRC for 16 and 8 bit operations +// version 2.00 + +// Include files +#include "ownet.h" + +// Local global variables +ushort utilcrc16[MAX_PORTNUM]; +uchar utilcrc8[MAX_PORTNUM]; +static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; +static uchar dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + +//-------------------------------------------------------------------------- +// Reset crc16 to the value passed in +// +// 'reset' - data to set crc16 to. +// +void setcrc16(int portnum, ushort reset) +{ + utilcrc16[portnum&0x0FF] = reset; + return; +} + +//-------------------------------------------------------------------------- +// Reset crc8 to the value passed in +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'reset' - data to set crc8 to +// +void setcrc8(int portnum, uchar reset) +{ + utilcrc8[portnum&0x0FF] = reset; + return; +} + +//-------------------------------------------------------------------------- +// Calculate a new CRC16 from the input data short. Return the current +// CRC16 and also update the global variable CRC16. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'data' - data to perform a CRC16 on +// +// Returns: the current CRC16 +// +ushort docrc16(int portnum, ushort cdata) +{ + cdata = (cdata ^ (utilcrc16[portnum&0x0FF] & 0xff)) & 0xff; + utilcrc16[portnum&0x0FF] >>= 8; + + if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) + utilcrc16[portnum&0x0FF] ^= 0xc001; + + cdata <<= 6; + utilcrc16[portnum&0x0FF] ^= cdata; + cdata <<= 1; + utilcrc16[portnum&0x0FF] ^= cdata; + + return utilcrc16[portnum&0x0FF]; +} + +//-------------------------------------------------------------------------- +// Update the Dallas Semiconductor One Wire CRC (utilcrc8) from the global +// variable utilcrc8 and the argument. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'x' - data byte to calculate the 8 bit crc from +// +// Returns: the updated utilcrc8. +// +uchar docrc8(int portnum, uchar x) +{ + utilcrc8[portnum&0x0FF] = dscrc_table[utilcrc8[portnum&0x0FF] ^ x]; + return utilcrc8[portnum&0x0FF]; +} diff --git a/windows/owTools/ibfs32.lib b/windows/owTools/ibfs32.lib new file mode 100644 index 0000000000000000000000000000000000000000..a856f6e6b74859e26749fddae8ec8217291ae5e6 GIT binary patch literal 14230 zcmds7O>7iL7JlY8IE1kL8ZdZljIsGKp7D%r2#ajvkg)L>%kB_v&R{n%V(hWTZ5FhV zHi~lO808p6k@l9oaEp{fR?2}(4vVt6E=QDHqMV~-zv}w0{z;F=*_F1XH&ylORefDm zuU@}bHQkphjm3Lc+ArknCttWYk}r)7<%ev(ETX!|Yu;@qqQ4Mzd`xug6Qa&BIpTH(CH3AA0lP+Bd31gG8(un2=6ukI@2lW1Eh>za5_6j#ONHx&gkry zoX+*53_6dgVKg|!>HK#ng9h;qjLz3MU3g3sQVuDjpE(U--a>kY6qFz1RKU1H3Xn2- z&S`jtC?vecFsL{v=u@Pi64ojtv?(z{J4PdD7ZTcxfJX7|jPhv1sQ)Ra6Mb0EzJ-PB z<=Go^-on)D^H=At&w4lJ7OqcTn;$OF!otkk)6>y<`YRXU)!v(L&%CuTHQ`Or!W(|D zaMN$BRqHF`MYOLjuP(SuuRO81=&!Afk4XWOgM1J)s<+nze>^{8NLXA*tq1iR5B$bd zqxt}n>}5l+xEilKS*tJJzkb7#GkHQ{K4|!r<*1aw_sUoARaWl$Q`LsQ7}Oh&thbD- zLyKB{&DZl`FhurRwPueYY@xW2n!9S_h%##M#(~d8jp=gOQf{_UzuTxR|EYf4oP92A z*LmeBzvj!Hjp=pRkdre}p0nQ3{|`DoPoP37HlD9jNrxx@`y?wvwCnANVy(@r9(WfGjLk)auz>uPk=QAf-a}To~6_d-%Ru=F3fwj~5_E&7kIZG$YUYYM*tF^&m_0H%O19kVSt6cTX zLEBtNnRdmPMwibd8}*gDQLS+KN|Kq0L~*;)D|>!pxw?W+!^9GwLUR+xR-#RPeevF8 z)ml`OCncDE8tTbK1XIY&`D<7uWBj3z;(Fzqm0C5<#=Cs4{7$2)M`3P@NQID98Y4G& zD5$tXDn^k)IfIXx=e9n;JX%}a<%c$K%D=sSm%+SQSy{pd-55RWU`%b)mhv}_@SFAL zhYLdm>CZnTqK`X>J~>A8Z70!3Cy0Il-RUBF2Aa$feGYoRo9HLdtsbJINWVrpbdu;Z z(4JnR_dwr+Zk{4~3c3RC@d>EoG|`8kA3?X^WnLaYf1u7YL?3`&facEP9nKMbiL@Un zbEBu=&3=dU3DO$U#}^PifPMzuL1gd@G?oW;fhYhy2h9wl571zd=u=R833Z_7pqUZW zf%->Lhj#z3&r{5?eEP7C>_Narf2M7;op#VpdWm+?E7VRe({9>BuhL%n1MQ>zbbt=h zAv#PQbcBx5F$$=Yj?)S1q8xS8N$RB@Iz(>y)}$D9DfA6$BaSJf{Wh{7NUWHcE*v52?fBF?!L%|mWP>N zlpB_}E*Z949C5v)K6ccX&gdPdIKc2AWBps_NvWC-@?1aX-oJnRf8ieb5Drd#NGYmQ%}9I7yW44p5{lAfF57~WN^%j39Gjvo|pd9-gM zzfGYpBMWdc#D|J;ge!xr<+-5j_$Z8H`yz^y$*qun0rwnaDZwF#e)?lR@$Q#A=9}I8 zsf9j{a8ylwbxpe=orkE$m2g0jcpzaOG{{~y1 zTOL{G#Q2Jx6zM0#^$AgYmZ;rQQPXvew^8y9RcLK7l)bXJk%@{1(D;-j2hA}Ko$Np2 zz^TJ2)HpUxwvl15EX&~6EJp^ygd*c`B30QzBrH`Gru9?I*oZYgLga@^+8)Y2+_=@@ zE88gfj)m0h)Q~eAzZ*3gUcBnYi3*LtPl~v1z2>`Np=D8(m}6Hp-?pv}-?p)`GB!q2 zm5GsBTx_PoF4^1-vLrteQCSs{iFV?pq*GyjSUk8?tMNGIw{9aw^Ccd<b4O4;pAs)SOq~Q%YMRCCCLr{3pImFERgJ-mrxVP z)G&VY8K=FIgVm)&6qFR$WVUvzDwUw@T&auM0fZ6P`2aiZ{b?@3NLIEJ%Ta*9j_3{o;B&0&1R zzUpDUBivMFhBb@QW?qgMQ<`lb6iV`bj_rdj;Xe2RFU4P$+T!$N$ru958hV1bnLkWV z{w50|WqQK;-SqX(vZ}`coOsuyRV3rAjgCgF$G-rOHfxW?EXc%|HJmK)hbiJWvLI4p zci}XGKTPhQvLMn;o!u-migTXCOS-1@uy|2SDC{wXTXVXN*<`kCmtbYt1)uFv>oqeC zNw)PXj>Mzk;uz0v_m0tk(%Fni!|_Omfz!s2jH3hH_Xb8J71EhM9LPZ{IgWX|*$P%E zA3r8$?6wLlH&AH>uP8s&&e)CsZyU!m!k?CqQnYZpfuw_~me3OB@gT;vgQJO1tre6~ zf(CX2Wv4)i27s*~7R9-6&RMTRKzvCcim=jv(b}Ua+u>pj@DYjOVPyFn1`Bh@z4@xf``C7tqwKD&GU=X z=JbfdvkwNy(12k{x^3Q~&g?G{MpIk*AU zd=#Cc89f}!JY6@SbT*p~s$-*=)jBDVoFjV;(X?))d5yg`nz$V`z?z@M6tD4=g(hzo zT0%?NV|^UWzOyjEbT;FvC3rSD?6K1l%e@HEAkD8^iaz#hJbCEf3R21}4rnBOWzz~) z%2(@*z~c8n21xT-nBd{#Z&vu6;;4&%jj#bvG(iK|*}!>; z#xKGQ7@f^HrWBhyC{WDXHQoOPMwDVLE(k39&hGa@8xuN^6N + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {7BC76CAE-ECA9-4C9B-9DE0-3F8449F815B4} + Win32Proj + owTools + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + true + + + true + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + .\windows\owTools;.\;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Use + Level3 + Disabled + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + .\windows\owTools;.\;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windows/owTools/owerr.cpp b/windows/owTools/owerr.cpp new file mode 100644 index 0000000..76c5176 --- /dev/null +++ b/windows/owTools/owerr.cpp @@ -0,0 +1,348 @@ +//--------------------------------------------------------------------------- +// 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. +//--------------------------------------------------------------------------- +// +// owerr.c - Library functions for error handling with 1-Wire library +// +// Version: 1.00 +// + +#include +#ifndef _WIN32_WCE +#include +#endif +#ifdef _WIN64 +#include +#endif +#include "ownet.h" + +#ifndef SIZE_OWERROR_STACK + #ifdef SMALL_MEMORY_TARGET + //for small memory, only hole 1 error + #define SIZE_OWERROR_STACK 1 + #else + #define SIZE_OWERROR_STACK 10 + #endif +#endif + +//--------------------------------------------------------------------------- +// Variables +//--------------------------------------------------------------------------- + +// Error Struct for holding error information. +// In DEBUG, this will also hold the line number and filename. +typedef struct +{ + int owErrorNum; +#ifdef DEBUG + int lineno; + char *filename; +#endif +} owErrorStruct; + +// Ring-buffer used for stack. +// In case of overflow, deepest error is over-written. +static owErrorStruct owErrorStack[SIZE_OWERROR_STACK]; + +// Stack pointer to top-most error. +static int owErrorPointer = 0; + + +//--------------------------------------------------------------------------- +// Functions Definitions +//--------------------------------------------------------------------------- +int owGetErrorNum(void); +void owClearError(void); +int owHasErrors(void); +#ifdef DEBUG + void owRaiseError(int,int,char*); +#else + void owRaiseError(int); +#endif +#ifndef SMALL_MEMORY_TARGET + void owPrintErrorMsg(FILE *); + void owPrintErrorMsgStd(); + char *owGetErrorMsg(int); +#endif + + +//-------------------------------------------------------------------------- +// The 'owGetErroNum' returns the error code of the top-most error on the +// error stack. NOTE: This function has the side effect of popping the +// current error off the stack. All successive calls to 'owGetErrorNum' +// will further clear the error stack. +// +// For list of error codes, see 'ownet.h' +// +// Returns: int : The error code of the top-most error on the stack +// +int owGetErrorNum(void) +{ + int i = owErrorStack[ owErrorPointer ].owErrorNum; + owErrorStack[ owErrorPointer ].owErrorNum = 0; + if(!owErrorPointer) + owErrorPointer = SIZE_OWERROR_STACK - 1; + else + owErrorPointer = (owErrorPointer - 1); + return i; +} + +//-------------------------------------------------------------------------- +// The 'owClearError' clears all the errors. +// +void owClearError(void) +{ + owErrorStack[ owErrorPointer ].owErrorNum = 0; +} + +//-------------------------------------------------------------------------- +// The 'owHasErrors' is a boolean test function which tests whether or not +// a valid error is waiting on the stack. +// +// Returns: TRUE (1) : When there are errors on the stack. +// FALSE (0): When stack's errors are set to 0, or NO_ERROR_SET. +// +int owHasErrors(void) +{ + if(owErrorStack[ owErrorPointer ].owErrorNum) + return 1; //TRUE + else + return 0; //FALSE +} + +#ifdef DEBUG + //-------------------------------------------------------------------------- + // The 'owRaiseError' is the method for raising an error onto the error + // stack. + // + // Arguments: int err - the error code you wish to raise. + // int lineno - DEBUG only - the line number where it was raised + // char* filename - DEBUG only - the file name where it occured. + // + void owRaiseError(int err, int lineno, char* filename) + { + owErrorPointer = (owErrorPointer + 1) % SIZE_OWERROR_STACK; + owErrorStack[ owErrorPointer ].owErrorNum = err; + owErrorStack[ owErrorPointer ].lineno = lineno; + owErrorStack[ owErrorPointer ].filename = filename; + } +#else + //-------------------------------------------------------------------------- + // The 'owRaiseError' is the method for raising an error onto the error + // stack. + // + // Arguments: int err - the error code you wish to raise. + // + void owRaiseError(int err) + { + owErrorPointer = (owErrorPointer + 1) % SIZE_OWERROR_STACK; + owErrorStack[ owErrorPointer ].owErrorNum = err; + } +#endif + + +// SMALL_MEMORY_TARGET - embedded microcontrollers, where these +// messaging functions might not make any sense. +#ifndef SMALL_MEMORY_TARGET + //Array of meaningful error messages to associate with codes. + //Not used on targets with low memory (i.e. PIC). + static char *owErrorMsg[125] = + { + /*000*/ "No Error Was Set", + /*001*/ "No Devices found on 1-Wire Network", + /*002*/ "1-Wire Net Reset Failed", + /*003*/ "Search ROM Error: Couldn't locate next device on 1-Wire", + /*004*/ "Access Failed: Could not select device", + /*005*/ "DS2480B Adapter Not Detected", + /*006*/ "DS2480B: Wrong Baud", + /*007*/ "DS2480B: Bad Response", + /*008*/ "Open COM Failed", + /*009*/ "Write COM Failed", + /*010*/ "Read COM Failed", + /*011*/ "Data Block Too Large", + /*012*/ "Block Transfer failed", + /*013*/ "Program Pulse Failed", + /*014*/ "Program Byte Failed", + /*015*/ "Write Byte Failed", + /*016*/ "Read Byte Failed", + /*017*/ "Write Verify Failed", + /*018*/ "Read Verify Failed", + /*019*/ "Write Scratchpad Failed", + /*020*/ "Copy Scratchpad Failed", + /*021*/ "Incorrect CRC Length", + /*022*/ "CRC Failed", + /*023*/ "Failed to acquire a necessary system resource", + /*024*/ "Failed to initialize system resource", + /*025*/ "Data too long to fit on specified device.", + /*026*/ "Read exceeds memory bank end.", + /*027*/ "Write exceeds memory bank end.", + /*028*/ "Device select failed", + /*029*/ "Read Scratch Pad verify failed.", + /*030*/ "Copy scratchpad complete not found", + /*031*/ "Erase scratchpad complete not found", + /*032*/ "Address read back from scrachpad was incorrect", + /*033*/ "Read page with extra-info not supported by this memory bank", + /*034*/ "Read page packet with extra-info not supported by this memory bank", + /*035*/ "Length of packet requested exceeds page size", + /*036*/ "Invalid length in packet", + /*037*/ "Program pulse required but not available", + /*038*/ "Trying to access a read-only memory bank", + /*039*/ "Current bank is not general purpose memory", + /*040*/ "Read back from write compare is incorrect, page may be locked", + /*041*/ "Invalid page number for this memory bank", + /*042*/ "Read page with CRC not supported by this memory bank", + /*043*/ "Read page with CRC and extra-info not supported by this memory bank", + /*044*/ "Read back from write incorrect, could not lock page", + /*045*/ "Read back from write incorrect, could not lock redirect byte", + /*046*/ "The read of the status was not completed.", + /*047*/ "Page redirection not supported by this memory bank", + /*048*/ "Lock Page redirection not supported by this memory bank", + /*049*/ "Read back byte on EPROM programming did not match.", + /*050*/ "Can not write to a page that is locked.", + /*051*/ "Can not lock a redirected page that has already been locked.", + /*052*/ "Trying to redirect a locked redirected page.", + /*053*/ "Trying to lock a page that is already locked.", + /*054*/ "Trying to write to a memory bank that is write protected.", + /*055*/ "Error due to not matching MAC.", + /*056*/ "Memory Bank is write protected.", + /*057*/ "Secret is write protected, can not Load First Secret.", + /*058*/ "Error in Reading Scratchpad after Computing Next Secret.", + /*059*/ "Load Error from Loading First Secret.", + /*060*/ "Power delivery required but not available", + /*061*/ "Not a valid file name.", + /*062*/ "Unable to Create a Directory in this part.", + /*063*/ "That file already exists.", + /*064*/ "The directory is not empty.", + /*065*/ "The wrong type of part for this operation.", + /*066*/ "The max len for this file is too small.", + /*067*/ "This is not a write once bank.", + /*068*/ "The file can not be found.", + /*069*/ "There is not enough space available.", + /*070*/ "There is not a page to match that bit in the bitmap.", + /*071*/ "There are no jobs for EPROM parts.", + /*072*/ "Function not supported to modify attributes.", + /*073*/ "Handle is not in use.", + /*074*/ "Tring to read a write only file.", + /*075*/ "There is no handle available for use.", + /*076*/ "The directory provided is an invalid directory.", + /*077*/ "Handle does not exist.", + /*078*/ "Serial Number did not match with current job.", + /*079*/ "Can not program EPROM because a non-EPROM part on the network.", + /*080*/ "Write protect redirection byte is set.", + /*081*/ "There is an inappropriate directory length.", + /*082*/ "The file has already been terminated.", + /*083*/ "Failed to read memory page of iButton part.", + /*084*/ "Failed to match scratchpad of iButton part.", + /*085*/ "Failed to erase scratchpad of iButton part.", + /*086*/ "Failed to read scratchpad of iButton part.", + /*087*/ "Failed to execute SHA function on SHA iButton.", + /*088*/ "SHA iButton did not return a status completion byte.", + /*089*/ "Write data page failed.", + /*090*/ "Copy secret into secret memory pages failed.", + /*091*/ "Bind unique secret to iButton failed.", + /*092*/ "Could not install secret into user token.", + /*093*/ "Transaction Incomplete: signature did not match.", + /*094*/ "Transaction Incomplete: could not sign service data.", + /*095*/ "User token did not provide a valid authentication response.", + /*096*/ "Failed to answer a challenge on the user token.", + /*097*/ "Failed to create a challenge on the coprocessor.", + /*098*/ "Transaction Incomplete: service data was not valid.", + /*099*/ "Transaction Incomplete: service data was not updated.", + /*100*/ "Unrecoverable, catastrophic service failure occured.", + /*101*/ "Load First Secret from scratchpad data failed.", + /*102*/ "Failed to match signature of user's service data.", + /*103*/ "Subkey out of range for the DS1991.", + /*104*/ "Block ID out of range for the DS1991", + /*105*/ "Password is enabled", + /*106*/ "Password is invalid", + /*107*/ "This memory bank has no read only password", + /*108*/ "This memory bank has no read/write password", + /*109*/ "1-Wire is shorted", + /*110*/ "Error communicating with 1-Wire adapter", + /*111*/ "CopyScratchpad failed: Ending Offset must go to end of page", + /*112*/ "WriteScratchpad failed: Ending Offset must go to end of page", + /*113*/ "Mission can not be stopped while one is not in progress", + /*114*/ "Error stopping the mission", + /*115*/ "Port number is outside (0,MAX_PORTNUM) interval", + /*116*/ "Level of the 1-Wire was not changed", + /*117*/ "Both the Read Only and Read Write Passwords must be set", + /*118*/ "Failure to change latch state." + /*119*/ "Could not open usb port through libusb", + /*120*/ "Libusb DS2490 port already opened", + /*121*/ "Failed to set libusb configuration", + /*122*/ "Failed to claim libusb interface", + /*123*/ "Failed to set libusb altinterface", + /*124*/ "No adapter found at this port number" + }; + + char *owGetErrorMsg(int err) + { + return owErrorMsg[err]; + } + +#ifndef __C51__ + //-------------------------------------------------------------------------- + // The 'owPrintErrorMsg' is the method for printing an error from the stack. + // The destination for the print is specified by the argument, fileno, which + // can be stderr, stdout, or a log file. In non-debug mode, the output is + // of the form: + // Error num: Error msg + // + // In debug-mode, the output is of the form: + // Error num: filename line#: Error msg + // + // NOTE: This function has the side-effect of popping the error off the stack. + // + // Arguments: FILE*: the destination for printing. + // + void owPrintErrorMsg(FILE *filenum) + { + #ifdef DEBUG + int l = owErrorStack[ owErrorPointer ].lineno; + char *f = owErrorStack[ owErrorPointer ].filename; + int err = owGetErrorNum(); + fprintf(filenum,"Error %d: %s line %d: %s\r\n",err,f,l,owErrorMsg[err]); + #else + int err = owGetErrorNum(); + fprintf(filenum,"Error %d: %s\r\n",err,owErrorMsg[err]); + #endif + } +#endif //__C51__ + + // Same as above, except uses default printf output + void owPrintErrorMsgStd() + { + #ifdef DEBUG + int l = owErrorStack[ owErrorPointer ].lineno; + char *f = owErrorStack[ owErrorPointer ].filename; + int err = owGetErrorNum(); + printf("Error %d: %s line %d: %s\r\n",err,f,l,owErrorMsg[err]); + #else + int err = owGetErrorNum(); + printf("Error %d: %s\r\n",err,owErrorMsg[err]); + #endif + } +#endif + diff --git a/windows/owTools/ownet.h b/windows/owTools/ownet.h new file mode 100644 index 0000000..dc1d106 --- /dev/null +++ b/windows/owTools/ownet.h @@ -0,0 +1,426 @@ +//--------------------------------------------------------------------------- +// 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. +//--------------------------------------------------------------------------- +// +// ownet.h - Include file for 1-Wire Net library +// +// Version: 2.10 +// +// History: 1.02 -> 1.03 Make sure uchar is not defined twice. +// 1.03 -> 2.00 Changed 'MLan' to 'ow'. +// 2.00 -> 2.01 Added error handling. Added circular-include check. +// 2.01 -> 2.10 Added raw memory error handling and SMALLINT +// 2.10 -> 3.00 Added memory bank functionality +// Added file I/O operations +// + +#ifndef OWNET_H +#define OWNET_H + +//--------------------------------------------------------------// +// Common Includes to ownet applications +//--------------------------------------------------------------// +#include +#include + + +//--------------------------------------------------------------// +// Target Specific Information +//--------------------------------------------------------------// +//--------------------------------------------------------------// +// Handhelds (PalmOS, WinCE) +//--------------------------------------------------------------// +#ifdef __MC68K__ + //MC68K is the type of processor in the PILOT + //Metrowerk's CodeWarrior defines this symbol + #include + #ifndef strcmp + #include + #define strcmp StrCompare + #endif + #include +#endif + +#ifdef _WIN32_WCE + //All of our projects had this flag defined by default (_WIN32_WCE), + //but I'm not 100% positive that this is _the_ definitive + //flag to use to identify a WinCE system. + #include "WinCElnk.h" + #ifndef FILE + #define FILE int + extern int sprintf(char *buffer, char *format,...); + extern void fprintf(FILE *fp, char *format,...); + extern void printf(char *format,...); + #endif +#endif + +#if !defined(_WIN32_WCE) && !defined(__MC68K__) + #include +#endif + +#ifdef __C51__ + #define FILE int + #define exit(c) return + typedef unsigned int ushort; + typedef unsigned long ulong; + #define SMALLINT uchar +#endif + +#ifdef __ICCMAXQ__ + #define FILE int + #define stdout 0 + #define stdin 1 + #define stderr 2 + typedef unsigned int ushort; + typedef unsigned long ulong; + #define SMALLINT short + #define main micro_main + #define real_main main + #define SMALL_MEMORY_TARGET +#endif + + +//--------------------------------------------------------------// +// Typedefs +//--------------------------------------------------------------// +#ifndef SMALLINT + // + // purpose of smallint is for compile-time changing of formal + // parameters and return values of functions. For each target + // machine, an integer is alleged to represent the most "simple" + // number representable by that architecture. This should, in + // most cases, produce optimal code for that particular arch. + // BUT... The majority of compilers designed for embedded + // processors actually keep an int at 16 bits, although the + // architecture might only be comfortable with 8 bits. + // The default size of smallint will be the same as that of + // an integer, but this allows for easy overriding of that size. + // + // NOTE: + // In all cases where a smallint is used, it is assumed that + // decreasing the size of this integer to something as low as + // a single byte _will_not_ change the functionality of the + // application. e.g. a loop counter that will iterate through + // several kilobytes of data should not be SMALLINT. The most + // common place you'll see smallint is for boolean return types. + // + #define SMALLINT int +#endif + +// setting max baud +#ifdef _WINDOWS + // 0x02 = PARAMSET_19200 +#define MAX_BAUD 0x02 +#else + // 0x06 = PARMSET_115200 +#define MAX_BAUD 0x06 +#endif + +#ifndef OW_UCHAR + #define OW_UCHAR + typedef unsigned char uchar; + #if !defined(__MINGW32__) && (defined(__CYGWIN__) || defined(__GNUC__)) + typedef unsigned long ulong; + //ushort already defined in sys/types.h + #include + #else + #if defined(_WIN32) || defined(WIN32) || defined(__MC68K__) || defined(_WIN32_WCE) || defined(_DOS) || defined(_WINDOWS) || defined(__MINGW32__) + typedef unsigned short ushort; + typedef unsigned long ulong; + #endif + #endif + #ifdef __sun__ + #include + #endif + #ifdef SDCC + //intent of ushort is 2 bytes unsigned. + //for ds390 in sdcc, an int, not a short, + //is 2 bytes. + typedef unsigned int ushort; + #endif +#endif + +// general defines +#define WRITE_FUNCTION 1 +#define READ_FUNCTION 0 + +// error codes +// todo: investigate these and replace with new Error Handling library +#define READ_ERROR -1 +#define INVALID_DIR -2 +#define NO_FILE -3 +#define WRITE_ERROR -4 +#define WRONG_TYPE -5 +#define FILE_TOO_BIG -6 + +// Misc +#define FALSE 0 +#define TRUE 1 + +#ifndef MAX_PORTNUM + #define MAX_PORTNUM 16 +#endif + +// mode bit flags +#define MODE_NORMAL 0x00 +#define MODE_OVERDRIVE 0x01 +#define MODE_STRONG5 0x02 +#define MODE_PROGRAM 0x04 +#define MODE_BREAK 0x08 + +// Output flags +#define LV_ALWAYS 2 +#define LV_OPTIONAL 1 +#define LV_VERBOSE 0 + +//--------------------------------------------------------------// +// Error handling +//--------------------------------------------------------------// +extern int owGetErrorNum(void); +extern int owHasErrors(void); + +//Clears the stack. +#define OWERROR_CLEAR() while(owHasErrors()) owGetErrorNum(); + +#ifdef DEBUG + //Raises an exception with extra debug info + #define OWERROR(err) owRaiseError(err,__LINE__,__FILE__) + extern void owRaiseError(int,int,char*); + #define OWASSERT(s,err,ret) if(!(s)){owRaiseError((err),__LINE__,__FILE__);return (ret);} +#else + //Raises an exception with just the error code + #define OWERROR(err) owRaiseError(err) + extern void owRaiseError(int); + #define OWASSERT(s,err,ret) if(!(s)){owRaiseError((err));return (ret);} +#endif + +#ifdef SMALL_MEMORY_TARGET + #define OWERROR_DUMP(fileno) /*no-op*/; +#else + //Prints the stack out to the given file. + #define OWERROR_DUMP(fileno) while(owHasErrors()) owPrintErrorMsg(fileno); + extern void owPrintErrorMsg(FILE *); + extern void owPrintErrorMsgStd(); + extern char *owGetErrorMsg(int); +#endif + +#define OWERROR_NO_ERROR_SET 0 +#define OWERROR_NO_DEVICES_ON_NET 1 +#define OWERROR_RESET_FAILED 2 +#define OWERROR_SEARCH_ERROR 3 +#define OWERROR_ACCESS_FAILED 4 +#define OWERROR_DS2480_NOT_DETECTED 5 +#define OWERROR_DS2480_WRONG_BAUD 6 +#define OWERROR_DS2480_BAD_RESPONSE 7 +#define OWERROR_OPENCOM_FAILED 8 +#define OWERROR_WRITECOM_FAILED 9 +#define OWERROR_READCOM_FAILED 10 +#define OWERROR_BLOCK_TOO_BIG 11 +#define OWERROR_BLOCK_FAILED 12 +#define OWERROR_PROGRAM_PULSE_FAILED 13 +#define OWERROR_PROGRAM_BYTE_FAILED 14 +#define OWERROR_WRITE_BYTE_FAILED 15 +#define OWERROR_READ_BYTE_FAILED 16 +#define OWERROR_WRITE_VERIFY_FAILED 17 +#define OWERROR_READ_VERIFY_FAILED 18 +#define OWERROR_WRITE_SCRATCHPAD_FAILED 19 +#define OWERROR_COPY_SCRATCHPAD_FAILED 20 +#define OWERROR_INCORRECT_CRC_LENGTH 21 +#define OWERROR_CRC_FAILED 22 +#define OWERROR_GET_SYSTEM_RESOURCE_FAILED 23 +#define OWERROR_SYSTEM_RESOURCE_INIT_FAILED 24 +#define OWERROR_DATA_TOO_LONG 25 +#define OWERROR_READ_OUT_OF_RANGE 26 +#define OWERROR_WRITE_OUT_OF_RANGE 27 +#define OWERROR_DEVICE_SELECT_FAIL 28 +#define OWERROR_READ_SCRATCHPAD_VERIFY 29 +#define OWERROR_COPY_SCRATCHPAD_NOT_FOUND 30 +#define OWERROR_ERASE_SCRATCHPAD_NOT_FOUND 31 +#define OWERROR_ADDRESS_READ_BACK_FAILED 32 +#define OWERROR_EXTRA_INFO_NOT_SUPPORTED 33 +#define OWERROR_PG_PACKET_WITHOUT_EXTRA 34 +#define OWERROR_PACKET_LENGTH_EXCEEDS_PAGE 35 +#define OWERROR_INVALID_PACKET_LENGTH 36 +#define OWERROR_NO_PROGRAM_PULSE 37 +#define OWERROR_READ_ONLY 38 +#define OWERROR_NOT_GENERAL_PURPOSE 39 +#define OWERROR_READ_BACK_INCORRECT 40 +#define OWERROR_INVALID_PAGE_NUMBER 41 +#define OWERROR_CRC_NOT_SUPPORTED 42 +#define OWERROR_CRC_EXTRA_INFO_NOT_SUPPORTED 43 +#define OWERROR_READ_BACK_NOT_VALID 44 +#define OWERROR_COULD_NOT_LOCK_REDIRECT 45 +#define OWERROR_READ_STATUS_NOT_COMPLETE 46 +#define OWERROR_PAGE_REDIRECTION_NOT_SUPPORTED 47 +#define OWERROR_LOCK_REDIRECTION_NOT_SUPPORTED 48 +#define OWERROR_READBACK_EPROM_FAILED 49 +#define OWERROR_PAGE_LOCKED 50 +#define OWERROR_LOCKING_REDIRECTED_PAGE_AGAIN 51 +#define OWERROR_REDIRECTED_PAGE 52 +#define OWERROR_PAGE_ALREADY_LOCKED 53 +#define OWERROR_WRITE_PROTECTED 54 +#define OWERROR_NONMATCHING_MAC 55 +#define OWERROR_WRITE_PROTECT 56 +#define OWERROR_WRITE_PROTECT_SECRET 57 +#define OWERROR_COMPUTE_NEXT_SECRET 58 +#define OWERROR_LOAD_FIRST_SECRET 59 +#define OWERROR_POWER_NOT_AVAILABLE 60 +#define OWERROR_XBAD_FILENAME 61 +#define OWERROR_XUNABLE_TO_CREATE_DIR 62 +#define OWERROR_REPEAT_FILE 63 +#define OWERROR_DIRECTORY_NOT_EMPTY 64 +#define OWERROR_WRONG_TYPE 65 +#define OWERROR_BUFFER_TOO_SMALL 66 +#define OWERROR_NOT_WRITE_ONCE 67 +#define OWERROR_FILE_NOT_FOUND 68 +#define OWERROR_OUT_OF_SPACE 69 +#define OWERROR_TOO_LARGE_BITNUM 70 +#define OWERROR_NO_PROGRAM_JOB 71 +#define OWERROR_FUNC_NOT_SUP 72 +#define OWERROR_HANDLE_NOT_USED 73 +#define OWERROR_FILE_WRITE_ONLY 74 +#define OWERROR_HANDLE_NOT_AVAIL 75 +#define OWERROR_INVALID_DIRECTORY 76 +#define OWERROR_HANDLE_NOT_EXIST 77 +#define OWERROR_NONMATCHING_SNUM 78 +#define OWERROR_NON_PROGRAM_PARTS 79 +#define OWERROR_PROGRAM_WRITE_PROTECT 80 +#define OWERROR_FILE_READ_ERR 81 +#define OWERROR_ADDFILE_TERMINATED 82 +#define OWERROR_READ_MEMORY_PAGE_FAILED 83 +#define OWERROR_MATCH_SCRATCHPAD_FAILED 84 +#define OWERROR_ERASE_SCRATCHPAD_FAILED 85 +#define OWERROR_READ_SCRATCHPAD_FAILED 86 +#define OWERROR_SHA_FUNCTION_FAILED 87 +#define OWERROR_NO_COMPLETION_BYTE 88 +#define OWERROR_WRITE_DATA_PAGE_FAILED 89 +#define OWERROR_COPY_SECRET_FAILED 90 +#define OWERROR_BIND_SECRET_FAILED 91 +#define OWERROR_INSTALL_SECRET_FAILED 92 +#define OWERROR_VERIFY_SIG_FAILED 93 +#define OWERROR_SIGN_SERVICE_DATA_FAILED 94 +#define OWERROR_VERIFY_AUTH_RESPONSE_FAILED 95 +#define OWERROR_ANSWER_CHALLENGE_FAILED 96 +#define OWERROR_CREATE_CHALLENGE_FAILED 97 +#define OWERROR_BAD_SERVICE_DATA 98 +#define OWERROR_SERVICE_DATA_NOT_UPDATED 99 +#define OWERROR_CATASTROPHIC_SERVICE_FAILURE 100 +#define OWERROR_LOAD_FIRST_SECRET_FAILED 101 +#define OWERROR_MATCH_SERVICE_SIGNATURE_FAILED 102 +#define OWERROR_KEY_OUT_OF_RANGE 103 +#define OWERROR_BLOCK_ID_OUT_OF_RANGE 104 +#define OWERROR_PASSWORDS_ENABLED 105 +#define OWERROR_PASSWORD_INVALID 106 +#define OWERROR_NO_READ_ONLY_PASSWORD 107 +#define OWERROR_NO_READ_WRITE_PASSWORD 108 +#define OWERROR_OW_SHORTED 109 +#define OWERROR_ADAPTER_ERROR 110 +#define OWERROR_EOP_COPY_SCRATCHPAD_FAILED 111 +#define OWERROR_EOP_WRITE_SCRATCHPAD_FAILED 112 +#define OWERROR_HYGRO_STOP_MISSION_UNNECESSARY 113 +#define OWERROR_HYGRO_STOP_MISSION_ERROR 114 +#define OWERROR_PORTNUM_ERROR 115 +#define OWERROR_LEVEL_FAILED 116 +#define OWERROR_PASSWORD_NOT_SET 117 +#define OWERROR_LATCH_NOT_SET 118 +#define OWERROR_LIBUSB_OPEN_FAILED 119 +#define OWERROR_LIBUSB_DEVICE_ALREADY_OPENED 120 +#define OWERROR_LIBUSB_SET_CONFIGURATION_ERROR 121 +#define OWERROR_LIBUSB_CLAIM_INTERFACE_ERROR 122 +#define OWERROR_LIBUSB_SET_ALTINTERFACE_ERROR 123 +#define OWERROR_LIBUSB_NO_ADAPTER_FOUND 124 + + + // One Wire functions defined in ownetu.c + SMALLINT owFirst_(int portnum, SMALLINT do_reset, SMALLINT alarm_only); + SMALLINT owNext_(int portnum, SMALLINT do_reset, SMALLINT alarm_only); + void owSerialNum(int portnum, uchar *serialnum_buf, SMALLINT do_read); + void owFamilySearchSetup(int portnum, SMALLINT search_family); + void owSkipFamily(int portnum); + SMALLINT owAccess(int portnum); + SMALLINT owVerify(int portnum, SMALLINT alarm_only); + SMALLINT owOverdriveAccess(int portnum); + + + // external One Wire functions defined in owsesu.c + SMALLINT owAcquire(int portnum, char *port_zstr); + int owAcquireEx(char *port_zstr); + void owRelease(int portnum); + + // external One Wire functions defined in findtype.c + // SMALLINT FindDevices(int,uchar FamilySN[][8],SMALLINT,int); + + // external One Wire functions from link layer owllu.c + SMALLINT owTouchReset(int portnum); + SMALLINT owTouchBit(int portnum, SMALLINT sendbit); + SMALLINT owTouchByte(int portnum, SMALLINT sendbyte); + SMALLINT owWriteByte(int portnum, SMALLINT sendbyte); + SMALLINT owReadByte(int portnum); + SMALLINT owSpeed(int portnum, SMALLINT new_speed); + SMALLINT owLevel(int portnum, SMALLINT new_level); + SMALLINT owProgramPulse(int portnum); + SMALLINT owWriteBytePower(int portnum, SMALLINT sendbyte); + SMALLINT owReadBytePower(int portnum); + SMALLINT owHasPowerDelivery(int portnum); + SMALLINT owHasProgramPulse(int portnum); + SMALLINT owHasOverDrive(int portnum); + SMALLINT owReadBitPower(int portnum, SMALLINT applyPowerResponse); + // external One Wire global from owllu.c + extern SMALLINT FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE; + + // external One Wire functions from transaction layer in owtrnu.c + SMALLINT owBlock(int portnum, SMALLINT do_reset, uchar *tran_buf, SMALLINT tran_len); + SMALLINT owReadPacketStd(int portnum, SMALLINT do_access, int start_page, uchar *read_buf); + SMALLINT owWritePacketStd(int portnum, int start_page, uchar *write_buf, + SMALLINT write_len, SMALLINT is_eprom, SMALLINT crc_type); + SMALLINT owProgramByte(int portnum, SMALLINT write_byte, int addr, SMALLINT write_cmd, + SMALLINT crc_type, SMALLINT do_access); + + // link functions + void msDelay(int len); + long msGettick(void); + + // ioutil.c functions prototypes + int EnterString(char *msg, char *buf, int min, int max); + int EnterNum(char *msg, int numchars, long *value, long min, long max); + int EnterHex(char *msg, int numchars, ulong *value); + int ToHex(char ch); + int getkeystroke(void); + int key_abort(void); + void ExitProg(char *msg, int exit_code); + int getData(uchar *write_buff, int max_len, SMALLINT gethex); + void PrintHex(uchar* buffer, int cnt); + void PrintChars(uchar* buffer, int cnt); + void PrintSerialNum(uchar* buffer); + + // external functions defined in crcutil.c + void setcrc16(int portnum, ushort reset); + ushort docrc16(int portnum, ushort cdata); + void setcrc8(int portnum, uchar reset); + uchar docrc8(int portnum, uchar x); + + extern int owInUse; + +#endif //OWNET_H diff --git a/windows/owTools/tmexlnk.cpp b/windows/owTools/tmexlnk.cpp new file mode 100644 index 0000000..47d22d1 --- /dev/null +++ b/windows/owTools/tmexlnk.cpp @@ -0,0 +1,368 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 2001 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. +//--------------------------------------------------------------------------- +// +// TMEXLnk.C - Link module to call on TMEX low-level functions to +// excersize the general 1-Wire Net functions. +// (Requires TMEX 3.11 or newer) +// +// Version: 3.00 +// +// History: 1.00 -> 1.01 Return values in owLevel corrected. +// Added function msDelay. +// 1.02 -> 1.03 Add msGettick, always return owLevel success +// to hide adapters (DS9097E) that do not have +// power delivery capabilities. +// 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for +// multiple ports. +// 2.10 -> 3.00 Added owReadBitPower and owWriteBytePower + +#include "ownet.h" +#include + +// external TMEX variables +extern long SessionHandle[MAX_PORTNUM]; +extern uchar StateBuffer[MAX_PORTNUM][5120]; +extern "C" short far pascal TMTouchByte(long, short); +extern "C" short far pascal TMTouchReset(long); +extern "C" short far pascal TMTouchBit(long, short); +extern "C" short far pascal TMProgramPulse(long); +extern "C" short far pascal TMOneWireCom(long, short, short); +extern "C" short far pascal TMOneWireLevel(long, short, short, short); + +// globals +SMALLINT FAMILY_CODE_04_ALARM_TOUCHRESET_COMPLIANCE = FALSE; // for compatibility purposes + +//-------------------------------------------------------------------------- +// Reset all of the devices on the 1-Wire Net and return the result. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +// Returns: TRUE(1): presense pulse(s) detected, device(s) reset +// FALSE(0): no presense pulses detected +// +SMALLINT owTouchReset(int portnum) +{ + int result; + + // Assume valid Session + result = TMTouchReset(SessionHandle[portnum]); + + // success if the normal or alarm presence + if ((result == 1) || (result == 2)) + return TRUE; + else + return FALSE; +} + + +//-------------------------------------------------------------------------- +// Send 1 bit of communication to the 1-Wire Net and return the +// result 1 bit read from the 1-Wire Net. The parameter 'sendbit' +// least significant bit is used and the least significant bit +// of the result is the return bit. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'sendbit' - the least significant bit is the bit to send +// +// Returns: 0: 0 bit read from sendbit +// 1: 1 bit read from sendbit +// +SMALLINT owTouchBit(int portnum, SMALLINT sendbit) +{ + // Assume valid Session + return TMTouchBit(SessionHandle[portnum],(short)sendbit); +} + +//-------------------------------------------------------------------------- +// Send 8 bits of communication to the 1-Wire Net and verify that the +// 8 bits read from the 1-Wire Net is the same (write operation). +// The parameter 'sendbyte' least significant 8 bits are used. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'sendbyte' - 8 bits to send (least significant byte) +// +// Returns: TRUE: bytes written and echo was the same +// FALSE: echo was not the same +// +SMALLINT owTouchByte(int portnum, SMALLINT sendbyte) +{ + // Assume valid Session + return TMTouchByte(SessionHandle[portnum],(short)sendbyte); +} + +//-------------------------------------------------------------------------- +// Send 8 bits of communication to the MicroLAN and verify that the +// 8 bits read from the MicroLAN is the same (write operation). +// The parameter 'sendbyte' least significant 8 bits are used. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'sendbyte' - 8 bits to send (least significant byte) +// +// Returns: TRUE: bytes written and echo was the same +// FALSE: echo was not the same +// +SMALLINT owWriteByte(int portnum, SMALLINT sendbyte) +{ + return (owTouchByte(portnum,sendbyte) == sendbyte) ? TRUE : FALSE; +} + +//-------------------------------------------------------------------------- +// Send 8 bits of read communication to the 1-Wire Net and and return the +// result 8 bits read from the 1-Wire Net. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +// Returns: TRUE: 8 bytes read from 1-Wire Net +// FALSE: the 8 bytes were not read +// +SMALLINT owReadByte(int portnum) +{ + return owTouchByte(portnum,0xFF); +} + +//-------------------------------------------------------------------------- +// Set the 1-Wire Net communucation speed. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'new_speed' - new speed defined as +// MODE_NORMAL 0x00 +// MODE_OVERDRIVE 0x01 +// +// Returns: current 1-Wire Net speed +// +SMALLINT owSpeed(int portnum, SMALLINT new_speed) +{ + return TMOneWireCom(SessionHandle[portnum],0,(short)new_speed); +} + +//-------------------------------------------------------------------------- +// Set the 1-Wire Net line level. The values for new_level are +// as follows: +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'new_level' - new level defined as +// MODE_NORMAL 0x00 +// MODE_STRONG5 0x02 +// MODE_PROGRAM 0x04 +// MODE_BREAK 0x08 (not supported) +// +// Returns: current 1-Wire Net level +// +SMALLINT owLevel(int portnum, SMALLINT new_level) +{ + int rslt; + int docheck = FALSE; + + // check for DS2480 bug + if (((SessionHandle[portnum] & 0x0F0) == 0x050) && + (TMOneWireLevel(SessionHandle[portnum],1,0,0) == 1)) + docheck = TRUE; + + switch (new_level) + { + case MODE_NORMAL: + rslt = TMOneWireLevel(SessionHandle[portnum],0,0,0); + // test code for DS2480 bug + if (docheck) + TMTouchBit(SessionHandle[portnum],1); + break; + case MODE_STRONG5: + rslt = TMOneWireLevel(SessionHandle[portnum],0,1,0); + break; + case MODE_PROGRAM: + rslt = TMOneWireLevel(SessionHandle[portnum],0,3,0); + break; + case MODE_BREAK: + rslt = TMOneWireLevel(SessionHandle[portnum],0,2,0); + break; + default: + rslt = 0; + } + + // Assume TMEX can do it so always return NewLevel + return new_level; +} + +//-------------------------------------------------------------------------- +// This procedure creates a fixed 480 microseconds 12 volt pulse +// on the 1-Wire Net for programming EPROM iButtons. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +// Returns: TRUE successful +// FALSE program voltage not available +// +SMALLINT owProgramPulse(int portnum) +{ + return TMProgramPulse(SessionHandle[portnum]); +} + +//-------------------------------------------------------------------------- +// Description: +// Delay for at least 'len' ms +// +void msDelay(int len) +{ + Sleep(len); +} + +//-------------------------------------------------------------------------- +// 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) +{ + return GetTickCount(); +} + +//-------------------------------------------------------------------------- +// Send 8 bits of communication to the 1-Wire Net and verify that the +// 8 bits read from the 1-Wire Net is the same (write operation). +// The parameter 'sendbyte' least significant 8 bits are used. After the +// 8 bits are sent change the level of the 1-Wire net. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'sendbyte' - 8 bits to send (least significant byte) +// +// Returns: TRUE: bytes written and echo was the same +// FALSE: echo was not the same +// +SMALLINT owWriteBytePower(int portnum, SMALLINT sendbyte) +{ + // prime for power delivery after byte + TMOneWireLevel(SessionHandle[portnum],0,1,2); + + // send the byte and start strong pullup + if(TMTouchByte(SessionHandle[portnum],(short)sendbyte) != sendbyte) + { + TMOneWireLevel(SessionHandle[portnum],0,0,0); + return FALSE; + } + + return TRUE; +} + +//-------------------------------------------------------------------------- +// Read 8 bits of communication to the 1-Wire Net and verify that the +// 8 bits read from the 1-Wire Net is the same (write operation). +// The parameter 'sendbyte' least significant 8 bits are used. After the +// 8 bits are read change the level of the 1-Wire net. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'sendbyte' - 8 bits to send (least significant byte) +// +// Returns: TRUE: bytes written and echo was the same +// FALSE: echo was not the same +// +SMALLINT owReadBytePower(int portnum) +{ + SMALLINT sendbyte = 0xFF; + + // prime for power delivery after byte + TMOneWireLevel(SessionHandle[portnum],0,1,2); + + // send the byte and start strong pullup + return TMTouchByte(SessionHandle[portnum],(short)sendbyte); +} + +//-------------------------------------------------------------------------- +// Send 1 bit of communication to the 1-Wire Net and verify that the +// response matches the 'applyPowerResponse' bit and apply power delivery +// to the 1-Wire net. Note that some implementations may apply the power +// first and then turn it off if the response is incorrect. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'applyPowerResponse' - 1 bit response to check, if correct then start +// power delivery +// +// Returns: TRUE: bit written and response correct, strong pullup now on +// FALSE: response incorrect +// +SMALLINT owReadBitPower(int portnum, SMALLINT applyPowerResponse) +{ + // prime for power delivery after bit + TMOneWireLevel(SessionHandle[portnum],0,1,1); + + // send the byte and start strong pullup + if(TMTouchBit(SessionHandle[portnum],0x01) != applyPowerResponse) + { + TMOneWireLevel(SessionHandle[portnum],0,0,0); + return FALSE; + } + + return TRUE; +} + +//-------------------------------------------------------------------------- +// This procedure indicates wether the adapter can deliver power. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +// Returns: TRUE because all userial adapters have over drive. +// +SMALLINT owHasPowerDelivery(int portnum) +{ + return TRUE; +} + +//-------------------------------------------------------------------------- +// This procedure indicates wether the adapter can deliver power. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +// Returns: TRUE because all userial adapters have over drive. +// +SMALLINT owHasOverDrive(int portnum) +{ + return TRUE; +} + +//-------------------------------------------------------------------------- +// This procedure creates a fixed 480 microseconds 12 volt pulse +// on the 1-Wire Net for programming EPROM iButtons. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// +// Returns: TRUE program volatage available +// FALSE program voltage not available +SMALLINT owHasProgramPulse(int portnum) +{ + return TMProgramPulse(SessionHandle[portnum]); +} \ No newline at end of file diff --git a/windows/owTools/tmexnet.cpp b/windows/owTools/tmexnet.cpp new file mode 100644 index 0000000..8712ac8 --- /dev/null +++ b/windows/owTools/tmexnet.cpp @@ -0,0 +1,251 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 2001 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. +//--------------------------------------------------------------------------- +// +// tmexnet.C - Wrapper class to hook 1-Wire Public Domain API to TMEX API +// for network functions. +// +// Version: 3.00 +// +// + +#include "ownet.h" +#include + +uchar StateBuffer[MAX_PORTNUM][5120]; + +int owInUse = 0; + +// external TMEX variables +extern long SessionHandle[MAX_PORTNUM]; +extern "C" short far pascal TMSearch(long session_handle, void *start_buffer, + short ResetSearch, short PerformReset, + short SrchCmd); +extern "C" short pascal TMFirst(long, void *); +extern "C" short pascal TMNext(long, void *); +extern "C" short pascal TMAccess(long, void *); +extern "C" short pascal TMStrongAccess(long, void *); +extern "C" short pascal TMStrongAlarmAccess(long, void *); +extern "C" short pascal TMOverAccess(long, void *); +extern "C" short pascal TMRom(long, void *, short *); +extern "C" short pascal TMFirstAlarm(long, void *); +extern "C" short pascal TMNextAlarm(long, void *); +extern "C" short pascal TMFamilySearchSetup(long, void *, short); +extern "C" short pascal TMSkipFamily(long, void *); +extern "C" short pascal TMAutoOverDrive(long, void *, short); + + +//-------------------------------------------------------------------------- +// The 'owFirst' finds the first device on the 1-Wire Net This function +// contains one parameter 'alarm_only'. When +// 'alarm_only' is TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0. +// Using the find alarm command 0xEC will limit the search to only +// 1-Wire devices that are in an 'alarm' state. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not +// perform reset before search. +// 'alarm_only' - TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0 +// +// Returns: TRUE (1) : when a 1-Wire device was found and it's +// Serial Number placed in the global SerialNum[portnum] +// FALSE (0): There are no devices on the 1-Wire Net. +// +SMALLINT owFirst_(int portnum, SMALLINT do_reset, SMALLINT alarm_only) +{ + return (TMSearch(SessionHandle[portnum], StateBuffer[portnum], 1, + (short)do_reset, (short)((alarm_only) ? 0xEC : 0xF0)) == 1); +} + +//-------------------------------------------------------------------------- +// The 'owNext' function does a general search. This function +// continues from the previos search state. The search state +// can be reset by using the 'owFirst' function. +// This function contains one parameter 'alarm_only'. +// When 'alarm_only' is TRUE (1) the find alarm command +// 0xEC is sent instead of the normal search command 0xF0. +// Using the find alarm command 0xEC will limit the search to only +// 1-Wire devices that are in an 'alarm' state. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not +// perform reset before search. +// 'alarm_only' - TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0 +// +// Returns: TRUE (1) : when a 1-Wire device was found and it's +// Serial Number placed in the global SerialNum[portnum] +// FALSE (0): when no new device was found. Either the +// last search was the last device or there +// are no devices on the 1-Wire Net. +// +SMALLINT owNext_(int portnum, SMALLINT do_reset, SMALLINT alarm_only) +{ + return (TMSearch(SessionHandle[portnum], StateBuffer[portnum], 0, + (short)do_reset, (short)((alarm_only) ? 0xEC : 0xF0)) == 1); +} + +//-------------------------------------------------------------------------- +// The 'owSerialNum' function either reads or sets the SerialNum buffer +// that is used in the search functions 'owFirst' and 'owNext'. +// This function contains two parameters, 'serialnum_buf' is a pointer +// to a buffer provided by the caller. 'serialnum_buf' should point to +// an array of 8 unsigned chars. The second parameter is a flag called +// 'do_read' that is TRUE (1) if the operation is to read and FALSE +// (0) if the operation is to set the internal SerialNum buffer from +// the data in the provided buffer. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'serialnum_buf' - buffer to that contains the serial number to set +// when do_read = FALSE (0) and buffer to get the serial +// number when do_read = TRUE (1). +// 'do_read' - flag to indicate reading (1) or setting (0) the current +// serial number. +// +void owSerialNum(int portnum, uchar *serialnum_buf, SMALLINT do_read) +{ + short ROM[8],i; + + // check if reading or writing + if (do_read) + { + ROM[0] = 0; + } + else + { + for (i = 0; i < 8; i++) + ROM[i] = serialnum_buf[i]; + } + + // call TMEX to read or set the current device + TMRom(SessionHandle[portnum], StateBuffer[portnum], ROM); + + // place in 'serialnum_buf' + if (do_read) + { + for (i = 0; i < 8; i++) + serialnum_buf[i] = (uchar)ROM[i]; + } +} + +//-------------------------------------------------------------------------- +// Setup the search algorithm to find a certain family of devices +// the next time a search function is called 'owNext'. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to +// OpenCOM to indicate the port number. +// 'search_family' - family code type to set the search algorithm to find +// next. +// +void owFamilySearchSetup(int portnum, SMALLINT search_family) +{ + TMFamilySearchSetup(SessionHandle[portnum], StateBuffer[portnum], + (short)search_family); +} + +//-------------------------------------------------------------------------- +// Set the current search state to skip the current family code. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +void owSkipFamily(int portnum) +{ + TMSkipFamily(SessionHandle[portnum], StateBuffer[portnum]); +} + +//-------------------------------------------------------------------------- +// The 'owAccess' function resets the 1-Wire and sends a MATCH Serial +// Number command followed by the current SerialNum code. After this +// function is complete the 1-Wire device is ready to accept device-specific +// commands. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +// Returns: TRUE (1) : reset indicates present and device is ready +// for commands. +// FALSE (0): reset does not indicate presence or echos 'writes' +// are not correct. +// +SMALLINT owAccess(int portnum) +{ + return (TMAccess(SessionHandle[portnum], StateBuffer[portnum]) == 1); +} + +//---------------------------------------------------------------------- +// The function 'owVerify' verifies that the current device +// is in contact with the 1-Wire Net. +// Using the find alarm command 0xEC will verify that the device +// is in contact with the 1-Wire Net and is in an 'alarm' state. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'alarm_only' - TRUE (1) the find alarm command 0xEC +// is sent instead of the normal search +// command 0xF0. +// +// Returns: TRUE (1) : when the 1-Wire device was verified +// to be on the 1-Wire Net +// with alarm_only == FALSE +// or verified to be on the 1-Wire Net +// AND in an alarm state when +// alarm_only == TRUE. +// FALSE (0): the 1-Wire device was not on the +// 1-Wire Net or if alarm_only +// == TRUE, the device may be on the +// 1-Wire Net but in a non-alarm state. +// +SMALLINT owVerify(int portnum, SMALLINT alarm_only) +{ + if (alarm_only) + return (TMStrongAlarmAccess(SessionHandle[portnum], StateBuffer[portnum]) == 1); + else + return (TMStrongAccess(SessionHandle[portnum], StateBuffer[portnum]) == 1); +} + +//---------------------------------------------------------------------- +// Perform a overdrive MATCH command to select the 1-Wire device with +// the address in the ID data register. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +// Returns: TRUE: If the device is present on the 1-Wire Net and +// can do overdrive then the device is selected. +// FALSE: Device is not present or not capable of overdrive. +// +// *Note: This function could be converted to send DS2480 +// commands in one packet. +// +SMALLINT owOverdriveAccess(int portnum) +{ + return (TMOverAccess(SessionHandle[portnum], StateBuffer[portnum]) == 1); +} diff --git a/windows/owTools/tmexses.cpp b/windows/owTools/tmexses.cpp new file mode 100644 index 0000000..5024acb --- /dev/null +++ b/windows/owTools/tmexses.cpp @@ -0,0 +1,216 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 2001 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. +//--------------------------------------------------------------------------- +// +// owsestmx.c - Acquire and release a Session on the 1-Wire Net using TMEX. +// (Requires TMEX 3.11 or newer) +// +// Version: 2.01 +// +// History: 1.03 -> 2.00 Changed 'MLan' to 'ow'. Added support for +// multiple ports. +// 2.00 -> 2.01 Added support for owError library. +// + +#include +#include +#include "ownet.h" + +// external function prototypes +extern "C" long far pascal TMExtendedStartSession(short, short, void far *); +extern "C" short far pascal TMEndSession(long); +extern "C" short far pascal TMClose(long); +extern "C" short far pascal TMSetup(long); +extern "C" short far pascal TMReadDefaultPort(short far *, short far *); +extern "C" short far pascal TMOneWireCom( + long session_handle, // session handle for the desired 1-Wire network + short Operation,// Read (1) or Set (0) the communication rate + short TimeMode // communication rate number + ); +short PortNum=1,PortType=2; +long SessionHandle[MAX_PORTNUM]; +SMALLINT handle_init = FALSE; + +//--------------------------------------------------------------------------- +// Attempt to acquire a 1-Wire net using a com port and a DS2480 based +// adapter. +// +// 'port_zstr' - zero terminated port name. For this platform +// use format {port number, port type}. +// +// Returns: port number and -1 if not successful in setting up the port. +// +int owAcquireEx(char *port_zstr) +{ + int portnum; + int string_counter, counter, i, lenmax; + char portnum_str[15]; + char porttype_str[15]; + void *tmex_options = NULL; + + if(!handle_init) + { + for(i=0; i 12) + lenmax = 12; + string_counter = 1; + counter = 0; + do + { + portnum_str[counter] = port_zstr[string_counter]; + + counter++; + string_counter++; + } + while((port_zstr[string_counter] != ',') && (string_counter <= lenmax)); + + portnum_str[counter] = '\0'; + + string_counter++; + counter = 0; + + do + { + porttype_str[counter] = port_zstr[string_counter]; + + counter++; + string_counter++; + } + while((port_zstr[string_counter] != '}') && (string_counter <= lenmax)); + + porttype_str[counter] = '\0'; + + PortNum = atoi(portnum_str); + PortType = atoi(porttype_str); + } + + // open a session + SessionHandle[portnum] = TMExtendedStartSession(PortNum,PortType,tmex_options); + + // check the session handle + if (SessionHandle[portnum] <= 0) + { + OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED); + SessionHandle[portnum] = 0; + return -1; + } + + // setup the port + if (TMSetup(SessionHandle[portnum]) != 1) + { + TMClose(SessionHandle[portnum]); + TMEndSession(SessionHandle[portnum]); + OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); + SessionHandle[portnum] = 0; + return -1; + } + + return portnum; +} + +//--------------------------------------------------------------------------- +// Attempt to acquire a 1-Wire net using a com port and a DS2480 based +// adapter. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'port_zstr' - zero terminated port name. For this platform +// use format COMX where X is the port number. +// +// Returns: TRUE - success, COM port opened +// +SMALLINT owAcquire(int portnum, char *port_zstr) +{ + int i; + + if(!handle_init) + { + for(i=0; i=0 && !SessionHandle[portnum], + OWERROR_PORTNUM_ERROR, FALSE ); + + // read the default PortNum and PortType + TMReadDefaultPort(&PortNum,&PortType); + + // convert the string in port_zstr to be the port number + PortNum = atoi(port_zstr); + + // open a session + SessionHandle[portnum] = TMExtendedStartSession(PortNum,PortType,NULL); + + // check the session handle + if (SessionHandle[portnum] <= 0) + { + OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED); + SessionHandle[portnum] = 0; + return FALSE; + } + + // setup the port + if (TMSetup(SessionHandle[portnum]) != 1) + { + TMClose(SessionHandle[portnum]); + TMEndSession(SessionHandle[portnum]); + OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED); + SessionHandle[portnum] = 0; + return FALSE; + } + + return TRUE; +} + +//--------------------------------------------------------------------------- +// Release the previously acquired a 1-Wire net. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// +void owRelease(int portnum) +{ + TMClose(SessionHandle[portnum]); + TMEndSession(SessionHandle[portnum]); + SessionHandle[portnum] = 0; +} + diff --git a/windows/owTools/tmextran.cpp b/windows/owTools/tmextran.cpp new file mode 100644 index 0000000..0cfc6dc --- /dev/null +++ b/windows/owTools/tmextran.cpp @@ -0,0 +1,199 @@ +//--------------------------------------------------------------------------- +// Copyright (C) 1999 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. +//--------------------------------------------------------------------------- +// +// tmexnet.C - Wrapper class to hook 1-Wire Public Domain API to TMEX API +// for transport functions. +// +// Version: 3.00 +// + +#include "ownet.h" +#include + +// external TMEX variables +extern long SessionHandle[MAX_PORTNUM]; +extern "C" short far pascal TMBlockIO(long, uchar *, short); +extern "C" short far pascal TMBlockStream(long, uchar *, short); + +//-------------------------------------------------------------------------- +// The 'owBlock' transfers a block of data to and from the +// 1-Wire Net with an optional reset at the begining of communication. +// The result is returned in the same buffer. +// +// 'do_reset' - cause a owTouchReset to occure at the begining of +// communication TRUE(1) or not FALSE(0) +// 'tran_buf' - pointer to a block of unsigned +// chars of length 'TranferLength' that will be sent +// to the 1-Wire Net +// 'tran_len' - length in bytes to transfer +// Supported devices: all +// +// Returns: TRUE (1) : The optional reset returned a valid +// presence (do_reset == TRUE) or there +// was no reset required. +// FALSE (0): The reset did not return a valid prsence +// (do_reset == TRUE). +// +// The maximum tran_len is 64 +// +SMALLINT owBlock(int portnum, SMALLINT do_reset, uchar *tran_buf, SMALLINT tran_len) +{ + short rslt; + + // check for a block too big + if (tran_len > 192) + { + OWERROR(OWERROR_BLOCK_TOO_BIG); + return FALSE; + } + + // check if need to do a owTouchReset first + if (do_reset) + rslt = TMBlockIO(SessionHandle[portnum], tran_buf, (short)tran_len); + else + rslt = TMBlockStream(SessionHandle[portnum], tran_buf, (short)tran_len); + + return (rslt == tran_len); +} + +//-------------------------------------------------------------------------- +// Write a byte to an EPROM 1-Wire device. +// +// Supported devices: crc_type=0(CRC8) +// DS1982 +// crc_type=1(CRC16) +// DS1985, DS1986, DS2407 +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'write_byte' - byte to program +// 'addr' - address of byte to program +// 'write_cmd' - command used to write (0x0F reg mem, 0x55 status) +// 'crc_type' - CRC used (0 CRC8, 1 CRC16) +// 'do_access' - Flag to access device for each byte +// (0 skip access, 1 do the access) +// WARNING, only use do_access=0 if programing the NEXT +// byte immediatly after the previous byte. +// +// Returns: >=0 success, this is the resulting byte from the program +// effort +// -1 error, device not connected or program pulse voltage +// not available +// +SMALLINT owProgramByte(int portnum, SMALLINT write_byte, int addr, SMALLINT write_cmd, + SMALLINT crc_type, SMALLINT do_access) +{ + ushort lastcrc16; + uchar lastcrc8; + + // optionally access the device + if (do_access) + { + if (!owAccess(portnum)) + { + OWERROR(OWERROR_ACCESS_FAILED); + return -1; + } + + // send the write command + if (!owWriteByte(portnum,write_cmd)) + { + OWERROR(OWERROR_WRITE_BYTE_FAILED); + return -1; + } + + // send the address + if (!owWriteByte(portnum,addr & 0xFF) || !owWriteByte(portnum,addr >> 8)) + { + OWERROR(OWERROR_WRITE_BYTE_FAILED); + return -1; + } + } + + // send the data to write + if (!owWriteByte(portnum,write_byte)) + { + OWERROR(OWERROR_WRITE_BYTE_FAILED); + return -1; + } + + // read the CRC + if (crc_type == 0) + { + // calculate CRC8 + if (do_access) + { + setcrc8(portnum,0); + docrc8(portnum,(uchar)write_cmd); + docrc8(portnum,(uchar)(addr & 0xFF)); + docrc8(portnum,(uchar)(addr >> 8)); + } + else + setcrc8(portnum,(uchar)(addr & 0xFF)); + + docrc8(portnum,(uchar)write_byte); + // read and calculate the read crc + lastcrc8 = docrc8(portnum,(uchar)owReadByte(portnum)); + // crc should now be 0x00 + if (lastcrc8 != 0) + { + OWERROR(OWERROR_CRC_FAILED); + return -1; + } + } + else + { + // CRC16 + if (do_access) + { + setcrc16(portnum,0); + docrc16(portnum,(ushort)write_cmd); + docrc16(portnum,(ushort)(addr & 0xFF)); + docrc16(portnum,(ushort)(addr >> 8)); + } + else + setcrc16(portnum,(ushort)addr); + docrc16(portnum,(ushort)write_byte); + // read and calculate the read crc + docrc16(portnum,(ushort)owReadByte(portnum)); + lastcrc16 = docrc16(portnum,(ushort)owReadByte(portnum)); + // crc should now be 0xB001 + if (lastcrc16 != 0xB001) + return -1; + } + + // send the program pulse + if (!owProgramPulse(portnum)) + { + OWERROR(OWERROR_PROGRAM_PULSE_FAILED); + return -1; + } + + // read back and return the resulting byte + return owReadByte(portnum); +} + + -- 2.34.1