Skip to content

Commit c82d2ff

Browse files
authored
Merge pull request #74 from qcabrol/master
sht3x: allow dynamic addressing to 0x44 and 0x45 with I2C address enum
2 parents 92fd612 + 1827d37 commit c82d2ff

File tree

5 files changed

+335
-65
lines changed

5 files changed

+335
-65
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
55

66
## [Unreleased]
77

8+
* [`changed`] SHT3x driver added macros to easily parse the STATUS register relevant bits
9+
* [`changed`] SHT3x driver support for alert thresholds configuration (read and write commands)
10+
* [`changed`] SHT3x driver support for clear status register
11+
* [`changed`] SHT3x driver allows use of 2 sensors in parallel (addresses 0x44 & 0x45)
12+
813
## [5.2.1] - 2020-12-14
914

1015
* [`changed`] Makefile to only include needed files from embedded-common

sht3x/sht3x.c

Lines changed: 170 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -46,84 +46,226 @@
4646
/* all measurement commands return T (CRC) RH (CRC) */
4747
#if USE_SENSIRION_CLOCK_STRETCHING
4848
#define SHT3X_CMD_MEASURE_HPM 0x2C06
49+
#define SHT3X_CMD_MEASURE_MPM 0x2C0D
4950
#define SHT3X_CMD_MEASURE_LPM 0x2C10
5051
#else /* USE_SENSIRION_CLOCK_STRETCHING */
5152
#define SHT3X_CMD_MEASURE_HPM 0x2400
53+
#define SHT3X_CMD_MEASURE_MPM 0x240B
5254
#define SHT3X_CMD_MEASURE_LPM 0x2416
5355
#endif /* USE_SENSIRION_CLOCK_STRETCHING */
56+
57+
#define SHT3X_HUMIDITY_LIMIT_MSK 0xFE00U
58+
#define SHT3X_TEMPERATURE_LIMIT_MSK 0x01FFU
59+
5460
static const uint16_t SHT3X_CMD_READ_STATUS_REG = 0xF32D;
61+
static const uint16_t SHT3X_CMD_CLR_STATUS_REG = 0x3041;
5562
static const uint16_t SHT3X_CMD_READ_SERIAL_ID = 0x3780;
5663
static const uint16_t SHT3X_CMD_DURATION_USEC = 1000;
57-
#ifdef SHT_ADDRESS
58-
static const uint8_t SHT3X_ADDRESS = SHT_ADDRESS;
59-
#else
60-
static const uint8_t SHT3X_ADDRESS = 0x44;
61-
#endif
64+
/* read commands for the alert settings */
65+
static const uint16_t SHT3X_CMD_READ_HIALRT_LIM_SET = 0xE11F;
66+
static const uint16_t SHT3X_CMD_READ_HIALRT_LIM_CLR = 0xE114;
67+
static const uint16_t SHT3X_CMD_READ_LOALRT_LIM_CLR = 0xE109;
68+
static const uint16_t SHT3X_CMD_READ_LOALRT_LIM_SET = 0xE102;
69+
/* write commands for the alert settings */
70+
static const uint16_t SHT3X_CMD_WRITE_HIALRT_LIM_SET = 0x611D;
71+
static const uint16_t SHT3X_CMD_WRITE_HIALRT_LIM_CLR = 0x6116;
72+
static const uint16_t SHT3X_CMD_WRITE_LOALRT_LIM_CLR = 0x610B;
73+
static const uint16_t SHT3X_CMD_WRITE_LOALRT_LIM_SET = 0x6100;
6274

6375
static uint16_t sht3x_cmd_measure = SHT3X_CMD_MEASURE_HPM;
6476

