Works now with Windows Visual Studio C++ too
[owTools.git] / src / owInterface.cpp
1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de\r
2 // All rights reserved.\r
3 //\r
4 // Redistribution and use in source and binary forms, with or without\r
5 // modification, are permitted provided that the following conditions are\r
6 // met:\r
7 //\r
8 //  * Redistributions of source code must retain the above copyright\r
9 //    notice, this list of conditions and the following disclaimer.\r
10 //  * Redistributions in binary form must reproduce the above copyright\r
11 //    notice, this list of conditions and the following disclaimer in the\r
12 //    documentation and/or other materials provided with the\r
13 //    distribution.\r
14 //  * All advertising materials mentioning features or use of this\r
15 //    software must display the following acknowledgement: This product\r
16 //    includes software developed by tm3d.de and its contributors.\r
17 //  * Neither the name of tm3d.de nor the names of its contributors may\r
18 //    be used to endorse or promote products derived from this software\r
19 //    without specific prior written permission.\r
20 //\r
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
32 \r
33 \r
34 #include "owInterface.h"\r
35 #ifdef LINUX\r
36 #include <unistd.h>\r
37 #endif\r
38 #include <math.h>\r
39 #include "hexfile.h"\r
40 \r
41 \r
42 #ifdef WIN\r
43 void usleep(__int64 usec)\r
44 {\r
45         HANDLE timer;\r
46         LARGE_INTEGER ft;\r
47 \r
48         ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time\r
49 \r
50         timer = CreateWaitableTimer(NULL, TRUE, NULL);\r
51         SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);\r
52         WaitForSingleObject(timer, INFINITE);\r
53         CloseHandle(timer);\r
54 }\r
55 #endif\r
56 \r
57 \r
58 static short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };\r
59 static unsigned char owi_dscrc_table[] = {\r
60         0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,\r
61       157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,\r
62        35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,\r
63       190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,\r
64        70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,\r
65       219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,\r
66       101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,\r
67       248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,\r
68       140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,\r
69        17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,\r
70       175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,\r
71        50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,\r
72       202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,\r
73        87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,\r
74       233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,\r
75       116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};\r
76 \r
77       \r
78 uint8_t owInterface::docrc8(uint8_t value) {\r
79    // See Application Note 27\r
80    \r
81    // TEST BUILD\r
82    crc8 = owi_dscrc_table[crc8 ^ value];\r
83    return crc8;\r
84 }\r
85  \r
86 uint16_t owInterface::docrc16(uint16_t cdata) {\r
87    cdata = (cdata ^ (crc16 & 0xff)) & 0xff;\r
88    crc16 >>= 8;\r
89 \r
90    if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4])\r
91      crc16 ^= 0xc001;\r
92 \r
93    cdata <<= 6;\r
94    crc16   ^= cdata;\r
95    cdata <<= 1;\r
96    crc16   ^= cdata;\r
97 \r
98    return crc16;\r
99                 \r
100         \r
101 }\r
102 \r
103 uint8_t owInterface::calcCRC8(std::vector<uint8_t> data) {\r
104          crc8 = 0;\r
105           for(uint8_t v: data) \r
106                         docrc8(v);\r
107         return crc8; //0 bei erfolg oder crc wenn crc nicht babei\r
108 }\r
109 \r
110 uint16_t owInterface::calcCRC16(std::vector<uint8_t> data) {\r
111         crc16=0;\r
112         for(uint8_t v:data) {\r
113                 docrc16(v);\r
114         }\r
115         return crc16;\r
116 }\r
117 \r
118 int owInterface::testCRC16(std::vector<uint8_t> data)  {\r
119         return calcCRC16(data)==0xB001;\r
120 }\r
121                 \r
122 void owInterface::resetFlasher() { // go back from Bootloader\r
123         std::vector<uint8_t> data;\r
124         data.push_back(0x89);\r
125         Wait_Free();\r
126         snum_t snum;\r
127         snum.num=0xfa55aa55aa55aaa3;\r
128         MatchRom(snum);\r
129         if (log->last()==OWLOG_ERROR) {Free(); return;}\r
130         Communicate(&data, 1, 0);\r
131         \r
132         Free();\r
133         if (log->last()==OWLOG_ERROR) return;\r
134         usleep(50);     \r
135 }\r
136 \r
137 void owInterface::resetID() {\r
138         std::vector<uint8_t> data;\r
139         data.push_back(0x8B);\r
140         Wait_Free();\r
141         snum_t snum;\r
142         snum.num=0xfa55aa55aa55aaa3;\r
143         MatchRom(snum);\r
144         if (log->last()==OWLOG_ERROR) {Free(); return;}\r
145         Communicate(&data, 1, 0);\r
146         Free();\r
147 }\r
148 \r
149 int owInterface::programmPage(int pagenr, std::vector<uint8_t> page, int pagesize) {\r
150         snum_t snum;\r
151         snum.num=0xfa55aa55aa55aaa3;\r
152 //      printf("programm page %i",pagenr);\r
153         \r
154         \r
155         int diff = pagesize - page.size();\r
156         if (diff>0) {\r
157                 for (int i = 0; i < (diff); i++) page.push_back(0xFF);\r
158         }\r
159         std::vector<uint8_t> cl;\r
160         std::vector<uint8_t> clb; //backup \r
161         cl.push_back(0x0F);  //code for Flashing\r
162         cl.push_back((pagenr*pagesize) & 0xFF); //adress in byte\r
163         cl.push_back((pagenr*pagesize) >> 8);\r
164         cl.insert(cl.end(),page.begin(),page.end()); //page\r
165         clb=cl;         //make backup\r
166         Wait_Free();\r
167         MatchRom(snum); \r
168         if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
169         Communicate(&cl, 3+pagesize, 0); //send (resive page)\r
170         Free();\r
171         if (log->last()==OWLOG_ERROR) return -3;\r
172         int err=0;\r
173         for(int k=0;k<maxrepeat;k++) { //repeat for readback error \r
174                 cl.clear();\r
175                 cl.push_back(0xAA); //code for readback scratchpad\r
176                 Wait_Free();\r
177                 MatchRom(snum);\r
178                 if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
179                 Communicate(&cl, 1, 2+pagesize); // read back scratchpad\r
180                 Free();\r
181                 if (log->last()==OWLOG_ERROR) return -3;\r
182                 err=0;\r
183                 for (int i = 0; i < pagesize+2; i++) {\r
184                         if (clb[i + 1] != cl[i + 1]) {  //test\r
185                                 usleep(50000);\r
186                                 err=1;\r
187                                 break;\r
188                         }\r
189                 }\r
190                 if (err==0) break;\r
191         }\r
192         if (err==1) {\r
193                 usleep(50000);\r
194                 return -1;  //error in scratchpad\r
195         }\r
196         cl.clear();\r
197         cl.push_back(0x55);//Programm\r
198         Wait_Free();\r
199         MatchRom(snum);\r
200         if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
201         Communicate(&cl, 1, 0);\r
202         Free();\r
203         if (log->last()==OWLOG_ERROR) return -3;\r
204         usleep(50000);\r
205         cl.clear();\r
206         cl.push_back(0xB8);//recal programm memory to scratchpad\r
207         cl.push_back((pagenr*pagesize) & 0xFF);\r
208         cl.push_back((pagenr*pagesize) >> 8);\r
209         Wait_Free();\r
210         MatchRom(snum);\r
211         if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
212         Communicate(&cl, 3, 0); //Copy programm memory to scratch\r
213         Free();\r
214         if (log->last()==OWLOG_ERROR) return -3;\r
215         usleep(50000);\r
216         \r
217         for(int k=0;k<maxrepeat;k++) { //repead for reading scratch error\r
218                 cl.clear();\r
219                 cl.push_back(0xAA);\r
220                 Wait_Free();\r
221                 MatchRom(snum);\r
222                 if (log->last()==OWLOG_ERROR) {Free();return -3;}\r
223                 Communicate(&cl, 1, 2 + pagesize); //Reread scratch\r
224                 Free();\r
225                 if (log->last()==OWLOG_ERROR) return -3;\r
226                 err=0;\r
227                 for (int i = 0; i < pagesize + 2; i++) {\r
228                         if (cl[i + 1] != clb[i + 1]) {\r
229                                 usleep(50000);\r
230                                 err=1;\r
231                                 break;\r
232                         }\r
233                 }\r
234                 if (err==0) break;\r
235         }\r
236         if (err==1) {\r
237                 usleep(50000);\r
238                 return -2;\r
239         }\r
240 \r
241 \r
242         return 0;\r
243 }\r
244 \r
245 \r
246 int owInterface::flashHEXFile(std::string filename,snum_t dev,int resetid,int progress) {\r
247         log->set(OWLOG_INFO,"Open Hex-File: %s",filename.c_str());\r
248         hexFile *hf=new hexFile(filename);\r
249         if (hf->lastError==1) {log->set(OWLOG_ERROR,"CRC Error in HEX-File %s",filename.c_str());return -1;}\r
250         if (hf->lastError==2) {log->set(OWLOG_ERROR,"Error interpreting  HEX-File %s",filename.c_str());return -2;}\r
251         if (hf->lastError==3) {log->set(OWLOG_ERROR,"File could not be opened: %s",filename.c_str());return -3;}\r
252         unsigned int blcount=hf->getBlockCount(64);\r
253         if (blcount>118) {\r
254                 log->set(OWLOG_ERROR,"Code to big, max 7552 Byte allowed (118 Pages). Code has %i pages!",blcount);\r
255                 return -5;\r
256         }\r
257         log->set(OWLOG_INFO,"Try to start Bootloader on device %llX",dev.num);\r
258         int r=maxrepeat+1;\r
259         int found;\r
260         do {\r
261                 log->clear();\r
262                 std::vector<uint8_t> data;\r
263                 MatchRom(dev);\r
264                 data.push_back(0x88);\r
265                 Communicate(&data, 1, 0);\r
266                 MatchRom(dev);\r
267                 Communicate(&data, 1, 0);\r
268                 MatchRom(dev);\r
269                 Communicate(&data, 1, 0);\r
270 #ifdef LINUX\r
271                 sleep(3);\r
272 #endif\r
273 #ifdef WIN\r
274                 Sleep(3000);\r
275 #endif\r
276                 log->set(OWLOG_INFO,"Search for Bootloader...");\r
277                 log->setLogLevel(OWLOG_WARNING);\r
278                 Find();\r
279                 log->setLogLevel(OWLOG_INFO);\r
280                 found=0;\r
281                 for (owDevice* dev :devices) {\r
282                         if (dev->getNum().num==0xfa55aa55aa55aaa3) {\r
283                                 found=1;\r
284                                 break;\r
285                         }       \r
286                 }\r
287                 if (found==0) log->set(OWLOG_WARNING,"Bootloader not found");\r
288                 r--;\r
289         }       while ((found==0)&&(r>0));\r
290         if (r==0) {\r
291                 log->set(OWLOG_ERROR,"Can not start Bootloader on this device %llX",dev.num);\r
292                 return -4;\r
293         }\r
294         log->set(OWLOG_INFO,"Start Programm %i Pages",blcount);\r
295         int rp=0;\r
296         int er=0;\r
297         unsigned int i =0;\r
298         for ( i= 0; i < blcount; i++) {\r
299                 std::vector<uint8_t> blk = hf->getBlock(i*64, 64);\r
300                 int errc = maxrepeat*5;\r
301                 while (errc != 0) {\r
302                         log->clear();\r
303                         if (programmPage(i, blk, 64) >= 0) {\r
304                                 if (progress) {printf("#");fflush(stdout);} \r
305                                 break;\r
306                         }\r
307                         \r
308                         errc -= 1;\r
309                         rp++;\r
310                         if (progress) {printf("\033[1;31m#\033[0m");fflush(stdout);} //printf("\033[1;33m%s\033[0m\n",s);\r
311                                         \r
312                 }\r
313       if (errc == 0) { er++; break; }\r
314         }\r
315         if (progress) printf("\n");\r
316         if (er != 0) {\r
317                 log->set(OWLOG_ERROR,"ERROR Writing Program Memory!!!");\r
318                 if (i==0) {\r
319                         log->set(OWLOG_ERROR,"If Fuse SELFPRGEN enabled?");\r
320                 } else\r
321                         log->set(OWLOG_ERROR,"Maybe 1-Wire Connection is verry bad!");\r
322         } else {\r
323                 if (resetid) {\r
324                         log->set(OWLOG_INFO,"Set 1-Wire ID to ID in hexfile...",blcount); \r
325                         resetID();\r
326 #ifdef LINUX\r
327                         sleep(3);\r
328 #endif\r
329 #ifdef WIN\r
330                         Sleep(3000);\r
331 #endif\r
332                         resetID();      \r
333 #ifdef LINUX\r
334                         sleep(3);\r
335 #endif\r
336 #ifdef WIN\r
337                         Sleep(3000);\r
338 #endif\r
339                 }\r
340         }       \r
341         \r
342         log->set(OWLOG_INFO,"Back from bootloader to normal device...",blcount); \r
343         \r
344         \r
345         resetFlasher();\r
346 #ifdef LINUX\r
347         sleep(1);       \r
348 #endif\r
349 #ifdef WIN\r
350         Sleep(1000);\r
351 #endif\r
352         resetFlasher();\r
353 #ifdef LINUX\r
354         sleep(3);\r
355 #endif\r
356 #ifdef WIN\r
357         Sleep(3000);\r
358 #endif\r
359 \r
360         Find();\r
361         \r
362         return 1;\r
363                 \r
364 }\r
365 \r
366 \r
367 int owInterface::owSearch() {\r
368         int id_bit_number;\r
369         int last_zero, rom_byte_number, search_result;\r
370         int id_bit, cmp_id_bit;\r
371         unsigned char rom_byte_mask, search_direction;\r
372 \r
373         // initialize for search\r
374         id_bit_number = 1;\r
375         last_zero = 0;\r
376         rom_byte_number = 0;\r
377         rom_byte_mask = 1;\r
378         search_result = 0;\r
379         crc8 = 0;\r
380 \r
381         // if the last call was not the last one\r
382         if (!LastDeviceFlag) {\r
383                 // 1-Wire reset\r
384                 Wait_Free();\r
385                 if (!Reset()) {\r
386         // reset the search\r
387                         LastDiscrepancy = 0;\r
388                         LastDeviceFlag = FALSE;\r
389                         LastFamilyDiscrepancy = 0;\r
390                         Free();\r
391                         return FALSE;\r
392                 }\r
393                 if (log->last()==OWLOG_ERROR) return -3;\r
394                 // issue the search command \r
395                 sendrecivByte(0xF0);  \r
396                 if (log->last()==OWLOG_ERROR) return -3;\r
397 \r
398                 // loop to do the search\r
399                 do {\r
400                         // read a bit and its complement\r
401                         id_bit = sendrecivBit(1);\r
402                         cmp_id_bit = sendrecivBit(1);\r
403                         // check for no devices on 1-wire\r
404                         if ((id_bit == 1) && (cmp_id_bit == 1))\r
405                                 break;\r
406                         else {\r
407                                 // all devices coupled have 0 or 1\r
408                                 if (id_bit != cmp_id_bit)\r
409                                         search_direction = id_bit;  // bit write value for search\r
410                                 else  {\r
411                                         // if this discrepancy if before the Last Discrepancy\r
412                                         // on a previous next then pick the same as last time\r
413                                         if (id_bit_number < LastDiscrepancy)\r
414                                                 search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);\r
415                                         else\r
416                                                 // if equal to last pick 1, if not then pick 0\r
417                                                 search_direction = (id_bit_number == LastDiscrepancy);\r
418 \r
419                                         // if 0 was picked then record its position in LastZero\r
420                                         if (search_direction == 0) {\r
421                                                 last_zero = id_bit_number;\r
422                                                 // check for Last discrepancy in family\r
423                                                 if (last_zero < 9)\r
424                                                         LastFamilyDiscrepancy = last_zero;\r
425                                         }\r
426                                 }\r
427                                 // set or clear the bit in the ROM byte rom_byte_number\r
428                                 // with mask rom_byte_mask\r
429                                 if (search_direction == 1)\r
430                                         ROM_NO[rom_byte_number] |= rom_byte_mask;\r
431                                 else\r
432                                         ROM_NO[rom_byte_number] &= ~rom_byte_mask;\r
433                                 // serial number search direction write bit\r
434                                 sendrecivBit(search_direction);\r
435                                 //usleep(50);\r
436 \r
437                                 // increment the byte counter id_bit_number\r
438                                 // and shift the mask rom_byte_mask\r
439                                 id_bit_number++;\r
440                                 rom_byte_mask <<= 1;\r
441 \r
442                                 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask\r
443                                 if (rom_byte_mask == 0) {\r
444                                         docrc8(ROM_NO[rom_byte_number]);  // accumulate the CRC\r
445                                         rom_byte_number++;\r
446                                         rom_byte_mask = 1;\r
447                                 }\r
448                         }\r
449                 }\r
450                 while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7\r
451                 // if the search was successful then\r
452                 if (!((id_bit_number < 65) || (crc8 != 0))) {\r
453                         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result\r
454                         LastDiscrepancy = last_zero;\r
455                         // check for last device\r
456                         if (LastDiscrepancy == 0)\r
457                         LastDeviceFlag = TRUE;\r
458                         search_result = TRUE;\r
459                 } else {\r
460                         log->set(OWLOG_WARNING,"CRC Error on Search Rom");\r
461                 }\r
462         }\r
463 \r
464                 // if no device found then reset counters so next 'search' will be like a first\r
465         if (!search_result || !ROM_NO[0]) {\r
466                 LastDiscrepancy = 0;\r
467                 LastDeviceFlag = FALSE;\r
468                 LastFamilyDiscrepancy = 0;\r
469                 search_result = FALSE;\r
470         }\r
471         Free();\r
472         return search_result;\r
473         \r
474 \r
475 }\r
476 void owInterface::Clean() {\r
477         for (owDevice* dev :devices) {\r
478                 delete dev;\r
479         }\r
480         devices.clear();\r
481         device_nums.clear();\r
482         devices_changed=1;\r
483 }\r
484 \r
485 int owInterface::Find() {\r
486         int rslt,i,cnt=0;\r
487         std::vector<snum_t> found;\r
488         for (int k=0;k<maxrepeat;k++) {\r
489                 cnt=0;\r
490                 log->clear();\r
491                 found.clear();\r
492                 rslt = owFirst();\r
493                 if (log->last()>=OWLOG_WARNING) continue;\r
494                 while (rslt){\r
495                         snum_t snum;\r
496                         // print device found\r
497                         for (i = 7; i >= 0; i--)\r
498                                 snum.byte[i]=ROM_NO[i];\r
499                                 //printf("%02X", ROM_NO[i]);\r
500                                 //printf("  %d\n",++cnt);\r
501                         found.push_back(snum);\r
502                         cnt++;\r
503                         log->clear();\r
504                         rslt = owNext();\r
505                         if (log->last()>=OWLOG_WARNING) {rslt=-1;break;}\r
506                 }\r
507                 if (rslt==0) break;\r
508         \r
509         }\r
510         if (log->last()>=OWLOG_WARNING) { \r
511                 log->set(OWLOG_ERROR,"To much Errors while search rom"); \r
512                 //Alles so lassen wie es ist?           \r
513                 return 0;\r
514         }\r
515         for(snum_t snum:found) {\r
516                 int snum_found=0;\r
517                 //Device schon forhanden?\r
518                 for(snum_t d : device_nums) {\r
519                         if (snum.num==d.num) {snum_found=1;break;}\r
520                 }\r
521                 //nein, dann anlegen.\r
522                 if (!snum_found) {\r
523                         log->set(OWLOG_INFO,"new dev %llx\n",snum.num);\r
524                         devices_changed=1;\r
525                         device_nums.push_back(snum);\r
526                         owDevice *d=NULL;\r
527                         \r
528                         switch (snum.byte[0]) {\r
529                                 case 0x28:d=new owDeviceDS18B20(this,snum);break;\r
530                                 case 0x26:d=new owDeviceDS2438(this,snum);break;\r
531                                 case 0x20:d=new owDeviceDS2450(this,snum);break;\r
532                                 case 0x1D:d=new owDeviceDS2423(this,snum);break;\r
533                                 default:d=new owDevice(this,snum);\r
534                         }\r
535                         devices.push_back(d);\r
536                         if (d!=NULL)    {d->readConfig();}\r
537                 }\r
538         }\r
539         //Pruefe nach nicht mehr vorhandenen devices\r
540         int dpos=0;\r
541         for(snum_t d:device_nums) {\r
542                 int snum_found=0;\r
543                 for(snum_t fd:found) {\r
544                         if (fd.num==d.num) {snum_found=1;break;}\r
545                 }\r
546                 //Device nicht gefunden, vieleicht nur Fehler?\r
547                 if (!snum_found) {\r
548                         devices[dpos]->lastfound++;\r
549                         log->set(OWLOG_INFO,"%llx not found %i times \n",device_nums[dpos].num,devices[dpos]->lastfound); \r
550                         \r
551                         if (devices[dpos]->lastfound>2) {\r
552 \r
553                                 log->set(OWLOG_INFO,"del device %llx (pos %i)\n",device_nums[dpos].num,dpos);\r
554                         \r
555                                 devices_changed=1;\r
556                                 delete devices[dpos];\r
557                                 device_nums.erase(device_nums.begin()+dpos);\r
558                                 devices.erase(devices.begin()+dpos);    \r
559                         //printf("new length %i\n",devices.size());\r
560                                 dpos--;\r
561                         } \r
562 \r
563                 } else {\r
564                         devices[dpos]->lastfound=0;\r
565                 }\r
566                 dpos++;\r
567                 \r
568         }       \r
569         return cnt;     \r
570 }\r
571 \r
572 int owInterface::MatchRom(snum_t snum) {\r
573         Reset();\r
574 /*      sendrecivByte(0x55);\r
575         usleep(20);\r
576         for(int i=0;i<8;i++) {\r
577                 sendrecivByte(snum.byte[i]); \r
578                 usleep(20);\r
579         }\r
580         if (log->last()>OWLOG_WARNING) return 0;*/\r
581         std::vector<uint8_t> cl;\r
582         cl.push_back(0x55);  //code for Flashing\r
583         for (int i = 0; i<8; i++) {\r
584                 cl.push_back(snum.byte[i]);\r
585         }\r
586         Communicate(&cl, 9, 0);\r
587 \r
588         return 1;\r
589 }\r
590 int owInterface::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {\r
591         int i=0;\r
592         data->resize(scount);\r
593         for(uint8_t v:*data) {\r
594                 (*data)[i]=sendrecivByte(v);i++;\r
595                 usleep(20);\r
596         }\r
597         for(i=0;i<rcount;i++) {\r
598                 data->push_back(sendrecivByte(0xFF));\r
599                 usleep(20);\r
600                 \r
601         }\r
602         return 0;\r
603 }\r
604 \r