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_PRESSURER_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_PRESSURER_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
870uint8_t stcc4_read(stcc4_handle_t *handle, int16_t *co2_raw, int16_t *co2_ppm,
871 uint16_t *temperature_raw, float *temperature_s,
872 uint16_t *humidity_raw, float *humidity_s, uint16_t *sensor_status)
873{
874 uint8_t res;
875 uint8_t buf[12];
876
877 if (handle == NULL) /* check handle */
878 {
879 return 2; /* return error */
880 }
881 if (handle->inited != 1) /* check handle initialization */
882 {
883 return 3; /* return error */
884 }
885
886 res = a_stcc4_iic_read(handle, STCC4_COMMAND_READ_MEASUREMENT, buf, 12, 1); /* read data */
887 if (res != 0) /* check result */
888 {
889 handle->debug_print("stcc4: read measurement failed.\n"); /* read measurement failed */
890
891 return 1; /* return error */
892 }
893
894 if (buf[2] != a_stcc4_generate_crc(&buf[0], 2)) /* check crc */
895 {
896 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
897
898 return 4; /* return error */
899 }
900 if (buf[5] != a_stcc4_generate_crc(&buf[3], 2)) /* check crc */
901 {
902 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
903
904 return 4; /* return error */
905 }
906 if (buf[8] != a_stcc4_generate_crc(&buf[6], 2)) /* check crc */
907 {
908 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
909
910 return 4; /* return error */
911 }
912 if (buf[11] != a_stcc4_generate_crc(&buf[9], 2)) /* check crc */
913 {
914 handle->debug_print("stcc4: crc is error.\n"); /* crc is error */
915
916 return 4; /* return error */
917 }
918
919 *co2_raw = (int16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set co2 raw */
920 *temperature_raw = (uint16_t)(((uint16_t)buf[3]) << 8) | buf[4]; /* set temperature raw */
921 *humidity_raw = (uint16_t)(((uint16_t)buf[6]) << 8) | buf[7]; /* set humidity raw */
922 *sensor_status = (uint16_t)(((uint16_t)buf[9]) << 8) | buf[10]; /* set sensor status */
923 *co2_ppm = *co2_raw; /* set co2 ppm */
924 *temperature_s = -45.0f + 175.0f * (float)(*temperature_raw) / 65535.0f; /* set temperature */
925 *humidity_s = 125.0f * (float)(*humidity_raw) / 65535.0f - 6.0f; /* set humidity */
926 if ((*sensor_status) != 0) /* check sensor status */
927 {
928 handle->debug_print("stcc4: sensor status is invalid.\n"); /* sensor status is invalid */
929
930 return 5; /* return error */
931 }
932
933 return 0; /* success return 0 */
934}
935
948{
949 uint8_t res;
950 uint8_t reg;
951 uint8_t i;
952 uint32_t product_id;
953 uint8_t buf[18];
954
955 if (handle == NULL) /* check handle */
956 {
957 return 2; /* return error */
958 }
959 if (handle->debug_print == NULL) /* check debug_print */
960 {
961 return 3; /* return error */
962 }
963 if (handle->iic_init == NULL) /* check iic_init */
964 {
965 handle->debug_print("stcc4: iic_init is null.\n"); /* iic_init is null */
966
967 return 3; /* return error */
968 }
969 if (handle->iic_deinit == NULL) /* check iic_deinit */
970 {
971 handle->debug_print("stcc4: iic_deinit is null.\n"); /* iic_deinit is null */
972
973 return 3; /* return error */
974 }
975 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
976 {
977 handle->debug_print("stcc4: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
978
979 return 3; /* return error */
980 }
981 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
982 {
983 handle->debug_print("stcc4: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
984
985 return 3; /* return error */
986 }
987 if (handle->delay_ms == NULL) /* check delay_ms */
988 {
989 handle->debug_print("stcc4: delay_ms is null.\n"); /* delay_ms is null */
990
991 return 3; /* return error */
992 }
993
994 if (handle->iic_init() != 0) /* iic init */
995 {
996 handle->debug_print("stcc4: iic init failed.\n"); /* iic init failed */
997
998 return 1; /* return error */
999 }
1000
1001 reg = STCC4_COMMAND_PERFORM_SOFT_RESET; /* perform soft reset command */
1002 (void)handle->iic_write_cmd(0x00, &reg, 1); /* perform soft reset */
1003 handle->delay_ms(10); /* wait 10ms */
1004
1005 res = a_stcc4_iic_read(handle, STCC4_COMMAND_GET_PRODUCT_ID, buf, 18, 1); /* write config */
1006 if (res != 0) /* check result */
1007 {
1008 handle->debug_print("stcc4: get product id failed.\n"); /* get product id failed */
1009 (void)handle->iic_deinit(); /* iic deinit */
1010
1011 return 4; /* return error */
1012 }
1013 for (i = 0; i < 18; i += 3) /* check all */
1014 {
1015 if (a_stcc4_generate_crc(buf + i, 2) != buf[i + 2]) /* check crc */
1016 {
1017 handle->debug_print("stcc4: crc check failed.\n"); /* crc check failed */
1018 (void)handle->iic_deinit(); /* iic deinit */
1019
1020 return 4; /* return error */
1021 }
1022 }
1023 product_id = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1024 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* set product id */
1025 if (product_id != 0x0901018AU) /* check product id */
1026 {
1027 handle->debug_print("stcc4: product id is invalid.\n"); /* id is invalid */
1028 (void)handle->iic_deinit(); /* iic deinit */
1029
1030 return 4; /* return error */
1031 }
1032
1033 handle->inited = 1; /* flag finish initialization */
1034
1035 return 0; /* success return 0 */
1036}
1037
1050{
1051 uint8_t res;
1052
1053 if (handle == NULL) /* check handle */
1054 {
1055 return 2; /* return error */
1056 }
1057 if (handle->inited != 1) /* check handle initialization */
1058 {
1059 return 3; /* return error */
1060 }
1061
1062 res = a_stcc4_iic_write(handle, STCC4_COMMAND_STOP_CONTINUOUS_MEASUREMENT, NULL, 0); /* write config */
1063 if (res != 0) /* check result */
1064 {
1065 handle->debug_print("stcc4: stop continuous measurement failed.\n"); /* stop continuous measurement failed */
1066
1067 return 4; /* return error */
1068 }
1069 if (handle->iic_deinit() != 0) /* iic deinit */
1070 {
1071 handle->debug_print("stcc4: iic close failed.\n"); /* iic close failed */
1072
1073 return 3; /* return error */
1074 }
1075 handle->inited = 0; /* flag close initialization */
1076
1077 return 0; /* success return 0 */
1078}
1079
1091uint8_t stcc4_frc_co2_convert_to_register(stcc4_handle_t *handle, float ppm, uint16_t *reg)
1092{
1093 if (handle == NULL) /* check handle */
1094 {
1095 return 2; /* return error */
1096 }
1097 if (handle->inited != 1) /* check handle initialization */
1098 {
1099 return 3; /* return error */
1100 }
1101
1102 *reg = (uint16_t)(ppm + 32768.0f); /* convert real data to register data */
1103
1104 return 0; /* success return 0 */
1105}
1106
1118uint8_t stcc4_frc_co2_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *ppm)
1119{
1120 if (handle == NULL) /* check handle */
1121 {
1122 return 2; /* return error */
1123 }
1124 if (handle->inited != 1) /* check handle initialization */
1125 {
1126 return 3; /* return error */
1127 }
1128
1129 *ppm = (float)(reg) - 32768.0f; /* convert raw data to real data */
1130
1131 return 0; /* success return 0 */
1132}
1133
1145uint8_t stcc4_humidity_convert_to_register(stcc4_handle_t *handle, float percentage, uint16_t *reg)
1146{
1147 if (handle == NULL) /* check handle */
1148 {
1149 return 2; /* return error */
1150 }
1151 if (handle->inited != 1) /* check handle initialization */
1152 {
1153 return 3; /* return error */
1154 }
1155
1156 *reg = (uint16_t)((percentage + 6.0f) * 65535.0f / 125.0f); /* convert real data to register data */
1157
1158 return 0; /* success return 0 */
1159}
1160
1172uint8_t stcc4_humidity_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *percentage)
1173{
1174 if (handle == NULL) /* check handle */
1175 {
1176 return 2; /* return error */
1177 }
1178 if (handle->inited != 1) /* check handle initialization */
1179 {
1180 return 3; /* return error */
1181 }
1182
1183 *percentage = (float)(reg) / 65535.0f * 125.0f - 6.0f; /* convert raw data to real data */
1184
1185 return 0; /* success return 0 */
1186}
1187
1199uint8_t stcc4_temperature_convert_to_register(stcc4_handle_t *handle, float deg, uint16_t *reg)
1200{
1201 if (handle == NULL) /* check handle */
1202 {
1203 return 2; /* return error */
1204 }
1205 if (handle->inited != 1) /* check handle initialization */
1206 {
1207 return 3; /* return error */
1208 }
1209
1210 *reg = (uint16_t)((deg + 45.0f) * 65535.0f / 175.0f); /* convert real data to register data */
1211
1212 return 0; /* success return 0 */
1213}
1214
1226uint8_t stcc4_temperature_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *deg)
1227{
1228 if (handle == NULL) /* check handle */
1229 {
1230 return 2; /* return error */
1231 }
1232 if (handle->inited != 1) /* check handle initialization */
1233 {
1234 return 3; /* return error */
1235 }
1236
1237 *deg = (float)(reg) / 65535.0f * 175.0f - 45.0f; /* convert raw data to real data */
1238
1239 return 0; /* success return 0 */
1240}
1241
1253uint8_t stcc4_pressure_convert_to_register(stcc4_handle_t *handle, float pa, uint16_t *reg)
1254{
1255 if (handle == NULL) /* check handle */
1256 {
1257 return 2; /* return error */
1258 }
1259 if (handle->inited != 1) /* check handle initialization */
1260 {
1261 return 3; /* return error */
1262 }
1263
1264 *reg = (uint16_t)(pa / 2.0f); /* convert real data to register data */
1265
1266 return 0; /* success return 0 */
1267}
1268
1280uint8_t stcc4_pressure_convert_to_data(stcc4_handle_t *handle, uint16_t reg, float *pa)
1281{
1282 if (handle == NULL) /* check handle */
1283 {
1284 return 2; /* return error */
1285 }
1286 if (handle->inited != 1) /* check handle initialization */
1287 {
1288 return 3; /* return error */
1289 }
1290
1291 *pa = (float)(reg) * 2; /* convert raw data to real data */
1292
1293 return 0; /* success return 0 */
1294}
1295
1309uint8_t stcc4_set_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
1310{
1311 if (handle == NULL) /* check handle */
1312 {
1313 return 2; /* return error */
1314 }
1315 if (handle->inited != 1) /* check handle initialization */
1316 {
1317 return 3; /* return error */
1318 }
1319
1320 return a_stcc4_iic_write(handle, reg, buf, len); /* write data */
1321}
1322
1337uint8_t stcc4_get_reg(stcc4_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len, uint16_t delay_ms)
1338{
1339 if (handle == NULL) /* check handle */
1340 {
1341 return 2; /* return error */
1342 }
1343 if (handle->inited != 1) /* check handle initialization */
1344 {
1345 return 3; /* return error */
1346 }
1347
1348 return a_stcc4_iic_read(handle, reg, buf, len, delay_ms); /* read data */
1349}
1350
1360{
1361 if (info == NULL) /* check handle */
1362 {
1363 return 2; /* return error */
1364 }
1365
1366 memset(info, 0, sizeof(stcc4_info_t)); /* initialize stcc4 info structure */
1367 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
1368 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
1369 strncpy(info->interface, "IIC", 8); /* copy interface name */
1370 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
1371 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
1372 info->max_current_ma = MAX_CURRENT; /* set maximum current */
1373 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
1374 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
1375 info->driver_version = DRIVER_VERSION; /* set driver version */
1376
1377 return 0; /* success return 0 */
1378}
#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_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
#define STCC4_COMMAND_SET_PRESSURER_COMPENSATION
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]