65-
int16_t sht3x_measure_blocking_read(int32_t* temperature, int32_t* humidity) {
66-
int16_t ret = sht3x_measure();
77+
int16_t sht3x_measure_blocking_read(sht3x_i2c_addr_t addr, int32_t* temperature,
78+
int32_t* humidity) {
79+
int16_t ret = sht3x_measure(addr);
6780
if (ret == STATUS_OK) {
6881
#if !defined(USE_SENSIRION_CLOCK_STRETCHING) || !USE_SENSIRION_CLOCK_STRETCHING
6982
sensirion_sleep_usec(SHT3X_MEASUREMENT_DURATION_USEC);
7083
#endif /* USE_SENSIRION_CLOCK_STRETCHING */
71-
ret = sht3x_read(temperature, humidity);
84+
ret = sht3x_read(addr, temperature, humidity);
7285
}
7386
return ret;
7487
}
7588

76-
int16_t sht3x_measure(void) {
77-
return sensirion_i2c_write_cmd(SHT3X_ADDRESS, sht3x_cmd_measure);
89+
int16_t sht3x_measure(sht3x_i2c_addr_t addr) {
90+
return sensirion_i2c_write_cmd(addr, sht3x_cmd_measure);
7891
}
7992

80-
int16_t sht3x_read(int32_t* temperature, int32_t* humidity) {
93+
int16_t sht3x_read(sht3x_i2c_addr_t addr, int32_t* temperature,
94+
int32_t* humidity) {
8195
uint16_t words[2];
82-
int16_t ret = sensirion_i2c_read_words(SHT3X_ADDRESS, words,
83-
SENSIRION_NUM_WORDS(words));
96+
int16_t ret =
97+
sensirion_i2c_read_words(addr, words, SENSIRION_NUM_WORDS(words));
8498
/**
8599
* formulas for conversion of the sensor signals, optimized for fixed point
86100
* algebra: Temperature = 175 * S_T / 2^16 - 45
87101
* Relative Humidity = * 100 * S_RH / 2^16
88102
*/
89-
*temperature = ((21875 * (int32_t)words[0]) >> 13) - 45000;
90-
*humidity = ((12500 * (int32_t)words[1]) >> 13);
103+
tick_to_temperature(words[0], temperature);
104+
tick_to_humidity(words[1], humidity);
91105

92106
return ret;
93107
}
94108

95-
int16_t sht3x_probe(void) {
109+
int16_t sht3x_probe(sht3x_i2c_addr_t addr) {
96110
uint16_t status;
97-
return sensirion_i2c_delayed_read_cmd(SHT3X_ADDRESS,
98-
SHT3X_CMD_READ_STATUS_REG,
111+
return sensirion_i2c_delayed_read_cmd(addr, SHT3X_CMD_READ_STATUS_REG,
99112
SHT3X_CMD_DURATION_USEC, &status, 1);
100113
}
101114

115+
int16_t sht3x_get_status(sht3x_i2c_addr_t addr, uint16_t* status) {
116+
return sensirion_i2c_delayed_read_cmd(addr, SHT3X_CMD_READ_STATUS_REG,
117+
SHT3X_CMD_DURATION_USEC, status, 1);
118+
}
119+
120+
int16_t sht3x_clear_status(sht3x_i2c_addr_t addr) {
121+
return sensirion_i2c_write_cmd(addr, SHT3X_CMD_CLR_STATUS_REG);
122+
}
123+
102124
void sht3x_enable_low_power_mode(uint8_t enable_low_power_mode) {
103125
sht3x_cmd_measure =
104126
enable_low_power_mode ? SHT3X_CMD_MEASURE_LPM : SHT3X_CMD_MEASURE_HPM;
105127
}
106128

107-
int16_t sht3x_read_serial(uint32_t* serial) {
129+
void sht3x_set_power_mode(sht3x_measurement_mode_t mode) {
130+
131+
switch (mode) {
132+
case SHT3X_MEAS_MODE_LPM: {
133+
sht3x_cmd_measure = SHT3X_CMD_MEASURE_LPM;
134+
break;
135+
}
136+
case SHT3X_MEAS_MODE_MPM: {
137+
sht3x_cmd_measure = SHT3X_CMD_MEASURE_MPM;
138+
break;
139+
}
140+
case SHT3X_MEAS_MODE_HPM: {
141+
sht3x_cmd_measure = SHT3X_CMD_MEASURE_HPM;
142+
break;
143+
}
144+
default: {
145+
sht3x_cmd_measure = SHT3X_CMD_MEASURE_HPM;
146+
break;
147+
}
148+
}
149+
}
150+
151+
int16_t sht3x_read_serial(sht3x_i2c_addr_t addr, uint32_t* serial) {
108152
int16_t ret;
109153
uint8_t serial_bytes[4];
110154

111-
ret = sensirion_i2c_write_cmd(SHT3X_ADDRESS, SHT3X_CMD_READ_SERIAL_ID);
112-
if (ret)
113-
return ret;
114-
155+
ret = sensirion_i2c_write_cmd(addr, SHT3X_CMD_READ_SERIAL_ID);
115156
sensirion_sleep_usec(SHT3X_CMD_DURATION_USEC);
116157

117-
ret = sensirion_i2c_read_words_as_bytes(SHT3X_ADDRESS, serial_bytes,
118-
SENSIRION_NUM_WORDS(serial_bytes));
119-
*serial = sensirion_bytes_to_uint32_t(serial_bytes);
158+
if (ret == STATUS_OK) {
159+
160+
ret = sensirion_i2c_read_words_as_bytes(
161+
addr, serial_bytes, SENSIRION_NUM_WORDS(serial_bytes));
162+
*serial = sensirion_bytes_to_uint32_t(serial_bytes);
163+
}
120164
return ret;
121165
}
122166

123167
const char* sht3x_get_driver_version(void) {
124168
return SHT_DRV_VERSION_STR;
125169
}
126170

127-
uint8_t sht3x_get_configured_address(void) {
128-
return SHT3X_ADDRESS;
171+
int16_t sht3x_set_alert_thd(sht3x_i2c_addr_t addr, sht3x_alert_thd_t thd,
172+
uint32_t humidity, int32_t temperature) {
173+
int16_t ret;
174+
uint16_t rawT;
175+
uint16_t rawRH;
176+
uint16_t limitVal = 0U;
177+
178+
temperature_to_tick(temperature, &rawT);
179+
humidity_to_tick(humidity, &rawRH);
180+
181+
/* convert inputs to alert threshold word */
182+
limitVal = (rawRH & SHT3X_HUMIDITY_LIMIT_MSK);
183+
limitVal |= ((rawT >> 7) & SHT3X_TEMPERATURE_LIMIT_MSK);
184+
185+
switch (thd) {
186+
case SHT3X_HIALRT_SET:
187+
ret = sensirion_i2c_write_cmd_with_args(
188+
addr, SHT3X_CMD_WRITE_HIALRT_LIM_SET, &limitVal, 1);
189+
break;
190+
191+
case SHT3X_HIALRT_CLR:
192+
ret = sensirion_i2c_write_cmd_with_args(
193+
addr, SHT3X_CMD_WRITE_HIALRT_LIM_CLR, &limitVal, 1);
194+
break;
195+
196+
case SHT3X_LOALRT_CLR:
197+
ret = sensirion_i2c_write_cmd_with_args(
198+
addr, SHT3X_CMD_WRITE_LOALRT_LIM_CLR, &limitVal, 1);
199+
break;
200+
201+
case SHT3X_LOALRT_SET:
202+
ret = sensirion_i2c_write_cmd_with_args(
203+
addr, SHT3X_CMD_WRITE_LOALRT_LIM_SET, &limitVal, 1);
204+
break;
205+
206+
default:
207+
ret = STATUS_ERR_INVALID_PARAMS;
208+
break;
209+
}
210+
return ret;
211+
}
212+
213+
int16_t sht3x_get_alert_thd(sht3x_i2c_addr_t addr, sht3x_alert_thd_t thd,
214+
int32_t* humidity, int32_t* temperature) {
215+
216+
int16_t ret;
217+
uint16_t word;
218+
uint16_t rawT;
219+
uint16_t rawRH;
220+
221+
switch (thd) {
222+
case SHT3X_HIALRT_SET:
223+
ret = sensirion_i2c_read_cmd(addr, SHT3X_CMD_READ_HIALRT_LIM_SET,
224+
&word, 1);
225+
break;
226+
227+
case SHT3X_HIALRT_CLR:
228+
ret = sensirion_i2c_read_cmd(addr, SHT3X_CMD_READ_HIALRT_LIM_CLR,
229+
&word, 1);
230+
break;
231+
232+
case SHT3X_LOALRT_CLR:
233+
ret = sensirion_i2c_read_cmd(addr, SHT3X_CMD_READ_LOALRT_LIM_CLR,
234+
&word, 1);
235+
break;
236+
237+
case SHT3X_LOALRT_SET:
238+
ret = sensirion_i2c_read_cmd(addr, SHT3X_CMD_READ_LOALRT_LIM_SET,
239+
&word, 1);
240+
break;
241+
242+
default:
243+
ret = STATUS_ERR_INVALID_PARAMS;
244+
break;
245+
}
246+
247+
/* convert threshold word to alert settings in 10*%RH & 10*°C */
248+
rawRH = (word & SHT3X_HUMIDITY_LIMIT_MSK);
249+
rawT = ((word & SHT3X_TEMPERATURE_LIMIT_MSK) << 7);
250+
251+
tick_to_humidity(rawRH, humidity);
252+
tick_to_temperature(rawT, temperature);
253+
254+
return ret;
255+
}
256+
257+
void tick_to_temperature(uint16_t tick, int32_t* temperature) {
258+
*temperature = ((21875 * (int32_t)tick) >> 13) - 45000;
129259
}
260+
261+
void tick_to_humidity(uint16_t tick, int32_t* humidity) {
262+
*humidity = ((12500 * (int32_t)tick) >> 13);
263+
}
264+
265+
void temperature_to_tick(int32_t temperature, uint16_t* tick) {
266+
*tick = (uint16_t)((temperature * 12271 + 552195000) >> 15);
267+
}
268+
269+
void humidity_to_tick(int32_t humidity, uint16_t* tick) {
270+
*tick = (uint16_t)((humidity * 21474) >> 15);
271+
}

0 commit comments

Comments
 (0)