18
18
19
19
#define DHT20_STATUS_MASK (BIT(0) | BIT(1))
20
20
21
- #define DHT20_STATUS_MASK_CHECK 0x18
22
- #define DHT20_STATUS_MASK_POLL_STATE 0x80
21
+ #define DHT20_STATUS_MASK_CHECK 0x18
23
22
24
23
#define DHT20_MASK_RESET_REGISTER 0xB0
25
24
38
37
#define DHT20_RESET_REGISTER_1 0x1C
39
38
#define DHT20_RESET_REGISTER_2 0x1E
40
39
41
- /** Length of the buffer used for data measurement */
42
- #define DHT20_MEASUREMENT_BUFFER_LENGTH 7
40
+ /** Measurement frame data indexes */
41
+ #define DHT20_MEAS_STATUS_IDX 0
42
+ #define DHT20_MEAS_HUMIDITY_IDX 1
43
+ #define DHT20_MEAS_HUM_TEMP_IDX 3
44
+ #define DHT20_MEAS_TEMPERATURE_IDX 4
45
+ #define DHT20_MEAS_CRC_IDX 6
46
+ #define DHT20_MEAS_FRAME_LENGTH 7
43
47
44
- /** Wait some time after reset sequence (in ms) */
45
- #define DHT20_RESET_SEQUENCE_WAIT_MS 10
48
+ #define DHT20_STATUS_BUSY_BIT BIT(7)
49
+ #define DHT20_IS_STATUS_BUSY ( status ) ((status) & DHT20_STATUS_BUSY_BIT)
46
50
47
- /** Wait after power on (in ms) */
48
- #define DHT20_POWER_ON_WAIT_MS 75
49
- /** Wait during polling after power on (in ms) */
50
- #define DHT20_INIT_POLL_STATUS_WAIT_MS 5
51
+ /** Wait some time after status reset sequence (in ms) */
52
+ #define DHT20_STATUS_RESET_SEQUENCE_WAIT_MS 10
53
+
54
+ /* According to datasheet 7.4: Wait time after power-on should be at least 100ms */
55
+ #define DHT20_POWER_ON_WAIT_TIME_MS 100
56
+ /** Wait for the measurement to be completed (in ms) */
57
+ #define DHT20_MEASUREMENT_TIME_MS 80
51
58
52
59
LOG_MODULE_REGISTER (DHT20 , CONFIG_SENSOR_LOG_LEVEL );
53
60
@@ -75,15 +82,9 @@ static inline int read_status(const struct device *dev, uint8_t *status)
75
82
uint8_t rx_buf [1 ];
76
83
77
84
/* Write DHT20_STATUS_REGISTER then read to get status */
78
- rc = i2c_write_dt (& cfg -> bus , tx_buf , sizeof (tx_buf ));
79
- if (rc < 0 ) {
80
- LOG_ERR ("Failed to start measurement." );
81
- return rc ;
82
- }
83
-
84
- rc = i2c_read_dt (& cfg -> bus , rx_buf , sizeof (rx_buf ));
85
+ rc = i2c_write_read_dt (& cfg -> bus , tx_buf , sizeof (tx_buf ), & rx_buf , sizeof (rx_buf ));
85
86
if (rc < 0 ) {
86
- LOG_ERR ("Failed to read data from device ." );
87
+ LOG_ERR ("Failed to read status register ." );
87
88
return rc ;
88
89
}
89
90
@@ -119,7 +120,7 @@ static inline int reset_register(const struct device *dev, uint8_t reg)
119
120
return rc ;
120
121
}
121
122
122
- static inline int reset_sensor (const struct device * dev )
123
+ static inline int initialize_status_register (const struct device * dev )
123
124
{
124
125
int rc ;
125
126
uint8_t status ;
@@ -147,16 +148,15 @@ static inline int reset_sensor(const struct device *dev)
147
148
if (rc < 0 ) {
148
149
return rc ;
149
150
}
150
- /* Wait 10ms after reset sequence */
151
- k_msleep (DHT20_RESET_SEQUENCE_WAIT_MS );
151
+ /* Wait 10ms after status reset sequence */
152
+ k_msleep (DHT20_STATUS_RESET_SEQUENCE_WAIT_MS );
152
153
}
153
154
154
155
return 0 ;
155
156
}
156
157
157
- static int dht20_read_sample (const struct device * dev , uint32_t * t_sample , uint32_t * rh_sample )
158
+ static int dht20_read_sample (const struct dht20_config * cfg , struct dht20_data * data )
158
159
{
159
- const struct dht20_config * cfg = dev -> config ;
160
160
/*
161
161
* Datasheet shows content of the measurement data as follow
162
162
*
@@ -172,32 +172,36 @@ static int dht20_read_sample(const struct device *dev, uint32_t *t_sample, uint3
172
172
* | 6 | CRC |
173
173
* +------+----------------------------------------+
174
174
*/
175
- uint8_t rx_buf [DHT20_MEASUREMENT_BUFFER_LENGTH ];
175
+
176
+ uint8_t rx_buf [DHT20_MEAS_FRAME_LENGTH ];
176
177
int rc ;
177
- uint8_t status ;
178
178
179
179
rc = i2c_read_dt (& cfg -> bus , rx_buf , sizeof (rx_buf ));
180
180
if (rc < 0 ) {
181
- LOG_ERR ("Failed to read data from device ." );
181
+ LOG_ERR ("Failed to read measurement frame ." );
182
182
return rc ;
183
183
}
184
184
185
- status = rx_buf [0 ];
185
+ if (DHT20_IS_STATUS_BUSY (rx_buf [DHT20_MEAS_STATUS_IDX ])) {
186
+ LOG_WRN ("Sensor measurement is not ready" );
187
+ return - EBUSY ;
188
+ }
189
+
186
190
/* Extract 20 bits for humidity data */
187
- * rh_sample = sys_get_be24 (& rx_buf [1 ]) >> 4 ;
191
+ data -> rh_sample = sys_get_be24 (& rx_buf [DHT20_MEAS_HUMIDITY_IDX ]) >> 4 ;
188
192
/* Extract 20 bits for temperature data */
189
- * t_sample = sys_get_be24 (& rx_buf [3 ]) & 0x0FFFFF ;
193
+ data -> t_sample = sys_get_be24 (& rx_buf [DHT20_MEAS_HUM_TEMP_IDX ]) & 0x0FFFFF ;
190
194
191
195
#if defined(CONFIG_DHT20_CRC )
192
196
/* Compute and check CRC with last byte of measurement data */
193
197
uint8_t crc = crc8 (rx_buf , 6 , DHT20_CRC_POLYNOM , 0xFF , false);
194
198
195
- if (crc != rx_buf [6 ]) {
196
- rc = - EIO ;
199
+ if (crc != rx_buf [DHT20_MEAS_CRC_IDX ]) {
200
+ return - EIO ;
197
201
}
198
202
#endif
199
203
200
- return rc ;
204
+ return 0 ;
201
205
}
202
206
203
207
static int dht20_sample_fetch (const struct device * dev , enum sensor_channel chan )
@@ -207,16 +211,12 @@ static int dht20_sample_fetch(const struct device *dev, enum sensor_channel chan
207
211
int rc ;
208
212
uint8_t tx_buf [DHT20_TRIGGER_MEASUREMENT_BUFFER_LENGTH ] = {
209
213
DHT20_TRIGGER_MEASUREMENT_COMMAND };
210
- uint8_t status ;
211
214
212
215
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP &&
213
216
chan != SENSOR_CHAN_HUMIDITY ) {
214
217
return - ENOTSUP ;
215
218
}
216
219
217
- /* Reset sensor if needed */
218
- reset_sensor (dev );
219
-
220
220
/* Send trigger measurement command */
221
221
rc = i2c_write_dt (& cfg -> bus , tx_buf , sizeof (tx_buf ));
222
222
if (rc < 0 ) {
@@ -228,19 +228,9 @@ static int dht20_sample_fetch(const struct device *dev, enum sensor_channel chan
228
228
* According to datasheet maximum time to make temperature and humidity
229
229
* measurements is 80ms
230
230
*/
231
- k_msleep (DHT20_POWER_ON_WAIT_MS );
232
-
233
- do {
234
- k_msleep (DHT20_INIT_POLL_STATUS_WAIT_MS );
235
-
236
- rc = read_status (dev , & status );
237
- if (rc < 0 ) {
238
- LOG_ERR ("Failed to read status." );
239
- return rc ;
240
- }
241
- } while ((status & DHT20_STATUS_MASK_POLL_STATE ) != 0 );
231
+ k_msleep (DHT20_MEASUREMENT_TIME_MS );
242
232
243
- rc = dht20_read_sample (dev , & data -> t_sample , & data -> rh_sample );
233
+ rc = dht20_read_sample (cfg , data );
244
234
if (rc < 0 ) {
245
235
LOG_ERR ("Failed to fetch data." );
246
236
return rc ;
@@ -298,12 +288,21 @@ static int dht20_channel_get(const struct device *dev, enum sensor_channel chan,
298
288
static int dht20_init (const struct device * dev )
299
289
{
300
290
const struct dht20_config * cfg = dev -> config ;
291
+ int rc ;
301
292
302
293
if (!i2c_is_ready_dt (& cfg -> bus )) {
303
294
LOG_ERR ("I2C dev %s not ready" , cfg -> bus .bus -> name );
304
295
return - ENODEV ;
305
296
}
306
297
298
+ k_msleep (DHT20_POWER_ON_WAIT_TIME_MS );
299
+
300
+ rc = initialize_status_register (dev );
301
+ if (rc < 0 ) {
302
+ LOG_ERR ("Failed to initialize status register." );
303
+ return rc ;
304
+ }
305
+
307
306
return 0 ;
308
307
}
309
308
0 commit comments