1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the
14 // * All advertising materials mentioning features or use of this
15 // software must display the following acknowledgement: This product
16 // includes software developed by tm3d.de and its contributors.
17 // * Neither the name of tm3d.de nor the names of its contributors may
18 // be used to endorse or promote products derived from this software
19 // without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "owInterface.h"
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) {
53 config=new owDeviceConfig;
54 configstate=OWDCS_NONE;
55 raw.insert(raw.begin(),4,0);
56 values.insert(values.begin(),4,0);
60 void owDevice::setDefaultConfig() {
64 std::vector<std::string> owDevice::getFamilyInfo() {
65 return owDeviceConfig::getFamilyInfo(snum.byte[0]);
67 int owDevice::readConfig() {
68 std::vector<uint8_t> cl;
69 int r=owi->maxrepeat+1;
76 Communicate(&cl, 1, 26);
77 //for (uint8_t v:cl) printf("%02X ",v);
78 if ((cl[1]==0xFF)||(cl[2]==0xFF)) {
79 owi->log->set(OWLOG_INFO,"Get Config not work, maybe not a emulation from www.tm3d.de");
84 for(int i=19;i<27;i++) if (cl[i]!=0xFF) {oldInfo=0;break;}
86 owi->log->set(OWLOG_INFO,"Old 16 Byte Config");
88 if (!owi->calcCRC8(std::vector<uint8_t>(cl.begin()+1,cl.begin()+17))) {
89 owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config");
92 if (!owi->testCRC16(cl)) {
93 owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config ");
96 if (owi->log->last()<OWLOG_WARNING) {
98 for(int i=0;i<7;i++) {cl[18+i]=cl[10+i];cl[10+i]=0;} //Move OWID2 Set Sensor to 0
104 if (!owi->calcCRC8(std::vector<uint8_t>(cl.begin()+1,cl.begin()+25))) {
105 owi->log->set(OWLOG_WARNING,"CRC8 ERROR Reading Config");
108 if (!owi->testCRC16(cl)) {
109 owi->log->set(OWLOG_WARNING,"CRC16 ERROR Reading Config ");
115 while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
117 owi->log->set(OWLOG_ERROR,"To much Errors while read config");
120 config->setConfig(std::vector<uint8_t>(cl.begin()+1,cl.begin()+25));
122 if (conf16) configstate=OWDCS_16; else configstate=OWDCS_24;
123 } else configstate=OWDCS_NONE;
128 int owDevice::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {
131 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
132 owi->Communicate(data, scount, rcount);
133 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
138 int owDevice::CommunicateShort(std::vector<uint8_t> *data, int scount, int rcount) {
141 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
142 owi->Communicate(data, scount, rcount);
143 if (owi->log->last()==OWLOG_ERROR) {owi->Free();return 0;}
149 void owDevice::changeID(snum_t nid) {
151 if (nid.byte[0] != snum.byte[0]) {
152 owi->log->set(OWLOG_ERROR,"Family ID should not be changed, no correct ID");
155 std::vector<uint8_t> id;
156 for(i=0;i<7;i++) id.push_back(nid.byte[i]);
157 id.push_back(owi->calcCRC8(id));
158 std::vector<uint8_t> cl;
159 int r=owi->maxrepeat+1;
164 cl.insert(cl.begin()+1,id.begin(),id.end());
165 Communicate(&cl, 9,0);
166 if (owi->log->last()==OWLOG_ERROR) {r--;continue;}
169 Communicate(&cl, 1, 8);
170 if (owi->log->last()==OWLOG_ERROR) {r--;continue;}
171 for (i = 0; i < 8; i++) {
172 if (cl[i + 1] != id[i]) {
173 owi->log->set(OWLOG_WARNING,"changeID Comunication ERROR");
179 while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
181 owi->log->set(OWLOG_ERROR,"Can not change ID");
186 cl.push_back(snum.byte[1]);
187 cl.push_back(snum.byte[5]);
188 cl.push_back(snum.byte[6]);
189 Communicate(&cl, 4, 0);
193 void owDevice::runFlasher() {
194 std::vector<uint8_t> cl;
196 this->Communicate(&cl, 1, 0);
197 this->Communicate(&cl, 1, 0);
198 this->Communicate(&cl, 1, 0);
209 void owDeviceDS18B20::setDefaultConfig() {
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});
211 configstate=OWDCS_DEFAULT;
214 int owDeviceDS18B20::readScratchpad(std::vector<uint8_t> *sp) {
215 std::vector<uint8_t> cl;
216 int r=owi->maxrepeat+1;
220 Communicate(&cl, 1, 9);
221 if (owi->log->last()>=OWLOG_ERROR) return -1;
223 sp->insert(sp->begin(),cl.begin()+1,cl.end());
224 if (owi->calcCRC8(*sp)==0) return 1;
225 owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS18B20 Scrachpad");
227 } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
232 int owDeviceDS18B20::convertAll() {
233 std::vector<uint8_t> sp;
235 Communicate(&sp, 1, 0);
238 if (readScratchpad(&sp)) {
240 tsht = sp[0] | ((int)sp[1] << 8);
244 values[0]=config->calculateValue(0, raw);
251 void owDeviceDS2438::setDefaultConfig() {
252 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});
253 configstate=OWDCS_DEFAULT;
257 int owDeviceDS2438::readScratchpad(std::vector<uint8_t> *sp, uint8_t page, int recall) {
258 std::vector<uint8_t> cl;
259 int r=owi->maxrepeat+1;
263 cl.push_back(0xB8); //recall
265 Communicate(&cl, 2, 0);
266 if (owi->log->last()>=OWLOG_ERROR) return -1;
271 Communicate(&cl, 2, 9);
272 if (owi->log->last()>=OWLOG_ERROR) return -1;
274 sp->insert(sp->begin(),cl.begin()+2,cl.end());
275 if (owi->calcCRC8(*sp)==0) return 1;
276 owi->log->set(OWLOG_WARNING,"CRC ERROR reading DS2438 Scrachpad");
278 } while ((owi->log->last()>=OWLOG_WARNING)&&(r>0));
283 int owDeviceDS2438::setConfigByte(uint8_t cb) {
284 std::vector<uint8_t> sp;
286 for(k=0;k<owi->maxrepeat;k++) {
292 Communicate(&sp,3,0);
293 if (owi->log->last()>=OWLOG_ERROR) return -1;
295 readScratchpad(&sp,0,0);
296 if (owi->log->last()>=OWLOG_ERROR) return -2;
297 if (cb==sp[0]) return 1;
298 owi->log->set(OWLOG_WARNING,"ERROR set config byte of DS2438");
300 owi->log->set(OWLOG_WARNING,"Config of DS2438 byte not set");
304 inline int16_t ow_fconvert(uint8_t b1, uint16_t b2) {
306 tsht=b1 |((int)b2<<8);
312 int owDeviceDS2438::convertAll() {
313 for(int k=0;k<owi->maxrepeat;k++) {
314 std::vector<uint8_t> sp;
316 Communicate(&sp, 1, 0);
317 if (owi->log->last()>=OWLOG_ERROR) continue;
319 if (setConfigByte(0x08)<=0) continue;
320 for(int k=0;k<owi->maxrepeat;k++) {
323 Communicate(&sp, 1, 0);
325 if (owi->log->last()>=OWLOG_ERROR) continue;
329 readScratchpad(&sp,0,1);
330 int temp=ow_fconvert(sp[1],sp[2]);
331 int VDD=ow_fconvert(sp[3],sp[4]);
332 if (setConfigByte(0x00)<=0) continue;
334 for(int k=0;k<owi->maxrepeat;k++) {
337 Communicate(&sp, 1, 0);
339 if (owi->log->last()>=OWLOG_ERROR) continue;
345 readScratchpad(&sp,0,1);
346 if (owi->log->last()>=OWLOG_ERROR) continue;
347 int I=ow_fconvert(sp[5],sp[6]);
348 int VAD=ow_fconvert(sp[3],sp[4]);
353 for(int i=0;i<4;i++) values[i]=config->calculateValue(i, raw);
356 if (owi->log->last()>=OWLOG_ERROR) return 0;
361 void owDeviceDS2450::setDefaultConfig() {
362 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});
363 configstate=OWDCS_DEFAULT;
366 int owDeviceDS2450::convertAll() {
368 if (owi->log->last()>=OWLOG_WARNING) {
371 std::vector<uint8_t> sp;
373 if (owi->log->last()>=OWLOG_WARNING) {
377 for(int i=0;i<4;i++) {
378 raw[i]=(sp[2 * i] | sp[2 * i + 1] << 8);
380 for(int i=0;i<4;i++) {
381 values[i]=config->calculateValue(i, raw);
387 void owDeviceDS2450::readMemory(uint8_t addr,std::vector<uint8_t> *sp) {
388 std::vector<uint8_t> cl;
392 Communicate(&cl,3,10-addr);
393 if (owi->log->last()>=OWLOG_WARNING) {
396 if (!owi->testCRC16(cl)) {
397 owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Memory of DS2450");
401 sp->insert(sp->begin(),cl.begin()+3,cl.end()-2);
404 void owDeviceDS2450::writeMemory(uint8_t addr,std::vector<uint8_t> *sp) {
405 std::vector<uint8_t> cl;
410 if (owi->log->last()>=OWLOG_WARNING) {
413 for(uint8_t b: (*sp)) {
415 owi->Communicate(&cl,cl.size(),2);
416 if (owi->log->last()>=OWLOG_WARNING) {
419 if (!owi->testCRC16(cl)) {
420 owi->log->set(OWLOG_ERROR,"CRC ERROR Writing Memory of DS2450");
424 owi->Communicate(&cl, 0, 1);
425 if (owi->log->last()>=OWLOG_WARNING) {
429 owi->log->set(OWLOG_ERROR,"ERROR Writing Memory of DS2450");
436 void owDeviceDS2450::convert(uint8_t mask, uint8_t preset) {
437 std::vector<uint8_t> cl;
440 cl.push_back(preset);
441 Communicate(&cl, 3, 2);
442 if (!owi->testCRC16(cl)) {
443 owi->log->set(OWLOG_ERROR,"CRC ERROR Convert Command of DS2450");
459 void owDeviceDS2423::setDefaultConfig() {
460 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});
461 configstate=OWDCS_DEFAULT;
464 int owDeviceDS2423::convertAll() {
465 for(uint8_t i=12;i<16;i++) {
466 raw[i-12]=readCounter(i);
468 for(int i=0;i<4;i++) {
469 values[i]=config->calculateValue(i, raw);
473 uint32_t owDeviceDS2423::readCounter(uint8_t page) {
474 std::vector<uint8_t> cl;
476 uint16_t addr=(page<<5)+31;
477 cl.push_back(addr&0xFF);
478 cl.push_back(addr>>8);
479 Communicate(&cl,3,11);
480 //for (uint8_t v :cl) printf("%02X ",v);
482 if (!owi->testCRC16(cl)) {
483 owi->log->set(OWLOG_ERROR,"CRC ERROR Reading Counter of DS2423");
488 for(size_t i=cl.size()-8;i>cl.size()-11;i--) {