Contiki-NG
sht25.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Zolertia <http://www.zolertia.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. 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  * 3. Neither the name of the Institute 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 INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * 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 INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 /*---------------------------------------------------------------------------*/
33 /**
34  * \addtogroup zoul-sht25-sensor
35  * @{
36  *
37  * \file
38  * SHT25 temperature and humidity sensor driver
39  * \author
40  * Antonio Lignan <alinan@zolertia.com>
41  */
42 /*---------------------------------------------------------------------------*/
43 #include <stdio.h>
44 #include "contiki.h"
45 #include "dev/i2c.h"
46 #include "dev/sht25.h"
47 #include "lib/sensors.h"
48 /*---------------------------------------------------------------------------*/
49 #define DEBUG 0
50 #if DEBUG
51 #define PRINTF(...) printf(__VA_ARGS__)
52 #else
53 #define PRINTF(...)
54 #endif
55 /*---------------------------------------------------------------------------*/
56 static uint8_t enabled;
57 static uint8_t user_reg;
58 /*---------------------------------------------------------------------------*/
59 static int
60 status(int type)
61 {
62  switch(type) {
63  case SENSORS_ACTIVE:
64  case SENSORS_READY:
65  return enabled;
66  }
67  return 0;
68 }
69 /*---------------------------------------------------------------------------*/
70 static uint16_t
71 sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t num)
72 {
73  if((buf == NULL) || (num <= 0)) {
74  return SHT25_ERROR;
75  }
76 
78  if(i2c_single_send(SHT25_ADDR, reg) == I2C_MASTER_ERR_NONE) {
79  if(i2c_burst_receive(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) {
80  return SHT25_SUCCESS;
81  }
82  }
83  return SHT25_ERROR;
84 }
85 /*---------------------------------------------------------------------------*/
86 static int16_t
87 sht25_convert(uint8_t variable, uint16_t value)
88 {
89  int16_t rd;
90  uint32_t buff;
91 
92  /* Clear the status bits */
93  buff = (uint32_t)(value & ~SHT25_STATUS_BITS_MASK);
94 
95  if(variable == SHT25_VAL_TEMP) {
96  buff *= 17572;
97  buff = buff >> 16;
98  rd = (int16_t)buff - 4685;
99  } else {
100  buff *= 12500;
101  buff = buff >> 16;
102  rd = (int16_t)buff - 600;
103  rd = (rd > 10000) ? 10000 : rd;
104  }
105  return rd;
106 }
107 /*---------------------------------------------------------------------------*/
108 static int
109 sht25_read(uint8_t variable, uint16_t *rd)
110 {
111  uint8_t buf[2];
112  uint16_t raw;
113 
114  if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) {
115  PRINTF("SHT25: invalid sensor requested\n");
116  return SHT25_ERROR;
117  }
118 
119  if(sht25_read_reg(variable, buf, 2) == SHT25_SUCCESS) {
120  raw = (buf[0] << 8) + buf[1];
121  *rd = sht25_convert(variable, raw);
122  return SHT25_SUCCESS;
123  }
124 
125  PRINTF("SHT25: failed to read sensor\n");
126  return SHT25_ERROR;
127 }
128 /*---------------------------------------------------------------------------*/
129 static int
130 sht25_write_reg(uint8_t *buf, uint8_t num)
131 {
132  if((buf == NULL) || (num <= 0)) {
133  PRINTF("SHT25: invalid write values\n");
134  return SHT25_ERROR;
135  }
136 
138  if(i2c_burst_send(SHT25_ADDR, buf, num) == I2C_MASTER_ERR_NONE) {
139  return SHT25_SUCCESS;
140  }
141  return SHT25_ERROR;
142 }
143 /*---------------------------------------------------------------------------*/
144 static int
145 sht25_read_user_register(void)
146 {
147  if(sht25_read_reg(SHT2X_UREG_READ, &user_reg, 1) == SHT25_SUCCESS) {
148  PRINTF("SHT25: user register 0x%02X\n", user_reg);
149  return SHT25_SUCCESS;
150  }
151  PRINTF("SHT25: failed to read user register\n");
152  return SHT25_ERROR;
153 }
154 /*---------------------------------------------------------------------------*/
155 static int
156 value(int type)
157 {
158  uint16_t val;
159 
160  if(!enabled) {
161  PRINTF("SHT25: sensor not started\n");
162  return SHT25_ERROR;
163  }
164 
165  if((type != SHT25_VAL_TEMP) && (type != SHT25_VAL_HUM) &&
166  (type != SHT25_VOLTAGE_ALARM)) {
167  PRINTF("SHT25: invalid value requested\n");
168  return SHT25_ERROR;
169  }
170 
171  if(type == SHT25_VOLTAGE_ALARM) {
172  if(sht25_read_user_register() == SHT25_SUCCESS) {
173  return (user_reg & SHT2x_LOW_VOLTAGE_MASK) >> SHT2x_LOW_VOLTAGE_SHIFT;
174  }
175  } else {
176  if(sht25_read(type, &val) == SHT25_SUCCESS) {
177  return val;
178  }
179  }
180  return SHT25_ERROR;
181 }
182 /*---------------------------------------------------------------------------*/
183 static int
184 configure(int type, int value)
185 {
186  uint8_t buf[2];
187 
188  if((type != SHT25_ACTIVE) && (type != SHT25_SOFT_RESET) &&
189  (type != SHT25_RESOLUTION)) {
190  PRINTF("SHT25: option not supported\n");
191  return SHT25_ERROR;
192  }
193 
194  switch(type) {
195  case SHT25_ACTIVE:
196  if(value) {
197  i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN,
198  I2C_SCL_NORMAL_BUS_SPEED);
199 
200  /* Read the user config register */
201  if(sht25_read_user_register() == SHT25_SUCCESS) {
202  enabled = value;
203  return SHT25_SUCCESS;
204  }
205  }
206 
207  case SHT25_SOFT_RESET:
208  buf[0] = SHT2X_SOFT_RESET;
209  if(sht25_write_reg(&buf[0], 1) != SHT25_SUCCESS) {
210  PRINTF("SHT25: failed to reset the sensor\n");
211  return SHT25_ERROR;
212  }
213  clock_delay_usec(SHT25_RESET_DELAY);
214  return SHT25_SUCCESS;
215 
216  case SHT25_RESOLUTION:
217  if((value != SHT2X_RES_14T_12RH) && (value != SHT2X_RES_12T_08RH) &&
218  (value != SHT2X_RES_13T_10RH) && (value != SHT2X_RES_11T_11RH)) {
219  PRINTF("SHT25: invalid resolution value\n");
220  return SHT25_ERROR;
221  }
222 
223  user_reg &= ~SHT2X_RES_11T_11RH;
224  user_reg |= value;
225  buf[0] = SHT2X_UREG_WRITE;
226  buf[1] = user_reg;
227 
228  if(sht25_write_reg(buf, 2) == SHT25_SUCCESS) {
229  PRINTF("SHT25: new user register value 0x%02X\n", user_reg);
230  return SHT25_SUCCESS;
231  }
232 
233  default:
234  return SHT25_ERROR;
235  }
236 
237  return SHT25_ERROR;
238 }
239 /*---------------------------------------------------------------------------*/
240 SENSORS_SENSOR(sht25, SHT25_SENSOR, value, configure, status);
241 /*---------------------------------------------------------------------------*/
242 /** @} */
uint8_t i2c_burst_send(uint8_t slave_addr, uint8_t *data, uint8_t len)
Perform all operations to send multiple bytes to a slave.
Definition: i2c.c:188
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition: clock.c:150
void i2c_init(uint8_t port_sda, uint8_t pin_sda, uint8_t port_scl, uint8_t pin_scl, uint32_t bus_speed)
Initialize the I2C peripheral and pins.
Definition: i2c.c:49
uint8_t i2c_burst_receive(uint8_t slave_addr, uint8_t *data, uint8_t len)
Perform all operations to receive multiple bytes from a slave.
Definition: i2c.c:218
uint8_t i2c_single_send(uint8_t slave_addr, uint8_t data)
Perform all operations to send a byte to a slave.
Definition: i2c.c:159
void i2c_master_enable(void)
Enable master I2C module.
Definition: i2c.c:91