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
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
74#define STCC4_CRC8_POLYNOMIAL 0x31
75#define STCC4_CRC8_INIT 0xFF
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)
101 memset(buf, 0,
sizeof(uint8_t) * 16);
102 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
103 buf[1] = (uint8_t)(reg & 0xFF);
104 for (i = 0; i < len; i++)
106 buf[2 + i] = data[i];
136static uint8_t a_stcc4_iic_read(
stcc4_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
140 memset(buf, 0,
sizeof(uint8_t) * 2);
141 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
142 buf[1] = (uint8_t)(reg & 0xFF);
169static uint8_t a_stcc4_iic_write(
stcc4_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
178 memset(buf, 0,
sizeof(uint8_t) * 16);
179 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
180 buf[1] = (uint8_t)(reg & 0xFF);
181 for (i = 0; i < len; i++)
183 buf[2 + i] = data[i];
203static uint8_t a_stcc4_generate_crc(uint8_t* data, uint8_t count)
205 uint8_t current_byte;
209 for (current_byte = 0; current_byte < count; ++current_byte)
211 crc ^= (data[current_byte]);
212 for (crc_bit = 8; crc_bit > 0; --crc_bit)
214 if ((crc & 0x80) != 0)
244 handle->
iic_addr = (uint8_t)address;
296 handle->
debug_print(
"stcc4: start continuous measurement failed.\n");
331 handle->
debug_print(
"stcc4: stop continuous measurement failed.\n");
366 buf[0] = (temperature_raw >> 8) & 0xFF;
367 buf[1] = (temperature_raw >> 0) & 0xFF;
368 buf[2] = a_stcc4_generate_crc(buf + 0, 2);
369 buf[3] = (humidity_raw >> 8) & 0xFF;
370 buf[4] = (humidity_raw >> 0) & 0xFF;
371 buf[5] = a_stcc4_generate_crc(buf + 3, 2);
375 handle->
debug_print(
"stcc4: set rht compensation failed.\n");
409 buf[0] = (pressure_raw >> 8) & 0xFF;
410 buf[1] = (pressure_raw >> 0) & 0xFF;
411 buf[2] = a_stcc4_generate_crc(buf + 0, 2);
415 handle->
debug_print(
"stcc4: set pressure compensation failed.\n");
450 handle->
debug_print(
"stcc4: measure single shot failed.\n");
485 handle->
debug_print(
"stcc4: enter sleep mode failed.\n");
549 handle->
debug_print(
"stcc4: perform conditioning failed.\n");
616 handle->
debug_print(
"stcc4: perform factory reset failed.\n");
620 result = (uint16_t)((uint16_t)buf[0] << 8) | buf[1];
660 handle->
debug_print(
"stcc4: perform self test failed.\n");
664 if (a_stcc4_generate_crc(buf, 2) != buf[2])
670 *result = (uint16_t)((uint16_t)buf[0] << 8) | buf[1];
701 handle->
debug_print(
"stcc4: enable testing mode failed.\n");
735 handle->
debug_print(
"stcc4: disable testing mode failed.\n");
771 buf[0] = (target_co2 >> 8) & 0xFF;
772 buf[1] = (target_co2 >> 0) & 0xFF;
773 buf[2] = a_stcc4_generate_crc(buf, 2);
775 buf, 3, 90, output, 3);
778 handle->
debug_print(
"stcc4: perform forced recalibration failed.\n");
782 if (a_stcc4_generate_crc(output, 2) != output[2])
788 *correct_co2 = (uint16_t)((uint16_t)output[0] << 8) | output[1];
824 handle->
debug_print(
"stcc4: get product id failed.\n");
828 for (i = 0; i < 18; i += 3)
830 if (a_stcc4_generate_crc(buf + i, 2) != buf[i + 2])
837 *product_id = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
838 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0);
839 unique_serial_number[0] = buf[6];
840 unique_serial_number[1] = buf[7];
841 unique_serial_number[2] = buf[9];
842 unique_serial_number[3] = buf[10];
843 unique_serial_number[4] = buf[12];
844 unique_serial_number[5] = buf[13];
845 unique_serial_number[6] = buf[15];
846 unique_serial_number[7] = buf[16];
871 uint16_t *temperature_raw,
float *temperature_s,
872 uint16_t *humidity_raw,
float *humidity_s, uint16_t *sensor_status)
889 handle->
debug_print(
"stcc4: read measurement failed.\n");
894 if (buf[2] != a_stcc4_generate_crc(&buf[0], 2))
900 if (buf[5] != a_stcc4_generate_crc(&buf[3], 2))
906 if (buf[8] != a_stcc4_generate_crc(&buf[6], 2))
912 if (buf[11] != a_stcc4_generate_crc(&buf[9], 2))
919 *co2_raw = (int16_t)(((uint16_t)buf[0]) << 8) | buf[1];
920 *temperature_raw = (uint16_t)(((uint16_t)buf[3]) << 8) | buf[4];
921 *humidity_raw = (uint16_t)(((uint16_t)buf[6]) << 8) | buf[7];
922 *sensor_status = (uint16_t)(((uint16_t)buf[9]) << 8) | buf[10];
924 *temperature_s = -45.0f + 175.0f * (float)(*temperature_raw) / 65535.0f;
925 *humidity_s = 125.0f * (float)(*humidity_raw) / 65535.0f - 6.0f;
926 if ((*sensor_status) != 0)
928 handle->
debug_print(
"stcc4: sensor status is invalid.\n");
971 handle->
debug_print(
"stcc4: iic_deinit is null.\n");
977 handle->
debug_print(
"stcc4: iic_write_cmd is null.\n");
983 handle->
debug_print(
"stcc4: iic_read_cmd is null.\n");
1008 handle->
debug_print(
"stcc4: get product id failed.\n");
1013 for (i = 0; i < 18; i += 3)
1015 if (a_stcc4_generate_crc(buf + i, 2) != buf[i + 2])
1017 handle->
debug_print(
"stcc4: crc check failed.\n");
1023 product_id = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1024 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0);
1025 if (product_id != 0x0901018AU)
1027 handle->
debug_print(
"stcc4: product id is invalid.\n");
1065 handle->
debug_print(
"stcc4: stop continuous measurement failed.\n");
1071 handle->
debug_print(
"stcc4: iic close failed.\n");
1102 *reg = (uint16_t)(ppm + 32768.0f);
1129 *ppm = (float)(reg) - 32768.0f;
1156 *reg = (uint16_t)((percentage + 6.0f) * 65535.0f / 125.0f);
1183 *percentage = (float)(reg) / 65535.0f * 125.0f - 6.0f;
1210 *reg = (uint16_t)((deg + 45.0f) * 65535.0f / 175.0f);
1237 *deg = (float)(reg) / 65535.0f * 175.0f - 45.0f;
1264 *reg = (uint16_t)(pa / 2.0f);
1291 *pa = (float)(reg) * 2;
1320 return a_stcc4_iic_write(handle, reg, buf, len);
1348 return a_stcc4_iic_read(handle, reg, buf, len, delay_ms);
#define STCC4_COMMAND_PERFORM_CONDITIONING
#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_COMMAND_ENABLE_TESTING_MODE
#define STCC4_COMMAND_ENTER_SLEEP_MODE
#define MANUFACTURER_NAME
#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 STCC4_COMMAND_PERFORM_SELF_TEST
#define STCC4_COMMAND_DISABLE_TESTING_MODE
#define STCC4_COMMAND_SET_PRESSURER_COMPENSATION
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 supply_voltage_max_v
char manufacturer_name[32]
float supply_voltage_min_v