42#define CHIP_NAME "Sensirion SGP40"
43#define MANUFACTURER_NAME "Sensirion"
44#define SUPPLY_VOLTAGE_MIN 1.70f
45#define SUPPLY_VOLTAGE_MAX 3.60f
46#define MAX_CURRENT 4.00f
47#define TEMPERATURE_MIN -20.0f
48#define TEMPERATURE_MAX 55.0f
49#define DRIVER_VERSION 1000
54#define SGP40_ADDRESS (0x59 << 1)
59#define SGP40_COMMAND_MEASURE_RAW 0x260FU
60#define SGP40_COMMAND_EXECUTE_SELF_TEST 0x280EU
61#define SGP40_COMMAND_TURN_HEATER_OFF 0x3615U
62#define SGP40_COMMAND_GET_SERIAL_ID 0x3682U
63#define SGP40_COMMAND_SOFT_RESET 0x0006U
68#define SGP40_CRC8_POLYNOMIAL 0x31
69#define SGP40_CRC8_INIT 0xFF
85static uint8_t a_sgp40_iic_read_with_param(
sgp40_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len,
86 uint16_t delay_ms, uint8_t *output, uint16_t output_len)
95 memset(buf, 0,
sizeof(uint8_t) * 16);
96 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
97 buf[1] = (uint8_t)(reg & 0xFF);
98 for (i = 0; i < len; i++)
100 buf[2 + i] = data[i];
130static uint8_t a_sgp40_iic_read(
sgp40_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
134 memset(buf, 0,
sizeof(uint8_t) * 2);
135 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
136 buf[1] = (uint8_t)(reg & 0xFF);
163static uint8_t a_sgp40_iic_write(
sgp40_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
172 memset(buf, 0,
sizeof(uint8_t) * 16);
173 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
174 buf[1] = (uint8_t)(reg & 0xFF);
175 for (i = 0; i < len; i++)
177 buf[2 + i] = data[i];
197static uint8_t a_sgp40_generate_crc(uint8_t* data, uint8_t count)
199 uint8_t current_byte;
203 for (current_byte = 0; current_byte < count; ++current_byte)
205 crc ^= (data[current_byte]);
206 for (crc_bit = 8; crc_bit > 0; --crc_bit)
208 if ((crc & 0x80) != 0)
245 *reg = (uint16_t)(rh / 100.0f * 65535.0f);
273 *reg = (uint16_t)((temp + 45.0f) / 175.0f * 65535.0f);
292 uint16_t raw_temperature, uint16_t *sraw_voc)
307 memset(buf, 0,
sizeof(uint8_t) * 3);
308 input[0] = (raw_humidity >> 8) & 0xFF;
309 input[1] = (raw_humidity >> 0) & 0xFF;
310 input[2] = a_sgp40_generate_crc(&input[0], 2);
311 input[3] = (raw_temperature >> 8) & 0xFF;
312 input[4] = (raw_temperature >> 0) & 0xFF;
313 input[5] = a_sgp40_generate_crc(&input[3], 2);
317 handle->
debug_print(
"sgp40: read measure raw failed.\n");
321 if (buf[2] != a_sgp40_generate_crc((uint8_t *)buf, 2))
323 handle->
debug_print(
"sgp40: sraw voc crc check error.\n");
327 *sraw_voc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
358 memset(buf, 0,
sizeof(uint8_t) * 3);
368 handle->
debug_print(
"sgp40: read measure raw failed.\n");
372 if (buf[2] != a_sgp40_generate_crc((uint8_t *)buf, 2))
374 handle->
debug_print(
"sgp40: sraw voc crc check error.\n");
378 *sraw_voc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
408 memset(buf, 0,
sizeof(uint8_t) * 3);
412 handle->
debug_print(
"sgp40: read measure test failed.\n");
416 if (buf[2] != a_sgp40_generate_crc((uint8_t *)buf, 2))
418 handle->
debug_print(
"sgp40: measure test check error.\n");
422 *result = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
455 handle->
debug_print(
"sgp40: write soft reset failed.\n");
490 handle->
debug_print(
"sgp40: write turn heater off failed.\n");
524 memset(buf, 0,
sizeof(uint8_t) * 9);
528 handle->
debug_print(
"sgp40: read serial id failed.\n");
532 if (buf[2] != a_sgp40_generate_crc((uint8_t *)&buf[0], 2))
534 handle->
debug_print(
"sgp40: crc 1 check failed.\n");
538 if (buf[5] != a_sgp40_generate_crc((uint8_t *)&buf[3], 2))
540 handle->
debug_print(
"sgp40: crc 2 check failed.\n");
544 if (buf[8] != a_sgp40_generate_crc((uint8_t *)&buf[6], 2))
546 handle->
debug_print(
"sgp40: crc 3 check failed.\n");
550 id[0] = (uint16_t)((((uint16_t)buf[0]) << 8) | buf[1]);
551 id[1] = (uint16_t)((((uint16_t)buf[3]) << 8) | buf[4]);
552 id[2] = (uint16_t)((((uint16_t)buf[6]) << 8) | buf[7]);
585 handle->
debug_print(
"sgp40: iic_deinit is null.\n");
591 handle->
debug_print(
"sgp40: iic_write_cmd is null.\n");
597 handle->
debug_print(
"sgp40: iic_read_cmd is null.\n");
643 handle->
debug_print(
"sgp40: turn heater off failed.\n");
682 return a_sgp40_iic_write(handle, reg, buf, len);
709 return a_sgp40_iic_read(handle, reg, buf, len, 320);
#define SGP40_COMMAND_MEASURE_RAW
chip command definition
#define SGP40_COMMAND_TURN_HEATER_OFF
#define SGP40_CRC8_POLYNOMIAL
crc8 definition
#define SGP40_ADDRESS
chip address definition
#define SUPPLY_VOLTAGE_MAX
#define SGP40_COMMAND_GET_SERIAL_ID
#define SGP40_COMMAND_EXECUTE_SELF_TEST
#define MANUFACTURER_NAME
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip information definition
uint8_t sgp40_get_measure_raw(sgp40_handle_t *handle, uint16_t raw_humidity, uint16_t raw_temperature, uint16_t *sraw_voc)
get the measure raw result
uint8_t sgp40_get_serial_id(sgp40_handle_t *handle, uint16_t id[3])
get the chip serial id
uint8_t sgp40_init(sgp40_handle_t *handle)
initialize the chip
uint8_t sgp40_soft_reset(sgp40_handle_t *handle)
soft reset the chip
uint8_t sgp40_get_measure_raw_without_compensation(sgp40_handle_t *handle, uint16_t *sraw_voc)
get the measure raw result without compensation
uint8_t sgp40_info(sgp40_info_t *info)
get chip information
uint8_t sgp40_humidity_convert_to_register(sgp40_handle_t *handle, float rh, uint16_t *reg)
convert the humidity to the register data
uint8_t sgp40_turn_heater_off(sgp40_handle_t *handle)
turn heater off
uint8_t sgp40_deinit(sgp40_handle_t *handle)
close the chip
uint8_t sgp40_get_measure_test(sgp40_handle_t *handle, uint16_t *result)
get the chip measure test
struct sgp40_handle_s sgp40_handle_t
sgp40 handle structure definition
uint8_t sgp40_temperature_convert_to_register(sgp40_handle_t *handle, float temp, uint16_t *reg)
convert the temperature to the register data
struct sgp40_info_s sgp40_info_t
sgp40 information structure definition
uint8_t sgp40_get_reg(sgp40_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
get the chip register
uint8_t sgp40_set_reg(sgp40_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