manueller import aus nem CVS checkout (ist eh nur zum testen)
[ds1820tousb.git] / ds1820.c
CommitLineData
93ac315e
MPM
1/* $Id: ds1820.c,v 1.3 2010/07/16 19:31:18 simimeie Exp $
2 * USB interface for ds1820
3 * This file handles everything that has to do with the temperature probes.
4 * (C) Michael "Fox" Meier 2009
5 */
6
7#include "usbdrv/usbdrv.h"
8#include "ds1wire.h"
9#include "time.h"
10
11#include "ds1820.h"
12
13struct probe ds1820probes[DS1820_MAXPROBES];
14
15void ds1820init(void) {
16 ds1wire_init(B, 0);
17 ds1wire_reset(B, 0);
18}
19
20void ds1820killbus(void) {
21 ds1wire_pulldown(B, 0);
22}
23
24static void ds1820write(uint8_t val) {
25 uint8_t i;
26 for (i = 0; i < 8; i++) {
27 if (val & 0x01) {
28 ds1wire_send1(B, 0);
29 } else {
30 ds1wire_send0(B, 0);
31 }
32 val >>= 1;
33 }
34}
35
36static uint8_t ds1820read(void) {
37 uint8_t i;
38 uint8_t res = 0;
39 for (i = 0; i < 8; i++) {
40 res |= ((ds1wire_read(B, 0)) << i);
41 }
42 return res;
43}
44
45void ds1820queryprobe(uint8_t probenum)
46{
47 uint8_t i; uint8_t crc = 0;
48 ds1wire_reset(B, 0);
49#ifdef KISS
50 ds1820write(DS1820_CMD_SKIPROM); /* Skip ROM */
51#else
52 ds1820write(DS1820_CMD_MATCHROM); /* Match ROM */
53 /* Send 64 bit serial */
54 ds1820write(ds1820probes[probenum].family);
55 crc = ds1wire_calccrc8(crc, ds1820probes[probenum].family);
56 for (i = 0; i < 6; i++) {
57 ds1820write(ds1820probes[probenum].serial[i]);
58 crc = ds1wire_calccrc8(crc, ds1820probes[probenum].serial[i]);
59 }
60 ds1820write(crc);
61#endif /* KISS */
62 /* Issue 'start temperature conversion' */
63 ds1820write(DS1820_CMD_CONVERTT);
64 if (ds1820probes[probenum].flags & DS1820FLAG_PARASITE) {
65 /* Provide parasite power */
66 ds1wire_parasitepoweron(B, 0);
67 }
68}
69
70/* Returns 1 on successful update, 0 otherwise */
71uint8_t ds1820updateprobe(uint8_t probenum)
72{
73 uint8_t i; uint8_t crc = 0; uint8_t t1 = 0; uint8_t t2 = 0;
74 if (ds1820probes[probenum].flags & DS1820FLAG_PARASITE) {
75 /* No longer provide parasite power */
76 ds1wire_parasitepoweroff(B, 0);
77 }
78 ds1wire_reset(B, 0);
79#ifdef KISS
80 ds1820write(DS1820_CMD_SKIPROM); /* Skip ROM */
81#else
82 ds1820write(DS1820_CMD_MATCHROM); /* Match ROM */
83 /* Send 64 bit serial */
84 ds1820write(ds1820probes[probenum].family);
85 crc = ds1wire_calccrc8(crc, ds1820probes[probenum].family);
86 for (i = 0; i < 6; i++) {
87 ds1820write(ds1820probes[probenum].serial[i]);
88 crc = ds1wire_calccrc8(crc, ds1820probes[probenum].serial[i]);
89 }
90 ds1820write(crc);
91#endif /* KISS */
92 /* Read Scratchpad */
93 ds1820write(DS1820_CMD_READSCRPAD);
94 crc = 0;
95 for (i = 0; i < 9; i++) {
96 uint8_t v = ds1820read();
97 if (i == 0) { t1 = v; }
98 if (i == 1) { t2 = v; }
99 crc = ds1wire_calccrc8(crc, v);
100 }
101 /* For parasite powered probes, reading 0x50 0x05 (85.0 deg) usually
102 * means the probe has lost power during temperature conversion and
103 * reset (85.0 is the poweron value of the temperature scratchpad).
104 * So we filter the value 85.0 for parasite powered probes. This means
105 * you can never use parasite powered probes for temperatures in this
106 * range. */
107 if ((crc == 0)
108 && (((ds1820probes[probenum].flags & DS1820FLAG_PARASITE) == 0)
109 || (t1 != 0x50) || (t2 != 0x05))) {
110 ds1820probes[probenum].lastts = gettime();
111 ds1820probes[probenum].lasttemp[0] = t1;
112 ds1820probes[probenum].lasttemp[1] = t2;
113 return 1;
114 } else {
115 return 0;
116 }
117}
118
119/* This is going to be a tough one:
120 * Scan the bus to find all probes.
121 */
122void ds1820scan(void) {
123#ifdef KISS
124 ds1wire_reset(B, 0);
125 ds1820probes[0].flags |= DS1820FLAG_SLOTINUSE;
126 ds1820write(DS1820_CMD_SKIPROM); /* Skip ROM */
127 ds1820write(DS1820_CMD_READPOWER); /* Read power supply */
128 if (ds1wire_read(B, 0) == 0) { /* Parasite powered probes return 0 */
129 ds1820probes[0].flags |= DS1820FLAG_PARASITE;
130 } else {
131 ds1820probes[0].flags &= ~DS1820FLAG_PARASITE;
132 }
133#else /* KISS */
134 uint8_t lastserialfound[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
135 int8_t lastcolwith0 = -1;
136 int8_t prevcolwith0;
137 int8_t i;
138 uint8_t j;
139 for (i = 0; i < DS1820_MAXPROBES; i++) { /* Clear list of probes */
140 ds1820probes[i].flags = 0;
141 }
142 do {
143 ds1wire_reset(B, 0);
144 prevcolwith0 = lastcolwith0;
145 lastcolwith0 = -1;
146 /* Send scan command */
147 ds1820write(DS1820_CMD_SEARCHROM);
148 for (i = 0; i < 64; i++) {
149 uint8_t val1 = ds1wire_read(B, 0);
150 uint8_t val2 = ds1wire_read(B, 0);
151 if (val1 == val2) { /* Collission */
152 if (val1 == 1) { /* and thus val2 is 1 too */
153 /* Nothing matched on the bus! This is actually pretty fatal! */
154 /* Try to get out alive. Send all 0. */
155 ds1wire_send0(B, 0); lastcolwith0 = -1;
156 } else { /* Both 0 */
157 /* Was that where we stopped last time? */
158 if (prevcolwith0 == i) { /* Send a 1 this time */
159 ds1wire_send1(B, 0);
160 lastserialfound[i >> 3] |= _BV(i & 0x07);
161 } else {
162 lastcolwith0 = i;
163 ds1wire_send0(B, 0);
164 lastserialfound[i >> 3] &= (uint8_t)~_BV(i & 0x07);
165 }
166 }
167 } else { /* val1 != val2 */
168 if (val1 == 0) { /* Was a 0, so select that */
169 ds1wire_send0(B, 0);
170 lastserialfound[i >> 3] &= (uint8_t)~_BV(i & 0x07);
171 } else { /* Was a 1 */
172 ds1wire_send1(B, 0);
173 lastserialfound[i >> 3] |= _BV(i & 0x07);
174 }
175 }
176 }
177 /* lastserialfound now contains the serial of the last probe we found,
178 * AND that probe is selected. */
179 /* Check CRC of serial number. */
180 j = 0; /* Used as CRC here */
181 for (i = 0; i < 8; i++) {
182 j = ds1wire_calccrc8(j, lastserialfound[i]);
183 }
184 if (j == 0) { /* CRC of serial number OK! */
185 for (i = 0; i < DS1820_MAXPROBES; i++) {
186 if ((ds1820probes[i].flags & DS1820FLAG_SLOTINUSE) == 0) {
187 /* Empty slot, use it. */
188 break;
189 }
190 }
191 if (i == DS1820_MAXPROBES) { /* No match. Overwrite last entry. */
192 i = DS1820_MAXPROBES - 1;
193 }
194 ds1820probes[i].flags |= DS1820FLAG_SLOTINUSE;
195 ds1820probes[i].family = lastserialfound[0];
196 for (j = 0; j < 6; j++) {
197 ds1820probes[i].serial[j] = lastserialfound[j+1];
198 }
199 ds1820probes[i].lastts = 0;
200 ds1820probes[i].lasttemp[0] = 0;
201 ds1820probes[i].lasttemp[1] = 0;
202 /* Find out if the probe is parasite powered or not. */
203 ds1820write(DS1820_CMD_READPOWER); /* Read power supply */
204 if (ds1wire_read(B, 0) == 0) { /* Parasite powered probes return 0 */
205 ds1820probes[i].flags |= DS1820FLAG_PARASITE;
206 } else {
207 ds1820probes[i].flags &= ~DS1820FLAG_PARASITE;
208 }
209 }
210 } while (lastcolwith0 >= 0);
211#endif /* KISS */
212}
This page took 0.07325 seconds and 4 git commands to generate.