LibDriver AM2320
Loading...
Searching...
No Matches
driver_am2320.c
Go to the documentation of this file.
1
36
37#include "driver_am2320.h"
38
42#define CHIP_NAME "ASAIR AM2320"
43#define MANUFACTURER_NAME "ASAIR"
44#define SUPPLY_VOLTAGE_MIN 3.1f
45#define SUPPLY_VOLTAGE_MAX 5.5f
46#define MAX_CURRENT 0.95f
47#define TEMPERATURE_MIN -20.0f
48#define TEMPERATURE_MAX 60.0f
49#define DRIVER_VERSION 1000
50
54#define AM2320_ADDRESS 0xB8
55
59#define AM2320_MODBUS_ADDRESS_HUMI_MSB 0x00
60#define AM2320_MODBUS_ADDRESS_HUMI_LSB 0x01
61#define AM2320_MODBUS_ADDRESS_TEMP_MSB 0x02
62#define AM2320_MODBUS_ADDRESS_TEMP_LSB 0x03
63#define AM2320_MODBUS_ADDRESS_DEVICE_TYPE_MSB 0x08
64#define AM2320_MODBUS_ADDRESS_DEVICE_TYPE_LSB 0x09
65#define AM2320_MODBUS_ADDRESS_VERSION 0x0A
66#define AM2320_MODBUS_ADDRESS_DEVICE_3 0x0B
67#define AM2320_MODBUS_ADDRESS_DEVICE_2 0x0C
68#define AM2320_MODBUS_ADDRESS_DEVICE_1 0x0D
69#define AM2320_MODBUS_ADDRESS_DEVICE_0 0x0E
70#define AM2320_MODBUS_ADDRESS_STATUS 0x0F
71#define AM2320_MODBUS_ADDRESS_USER_REG1_MSB 0x10
72#define AM2320_MODBUS_ADDRESS_USER_REG1_LSB 0x11
73#define AM2320_MODBUS_ADDRESS_USER_REG2_MSB 0x12
74#define AM2320_MODBUS_ADDRESS_USER_REG2_LSB 0x13
75
79static const uint8_t gs_crc_table_hi[] =
80{
81 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
82 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
83 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
84 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
85 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
86 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
87 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1,
88 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
89 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
90 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
91 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
92 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
93 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
94 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
95 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
96 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
97 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
98 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
99 0x00, 0xC1, 0x81, 0x40
100};
101
105static const uint8_t gs_crc_table_lo[] =
106{
107 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5,
108 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B,
109 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE,
110 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6,
111 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
112 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
113 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8,
114 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
115 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21,
116 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
117 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A,
118 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
119 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7,
120 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51,
121 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
122 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
123 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D,
124 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
125 0x41, 0x81, 0x80, 0x40
126};
127
135static uint16_t a_am2320_generate_crc16(uint8_t *data, uint16_t count)
136{
137 uint8_t crc_hi = 0xFF;
138 uint8_t crc_lo = 0xFF;
139 uint8_t i;
140
141 while (count--) /* count-- */
142 {
143 i = crc_lo ^ *data++; /* get index */
144 crc_lo = crc_hi ^ gs_crc_table_hi[i]; /* get crc lo */
145 crc_hi = gs_crc_table_lo[i]; /* get crc hi */
146 }
147
148 return ((uint16_t)crc_hi << 8 | crc_lo); /* return crc16 */
149}
150
159static uint8_t a_am2320_reset(am2320_handle_t *handle)
160{
161 uint8_t retry = 0;
162 uint8_t res;
163 uint8_t value;
164
165 res = handle->bus_write(0); /* set low */
166 if (res != 0) /* check result */
167 {
168 handle->debug_print("am2320: bus write 0 failed.\n"); /* write failed */
169
170 return 1; /* return error */
171 }
172 handle->delay_ms(1); /* wait 1ms */
173 handle->disable_irq(); /* disable interrupt */
174 res = handle->bus_write(1); /* set high */
175 if (res != 0) /* check result */
176 {
177 handle->enable_irq(); /* enable interrupt */
178 handle->debug_print("am2320: bus write 1 failed.\n"); /* write failed */
179
180 return 1; /* return error */
181 }
182 handle->delay_us(30); /* wait 20-40us */
183 res = handle->bus_read((uint8_t *)&value); /* read 1 bit */
184 if (res != 0) /* check result */
185 {
186 handle->enable_irq(); /* enable interrupt */
187 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
188
189 return 1; /* return error */
190 }
191 while ((value != 0) && (retry < 100)) /* wait 40-80us */
192 {
193 res = handle->bus_read((uint8_t *)&value); /* read 1 bit */
194 if (res != 0) /* check result */
195 {
196 handle->enable_irq(); /* enable interrupt */
197 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
198
199 return 1; /* return error */
200 }
201 retry++; /* retry times++ */
202 handle->delay_us(1); /* delay 1us */
203 }
204 if (retry >= 100) /* if retry times is over 100 times */
205 {
206 handle->enable_irq(); /* enable interrupt */
207 handle->debug_print("am2320: bus no response.\n"); /* no response */
208
209 return 1; /* return error */
210 }
211 else
212 {
213 retry = 0; /* reset retry times */
214 }
215 res = handle->bus_read((uint8_t *)&value); /* read 1 bit */
216 if (res != 0) /* check result */
217 {
218 handle->enable_irq(); /* enable interrupt */
219 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
220
221 return 1; /* return error */
222 }
223 while ((!value) && (retry < 100)) /* wait for 40-80us */
224 {
225 res = handle->bus_read((uint8_t *)&value); /* read 1 bit */
226 if (res != 0) /* check result */
227 {
228 handle->enable_irq(); /* enable interrupt */
229 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
230
231 return 1; /* return error */
232 }
233 retry++; /* retry times++ */
234 handle->delay_us(1); /* delay 1 us */
235 }
236 if (retry >= 100) /* if retry times is over 100 times */
237 {
238 handle->enable_irq(); /* enable interrupt */
239 handle->debug_print("am2320: bus no response.\n"); /* no response */
240
241 return 1; /* return error */
242 }
243 handle->enable_irq(); /* enable interrupt */
244
245 return 0; /* success return 0 */
246}
247
257static uint8_t a_am2320_read_bit(am2320_handle_t *handle, uint8_t *value)
258{
259 uint8_t retry = 0;
260 uint8_t res;
261
262 res = handle->bus_read((uint8_t *)value); /* read 1 bit */
263 if (res != 0) /* check result */
264 {
265 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
266
267 return 1; /* return error */
268 }
269 while (((*value) != 0) && (retry < 100)) /* wait 100us */
270 {
271 res = handle->bus_read((uint8_t *)value); /* read 1 bit */
272 if (res != 0) /* check result */
273 {
274 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
275
276 return 1; /* return error */
277 }
278 retry++; /* retry times++ */
279 handle->delay_us(1); /* delay 1 us */
280 }
281 retry = 0; /* reset retry times */
282 res = handle->bus_read((uint8_t *)value); /* read 1 bit */
283 if (res != 0) /* check result */
284 {
285 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
286
287 return 1; /* return error */
288 }
289 while ((!(*value)) && (retry < 100)) /* wait 100us */
290 {
291 res = handle->bus_read((uint8_t *)value); /* read 1 bit */
292 if (res != 0) /* check result */
293 {
294 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
295
296 return 1; /* return error */
297 }
298 retry++; /* retry times++ */
299 handle->delay_us(1); /* wait 1 us */
300 }
301 handle->delay_us(40); /* wait 40us */
302 res = handle->bus_read((uint8_t *)value); /* read 1 bit */
303 if (res != 0) /* check result */
304 {
305 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
306
307 return 1; /* return error */
308 }
309 else
310 {
311 return 0; /* success return 0 */
312 }
313}
314
324static uint8_t a_am2320_read_byte(am2320_handle_t *handle, uint8_t *byte)
325{
326 uint8_t i;
327 uint8_t res;
328 uint8_t value;
329
330 *byte = 0; /* set byte 0 */
331 for (i = 0; i < 8; i++) /* read 8 bits */
332 {
333 *byte <<= 1; /* left shift 1 bit */
334 res = a_am2320_read_bit(handle, (uint8_t *)&value); /* read 1 bit */
335 if (res != 0) /* check result */
336 {
337 handle->debug_print("am2320: bus read failed.\n"); /* read failed */
338
339 return 1; /* return error */
340 }
341 *byte |= value; /* set LSB */
342 }
343
344 return 0; /* success return 0 */
345}
346
357{
358 if (handle == NULL) /* check handle */
359 {
360 return 2; /* return error */
361 }
362
363 handle->gpio_iic = (uint8_t)interface; /* set interface */
364
365 return 0; /* success return 0 */
366}
367
378{
379 if (handle == NULL) /* check handle */
380 {
381 return 2; /* return error */
382 }
383
384 *interface = (am2320_interface_t)(handle->gpio_iic); /* get interface */
385
386 return 0; /* success return 0 */
387}
388
401uint8_t am2320_read_humidity(am2320_handle_t *handle, uint16_t *raw, float *s)
402{
403 uint8_t buf[5];
404 uint8_t i;
405
406 if (handle == NULL) /* check handle */
407 {
408 return 2; /* return error */
409 }
410 if (handle->inited != 1) /* check handle initialization */
411 {
412 return 3; /* return error */
413 }
414
415 if (handle->gpio_iic != 0) /* gpio */
416 {
417 if (a_am2320_reset(handle) == 0) /* reset the chip */
418 {
419 handle->disable_irq(); /* disable interrupt */
420 for (i = 0; i < 5; i++) /* read 5 bytes */
421 {
422 if (a_am2320_read_byte(handle, (uint8_t *)&buf[i]) != 0) /* read each byte */
423 {
424 handle->enable_irq(); /* enable interrupt */
425 handle->debug_print("am2320: read byte failed.\n"); /* read failed */
426
427 return 1; /* return error */
428 }
429 }
430 handle->enable_irq(); /* enable interrupt */
431 if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) /* calculate checksum */
432 {
433 *raw = (uint16_t)buf[0] << 8 | buf[1]; /* get raw data */
434 *s = (float)(*raw) / 10.0f; /* convert raw data to real data */
435
436 return 0; /* success return 0 */
437 }
438 else
439 {
440 handle->debug_print("am2320: data check failed.\n"); /* checksum error */
441
442 return 1; /* return error */
443 }
444 }
445 else
446 {
447 handle->debug_print("am2320: reset failed.\n"); /* reset failed */
448
449 return 1; /* return error */
450 }
451 }
452 else /* iic */
453 {
454 uint8_t res;
455 uint8_t input_buf[3];
456 uint8_t out_buf[6];
457 uint16_t crc16;
458
459 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
460 input_buf[0] = 0x03; /* set function code */
461 input_buf[1] = AM2320_MODBUS_ADDRESS_HUMI_MSB; /* set addr */
462 input_buf[2] = 0x02; /* set number */
463 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
464 if (res != 0) /* check result */
465 {
466 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
467
468 return 1; /* return error */
469 }
470 handle->delay_ms(2); /* delay 2ms */
471 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 6); /* read command */
472 if (res != 0) /* check result */
473 {
474 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
475
476 return 1; /* return error */
477 }
478 crc16 = ((uint16_t)out_buf[5] << 8 | (uint16_t)out_buf[4]); /* get crc16 */
479 if (crc16 != a_am2320_generate_crc16(out_buf, 4)) /* check crc16 */
480 {
481 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
482
483 return 1; /* return error */
484 }
485 if (out_buf[0] != 0x03) /* check code */
486 {
487 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
488
489 return 1; /* return error */
490 }
491 if (out_buf[1] != 0x02) /* check number */
492 {
493 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
494
495 return 1; /* return error */
496 }
497 *raw = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get humidity raw */
498 *s = (float)(*raw) / 10.0f; /* convert humidity raw data to real data */
499
500 return 0; /* success return 0 */
501 }
502}
503
518uint8_t am2320_read_temperature_humidity(am2320_handle_t *handle, uint16_t *temperature_raw, float *temperature_s, uint16_t *humidity_raw, float *humidity_s)
519{
520 uint8_t buf[5];
521 uint8_t i;
522
523 if (handle == NULL) /* check handle */
524 {
525 return 2; /* return error */
526 }
527 if (handle->inited != 1) /* check handle initialization */
528 {
529 return 3; /* return error */
530 }
531
532 if (handle->gpio_iic != 0) /* gpio */
533 {
534 if (a_am2320_reset(handle) == 0) /* reset the chip */
535 {
536 handle->disable_irq(); /* disable interrupt */
537 for (i = 0; i < 5; i++) /* read 5 bytes */
538 {
539 if (a_am2320_read_byte(handle, (uint8_t *)&buf[i]) != 0) /* read each byte */
540 {
541 handle->enable_irq(); /* enable interrupt */
542 handle->debug_print("am2320: read byte failed.\n"); /* read failed */
543
544 return 1; /* return error */
545 }
546 }
547 handle->enable_irq(); /* enable interrupt */
548 if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) /* calculate checksum */
549 {
550 if ((buf[2] & (1 << 7)) != 0) /* if temperature is below zero */
551 {
552 *temperature_raw = (uint16_t)buf[2] << 8 | buf[3]; /* get temperature raw data */
553 *temperature_s= (float)((buf[2] & ~(1 << 7)) * 256 +
554 buf[3]) / 10.0f * (-1.0f); /* convert temperature raw data to temperature real data */
555 }
556 else
557 {
558 *temperature_raw = (uint16_t)buf[2] << 8 | buf[3]; /* get temperature raw data */
559 *temperature_s= (float)(buf[2] * 256 + buf[3]) / 10.0f; /* convert temperature raw data to temperature real data */
560 }
561 *humidity_raw = (uint16_t)buf[0] << 8 | buf[1]; /* get humidity raw */
562 *humidity_s = (float)(*humidity_raw) / 10.0f; /* convert humidity raw data to real data */
563
564 return 0; /* success return 0 */
565 }
566 else
567 {
568 handle->debug_print("am2320: data check failed.\n"); /* checksum error */
569
570 return 1; /* return error */
571 }
572 }
573 else
574 {
575 handle->debug_print("am2320: reset failed.\n"); /* reset failed */
576
577 return 1; /* return error */
578 }
579 }
580 else /* iic */
581 {
582 uint8_t res;
583 uint8_t input_buf[3];
584 uint8_t out_buf[8];
585 uint16_t crc16;
586
587 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
588 input_buf[0] = 0x03; /* set function code */
589 input_buf[1] = AM2320_MODBUS_ADDRESS_HUMI_MSB; /* set addr */
590 input_buf[2] = 0x04; /* set number */
591 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
592 if (res != 0) /* check result */
593 {
594 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
595
596 return 1; /* return error */
597 }
598 handle->delay_ms(2); /* delay 2ms */
599 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 8); /* read command */
600 if (res != 0) /* check result */
601 {
602 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
603
604 return 1; /* return error */
605 }
606 crc16 = ((uint16_t)out_buf[7] << 8 | (uint16_t)out_buf[6]); /* get crc16 */
607 if (crc16 != a_am2320_generate_crc16(out_buf, 6)) /* check crc16 */
608 {
609 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
610
611 return 1; /* return error */
612 }
613 if (out_buf[0] != 0x03) /* check code */
614 {
615 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
616
617 return 1; /* return error */
618 }
619 if (out_buf[1] != 0x04) /* check number */
620 {
621 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
622
623 return 1; /* return error */
624 }
625 if ((out_buf[4] & (1 << 7)) != 0) /* if temperature is below zero */
626 {
627 *temperature_raw = (uint16_t)out_buf[4] << 8 | out_buf[5]; /* get temperature raw data */
628 *temperature_s= (float)((out_buf[4] & ~(1 << 7)) * 256 +
629 out_buf[5]) / 10.0f * (-1.0f); /* convert temperature raw data to temperature real data */
630 }
631 else
632 {
633 *temperature_raw = (uint16_t)out_buf[4] << 8 | out_buf[5]; /* get temperature raw data */
634 *temperature_s= (float)(out_buf[4] * 256 + out_buf[5]) / 10.0f; /* convert temperature raw data to temperature real data */
635 }
636 *humidity_raw = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get humidity raw */
637 *humidity_s = (float)(*humidity_raw) / 10.0f; /* convert humidity raw data to real data */
638
639 return 0; /* success return 0 */
640 }
641}
642
655uint8_t am2320_read_temperature(am2320_handle_t *handle, uint16_t *raw, float *s)
656{
657 uint8_t buf[5];
658 uint8_t i;
659
660 if (handle == NULL) /* check handle */
661 {
662 return 2; /* return error */
663 }
664 if (handle->inited != 1) /* check handle initialization */
665 {
666 return 3; /* return error */
667 }
668
669 if (handle->gpio_iic != 0) /* gpio */
670 {
671 if (a_am2320_reset(handle) == 0) /* reset the chip */
672 {
673 handle->disable_irq(); /* disable interrupt */
674 for (i = 0; i < 5; i++) /* read 5 bytes */
675 {
676 if (a_am2320_read_byte(handle, (uint8_t *)&buf[i]) != 0) /* read each byte */
677 {
678 handle->enable_irq(); /* enable interrupt */
679 handle->debug_print("am2320: read byte failed.\n"); /* read failed */
680
681 return 1; /* return error */
682 }
683 }
684 handle->enable_irq(); /* enable interrupt */
685 if ((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4]) /* calculate checksum */
686 {
687 if ((buf[2] & (1 << 7)) != 0) /* if temperature is below zero */
688 {
689 *raw = (uint16_t)buf[2] << 8 | buf[3]; /* get temperature raw data */
690 *s= (float)((buf[2] & ~(1 << 7)) * 256 +
691 buf[3]) / 10.0f * (-1.0f); /* convert temperature raw data to temperature real data */
692 }
693 else
694 {
695 *raw = (uint16_t)buf[2] << 8 | buf[3]; /* get temperature raw data */
696 *s= (float)(buf[2] * 256 + buf[3]) / 10.0f; /* convert temperature raw data to temperature real data */
697 }
698
699 return 0; /* success return 0 */
700 }
701 else
702 {
703 handle->debug_print("am2320: data check failed.\n"); /* checksum error */
704
705 return 1; /* return error */
706 }
707 }
708 else
709 {
710 handle->debug_print("am2320: reset failed.\n"); /* reset failed */
711
712 return 1; /* return error */
713 }
714 }
715 else /* iic */
716 {
717 uint8_t res;
718 uint8_t input_buf[3];
719 uint8_t out_buf[6];
720 uint16_t crc16;
721
722 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
723 input_buf[0] = 0x03; /* set function code */
724 input_buf[1] = AM2320_MODBUS_ADDRESS_TEMP_MSB; /* set addr */
725 input_buf[2] = 0x02; /* set number */
726 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
727 if (res != 0) /* check result */
728 {
729 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
730
731 return 1; /* return error */
732 }
733 handle->delay_ms(2); /* delay 2ms */
734 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 6); /* read command */
735 if (res != 0) /* check result */
736 {
737 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
738
739 return 1; /* return error */
740 }
741 crc16 = ((uint16_t)out_buf[5] << 8 | (uint16_t)out_buf[4]); /* get crc16 */
742 if (crc16 != a_am2320_generate_crc16(out_buf, 4)) /* check crc16 */
743 {
744 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
745
746 return 1; /* return error */
747 }
748 if (out_buf[0] != 0x03) /* check code */
749 {
750 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
751
752 return 1; /* return error */
753 }
754 if (out_buf[1] != 0x02) /* check number */
755 {
756 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
757
758 return 1; /* return error */
759 }
760 if ((out_buf[2] & (1 << 7)) != 0) /* if temperature is below zero */
761 {
762 *raw = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get temperature raw data */
763 *s= (float)((out_buf[2] & ~(1 << 7)) * 256 +
764 out_buf[3]) / 10.0f * (-1.0f); /* convert temperature raw data to temperature real data */
765 }
766 else
767 {
768 *raw = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get temperature raw data */
769 *s= (float)(out_buf[2] * 256 + out_buf[3]) / 10.0f; /* convert temperature raw data to temperature real data */
770 }
771
772 return 0; /* success return 0 */
773 }
774}
775
788uint8_t am2320_get_device_type(am2320_handle_t *handle, uint16_t *type)
789{
790 uint8_t res;
791 uint8_t input_buf[3];
792 uint8_t out_buf[6];
793 uint16_t crc16;
794
795 if (handle == NULL) /* check handle */
796 {
797 return 2; /* return error */
798 }
799 if (handle->inited != 1) /* check handle initialization */
800 {
801 return 3; /* return error */
802 }
803
804 if (handle->gpio_iic != 0) /* gpio */
805 {
806 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
807
808 return 4; /* return error */
809 }
810
811 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
812 input_buf[0] = 0x03; /* set function code */
813 input_buf[1] = AM2320_MODBUS_ADDRESS_DEVICE_TYPE_MSB; /* set addr */
814 input_buf[2] = 0x02; /* set number */
815 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
816 if (res != 0) /* check result */
817 {
818 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
819
820 return 1; /* return error */
821 }
822 handle->delay_ms(2); /* delay 2ms */
823 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 6); /* read command */
824 if (res != 0) /* check result */
825 {
826 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
827
828 return 1; /* return error */
829 }
830 crc16 = ((uint16_t)out_buf[5] << 8 | (uint16_t)out_buf[4]); /* get crc16 */
831 if (crc16 != a_am2320_generate_crc16(out_buf, 4)) /* check crc16 */
832 {
833 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
834
835 return 1; /* return error */
836 }
837 if (out_buf[0] != 0x03) /* check code */
838 {
839 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
840
841 return 1; /* return error */
842 }
843 if (out_buf[1] != 0x02) /* check number */
844 {
845 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
846
847 return 1; /* return error */
848 }
849 *type = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get type */
850
851 return 0; /* success return 0 */
852}
853
866uint8_t am2320_get_version(am2320_handle_t *handle, uint8_t *version)
867{
868 uint8_t res;
869 uint8_t input_buf[3];
870 uint8_t out_buf[5];
871 uint16_t crc16;
872
873 if (handle == NULL) /* check handle */
874 {
875 return 2; /* return error */
876 }
877 if (handle->inited != 1) /* check handle initialization */
878 {
879 return 3; /* return error */
880 }
881
882 if (handle->gpio_iic != 0) /* gpio */
883 {
884 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
885
886 return 4; /* return error */
887 }
888
889 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
890 input_buf[0] = 0x03; /* set function code */
891 input_buf[1] = AM2320_MODBUS_ADDRESS_VERSION; /* set addr */
892 input_buf[2] = 0x01; /* set number */
893 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
894 if (res != 0) /* check result */
895 {
896 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
897
898 return 1; /* return error */
899 }
900 handle->delay_ms(2); /* delay 2ms */
901 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 5); /* read command */
902 if (res != 0) /* check result */
903 {
904 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
905
906 return 1; /* return error */
907 }
908 crc16 = ((uint16_t)out_buf[4] << 8 | (uint16_t)out_buf[3]); /* get crc16 */
909 if (crc16 != a_am2320_generate_crc16(out_buf, 3)) /* check crc16 */
910 {
911 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
912
913 return 1; /* return error */
914 }
915 if (out_buf[0] != 0x03) /* check code */
916 {
917 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
918
919 return 1; /* return error */
920 }
921 if (out_buf[1] != 0x01) /* check number */
922 {
923 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
924
925 return 1; /* return error */
926 }
927 *version = out_buf[2]; /* get type */
928
929 return 0; /* success return 0 */
930}
931
944uint8_t am2320_get_status(am2320_handle_t *handle, uint8_t *status)
945{
946 uint8_t res;
947 uint8_t input_buf[3];
948 uint8_t out_buf[5];
949 uint16_t crc16;
950
951 if (handle == NULL) /* check handle */
952 {
953 return 2; /* return error */
954 }
955 if (handle->inited != 1) /* check handle initialization */
956 {
957 return 3; /* return error */
958 }
959
960 if (handle->gpio_iic != 0) /* gpio */
961 {
962 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
963
964 return 4; /* return error */
965 }
966
967 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
968 input_buf[0] = 0x03; /* set function code */
969 input_buf[1] = AM2320_MODBUS_ADDRESS_STATUS; /* set addr */
970 input_buf[2] = 0x01; /* set number */
971 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
972 if (res != 0) /* check result */
973 {
974 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
975
976 return 1; /* return error */
977 }
978 handle->delay_ms(2); /* delay 2ms */
979 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 5); /* read command */
980 if (res != 0) /* check result */
981 {
982 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
983
984 return 1; /* return error */
985 }
986 crc16 = ((uint16_t)out_buf[4] << 8 | (uint16_t)out_buf[3]); /* get crc16 */
987 if (crc16 != a_am2320_generate_crc16(out_buf, 3)) /* check crc16 */
988 {
989 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
990
991 return 1; /* return error */
992 }
993 if (out_buf[0] != 0x03) /* check code */
994 {
995 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
996
997 return 1; /* return error */
998 }
999 if (out_buf[1] != 0x01) /* check number */
1000 {
1001 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1002
1003 return 1; /* return error */
1004 }
1005 *status = out_buf[2]; /* get status */
1006
1007 return 0; /* success return 0 */
1008}
1009
1022uint8_t am2320_get_device_id(am2320_handle_t *handle, uint32_t *id)
1023{
1024 uint8_t res;
1025 uint8_t input_buf[3];
1026 uint8_t out_buf[8];
1027 uint16_t crc16;
1028
1029 if (handle == NULL) /* check handle */
1030 {
1031 return 2; /* return error */
1032 }
1033 if (handle->inited != 1) /* check handle initialization */
1034 {
1035 return 3; /* return error */
1036 }
1037
1038 if (handle->gpio_iic != 0) /* gpio */
1039 {
1040 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1041
1042 return 4; /* return error */
1043 }
1044
1045 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1046 input_buf[0] = 0x03; /* set function code */
1047 input_buf[1] = AM2320_MODBUS_ADDRESS_DEVICE_3; /* set addr */
1048 input_buf[2] = 0x04; /* set number */
1049 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
1050 if (res != 0) /* check result */
1051 {
1052 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1053
1054 return 1; /* return error */
1055 }
1056 handle->delay_ms(2); /* delay 2ms */
1057 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 8); /* read command */
1058 if (res != 0) /* check result */
1059 {
1060 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1061
1062 return 1; /* return error */
1063 }
1064 crc16 = ((uint16_t)out_buf[7] << 8 | (uint16_t)out_buf[6]); /* get crc16 */
1065 if (crc16 != a_am2320_generate_crc16(out_buf, 6)) /* check crc16 */
1066 {
1067 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
1068
1069 return 1; /* return error */
1070 }
1071 if (out_buf[0] != 0x03) /* check code */
1072 {
1073 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
1074
1075 return 1; /* return error */
1076 }
1077 if (out_buf[1] != 0x04) /* check number */
1078 {
1079 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1080
1081 return 1; /* return error */
1082 }
1083 *id = (uint32_t)out_buf[2] << 24 | (uint32_t)out_buf[3] << 16 |
1084 (uint32_t)out_buf[4] << 8 | (uint32_t)out_buf[5] << 0; /* get device id */
1085
1086 return 0; /* success return 0 */
1087}
1088
1101uint8_t am2320_set_user_reg1(am2320_handle_t *handle, uint16_t reg)
1102{
1103 uint8_t res;
1104 uint8_t input_buf[7];
1105 uint8_t out_buf[5];
1106 uint16_t crc16;
1107
1108 if (handle == NULL) /* check handle */
1109 {
1110 return 2; /* return error */
1111 }
1112 if (handle->inited != 1) /* check handle initialization */
1113 {
1114 return 3; /* return error */
1115 }
1116
1117 if (handle->gpio_iic != 0) /* gpio */
1118 {
1119 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1120
1121 return 4; /* return error */
1122 }
1123
1124 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1125 input_buf[0] = 0x10; /* set function code */
1126 input_buf[1] = AM2320_MODBUS_ADDRESS_USER_REG1_MSB; /* set addr */
1127 input_buf[2] = 0x02; /* set number */
1128 input_buf[3] = (reg >> 8) & 0xFF; /* set reg msb */
1129 input_buf[4] = (reg >> 0) & 0xFF; /* set reg lsb */
1130 crc16 = a_am2320_generate_crc16(input_buf, 5); /* get crc16*/
1131 input_buf[5] = (crc16 >> 0) & 0xFF; /* set reg msb */
1132 input_buf[6] = (crc16 >> 8) & 0xFF; /* set reg lsb */
1133 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 7); /* write command */
1134 if (res != 0) /* check result */
1135 {
1136 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1137
1138 return 1; /* return error */
1139 }
1140 handle->delay_ms(2); /* delay 2ms */
1141 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 5); /* read command */
1142 if (res != 0) /* check result */
1143 {
1144 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1145
1146 return 1; /* return error */
1147 }
1148 crc16 = ((uint16_t)out_buf[4] << 8 | (uint16_t)out_buf[3]); /* get crc16 */
1149 if (crc16 != a_am2320_generate_crc16(out_buf, 3)) /* check crc16 */
1150 {
1151 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
1152
1153 return 1; /* return error */
1154 }
1155 if (out_buf[0] != 0x10) /* check code */
1156 {
1157 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
1158
1159 return 1; /* return error */
1160 }
1161 if (out_buf[1] != AM2320_MODBUS_ADDRESS_USER_REG1_MSB) /* check number */
1162 {
1163 handle->debug_print("am2320: addr is invalid.\n"); /* addr is invalid */
1164
1165 return 1; /* return error */
1166 }
1167 if (out_buf[2] != 0x02) /* check number */
1168 {
1169 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1170
1171 return 1; /* return error */
1172 }
1173
1174 return 0; /* success return 0 */
1175}
1176
1189uint8_t am2320_get_user_reg1(am2320_handle_t *handle, uint16_t *reg)
1190{
1191 uint8_t res;
1192 uint8_t input_buf[3];
1193 uint8_t out_buf[6];
1194 uint16_t crc16;
1195
1196 if (handle == NULL) /* check handle */
1197 {
1198 return 2; /* return error */
1199 }
1200 if (handle->inited != 1) /* check handle initialization */
1201 {
1202 return 3; /* return error */
1203 }
1204
1205 if (handle->gpio_iic != 0) /* gpio */
1206 {
1207 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1208
1209 return 4; /* return error */
1210 }
1211
1212 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1213 input_buf[0] = 0x03; /* set function code */
1214 input_buf[1] = AM2320_MODBUS_ADDRESS_USER_REG1_MSB; /* set addr */
1215 input_buf[2] = 0x02; /* set number */
1216 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
1217 if (res != 0) /* check result */
1218 {
1219 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1220
1221 return 1; /* return error */
1222 }
1223 handle->delay_ms(2); /* delay 2ms */
1224 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 6); /* read command */
1225 if (res != 0) /* check result */
1226 {
1227 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1228
1229 return 1; /* return error */
1230 }
1231 crc16 = ((uint16_t)out_buf[5] << 8 | (uint16_t)out_buf[4]); /* get crc16 */
1232 if (crc16 != a_am2320_generate_crc16(out_buf, 4)) /* check crc16 */
1233 {
1234 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
1235
1236 return 1; /* return error */
1237 }
1238 if (out_buf[0] != 0x03) /* check code */
1239 {
1240 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
1241
1242 return 1; /* return error */
1243 }
1244 if (out_buf[1] != 0x02) /* check number */
1245 {
1246 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1247
1248 return 1; /* return error */
1249 }
1250 *reg = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get reg */
1251
1252 return 0; /* success return 0 */
1253}
1254
1267uint8_t am2320_set_user_reg2(am2320_handle_t *handle, uint16_t reg)
1268{
1269 uint8_t res;
1270 uint8_t input_buf[7];
1271 uint8_t out_buf[5];
1272 uint16_t crc16;
1273
1274 if (handle == NULL) /* check handle */
1275 {
1276 return 2; /* return error */
1277 }
1278 if (handle->inited != 1) /* check handle initialization */
1279 {
1280 return 3; /* return error */
1281 }
1282
1283 if (handle->gpio_iic != 0) /* gpio */
1284 {
1285 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1286
1287 return 4; /* return error */
1288 }
1289
1290 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1291 input_buf[0] = 0x10; /* set function code */
1292 input_buf[1] = AM2320_MODBUS_ADDRESS_USER_REG2_MSB; /* set addr */
1293 input_buf[2] = 0x02; /* set number */
1294 input_buf[3] = (reg >> 8) & 0xFF; /* set reg msb */
1295 input_buf[4] = (reg >> 0) & 0xFF; /* set reg lsb */
1296 crc16 = a_am2320_generate_crc16(input_buf, 5); /* get crc16*/
1297 input_buf[5] = (crc16 >> 0) & 0xFF; /* set reg msb */
1298 input_buf[6] = (crc16 >> 8) & 0xFF; /* set reg lsb */
1299 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 7); /* write command */
1300 if (res != 0) /* check result */
1301 {
1302 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1303
1304 return 1; /* return error */
1305 }
1306 handle->delay_ms(2); /* delay 2ms */
1307 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 5); /* read command */
1308 if (res != 0) /* check result */
1309 {
1310 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1311
1312 return 1; /* return error */
1313 }
1314 crc16 = ((uint16_t)out_buf[4] << 8 | (uint16_t)out_buf[3]); /* get crc16 */
1315 if (crc16 != a_am2320_generate_crc16(out_buf, 3)) /* check crc16 */
1316 {
1317 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
1318
1319 return 1; /* return error */
1320 }
1321 if (out_buf[0] != 0x10) /* check code */
1322 {
1323 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
1324
1325 return 1; /* return error */
1326 }
1327 if (out_buf[1] != AM2320_MODBUS_ADDRESS_USER_REG2_MSB) /* check number */
1328 {
1329 handle->debug_print("am2320: addr is invalid.\n"); /* addr is invalid */
1330
1331 return 1; /* return error */
1332 }
1333 if (out_buf[2] != 0x02) /* check number */
1334 {
1335 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1336
1337 return 1; /* return error */
1338 }
1339
1340 return 0; /* success return 0 */
1341}
1342
1355uint8_t am2320_get_user_reg2(am2320_handle_t *handle, uint16_t *reg)
1356{
1357 uint8_t res;
1358 uint8_t input_buf[3];
1359 uint8_t out_buf[6];
1360 uint16_t crc16;
1361
1362 if (handle == NULL) /* check handle */
1363 {
1364 return 2; /* return error */
1365 }
1366 if (handle->inited != 1) /* check handle initialization */
1367 {
1368 return 3; /* return error */
1369 }
1370
1371 if (handle->gpio_iic != 0) /* gpio */
1372 {
1373 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1374
1375 return 4; /* return error */
1376 }
1377
1378 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1379 input_buf[0] = 0x03; /* set function code */
1380 input_buf[1] = AM2320_MODBUS_ADDRESS_USER_REG2_MSB; /* set addr */
1381 input_buf[2] = 0x02; /* set number */
1382 res = handle->iic_write_cmd(AM2320_ADDRESS, (uint8_t *)input_buf, 3); /* write command */
1383 if (res != 0) /* check result */
1384 {
1385 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1386
1387 return 1; /* return error */
1388 }
1389 handle->delay_ms(2); /* delay 2ms */
1390 res = handle->iic_read_cmd(AM2320_ADDRESS, (uint8_t *)out_buf, 6); /* read command */
1391 if (res != 0) /* check result */
1392 {
1393 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1394
1395 return 1; /* return error */
1396 }
1397 crc16 = ((uint16_t)out_buf[5] << 8 | (uint16_t)out_buf[4]); /* get crc16 */
1398 if (crc16 != a_am2320_generate_crc16(out_buf, 4)) /* check crc16 */
1399 {
1400 handle->debug_print("am2320: crc check error.\n"); /* crc check error */
1401
1402 return 1; /* return error */
1403 }
1404 if (out_buf[0] != 0x03) /* check code */
1405 {
1406 handle->debug_print("am2320: code is invalid.\n"); /* code is invalid */
1407
1408 return 1; /* return error */
1409 }
1410 if (out_buf[1] != 0x02) /* check number */
1411 {
1412 handle->debug_print("am2320: number is invalid.\n"); /* number is invalid */
1413
1414 return 1; /* return error */
1415 }
1416 *reg = (uint16_t)out_buf[2] << 8 | out_buf[3]; /* get reg */
1417
1418 return 0; /* success return 0 */
1419}
1420
1433{
1434 if (handle == NULL) /* check handle */
1435 {
1436 return 2; /* return error */
1437 }
1438 if (handle->debug_print == NULL) /* check debug_print */
1439 {
1440 return 3; /* return error */
1441 }
1442 if (handle->iic_init == NULL) /* check iic_init */
1443 {
1444 handle->debug_print("am2320: iic_init is null.\n"); /* iic_init is null */
1445
1446 return 3; /* return error */
1447 }
1448 if (handle->iic_deinit == NULL) /* check iic_deinit */
1449 {
1450 handle->debug_print("am2320: iic_deinit is null.\n"); /* iic_deinit is null */
1451
1452 return 3; /* return error */
1453 }
1454 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
1455 {
1456 handle->debug_print("am2320: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
1457
1458 return 3; /* return error */
1459 }
1460 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
1461 {
1462 handle->debug_print("am2320: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
1463
1464 return 3; /* return error */
1465 }
1466 if (handle->bus_init == NULL) /* check bus_init */
1467 {
1468 handle->debug_print("am2320: bus_init is null.\n"); /* bus_init is null */
1469
1470 return 3; /* return error */
1471 }
1472 if (handle->bus_deinit == NULL) /* check bus_deinit */
1473 {
1474 handle->debug_print("am2320: bus_deinit is null.\n"); /* bus_deinit is null */
1475
1476 return 3; /* return error */
1477 }
1478 if (handle->bus_read == NULL) /* check bus_read */
1479 {
1480 handle->debug_print("am2320: bus_read is null.\n"); /* bus_read is null */
1481
1482 return 3; /* return error */
1483 }
1484 if (handle->bus_write == NULL) /* check bus_write */
1485 {
1486 handle->debug_print("am2320: bus_write is null.\n"); /* bus_write is null */
1487
1488 return 3; /* return error */
1489 }
1490 if (handle->delay_ms == NULL) /* check delay_ms */
1491 {
1492 handle->debug_print("am2320: delay_ms is null.\n"); /* delay_ms is null */
1493
1494 return 3; /* return error */
1495 }
1496 if (handle->delay_us == NULL) /* check delay_us */
1497 {
1498 handle->debug_print("am2320: delay_us is null.\n"); /* delay_us is null */
1499
1500 return 3; /* return error */
1501 }
1502 if (handle->enable_irq == NULL) /* check enable_irq */
1503 {
1504 handle->debug_print("am2320: enable_irq is null.\n"); /* enable_irq is null */
1505
1506 return 3; /* return error */
1507 }
1508 if (handle->disable_irq == NULL) /* check disable_irq */
1509 {
1510 handle->debug_print("am2320: disable_irq is null.\n"); /* disable_irq is null */
1511
1512 return 3; /* return error */
1513 }
1514
1515 if (handle->gpio_iic != 0) /* gpio */
1516 {
1517 if (handle->bus_init() != 0) /* initialize bus */
1518 {
1519 handle->debug_print("am2320: bus init failed.\n"); /* bus init failed */
1520
1521 return 1; /* return error */
1522 }
1523 if (a_am2320_reset(handle) != 0) /* reset the chip */
1524 {
1525 handle->debug_print("am2320: reset failed.\n"); /* reset failed */
1526 (void)handle->bus_deinit(); /* close bus */
1527
1528 return 4; /* return error */
1529 }
1530 }
1531 else /* iic */
1532 {
1533 if (handle->iic_init() != 0) /* iic init */
1534 {
1535 handle->debug_print("am2320: iic init failed.\n"); /* iic init failed */
1536
1537 return 1; /* return error */
1538 }
1539 }
1540 handle->inited = 1; /* flag finish initialization */
1541
1542 return 0; /* success return 0 */
1543}
1544
1556{
1557 if (handle == NULL) /* check handle */
1558 {
1559 return 2; /* return error */
1560 }
1561 if (handle->inited != 1) /* check handle initialization */
1562 {
1563 return 3; /* return error */
1564 }
1565
1566 if (handle->gpio_iic != 0) /* gpio */
1567 {
1568 if (handle->bus_deinit() != 0) /* close bus */
1569 {
1570 handle->debug_print("am2320: deinit failed.\n"); /* deinit failed */
1571
1572 return 1; /* return error */
1573 }
1574 }
1575 else /* iic */
1576 {
1577 if (handle->iic_deinit() != 0) /* iic deinit */
1578 {
1579 handle->debug_print("am2320: iic deinit failed.\n"); /* iic deinit failed */
1580
1581 return 1; /* return error */
1582 }
1583 }
1584 handle->inited = 0; /* flag close */
1585
1586 return 0; /* success return 0 */
1587}
1588
1604uint8_t am2320_set_get_reg(am2320_handle_t *handle, uint8_t *input_buf, uint16_t input_len, uint8_t *output_buf, uint16_t output_len)
1605{
1606 uint8_t res;
1607
1608 if (handle == NULL) /* check handle */
1609 {
1610 return 2; /* return error */
1611 }
1612 if (handle->inited != 1) /* check handle initialization */
1613 {
1614 return 3; /* return error */
1615 }
1616
1617 if (handle->gpio_iic != 0) /* gpio */
1618 {
1619 handle->debug_print("am2320: gpio can't use this function.\n"); /* gpio can't use this function */
1620
1621 return 4; /* return error */
1622 }
1623
1624 (void)handle->iic_write_cmd(AM2320_ADDRESS, NULL, 0); /* wake up */
1625 res = handle->iic_write_cmd(AM2320_ADDRESS, input_buf, input_len); /* write command */
1626 if (res != 0) /* check result */
1627 {
1628 handle->debug_print("am2320: write command failed.\n"); /* write command failed */
1629
1630 return 1; /* return error */
1631 }
1632 handle->delay_ms(2); /* delay 2ms */
1633 res = handle->iic_read_cmd(AM2320_ADDRESS, output_buf, output_len); /* read command */
1634 if (res != 0) /* check result */
1635 {
1636 handle->debug_print("am2320: read command failed.\n"); /* read command failed */
1637
1638 return 1; /* return error */
1639 }
1640
1641 return 0; /* success return 0 */
1642}
1643
1653{
1654 if (info == NULL) /* check handle */
1655 {
1656 return 2; /* return error */
1657 }
1658
1659 memset(info, 0, sizeof(am2320_info_t)); /* initialize am2320 info structure */
1660 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
1661 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
1662 strncpy(info->interface, "GPIO IIC", 16); /* copy interface name */
1663 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
1664 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
1665 info->max_current_ma = MAX_CURRENT; /* set maximum current */
1666 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
1667 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
1668 info->driver_version = DRIVER_VERSION; /* set driver version */
1669
1670 return 0; /* success return 0 */
1671}
#define AM2320_MODBUS_ADDRESS_DEVICE_TYPE_MSB
#define AM2320_MODBUS_ADDRESS_HUMI_MSB
modbus address definition
#define AM2320_MODBUS_ADDRESS_USER_REG2_MSB
#define MAX_CURRENT
#define AM2320_MODBUS_ADDRESS_VERSION
#define AM2320_MODBUS_ADDRESS_DEVICE_3
#define AM2320_MODBUS_ADDRESS_STATUS
#define AM2320_ADDRESS
chip address definition
#define SUPPLY_VOLTAGE_MAX
#define TEMPERATURE_MAX
#define MANUFACTURER_NAME
#define AM2320_MODBUS_ADDRESS_TEMP_MSB
#define TEMPERATURE_MIN
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip information definition
#define AM2320_MODBUS_ADDRESS_USER_REG1_MSB
#define DRIVER_VERSION
driver am2320 header file
uint8_t am2320_set_user_reg1(am2320_handle_t *handle, uint16_t reg)
set user reg1
uint8_t am2320_get_version(am2320_handle_t *handle, uint8_t *version)
get version
uint8_t am2320_get_device_type(am2320_handle_t *handle, uint16_t *type)
get device type
struct am2320_handle_s am2320_handle_t
am2320 handle structure definition
uint8_t am2320_init(am2320_handle_t *handle)
initialize the chip
uint8_t am2320_get_interface(am2320_handle_t *handle, am2320_interface_t *interface)
get the chip interface
uint8_t am2320_read_temperature(am2320_handle_t *handle, uint16_t *raw, float *s)
read the temperature data
uint8_t am2320_read_temperature_humidity(am2320_handle_t *handle, uint16_t *temperature_raw, float *temperature_s, uint16_t *humidity_raw, float *humidity_s)
read the temperature and humidity data
am2320_interface_t
am2320 interface enumeration definition
uint8_t am2320_set_user_reg2(am2320_handle_t *handle, uint16_t reg)
set user reg2
uint8_t am2320_get_device_id(am2320_handle_t *handle, uint32_t *id)
get device id
uint8_t am2320_get_status(am2320_handle_t *handle, uint8_t *status)
get status
uint8_t am2320_get_user_reg1(am2320_handle_t *handle, uint16_t *reg)
get user reg1
uint8_t am2320_read_humidity(am2320_handle_t *handle, uint16_t *raw, float *s)
read the humidity data
uint8_t am2320_deinit(am2320_handle_t *handle)
close the chip
uint8_t am2320_info(am2320_info_t *info)
get chip's information
uint8_t am2320_set_interface(am2320_handle_t *handle, am2320_interface_t interface)
set the chip interface
struct am2320_info_s am2320_info_t
am2320 info structure definition
uint8_t am2320_get_user_reg2(am2320_handle_t *handle, uint16_t *reg)
get user reg2
uint8_t am2320_set_get_reg(am2320_handle_t *handle, uint8_t *input_buf, uint16_t input_len, uint8_t *output_buf, uint16_t output_len)
set and get the register value
void(* enable_irq)(void)
uint8_t(* bus_deinit)(void)
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* iic_init)(void)
void(* delay_us)(uint32_t us)
void(* disable_irq)(void)
uint8_t(* bus_read)(uint8_t *value)
uint8_t(* bus_write)(uint8_t value)
uint8_t(* iic_read_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
uint8_t(* bus_init)(void)
uint8_t(* iic_deinit)(void)
uint8_t(* iic_write_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
float supply_voltage_max_v
uint32_t driver_version
char interface[16]
char manufacturer_name[32]
float supply_voltage_min_v
char chip_name[32]