µracoli Manual Version foo

- µracoli
- User Guide
- Reference Guide

ds18b20.h
1 /* Copyright (c) 2014 Daniel Thiele, Axel Wachtler
2 All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
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 distribution.
13 * Neither the name of the authors nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE. */
28
29 #ifndef DS18B20_H
30 #define DS18B20_H
31
45 /* === includes ============================================================ */
46 #include <util/crc16.h>
47 #include <string.h>
48 #include "ow.h"
49 #include "sensor_defs.h"
50
51 /* === macros ============================================================== */
75 #if !defined(DS18B20_NB)
76 # define DS18B20_NB (1)
77 # define DS18B20_ADDR {0}
78 #endif
79
80
81 /* undefine if DS18B20 is self-powered */
82 #define DS18B20_PARASITE_POWER (1)
83
84 #define DS18B20_DEBUG (0)
85 #if DS18B20_DEBUG == 1
86 # include "hif.h"
87 # define DBG(...) PRINTF(__VA_ARGS__)
88 # define DBGP(x) PRINT(x)
89 #else
90 # define DBG(...)
91 # define DBGP(x)
92 #endif
93
94
95 /* depends on selected resolution */
96 #define DS18B20_CONV_TIME_MS (188) /* 10-bit resolution, 187.5ms */
97 #define DS18B20_COPYSCRATCH_TIME_MS (20) /* at least 10ms, acc. to datasheet */
98 #define DS18B20_SIZE_SCRATCHPAD (9)
99
100 #define DS18B20_FUNCCMD_CONVT (0x44)
101 #define DS18B20_FUNCCMD_READSCRATCH (0xBE)
102 #define DS18B20_FUNCCMD_WRITESCRATCH (0x4E)
103 #define DS18B20_FUNCCMD_COPYSCRATCH (0x48)
104 #define DS18B20_FUNCCMD_RECALLEE (0xB8)
105 #define DS18B20_FUNCCMD_READPOWER (0xB4)
106
107 /* === types =============================================================== */
109 typedef struct
110 {
111 sensor_driver_t g;
112 ow_serial_t addr[DS18B20_NB];
113 } ds18b20_ctx_t;
114
115 /* === prototypes ========================================================== */
116 #ifdef __cplusplus
117 extern "C" {
118 #endif
119
120 /* === low level functions ================================================== */
128 static inline uint8_t ds18b20_command(uint8_t command, uint8_t *buf)
129 {
130 uint8_t i;
131 uint8_t crc = 0;
132 uint8_t rv = SENSOR_ERR_OK;
133
134 switch(command)
135 {
136 case DS18B20_FUNCCMD_CONVT :
137 break;
138 case DS18B20_FUNCCMD_READSCRATCH:
139 ow_byte_write(DS18B20_FUNCCMD_READSCRATCH);
140 DBGP("read scratch:");
141 for(i=0; i<9; i++)
142 {
143 *buf = ow_byte_read();
144 DBG("0x%02x ", *buf);
145 crc = _crc_ibutton_update(crc, *buf++);
146 }
147 DBG("crc = 0x%x\n", crc);
148 if (crc != 0)
149 {
150 rv = SENSOR_ERR_CRC;
151 }
152 break;
153 case DS18B20_FUNCCMD_WRITESCRATCH:
154 break;
155 case DS18B20_FUNCCMD_COPYSCRATCH:
156 #if defined(DS18B20_PARASITE_POWER)
157 PINHI(DQ);
158 PINOUTP(DQ);
159 #endif
160 break;
161 case DS18B20_FUNCCMD_RECALLEE:
162 break;
163 case DS18B20_FUNCCMD_READPOWER:
164 break;
165 default:
166 /* unknown */
167 break;
168 }
169
170 return rv;
171 }
180 static inline uint8_t ds18b20_read_temperature(ow_serial_t ser, int16_t *temp)
181 {
182 uint8_t buf[DS18B20_SIZE_SCRATCHPAD];
183 uint8_t rv = SENSOR_ERR_OK;
184 /* send convert to all */
185 ow_reset();
186 ow_byte_write(OW_ROMCMD_SKIP);
187 ow_byte_write(DS18B20_FUNCCMD_CONVT);
188 _delay_ms(DS18B20_CONV_TIME_MS);
189
190 if (ser != 0)
191 {
192 ow_master_matchrom(ser);
193 DBGP("match rom");
194
195 }
196 else
197 {
198 ow_reset();
199 ow_byte_write(OW_ROMCMD_SKIP);
200 DBGP("skip rom");
201 }
202
203
204 #if defined(DS18B20_PARASITE_POWER)
205 PINHI(DQ);
206 PINOUTP(DQ);
207 #endif
208
209
210 #if defined(DS18B20_PARASITE_POWER)
211 PININP(DQ);
212 PINLO(DQ);
213 #endif
214
215 rv = ds18b20_command(DS18B20_FUNCCMD_READSCRATCH, buf);
216 if (rv == SENSOR_ERR_OK)
217 {
218 *temp = ( ((int16_t)buf[1] << 8)| ((int16_t)buf[0] << 0) )/16;
219 }
220 /* TODO: evaluate CRC */
221 return rv;
222 }
223
224 /* === high level sensor functions ========================================= */
226 static inline void ds18b20_trigger(void *pctx, bool one_shot)
227 {
228 }
229
231 static inline uint8_t ds18b20_get_val(void *pctx, uint8_t *pdata)
232 {
233 uint8_t rv, err, i;
234 int16_t temp;
235 ds18b20_ctx_t *p = (ds18b20_ctx_t*) pctx;
236
237 rv = sizeof(sensor_temperature_t)*DS18B20_NB;
238 if (pdata != NULL)
239 {
240 rv = 0;
241 for (i = 0; i < DS18B20_NB; i++)
242 {
243 err = ds18b20_read_temperature(p->addr[i], &temp);
244 if (temp == 85 && err == SENSOR_ERR_OK)
245 {
246 /* TODO: add some quirks or heuristics,
247 If temp is const 85°C we will have a problem here.
248 What a silly chip design - to signal PWRON with a value
249 just from the middle of the valid data range!
250 */
251 err = SENSOR_ERR_PWRON;
252 }
253 if (err == SENSOR_ERR_OK)
254 {
255 ((sensor_temperature_t*)pdata)->type = SENSOR_DATA_TEMPERATURE;
256 ((sensor_temperature_t*)pdata)->sensor = SENSOR_DS18B20;
257 ((sensor_temperature_t*)pdata)->temp = (float)temp;
258 rv += sizeof(sensor_temperature_t);
259 pdata += sizeof(sensor_temperature_t);
260 }
261 else
262 {
263 *pdata++ = 0x80;
264 *pdata++ = err;
265 rv += 2;
266 }
267 ((ds18b20_ctx_t*)pctx)->g.last_error = err;
268 DBG("ds18b20_get_val: temp=%d, rv=%d, err=%d\n\r", temp, rv, err);
269 }
270 }
271
272 return rv;
273 }
274
275 static inline uint8_t ds18b20_get_raw(void *pctx, uint8_t *pdata)
276 {
277 return 0;
278 }
279
280 static inline void ds18b20_sleep(void *pctx)
281 {
282 }
283
290 static inline uint8_t sensor_create_ds18b20(void *pdata, bool raw)
291 {
292 uint8_t rv = sizeof(ds18b20_ctx_t);
293 ds18b20_ctx_t *pcfg;
294 ow_serial_t tmp_addr[DS18B20_NB] = DS18B20_ADDR;
295 if (pdata != NULL)
296 {
297 /* init generic sensor data */
298 pcfg = (ds18b20_ctx_t *)pdata;
299 pcfg->g.id = SENSOR_DS18B20;
300 pcfg->g.f_trigger = NULL;
301 pcfg->g.f_get_val = raw ? ds18b20_get_raw : ds18b20_get_val;
302 pcfg->g.f_sleep = NULL;
303 // ... more functions to setup
304
305 /* init private sensor data */
306 memcpy(pcfg->addr, tmp_addr, sizeof(tmp_addr));
307 /* TODO: scan bus for DS18B20 devices and store addresses sorted */
308
309 /* initialize sensor hardware */
310 }
311 return rv;
312 }
313
314 #ifdef __cplusplus
315 } /* extern "C" */
316 #endif
317
318 #endif /* DS18B20_H */
sensor_create_ds18b20
static uint8_t sensor_create_ds18b20(void *pdata, bool raw)
Definition: ds18b20.h:290
DS18B20_NB
#define DS18B20_NB
Definition: ds18b20.h:76
ds18b20_get_val
static uint8_t ds18b20_get_val(void *pctx, uint8_t *pdata)
Definition: ds18b20.h:231
ow_reset
uint8_t ow_reset(void)
ow_master_matchrom
void ow_master_matchrom(ow_serial_t ser)
ds18b20_command
static uint8_t ds18b20_command(uint8_t command, uint8_t *buf)
Definition: ds18b20.h:128
ds18b20_trigger
static void ds18b20_trigger(void *pctx, bool one_shot)
Definition: ds18b20.h:226
ow_byte_read
uint8_t ow_byte_read(void)
ow_byte_write
void ow_byte_write(uint8_t byte)
ds18b20_ctx_t
Definition: ds18b20.h:109
sensor_driver_t
Definition: sensor_defs.h:59
sensor_temperature_t
Definition: sensor_defs.h:69
ds18b20_read_temperature
static uint8_t ds18b20_read_temperature(ow_serial_t ser, int16_t *temp)
Definition: ds18b20.h:180