Skip to content

Commit 97d43a5

Browse files
committed
drivers/sensors: Add SHTC3 temperature and humidity sensor. The driver implements the standard IOCTL read functionality.
1 parent 24b245a commit 97d43a5

4 files changed

Lines changed: 326 additions & 0 deletions

File tree

drivers/sensors/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,5 +494,10 @@ if(CONFIG_SENSORS)
494494
list(APPEND SRCS cxd5602pwbimu.c)
495495
endif()
496496

497+
# SENSIRON SHTC3
498+
if(CONFIG_SENSORS_SHTC3)
499+
list(APPEND SRCS shtc3.c)
500+
endif()
501+
497502
target_sources(drivers PRIVATE ${SRCS})
498503
endif()

drivers/sensors/Kconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,24 @@ config SHT3X_DEBUG
19041904

19051905
endif # SENSORS_SHT3X
19061906

1907+
config SENSORS_SHTC3
1908+
bool "Sensirion SHTC3 Sensor"
1909+
depends on I2C
1910+
---help---
1911+
Enable driver support for the Sensirion SHTC3
1912+
temperature and humidity sensor.
1913+
1914+
if SENSORS_SHTC3
1915+
1916+
config SHTC3_I2C_FREQUENCY
1917+
int "SHTC3 I2C Frequency"
1918+
default 400000
1919+
1920+
endif # SENSORS_SHTC3
1921+
1922+
1923+
1924+
19071925
config SENSORS_SHT4X
19081926
bool "Sensirion SHT4x temperature and humidity sensor"
19091927
default n

drivers/sensors/shtc3.c

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/****************************************************************************
2+
* drivers/sensors/shtc3.c
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed to the Apache Software Foundation (ASF) under one or more
7+
* contributor license agreements. See the NOTICE file distributed with
8+
* this work for additional information regarding copyright ownership. The
9+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance with the
11+
* License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+
* License for the specific language governing permissions and limitations
19+
* under the License.
20+
*
21+
****************************************************************************/
22+
23+
#warning "This is a deprecated legacy sensor driver."
24+
25+
/****************************************************************************
26+
* Included Files
27+
****************************************************************************/
28+
29+
#include <nuttx/config.h>
30+
31+
#include <stdio.h>
32+
#include <errno.h>
33+
34+
#include <nuttx/debug.h>
35+
#include <nuttx/kmalloc.h>
36+
#include <nuttx/mutex.h>
37+
#include <nuttx/fs/fs.h>
38+
#include <nuttx/i2c/i2c_master.h>
39+
#include <nuttx/sensors/shtc3.h>
40+
41+
#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_SHTC3)
42+
43+
/****************************************************************************
44+
* Pre-processor Definitions
45+
****************************************************************************/
46+
47+
#define SHTC3_CMD_WAKEUP 0x3517
48+
#define SHTC3_CMD_SLEEP 0xb098
49+
#define SHTC3_CMD_MEASURE 0x7866 /* Read T first, clock stretching disabled */
50+
51+
/****************************************************************************
52+
* Private Types
53+
****************************************************************************/
54+
55+
struct shtc3_dev_s
56+
{
57+
FAR struct i2c_master_s *i2c;
58+
uint8_t addr;
59+
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
60+
bool unlinked;
61+
int16_t crefs;
62+
#endif
63+
mutex_t devlock;
64+
};
65+
66+
/****************************************************************************
67+
* Private Function Prototypes
68+
****************************************************************************/
69+
70+
static int shtc3_write_cmd(FAR struct shtc3_dev_s *priv, uint16_t cmd);
71+
static int shtc3_read_data(FAR struct shtc3_dev_s *priv, FAR uint8_t *data);
72+
static uint8_t shtc3_crc(uint16_t word);
73+
static int shtc3_read_values(FAR struct shtc3_dev_s *priv,
74+
FAR struct shtc3_meas_data_s *out);
75+
static int shtc3_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
76+
77+
/****************************************************************************
78+
* Private Data
79+
****************************************************************************/
80+
81+
static const struct file_operations g_shtc3fops =
82+
{
83+
NULL, /* open */
84+
NULL, /* close */
85+
NULL, /* read */
86+
NULL, /* write */
87+
NULL, /* seek */
88+
shtc3_ioctl, /* ioctl */
89+
NULL, /* mmap */
90+
NULL, /* truncate */
91+
NULL, /* poll */
92+
NULL, /* readv */
93+
NULL /* writev */
94+
};
95+
96+
/****************************************************************************
97+
* Private Functions
98+
****************************************************************************/
99+
100+
static int shtc3_write_cmd(FAR struct shtc3_dev_s *priv, uint16_t cmd)
101+
{
102+
struct i2c_msg_s msg;
103+
uint8_t buf[2];
104+
105+
buf[0] = cmd >> 8;
106+
buf[1] = cmd & 0xff;
107+
108+
msg.frequency = CONFIG_SHTC3_I2C_FREQUENCY;
109+
msg.addr = priv->addr;
110+
msg.flags = 0;
111+
msg.buffer = buf;
112+
msg.length = 2;
113+
114+
return I2C_TRANSFER(priv->i2c, &msg, 1);
115+
}
116+
117+
static int shtc3_read_data(FAR struct shtc3_dev_s *priv, FAR uint8_t *data)
118+
{
119+
struct i2c_msg_s msg;
120+
121+
msg.frequency = CONFIG_SHTC3_I2C_FREQUENCY;
122+
msg.addr = priv->addr;
123+
msg.flags = I2C_M_READ;
124+
msg.buffer = data;
125+
msg.length = 6;
126+
127+
return I2C_TRANSFER(priv->i2c, &msg, 1);
128+
}
129+
130+
static uint8_t shtc3_crc(uint16_t word)
131+
{
132+
static const uint8_t crc_table[16] =
133+
{
134+
0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97,
135+
0xb9, 0x88, 0xdb, 0xea, 0x7d, 0x4c, 0x1f, 0x2e
136+
};
137+
138+
uint8_t crc = 0xff;
139+
crc ^= word >> 8;
140+
crc = (crc << 4) ^ crc_table[crc >> 4];
141+
crc = (crc << 4) ^ crc_table[crc >> 4];
142+
crc ^= word & 0xff;
143+
crc = (crc << 4) ^ crc_table[crc >> 4];
144+
crc = (crc << 4) ^ crc_table[crc >> 4];
145+
146+
return crc;
147+
}
148+
149+
static int shtc3_read_values(FAR struct shtc3_dev_s *priv,
150+
FAR struct shtc3_meas_data_s *out)
151+
{
152+
uint8_t data[6];
153+
uint16_t temp_raw;
154+
uint16_t hum_raw;
155+
int ret;
156+
157+
ret = shtc3_write_cmd(priv, SHTC3_CMD_WAKEUP);
158+
if (ret < 0)
159+
{
160+
return ret;
161+
}
162+
163+
nxsched_usleep(240);
164+
165+
ret = shtc3_write_cmd(priv, SHTC3_CMD_MEASURE);
166+
if (ret < 0)
167+
{
168+
return ret;
169+
}
170+
171+
nxsched_usleep(13000);
172+
173+
ret = shtc3_read_data(priv, data);
174+
if (ret < 0)
175+
{
176+
return ret;
177+
}
178+
179+
shtc3_write_cmd(priv, SHTC3_CMD_SLEEP);
180+
181+
temp_raw = (data[0] << 8) | data[1];
182+
if (shtc3_crc(temp_raw) != data[2])
183+
{
184+
return -EIO;
185+
}
186+
187+
hum_raw = (data[3] << 8) | data[4];
188+
if (shtc3_crc(hum_raw) != data[5])
189+
{
190+
return -EIO;
191+
}
192+
193+
out->temperature = -45.0f + 175.0f * (float)temp_raw / 65535.0f;
194+
out->humidity = 100.0f * (float)hum_raw / 65535.0f;
195+
196+
return OK;
197+
}
198+
199+
static int shtc3_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
200+
{
201+
FAR struct inode *inode = filep->f_inode;
202+
FAR struct shtc3_dev_s *priv = inode->i_private;
203+
int ret;
204+
205+
ret = nxmutex_lock(&priv->devlock);
206+
if (ret < 0)
207+
{
208+
return ret;
209+
}
210+
211+
if (cmd == SNIOC_READ_CONVERT_DATA)
212+
{
213+
FAR struct shtc3_meas_data_s *data =
214+
(FAR struct shtc3_meas_data_s *)arg;
215+
216+
ret = shtc3_read_values(priv, data);
217+
}
218+
else
219+
{
220+
ret = -ENOTTY;
221+
}
222+
223+
nxmutex_unlock(&priv->devlock);
224+
return ret;
225+
}
226+
227+
/****************************************************************************
228+
* Public Functions
229+
****************************************************************************/
230+
231+
int shtc3_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
232+
uint8_t addr)
233+
{
234+
FAR struct shtc3_dev_s *priv;
235+
236+
priv = kmm_zalloc(sizeof(struct shtc3_dev_s));
237+
if (priv == NULL)
238+
{
239+
return -ENOMEM;
240+
}
241+
242+
priv->i2c = i2c;
243+
priv->addr = addr;
244+
nxmutex_init(&priv->devlock);
245+
246+
return register_driver(devpath, &g_shtc3fops, 0666, priv);
247+
}
248+
#endif /* CONFIG_I2C && CONFIG_SENSORS_SHTC3 */

