LibDriver STCC4
Loading...
Searching...
No Matches
driver_stcc4.c
Go to the documentation of this file.
1
36
37#include "driver_stcc4.h"
38
42#define CHIP_NAME "Sensirion STCC4"
43#define MANUFACTURER_NAME "Sensirion"
44#define SUPPLY_VOLTAGE_MIN 2.7f
45#define SUPPLY_VOLTAGE_MAX 5.5f
46#define MAX_CURRENT 4.2f
47#define TEMPERATURE_MIN -40.0f
48#define TEMPERATURE_MAX 85.0f
49#define DRIVER_VERSION 1000
50
54#define STCC4_COMMAND_START_CONTINUOUS_MEASUREMENT 0x218BU
55#define STCC4_COMMAND_STOP_CONTINUOUS_MEASUREMENT 0x3F86U
56#define STCC4_COMMAND_READ_MEASUREMENT 0xEC05U
57#define STCC4_COMMAND_SET_RHT_COMPENSATION 0xE000U
58#define STCC4_COMMAND_SET_PRESSURE_COMPENSATION 0xE016U
59#define STCC4_COMMAND_MEASURE_SINGLE_SHOT 0x219DU
60#define STCC4_COMMAND_ENTER_SLEEP_MODE 0x3650U
61#define STCC4_COMMAND_EXIT_SLEEP_MODE 0x00U
62#define STCC4_COMMAND_PERFORM_CONDITIONING 0x29BCU
63#define STCC4_COMMAND_PERFORM_SOFT_RESET 0x06U
64#define STCC4_COMMAND_PERFORM_FACTORY_RESET 0x3632U
65#define STCC4_COMMAND_PERFORM_SELF_TEST 0x278CU
66#define STCC4_COMMAND_ENABLE_TESTING_MODE 0x3FBCU
67#define STCC4_COMMAND_DISABLE_TESTING_MODE 0x3F3DU
68#define STCC4_COMMAND_PERFORM_FORCED_RECALIBRATION 0x362FU
69#define STCC4_COMMAND_GET_PRODUCT_ID 0x365BU
70
74#define STCC4_CRC8_POLYNOMIAL 0x31
75#define STCC4_CRC8_INIT 0xFF
76
91static uint8_t a_stcc4_iic_read_with_param(stcc4_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len,
92 uint16_t delay_ms, uint8_t *output, uint16_t output_len)
93{
94 uint8_t buf[16];
95 uint16_t i;
96
97 if ((len + 2) > 16) /* check length */
98 {
99 return 1; /* return error */
100 }
101 memset(buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
102 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set MSB of reg */
103 buf[1] = (uint8_t)(reg & 0xFF); /* set LSB of reg */
104 for (i = 0; i < len; i++)
105 {
106 buf[2 + i] = data[i]; /* copy write data */
107 }
108
109 if (handle->iic_write_cmd(handle->iic_addr, (uint8_t *)buf, len + 2) != 0) /* write iic command */
110 {
111 return 1; /* write command */
112 }
113 handle->delay_ms(delay_ms); /* delay ms */
114 if (handle->iic_read_cmd(handle->iic_addr, output, output_len) != 0) /* read data */
115 {
116 return 1; /* write command */
117 }
118 else
119 {
120 return 0; /* success return 0 */
121 }
122}
123
136static uint8_t a_stcc4_iic_read(stcc4_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
137{
138 uint8_t buf[2];
139
140 memset(buf, 0, sizeof(uint8_t) * 2); /* clear the buffer */
141 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set reg MSB */
142 buf[1] = (uint8_t)(reg & 0xFF); /* set reg LSB */
143 if (handle->iic_write_cmd(handle->iic_addr, (uint8_t *)buf, 2) != 0) /* write command */
144 {
145 return 1; /* return error */
146 }
147 handle->delay_ms(delay_ms); /* delay ms */
148 if (handle->iic_read_cmd(handle->iic_addr, data, len) != 0) /* read data */
149 {
150 return 1; /* write command */
151 }
152 else
153 {
154 return 0; /* success return 0 */
155 }
156}
157
169static uint8_t a_stcc4_iic_write(stcc4_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
170{
171 uint8_t buf[16];
172 uint16_t i;
173
174 if ((len + 2) > 16) /* check length */
175 {
176 return 1; /* return error */
177 }
178 memset(buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
179 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set MSB of reg */
180 buf[1] = (uint8_t)(reg & 0xFF); /* set LSB of reg */
181 for (i = 0; i < len; i++)
182 {
183 buf[2 + i] = data[i]; /* copy write data */
184 }
185
186 if (handle->iic_write_cmd(handle->iic_addr, (uint8_t *)buf, len + 2) != 0) /* write iic command */
187 {
188 return 1; /* write command */
189 }
190 else
191 {
192 return 0; /* success return 0 */
193 }
194}
195
203static uint8_t a_stcc4_generate_crc(uint8_t* data, uint8_t count)
204{
205 uint8_t current_byte;
206 uint8_t crc = STCC4_CRC8_INIT;
207 uint8_t crc_bit;
208
209 for (current_byte = 0; current_byte < count; ++current_byte) /* calculate crc */
210 {
211 crc ^= (data[current_byte]); /* xor data */
212 for (crc_bit = 8; crc_bit > 0; --crc_bit) /* 8 bit */
213 {
214 if ((crc & 0x80) != 0) /* if 7th bit is 1 */
215 {
216 crc = (crc << 1) ^ STCC4_CRC8_POLYNOMIAL; /* xor */
217 }
218 else
219 {
220 crc = crc << 1; /* left shift 1 */
221 }
222 }
223 }
224
225 return crc; /* return crc */
226}
227
238{
239 if (handle == NULL) /* check handle */
240 {
241 return 2; /* return error */
242 }
243
244 handle->iic_addr = (uint8_t)address; /* set address */
245
246 return 0; /* success return 0 */
247}
248
259{
260 if (handle == NULL) /* check handle */
261 {
262 return 2; /* return error */
263 }
264
265 *address = (stcc4_address_t)(handle->iic_addr); /* get address */
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_stcc4_iic_write(handle, STCC4_COMMAND_START_CONTINUOUS_MEASUREMENT, NULL, 0); /* write config */
294 if (res != 0) /* check result */
295 {
296 handle->debug_print("stcc4: start continuous measurement failed.\n"); /* start continuous measurement failed */
297
298 return 1; /* return error */
299 }
300 handle->delay_ms(1000); /* wait 1000ms */
301
302 return 0; /* success return 0 */
303}
304
316{
317 uint8_t res;
318
319 if (handle == NULL) /* check handle */
320 {
321 return 2; /* return error */
322 }
323 if (handle->inited != 1) /* check handle initialization */
324 {
325 return 3; /* return error */
326 }
327
328 res = a_stcc4_iic_write(handle, STCC4_COMMAND_STOP_CONTINUOUS_MEASUREMENT, NULL, 0); /* write config */
329 if (res != 0) /* check result */
330 {
331 handle->debug_print("stcc4: stop continuous measurement failed.\n"); /* stop continuous measurement failed */
332
333 return 1; /* return error */
334 }
335 handle->delay_ms(1200); /* wait 1200ms */
336
337 return 0; /* success return 0 */
338}
339
352uint8_t stcc4_set_rht_compensation(stcc4_handle_t *handle, uint16_t temperature_raw, uint16_t humidity_raw)
353{
354 uint8_t res;
355 uint8_t buf[6];
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 buf[0] = (temperature_raw >> 8) & 0xFF; /* set temperature msb */
367 buf[1] = (temperature_raw >> 0) & 0xFF; /* set temperature lsb */
368 buf[2] = a_stcc4_generate_crc(buf + 0, 2); /* set temperature crc */
369 buf[3] = (humidity_raw >> 8) & 0xFF; /* set humidity msb */
370 buf[4] = (humidity_raw >> 0) & 0xFF; /* set humidity lsb */
371 buf[5] = a_stcc4_generate_crc(buf + 3, 2); /* set humidity crc */
372 res = a_stcc4_iic_write(handle, STCC4_COMMAND_SET_RHT_COMPENSATION, buf, 6); /* write config */
373 if (res != 0) /* check result */
374 {
375 handle->debug_print("stcc4: set rht compensation failed.\n"); /* set rht compensation failed */
376
377 return 1; /* return error */
378 }
379 handle->delay_ms(1); /* wait 1ms */
380
381 return 0; /* success return 0 */
382}
383
395uint8_t stcc4_set_pressure_compensation(stcc4_handle_t *handle, uint16_t pressure_raw)
396{
397 uint8_t res;
398 uint8_t buf[3];
399
400 if (handle == NULL) /* check handle */
401 {
402 return 2; /* return error */
403 }
404 if (handle->inited != 1) /* check handle initialization */
405 {
406 return 3; /* return error */
407 }
408
409 buf[0] = (pressure_raw >> 8) & 0xFF; /* set pressure msb */
410 buf[1] = (pressure_raw >> 0) & 0xFF; /* set pressure lsb */
411 buf[2] = a_stcc4_generate_crc(buf + 0, 2); /* set pressure crc */
412 res = a_stcc4_iic_write(handle, STCC4_COMMAND_SET_PRESSURE_COMPENSATION, buf, 3); /* write config */
413 if (res != 0) /* check result */
414 {
415 handle->debug_print("stcc4: set pressure compensation failed.\n"); /* set pressure compensation failed */
416
417 return 1; /* return error */
418 }
419 handle->delay_ms(1); /* wait 1ms */
420
421 return 0; /* success return 0 */
422}
423
435{
436 uint8_t res;
437
438 if (handle == NULL) /* check handle */
439 {
440 return 2; /* return error */
441 }
442 if (handle->inited != 1) /* check handle initialization */
443 {
444 return 3; /* return error */
445 }
446
447 res = a_stcc4_iic_write(handle, STCC4_COMMAND_MEASURE_SINGLE_SHOT, NULL, 0); /* write config */
448 if (res != 0) /* check result */
449 {
450 handle->debug_print("stcc4: measure single shot failed.\n"); /* measure single shot failed */
451
452 return 1; /* return error */
453 }
454 handle->delay_ms(500); /* wait 500ms */
455
456 return 0; /* success return 0 */
457}
458
470{
471 uint8_t res;
472
473 if (handle == NULL) /* check handle */
474 {
475 return 2; /* return error */
476 }
477 if (handle->inited != 1) /* check handle initialization */
478 {
479 return 3; /* return error */
480 }
481
482 res = a_stcc4_iic_write(handle, STCC4_COMMAND_ENTER_SLEEP_MODE, NULL, 0); /* write config */
483 if (res != 0) /* check result */
484 {
485 handle->debug_print("stcc4: enter sleep mode failed.\n"); /* enter sleep mode failed */
486
487 return 1; /* return error */
488 }
489 handle->delay_ms(1); /* wait 1ms */
490
491 return 0; /* success return 0 */
492}
493
504{
505 uint8_t reg;
506
507 if (handle == NULL) /* check handle */
508 {
509 return 2; /* return error */
510 }
511 if (handle->inited != 1) /* check handle initialization */
512 {
513 return 3; /* return error */
514 }
515
516 reg = STCC4_COMMAND_EXIT_SLEEP_MODE; /* set exit sleep command */
517 (void)handle->iic_write_cmd(handle->iic_addr, &reg, 1); /* exit sleep mode */
518 handle->delay_ms(5); /* wait 5ms */
519
520 return 0; /* success return 0 */
521}
522
534{
535 uint8_t res;
536
537 if (handle == NULL) /* check handle */
538 {
539 return 2; /* return error */
540 }
541 if (handle->inited != 1) /* check handle initialization */
542 {
543 return 3; /* return error */
544 }
545
546 res = a_stcc4_iic_write(handle, STCC4_COMMAND_PERFORM_CONDITIONING, NULL, 0); /* write config */
547 if (res != 0) /* check result */
548 {
549 handle->debug_print("stcc4: perform conditioning failed.\n"); /* perform conditioning failed */
550
551 return 1; /* return error */
552 }
553 handle->delay_ms(22000); /* wait 22000ms */
554
555 return 0; /* success return 0 */
556}
557
568{
569 uint8_t reg;
570
571 if (handle == NULL) /* check handle */
572 {
573 return 2; /* return error */
574 }
575 if (handle->inited != 1) /* check handle initialization */
576 {
577 return 3; /* return error */
578 }
579
580 reg = STCC4_COMMAND_PERFORM_SOFT_RESET; /* perform soft reset command */
581 (void)handle->iic_write_cmd(0x00, &reg, 1); /* perform soft reset */
582 handle->delay_ms(10); /* wait 10ms */
583
584 return 0; /* success return 0 */
585}
586
599{
600 uint8_t res;
601 uint8_t buf[2];
602 uint16_t result;
603
604 if (handle == NULL) /* check handle */
605 {
606 return 2; /* return error */
607 }
608 if (handle->inited != 1) /* check handle initialization */
609 {
610 return 3; /* return error */
611 }
612
613 res = a_stcc4_iic_read(handle, STCC4_COMMAND_PERFORM_FACTORY_RESET, buf, 2, 90); /* write config */
614 if (res != 0) /* check result */
615 {
616 handle->debug_print("stcc4: perform factory reset failed.\n"); /* perform factory reset failed */
617
618 return 1; /* return error */
619 }
620 result = (uint16_t)((uint16_t)buf[0] << 8) | buf[1]; /* set the result */
621 if (result != 0) /* check the result */
622 {
623 handle->debug_print("stcc4: not passed.\n"); /* not passed */
624
625 return 4; /* return error */
626 }
627
628 return 0; /* success return 0 */
629}
630
643uint8_t stcc4_perform_self_test(stcc4_handle_t *handle, uint16_t *result)
644{
645 uint8_t res;
646 uint8_t buf[3];
647
648 if (handle == NULL) /* check handle */
649 {
650 return 2; /* return error */
651 }
652 if (handle->inited != 1) /* check handle initialization */
653 {
654 return 3; /* return error */
655 }
656
657 res = a_stcc4_iic_read(handle, STCC4_COMMAND_PERFORM_SELF_TEST, buf, 3, 360); /* write config */
658 if (res != 0) /* check result */
659 {
660 handle->debug_print("stcc4: perform self test failed.\n"); /* perform self test failed */
661
662 return 1; /* return error */
663 }
664 if (a_stcc4_generate_crc(buf, 2) != buf[2]) /* check crc */
665 {
666 handle->debug_print("stcc4: crc check failed.\n"); /* crc check failed */
667
668 return 4; /* return error */
669 }
670 *result = (uint16_t)((uint16_t)buf[0] << 8) | buf[1]; /* set the result */
671
672 return 0; /* success return 0 */
673}
674
686{
687 uint8_t res;
688
689 if (handle == NULL) /* check handle */
690 {
691 return 2; /* return error */
692 }
693 if (handle->inited != 1) /* check handle initialization */
694 {
695 return 3; /* return error */
696 }
697
698 res = a_stcc4_iic_write(handle, STCC4_COMMAND_ENABLE_TESTING_MODE, NULL, 0); /* write config */
699 if (res != 0) /* check result */
700 {
701 handle->debug_print("stcc4: enable testing mode failed.\n"); /* enable testing mode failed */
702
703 return 1; /* return error */
704 }
705
706 return 0; /* success return 0 */
707}
708
720{
721 uint8_t res;
722
723 if (handle == NULL) /* check handle */
724 {
725 return 2; /* return error */
726 }
727 if (handle->inited != 1) /* check handle initialization */
728 {
729 return 3; /* return error */
730 }
731
732 res = a_stcc4_iic_write(handle, STCC4_COMMAND_DISABLE_TESTING_MODE, NULL, 0); /* write config */
733 if (res != 0) /* check result */
734 {
735 handle->debug_print("stcc4: disable testing mode failed.\n"); /* disable testing mode failed */
736
737 return 1; /* return error */
738 }
739
740 return 0; /* success return 0 */
741}
742
756uint8_t stcc4_perform_forced_recalibration(stcc4_handle_t *handle, uint16_t target_co2, uint16_t *correct_co2)
757{
758 uint8_t res;
759 uint8_t buf[3];
760 uint8_t output[3];
761
762 if (handle == NULL) /* check handle */
763 {
764 return 2; /* return error */
765 }
766 if (handle->inited != 1) /* check handle initialization */
767 {
768 return 3; /* return error */
769 }
770
771 buf[0] = (target_co2 >> 8) & 0xFF; /* set target co2 msb */
772 buf[1] = (target_co2 >> 0) & 0xFF; /* set target co2 lsb */
773 buf[2] = a_stcc4_generate_crc(buf, 2); /* set target co2 crc */
774 res = a_stcc4_iic_read_with_param(handle, STCC4_COMMAND_PERFORM_FORCED_RECALIBRATION,
775 buf, 3, 90, output, 3); /* write config */
776 if (res != 0) /* check result */
777 {
778 handle->debug_print("stcc4: perform forced recalibration failed.\n"); /* perform forced recalibration failed */
779
780 return 1; /* return error */
781 }
782 if (a_stcc4_generate_crc(output, 2) != output[2]) /* check crc */
783 {
784 handle->debug_print("stcc4: crc check failed.\n"); /* crc check failed */
785
786 return 4; /* return error */
787 }
788 *correct_co2 = (uint16_t)((uint16_t)output[0] << 8) | output[1]; /* set the correct co2 */
789
790 return 0; /* success return 0 */
791}
792
806uint8_t stcc4_get_product_id(stcc4_handle_t *handle, uint32_t *product_id, uint8_t unique_serial_number[8])
807{
808 uint8_t res;
809 uint8_t i;
810 uint8_t buf[18];
811
812 if (handle == NULL) /* check handle */
813 {
814 return 2; /* return error */
815 }
816 if (handle->inited != 1) /* check handle initialization */
817 {
818 return 3; /* return error */
819 }
820
821 res = a_stcc4_iic_read(handle, STCC4_COMMAND_GET_PRODUCT_ID, buf, 18, 1); /* write config */
822 if (res != 0) /* check result */
823 {
824 handle->debug_print("stcc4: get product id failed.\n"); /* get product id failed */
825
826 return 1; /* return error */
827 }
828 for (i = 0; i < 18; i += 3) /* check all */
829 {
830 if (a_stcc4_generate_crc(buf + i, 2) != buf[i + 2]) /* check crc */
831 {
832 handle->debug_print("stcc4: crc check failed.\n"); /* crc check failed */
833
834 return 4; /* return error */
835 }
836 }
837 *product_id = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
838 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* set product id */
839 unique_serial_number[0] = buf[6]; /* set unique serial number index 0 */
840 unique_serial_number[1] = buf[7]; /* set unique serial number index 1 */
841 unique_serial_number[2] = buf[9]; /* set unique serial number index 2 */
842 unique_serial_number[3] = buf[10]; /* set unique serial number index 3 */
843 unique_serial_number[4] = buf[12]; /* set unique serial number index 4 */
844 unique_serial_number[5] = buf[13]; /* set unique serial number index 5 */
845 unique_serial_number[6] = buf[15]; /* set unique serial number index 6 */
846 unique_serial_number[7] = buf[16]; /* set unique serial number index 7 */
847
848 return 0; /* success return 0 */
849}
850
869uint8_t stcc4_read(stcc4_handle_t *handle, int16_t *co2_raw, int16_t *co2_ppm,
870 uint16_t *temperature_raw, float *temperature_s,
871 uint16_t *humidity_raw, float *humidity_s, uint16_t *sensor_status)
872{
873 uint8_t res;
874 uint8_t buf[12];
875
876 if (handle == NULL) /* check handle */
877 {
878 return 2; /* return error */
879 }
880 if (handle->inited != 1) /* check handle initialization */
881 {
882 return 3; /* return error */
883 }
884
885 res = a_stcc4_iic_read(handle, STCC4_COMMAND_READ_MEASUREMENT, buf, 12, 1); /* read data */
886 if (res != 0) /* check result */
887 {
888 handle->debug_print("stcc4: read measurement failed.\n"); /* read measurement failed */
889
890 return 1; /* return error */
891 }
892
893 if (buf[2] != a_stcc4_generate_crc(&buf[0], 2)) /* check crc */
894 {
895 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
896
897 return 4; /* return error */
898 }
899 if (buf[5] != a_stcc4_generate_crc(&buf[3], 2)) /* check crc */
900 {
901 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
902
903 return 4; /* return error */
904 }
905 if (buf[8] != a_stcc4_generate_crc(&buf[6], 2)) /* check crc */
906 {
907 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
908
909 return 4; /* return error */
910 }
911 if (buf[11] != a_stcc4_generate_crc(&buf[9], 2)) /* check crc */
912 {
913 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
914
915 return 4; /* return error */
916 }
917
918 *co2_raw = (int16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set co2 raw */
919 *temperature_raw = (uint16_t)(((uint16_t)buf[3]) << 8) | buf[4]; /* set temperature raw */
920 *humidity_raw = (uint16_t)(((uint16_t)buf[6]) << 8) | buf[7]; /* set humidity raw */
921 *sensor_status = (uint16_t)(((uint16_t)buf[9]) << 8) | buf[10]; /* set sensor status */
922 *co2_ppm = *co2_raw; /* set co2 ppm */
923 *temperature_s = -45.0f + 175.0f * (float)(*temperature_raw) / 65535.0f; /* set temperature */
924 *humidity_s = 125.0f * (float)(*humidity_raw) / 65535.0f - 6.0f; /* set humidity */
925
926 return 0; /* success return 0 */
927}
928
941{
942 uint8_t res;
943 uint8_t reg;
944 uint8_t i;
945 uint32_t product_id;
946 uint8_t buf[18];
947
948 if (handle == NULL) /* check handle */
949 {
950 return 2; /* return error */
951 }
952 if (handle->debug_print == NULL) /* check debug_print */
953 {
954 return 3; /* return error */
955 }
956 if (handle->iic_init == NULL) /* check iic_init */
957 {
958 handle->debug_print("stcc4: iic_init is null.\n"); /* iic_init is null */
959
960 return 3; /* return error */
961 }
962 if (handle->iic_deinit == NULL) /* check iic_deinit */
963 {
964 handle->debug_print("stcc4: iic_deinit is null.\n"); /* iic_deinit is null */
965
966 return 3; /* return error */
967 }
968 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
969 {
970 handle->debug_print("stcc4: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
971
972 return 3; /* return error */
973 }
974 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
975 {
976 handle->debug_print("stcc4: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
977
978 return 3; /* return error */
979 }
980 if (handle->delay_ms == NULL) /* check delay_ms */
981 {
982 handle->debug_print("stcc4: delay_ms is null.\n"); /* delay_ms is null */
983
984 return 3; /* return error */
985 }
986
987 if (handle->iic_init() != 0) /* iic init */
988 {
989 handle->debug_print("stcc4: iic init failed.\n"); /* iic init failed */
990
991 return 1; /* return error */
992 }
993
994 reg = STCC4_COMMAND_PERFORM_SOFT_RESET; /* perform soft reset command */
995 (void)handle->iic_write_cmd(0x00, &reg, 1); /* perform soft reset */
996 handle->delay_ms(10); /* wait 10ms */
997
998 res = a_stcc4_iic_read(handle, STCC4_COMMAND_GET_PRODUCT_ID, buf, 18, 1); /* write config */
999 if (res != 0) /* check result */
1000 {
1001 handle->debug_print("stcc4: get product id failed.\n"); /* get product id failed */
1002 (void)handle->iic_deinit(); /* iic deinit */
1003
1004 return 4; /* return error */
1005 }
1006 for (i = 0; i < 18; i += 3) /* check all */
1007 {
1008 if (a_stcc4_generate_crc(buf + i, 2) != buf[i + 2]) /* check crc */
1009 {
1010 handle->debug_print("stcc4: crc check failed.\n"); /* crc check failed */
1011 (void)handle->iic_deinit(); /* iic deinit */
1012
1013 return 4; /* return error */
1014 }
1015 }
1016 product_id = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1017 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* set product id */
1018 if (product_id != 0x0901018AU) /* check product id */
1019 {
1020 handle->debug_print("stcc4: product id is invalid.\n"); /* id is invalid */
1021 (void)handle->iic_deinit(); /* iic deinit */
1022
1023 return 4; /* return error */
1024 }
1025
1026 handle->inited = 1; /* flag finish initialization */
1027
1028 return 0; /* success return 0 */
1029}
1030
1043{
1044 uint8_t res;
1045
1046 if (handle == NULL) /* check handle */
1047 {
1048 return 2; /* return error */
1049 }
1050 if (handle->inited != 1) /* check handle initialization */
1051 {
1052 return 3; /* return error */
1053 }
1054
1055 res = a_stcc4_iic_write(handle, STCC4_COMMAND_STOP_CONTINUOUS_MEASUREMENT, NULL, 0); /* write config */
1056 if (res != 0) /* check result */
1057 {
1058 handle->debug_print("stcc4: stop continuous measurement failed.\n"); /* stop continuous measurement failed */
1059
1060 return 4; /* return error */
1061 }
1062 if (handle->iic_deinit() != 0) /* iic deinit */
1063 {
1064 handle->debug_print("stcc4: iic close failed.\n"); /* iic close failed */
1065
1066 return 3; /* return error */
1067 }
1068 handle->inited = 0; /* flag close initialization */
1069
1070 return 0; /* success return 0 */
1071}
1072
1084uint8_t stcc4_frc_co2_convert_to_register(stcc4_handle_t *handle, float ppm, uint16_t *reg)
1085{
1086 if (handle == NULL) /* check handle */
1087 {
1088 return 2; /* return error */
1089 }
1090 if (handle->inited != 1) /* check handle initialization */
1091 {
1092 return 3; /* return error */
1093 }
1094
1095 *reg = (uint16_t)(ppm); /* convert real data to register data */
1096
1097 return 0; /* success return 0 */
1098}
1099
1111uint8_t stcc4_frc_co2_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *ppm)
1112{
1113 if (handle == NULL) /* check handle */
1114 {
1115 return 2; /* return error */
1116 }
1117 if (handle->inited != 1) /* check handle initialization */
1118 {
1119 return 3; /* return error */
1120 }
1121
1122 *ppm = (float)(reg) - 32768.0f; /* convert raw data to real data */
1123
1124 return 0; /* success return 0 */
1125}
1126
1138uint8_t stcc4_humidity_convert_to_register(stcc4_handle_t *handle, float percentage, uint16_t *reg)
1139{
1140 if (handle == NULL) /* check handle */
1141 {
1142 return 2; /* return error */
1143 }
1144 if (handle->inited != 1) /* check handle initialization */
1145 {
1146 return 3; /* return error */
1147 }
1148
1149 *reg = (uint16_t)((percentage + 6.0f) * 65535.0f / 125.0f); /* convert real data to register data */
1150
1151 return 0; /* success return 0 */
1152}
1153
1165uint8_t stcc4_humidity_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *percentage)
1166{
1167 if (handle == NULL) /* check handle */
1168 {
1169 return 2; /* return error */
1170 }
1171 if (handle->inited != 1) /* check handle initialization */
1172 {
1173 return 3; /* return error */
1174 }
1175
1176 *percentage = (float)(reg) / 65535.0f * 125.0f - 6.0f; /* convert raw data to real data */
1177
1178 return 0; /* success return 0 */
1179}
1180
1192uint8_t stcc4_temperature_convert_to_register(stcc4_handle_t *handle, float deg, uint16_t *reg)
1193{
1194 if (handle == NULL) /* check handle */
1195 {
1196 return 2; /* return error */
1197 }
1198 if (handle->inited != 1) /* check handle initialization */
1199 {
1200 return 3; /* return error */
1201 }
1202
1203 *reg = (uint16_t)((deg + 45.0f) * 65535.0f / 175.0f); /* convert real data to register data */
1204
1205 return 0; /* success return 0 */
1206}
1207
1219uint8_t stcc4_temperature_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *deg)
1220{
1221 if (handle == NULL) /* check handle */
1222 {
1223 return 2; /* return error */
1224 }
1225 if (handle->inited != 1) /* check handle initialization */
1226 {
1227 return 3; /* return error */
1228 }
1229
1230 *deg = (float)(reg) / 65535.0f * 175.0f - 45.0f; /* convert raw data to real data */
1231
1232 return 0; /* success return 0 */
1233}
1234
1246uint8_t stcc4_pressure_convert_to_register(stcc4_handle_t *handle, float pa, uint16_t *reg)
1247{
1248 if (handle == NULL) /* check handle */
1249 {
1250 return 2; /* return error */
1251 }
1252 if (handle->inited != 1) /* check handle initialization */
1253 {
1254 return 3; /* return error */
1255 }
1256
1257 *reg = (uint16_t)(pa / 2.0f); /* convert real data to register data */
1258
1259 return 0; /* success return 0 */
1260}
1261
1273uint8_t stcc4_pressure_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *pa)
1274{
1275 if (handle == NULL) /* check handle */
1276 {
1277 return 2; /* return error */
1278 }
1279 if (handle->inited != 1) /* check handle initialization */
1280 {
1281 return 3; /* return error */
1282 }
1283
1284 *pa = (float)(reg) * 2; /* convert raw data to real data */
1285
1286 return 0; /* success return 0 */
1287}
1288
1302uint8_t stcc4_set_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
1303{
1304 if (handle == NULL) /* check handle */
1305 {
1306 return 2; /* return error */
1307 }
1308 if (handle->inited != 1) /* check handle initialization */
1309 {
1310 return 3; /* return error */
1311 }
1312
1313 return a_stcc4_iic_write(handle, reg, buf, len); /* write data */
1314}
1315
1330uint8_t stcc4_get_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len, uint16_t delay_ms)
1331{
1332 if (handle == NULL) /* check handle */
1333 {
1334 return 2; /* return error */
1335 }
1336 if (handle->inited != 1) /* check handle initialization */
1337 {
1338 return 3; /* return error */
1339 }
1340
1341 return a_stcc4_iic_read(handle, reg, buf, len, delay_ms); /* read data */
1342}
1343
1353{
1354 if (info == NULL) /* check handle */
1355 {
1356 return 2; /* return error */
1357 }
1358
1359 memset(info, 0, sizeof(stcc4_info_t)); /* initialize stcc4 info structure */
1360 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
1361 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
1362 strncpy(info->interface, "IIC", 8); /* copy interface name */
1363 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
1364 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
1365 info->max_current_ma = MAX_CURRENT; /* set maximum current */
1366 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
1367 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
1368 info->driver_version = DRIVER_VERSION; /* set driver version */
1369
1370 return 0; /* success return 0 */
1371}
#define STCC4_COMMAND_PERFORM_CONDITIONING
#define MAX_CURRENT
#define STCC4_COMMAND_START_CONTINUOUS_MEASUREMENT
chip command definition
#define STCC4_COMMAND_EXIT_SLEEP_MODE
#define STCC4_COMMAND_PERFORM_FORCED_RECALIBRATION
#define SUPPLY_VOLTAGE_MAX
#define STCC4_COMMAND_PERFORM_SOFT_RESET
#define STCC4_COMMAND_GET_PRODUCT_ID
#define STCC4_CRC8_INIT
#define STCC4_COMMAND_SET_PRESSURE_COMPENSATION
#define STCC4_COMMAND_ENABLE_TESTING_MODE
#define TEMPERATURE_MAX
#define STCC4_COMMAND_ENTER_SLEEP_MODE
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define STCC4_COMMAND_SET_RHT_COMPENSATION
#define SUPPLY_VOLTAGE_MIN
#define STCC4_COMMAND_PERFORM_FACTORY_RESET
#define STCC4_COMMAND_READ_MEASUREMENT
#define STCC4_CRC8_POLYNOMIAL
crc8 definition
#define CHIP_NAME
chip information definition
#define STCC4_COMMAND_MEASURE_SINGLE_SHOT
#define STCC4_COMMAND_STOP_CONTINUOUS_MEASUREMENT
#define DRIVER_VERSION
#define STCC4_COMMAND_PERFORM_SELF_TEST
#define STCC4_COMMAND_DISABLE_TESTING_MODE
driver stcc4 header file
uint8_t stcc4_humidity_convert_to_register(stcc4_handle_t *handle, float percentage, uint16_t *reg)
convert the humidity to the register raw data
uint8_t stcc4_perform_self_test(stcc4_handle_t *handle, uint16_t *result)
perform self test
uint8_t stcc4_frc_co2_convert_to_register(stcc4_handle_t *handle, float ppm, uint16_t *reg)
convert the frc co2 to the register raw data
uint8_t stcc4_stop_continuous_measurement(stcc4_handle_t *handle)
stop continuous measurement
uint8_t stcc4_pressure_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *pa)
convert the register raw data to pressure
uint8_t stcc4_set_rht_compensation(stcc4_handle_t *handle, uint16_t temperature_raw, uint16_t humidity_raw)
set rht compensation
uint8_t stcc4_exit_sleep_mode(stcc4_handle_t *handle)
exit sleep mode
uint8_t stcc4_deinit(stcc4_handle_t *handle)
close the chip
uint8_t stcc4_temperature_convert_to_register(stcc4_handle_t *handle, float deg, uint16_t *reg)
convert the temperature to the register raw data
uint8_t stcc4_perform_conditioning(stcc4_handle_t *handle)
perform conditioning
uint8_t stcc4_pressure_convert_to_register(stcc4_handle_t *handle, float pa, uint16_t *reg)
convert the pressure to the register raw data
uint8_t stcc4_frc_co2_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *ppm)
convert the register raw data to frc co2 ppm
uint8_t stcc4_set_pressure_compensation(stcc4_handle_t *handle, uint16_t pressure_raw)
set pressure compensation
uint8_t stcc4_enable_testing_mode(stcc4_handle_t *handle)
enable testing mode
uint8_t stcc4_info(stcc4_info_t *info)
get chip information
uint8_t stcc4_perform_factory_reset(stcc4_handle_t *handle)
perform factory reset
struct stcc4_handle_s stcc4_handle_t
stcc4 handle structure definition
stcc4_address_t
stcc4 address enumeration definition
uint8_t stcc4_enter_sleep_mode(stcc4_handle_t *handle)
enter sleep mode
uint8_t stcc4_measure_single_shot(stcc4_handle_t *handle)
measure single shot
uint8_t stcc4_perform_soft_reset(stcc4_handle_t *handle)
perform soft reset
uint8_t stcc4_init(stcc4_handle_t *handle)
initialize the chip
uint8_t stcc4_temperature_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *deg)
convert the register raw data to temperature
uint8_t stcc4_get_address_pin(stcc4_handle_t *handle, stcc4_address_t *address)
get address pin
uint8_t stcc4_set_address_pin(stcc4_handle_t *handle, stcc4_address_t address)
set address pin
uint8_t stcc4_humidity_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *percentage)
convert the register raw data to humidity
uint8_t stcc4_read(stcc4_handle_t *handle, int16_t *co2_raw, int16_t *co2_ppm, uint16_t *temperature_raw, float *temperature_s, uint16_t *humidity_raw, float *humidity_s, uint16_t *sensor_status)
read data
uint8_t stcc4_get_product_id(stcc4_handle_t *handle, uint32_t *product_id, uint8_t unique_serial_number[8])
get product id
uint8_t stcc4_disable_testing_mode(stcc4_handle_t *handle)
disable testing mode
uint8_t stcc4_start_continuous_measurement(stcc4_handle_t *handle)
start continuous measurement
uint8_t stcc4_perform_forced_recalibration(stcc4_handle_t *handle, uint16_t target_co2, uint16_t *correct_co2)
perform forced recalibration
struct stcc4_info_s stcc4_info_t
stcc4 information structure definition
uint8_t stcc4_get_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len, uint16_t delay_ms)
get the chip register
uint8_t stcc4_set_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set 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]