X-Git-Url: http://git.smho.de/gw/?p=owTools.git;a=blobdiff_plain;f=src%2FowInterface.cpp;fp=src%2FowInterface.cpp;h=c08ea2d8a8ebb1aebac720e6dcade876dd02195a;hp=66ea440243e172b2102c361dd0c3d83eecec5f68;hb=1a6465a924428af072a8eb5e75ee547c394f4d8e;hpb=039b202e5c68834801d23e22eecc7cae2879ea83 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; +} +