include/nuttx/sensors/shtc3.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/****************************************************************************
2+
* include/nuttx/sensors/shtc3.h
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed to the Apache Software Foundation (ASF) under one or more
7+
* contributor license agreements. See the NOTICE file distributed with
8+
* this work for additional information regarding copyright ownership. The
9+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance with the
11+
* License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+
* License for the specific language governing permissions and limitations
19+
* under the License.
20+
*
21+
****************************************************************************/
22+
23+
#ifndef __INCLUDE_NUTTX_SENSORS_SHTC3_H
24+
#define __INCLUDE_NUTTX_SENSORS_SHTC3_H
25+
26+
/****************************************************************************
27+
* Included Files
28+
****************************************************************************/
29+
30+
#include <nuttx/config.h>
31+
#include <nuttx/sensors/ioctl.h>
32+
33+
#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_SHTC3)
34+
35+
/****************************************************************************
36+
* Public Types
37+
****************************************************************************/
38+
39+
struct i2c_master_s;
40+
41+
struct shtc3_meas_data_s
42+
{
43+
float temperature; /* Temperature in degrees Celsius */
44+
float humidity; /* Relative humidity in percent */
45+
};
46+
47+
/****************************************************************************
48+
* Public Function Prototypes
49+
****************************************************************************/
50+
51+
int shtc3_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
52+
uint8_t addr);
53+
54+
#endif /* CONFIG_I2C && CONFIG_SENSORS_SHTC3 */
55+
#endif /* __INCLUDE_NUTTX_SENSORS_SHTC3_H */

0 commit comments

Comments
 (0)