42#define CHIP_NAME "ASAIR APM2000"
43#define MANUFACTURER_NAME "ASAIR"
44#define SUPPLY_VOLTAGE_MIN 4.75f
45#define SUPPLY_VOLTAGE_MAX 5.25f
46#define MAX_CURRENT 100.0f
47#define TEMPERATURE_MIN -10.0f
48#define TEMPERATURE_MAX 50.0f
49#define DRIVER_VERSION 1000
54#define APM2000_ADDRESS (0x08 << 1)
59#define APM2000_REG_START 0x0010U
60#define APM2000_REG_STOP 0x0104U
61#define APM2000_REG_READ 0x0300U
71static uint8_t a_apm2000_generate_crc(
apm2000_handle_t *handle, uint8_t* data, uint8_t count)
79 for (current_byte = 0; current_byte < count; current_byte++)
81 crc ^= (data[current_byte]);
82 for (crc_bit = 8; crc_bit > 0; --crc_bit)
84 if ((crc & 0x80) != 0)
86 crc = (crc << 1) ^ 0x31;
102 for (i = 0; i < count; i++)
107 return (uint8_t)((sum & 0xFF));
122static uint8_t a_apm2000_iic_read(
apm2000_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
143static uint8_t a_apm2000_iic_write(
apm2000_handle_t *handle, uint16_t reg, uint8_t *data, uint16_t len)
166static uint8_t a_apm2000_uart_write_read(
apm2000_handle_t *handle, uint8_t *input, uint16_t in_len,
167 uint16_t delay_ms, uint8_t *output, uint16_t out_len)
180 len = handle->
uart_read(output, out_len);
198static uint16_t a_apm2000_uart_make_frame(
apm2000_handle_t *handle, uint8_t cmd, uint8_t *data, uint8_t len)
200 memset(handle->
buf, 0, 255 + 5);
201 handle->
buf[0] = 0xFE;
202 handle->
buf[1] = 0xA5;
203 handle->
buf[2] = len;
204 handle->
buf[3] = cmd;
207 memcpy(&handle->
buf[4], data, len);
209 handle->
buf[4 + len] = a_apm2000_generate_crc(handle, &handle->
buf[1], len + 3);
211 return (uint16_t)(len + 5);
226static uint8_t a_apm2000_uart_parse_frame(
apm2000_handle_t *handle, uint8_t len, uint8_t *cmd, uint8_t *data, uint8_t *out_len)
234 if (handle->
buf[0] != 0xFE)
236 handle->
debug_print(
"apm2000: header is invalid.\n");
240 if (handle->
buf[1] != 0xA5)
246 if (handle->
buf[2] != 0x02)
248 handle->
debug_print(
"apm2000: length is invalid.\n");
252 crc = a_apm2000_generate_crc(handle, &handle->
buf[1], len - 2);
253 if (crc != handle->
buf[len - 1])
259 *cmd = handle->
buf[3];
260 if ((len - 5) != (*out_len))
262 handle->
debug_print(
"apm2000: output length is invalid.\n");
266 memcpy(data, &handle->
buf[4], (*out_len));
287 handle->
iic_uart = (uint8_t)interface;
337 handle->
debug_print(
"apm2000: uart can't use this function.\n");
352 handle->
debug_print(
"apm2000: start measurement failed.\n");
385 handle->
debug_print(
"apm2000: uart can't use this function.\n");
396 handle->
debug_print(
"apm2000: stop measurement failed.\n");
421 if ((handle == NULL) || (pm == NULL))
437 len = a_apm2000_uart_make_frame(handle, 0x01, NULL, 0);
438 res = a_apm2000_uart_write_read(handle, handle->
buf, len,
439 200, handle->
buf, 11);
442 handle->
debug_print(
"apm2000: uart write read failed.\n");
447 res = a_apm2000_uart_parse_frame(handle, 11, &cmd, data, &out_len);
454 handle->
debug_print(
"apm2000: command is invalid.\n");
458 pm->
pm1p0_ug_m3 = ((uint16_t)data[0]) << 8 | data[1];
459 pm->
pm2p5_ug_m3 = ((uint16_t)data[2]) << 8 | data[3];
460 pm->
pm10_ug_m3 = ((uint16_t)data[4]) << 8 | data[5];
469 handle->
debug_print(
"apm2000: read data failed.\n");
473 if (buf[2] != a_apm2000_generate_crc(handle, (uint8_t *)buf + 0, 2))
475 handle->
debug_print(
"apm2000: crc check failed.\n");
479 if (buf[5] != a_apm2000_generate_crc(handle, (uint8_t *)buf + 3, 2))
481 handle->
debug_print(
"apm2000: crc check failed.\n");
485 if (buf[11] != a_apm2000_generate_crc(handle, (uint8_t *)buf + 9, 2))
487 handle->
debug_print(
"apm2000: crc check failed.\n");
491 pm->
pm1p0_ug_m3 = ((uint16_t)buf[0]) << 8 | buf[1];
492 pm->
pm2p5_ug_m3 = ((uint16_t)buf[3]) << 8 | buf[4];
493 pm->
pm10_ug_m3 = ((uint16_t)buf[9]) << 8 | buf[10];
531 len = a_apm2000_uart_make_frame(handle, 0x00, NULL, 0);
532 res = a_apm2000_uart_write_read(handle, handle->
buf, len,
533 200, handle->
buf, 7);
536 handle->
debug_print(
"apm2000: uart write read failed.\n");
541 res = a_apm2000_uart_parse_frame(handle, 7, &cmd, data, &out_len);
548 handle->
debug_print(
"apm2000: command is invalid.\n");
552 *pm2p5_ug_m3 = ((uint16_t)data[0]) << 8 | data[1];
556 handle->
debug_print(
"apm2000: iic can't use this function.\n");
586 handle->
debug_print(
"apm2000: iic_init is null.\n");
592 handle->
debug_print(
"apm2000: iic_deinit is null.\n");
598 handle->
debug_print(
"apm2000: iic_write_address16 is null.\n");
604 handle->
debug_print(
"apm2000: iic_read_address16 is null.\n");
610 handle->
debug_print(
"apm2000: uart_init is null.\n");
616 handle->
debug_print(
"apm2000: uart_deinit is null.\n");
622 handle->
debug_print(
"apm2000: uart_read is null.\n");
628 handle->
debug_print(
"apm2000: uart_write is null.\n");
634 handle->
debug_print(
"apm2000: uart_flush is null.\n");
640 handle->
debug_print(
"apm2000: delay_ms is null.\n");
649 handle->
debug_print(
"apm2000: uart init failed.\n");
658 handle->
debug_print(
"apm2000: iic init failed.\n");
695 handle->
debug_print(
"apm2000: uart deinit failed.\n");
705 handle->
debug_print(
"apm2000: iic deinit failed.\n");
740 return a_apm2000_uart_write_read(handle, input, in_len, 200, output, out_len);
744 handle->
debug_print(
"apm2000: iic interface is invalid.\n");
776 handle->
debug_print(
"apm2000: uart interface is invalid.\n");
782 return a_apm2000_iic_write(handle, reg, buf, len);
812 handle->
debug_print(
"apm2000: uart interface is invalid.\n");
818 return a_apm2000_iic_read(handle, reg, buf, len);
840 strncpy(info->
interface,
"UART IIC", 16);
#define APM2000_REG_START
chip reg definition
#define APM2000_ADDRESS
chip address definition
#define SUPPLY_VOLTAGE_MAX
#define MANUFACTURER_NAME
#define SUPPLY_VOLTAGE_MIN
#define CHIP_NAME
chip information definition
driver apm2000 header file
uint8_t apm2000_deinit(apm2000_handle_t *handle)
close the chip
struct apm2000_pm_s apm2000_pm_t
apm2000 pm structure definition
uint8_t apm2000_read_pm2p5(apm2000_handle_t *handle, uint16_t *pm2p5_ug_m3)
read pm2.5
uint8_t apm2000_get_interface(apm2000_handle_t *handle, apm2000_interface_t *interface)
get the chip interface
struct apm2000_info_s apm2000_info_t
apm2000 information structure definition
uint8_t apm2000_set_interface(apm2000_handle_t *handle, apm2000_interface_t interface)
set the chip interface
uint8_t apm2000_stop_measurement(apm2000_handle_t *handle)
stop the measurement
struct apm2000_handle_s apm2000_handle_t
apm2000 handle structure definition
uint8_t apm2000_init(apm2000_handle_t *handle)
initialize the chip
apm2000_interface_t
apm2000 interface enumeration definition
uint8_t apm2000_start_measurement(apm2000_handle_t *handle)
start the measurement
uint8_t apm2000_read(apm2000_handle_t *handle, apm2000_pm_t *pm)
read the result
uint8_t apm2000_info(apm2000_info_t *info)
get chip information
uint8_t apm2000_set_get_reg_uart(apm2000_handle_t *handle, uint8_t *input, uint16_t in_len, uint8_t *output, uint16_t out_len)
set and get the chip register with uart interface
uint8_t apm2000_get_reg_iic(apm2000_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
get the chip register with iic interface
uint8_t apm2000_set_reg_iic(apm2000_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register with iic interface
uint8_t(* uart_flush)(void)
uint8_t(* uart_write)(uint8_t *buf, uint16_t len)
void(* delay_ms)(uint32_t ms)
uint8_t(* uart_deinit)(void)
uint8_t(* iic_read_address16)(uint8_t addr, uint16_t reg, uint8_t *buf, uint16_t len)
void(* debug_print)(const char *const fmt,...)
uint8_t(* iic_init)(void)
uint16_t(* uart_read)(uint8_t *buf, uint16_t len)
uint8_t(* iic_write_address16)(uint8_t addr, uint16_t reg, uint8_t *buf, uint16_t len)
uint8_t(* uart_init)(void)
uint8_t(* iic_deinit)(void)
float supply_voltage_max_v
char manufacturer_name[32]
float supply_voltage_min_v