1 // Copyright (c) 2019, Tobias Mueller tm(at)tm3d.de
\r
2 // All rights reserved.
\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
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
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
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
34 #include "owInterface.h"
\r
39 void usleep(int waitTime) {
\r
40 __int64 time1 = 0, time2 = 0, freq = 0;
\r
42 QueryPerformanceCounter((LARGE_INTEGER *)&time1);
\r
43 QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
\r
46 QueryPerformanceCounter((LARGE_INTEGER *)&time2);
\r
47 } while ((time2 - time1) < waitTime);
\r
50 owDevice::owDevice(owInterface *owi_,snum_t num) {
\r
53 config=new owDeviceConfig;
\r
54 configstate=OWDCS_NONE;
\r
55 raw.insert(raw.begin(),4,0);
\r
56 values.insert(values.begin(),4,0);
\r
60 void owDevice::setDefaultConfig() {
\r
61 config->setInvalid();
\r
64 std::vector<std::string> owDevice::getFamilyInfo() {
\r
65 return owDeviceConfig::getFamilyInfo(snum.byte[0]);
\r
67 int owDevice::readConfig() {
\r
68 std::vector<uint8_t> cl;
\r
69 int r=owi->maxrepeat+1;
\r
76 Communicate(&cl, 1, 26);
\r
77 //for (uint8_t v:cl) printf("%02X ",v);
\r
78 if ((cl[1]==0xFF)||(cl[2]==0xFF)) {
\r
79 owi->log->set(OWLOG_INFO,"Get Config not work, maybe not a emulation from www.tm3d.de");
\r
84 for(int i=19;i<27;i++) if (cl[i]!=0xFF) {oldInfo=0;break;}
\r
86 owi->log->set(OWLOG_INFO,"Old 16 Byte Config");
\r
87 if (cl[18]==0xFF) {
\r
88 if (!owi->calcCRC8(std::vector<uint8_t>(cl.begin()+1,cl.begin()+17))) {
\r
89 owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config");
\r
92 if (!owi->testCRC16(cl)) {
\r
93 owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config ");
\r
96 if (owi->log->last()<OWLOG_WARNING) {
\r
97 cl[9]=2; //Attiny84A
\r
98 for(int i=0;i<7;i++) {cl[18+i]=cl[10+i];cl[10+i]=0;} //Move OWID2 Set Sensor to 0
\r
103 if (cl[26]==0xFF) {
\r
104 if (!owi->calcCRC8(std::vector<uint8_t>(cl.begin()+1,cl.begin()+25))) {
\r
105 owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config");
\r
108 if (!owi->testCRC16(cl)) {
\r
109 owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config ");
\r
115 while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
\r
117 owi->log->set(OWLOG_ERROR,"To much Errors while read config");
\r
120 config->setConfig(std::vector<uint8_t>(cl.begin()+1,cl.begin()+25));
\r
121 if (config->valid) {
\r
122 if (conf16) configstate=OWDCS_16; else configstate=OWDCS_24;
\r
123 } else configstate=OWDCS_NONE;
\r
128 int owDevice::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {
\r
130 owi->MatchRom(snum);
\r
131 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
\r
132 owi->Communicate(data, scount, rcount);
\r
133 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
\r
138 int owDevice::CommunicateShort(std::vector<uint8_t> *data, int scount, int rcount) {
\r
141 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
\r
142 owi->Communicate(data, scount, rcount);
\r
143 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
\r
149 void owDevice::changeID(snum_t nid) {
\r
151 if (nid.byte[0] != snum.byte[0]) {
\r
152 owi->log->set(OWLOG_WARNING,"Family ID should not be changed, no correct ID");
\r
155 std::vector<uint8_t> id;
\r
156 for(i=0;i<7;i++) id.push_back(nid.byte[i]);
\r
157 id.push_back(owi->calcCRC8(id));
\r
158 std::vector<uint8_t> cl;
\r
159 int r=owi->maxrepeat+1;
\r
163 cl.push_back(0x75);
\r
164 cl.insert(cl.begin()+1,id.begin(),id.end());
\r
165 Communicate(&cl, 9,0);
\r
166 if (owi->log->last()==OWLOG_ERROR) {r--;continue;}
\r
168 cl.push_back(0xA7);
\r
169 Communicate(&cl, 1, 8);
\r
170 if (owi->log->last()==OWLOG_ERROR) {r--;continue;}
\r
171 for (i = 0; i < 8; i++) {
\r
172 if (cl[i + 1] != id[i]) {
\r
173 owi->log->set(OWLOG_WARNING,"changeID Comunication ERROR");
\r
179 while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
\r
181 owi->log->set(OWLOG_ERROR,"Can not change ID");
\r
185 cl.push_back(0x79);
\r
186 cl.push_back(snum.byte[1]);
\r
187 cl.push_back(snum.byte[5]);
\r
188 cl.push_back(snum.byte[6]);
\r
189 Communicate(&cl, 4, 0);
\r
193 void owDevice::runFlasher() {
\r
194 std::vector<uint8_t> cl;
\r
195 cl.push_back(0x88);
\r
196 this->Communicate(&cl, 1, 0);
\r
197 this->Communicate(&cl, 1, 0);
\r
198 this->Communicate(&cl, 1, 0);
\r
209 void owDeviceDS18B20::setDefaultConfig() {
\r
210 config->setConfig({1,1, 0,0, 0,0, 0,0, 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0});
\r
211 configstate=OWDCS_DEFAULT;
\r
214 int owDeviceDS18B20::readScratchpad(std::vector<uint8_t> *sp) {
\r
215 std::vector<uint8_t> cl;
\r
216 int r=owi->maxrepeat+1;
\r
219 cl.push_back(0xBE);
\r
220 Communicate(&cl, 1, 9);
\r
221 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
223 sp->insert(sp->begin(),cl.begin()+1,cl.end());
\r
224 if (owi->calcCRC8(*sp)==0) return 1;
\r
225 owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS18B20 Scrachpad");
\r
227 } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
\r
232 int owDeviceDS18B20::convertAll() {
\r
233 std::vector<uint8_t> sp;
\r
234 if (owCC_44_Temp==0) {
\r
235 sp.push_back(0x44);
\r
236 Communicate(&sp, 1, 0); ///########################################################
\r
239 if (readScratchpad(&sp)) {
\r
241 tsht = sp[0] | ((int)sp[1] << 8);
\r
243 tsht |= 0xFFFFF0000;
\r
245 values[0]=config->calculateValue(0, raw);
\r
251 int owDeviceDS18B20::readMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
252 std::vector<uint8_t> d;
\r
253 readScratchpad(&d);
\r
254 data->insert(data->begin(),d.begin()+start,d.end());
\r
259 void owDeviceDS2438::setDefaultConfig() {
\r
260 config->setConfig({1,6, 6,8, 4,7, 6,17, 0,2,3,12,4,0,0,0,0,0,0,0,0,0,0,0});
\r
261 configstate=OWDCS_DEFAULT;
\r
265 int owDeviceDS2438::readScratchpad(std::vector<uint8_t> *sp, uint8_t page, int recall) {
\r
266 std::vector<uint8_t> cl;
\r
267 int r=owi->maxrepeat+1;
\r
271 cl.push_back(0xB8); //recall
\r
272 cl.push_back(page);
\r
273 Communicate(&cl, 2, 0);
\r
274 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
277 cl.push_back(0xBE);
\r
278 cl.push_back(page);
\r
279 Communicate(&cl, 2, 9);
\r
280 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
282 sp->insert(sp->begin(),cl.begin()+2,cl.end());
\r
283 if (owi->calcCRC8(*sp)==0) return 1;
\r
284 owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS2438 Scrachpad");
\r
286 } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
\r
291 int owDeviceDS2438::readMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
292 if ((page>7)||(page<0)||(start>7)||(start<0)||(start+count>8)) return 0;
\r
293 std::vector<uint8_t> cl;
\r
295 cl.push_back(0xB8); //recall
\r
296 cl.push_back(page);
\r
297 Communicate(&cl, 2, 0);
\r
298 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
300 cl.push_back(0xBE);
\r
301 cl.push_back(page);
\r
302 Communicate(&cl, 2, 9);
\r
303 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
304 cl.erase(cl.begin());
\r
305 cl.erase(cl.begin());
\r
306 if (owi->calcCRC8(cl)!=0) {
\r
307 owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS2438 Scrachpad");
\r
310 data->insert(data->begin(),cl.begin()+start,cl.begin()+start+count);
\r
313 int owDeviceDS2438::writeMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
314 if ((page>7)||(page<0)||(start>7)||(start<0)||(start+count>8)) return 0;
\r
315 std::vector<uint8_t> sp;
\r
316 if ((start>0)||(count<8)) {
\r
317 readMemory(page,0,8,&sp);
\r
319 std::vector<uint8_t> cl;
\r
320 cl.push_back(0x4E);
\r
321 cl.push_back(page);
\r
323 for(int i=0;i<8;i++) {
\r
324 if ((i<start)||(i>=start+count)) cl.push_back(sp[i]); else {cl.push_back((*data)[j]);j++;}
\r
326 Communicate(&cl, 10,0);
\r
327 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
328 std::vector<uint8_t> cl1;
\r
329 cl1.push_back(0xBE);
\r
330 cl1.push_back(page);
\r
331 Communicate(&cl1, 2, 9);
\r
332 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
333 cl1.erase(cl1.begin());
\r
334 cl1.erase(cl1.begin());
\r
335 if (owi->calcCRC8(cl1)!=0) {
\r
336 owi->log->set(OWLOG_WARNING,"CRC ERROR rereading DS2438 Scrachpad");
\r
338 for(int i=0;i<8;i++) {
\r
339 if (cl1[i]!=cl[i+2]) {
\r
340 owi->log->set(OWLOG_ERROR,"Reread not equal, nothing copied");
\r
345 cl.push_back(0x48);
\r
346 cl.push_back(page);
\r
347 Communicate(&cl, 2, 0);
\r
348 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
354 int owDeviceDS2438::setConfigByte(uint8_t cb) {
\r
355 std::vector<uint8_t> sp;
\r
357 for(k=0;k<owi->maxrepeat;k++) {
\r
360 sp.push_back(0x4E);
\r
361 sp.push_back(0x00);
\r
363 Communicate(&sp,3,0);
\r
364 if (owi->log->last()>=OWLOG_ERROR) return -1;
\r
366 readScratchpad(&sp,0,0);
\r
367 if (owi->log->last()>=OWLOG_ERROR) return -2;
\r
368 if (cb==sp[0]) return 1;
\r
369 owi->log->set(OWLOG_WARNING,"ERROR set config byte of DS2438");
\r
371 owi->log->set(OWLOG_WARNING,"Config of DS2438 byte not set");
\r
375 inline int16_t ow_fconvert(uint8_t b1, uint16_t b2) {
\r
377 tsht=b1 |((int)b2<<8);
\r
379 tsht |= 0xFFFFF0000;
\r
383 int owDeviceDS2438::convertAll() {
\r
384 for(int k=0;k<owi->maxrepeat;k++) {
\r
385 std::vector<uint8_t> sp;
\r
386 if (owCC_44_Temp==0) {
\r
387 sp.push_back(0x44);
\r
388 Communicate(&sp, 1, 0);///########################################################
\r
389 if (owi->log->last()>=OWLOG_ERROR) continue;
\r
392 if (setConfigByte(0x08)<=0) continue;
\r
393 for(int k=0;k<owi->maxrepeat;k++) {
\r
395 sp.push_back(0xB4);
\r
396 Communicate(&sp, 1, 0);
\r
398 if (owi->log->last()>=OWLOG_ERROR) continue;
\r
402 readScratchpad(&sp,0,1);
\r
403 int temp=ow_fconvert(sp[1],sp[2]);
\r
404 int VDD=ow_fconvert(sp[3],sp[4]);
\r
405 if (setConfigByte(0x00)<=0) continue;
\r
407 for(int k=0;k<owi->maxrepeat;k++) {
\r
409 sp.push_back(0xB4);
\r
410 Communicate(&sp, 1, 0);
\r
412 if (owi->log->last()>=OWLOG_ERROR) continue;
\r
418 readScratchpad(&sp,0,1);
\r
419 if (owi->log->last()>=OWLOG_ERROR) continue;
\r
420 int I=ow_fconvert(sp[5],sp[6]);
\r
421 int VAD=ow_fconvert(sp[3],sp[4]);
\r
426 for(int i=0;i<4;i++) values[i]=config->calculateValue(i, raw);
\r
429 if (owi->log->last()>=OWLOG_ERROR) return 0;
\r
434 void owDeviceDS2450::setDefaultConfig() {
\r
435 config->setConfig({6,9, 6,9, 6,9, 6,9, 0,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0});
\r
436 configstate=OWDCS_DEFAULT;
\r
439 int owDeviceDS2450::convertAll() {
\r
441 if (owi->log->last()>=OWLOG_WARNING) {
\r
444 std::vector<uint8_t> sp;
\r
445 readMemory(0,0,8,&sp);
\r
446 if (owi->log->last()>=OWLOG_WARNING) {
\r
450 for(int i=0;i<4;i++) {
\r
451 raw[i]=(sp[2 * i] | sp[2 * i + 1] << 8);
\r
453 for(int i=0;i<4;i++) {
\r
454 values[i]=config->calculateValue(i, raw);
\r
460 int owDeviceDS2450::readMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
461 std::vector<uint8_t> cl;
\r
462 cl.push_back(0xAA);
\r
463 cl.push_back(page*8+start);
\r
464 cl.push_back(0x00);
\r
465 Communicate(&cl,3,10-start);
\r
466 if (owi->log->last()>=OWLOG_WARNING) {
\r
469 if (!owi->testCRC16(cl)) {
\r
470 for (uint8_t v :cl) printf("%02X ",v);
\r
472 owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Memory of DS2450");
\r
476 data->insert(data->begin(),cl.begin()+3,cl.end()-2);
\r
479 int owDeviceDS2450::writeMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
480 std::vector<uint8_t> cl;
\r
481 cl.push_back(0x55);
\r
482 cl.push_back(page*8+start);
\r
483 cl.push_back(0x00);
\r
484 owi->MatchRom(snum);
\r
485 if (owi->log->last()>=OWLOG_WARNING) {
\r
489 for(uint8_t b: (*data)) {
\r
491 owi->Communicate(&cl,cl.size(),2);
\r
492 if (owi->log->last()>=OWLOG_WARNING) {
\r
496 if (!owi->testCRC16(cl,i+page*8+start)) {
\r
497 owi->log->set(OWLOG_ERROR,"CRC ERROR Writing Memory of DS2450");
\r
501 if (!owi->testCRC16(cl)) {
\r
502 owi->log->set(OWLOG_ERROR,"CRC ERROR Writing Memory of DS2450");
\r
507 owi->Communicate(&cl, 0, 1);
\r
508 if (owi->log->last()>=OWLOG_WARNING) {
\r
512 owi->log->set(OWLOG_ERROR,"ERROR Writing Memory of DS2450");
\r
522 void owDeviceDS2450::readMemory_int(uint8_t addr,std::vector<uint8_t> *sp) {
\r
523 std::vector<uint8_t> cl;
\r
524 cl.push_back(0xAA);
\r
525 cl.push_back(addr);
\r
526 cl.push_back(0x00);
\r
527 Communicate(&cl,3,10-addr);
\r
528 if (owi->log->last()>=OWLOG_WARNING) {
\r
531 if (!owi->testCRC16(cl)) {
\r
532 for (uint8_t v :cl) printf("%02X ",v);
\r
534 owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Memory of DS2450");
\r
538 sp->insert(sp->begin(),cl.begin()+3,cl.end()-2);
\r
541 void owDeviceDS2450::writeMemory_int(uint8_t addr,std::vector<uint8_t> *sp) {
\r
542 std::vector<uint8_t> cl;
\r
543 cl.push_back(0x55);
\r
544 cl.push_back(addr);
\r
545 cl.push_back(0x00);
\r
546 owi->MatchRom(snum);
\r
547 if (owi->log->last()>=OWLOG_WARNING) {
\r
550 for(uint8_t b: (*sp)) {
\r
552 owi->Communicate(&cl,cl.size(),2);
\r
553 if (owi->log->last()>=OWLOG_WARNING) {
\r
556 if (!owi->testCRC16(cl)) {
\r
557 owi->log->set(OWLOG_ERROR,"CRC ERROR Writing Memory of DS2450");
\r
561 owi->Communicate(&cl, 0, 1);
\r
562 if (owi->log->last()>=OWLOG_WARNING) {
\r
566 owi->log->set(OWLOG_ERROR,"ERROR Writing Memory of DS2450");
\r
573 void owDeviceDS2450::convert(uint8_t mask, uint8_t preset) {
\r
574 std::vector<uint8_t> cl;
\r
575 cl.push_back(0x3C);
\r
576 cl.push_back(mask);
\r
577 cl.push_back(preset);
\r
578 Communicate(&cl, 3, 2);
\r
579 if (!owi->testCRC16(cl)) {
\r
580 for (uint8_t v :cl) printf("%02X ",v);
\r
582 owi->log->set(OWLOG_ERROR,"CRC ERROR Convert Command of DS2450");
\r
598 void owDeviceDS2423::setDefaultConfig() {
\r
599 config->setConfig({9,13, 9,13, 9,13, 9,13, 0,19,19,19,19,0,0,0,0,0,0,0,0,0,0,0});
\r
600 configstate=OWDCS_DEFAULT;
\r
603 int owDeviceDS2423::convertAll() {
\r
604 for(uint8_t i=12;i<16;i++) {
\r
605 raw[i-12]=readCounter(i);
\r
607 for(int i=0;i<4;i++) {
\r
608 values[i]=config->calculateValue(i, raw);
\r
612 uint32_t owDeviceDS2423::readCounter(uint8_t page) {
\r
613 std::vector<uint8_t> cl;
\r
614 cl.push_back(0xA5);
\r
615 uint16_t addr=(page<<5)+31;
\r
616 cl.push_back(addr&0xFF);
\r
617 cl.push_back(addr>>8);
\r
618 Communicate(&cl,3,11);
\r
619 //for (uint8_t v :cl) printf("%02X ",v);
\r
621 if (!owi->testCRC16(cl)) {
\r
622 owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Counter of DS2423");
\r
627 for(size_t i=cl.size()-7;i>cl.size()-11;i--) {
\r
636 int owDeviceDS2423::readMemory(int page,int start, int count,std::vector<uint8_t> *data){
\r
637 std::vector<uint8_t> cl;
\r
638 cl.push_back(0xF0);
\r
639 uint16_t adr=page<<5;
\r
640 cl.push_back(adr&0xFF);
\r
641 cl.push_back((adr>>8)&0xFF);
\r
642 Communicate(&cl, 3, 32);
\r
645 data->insert(data->begin(),cl.begin()+3+start,cl.begin()+start+3+count);
\r
649 int owDeviceDS2423::writeMemory(int page,int start, int count,std::vector<uint8_t> *data) {
\r
650 std::vector<uint8_t> cl;
\r
651 cl.push_back(0x0F);
\r
652 uint16_t adr=(page<<5)+start;
\r
653 cl.push_back(adr&0xFF);
\r
654 cl.push_back(adr>>8);
\r
655 if (count > (int)(*data).size()) count = (*data).size();
\r
656 for(int i=0;i<count;i++) {
\r
657 cl.push_back((*data)[i]);
\r
659 Communicate(&cl, 3+count, 0);
\r
660 for (uint8_t v :cl) printf("%02X ",v);printf("\n");
\r
662 cl.push_back(0xAA);
\r
663 Communicate(&cl, 1, 36);
\r
664 //for (uint8_t v :cl) printf("%02X ",v);;printf("\n");
\r
666 Communicate(&cl, 4, 1);
\r
669 for (uint8_t v :cl) printf("%02X ",v);;printf("\n");
\r
670 owi->log->set(OWLOG_ERROR,"DS2423 Copy from Scratchpad to Memmory Error");
\r