1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "aos/kernel.h"
11 #include "sensor_drv_api.h"
12 #include "sensor_hal.h"
13
14 /* ADI Temperature SENSOR REGISTER MAP */
15 #define ADT7410_BIT(x) ((uint8_t)x)
16 #define ADT7410_I2C_ADDR (0x48)
17 //#define ADT7410_I2C_ADDR_TRANS(n) ((n)<<1)
18 //#define ADT7410_I2C_ADDR ADT7410_I2C_ADDR_TRANS(ADT7410_I2C_ADDR1)
19
20 // Who Am I
21 #define ADT7410_WHO_AM_I_REG (uint8_t)0x0B
22 #define ADT7410_WHO_AM_I_VAL (uint8_t)0xCB
23
24 // ADI Temperature REGISTER
25 #define ADT7410_TEMPREG_MSB (uint8_t)0x00
26 #define ADT7410_TEMPREG_LSB (uint8_t)0x01
27 #define ADT7410_STATUS (uint8_t)0x02
28 #define ADT7410_CONFIG (uint8_t)0x03
29 #define ADT7410_THIGH_MSB (uint8_t)0x04
30 #define ADT7410_THIGH_LSB (uint8_t)0x05
31 #define ADT7410_TLOW_MSB (uint8_t)0x06
32 #define ADT7410_TLOW_LSB (uint8_t)0x07
33 #define ADT7410_TCRIT_MSB (uint8_t)0x08
34 #define ADT7410_TCRIT_LSB (uint8_t)0x09
35 #define ADT7410_THYST (uint8_t)0x0A
36 #define ADT7410_SOFT_RESET (uint8_t)0x2F
37
38
39 typedef enum
40 {
41 ADT7410_OD_13bits = (uint8_t)0x00, /*!< Output Data : 13bits */
42 ADT7410_OD_16bits = (uint8_t)0x01, /*!< Output Data : 16bits */
43 } adt7410_od_resolution;
44
45 typedef enum
46 {
47 ADT7410_OPMODE_CONTINUOUS =
48 (uint8_t)0x00, /*!< Operation Mode continuously */
49 ADT7410_OPMODE_ONESHOT = (uint8_t)0x01, /*!< Operation Mode one shot */
50 ADT7410_OPMODE_FASTONESHOT =
51 (uint8_t)0x02, /*!< Operation Mode fast one shot */
52 ADT7410_OPMODE_SHUTDOWN = (uint8_t)0x03 /*!< Operation Mode shut down */
53 } adt7410_opmode_s;
54
55 i2c_dev_t adt7410_ctx = {
56 .port = 3,
57 .config.address_width = 8,
58 .config.dev_addr = ADT7410_I2C_ADDR << 1,
59 };
60
drv_temp_adi_adt7410_validate_id(i2c_dev_t * drv,uint8_t id_value)61 static int drv_temp_adi_adt7410_validate_id(i2c_dev_t *drv, uint8_t id_value)
62 {
63 uint8_t value = 0x00;
64 int ret = 0;
65
66 if (drv == NULL) {
67 return -1;
68 }
69
70 ret = sensor_i2c_read(drv, ADT7410_WHO_AM_I_REG, &value, I2C_DATA_LEN,
71 I2C_OP_RETRIES);
72 if (unlikely(ret)) {
73 return ret;
74 }
75
76 if (id_value != value) {
77 return -1;
78 }
79 return 0;
80 }
81
drv_temp_adi_adt7410_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)82 static int drv_temp_adi_adt7410_set_power_mode(i2c_dev_t * drv,
83 dev_power_mode_e mode)
84 {
85 uint8_t value = 0x00;
86 int ret = 0;
87
88 ret = sensor_i2c_read(drv, ADT7410_CONFIG, &value, I2C_DATA_LEN,
89 I2C_OP_RETRIES);
90 if (unlikely(ret)) {
91 return ret;
92 }
93
94 switch (mode) {
95 case DEV_POWER_ON: {
96 value &= ~(0x03 << 5);
97 value |= (ADT7410_OPMODE_CONTINUOUS << 5);
98 ret = sensor_i2c_write(drv, ADT7410_CONFIG, &value, I2C_DATA_LEN,
99 I2C_OP_RETRIES);
100 if (unlikely(ret)) {
101 return ret;
102 }
103 } break;
104
105 case DEV_POWER_OFF: {
106 value &= ~(0x03 << 5);
107 value |= (ADT7410_OPMODE_SHUTDOWN << 5);
108 ret = sensor_i2c_write(drv, ADT7410_CONFIG, &value, I2C_DATA_LEN,
109 I2C_OP_RETRIES);
110 if (unlikely(ret)) {
111 return ret;
112 }
113 } break;
114
115 default:
116 break;
117 }
118 return 0;
119 }
120
drv_temp_adi_adt7410_set_od_res(i2c_dev_t * drv,adt7410_od_resolution odr)121 static int drv_temp_adi_adt7410_set_od_res(i2c_dev_t * drv,
122 adt7410_od_resolution odr)
123 {
124 uint8_t value = 0x00;
125 int ret = 0;
126
127 ret = sensor_i2c_read(drv, ADT7410_CONFIG, &value, I2C_DATA_LEN,
128 I2C_OP_RETRIES);
129 if (unlikely(ret)) {
130 return ret;
131 }
132 value &= ~0x80;
133 value |= (uint8_t)(odr << 7);
134
135 ret = sensor_i2c_write(drv, ADT7410_CONFIG, &value, I2C_DATA_LEN,
136 I2C_OP_RETRIES);
137 if (unlikely(ret)) {
138 return ret;
139 }
140 return 0;
141 }
142
drv_temp_adi_adt7410_set_default_config(i2c_dev_t * drv)143 static int drv_temp_adi_adt7410_set_default_config(i2c_dev_t *drv)
144 {
145 int ret = 0;
146
147 ret = drv_temp_adi_adt7410_set_power_mode(drv, DEV_POWER_OFF);
148 if (unlikely(ret)) {
149 return ret;
150 }
151 ret = drv_temp_adi_adt7410_set_od_res(drv, ADT7410_OD_16bits);
152 if (unlikely(ret)) {
153 return ret;
154 }
155
156 /* you also can set the low-pass filter and cut off config here */
157 return 0;
158 }
159
160
drv_temp_adi_adt7410_irq_handle(void)161 static void drv_temp_adi_adt7410_irq_handle(void)
162 {
163 /* no handle so far */
164 }
165
drv_temp_adi_adt7410_open(void)166 static int drv_temp_adi_adt7410_open(void)
167 {
168 int ret = 0;
169 ret = drv_temp_adi_adt7410_set_power_mode(&adt7410_ctx, DEV_POWER_ON);
170 if (unlikely(ret)) {
171 return -1;
172 }
173 LOG("%s %s successfully \n", SENSOR_STR, __func__);
174 return 0;
175 }
176
drv_temp_adi_adt7410_close(void)177 static int drv_temp_adi_adt7410_close(void)
178 {
179 int ret = 0;
180 ret = drv_temp_adi_adt7410_set_power_mode(&adt7410_ctx, DEV_POWER_OFF);
181 if (unlikely(ret)) {
182 return -1;
183 }
184 LOG("%s %s successfully \n", SENSOR_STR, __func__);
185 return 0;
186 }
187
188
drv_temp_adi_adt7410_read(void * buf,size_t len)189 static int drv_temp_adi_adt7410_read(void *buf, size_t len)
190 {
191 int ret = 0;
192 size_t size;
193 uint8_t data[2], buffer[2];
194 int16_t tmp;
195 int16_t temp;
196 temperature_data_t *pdata = (temperature_data_t *)buf;
197 if (buf == NULL) {
198 return -1;
199 }
200
201 size = sizeof(temperature_data_t);
202 if (len < size) {
203 return -1;
204 }
205
206 ret = sensor_i2c_read(&adt7410_ctx, ADT7410_TEMPREG_MSB, buffer, 2,
207 I2C_OP_RETRIES);
208 tmp = (((uint16_t)buffer[0]) << 8) | buffer[1];
209 if (tmp > 0)
210 temp = (tmp * 10) / 128;
211 else
212 temp = ((tmp - 65536) * 10) / 128;
213 data[0] = temp & 0x0FF;
214 data[1] = temp >> 8;
215
216 if (unlikely(ret)) {
217 return -1;
218 }
219
220 /* hatch the temp data here*/
221 for (int i = 0; i < 2; i++) {
222 pdata->t |= (((uint32_t)data[i]) << (8 * i));
223 }
224
225 pdata->timestamp = aos_now_ms();
226
227 return (int)size;
228 }
229
drv_temp_adi_adt7410_write(const void * buf,size_t len)230 static int drv_temp_adi_adt7410_write(const void *buf, size_t len)
231 {
232 return 0;
233 }
234
drv_temp_adi_adt7410_ioctl(int cmd,unsigned long arg)235 static int drv_temp_adi_adt7410_ioctl(int cmd, unsigned long arg)
236 {
237 int ret = 0;
238
239 switch (cmd) {
240 case SENSOR_IOCTL_ODR_SET: {
241 ret = drv_temp_adi_adt7410_set_od_res(&adt7410_ctx, arg);
242 if (unlikely(ret)) {
243 return -1;
244 }
245 } break;
246 case SENSOR_IOCTL_SET_POWER: {
247 ret = drv_temp_adi_adt7410_set_power_mode(&adt7410_ctx, arg);
248 if (unlikely(ret)) {
249 return -1;
250 }
251 } break;
252 case SENSOR_IOCTL_GET_INFO: {
253 /* fill the dev info here */
254 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
255 info->model = "adt7410";
256 info->range_max = 105;
257 info->range_min = -40;
258 info->unit = dCelsius;
259
260 } break;
261
262 default:
263 break;
264 }
265
266 LOG("%s %s successfully \n", SENSOR_STR, __func__);
267 return 0;
268 }
269
drv_temp_adi_adt7410_init(void)270 int drv_temp_adi_adt7410_init(void)
271 {
272 int ret = 0;
273 sensor_obj_t sensor;
274 memset(&sensor, 0, sizeof(sensor));
275
276 /* fill the sensor obj parameters here */
277 sensor.tag = TAG_DEV_TEMP;
278 sensor.path = dev_temp_path;
279 sensor.io_port = I2C_PORT;
280 sensor.open = drv_temp_adi_adt7410_open;
281 sensor.close = drv_temp_adi_adt7410_close;
282 sensor.read = drv_temp_adi_adt7410_read;
283 sensor.write = drv_temp_adi_adt7410_write;
284 sensor.ioctl = drv_temp_adi_adt7410_ioctl;
285 sensor.irq_handle = drv_temp_adi_adt7410_irq_handle;
286
287
288 ret = sensor_create_obj(&sensor);
289 if (unlikely(ret)) {
290 return -1;
291 }
292
293 ret = drv_temp_adi_adt7410_validate_id(&adt7410_ctx, ADT7410_WHO_AM_I_VAL);
294 if (unlikely(ret)) {
295 return -1;
296 }
297
298 /* set the default config for the sensor here */
299 ret = drv_temp_adi_adt7410_set_default_config(&adt7410_ctx);
300 if (unlikely(ret)) {
301 return -1;
302 }
303
304 LOG("%s %s successfully \n", SENSOR_STR, __func__);
305
306 return 0;
307 }
308
309 SENSOR_DRV_ADD(drv_temp_adi_adt7410_init);
310
311