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