µracoli Manual Version foo

- µracoli
- User Guide
- Reference Guide

lm73.h
1 /* Copyright (c) 2013 - 2014 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 LM73_H
30 #define LM73_H
31
43 /* === includes ============================================================ */
44 #include "sensor_defs.h"
45
46 /* === macros ============================================================== */
47 #define LM73_DEBUG (0)
48 #if LM73_DEBUG == 1
49 # include "hif.h"
50 # define DBG_LM73(...) PRINTF(__VA_ARGS__)
51 #else
52 # define DBG_LM73(...)
53 #endif
54
55 #define LM73_ADDR_0 (0x48)
56 #define LM73_ADDR_1 (0x49)
57 #define LM73_ADDR_2 (0x4A)
59 #define LM73_ADDR_3 (0x4C)
60 #define LM73_ADDR_4 (0x4D)
61 #define LM73_ADDR_5 (0x4E)
63 #define LM73_PTR_TEMP (0x00)
64 #define LM73_PTR_CFG (0x01)
65 #define LM73_PTR_THIGH (0x02)
66 #define LM73_PTR_TLOW (0x03)
67 #define LM73_PTR_STATUS (0x04)
68 #define LM73_PTR_ID (0x07)
69
70 #define LM73_CFG_RESERVED (0x03)
71 #define LM73_CFG_ONE_SHOT (0x04)
72 #define LM73_CFG_ALERT_RST (0x08)
73 #define LM73_CFG_ALERT_POL (0x10)
74 #define LM73_CFG_ALERT_EN (0x20)
75 #define LM73_CFG_PWR_DOWN (0x80)
76
77 #define LM73_STATUS_DAV (0x01)
78 #define LM73_STATUS_TLOW (0x02)
79 #define LM73_STATUS_THIGH (0x04)
80 #define LM73_STATUS_ALERT (0x08)
81 #define LM73_STATUS_RES (0x60)
82
88 #define LM73_T_BUS_FREE_US (8)
89
90 // LM73_TEMP_SCALE = 1/128
91 #define LM73_REG_TO_TEMP_SCALE (0.0078125)
92 #define LM73_TEMP_TO_REG_SCALE (128)
93 /* === types =============================================================== */
94 typedef struct
95 {
96 sensor_driver_t g;
97 uint8_t addr;
98 int8_t temp_offset;
99 } lm73_ctx_t;
100
101 /* === prototypes ========================================================== */
102 #ifdef __cplusplus
103 extern "C" {
104 #endif
105 /* === low level functions ================================================== */
106
107 static inline uint8_t lm73_byte_read(lm73_ctx_t *pctx, uint8_t addr)
108 {
109 uint8_t buf[1] = {addr,};
110 i2c_master_writeread(pctx->addr, buf, 1, buf, 1);
111 DBG_LM73("d: lm73_byte_read: addr=0x%x val=0x%x\n", addr, buf[0]);
112 return buf[0];
113 }
114
115 static inline void lm73_byte_write(lm73_ctx_t *pctx, uint8_t addr, uint8_t val)
116 {
117 uint8_t buf[2] = {addr, val};
118 i2c_master_writeread(pctx->addr, buf, 2, NULL, 0);
119 DBG_LM73("d: lm73_byte_write: addr=0x%x val=0x%x\n", addr, val);
120 }
121
122 static inline uint16_t lm73_word_read(lm73_ctx_t *pctx, uint8_t addr)
123 {
124 uint16_t rv;
125 uint8_t buf[2] = {addr,};
126 i2c_master_writeread(pctx->addr, buf, 1, buf, 2);
127 rv = (buf[0]<<8) | buf[1];
128 DBG_LM73("d: lm73_word_read: addr=0x%x val=0x%x\n", addr, rv);
129 return rv;
130 }
131
132 static inline void lm73_word_write(lm73_ctx_t *pctx, uint8_t addr, uint16_t val)
133 {
134 uint8_t buf[3] = {addr, ((val>>8) &0xff), (val & 0xff)};
135 i2c_master_writeread(pctx->addr, buf, 3, NULL, 0);
136 DBG_LM73("d: lm73_word_write: addr=0x%x val=0x%x\n", addr, val);
137 }
138
139 static inline int16_t lm73_get(lm73_ctx_t *pctx)
140 {
141 int16_t rv;
142 rv = lm73_word_read(pctx, LM73_PTR_TEMP);
143 DBG_LM73("d: lm73_get: val=0x%x\n", rv);
144 return rv;
145 }
146
147 static inline void lm73_set_upper_limit(lm73_ctx_t *pctx, int16_t val)
148 {
149 lm73_word_write(pctx, LM73_PTR_THIGH, val);
150 }
151
152 static inline void lm73_set_lower_limit(lm73_ctx_t *pctx, int16_t val)
153 {
154 lm73_word_write(pctx, LM73_PTR_TLOW, val);
155 }
156
157 static inline uint16_t lm73_get_id(lm73_ctx_t *pctx)
158 {
159 uint8_t buf[2] = {7};
160 i2c_master_writeread(pctx->addr, buf, 1, buf, 2);
161 return buf[0] | buf[1]*256;
162 }
163
164 static inline float lm73_scale(int16_t val)
165 {
166 return LM73_REG_TO_TEMP_SCALE * (val);
167 }
168
169
170 /* === high level sensor functions ========================================= */
171
172 static inline void lm73_trigger(void *pctx, bool one_shot)
173 {
174 uint8_t tmp;
175 tmp = lm73_byte_read(((lm73_ctx_t *)pctx), LM73_PTR_CFG);
176 if (one_shot)
177 {
178 tmp |= (LM73_CFG_PWR_DOWN | LM73_CFG_ONE_SHOT);
179 }
180 else
181 {
182 tmp &= ~LM73_CFG_PWR_DOWN;
183 }
184 tmp &= ~LM73_CFG_RESERVED;
185 tmp |= 1<<6;
186 DELAY_US(LM73_T_BUS_FREE_US);
187 lm73_byte_write(((lm73_ctx_t *)pctx), LM73_PTR_CFG, tmp);
188 DBG_LM73("d: lm73_trigger: cfg=0x%x, one_shot=%d\n", tmp, one_shot);
189 }
190
191 static inline uint8_t lm73_get_val(void *pctx, uint8_t *pdata)
192 {
193 uint8_t rv, status;
194 uint16_t temp;
195 rv = sizeof(sensor_temperature_t);
196 if (pdata != NULL)
197 {
198 temp = lm73_get((lm73_ctx_t *)pctx);
199 status = lm73_byte_read(((lm73_ctx_t *)pctx), LM73_PTR_STATUS);
200 if (status & LM73_STATUS_DAV)
201 {
202 ((sensor_temperature_t*)pdata)->type = SENSOR_DATA_TEMPERATURE;
203 ((sensor_temperature_t*)pdata)->sensor = SENSOR_LM73;
204 ((sensor_temperature_t*)pdata)->temp = lm73_scale(temp);
205 }
206 else
207 {
208 rv = 0;
209 }
210 DBG_LM73("d: lm73_get_val: temp=%d, status=0x%x\n", temp, status);
211
212 }
213 return rv;
214
215 }
216 static inline uint8_t lm73_get_raw(void *pctx, uint8_t *pdata)
217 {
218 uint8_t rv, status;
219 uint16_t tempi;
220 rv = sizeof(sensor_raw_t) - 1 + sizeof(tempi);
221 if (pdata != NULL)
222 {
223 status = lm73_byte_read(((lm73_ctx_t *)pctx), LM73_PTR_STATUS);
224 if (status & LM73_STATUS_DAV)
225 {
226 ((sensor_raw_t*)pdata)->type = SENSOR_DATA_RAW | sizeof(tempi);
227 ((sensor_raw_t*)pdata)->sensor = SENSOR_LM73;
228 tempi = lm73_get((lm73_ctx_t *)pctx);
229 ((sensor_raw_t*)pdata)->data[0] = tempi & 0xff;
230 ((sensor_raw_t*)pdata)->data[1] = (tempi >> 8) & 0xff;
231 }
232 else
233 {
234 rv = 0;
235 }
236 }
237 return rv;
238 }
239
240 static inline void lm73_sleep(void *pctx)
241 {
242 uint8_t tmp;
243 tmp = lm73_byte_read(((lm73_ctx_t *)pctx), LM73_PTR_CFG);
244 tmp |= LM73_CFG_PWR_DOWN;
245 DELAY_US(LM73_T_BUS_FREE_US);
246 lm73_byte_write(((lm73_ctx_t *)pctx), LM73_PTR_CFG, tmp);
247 DBG_LM73("d: lm73_sleep: val=0x%x\n", tmp);
248 }
249
270 static inline uint8_t sensor_create_lm73(void *pdata,
271 bool raw,
272 uint8_t addr,
273 int8_t temp_offset)
274 {
275 uint8_t rv = sizeof(lm73_ctx_t);
276 lm73_ctx_t *pcfg;
277 uint8_t tst;
278
279 if (pdata != NULL)
280 {
281 /* init generic sensor data */
282 pcfg = (lm73_ctx_t *)pdata;
283 pcfg->g.id = SENSOR_LM73;
284 pcfg->g.f_trigger = lm73_trigger;
285 pcfg->g.f_get_val = raw ? lm73_get_raw : lm73_get_val;
286 pcfg->g.f_sleep = lm73_sleep;
287 // ... more functions to setup
288
289 /* init private sensor data */
290 pcfg->addr = addr;
291 pcfg->temp_offset = temp_offset;
292
293 /* initialize sensor */
294 tst = i2c_probe(pcfg->addr);
295 pcfg->g.last_error = tst ? SENSOR_ERR_OK : SENSOR_ERR_INIT;
296 DBG_LM73("d: lm73_init: addr=0x%x\n", addr);
297 }
298 return rv;
299 }
300
301 #ifdef __cplusplus
302 } /* extern "C" */
303 #endif
304
305 #endif /* #ifndef LM73_H */
DELAY_US
#define DELAY_US(x)
Macro for delays with us resolution.
Definition: board.h:89
i2c_probe
uint8_t i2c_probe(uint8_t devaddr)
LM73_T_BUS_FREE_US
#define LM73_T_BUS_FREE_US
Definition: lm73.h:88
i2c_master_writeread
uint8_t i2c_master_writeread(uint8_t devaddr, uint8_t *writebuf, uint8_t bytestowrite, uint8_t *readbuf, uint8_t bytestoread)
sensor_driver_t
Definition: sensor_defs.h:59
sensor_temperature_t
Definition: sensor_defs.h:69
sensor_create_lm73
static uint8_t sensor_create_lm73(void *pdata, bool raw, uint8_t addr, int8_t temp_offset)
Definition: lm73.h:270
sensor_raw_t
Definition: sensor_defs.h:104