LibDriver SGP30
Loading...
Searching...
No Matches
driver_sgp30.c
Go to the documentation of this file.
1
37
38#include "driver_sgp30.h"
39
43#define CHIP_NAME "Sensirion SGP30"
44#define MANUFACTURER_NAME "Sensirion"
45#define SUPPLY_VOLTAGE_MIN 1.62f
46#define SUPPLY_VOLTAGE_MAX 1.98f
47#define MAX_CURRENT 48.8f
48#define TEMPERATURE_MIN -40.0f
49#define TEMPERATURE_MAX 85.0f
50#define DRIVER_VERSION 2000
51
55#define SGP30_ADDRESS (0x58 << 1)
56
60#define SGP30_COMMAND_IAQ_INIT 0x2003U
61#define SGP30_COMMAND_MEASURE_IAQ 0x2008U
62#define SGP30_COMMAND_GET_IAQ_BASELINE 0x2015U
63#define SGP30_COMMAND_SET_IAQ_BASELINE 0x201EU
64#define SGP30_COMMAND_SET_ABSOLUTE_HUMIDITY 0x2061U
65#define SGP30_COMMAND_MEASURE_TEST 0x2032U
66#define SGP30_COMMAND_GET_FEATURE_SET 0x202FU
67#define SGP30_COMMAND_MEASURE_RAW 0x2050U
68#define SGP30_COMMAND_GET_TVOC_INCEPTIVE_BASELINE 0x20B3U
69#define SGP30_COMMAND_SET_TVOC_BASELINE 0x2077U
70#define SGP30_COMMAND_SOFT_RESET 0x0006U
71#define SGP30_COMMAND_GET_SERIAL_ID 0x3682U
72
76#define SGP30_CRC8_POLYNOMIAL 0x31
77#define SGP30_CRC8_INIT 0xFF
78
92static uint8_t a_sgp30_iic_read(sgp30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
93{
94 uint8_t buf[2];
95
96 memset(buf, 0, sizeof(uint8_t) * 2); /* clear the buffer */
97 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set reg MSB */
98 buf[1] = (uint8_t)(reg & 0xFF); /* set reg LSB */
99 if (handle->iic_write_cmd(addr, (uint8_t *)buf, 2) != 0) /* write command */
100 {
101 return 1; /* return error */
102 }
103 handle->delay_ms(delay_ms); /* delay ms */
104 if (handle->iic_read_cmd(addr, data, len) != 0) /* read data */
105 {
106 return 1; /* return error */
107 }
108 else
109 {
110 return 0; /* success return 0 */
111 }
112}
113
126static uint8_t a_sgp30_iic_write(sgp30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len)
127{
128 uint8_t buf[16];
129 uint16_t i;
130
131 if ((len + 2) > 16) /* check length */
132 {
133 return 1; /* return error */
134 }
135 memset(buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
136 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set MSB of reg */
137 buf[1] = (uint8_t)(reg & 0xFF); /* set LSB of reg */
138 for (i = 0; i < len; i++)
139 {
140 buf[2 + i] = data[i]; /* copy write data */
141 }
142
143 if (handle->iic_write_cmd(addr, (uint8_t *)buf, len + 2) != 0) /* write iic command */
144 {
145 return 1; /* return error */
146 }
147 else
148 {
149 return 0; /* success return 0 */
150 }
151}
152
160static uint8_t a_sgp30_generate_crc(uint8_t* data, uint8_t count)
161{
162 uint8_t current_byte;
163 uint8_t crc = SGP30_CRC8_INIT;
164 uint8_t crc_bit;
165
166 for (current_byte = 0; current_byte < count; ++current_byte) /* calculate crc */
167 {
168 crc ^= (data[current_byte]); /* xor data */
169 for (crc_bit = 8; crc_bit > 0; --crc_bit) /* 8 bit */
170 {
171 if ((crc & 0x80) != 0) /* if 7th bit is 1 */
172 {
173 crc = (crc << 1) ^ SGP30_CRC8_POLYNOMIAL; /* xor */
174 }
175 else
176 {
177 crc = crc << 1; /* left shift 1 */
178 }
179 }
180 }
181
182 return crc; /* return crc */
183}
184
196uint8_t sgp30_set_tvoc_baseline(sgp30_handle_t *handle, uint16_t tvoc_baseline)
197{
198 uint8_t res;
199 uint8_t buf[3];
200
201 if (handle == NULL) /* check handle */
202 {
203 return 2; /* return error */
204 }
205 if (handle->inited != 1) /* check handle initialization */
206 {
207 return 3; /* return error */
208 }
209
210 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
211 buf[0] = (tvoc_baseline >> 8) & 0xFF; /* get high part */
212 buf[1] = (tvoc_baseline >> 0) & 0xFF; /* get low part */
213 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2); /* generate crc */
214 res = a_sgp30_iic_write(handle, SGP30_ADDRESS, SGP30_COMMAND_SET_TVOC_BASELINE, (uint8_t *)buf, 3); /* write set tvoc baseline command */
215 if (res != 0) /* check result */
216 {
217 handle->debug_print("sgp30: write tvoc baseline failed.\n"); /* write tvoc baseline failed */
218
219 return 1; /* return error */
220 }
221 handle->delay_ms(10); /* wait 10 ms */
222
223 return 0; /* success return 0 */
224}
225
237uint8_t sgp30_get_tvoc_inceptive_baseline(sgp30_handle_t *handle, uint16_t *tvoc_baseline)
238{
239 uint8_t res;
240 uint8_t buf[3];
241
242 if (handle == NULL) /* check handle */
243 {
244 return 2; /* return error */
245 }
246 if (handle->inited != 1) /* check handle initialization */
247 {
248 return 3; /* return error */
249 }
250
251 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
252 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_GET_TVOC_INCEPTIVE_BASELINE, (uint8_t *)buf, 3, 10); /* read tvoc inceptive baseline */
253 if (res != 0) /* check result */
254 {
255 handle->debug_print("sgp30: read tvoc baseline failed.\n"); /* read tvoc baseline failed */
256
257 return 1; /* return error */
258 }
259 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check crc */
260 {
261 handle->debug_print("sgp30: crc check error.\n"); /* crc check error */
262
263 return 1; /* return error */
264 }
265 *tvoc_baseline = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* get data */
266
267 return 0; /* success return 0 */
268}
269
281{
282 uint8_t res;
283
284 if (handle == NULL) /* check handle */
285 {
286 return 2; /* return error */
287 }
288 if (handle->inited != 1) /* check handle initialization */
289 {
290 return 3; /* return error */
291 }
292
293 res = a_sgp30_iic_write(handle, SGP30_ADDRESS, SGP30_COMMAND_IAQ_INIT, NULL, 0); /* write iaq init command */
294 if (res != 0) /* check result */
295 {
296 handle->debug_print("sgp30: write iaq init failed.\n"); /* write iaq init failed */
297
298 return 1; /* return error */
299 }
300 handle->delay_ms(10); /* wait 10 ms */
301
302 return 0; /* success return 0 */
303}
304
316{
317 uint8_t res;
318 uint8_t reg;
319
320 if (handle == NULL) /* check handle */
321 {
322 return 2; /* return error */
323 }
324 if (handle->inited != 1) /* check handle initialization */
325 {
326 return 3; /* return error */
327 }
328
329 reg = 0x06; /* soft reset command */
330 res = handle->iic_write_cmd(0x00, (uint8_t *)&reg, 1); /* write reset config */
331 if (res != 0) /* check result */
332 {
333 handle->debug_print("sgp30: write soft reset failed.\n"); /* write soft reset failed */
334
335 return 1; /* return error */
336 }
337
338 return 0; /* success return 0 */
339}
340
352uint8_t sgp30_get_serial_id(sgp30_handle_t *handle, uint16_t id[3])
353{
354 uint8_t res;
355 uint8_t buf[9];
356
357 if (handle == NULL) /* check handle */
358 {
359 return 2; /* return error */
360 }
361 if (handle->inited != 1) /* check handle initialization */
362 {
363 return 3; /* return error */
364 }
365
366 memset(buf, 0, sizeof(uint8_t) * 9); /* clear the buffer */
367 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_GET_SERIAL_ID, (uint8_t *)buf, 9, 10); /* read config */
368 if (res != 0) /* check result */
369 {
370 handle->debug_print("sgp30: read serial id failed.\n"); /* read serial id failed */
371
372 return 1; /* return error */
373 }
374 if (buf[2] != a_sgp30_generate_crc((uint8_t *)&buf[0], 2)) /* check 1st crc */
375 {
376 handle->debug_print("sgp30: crc 1 check failed.\n"); /* crc 1 check failed */
377
378 return 1; /* return error */
379 }
380 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2)) /* check 2nd crc */
381 {
382 handle->debug_print("sgp30: crc 2 check failed.\n"); /* crc 2 check failed */
383
384 return 1; /* return error */
385 }
386 if (buf[8] != a_sgp30_generate_crc((uint8_t *)&buf[6], 2)) /* check 3rd crc */
387 {
388 handle->debug_print("sgp30: crc 3 check failed.\n"); /* crc 3 check failed */
389
390 return 1; /* return error */
391 }
392 id[0] = (uint16_t)((((uint16_t)buf[0]) << 8) | buf[1]); /* set id 0 */
393 id[1] = (uint16_t)((((uint16_t)buf[3]) << 8) | buf[4]); /* set id 1 */
394 id[2] = (uint16_t)((((uint16_t)buf[6]) << 8) | buf[7]); /* set id 2 */
395
396 return 0; /* success return 0 */
397}
398
411uint8_t sgp30_measure_iaq(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
412{
413 uint8_t res;
414 uint8_t buf[6];
415
416 if (handle == NULL) /* check handle */
417 {
418 return 2; /* return error */
419 }
420 if (handle->inited != 1) /* check handle initialization */
421 {
422 return 3; /* return error */
423 }
424
425 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
426 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_MEASURE_IAQ, (uint8_t *)buf, 6, 12); /* read measure iaq */
427 if (res != 0) /* check result */
428 {
429 handle->debug_print("sgp30: read measure iaq failed.\n"); /* read measure iaq failed */
430
431 return 1; /* return error */
432 }
433 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* calculate crc */
434 {
435 handle->debug_print("sgp30: co2 eq crc check error.\n"); /* co2 eq crc check error */
436
437 return 1; /* return error */
438 }
439 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2)) /* calculate crc */
440 {
441 handle->debug_print("sgp30: tvoc crc check error.\n"); /* tvoc crc check error */
442
443 return 1; /* return error */
444 }
445 *co2_eq_ppm = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* get co2 eq ppm */
446 *tvoc_ppb = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]); /* get tvoc ppb */
447
448 return 0; /* success return 0 */
449}
450
463uint8_t sgp30_get_iaq_baseline(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
464{
465 uint8_t res;
466 uint8_t buf[6];
467
468 if (handle == NULL) /* check handle */
469 {
470 return 2; /* return error */
471 }
472 if (handle->inited != 1) /* check handle initialization */
473 {
474 return 3; /* return error */
475 }
476
477 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
478 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_GET_IAQ_BASELINE, (uint8_t *)buf, 6, 10); /* read iaq baseline */
479 if (res != 0) /* check result */
480 {
481 handle->debug_print("sgp30: read measure iaq failed.\n"); /* read measure iaq failed */
482
483 return 1; /* return error */
484 }
485 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check co2 crc */
486 {
487 handle->debug_print("sgp30: co2 eq crc check error.\n"); /* co2 eq crc check error */
488
489 return 1; /* return error */
490 }
491 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2)) /* check tvoc crc */
492 {
493 handle->debug_print("sgp30: tvoc crc check error.\n"); /* tvoc crc check error */
494
495 return 1; /* return error */
496 }
497 *co2_eq = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* get co2 eq */
498 *tvoc = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]); /* get tvoc */
499
500 return 0; /* success return 0 */
501}
502
515uint8_t sgp30_set_iaq_baseline(sgp30_handle_t *handle, uint16_t tvoc, uint16_t co2_eq)
516{
517 uint8_t res;
518 uint8_t buf[6];
519
520 if (handle == NULL) /* check handle */
521 {
522 return 2; /* return error */
523 }
524 if (handle->inited != 1) /* check handle initialization */
525 {
526 return 3; /* return error */
527 }
528
529 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
530 buf[0] = (tvoc >> 8) & 0xFF; /* set tvoc high part */
531 buf[1] = tvoc & 0xFF; /* set tvoc low part */
532 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2); /* generate tvoc crc */
533 buf[3] = (co2_eq >> 8) & 0xFF; /* set co2 eq high part */
534 buf[4] = co2_eq & 0xFF; /* set co2 eq low part */
535 buf[5] = a_sgp30_generate_crc((uint8_t *)&buf[3], 2); /* generate co2_eq crc */
536 res = a_sgp30_iic_write(handle, SGP30_ADDRESS, SGP30_COMMAND_SET_IAQ_BASELINE, (uint8_t *)buf, 6); /* write iaq baseline command */
537 if (res != 0) /* check result */
538 {
539 handle->debug_print("sgp30: write iaq baseline failed.\n"); /* write iaq baseline failed */
540
541 return 1; /* return error */
542 }
543 handle->delay_ms(10); /* delay 10 ms */
544
545 return 0; /* success return 0 */
546}
547
559uint8_t sgp30_set_absolute_humidity(sgp30_handle_t *handle, uint16_t humidity)
560{
561 uint8_t res;
562 uint8_t buf[3];
563
564 if (handle == NULL) /* check handle */
565 {
566 return 2; /* return error */
567 }
568 if (handle->inited != 1) /* check handle initialization */
569 {
570 return 3; /* return error */
571 }
572
573 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
574 buf[0] = (humidity >> 8) & 0xFF; /* set humidity high part */
575 buf[1] = (humidity >> 0) & 0xFF; /* set humidity low part */
576 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2); /* generate crc */
577 res = a_sgp30_iic_write(handle, SGP30_ADDRESS, SGP30_COMMAND_SET_ABSOLUTE_HUMIDITY, (uint8_t *)buf, 3); /* write set absolute humidity command */
578 if (res != 0) /* check result */
579 {
580 handle->debug_print("sgp30: write absolute humidity failed.\n"); /* write absolute humidity failed */
581
582 return 1; /* return error */
583 }
584 handle->delay_ms(10); /* delay 10 ms */
585
586 return 0; /* success return 0 */
587}
588
602uint8_t sgp30_absolute_humidity_convert_to_register(sgp30_handle_t *handle, float temp, float rh, uint16_t *reg)
603{
604 float absolute_humidity;
605 float intpart, fractpart;
606
607 if (handle == NULL) /* check handle */
608 {
609 return 2; /* return error */
610 }
611 if (handle->inited != 1) /* check handle initialization */
612 {
613 return 3; /* return error */
614 }
615
616 absolute_humidity = (rh / 100.0f * 6.112f * powf(17.62f * temp, 243.12f + temp)) / (273.15f + temp) * 216.7f; /* get absolute humidity */
617 fractpart = modff(absolute_humidity, (float *)&intpart); /* get intpart and fractpart */
618 *reg = (uint16_t)(intpart) << 8 | (uint8_t)(fractpart * 256); /* convert to register */
619
620 return 0; /* success return 0 */
621}
622
634uint8_t sgp30_measure_test(sgp30_handle_t *handle, uint16_t *result)
635{
636 uint8_t res;
637 uint8_t buf[3];
638
639 if (handle == NULL) /* check handle */
640 {
641 return 2; /* return error */
642 }
643 if (handle->inited != 1) /* check handle initialization */
644 {
645 return 3; /* return error */
646 }
647
648 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
649 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_MEASURE_TEST, (uint8_t *)buf, 3, 220); /* read measure test */
650 if (res != 0) /* check result */
651 {
652 handle->debug_print("sgp30: read measure test failed.\n"); /* read measure test failed */
653
654 return 1; /* return error */
655 }
656 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check crc */
657 {
658 handle->debug_print("sgp30: measure test check error.\n"); /* measure test check error */
659
660 return 1; /* return error */
661 }
662 *result = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* combine data */
663
664 return 0; /* success return 0 */
665}
666
679uint8_t sgp30_get_feature_set(sgp30_handle_t *handle, uint8_t *product_type, uint8_t *product_version)
680{
681 uint8_t res;
682 uint8_t buf[3];
683
684 if (handle == NULL) /* check handle */
685 {
686 return 2; /* return error */
687 }
688 if (handle->inited != 1) /* check handle initialization */
689 {
690 return 3; /* return error */
691 }
692
693 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
694 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_GET_FEATURE_SET, (uint8_t *)buf, 3, 10); /* read get feature set */
695 if (res != 0) /* check result */
696 {
697 handle->debug_print("sgp30: get feature set failed.\n"); /* get feature set failed */
698
699 return 1; /* return error */
700 }
701 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check crc */
702 {
703 handle->debug_print("sgp30: feature set check error.\n"); /* crc check error */
704
705 return 1; /* return error */
706 }
707 *product_type = (buf[0] >> 4) & 0xF; /* get product type */
708 *product_version = buf[1]; /* get product version */
709
710 return 0; /* success return 0 */
711}
712
725uint8_t sgp30_get_measure_raw(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
726{
727 uint8_t res;
728 uint8_t buf[6];
729
730 if (handle == NULL) /* check handle */
731 {
732 return 2; /* return error */
733 }
734 if (handle->inited != 1) /* check handle initialization */
735 {
736 return 3; /* return error */
737 }
738
739 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
740 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_MEASURE_RAW, (uint8_t *)buf, 6, 25); /* read measure raw */
741 if (res != 0) /* check result */
742 {
743 handle->debug_print("sgp30: read measure raw failed.\n"); /* read measure failed */
744
745 return 1; /* return error */
746 }
747 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check 1st crc */
748 {
749 handle->debug_print("sgp30: co2 eq crc check error.\n"); /* co2 eq crc check error */
750
751 return 1; /* return error */
752 }
753 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2)) /* check 2nd crc */
754 {
755 handle->debug_print("sgp30: tvoc crc check error.\n"); /* tvoc crc check error */
756
757 return 1; /* return error */
758 }
759 *tvoc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* get tvoc data */
760 *co2_eq = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]); /* get co2 eq data */
761
762 return 0; /* success return 0 */
763}
764
776{
777 if (handle == NULL) /* check handle */
778 {
779 return 2; /* return error */
780 }
781 if (handle->debug_print == NULL) /* check debug_print */
782 {
783 return 3; /* return error */
784 }
785 if (handle->iic_init == NULL) /* check iic_init */
786 {
787 handle->debug_print("sgp30: iic_init is null.\n"); /* iic_init is null */
788
789 return 3; /* return error */
790 }
791 if (handle->iic_deinit == NULL) /* check iic_deinit */
792 {
793 handle->debug_print("sgp30: iic_deinit is null.\n"); /* iic_deinit is null */
794
795 return 3; /* return error */
796 }
797 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
798 {
799 handle->debug_print("sgp30: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
800
801 return 3; /* return error */
802 }
803 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
804 {
805 handle->debug_print("sgp30: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
806
807 return 3; /* return error */
808 }
809 if (handle->delay_ms == NULL) /* check delay_ms */
810 {
811 handle->debug_print("sgp30: delay_ms is null.\n"); /* delay_ms is null */
812
813 return 3; /* return error */
814 }
815
816 if (handle->iic_init() != 0) /* iic init */
817 {
818 handle->debug_print("sgp30: iic init failed.\n"); /* iic init failed */
819
820 return 3; /* return error */
821 }
822 handle->inited = 1; /* flag finish initialization */
823
824 return 0; /* success return 0 */
825}
826
839{
840 if (handle == NULL) /* check handle */
841 {
842 return 2; /* return error */
843 }
844 if (handle->inited != 1) /* check handle initialization */
845 {
846 return 3; /* return error */
847 }
848
849 if (sgp30_soft_reset(handle) != 0) /* reset chip */
850 {
851 handle->debug_print("sgp30: soft reset failed.\n"); /* soft reset failed */
852
853 return 4; /* return error */
854 }
855 if (handle->iic_deinit() != 0) /* iic deinit */
856 {
857 handle->debug_print("sgp30: iic close failed.\n"); /* iic close failed */
858
859 return 1; /* return error */
860 }
861 handle->inited = 0; /* flag close initialization */
862
863 return 0; /* success return 0 */
864}
865
878uint8_t sgp30_read(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
879{
880 uint8_t res;
881 uint8_t buf[6];
882
883 if (handle == NULL) /* check handle */
884 {
885 return 2; /* return error */
886 }
887 if (handle->inited != 1) /* check handle initialization */
888 {
889 return 3; /* return error */
890 }
891
892 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
893 res = a_sgp30_iic_read(handle, SGP30_ADDRESS, SGP30_COMMAND_MEASURE_IAQ, (uint8_t *)buf, 6, 12); /* read measure iaq */
894 if (res != 0) /* check result */
895 {
896 handle->debug_print("sgp30: read measure iaq failed.\n"); /* read measure iaq failed */
897
898 return 1; /* return error */
899 }
900 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2)) /* check 1st crc */
901 {
902 handle->debug_print("sgp30: co2 eq crc check error.\n"); /* co2 eq crc check error */
903
904 return 1; /* return error */
905 }
906 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2)) /* check 2nd crc */
907 {
908 handle->debug_print("sgp30: tvoc crc check error.\n"); /* tvoc crc check error */
909
910 return 1; /* return error */
911 }
912 *co2_eq_ppm = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]); /* get co2 eq ppm data */
913 *tvoc_ppb = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]); /* get tvoc ppb data */
914
915 return 0; /* success return 0 */
916}
917
931uint8_t sgp30_set_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
932{
933 if (handle == NULL) /* check handle */
934 {
935 return 2; /* return error */
936 }
937 if (handle->inited != 1) /* check handle initialization */
938 {
939 return 3; /* return error */
940 }
941
942 return a_sgp30_iic_write(handle, SGP30_ADDRESS, reg, buf, len); /* write data */
943}
944
958uint8_t sgp30_get_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
959{
960 if (handle == NULL) /* check handle */
961 {
962 return 2; /* return error */
963 }
964 if (handle->inited != 1) /* check handle initialization */
965 {
966 return 3; /* return error */
967 }
968
969 return a_sgp30_iic_read(handle, SGP30_ADDRESS, reg, buf, len, 20); /* read data */
970}
971
981{
982 if (info == NULL) /* check handle */
983 {
984 return 2; /* return error */
985 }
986
987 memset(info, 0, sizeof(sgp30_info_t)); /* initialize sgp30 info structure */
988 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
989 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
990 strncpy(info->interface, "IIC", 8); /* copy interface name */
991 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
992 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
993 info->max_current_ma = MAX_CURRENT; /* set maximum current */
994 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
995 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
996 info->driver_version = DRIVER_VERSION; /* set driver version */
997
998 return 0; /* success return 0 */
999}
#define SGP30_CRC8_POLYNOMIAL
crc8 definition
#define SGP30_COMMAND_GET_SERIAL_ID
#define SGP30_COMMAND_GET_IAQ_BASELINE
#define MAX_CURRENT
#define SGP30_COMMAND_MEASURE_RAW
#define SGP30_COMMAND_SET_TVOC_BASELINE
#define SUPPLY_VOLTAGE_MAX
#define SGP30_ADDRESS
chip address definition
#define SGP30_COMMAND_SET_IAQ_BASELINE
#define SGP30_COMMAND_GET_TVOC_INCEPTIVE_BASELINE
#define TEMPERATURE_MAX
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define SUPPLY_VOLTAGE_MIN
#define SGP30_CRC8_INIT
#define SGP30_COMMAND_GET_FEATURE_SET
#define SGP30_COMMAND_MEASURE_TEST
#define CHIP_NAME
chip information definition
#define SGP30_COMMAND_MEASURE_IAQ
#define DRIVER_VERSION
#define SGP30_COMMAND_IAQ_INIT
chip command definition
#define SGP30_COMMAND_SET_ABSOLUTE_HUMIDITY
driver sgp30 header file
uint8_t sgp30_get_iaq_baseline(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
get the chip iaq baseline
uint8_t sgp30_set_tvoc_baseline(sgp30_handle_t *handle, uint16_t tvoc_baseline)
set the chip tvoc baseline
struct sgp30_handle_s sgp30_handle_t
sgp30 handle structure definition
uint8_t sgp30_init(sgp30_handle_t *handle)
initialize the chip
uint8_t sgp30_absolute_humidity_convert_to_register(sgp30_handle_t *handle, float temp, float rh, uint16_t *reg)
convert the absolute humidity to the register data
uint8_t sgp30_deinit(sgp30_handle_t *handle)
close the chip
struct sgp30_info_s sgp30_info_t
sgp30 information structure definition
uint8_t sgp30_get_serial_id(sgp30_handle_t *handle, uint16_t id[3])
get the chip serial id
uint8_t sgp30_set_iaq_baseline(sgp30_handle_t *handle, uint16_t tvoc, uint16_t co2_eq)
set the chip iaq baseline
uint8_t sgp30_set_absolute_humidity(sgp30_handle_t *handle, uint16_t humidity)
set the chip absolute_humidity
uint8_t sgp30_get_measure_raw(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
get the iaq measure raw result
uint8_t sgp30_read(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
read the iaq measure result
uint8_t sgp30_get_feature_set(sgp30_handle_t *handle, uint8_t *product_type, uint8_t *product_version)
get the chip feature
uint8_t sgp30_info(sgp30_info_t *info)
get chip information
uint8_t sgp30_soft_reset(sgp30_handle_t *handle)
soft reset the chip
uint8_t sgp30_measure_test(sgp30_handle_t *handle, uint16_t *result)
run the chip measure test
uint8_t sgp30_measure_iaq(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
get the iaq measure result
uint8_t sgp30_iaq_init(sgp30_handle_t *handle)
initialize the chip iaq
uint8_t sgp30_get_tvoc_inceptive_baseline(sgp30_handle_t *handle, uint16_t *tvoc_baseline)
get the chip tvoc inceptive baseline
uint8_t sgp30_set_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register
uint8_t sgp30_get_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
get the chip register
void(* delay_ms)(uint32_t ms)
void(* debug_print)(const char *const fmt,...)
uint8_t(* iic_init)(void)
uint8_t(* iic_read_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
uint8_t(* iic_deinit)(void)
uint8_t(* iic_write_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
float temperature_max
float supply_voltage_max_v
uint32_t driver_version
float temperature_min
float max_current_ma
char manufacturer_name[32]
float supply_voltage_min_v
char interface[8]
char chip_name[32]