43#define CHIP_NAME "Sensirion SGP30"
44#define MANUFACTURER_NAME "Sensirion"
45#define SUPPLY_VOLTAGE_MIN 1.62f
46#define SUPPLY_VOLTAGE_MAX 1.98f
47#define MAX_CURRENT 48.8f
48#define TEMPERATURE_MIN -40.0f
49#define TEMPERATURE_MAX 85.0f
50#define DRIVER_VERSION 2000
55#define SGP30_ADDRESS (0x58 << 1)
60#define SGP30_COMMAND_IAQ_INIT 0x2003U
61#define SGP30_COMMAND_MEASURE_IAQ 0x2008U
62#define SGP30_COMMAND_GET_IAQ_BASELINE 0x2015U
63#define SGP30_COMMAND_SET_IAQ_BASELINE 0x201EU
64#define SGP30_COMMAND_SET_ABSOLUTE_HUMIDITY 0x2061U
65#define SGP30_COMMAND_MEASURE_TEST 0x2032U
66#define SGP30_COMMAND_GET_FEATURE_SET 0x202FU
67#define SGP30_COMMAND_MEASURE_RAW 0x2050U
68#define SGP30_COMMAND_GET_TVOC_INCEPTIVE_BASELINE 0x20B3U
69#define SGP30_COMMAND_SET_TVOC_BASELINE 0x2077U
70#define SGP30_COMMAND_SOFT_RESET 0x0006U
71#define SGP30_COMMAND_GET_SERIAL_ID 0x3682U
76#define SGP30_CRC8_POLYNOMIAL 0x31
77#define SGP30_CRC8_INIT 0xFF
92static uint8_t a_sgp30_iic_read(
sgp30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
96 memset(buf, 0,
sizeof(uint8_t) * 2);
97 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
98 buf[1] = (uint8_t)(reg & 0xFF);
126static uint8_t a_sgp30_iic_write(
sgp30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len)
135 memset(buf, 0,
sizeof(uint8_t) * 16);
136 buf[0] = (uint8_t)((reg >> 8) & 0xFF);
137 buf[1] = (uint8_t)(reg & 0xFF);
138 for (i = 0; i < len; i++)
140 buf[2 + i] = data[i];
143 if (handle->
iic_write_cmd(addr, (uint8_t *)buf, len + 2) != 0)
160static uint8_t a_sgp30_generate_crc(uint8_t* data, uint8_t count)
162 uint8_t current_byte;
166 for (current_byte = 0; current_byte < count; ++current_byte)
168 crc ^= (data[current_byte]);
169 for (crc_bit = 8; crc_bit > 0; --crc_bit)
171 if ((crc & 0x80) != 0)
210 memset(buf, 0,
sizeof(uint8_t) * 3);
211 buf[0] = (tvoc_baseline >> 8) & 0xFF;
212 buf[1] = (tvoc_baseline >> 0) & 0xFF;
213 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2);
217 handle->
debug_print(
"sgp30: write tvoc baseline failed.\n");
251 memset(buf, 0,
sizeof(uint8_t) * 3);
255 handle->
debug_print(
"sgp30: read tvoc baseline failed.\n");
259 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
265 *tvoc_baseline = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
296 handle->
debug_print(
"sgp30: write iaq init failed.\n");
333 handle->
debug_print(
"sgp30: write soft reset failed.\n");
366 memset(buf, 0,
sizeof(uint8_t) * 9);
370 handle->
debug_print(
"sgp30: read serial id failed.\n");
374 if (buf[2] != a_sgp30_generate_crc((uint8_t *)&buf[0], 2))
376 handle->
debug_print(
"sgp30: crc 1 check failed.\n");
380 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2))
382 handle->
debug_print(
"sgp30: crc 2 check failed.\n");
386 if (buf[8] != a_sgp30_generate_crc((uint8_t *)&buf[6], 2))
388 handle->
debug_print(
"sgp30: crc 3 check failed.\n");
392 id[0] = (uint16_t)((((uint16_t)buf[0]) << 8) | buf[1]);
393 id[1] = (uint16_t)((((uint16_t)buf[3]) << 8) | buf[4]);
394 id[2] = (uint16_t)((((uint16_t)buf[6]) << 8) | buf[7]);
425 memset(buf, 0,
sizeof(uint8_t) * 6);
429 handle->
debug_print(
"sgp30: read measure iaq failed.\n");
433 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
435 handle->
debug_print(
"sgp30: co2 eq crc check error.\n");
439 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2))
441 handle->
debug_print(
"sgp30: tvoc crc check error.\n");
445 *co2_eq_ppm = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
446 *tvoc_ppb = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
477 memset(buf, 0,
sizeof(uint8_t) * 6);
481 handle->
debug_print(
"sgp30: read measure iaq failed.\n");
485 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
487 handle->
debug_print(
"sgp30: co2 eq crc check error.\n");
491 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2))
493 handle->
debug_print(
"sgp30: tvoc crc check error.\n");
497 *co2_eq = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
498 *tvoc = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
529 memset(buf, 0,
sizeof(uint8_t) * 6);
530 buf[0] = (tvoc >> 8) & 0xFF;
531 buf[1] = tvoc & 0xFF;
532 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2);
533 buf[3] = (co2_eq >> 8) & 0xFF;
534 buf[4] = co2_eq & 0xFF;
535 buf[5] = a_sgp30_generate_crc((uint8_t *)&buf[3], 2);
539 handle->
debug_print(
"sgp30: write iaq baseline failed.\n");
573 memset(buf, 0,
sizeof(uint8_t) * 3);
574 buf[0] = (humidity >> 8) & 0xFF;
575 buf[1] = (humidity >> 0) & 0xFF;
576 buf[2] = a_sgp30_generate_crc((uint8_t *)buf, 2);
580 handle->
debug_print(
"sgp30: write absolute humidity failed.\n");
604 float absolute_humidity;
605 float intpart, fractpart;
616 absolute_humidity = (rh / 100.0f * 6.112f * powf(17.62f * temp, 243.12f + temp)) / (273.15f + temp) * 216.7f;
617 fractpart = modff(absolute_humidity, (
float *)&intpart);
618 *reg = (uint16_t)(intpart) << 8 | (uint8_t)(fractpart * 256);
648 memset(buf, 0,
sizeof(uint8_t) * 3);
652 handle->
debug_print(
"sgp30: read measure test failed.\n");
656 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
658 handle->
debug_print(
"sgp30: measure test check error.\n");
662 *result = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
693 memset(buf, 0,
sizeof(uint8_t) * 3);
697 handle->
debug_print(
"sgp30: get feature set failed.\n");
701 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
703 handle->
debug_print(
"sgp30: feature set check error.\n");
707 *product_type = (buf[0] >> 4) & 0xF;
708 *product_version = buf[1];
739 memset(buf, 0,
sizeof(uint8_t) * 6);
743 handle->
debug_print(
"sgp30: read measure raw failed.\n");
747 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
749 handle->
debug_print(
"sgp30: co2 eq crc check error.\n");
753 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2))
755 handle->
debug_print(
"sgp30: tvoc crc check error.\n");
759 *tvoc = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
760 *co2_eq = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
793 handle->
debug_print(
"sgp30: iic_deinit is null.\n");
799 handle->
debug_print(
"sgp30: iic_write_cmd is null.\n");
805 handle->
debug_print(
"sgp30: iic_read_cmd is null.\n");
851 handle->
debug_print(
"sgp30: soft reset failed.\n");
892 memset(buf, 0,
sizeof(uint8_t) * 6);
896 handle->
debug_print(
"sgp30: read measure iaq failed.\n");
900 if (buf[2] != a_sgp30_generate_crc((uint8_t *)buf, 2))
902 handle->
debug_print(
"sgp30: co2 eq crc check error.\n");
906 if (buf[5] != a_sgp30_generate_crc((uint8_t *)&buf[3], 2))
908 handle->
debug_print(
"sgp30: tvoc crc check error.\n");
912 *co2_eq_ppm = (uint16_t)(((uint16_t)buf[0]) << 8 | buf[1]);
913 *tvoc_ppb = (uint16_t)(((uint16_t)buf[3]) << 8 | buf[4]);
942 return a_sgp30_iic_write(handle,
SGP30_ADDRESS, reg, buf, len);
969 return a_sgp30_iic_read(handle,
SGP30_ADDRESS, reg, buf, len, 20);
#define SGP30_CRC8_POLYNOMIAL
crc8 definition
#define SGP30_COMMAND_GET_SERIAL_ID
#define SGP30_COMMAND_GET_IAQ_BASELINE
#define SGP30_COMMAND_MEASURE_RAW
#define SGP30_COMMAND_SET_TVOC_BASELINE
#define SUPPLY_VOLTAGE_MAX
#define SGP30_ADDRESS
chip address definition
#define SGP30_COMMAND_SET_IAQ_BASELINE
#define SGP30_COMMAND_GET_TVOC_INCEPTIVE_BASELINE
#define MANUFACTURER_NAME
#define SUPPLY_VOLTAGE_MIN
#define SGP30_COMMAND_GET_FEATURE_SET
#define SGP30_COMMAND_MEASURE_TEST
#define CHIP_NAME
chip information definition
#define SGP30_COMMAND_MEASURE_IAQ
#define SGP30_COMMAND_IAQ_INIT
chip command definition
#define SGP30_COMMAND_SET_ABSOLUTE_HUMIDITY
uint8_t sgp30_get_iaq_baseline(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
get the chip iaq baseline
uint8_t sgp30_set_tvoc_baseline(sgp30_handle_t *handle, uint16_t tvoc_baseline)
set the chip tvoc baseline
struct sgp30_handle_s sgp30_handle_t
sgp30 handle structure definition
uint8_t sgp30_init(sgp30_handle_t *handle)
initialize the chip
uint8_t sgp30_absolute_humidity_convert_to_register(sgp30_handle_t *handle, float temp, float rh, uint16_t *reg)
convert the absolute humidity to the register data
uint8_t sgp30_deinit(sgp30_handle_t *handle)
close the chip
struct sgp30_info_s sgp30_info_t
sgp30 information structure definition
uint8_t sgp30_get_serial_id(sgp30_handle_t *handle, uint16_t id[3])
get the chip serial id
uint8_t sgp30_set_iaq_baseline(sgp30_handle_t *handle, uint16_t tvoc, uint16_t co2_eq)
set the chip iaq baseline
uint8_t sgp30_set_absolute_humidity(sgp30_handle_t *handle, uint16_t humidity)
set the chip absolute_humidity
uint8_t sgp30_get_measure_raw(sgp30_handle_t *handle, uint16_t *tvoc, uint16_t *co2_eq)
get the iaq measure raw result
uint8_t sgp30_read(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
read the iaq measure result
uint8_t sgp30_get_feature_set(sgp30_handle_t *handle, uint8_t *product_type, uint8_t *product_version)
get the chip feature
uint8_t sgp30_info(sgp30_info_t *info)
get chip information
uint8_t sgp30_soft_reset(sgp30_handle_t *handle)
soft reset the chip
uint8_t sgp30_measure_test(sgp30_handle_t *handle, uint16_t *result)
run the chip measure test
uint8_t sgp30_measure_iaq(sgp30_handle_t *handle, uint16_t *co2_eq_ppm, uint16_t *tvoc_ppb)
get the iaq measure result
uint8_t sgp30_iaq_init(sgp30_handle_t *handle)
initialize the chip iaq
uint8_t sgp30_get_tvoc_inceptive_baseline(sgp30_handle_t *handle, uint16_t *tvoc_baseline)
get the chip tvoc inceptive baseline
uint8_t sgp30_set_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register
uint8_t sgp30_get_reg(sgp30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
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 supply_voltage_max_v
char manufacturer_name[32]
float supply_voltage_min_v