LibDriver SCD4X
Loading...
Searching...
No Matches
driver_scd4x.c
Go to the documentation of this file.
1
36
37#include "driver_scd4x.h"
38
42#define CHIP_NAME "Sensirion SCD4X"
43#define MANUFACTURER_NAME "Sensirion"
44#define SUPPLY_VOLTAGE_MIN 2.40f
45#define SUPPLY_VOLTAGE_MAX 5.50f
46#define MAX_CURRENT 205.0f
47#define TEMPERATURE_MIN -10.0f
48#define TEMPERATURE_MAX 60.0f
49#define DRIVER_VERSION 1000
50
54#define SCD4X_ADDRESS (0x62 << 1)
55
59#define SCD4X_COMMAND_START_PERIODIC 0x21B1U
60#define SCD4X_COMMAND_READ 0xEC05U
61#define SCD4X_COMMAND_STOP_PERIODIC 0x3F86U
62#define SCD4X_COMMAND_SET_TEMPERATURE_OFFSET 0x241DU
63#define SCD4X_COMMAND_GET_TEMPERATURE_OFFSET 0x2318U
64#define SCD4X_COMMAND_SET_SENSOR_ALTITUDE 0x2427U
65#define SCD4X_COMMAND_GET_SENSOR_ALTITUDE 0x2322U
66#define SCD4X_COMMAND_SET_AMBIENT_PRESSURE 0xE000U
67#define SCD4X_COMMAND_GET_AMBIENT_PRESSURE 0xE000U
68#define SCD4X_COMMAND_PERFORM_FORCED_RECALIBRATION 0x362FU
69#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION 0x2416U
70#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION 0x2313U
71#define SCD4X_COMMAND_START_LOW_POWER_PERIODIC 0x21ACU
72#define SCD4X_COMMAND_GET_DATA_READY_STATUS 0xE4B8U
73#define SCD4X_COMMAND_PERSIST_SETTINGS 0x3615U
74#define SCD4X_COMMAND_GET_SERIAL_NUMBER 0x3682U
75#define SCD4X_COMMAND_PERFORM_SELF_TEST 0x3639U
76#define SCD4X_COMMAND_PERFORM_FACTORY_RESET 0x3632U
77#define SCD4X_COMMAND_REINIT 0x3646U
78#define SCD4X_COMMAND_MEASURE_SINGLE_SHOT 0x219DU
79#define SCD4X_COMMAND_MEASURE_SINGLE_SHOT_RHT_ONLY 0x2196U
80#define SCD4X_COMMAND_POWER_DOWN 0x36E0U
81#define SCD4X_COMMAND_WAKE_UP 0x36F6U
82#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_INIT_PERIOD 0x2445U
83#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_INIT_PERIOD 0x2340U
84#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD 0x244EU
85#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD 0x234BU
86#define SCD4X_COMMAND_SET_AUTOMATIC_SELF_CALIBRATION_TARGET 0x243AU
87#define SCD4X_COMMAND_GET_AUTOMATIC_SELF_CALIBRATION_TARGET 0x233FU
88#define SCD4X_COMMAND_GET_SENSOR_VARIANT 0x202FU
89
93#define SCD4X_CRC8_POLYNOMIAL 0x31
94#define SCD4X_CRC8_INIT 0xFF
95
110static uint8_t a_scd4x_iic_read_with_param(scd4x_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len,
111 uint16_t delay_ms, uint8_t *output, uint16_t output_len)
112{
113 uint8_t buf[16];
114 uint16_t i;
115
116 if ((len + 2) > 16) /* check length */
117 {
118 return 1; /* return error */
119 }
120 memset(buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
121 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set MSB of reg */
122 buf[1] = (uint8_t)(reg & 0xFF); /* set LSB of reg */
123 for (i = 0; i < len; i++)
124 {
125 buf[2 + i] = data[i]; /* copy write data */
126 }
127
128 if (handle->iic_write_cmd(SCD4X_ADDRESS, (uint8_t *)buf, len + 2) != 0) /* write iic command */
129 {
130 return 1; /* write command */
131 }
132 handle->delay_ms(delay_ms); /* delay ms */
133 if (handle->iic_read_cmd(SCD4X_ADDRESS, output, output_len) != 0) /* read data */
134 {
135 return 1; /* write command */
136 }
137 else
138 {
139 return 0; /* success return 0 */
140 }
141}
142
155static uint8_t a_scd4x_iic_read(scd4x_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
156{
157 uint8_t buf[2];
158
159 memset(buf, 0, sizeof(uint8_t) * 2); /* clear the buffer */
160 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set reg MSB */
161 buf[1] = (uint8_t)(reg & 0xFF); /* set reg LSB */
162 if (handle->iic_write_cmd(SCD4X_ADDRESS, (uint8_t *)buf, 2) != 0) /* write command */
163 {
164 return 1; /* return error */
165 }
166 handle->delay_ms(delay_ms); /* delay ms */
167 if (handle->iic_read_cmd(SCD4X_ADDRESS, data, len) != 0) /* read data */
168 {
169 return 1; /* write command */
170 }
171 else
172 {
173 return 0; /* success return 0 */
174 }
175}
176
188static uint8_t a_scd4x_iic_write(scd4x_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
189{
190 uint8_t buf[16];
191 uint16_t i;
192
193 if ((len + 2) > 16) /* check length */
194 {
195 return 1; /* return error */
196 }
197 memset(buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
198 buf[0] = (uint8_t)((reg >> 8) & 0xFF); /* set MSB of reg */
199 buf[1] = (uint8_t)(reg & 0xFF); /* set LSB of reg */
200 for (i = 0; i < len; i++)
201 {
202 buf[2 + i] = data[i]; /* copy write data */
203 }
204
205 if (handle->iic_write_cmd(SCD4X_ADDRESS, (uint8_t *)buf, len + 2) != 0) /* write iic command */
206 {
207 return 1; /* write command */
208 }
209 else
210 {
211 return 0; /* success return 0 */
212 }
213}
214
222static uint8_t a_scd4x_generate_crc(uint8_t* data, uint8_t count)
223{
224 uint8_t current_byte;
225 uint8_t crc = SCD4X_CRC8_INIT;
226 uint8_t crc_bit;
227
228 for (current_byte = 0; current_byte < count; ++current_byte) /* calculate crc */
229 {
230 crc ^= (data[current_byte]); /* xor data */
231 for (crc_bit = 8; crc_bit > 0; --crc_bit) /* 8 bit */
232 {
233 if ((crc & 0x80) != 0) /* if 7th bit is 1 */
234 {
235 crc = (crc << 1) ^ SCD4X_CRC8_POLYNOMIAL; /* xor */
236 }
237 else
238 {
239 crc = crc << 1; /* left shift 1 */
240 }
241 }
242 }
243
244 return crc; /* return crc */
245}
246
257{
258 if (handle == NULL) /* check handle */
259 {
260 return 2; /* return error */
261 }
262
263 handle->type = type; /* set type */
264
265 return 0; /* success return 0 */
266}
267
277uint8_t scd4x_get_type(scd4x_handle_t *handle, scd4x_t *type)
278{
279 if (handle == NULL) /* check handle */
280 {
281 return 2; /* return error */
282 }
283
284 *type = (scd4x_t)(handle->type); /* get type */
285
286 return 0; /* success return 0 */
287}
288
300{
301 uint8_t res;
302
303 if (handle == NULL) /* check handle */
304 {
305 return 2; /* return error */
306 }
307 if (handle->inited != 1) /* check handle initialization */
308 {
309 return 3; /* return error */
310 }
311
312 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_START_PERIODIC, NULL, 0); /* write config */
313 if (res != 0) /* check result */
314 {
315 handle->debug_print("scd4x: start periodic measurement failed.\n"); /* start periodic measurement failed */
316
317 return 1; /* return error */
318 }
319
320 return 0; /* success return 0 */
321}
322
341uint8_t scd4x_read(scd4x_handle_t *handle, uint16_t *co2_raw, uint16_t *co2_ppm,
342 uint16_t *temperature_raw, float *temperature_s,
343 uint16_t *humidity_raw, float *humidity_s)
344{
345 uint8_t res;
346 uint8_t buf[9];
347 uint16_t prev;
348
349 if (handle == NULL) /* check handle */
350 {
351 return 2; /* return error */
352 }
353 if (handle->inited != 1) /* check handle initialization */
354 {
355 return 3; /* return error */
356 }
357
358 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_DATA_READY_STATUS, buf, 3, 1); /* read config */
359 if (res != 0) /* check result */
360 {
361 handle->debug_print("scd4x: get data ready status failed.\n"); /* get data ready status failed */
362
363 return 1; /* return error */
364 }
365 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
366 {
367 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
368
369 return 4; /* return error */
370 }
371 prev = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set prev */
372 if ((prev & 0x07FF) == 0) /* check data */
373 {
374 handle->debug_print("scd4x: data is not ready.\n"); /* data is not ready */
375
376 return 5; /* return error */
377 }
378
379 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_READ, buf, 9, 1); /* read data */
380 if (res != 0) /* check result */
381 {
382 handle->debug_print("scd4x: read failed.\n"); /* read failed */
383
384 return 1; /* return error */
385 }
386
387 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
388 {
389 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
390
391 return 4; /* return error */
392 }
393 if (buf[5] != a_scd4x_generate_crc(&buf[3], 2)) /* check crc */
394 {
395 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
396
397 return 4; /* return error */
398 }
399 if (buf[8] != a_scd4x_generate_crc(&buf[6], 2)) /* check crc */
400 {
401 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
402
403 return 4; /* return error */
404 }
405
406 *co2_raw = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set co2 raw */
407 *temperature_raw = (uint16_t)(((uint16_t)buf[3]) << 8) | buf[4]; /* set temperature raw */
408 *humidity_raw = (uint16_t)(((uint16_t)buf[6]) << 8) | buf[7]; /* set humidity raw */
409 *co2_ppm = *co2_raw; /* set co2 ppm */
410 *temperature_s = -45.0f + 175.0f * (float)(*temperature_raw) / 65535.0f; /* set temperature */
411 *humidity_s = 100.0f * (float)(*humidity_raw) / 65535.0f; /* set humidity */
412
413 return 0; /* success return 0 */
414}
415
427{
428 uint8_t res;
429
430 if (handle == NULL) /* check handle */
431 {
432 return 2; /* return error */
433 }
434 if (handle->inited != 1) /* check handle initialization */
435 {
436 return 3; /* return error */
437 }
438
439 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_STOP_PERIODIC, NULL, 0); /* write config */
440 if (res != 0) /* check result */
441 {
442 handle->debug_print("scd4x: stop periodic measurement failed.\n"); /* stop periodic measurement failed */
443
444 return 1; /* return error */
445 }
446 handle->delay_ms(500); /* delay 500ms */
447
448 return 0; /* success return 0 */
449}
450
462uint8_t scd4x_set_temperature_offset(scd4x_handle_t *handle, uint16_t offset)
463{
464 uint8_t res;
465 uint8_t buf[3];
466
467 if (handle == NULL) /* check handle */
468 {
469 return 2; /* return error */
470 }
471 if (handle->inited != 1) /* check handle initialization */
472 {
473 return 3; /* return error */
474 }
475
476 buf[0] = (offset >> 8) & 0xFF; /* msb */
477 buf[1] = (offset >> 0) & 0xFF; /* lsb */
478 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* set crc */
479 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_TEMPERATURE_OFFSET, buf, 3); /* write config */
480 if (res != 0) /* check result */
481 {
482 handle->debug_print("scd4x: set temperature offset failed.\n"); /* set temperature offset failed */
483
484 return 1; /* return error */
485 }
486 handle->delay_ms(1); /* delay 1ms */
487
488 return 0; /* success return 0 */
489}
490
503uint8_t scd4x_get_temperature_offset(scd4x_handle_t *handle, uint16_t *offset)
504{
505 uint8_t res;
506 uint8_t buf[3];
507
508 if (handle == NULL) /* check handle */
509 {
510 return 2; /* return error */
511 }
512 if (handle->inited != 1) /* check handle initialization */
513 {
514 return 3; /* return error */
515 }
516
517 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_TEMPERATURE_OFFSET, buf, 3, 1); /* read config */
518 if (res != 0) /* check result */
519 {
520 handle->debug_print("scd4x: get temperature offset failed.\n"); /* get temperature offset failed */
521
522 return 1; /* return error */
523 }
524 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
525 {
526 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
527
528 return 4; /* return error */
529 }
530 *offset = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set offset */
531
532 return 0; /* success return 0 */
533}
534
546uint8_t scd4x_temperature_offset_convert_to_register(scd4x_handle_t *handle, float degrees, uint16_t *reg)
547{
548 if (handle == NULL) /* check handle */
549 {
550 return 2; /* return error */
551 }
552 if (handle->inited != 1) /* check handle initialization */
553 {
554 return 3; /* return error */
555 }
556
557 *reg = (uint16_t)(degrees * (65535.0f / 175.0f)); /* convert real data to register data */
558
559 return 0; /* success return 0 */
560}
561
573uint8_t scd4x_temperature_offset_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *degrees)
574{
575 if (handle == NULL) /* check handle */
576 {
577 return 2; /* return error */
578 }
579 if (handle->inited != 1) /* check handle initialization */
580 {
581 return 3; /* return error */
582 }
583
584 *degrees = (float)(reg) * 175.0f / 65535.0f; /* convert raw data to real data */
585
586 return 0; /* success return 0 */
587}
588
600uint8_t scd4x_set_sensor_altitude(scd4x_handle_t *handle, uint16_t altitude)
601{
602 uint8_t res;
603 uint8_t buf[3];
604
605 if (handle == NULL) /* check handle */
606 {
607 return 2; /* return error */
608 }
609 if (handle->inited != 1) /* check handle initialization */
610 {
611 return 3; /* return error */
612 }
613
614 buf[0] = (altitude >> 8) & 0xFF; /* msb */
615 buf[1] = (altitude >> 0) & 0xFF; /* lsb */
616 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* set crc */
617 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_SENSOR_ALTITUDE , buf, 3); /* write config */
618 if (res != 0) /* check result */
619 {
620 handle->debug_print("scd4x: set sensor altitude failed.\n"); /* set sensor altitude failed */
621
622 return 1; /* return error */
623 }
624 handle->delay_ms(1); /* delay 1ms */
625
626 return 0; /* success return 0 */
627}
628
641uint8_t scd4x_get_sensor_altitude(scd4x_handle_t *handle, uint16_t *altitude)
642{
643 uint8_t res;
644 uint8_t buf[3];
645
646 if (handle == NULL) /* check handle */
647 {
648 return 2; /* return error */
649 }
650 if (handle->inited != 1) /* check handle initialization */
651 {
652 return 3; /* return error */
653 }
654
655 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_SENSOR_ALTITUDE, buf, 3, 1); /* read config */
656 if (res != 0) /* check result */
657 {
658 handle->debug_print("scd4x: get sensor altitude failed.\n"); /* get sensor altitude failed */
659
660 return 1; /* return error */
661 }
662 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
663 {
664 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
665
666 return 4; /* return error */
667 }
668 *altitude = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set offset */
669
670 return 0; /* success return 0 */
671}
672
684uint8_t scd4x_sensor_altitude_convert_to_register(scd4x_handle_t *handle, float m, uint16_t *reg)
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 *reg = (uint16_t)(m); /* convert real data to register data */
696
697 return 0; /* success return 0 */
698}
699
711uint8_t scd4x_sensor_altitude_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *m)
712{
713 if (handle == NULL) /* check handle */
714 {
715 return 2; /* return error */
716 }
717 if (handle->inited != 1) /* check handle initialization */
718 {
719 return 3; /* return error */
720 }
721
722 *m = (float)(reg); /* convert raw data to real data */
723
724 return 0; /* success return 0 */
725}
726
738uint8_t scd4x_set_ambient_pressure(scd4x_handle_t *handle, uint16_t pressure)
739{
740 uint8_t res;
741 uint8_t buf[3];
742
743 if (handle == NULL) /* check handle */
744 {
745 return 2; /* return error */
746 }
747 if (handle->inited != 1) /* check handle initialization */
748 {
749 return 3; /* return error */
750 }
751
752 buf[0] = (pressure >> 8) & 0xFF; /* msb */
753 buf[1] = (pressure >> 0) & 0xFF; /* lsb */
754 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* set crc */
755 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_AMBIENT_PRESSURE , buf, 3); /* write config */
756 if (res != 0) /* check result */
757 {
758 handle->debug_print("scd4x: set ambient pressure failed.\n"); /* set ambient pressure failed */
759
760 return 1; /* return error */
761 }
762 handle->delay_ms(1); /* delay 1ms */
763
764 return 0; /* success return 0 */
765}
766
779uint8_t scd4x_get_ambient_pressure(scd4x_handle_t *handle, uint16_t *pressure)
780{
781 uint8_t res;
782 uint8_t buf[3];
783
784 if (handle == NULL) /* check handle */
785 {
786 return 2; /* return error */
787 }
788 if (handle->inited != 1) /* check handle initialization */
789 {
790 return 3; /* return error */
791 }
792
793 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_AMBIENT_PRESSURE, buf, 3, 1); /* read config */
794 if (res != 0) /* check result */
795 {
796 handle->debug_print("scd4x: get ambient pressure failed.\n"); /* get ambient pressure failed */
797
798 return 1; /* return error */
799 }
800 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
801 {
802 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
803
804 return 4; /* return error */
805 }
806 *pressure = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set offset */
807
808 return 0; /* success return 0 */
809}
810
822uint8_t scd4x_ambient_pressure_convert_to_register(scd4x_handle_t *handle, float pa, uint16_t *reg)
823{
824 if (handle == NULL) /* check handle */
825 {
826 return 2; /* return error */
827 }
828 if (handle->inited != 1) /* check handle initialization */
829 {
830 return 3; /* return error */
831 }
832
833 *reg = (uint16_t)(pa / 100.0f); /* convert real data to register data */
834
835 return 0; /* success return 0 */
836}
837
849uint8_t scd4x_ambient_pressure_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *pa)
850{
851 if (handle == NULL) /* check handle */
852 {
853 return 2; /* return error */
854 }
855 if (handle->inited != 1) /* check handle initialization */
856 {
857 return 3; /* return error */
858 }
859
860 *pa = (float)(reg * 100.0f); /* convert raw data to real data */
861
862 return 0; /* success return 0 */
863}
864
878uint8_t scd4x_perform_forced_recalibration(scd4x_handle_t *handle, uint16_t co2_raw, uint16_t *frc)
879{
880 uint8_t res;
881 uint8_t in_buf[3];
882 uint8_t out_buf[3];
883
884 if (handle == NULL) /* check handle */
885 {
886 return 2; /* return error */
887 }
888 if (handle->inited != 1) /* check handle initialization */
889 {
890 return 3; /* return error */
891 }
892
893 in_buf[0] = (co2_raw >> 8) & 0xFF; /* set msb */
894 in_buf[1] = (co2_raw >> 0) & 0xFF; /* set lsb */
895 in_buf[2] = a_scd4x_generate_crc(&in_buf[0], 2); /* set crc */
896 res = a_scd4x_iic_read_with_param(handle, SCD4X_COMMAND_PERFORM_FORCED_RECALIBRATION,
897 in_buf, 3, 400, out_buf, 3); /* read config */
898 if (res != 0) /* check result */
899 {
900 handle->debug_print("scd4x: perform forced recalibration failed.\n"); /* perform forced recalibration failed */
901
902 return 1; /* return error */
903 }
904 if (out_buf[2] != a_scd4x_generate_crc(&out_buf[0], 2)) /* check crc */
905 {
906 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
907
908 return 4; /* return error */
909 }
910 *frc = (uint16_t)(((uint16_t)out_buf[0]) << 8) | out_buf[1]; /* set frc */
911
912 return 0; /* success return 0 */
913}
914
926uint8_t scd4x_co2_convert_to_register(scd4x_handle_t *handle, float ppm, uint16_t *reg)
927{
928 if (handle == NULL) /* check handle */
929 {
930 return 2; /* return error */
931 }
932 if (handle->inited != 1) /* check handle initialization */
933 {
934 return 3; /* return error */
935 }
936
937 *reg = (uint16_t)(ppm); /* convert real data to register data */
938
939 return 0; /* success return 0 */
940}
941
953uint8_t scd4x_co2_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *ppm)
954{
955 if (handle == NULL) /* check handle */
956 {
957 return 2; /* return error */
958 }
959 if (handle->inited != 1) /* check handle initialization */
960 {
961 return 3; /* return error */
962 }
963
964 *ppm = (float)(reg); /* convert raw data to real data */
965
966 return 0; /* success return 0 */
967}
968
981{
982 uint8_t res;
983 uint8_t buf[3];
984 uint16_t prev;
985
986 if (handle == NULL) /* check handle */
987 {
988 return 2; /* return error */
989 }
990 if (handle->inited != 1) /* check handle initialization */
991 {
992 return 3; /* return error */
993 }
994
995 prev = enable; /* set bool */
996 buf[0] = (prev >> 8) & 0xFF; /* msb */
997 buf[1] = (prev >> 0) & 0xFF; /* lsb */
998 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* set crc */
999 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION , buf, 3); /* write config */
1000 if (res != 0) /* check result */
1001 {
1002 handle->debug_print("scd4x: set automatic self calibration failed.\n"); /* set automatic self calibration failed */
1003
1004 return 1; /* return error */
1005 }
1006 handle->delay_ms(1); /* delay 1ms */
1007
1008 return 0; /* success return 0 */
1009}
1010
1024{
1025 uint8_t res;
1026 uint8_t buf[3];
1027 uint16_t prev;
1028
1029 if (handle == NULL) /* check handle */
1030 {
1031 return 2; /* return error */
1032 }
1033 if (handle->inited != 1) /* check handle initialization */
1034 {
1035 return 3; /* return error */
1036 }
1037
1038 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION, buf, 3, 1); /* read config */
1039 if (res != 0) /* check result */
1040 {
1041 handle->debug_print("scd4x: get automatic self calibration failed.\n"); /* get automatic self calibration failed */
1042
1043 return 1; /* return error */
1044 }
1045 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1046 {
1047 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1048
1049 return 4; /* return error */
1050 }
1051 prev = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set prev */
1052 *enable = (scd4x_bool_t)((prev >> 0) & 0x01); /* get bool */
1053
1054 return 0; /* success return 0 */
1055}
1056
1068{
1069 uint8_t res;
1070
1071 if (handle == NULL) /* check handle */
1072 {
1073 return 2; /* return error */
1074 }
1075 if (handle->inited != 1) /* check handle initialization */
1076 {
1077 return 3; /* return error */
1078 }
1079
1080 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_START_LOW_POWER_PERIODIC, NULL, 0); /* write config */
1081 if (res != 0) /* check result */
1082 {
1083 handle->debug_print("scd4x: start low power periodic measurement failed.\n"); /* start low power periodic measurement failed */
1084
1085 return 1; /* return error */
1086 }
1087
1088 return 0; /* success return 0 */
1089}
1090
1104{
1105 uint8_t res;
1106 uint8_t buf[3];
1107 uint16_t prev;
1108
1109 if (handle == NULL) /* check handle */
1110 {
1111 return 2; /* return error */
1112 }
1113 if (handle->inited != 1) /* check handle initialization */
1114 {
1115 return 3; /* return error */
1116 }
1117
1118 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_DATA_READY_STATUS, buf, 3, 1); /* read config */
1119 if (res != 0) /* check result */
1120 {
1121 handle->debug_print("scd4x: get data ready status failed.\n"); /* get data ready status failed */
1122
1123 return 1; /* return error */
1124 }
1125 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1126 {
1127 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1128
1129 return 4; /* return error */
1130 }
1131 prev = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set prev */
1132 if ((prev & 0x07FF) != 0) /* check data */
1133 {
1134 *enable = SCD4X_BOOL_TRUE; /* ready */
1135 }
1136 else
1137 {
1138 *enable = SCD4X_BOOL_FALSE; /* not ready */
1139 }
1140
1141 return 0; /* success return 0 */
1142}
1143
1155{
1156 uint8_t res;
1157
1158 if (handle == NULL) /* check handle */
1159 {
1160 return 2; /* return error */
1161 }
1162 if (handle->inited != 1) /* check handle initialization */
1163 {
1164 return 3; /* return error */
1165 }
1166
1167 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_PERSIST_SETTINGS, NULL, 0); /* write config */
1168 if (res != 0) /* check result */
1169 {
1170 handle->debug_print("scd4x: persist settings failed.\n"); /* persist settings failed */
1171
1172 return 1; /* return error */
1173 }
1174 handle->delay_ms(800); /* delay 800ms */
1175
1176 return 0; /* success return 0 */
1177}
1178
1191uint8_t scd4x_get_serial_number(scd4x_handle_t *handle, uint16_t number[3])
1192{
1193 uint8_t res;
1194 uint8_t buf[9];
1195
1196 if (handle == NULL) /* check handle */
1197 {
1198 return 2; /* return error */
1199 }
1200 if (handle->inited != 1) /* check handle initialization */
1201 {
1202 return 3; /* return error */
1203 }
1204
1205 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_SERIAL_NUMBER, buf, 9, 1); /* read config */
1206 if (res != 0) /* check result */
1207 {
1208 handle->debug_print("scd4x: get serial number failed.\n"); /* get serial number failed */
1209
1210 return 1; /* return error */
1211 }
1212 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1213 {
1214 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1215
1216 return 4; /* return error */
1217 }
1218 if (buf[5] != a_scd4x_generate_crc(&buf[3], 2)) /* check crc */
1219 {
1220 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1221
1222 return 4; /* return error */
1223 }
1224 if (buf[8] != a_scd4x_generate_crc(&buf[6], 2)) /* check crc */
1225 {
1226 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1227
1228 return 4; /* return error */
1229 }
1230 number[0] = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set number0 */
1231 number[1] = (uint16_t)(((uint16_t)buf[3]) << 8) | buf[4]; /* set number1 */
1232 number[2] = (uint16_t)(((uint16_t)buf[6]) << 8) | buf[7]; /* set number2 */
1233
1234 return 0; /* success return 0 */
1235}
1236
1249uint8_t scd4x_perform_self_test(scd4x_handle_t *handle, scd4x_bool_t *malfunction_detected)
1250{
1251 uint8_t res;
1252 uint8_t buf[3];
1253 uint16_t prev;
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 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_PERFORM_SELF_TEST, buf, 3, 10000); /* read config */
1265 if (res != 0) /* check result */
1266 {
1267 handle->debug_print("scd4x: perform self test failed.\n"); /* perform self test failed */
1268
1269 return 1; /* return error */
1270 }
1271 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1272 {
1273 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1274
1275 return 4; /* return error */
1276 }
1277 prev = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set prev */
1278 if (prev != 0) /* check data */
1279 {
1280 *malfunction_detected = SCD4X_BOOL_TRUE; /* true */
1281 }
1282 else
1283 {
1284 *malfunction_detected = SCD4X_BOOL_FALSE; /* false */
1285 }
1286
1287 return 0; /* success return 0 */
1288}
1289
1301{
1302 uint8_t res;
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 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_PERFORM_FACTORY_RESET, NULL, 0); /* write config */
1314 if (res != 0) /* check result */
1315 {
1316 handle->debug_print("scd4x: perform factory reset failed.\n"); /* perform factory reset failed */
1317
1318 return 1; /* return error */
1319 }
1320 handle->delay_ms(1200); /* delay 1200ms */
1321
1322 return 0; /* success return 0 */
1323}
1324
1336{
1337 uint8_t res;
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 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_REINIT, NULL, 0); /* write config */
1349 if (res != 0) /* check result */
1350 {
1351 handle->debug_print("scd4x: reinit failed.\n"); /* reinit failed */
1352
1353 return 1; /* return error */
1354 }
1355 handle->delay_ms(30); /* delay 30ms */
1356
1357 return 0; /* success return 0 */
1358}
1359
1372{
1373 uint8_t res;
1374
1375 if (handle == NULL) /* check handle */
1376 {
1377 return 2; /* return error */
1378 }
1379 if (handle->inited != 1) /* check handle initialization */
1380 {
1381 return 3; /* return error */
1382 }
1383 if (handle->type == SCD40) /* check type */
1384 {
1385 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1386
1387 return 4; /* return error */
1388 }
1389
1390 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_MEASURE_SINGLE_SHOT, NULL, 0); /* write config */
1391 if (res != 0) /* check result */
1392 {
1393 handle->debug_print("scd4x: measure single shot failed.\n"); /* measure single shot failed */
1394
1395 return 1; /* return error */
1396 }
1397 handle->delay_ms(5000); /* delay 5000ms */
1398
1399 return 0; /* success return 0 */
1400}
1401
1414{
1415 uint8_t res;
1416
1417 if (handle == NULL) /* check handle */
1418 {
1419 return 2; /* return error */
1420 }
1421 if (handle->inited != 1) /* check handle initialization */
1422 {
1423 return 3; /* return error */
1424 }
1425 if (handle->type == SCD40) /* check type */
1426 {
1427 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1428
1429 return 4; /* return error */
1430 }
1431
1432 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_MEASURE_SINGLE_SHOT_RHT_ONLY, NULL, 0); /* write config */
1433 if (res != 0) /* check result */
1434 {
1435 handle->debug_print("scd4x: measure single shot rht only failed.\n"); /* measure single shot rht only failed */
1436
1437 return 1; /* return error */
1438 }
1439 handle->delay_ms(50); /* delay 50ms */
1440
1441 return 0; /* success return 0 */
1442}
1443
1456{
1457 uint8_t res;
1458
1459 if (handle == NULL) /* check handle */
1460 {
1461 return 2; /* return error */
1462 }
1463 if (handle->inited != 1) /* check handle initialization */
1464 {
1465 return 3; /* return error */
1466 }
1467 if (handle->type == SCD40) /* check type */
1468 {
1469 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1470
1471 return 4; /* return error */
1472 }
1473
1474 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_POWER_DOWN, NULL, 0); /* write config */
1475 if (res != 0) /* check result */
1476 {
1477 handle->debug_print("scd4x: power down failed.\n"); /* power down failed */
1478
1479 return 1; /* return error */
1480 }
1481 handle->delay_ms(1); /* delay 1ms */
1482
1483 return 0; /* success return 0 */
1484}
1485
1498{
1499 if (handle == NULL) /* check handle */
1500 {
1501 return 2; /* return error */
1502 }
1503 if (handle->inited != 1) /* check handle initialization */
1504 {
1505 return 3; /* return error */
1506 }
1507 if (handle->type == SCD40) /* check type */
1508 {
1509 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1510
1511 return 4; /* return error */
1512 }
1513
1514 (void)a_scd4x_iic_write(handle, SCD4X_COMMAND_WAKE_UP, NULL, 0); /* write config */
1515 handle->delay_ms(30); /* delay 30ms */
1516
1517 return 0; /* success return 0 */
1518}
1519
1534{
1535 uint8_t res;
1536 uint8_t buf[3];
1537
1538 if (handle == NULL) /* check handle */
1539 {
1540 return 2; /* return error */
1541 }
1542 if (handle->inited != 1) /* check handle initialization */
1543 {
1544 return 3; /* return error */
1545 }
1546 if (handle->type == SCD40) /* check type */
1547 {
1548 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1549
1550 return 4; /* return error */
1551 }
1552 if ((hour % 4) != 0) /* check hour */
1553 {
1554 handle->debug_print("scd4x: hour is not integer multiples of 4.\n"); /* hour is not integer multiples of 4 */
1555
1556 return 5; /* return error */
1557 }
1558
1559 buf[0] = (hour >> 8) & 0xFF; /* msb */
1560 buf[1] = (hour >> 0) & 0xFF; /* lsb */
1561 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* crc */
1562 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_INIT_PERIOD, buf, 3); /* write config */
1563 if (res != 0) /* check result */
1564 {
1565 handle->debug_print("scd4x: set automatic self calibration initial period failed.\n"); /* set automatic self calibration initial period failed */
1566
1567 return 1; /* return error */
1568 }
1569 handle->delay_ms(1); /* delay 1ms */
1570
1571 return 0; /* success return 0 */
1572}
1573
1588{
1589 uint8_t res;
1590 uint8_t buf[3];
1591
1592 if (handle == NULL) /* check handle */
1593 {
1594 return 2; /* return error */
1595 }
1596 if (handle->inited != 1) /* check handle initialization */
1597 {
1598 return 3; /* return error */
1599 }
1600 if (handle->type == SCD40) /* check type */
1601 {
1602 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1603
1604 return 4; /* return error */
1605 }
1606
1607 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_INIT_PERIOD, buf, 3, 1); /* read config */
1608 if (res != 0) /* check result */
1609 {
1610 handle->debug_print("scd4x: get automatic self calibration initial period failed.\n"); /* get automatic self calibration initial period failed */
1611
1612 return 1; /* return error */
1613 }
1614 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1615 {
1616 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1617
1618 return 5; /* return error */
1619 }
1620 *hour = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* get hour */
1621
1622 return 0; /* success return 0 */
1623}
1624
1639{
1640 uint8_t res;
1641 uint8_t buf[3];
1642
1643 if (handle == NULL) /* check handle */
1644 {
1645 return 2; /* return error */
1646 }
1647 if (handle->inited != 1) /* check handle initialization */
1648 {
1649 return 3; /* return error */
1650 }
1651 if (handle->type == SCD40) /* check type */
1652 {
1653 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1654
1655 return 4; /* return error */
1656 }
1657 if ((hour % 4) != 0) /* check hour */
1658 {
1659 handle->debug_print("scd4x: hour is not integer multiples of 4.\n"); /* hour is not integer multiples of 4 */
1660
1661 return 5; /* return error */
1662 }
1663
1664 buf[0] = (hour >> 8) & 0xFF; /* msb */
1665 buf[1] = (hour >> 0) & 0xFF; /* lsb */
1666 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* crc */
1667 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD, buf, 3); /* write config */
1668 if (res != 0) /* check result */
1669 {
1670 handle->debug_print("scd4x: set automatic self calibration standard period failed.\n"); /* set automatic self calibration standard period failed */
1671
1672 return 1; /* return error */
1673 }
1674 handle->delay_ms(1); /* delay 1ms */
1675
1676 return 0; /* success return 0 */
1677}
1678
1693{
1694 uint8_t res;
1695 uint8_t buf[3];
1696
1697 if (handle == NULL) /* check handle */
1698 {
1699 return 2; /* return error */
1700 }
1701 if (handle->inited != 1) /* check handle initialization */
1702 {
1703 return 3; /* return error */
1704 }
1705 if (handle->type == SCD40) /* check type */
1706 {
1707 handle->debug_print("scd4x: only scd41 and scd43 has this function.\n"); /* only scd41 and scd43 has this function */
1708
1709 return 4; /* return error */
1710 }
1711
1712 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD, buf, 3, 1); /* read config */
1713 if (res != 0) /* check result */
1714 {
1715 handle->debug_print("scd4x: get automatic self calibration standard period failed.\n"); /* get automatic self calibration standard period failed */
1716
1717 return 1; /* return error */
1718 }
1719 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1720 {
1721 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1722
1723 return 5; /* return error */
1724 }
1725 *hour = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* get hour */
1726
1727 return 0; /* success return 0 */
1728}
1729
1742{
1743 uint8_t res;
1744 uint8_t buf[3];
1745
1746 if (handle == NULL) /* check handle */
1747 {
1748 return 2; /* return error */
1749 }
1750 if (handle->inited != 1) /* check handle initialization */
1751 {
1752 return 3; /* return error */
1753 }
1754
1755 buf[0] = (co2_ppm >> 8) & 0xFF; /* msb */
1756 buf[1] = (co2_ppm >> 0) & 0xFF; /* lsb */
1757 buf[2] = a_scd4x_generate_crc(&buf[0], 2); /* crc */
1758 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_SET_AUTOMATIC_SELF_CALIBRATION_TARGET, buf, 3); /* write config */
1759 if (res != 0) /* check result */
1760 {
1761 handle->debug_print("scd4x: set automatic self calibration target failed.\n"); /* set automatic self calibration target failed */
1762
1763 return 1; /* return error */
1764 }
1765 handle->delay_ms(1); /* delay 1ms */
1766
1767 return 0; /* success return 0 */
1768}
1769
1783{
1784 uint8_t res;
1785 uint8_t buf[3];
1786
1787 if (handle == NULL) /* check handle */
1788 {
1789 return 2; /* return error */
1790 }
1791 if (handle->inited != 1) /* check handle initialization */
1792 {
1793 return 3; /* return error */
1794 }
1795
1796 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_AUTOMATIC_SELF_CALIBRATION_TARGET, buf, 3, 1); /* read config */
1797 if (res != 0) /* check result */
1798 {
1799 handle->debug_print("scd4x: get automatic self calibration target failed.\n"); /* get automatic self calibration target failed */
1800
1801 return 1; /* return error */
1802 }
1803 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1804 {
1805 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1806
1807 return 4; /* return error */
1808 }
1809 *co2_ppm = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set co2 ppm */
1810
1811 return 0; /* success return 0 */
1812}
1813
1828uint8_t scd4x_get_sensor_variant(scd4x_handle_t *handle, uint16_t *variant)
1829{
1830 uint8_t res;
1831 uint8_t buf[3];
1832
1833 if (handle == NULL) /* check handle */
1834 {
1835 return 2; /* return error */
1836 }
1837 if (handle->inited != 1) /* check handle initialization */
1838 {
1839 return 3; /* return error */
1840 }
1841
1842 res = a_scd4x_iic_read(handle, SCD4X_COMMAND_GET_SENSOR_VARIANT, buf, 3, 1); /* read config */
1843 if (res != 0) /* check result */
1844 {
1845 handle->debug_print("scd4x: get sensor variant failed.\n"); /* get sensor variant failed */
1846
1847 return 1; /* return error */
1848 }
1849 if (buf[2] != a_scd4x_generate_crc(&buf[0], 2)) /* check crc */
1850 {
1851 handle->debug_print("scd4x: crc is error.\n"); /* crc is error */
1852
1853 return 4; /* return error */
1854 }
1855 *variant = (uint16_t)(((uint16_t)buf[0]) << 8) | buf[1]; /* set variant */
1856
1857 return 0; /* success return 0 */
1858}
1859
1871{
1872 if (handle == NULL) /* check handle */
1873 {
1874 return 2; /* return error */
1875 }
1876 if (handle->debug_print == NULL) /* check debug_print */
1877 {
1878 return 3; /* return error */
1879 }
1880 if (handle->iic_init == NULL) /* check iic_init */
1881 {
1882 handle->debug_print("scd4x: iic_init is null.\n"); /* iic_init is null */
1883
1884 return 3; /* return error */
1885 }
1886 if (handle->iic_deinit == NULL) /* check iic_deinit */
1887 {
1888 handle->debug_print("scd4x: iic_deinit is null.\n"); /* iic_deinit is null */
1889
1890 return 3; /* return error */
1891 }
1892 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
1893 {
1894 handle->debug_print("scd4x: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
1895
1896 return 3; /* return error */
1897 }
1898 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
1899 {
1900 handle->debug_print("scd4x: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
1901
1902 return 3; /* return error */
1903 }
1904 if (handle->delay_ms == NULL) /* check delay_ms */
1905 {
1906 handle->debug_print("scd4x: delay_ms is null.\n"); /* delay_ms is null */
1907
1908 return 3; /* return error */
1909 }
1910
1911 if (handle->iic_init() != 0) /* iic init */
1912 {
1913 handle->debug_print("scd4x: iic init failed.\n"); /* iic init failed */
1914
1915 return 1; /* return error */
1916 }
1917 handle->inited = 1; /* flag finish initialization */
1918
1919 return 0; /* success return 0 */
1920}
1921
1934{
1935 uint8_t res;
1936
1937 if (handle == NULL) /* check handle */
1938 {
1939 return 2; /* return error */
1940 }
1941 if (handle->inited != 1) /* check handle initialization */
1942 {
1943 return 3; /* return error */
1944 }
1945
1946 res = a_scd4x_iic_write(handle, SCD4X_COMMAND_STOP_PERIODIC, NULL, 0); /* write config */
1947 if (res != 0) /* check result */
1948 {
1949 handle->debug_print("scd4x: stop periodic measurement failed.\n"); /* stop periodic measurement failed */
1950
1951 return 4; /* return error */
1952 }
1953 handle->delay_ms(500); /* delay 500ms */
1954 if (handle->iic_deinit() != 0) /* iic deinit */
1955 {
1956 handle->debug_print("scd4x: iic close failed.\n"); /* iic close failed */
1957
1958 return 3; /* return error */
1959 }
1960 handle->inited = 0; /* flag close initialization */
1961
1962 return 0; /* success return 0 */
1963}
1964
1978uint8_t scd4x_set_reg(scd4x_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
1979{
1980 if (handle == NULL) /* check handle */
1981 {
1982 return 2; /* return error */
1983 }
1984 if (handle->inited != 1) /* check handle initialization */
1985 {
1986 return 3; /* return error */
1987 }
1988
1989 return a_scd4x_iic_write(handle, reg, buf, len); /* write data */
1990}
1991
2006uint8_t scd4x_get_reg(scd4x_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len, uint16_t delay_ms)
2007{
2008 if (handle == NULL) /* check handle */
2009 {
2010 return 2; /* return error */
2011 }
2012 if (handle->inited != 1) /* check handle initialization */
2013 {
2014 return 3; /* return error */
2015 }
2016
2017 return a_scd4x_iic_read(handle, reg, buf, len, delay_ms); /* read data */
2018}
2019
2029{
2030 if (info == NULL) /* check handle */
2031 {
2032 return 2; /* return error */
2033 }
2034
2035 memset(info, 0, sizeof(scd4x_info_t)); /* initialize scd4x info structure */
2036 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
2037 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
2038 strncpy(info->interface, "IIC", 8); /* copy interface name */
2039 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
2040 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
2041 info->max_current_ma = MAX_CURRENT; /* set maximum current */
2042 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
2043 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
2044 info->driver_version = DRIVER_VERSION; /* set driver version */
2045
2046 return 0; /* success return 0 */
2047}
#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_INIT_PERIOD
#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION
#define SCD4X_COMMAND_GET_AUTOMATIC_SELF_CALIBRATION_TARGET
#define SCD4X_COMMAND_GET_SENSOR_VARIANT
#define SCD4X_CRC8_POLYNOMIAL
crc8 definition
#define SCD4X_COMMAND_PERFORM_FORCED_RECALIBRATION
#define MAX_CURRENT
#define SCD4X_COMMAND_STOP_PERIODIC
#define SCD4X_COMMAND_PERFORM_FACTORY_RESET
#define SCD4X_COMMAND_SET_TEMPERATURE_OFFSET
#define SCD4X_COMMAND_POWER_DOWN
#define SCD4X_COMMAND_MEASURE_SINGLE_SHOT
#define SCD4X_COMMAND_GET_SERIAL_NUMBER
#define SUPPLY_VOLTAGE_MAX
#define SCD4X_COMMAND_SET_SENSOR_ALTITUDE
#define SCD4X_COMMAND_START_LOW_POWER_PERIODIC
#define SCD4X_COMMAND_PERSIST_SETTINGS
#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION
#define SCD4X_COMMAND_REINIT
#define SCD4X_COMMAND_GET_TEMPERATURE_OFFSET
#define SCD4X_COMMAND_PERFORM_SELF_TEST
#define SCD4X_ADDRESS
chip address definition
#define TEMPERATURE_MAX
#define SCD4X_COMMAND_READ
#define SCD4X_COMMAND_GET_SENSOR_ALTITUDE
#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_INIT_PERIOD
#define SCD4X_COMMAND_START_PERIODIC
chip command definition
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#define SCD4X_COMMAND_WAKE_UP
#define SUPPLY_VOLTAGE_MIN
#define SCD4X_CRC8_INIT
#define SCD4X_COMMAND_GET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD
#define SCD4X_COMMAND_GET_DATA_READY_STATUS
#define SCD4X_COMMAND_SET_AUTO_SELF_CALIBRATION_STANDARD_PERIOD
#define SCD4X_COMMAND_SET_AUTOMATIC_SELF_CALIBRATION_TARGET
#define CHIP_NAME
chip information definition
#define DRIVER_VERSION
#define SCD4X_COMMAND_SET_AMBIENT_PRESSURE
#define SCD4X_COMMAND_MEASURE_SINGLE_SHOT_RHT_ONLY
#define SCD4X_COMMAND_GET_AMBIENT_PRESSURE
driver scd4x header file
uint8_t scd4x_get_automatic_self_calibration_target(scd4x_handle_t *handle, uint16_t *co2_ppm)
get automatic self calibration target
uint8_t scd4x_wake_up(scd4x_handle_t *handle)
wake up
uint8_t scd4x_set_automatic_self_calibration_standard_period(scd4x_handle_t *handle, uint16_t hour)
set automatic self calibration standard period
uint8_t scd4x_set_automatic_self_calibration_initial_period(scd4x_handle_t *handle, uint16_t hour)
set automatic self calibration initial period
uint8_t scd4x_power_down(scd4x_handle_t *handle)
power down
uint8_t scd4x_measure_single_shot(scd4x_handle_t *handle)
measure single shot
uint8_t scd4x_get_automatic_self_calibration_standard_period(scd4x_handle_t *handle, uint16_t *hour)
get automatic self calibration standard period
uint8_t scd4x_get_automatic_self_calibration_initial_period(scd4x_handle_t *handle, uint16_t *hour)
get automatic self calibration initial period
uint8_t scd4x_set_automatic_self_calibration_target(scd4x_handle_t *handle, uint16_t co2_ppm)
set automatic self calibration target
uint8_t scd4x_get_sensor_variant(scd4x_handle_t *handle, uint16_t *variant)
get sensor variant
uint8_t scd4x_measure_single_shot_rht_only(scd4x_handle_t *handle)
measure single shot rht only
struct scd4x_info_s scd4x_info_t
scd4x information structure definition
uint8_t scd4x_get_type(scd4x_handle_t *handle, scd4x_t *type)
get type
uint8_t scd4x_get_data_ready_status(scd4x_handle_t *handle, scd4x_bool_t *enable)
get data ready status
uint8_t scd4x_stop_periodic_measurement(scd4x_handle_t *handle)
stop periodic measurement
uint8_t scd4x_get_sensor_altitude(scd4x_handle_t *handle, uint16_t *altitude)
get sensor altitude
uint8_t scd4x_sensor_altitude_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *m)
convert the register raw data to the sensor altitude
uint8_t scd4x_set_temperature_offset(scd4x_handle_t *handle, uint16_t offset)
set temperature offset
uint8_t scd4x_get_serial_number(scd4x_handle_t *handle, uint16_t number[3])
get serial number
uint8_t scd4x_deinit(scd4x_handle_t *handle)
close the chip
uint8_t scd4x_get_automatic_self_calibration(scd4x_handle_t *handle, scd4x_bool_t *enable)
get automatic self calibration status
uint8_t scd4x_set_ambient_pressure(scd4x_handle_t *handle, uint16_t pressure)
set ambient pressure
uint8_t scd4x_co2_convert_to_register(scd4x_handle_t *handle, float ppm, uint16_t *reg)
convert the co2 to the register raw data
uint8_t scd4x_read(scd4x_handle_t *handle, uint16_t *co2_raw, uint16_t *co2_ppm, uint16_t *temperature_raw, float *temperature_s, uint16_t *humidity_raw, float *humidity_s)
read data
uint8_t scd4x_set_type(scd4x_handle_t *handle, scd4x_t type)
set type
uint8_t scd4x_get_temperature_offset(scd4x_handle_t *handle, uint16_t *offset)
get temperature offset
uint8_t scd4x_temperature_offset_convert_to_register(scd4x_handle_t *handle, float degrees, uint16_t *reg)
convert the temperature offset to the register raw data
uint8_t scd4x_reinit(scd4x_handle_t *handle)
reinit
uint8_t scd4x_ambient_pressure_convert_to_register(scd4x_handle_t *handle, float pa, uint16_t *reg)
convert the ambient pressure to the register raw data
uint8_t scd4x_co2_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *ppm)
convert the register raw data to the co2
uint8_t scd4x_set_automatic_self_calibration(scd4x_handle_t *handle, scd4x_bool_t enable)
enable or disable automatic self calibration
uint8_t scd4x_init(scd4x_handle_t *handle)
initialize the chip
uint8_t scd4x_perform_forced_recalibration(scd4x_handle_t *handle, uint16_t co2_raw, uint16_t *frc)
perform forced recalibration
uint8_t scd4x_perform_factory_reset(scd4x_handle_t *handle)
perform factory reset
uint8_t scd4x_persist_settings(scd4x_handle_t *handle)
persist settings
uint8_t scd4x_start_periodic_measurement(scd4x_handle_t *handle)
start periodic measurement
struct scd4x_handle_s scd4x_handle_t
scd4x handle structure definition
uint8_t scd4x_perform_self_test(scd4x_handle_t *handle, scd4x_bool_t *malfunction_detected)
perform self test
uint8_t scd4x_info(scd4x_info_t *info)
get chip information
uint8_t scd4x_ambient_pressure_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *pa)
convert the register raw data to the ambient pressure
uint8_t scd4x_set_sensor_altitude(scd4x_handle_t *handle, uint16_t altitude)
set sensor altitude
uint8_t scd4x_sensor_altitude_convert_to_register(scd4x_handle_t *handle, float m, uint16_t *reg)
convert the sensor altitude to the register raw data
uint8_t scd4x_temperature_offset_convert_to_data(scd4x_handle_t *handle, uint16_t reg, float *degrees)
convert the register raw data to the temperature offset
scd4x_t
scd4x type enumeration definition
scd4x_bool_t
scd4x bool enumeration definition
uint8_t scd4x_get_ambient_pressure(scd4x_handle_t *handle, uint16_t *pressure)
get ambient pressure
uint8_t scd4x_start_low_power_periodic_measurement(scd4x_handle_t *handle)
start low power periodic measurement
@ SCD40
@ SCD4X_BOOL_TRUE
@ SCD4X_BOOL_FALSE
uint8_t scd4x_set_reg(scd4x_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register
uint8_t scd4x_get_reg(scd4x_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len, uint16_t delay_ms)
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]