Works now with Windows Visual Studio C++ too
[owTools.git] / src / owInterface.cpp
index 66ea440..c08ea2d 100755 (executable)
-// 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 <unistd.h>
-#include <math.h>
-#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<uint8_t> 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<uint8_t> data) {
-       crc16=0;
-       for(uint8_t v:data) {
-               docrc16(v);
-       }
-       return crc16;
-}
-
-int owInterface::testCRC16(std::vector<uint8_t> data)  {
-       return calcCRC16(data)==0xB001;
-}
-               
-void owInterface::resetFlasher() { // go back from Bootloader
-       std::vector<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> cl;
-       std::vector<uint8_t> 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;k<maxrepeat;k++) { //repeat for readback error 
-               cl.clear();
-               cl.push_back(0xAA); //code for readback scratchpad
-               Wait_Free();
-               MatchRom(snum);
-               if (log->last()==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;k<maxrepeat;k++) { //repead for reading scratch error
-               cl.clear();
-               cl.push_back(0xAA);
-               Wait_Free();
-               MatchRom(snum);
-               if (log->last()==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<uint8_t> 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<uint8_t> 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<snum_t> found;
-       for (int k=0;k<maxrepeat;k++) {
-               cnt=0;
-               log->clear();
-               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<uint8_t> *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;i<rcount;i++) {
-               data->push_back(sendrecivByte(0xFF));
-               usleep(20);
-               
-       }
-       return 0;
-}
-
+// Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de\r
+// All rights reserved.\r
+//\r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are\r
+// met:\r
+//\r
+//  * Redistributions of source code must retain the above copyright\r
+//    notice, this list of conditions and the following disclaimer.\r
+//  * Redistributions in binary form must reproduce the above copyright\r
+//    notice, this list of conditions and the following disclaimer in the\r
+//    documentation and/or other materials provided with the\r
+//    distribution.\r
+//  * All advertising materials mentioning features or use of this\r
+//    software must display the following acknowledgement: This product\r
+//    includes software developed by tm3d.de and its contributors.\r
+//  * Neither the name of tm3d.de nor the names of its contributors may\r
+//    be used to endorse or promote products derived from this software\r
+//    without specific prior written permission.\r
+//\r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+\r
+#include "owInterface.h"\r
+#ifdef LINUX\r
+#include <unistd.h>\r
+#endif\r
+#include <math.h>\r
+#include "hexfile.h"\r
+\r
+\r
+#ifdef WIN\r
+void usleep(__int64 usec)\r
+{\r
+       HANDLE timer;\r
+       LARGE_INTEGER ft;\r
+\r
+       ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time\r
+\r
+       timer = CreateWaitableTimer(NULL, TRUE, NULL);\r
+       SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);\r
+       WaitForSingleObject(timer, INFINITE);\r
+       CloseHandle(timer);\r
+}\r
+#endif\r
+\r
+\r
+static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };\r
+static unsigned char owi_dscrc_table[] = {\r
+        0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,\r
+      157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,\r
+       35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,\r
+      190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,\r
+       70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,\r
+      219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,\r
+      101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,\r
+      248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,\r
+      140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,\r
+       17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,\r
+      175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,\r
+       50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,\r
+      202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,\r
+       87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,\r
+      233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,\r
+      116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};\r
+\r
+      \r
+uint8_t owInterface::docrc8(uint8_t value) {\r
+   // See Application Note 27\r
+   \r
+   // TEST BUILD\r
+   crc8 = owi_dscrc_table[crc8 ^ value];\r
+   return crc8;\r
+}\r
\r
+uint16_t owInterface::docrc16(uint16_t cdata) {\r
+   cdata = (cdata ^ (crc16 & 0xff)) & 0xff;\r
+   crc16 >>= 8;\r
+\r
+   if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4])\r
+     crc16 ^= 0xc001;\r
+\r
+   cdata <<= 6;\r
+   crc16   ^= cdata;\r
+   cdata <<= 1;\r
+   crc16   ^= cdata;\r
+\r
+   return crc16;\r
+               \r
+       \r
+}\r
+\r
+uint8_t owInterface::calcCRC8(std::vector<uint8_t> data) {\r
+        crc8 = 0;\r
+         for(uint8_t v: data) \r
+                       docrc8(v);\r
+       return crc8; //0 bei erfolg oder crc wenn crc nicht babei\r
+}\r
+\r
+uint16_t owInterface::calcCRC16(std::vector<uint8_t> data) {\r
+       crc16=0;\r
+       for(uint8_t v:data) {\r
+               docrc16(v);\r
+       }\r
+       return crc16;\r
+}\r
+\r
+int owInterface::testCRC16(std::vector<uint8_t> data)  {\r
+       return calcCRC16(data)==0xB001;\r
+}\r
+               \r
+void owInterface::resetFlasher() { // go back from Bootloader\r
+       std::vector<uint8_t> data;\r
+       data.push_back(0x89);\r
+       Wait_Free();\r
+       snum_t snum;\r
+       snum.num=0xfa55aa55aa55aaa3;\r
+       MatchRom(snum);\r
+       if (log->last()==OWLOG_ERROR) {Free(); return;}\r
+       Communicate(&data, 1, 0);\r
+       \r
+       Free();\r
+       if (log->last()==OWLOG_ERROR) return;\r
+       usleep(50);     \r
+}\r
+\r
+void owInterface::resetID() {\r
+       std::vector<uint8_t> data;\r
+       data.push_back(0x8B);\r
+       Wait_Free();\r
+       snum_t snum;\r
+       snum.num=0xfa55aa55aa55aaa3;\r
+       MatchRom(snum);\r
+       if (log->last()==OWLOG_ERROR) {Free(); return;}\r
+       Communicate(&data, 1, 0);\r
+       Free();\r
+}\r
+\r
+int owInterface::programmPage(int pagenr, std::vector<uint8_t> page, int pagesize) {\r
+       snum_t snum;\r
+       snum.num=0xfa55aa55aa55aaa3;\r
+//     printf("programm page %i",pagenr);\r
+       \r
+       \r
+       int diff = pagesize - page.size();\r
+       if (diff>0) {\r
+               for (int i = 0; i < (diff); i++) page.push_back(0xFF);\r
+       }\r
+       std::vector<uint8_t> cl;\r
+       std::vector<uint8_t> clb; //backup \r
+       cl.push_back(0x0F);  //code for Flashing\r
+       cl.push_back((pagenr*pagesize) & 0xFF); //adress in byte\r
+       cl.push_back((pagenr*pagesize) >> 8);\r
+       cl.insert(cl.end(),page.begin(),page.end()); //page\r
+       clb=cl;         //make backup\r
+       Wait_Free();\r
+       MatchRom(snum); \r
+       if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
+       Communicate(&cl, 3+pagesize, 0); //send (resive page)\r
+       Free();\r
+       if (log->last()==OWLOG_ERROR) return -3;\r
+       int err=0;\r
+       for(int k=0;k<maxrepeat;k++) { //repeat for readback error \r
+               cl.clear();\r
+               cl.push_back(0xAA); //code for readback scratchpad\r
+               Wait_Free();\r
+               MatchRom(snum);\r
+               if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
+               Communicate(&cl, 1, 2+pagesize); // read back scratchpad\r
+               Free();\r
+               if (log->last()==OWLOG_ERROR) return -3;\r
+               err=0;\r
+               for (int i = 0; i < pagesize+2; i++) {\r
+                       if (clb[i + 1] != cl[i + 1]) {  //test\r
+                               usleep(50000);\r
+                               err=1;\r
+                               break;\r
+                       }\r
+               }\r
+               if (err==0) break;\r
+       }\r
+       if (err==1) {\r
+               usleep(50000);\r
+               return -1;  //error in scratchpad\r
+       }\r
+       cl.clear();\r
+       cl.push_back(0x55);//Programm\r
+       Wait_Free();\r
+       MatchRom(snum);\r
+       if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
+       Communicate(&cl, 1, 0);\r
+       Free();\r
+       if (log->last()==OWLOG_ERROR) return -3;\r
+       usleep(50000);\r
+       cl.clear();\r
+       cl.push_back(0xB8);//recal programm memory to scratchpad\r
+       cl.push_back((pagenr*pagesize) & 0xFF);\r
+       cl.push_back((pagenr*pagesize) >> 8);\r
+       Wait_Free();\r
+       MatchRom(snum);\r
+       if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
+       Communicate(&cl, 3, 0); //Copy programm memory to scratch\r
+       Free();\r
+       if (log->last()==OWLOG_ERROR) return -3;\r
+       usleep(50000);\r
+       \r
+       for(int k=0;k<maxrepeat;k++) { //repead for reading scratch error\r
+               cl.clear();\r
+               cl.push_back(0xAA);\r
+               Wait_Free();\r
+               MatchRom(snum);\r
+               if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
+               Communicate(&cl, 1, 2 + pagesize); //Reread scratch\r
+               Free();\r
+               if (log->last()==OWLOG_ERROR) return -3;\r
+               err=0;\r
+               for (int i = 0; i < pagesize + 2; i++) {\r
+                       if (cl[i + 1] != clb[i + 1]) {\r
+                               usleep(50000);\r
+                               err=1;\r
+                               break;\r
+                       }\r
+               }\r
+               if (err==0) break;\r
+       }\r
+       if (err==1) {\r
+               usleep(50000);\r
+               return -2;\r
+       }\r
+\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+int owInterface::flashHEXFile(std::string filename,snum_t dev,int resetid,int progress) {\r
+       log->set(OWLOG_INFO,"Open Hex-File: %s",filename.c_str());\r
+       hexFile *hf=new hexFile(filename);\r
+       if (hf->lastError==1) {log->set(OWLOG_ERROR,"CRC Error in HEX-File %s",filename.c_str());return -1;}\r
+       if (hf->lastError==2) {log->set(OWLOG_ERROR,"Error interpreting  HEX-File %s",filename.c_str());return -2;}\r
+       if (hf->lastError==3) {log->set(OWLOG_ERROR,"File could not be opened: %s",filename.c_str());return -3;}\r
+       unsigned int blcount=hf->getBlockCount(64);\r
+       if (blcount>118) {\r
+               log->set(OWLOG_ERROR,"Code to big, max 7552 Byte allowed (118 Pages). Code has %i pages!",blcount);\r
+               return -5;\r
+       }\r
+       log->set(OWLOG_INFO,"Try to start Bootloader on device %llX",dev.num);\r
+       int r=maxrepeat+1;\r
+       int found;\r
+       do {\r
+               log->clear();\r
+               std::vector<uint8_t> data;\r
+               MatchRom(dev);\r
+               data.push_back(0x88);\r
+               Communicate(&data, 1, 0);\r
+               MatchRom(dev);\r
+               Communicate(&data, 1, 0);\r
+               MatchRom(dev);\r
+               Communicate(&data, 1, 0);\r
+#ifdef LINUX\r
+               sleep(3);\r
+#endif\r
+#ifdef WIN\r
+               Sleep(3000);\r
+#endif\r
+               log->set(OWLOG_INFO,"Search for Bootloader...");\r
+               log->setLogLevel(OWLOG_WARNING);\r
+               Find();\r
+               log->setLogLevel(OWLOG_INFO);\r
+               found=0;\r
+               for (owDevice* dev :devices) {\r
+                       if (dev->getNum().num==0xfa55aa55aa55aaa3) {\r
+                               found=1;\r
+                               break;\r
+                       }       \r
+               }\r
+               if (found==0) log->set(OWLOG_WARNING,"Bootloader not found");\r
+               r--;\r
+       }       while ((found==0)&&(r>0));\r
+       if (r==0) {\r
+               log->set(OWLOG_ERROR,"Can not start Bootloader on this device %llX",dev.num);\r
+               return -4;\r
+       }\r
+       log->set(OWLOG_INFO,"Start Programm %i Pages",blcount);\r
+       int rp=0;\r
+       int er=0;\r
+       unsigned int i =0;\r
+       for ( i= 0; i < blcount; i++) {\r
+               std::vector<uint8_t> blk = hf->getBlock(i*64, 64);\r
+               int errc = maxrepeat*5;\r
+               while (errc != 0) {\r
+                       log->clear();\r
+                       if (programmPage(i, blk, 64) >= 0) {\r
+                               if (progress) {printf("#");fflush(stdout);} \r
+                               break;\r
+                       }\r
+                       \r
+                       errc -= 1;\r
+                       rp++;\r
+                       if (progress) {printf("\033[1;31m#\033[0m");fflush(stdout);} //printf("\033[1;33m%s\033[0m\n",s);\r
+                                       \r
+               }\r
+      if (errc == 0) { er++; break; }\r
+       }\r
+       if (progress) printf("\n");\r
+       if (er != 0) {\r
+               log->set(OWLOG_ERROR,"ERROR Writing Program Memory!!!");\r
+               if (i==0) {\r
+                       log->set(OWLOG_ERROR,"If Fuse SELFPRGEN enabled?");\r
+               } else\r
+                       log->set(OWLOG_ERROR,"Maybe 1-Wire Connection is verry bad!");\r
+       } else {\r
+               if (resetid) {\r
+                       log->set(OWLOG_INFO,"Set 1-Wire ID to ID in hexfile...",blcount); \r
+                       resetID();\r
+#ifdef LINUX\r
+                       sleep(3);\r
+#endif\r
+#ifdef WIN\r
+                       Sleep(3000);\r
+#endif\r
+                       resetID();      \r
+#ifdef LINUX\r
+                       sleep(3);\r
+#endif\r
+#ifdef WIN\r
+                       Sleep(3000);\r
+#endif\r
+               }\r
+       }       \r
+       \r
+       log->set(OWLOG_INFO,"Back from bootloader to normal device...",blcount); \r
+       \r
+       \r
+       resetFlasher();\r
+#ifdef LINUX\r
+       sleep(1);       \r
+#endif\r
+#ifdef WIN\r
+       Sleep(1000);\r
+#endif\r
+       resetFlasher();\r
+#ifdef LINUX\r
+       sleep(3);\r
+#endif\r
+#ifdef WIN\r
+       Sleep(3000);\r
+#endif\r
+\r
+       Find();\r
+       \r
+       return 1;\r
+               \r
+}\r
+\r
+\r
+int owInterface::owSearch() {\r
+       int id_bit_number;\r
+       int last_zero, rom_byte_number, search_result;\r
+       int id_bit, cmp_id_bit;\r
+       unsigned char rom_byte_mask, search_direction;\r
+\r
+       // initialize for search\r
+       id_bit_number = 1;\r
+       last_zero = 0;\r
+       rom_byte_number = 0;\r
+       rom_byte_mask = 1;\r
+       search_result = 0;\r
+       crc8 = 0;\r
+\r
+       // if the last call was not the last one\r
+       if (!LastDeviceFlag) {\r
+               // 1-Wire reset\r
+               Wait_Free();\r
+               if (!Reset()) {\r
+        // reset the search\r
+                       LastDiscrepancy = 0;\r
+                       LastDeviceFlag = FALSE;\r
+                       LastFamilyDiscrepancy = 0;\r
+                       Free();\r
+                       return FALSE;\r
+               }\r
+               if (log->last()==OWLOG_ERROR) return -3;\r
+               // issue the search command \r
+               sendrecivByte(0xF0);  \r
+               if (log->last()==OWLOG_ERROR) return -3;\r
+\r
+               // loop to do the search\r
+               do {\r
+                       // read a bit and its complement\r
+                       id_bit = sendrecivBit(1);\r
+                       cmp_id_bit = sendrecivBit(1);\r
+                       // check for no devices on 1-wire\r
+                       if ((id_bit == 1) && (cmp_id_bit == 1))\r
+                               break;\r
+                       else {\r
+                               // all devices coupled have 0 or 1\r
+                               if (id_bit != cmp_id_bit)\r
+                                       search_direction = id_bit;  // bit write value for search\r
+                               else  {\r
+                                       // if this discrepancy if before the Last Discrepancy\r
+                                       // on a previous next then pick the same as last time\r
+                                       if (id_bit_number < LastDiscrepancy)\r
+                                               search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);\r
+                                       else\r
+                                               // if equal to last pick 1, if not then pick 0\r
+                                               search_direction = (id_bit_number == LastDiscrepancy);\r
+\r
+                                       // if 0 was picked then record its position in LastZero\r
+                                       if (search_direction == 0) {\r
+                                               last_zero = id_bit_number;\r
+                                               // check for Last discrepancy in family\r
+                                               if (last_zero < 9)\r
+                                                       LastFamilyDiscrepancy = last_zero;\r
+                                       }\r
+                               }\r
+                               // set or clear the bit in the ROM byte rom_byte_number\r
+                               // with mask rom_byte_mask\r
+                               if (search_direction == 1)\r
+                                       ROM_NO[rom_byte_number] |= rom_byte_mask;\r
+                               else\r
+                                       ROM_NO[rom_byte_number] &= ~rom_byte_mask;\r
+                               // serial number search direction write bit\r
+                               sendrecivBit(search_direction);\r
+                               //usleep(50);\r
+\r
+                               // increment the byte counter id_bit_number\r
+                               // and shift the mask rom_byte_mask\r
+                               id_bit_number++;\r
+                               rom_byte_mask <<= 1;\r
+\r
+                               // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask\r
+                               if (rom_byte_mask == 0) {\r
+                                       docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC\r
+                                       rom_byte_number++;\r
+                                       rom_byte_mask = 1;\r
+                               }\r
+                       }\r
+               }\r
+               while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7\r
+               // if the search was successful then\r
+               if (!((id_bit_number < 65) || (crc8 != 0))) {\r
+                       // search successful so set LastDiscrepancy,LastDeviceFlag,search_result\r
+                       LastDiscrepancy = last_zero;\r
+                       // check for last device\r
+                       if (LastDiscrepancy == 0)\r
+                       LastDeviceFlag = TRUE;\r
+                       search_result = TRUE;\r
+               } else {\r
+                       log->set(OWLOG_WARNING,"CRC Error on Search Rom");\r
+               }\r
+       }\r
+\r
+               // if no device found then reset counters so next 'search' will be like a first\r
+       if (!search_result || !ROM_NO[0]) {\r
+               LastDiscrepancy = 0;\r
+               LastDeviceFlag = FALSE;\r
+               LastFamilyDiscrepancy = 0;\r
+               search_result = FALSE;\r
+       }\r
+       Free();\r
+       return search_result;\r
+       \r
+\r
+}\r
+void owInterface::Clean() {\r
+       for (owDevice* dev :devices) {\r
+               delete dev;\r
+       }\r
+       devices.clear();\r
+       device_nums.clear();\r
+       devices_changed=1;\r
+}\r
+\r
+int owInterface::Find() {\r
+       int rslt,i,cnt=0;\r
+       std::vector<snum_t> found;\r
+       for (int k=0;k<maxrepeat;k++) {\r
+               cnt=0;\r
+               log->clear();\r
+               found.clear();\r
+               rslt = owFirst();\r
+               if (log->last()>=OWLOG_WARNING) continue;\r
+               while (rslt){\r
+                       snum_t snum;\r
+                       // print device found\r
+                       for (i = 7; i >= 0; i--)\r
+                               snum.byte[i]=ROM_NO[i];\r
+                               //printf("%02X", ROM_NO[i]);\r
+                               //printf("  %d\n",++cnt);\r
+                       found.push_back(snum);\r
+                       cnt++;\r
+                       log->clear();\r
+                       rslt = owNext();\r
+                       if (log->last()>=OWLOG_WARNING) {rslt=-1;break;}\r
+               }\r
+               if (rslt==0) break;\r
+       \r
+       }\r
+       if (log->last()>=OWLOG_WARNING) { \r
+               log->set(OWLOG_ERROR,"To much Errors while search rom"); \r
+               //Alles so lassen wie es ist?           \r
+               return 0;\r
+       }\r
+       for(snum_t snum:found) {\r
+               int snum_found=0;\r
+               //Device schon forhanden?\r
+               for(snum_t d : device_nums) {\r
+                       if (snum.num==d.num) {snum_found=1;break;}\r
+               }\r
+               //nein, dann anlegen.\r
+               if (!snum_found) {\r
+                       log->set(OWLOG_INFO,"new dev %llx\n",snum.num);\r
+                       devices_changed=1;\r
+                       device_nums.push_back(snum);\r
+                       owDevice *d=NULL;\r
+                       \r
+                       switch (snum.byte[0]) {\r
+                               case 0x28:d=new owDeviceDS18B20(this,snum);break;\r
+                               case 0x26:d=new owDeviceDS2438(this,snum);break;\r
+                               case 0x20:d=new owDeviceDS2450(this,snum);break;\r
+                               case 0x1D:d=new owDeviceDS2423(this,snum);break;\r
+                               default:d=new owDevice(this,snum);\r
+                       }\r
+                       devices.push_back(d);\r
+                       if (d!=NULL)    {d->readConfig();}\r
+               }\r
+       }\r
+       //Pruefe nach nicht mehr vorhandenen devices\r
+       int dpos=0;\r
+       for(snum_t d:device_nums) {\r
+               int snum_found=0;\r
+               for(snum_t fd:found) {\r
+                       if (fd.num==d.num) {snum_found=1;break;}\r
+               }\r
+               //Device nicht gefunden, vieleicht nur Fehler?\r
+               if (!snum_found) {\r
+                       devices[dpos]->lastfound++;\r
+                       log->set(OWLOG_INFO,"%llx not found %i times \n",device_nums[dpos].num,devices[dpos]->lastfound); \r
+                       \r
+                       if (devices[dpos]->lastfound>2) {\r
+\r
+                               log->set(OWLOG_INFO,"del device %llx (pos %i)\n",device_nums[dpos].num,dpos);\r
+                       \r
+                               devices_changed=1;\r
+                               delete devices[dpos];\r
+                               device_nums.erase(device_nums.begin()+dpos);\r
+                               devices.erase(devices.begin()+dpos);    \r
+                       //printf("new length %i\n",devices.size());\r
+                               dpos--;\r
+                       } \r
+\r
+               } else {\r
+                       devices[dpos]->lastfound=0;\r
+               }\r
+               dpos++;\r
+               \r
+       }       \r
+       return cnt;     \r
+}\r
+\r
+int owInterface::MatchRom(snum_t snum) {\r
+       Reset();\r
+/*     sendrecivByte(0x55);\r
+       usleep(20);\r
+       for(int i=0;i<8;i++) {\r
+               sendrecivByte(snum.byte[i]); \r
+               usleep(20);\r
+       }\r
+       if (log->last()>OWLOG_WARNING) return 0;*/\r
+       std::vector<uint8_t> cl;\r
+       cl.push_back(0x55);  //code for Flashing\r
+       for (int i = 0; i<8; i++) {\r
+               cl.push_back(snum.byte[i]);\r
+       }\r
+       Communicate(&cl, 9, 0);\r
+\r
+       return 1;\r
+}\r
+int owInterface::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {\r
+       int i=0;\r
+       data->resize(scount);\r
+       for(uint8_t v:*data) {\r
+               (*data)[i]=sendrecivByte(v);i++;\r
+               usleep(20);\r
+       }\r
+       for(i=0;i<rcount;i++) {\r
+               data->push_back(sendrecivByte(0xFF));\r
+               usleep(20);\r
+               \r
+       }\r
+       return 0;\r
+}\r
+\r