42 #define CHIP_NAME "Sensirion SPS30"
43 #define MANUFACTURER_NAME "Sensirion"
44 #define SUPPLY_VOLTAGE_MIN 4.50f
45 #define SUPPLY_VOLTAGE_MAX 5.50f
46 #define MAX_CURRENT 80.0f
47 #define TEMPERATURE_MIN -10.0f
48 #define TEMPERATURE_MAX 60.0f
49 #define DRIVER_VERSION 1000
54 #define SPS30_ADDRESS (0x69 << 1)
59 #define SPS30_IIC_COMMAND_START_MEASUREMENT 0x0010U
60 #define SPS30_IIC_COMMAND_STOP_MEASUREMENT 0x0104U
61 #define SPS30_IIC_COMMAND_READ_DATA_READY_FLAG 0x0202U
62 #define SPS30_IIC_COMMAND_READ_MEASURED_VALUES 0x0300U
63 #define SPS30_IIC_COMMAND_SLEEP 0x1001U
64 #define SPS30_IIC_COMMAND_WAKE_UP 0x1103U
65 #define SPS30_IIC_COMMAND_START_FAN_CLEANING 0x5607U
66 #define SPS30_IIC_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL 0x8004U
67 #define SPS30_IIC_COMMAND_READ_PRODUCT_TYPE 0xD002U
68 #define SPS30_IIC_COMMAND_READ_SERIAL_NUMBER 0xD033U
69 #define SPS30_IIC_COMMAND_READ_VERSION 0xD100U
70 #define SPS30_IIC_COMMAND_READ_DEVICE_STATUS_REG 0xD206U
71 #define SPS30_IIC_COMMAND_CLEAR_DEVICE_STATUS_REG 0xD210U
72 #define SPS30_IIC_COMMAND_RESET 0xD304U
73 #define SPS30_UART_COMMAND_START_MEASUREMENT 0x00
74 #define SPS30_UART_COMMAND_STOP_MEASUREMENT 0x01
75 #define SPS30_UART_COMMAND_READ_MEASURED_VALUES 0x03
76 #define SPS30_UART_COMMAND_SLEEP 0x10
77 #define SPS30_UART_COMMAND_WAKE_UP 0x11
78 #define SPS30_UART_COMMAND_START_FAN_CLEANING 0x56
79 #define SPS30_UART_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL 0x80
80 #define SPS30_UART_COMMAND_READ_PRODUCT_TYPE 0xD0
81 #define SPS30_UART_COMMAND_READ_VERSION 0xD1
82 #define SPS30_UART_COMMAND_READ_DEVICE_STATUS_REG 0xD2
83 #define SPS30_UART_COMMAND_RESET 0xD3
93 static uint8_t a_sps30_generate_crc(
sps30_handle_t *handle, uint8_t* data, uint8_t count)
101 for (current_byte = 0; current_byte < count; ++current_byte)
103 crc ^= (data[current_byte]);
104 for (crc_bit = 8; crc_bit > 0; --crc_bit)
106 if ((crc & 0x80) != 0)
108 crc = (crc << 1) ^ 0x31;
124 for (i = 0; i < count; i++)
129 return (uint8_t)(~(crc & 0xFF));
146 static uint8_t a_sps30_iic_read(
sps30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
150 buf[0] = (reg >> 8) & 0xFF;
151 buf[1] = (reg >> 0) & 0xFF;
157 if (handle->
iic_read_cmd(addr, (uint8_t *)data, len) != 0)
178 static uint8_t a_sps30_iic_write(
sps30_handle_t *handle, uint8_t addr, uint16_t reg, uint8_t *data, uint16_t len, uint16_t delay_ms)
186 buf[0] = (reg >> 8) & 0xFF;
187 buf[1] = (reg >> 0) & 0xFF;
188 memcpy((uint8_t *)&buf[2], data, len);
189 if (handle->
iic_write_cmd(addr, (uint8_t *)buf, len + 2) != 0)
209 static uint8_t a_sps30_uart_get_rx_frame(
sps30_handle_t *handle, uint16_t len, uint8_t *output, uint16_t out_len)
213 output[0] = handle->
buf[0];
215 for (i = 1; i < (len - 1); i++)
217 if (point >= (out_len - 1))
221 if (((handle->
buf[i] == 0x7D) && (handle->
buf[i + 1]) == 0x5E) ||
222 ((handle->
buf[i] == 0x7D) && (handle->
buf[i + 1]) == 0x5D) ||
223 ((handle->
buf[i] == 0x7D) && (handle->
buf[i + 1]) == 0x31) ||
224 ((handle->
buf[i] == 0x7D) && (handle->
buf[i + 1]) == 0x33)
227 switch (handle->
buf[i + 1])
231 output[point] = 0x7E;
239 output[point] = 0x7D;
247 output[point] = 0x11;
255 output[point] = 0x13;
269 output[point] = handle->
buf[i];
273 output[point] = handle->
buf[len - 1];
275 if (point != out_len)
294 static uint8_t a_sps30_uart_set_tx_frame(
sps30_handle_t *handle, uint8_t *input, uint16_t in_len, uint16_t *out_len)
298 memset(handle->
buf, 0,
sizeof(uint8_t) * 256);
299 handle->
buf[0] = input[0];
301 for (i = 1; i < (in_len - 1); i++)
303 if ((*out_len) >= 255)
307 if ((input[i] == 0x7E) || (input[i] == 0x7D) ||
308 (input[i] == 0x11) || (input[i] == 0x13)
315 handle->
buf[*out_len] = 0x7D;
317 handle->
buf[*out_len] = 0x5E;
324 handle->
buf[*out_len] = 0x7D;
326 handle->
buf[*out_len] = 0x5D;
333 handle->
buf[*out_len] = 0x7D;
335 handle->
buf[*out_len] = 0x31;
342 handle->
buf[*out_len] = 0x7D;
344 handle->
buf[*out_len] = 0x33;
357 handle->
buf[*out_len] = input[i];
361 handle->
buf[*out_len] = input[in_len - 1];
380 static uint8_t a_sps30_uart_write_read(
sps30_handle_t *handle, uint8_t *input, uint16_t in_len,
381 uint16_t delay_ms, uint8_t *output, uint16_t out_len)
385 if (a_sps30_uart_set_tx_frame(handle, input, in_len, (uint16_t *)&len) != 0)
399 if (a_sps30_uart_get_rx_frame(handle, len, output, out_len) != 0)
414 static uint8_t a_sps30_uart_error(
sps30_handle_t *handle, uint8_t e)
424 handle->
debug_print(
"sps30: wrong data length for this command error.\n");
436 handle->
debug_print(
"sps30: no access right for command.\n");
442 handle->
debug_print(
"sps30: illegal command parameter or parameter "
443 "out of allowed range.\n");
449 handle->
debug_print(
"sps30: internal function argument out of range.\n");
455 handle->
debug_print(
"sps30: command not allowed in current state.\n");
486 handle->
iic_uart = (uint8_t)interface;
538 uint8_t input_buf[6 + 2];
546 input_buf[5] = format;
548 input_buf[6] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 5);
550 memset(out_buf, 0,
sizeof(uint8_t) * 7);
551 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 8, 20, (uint8_t *)out_buf, 7);
554 handle->
debug_print(
"sps30: write read failed.\n");
558 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
564 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
576 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)buf, 2);
580 handle->
debug_print(
"sps30: start measurement failed.\n");
614 uint8_t input_buf[6 + 0];
621 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
623 memset(out_buf, 0,
sizeof(uint8_t) * 7);
624 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 7);
627 handle->
debug_print(
"sps30: write read failed.\n");
631 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
637 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
647 handle->
debug_print(
"sps30: stop measurement failed.\n");
682 handle->
debug_print(
"sps30: uart has no command.\n");
690 memset(buf, 0,
sizeof(uint8_t) * 3);
694 handle->
debug_print(
"sps30: read data ready flag failed.\n");
698 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)buf, 2))
735 uint8_t input_buf[6 + 0];
742 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
744 memset(out_buf, 0,
sizeof(uint8_t) * 7);
745 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 5, (uint8_t *)out_buf, 7);
748 handle->
debug_print(
"sps30: write read failed.\n");
752 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
758 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
802 uint8_t input_buf[6 + 0];
804 uint8_t wake_up = 0xFF;
810 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
812 if (handle->
uart_write((uint8_t *)&wake_up, 1) != 0)
816 memset(out_buf, 0,
sizeof(uint8_t) * 7);
817 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7);
820 handle->
debug_print(
"sps30: write read failed.\n");
824 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
830 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
875 uint8_t input_buf[6 + 0];
882 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
884 memset(out_buf, 0,
sizeof(uint8_t) * 7);
885 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 7);
888 handle->
debug_print(
"sps30: write read failed.\n");
892 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
898 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
908 handle->
debug_print(
"sps30: start the fan cleaning failed.\n");
941 if ((second < 10) || (second > 604800))
943 handle->
debug_print(
"sps30: second is invalid.\n");
950 uint8_t input_buf[6 + 5];
958 input_buf[5] = (second >> 24) & 0xFF;
959 input_buf[6] = (second >> 16) & 0xFF;
960 input_buf[7] = (second >> 8) & 0xFF;
961 input_buf[8] = (second >> 0) & 0xFF;
962 input_buf[9] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 8);
963 input_buf[10] = 0x7E;
964 memset(out_buf, 0,
sizeof(uint8_t) * 7);
965 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 11, 20, (uint8_t *)out_buf, 7);
968 handle->
debug_print(
"sps30: write read failed.\n");
972 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
978 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
987 buf[0] = (second >> 24) & 0xFF;
988 buf[1] = (second >> 16) & 0xFF;
989 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2);
990 buf[3] = (second >> 8) & 0xFF;
991 buf[4] = (second >> 0) & 0xFF;
992 buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2);
994 (uint8_t *)buf, 6, 20);
997 handle->
debug_print(
"sps30: set auto cleaning interval failed.\n");
1032 uint8_t input_buf[6 + 1];
1033 uint8_t out_buf[7 + 4];
1035 input_buf[0] = 0x7E;
1036 input_buf[1] = 0x00;
1038 input_buf[3] = 0x01;
1039 input_buf[4] = 0x00;
1040 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4);
1041 input_buf[6] = 0x7E;
1042 memset(out_buf, 0,
sizeof(uint8_t) * 11);
1043 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 11);
1046 handle->
debug_print(
"sps30: write read failed.\n");
1050 if (out_buf[9] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 8))
1056 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1060 *second = ((uint32_t)out_buf[5] << 24) | ((uint32_t)out_buf[6] << 16) |
1061 ((uint32_t)out_buf[7] << 8) | ((uint32_t)out_buf[8] << 0);
1067 memset(buf, 0,
sizeof(uint8_t) * 6);
1069 (uint8_t *)buf, 6, 20);
1072 handle->
debug_print(
"sps30: get auto cleaning interval failed.\n");
1076 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2))
1082 if (buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2))
1088 *second = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1089 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0);
1121 uint8_t input_buf[6 + 5];
1125 input_buf[0] = 0x7E;
1126 input_buf[1] = 0x00;
1128 input_buf[3] = 0x05;
1129 input_buf[4] = 0x00;
1130 input_buf[5] = (second >> 24) & 0xFF;
1131 input_buf[6] = (second >> 16) & 0xFF;
1132 input_buf[7] = (second >> 8) & 0xFF;
1133 input_buf[8] = (second >> 0) & 0xFF;
1134 input_buf[9] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 8);
1135 input_buf[10] = 0x7E;
1136 memset(out_buf, 0,
sizeof(uint8_t) * 7);
1137 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 11, 20, (uint8_t *)out_buf, 7);
1140 handle->
debug_print(
"sps30: write read failed.\n");
1144 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
1150 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1160 buf[0] = (second >> 24) & 0xFF;
1161 buf[1] = (second >> 16) & 0xFF;
1162 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2);
1163 buf[3] = (second >> 8) & 0xFF;
1164 buf[4] = (second >> 0) & 0xFF;
1165 buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2);
1167 (uint8_t *)buf, 6, 20);
1170 handle->
debug_print(
"sps30: set auto cleaning interval failed.\n");
1205 uint8_t input_buf[6 + 1];
1206 uint8_t out_buf[7 + 9];
1208 input_buf[0] = 0x7E;
1209 input_buf[1] = 0x00;
1211 input_buf[3] = 0x01;
1212 input_buf[4] = 0x00;
1213 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4);
1214 input_buf[6] = 0x7E;
1215 memset(out_buf, 0,
sizeof(uint8_t) * 16);
1216 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 16);
1219 handle->
debug_print(
"sps30: write read failed.\n");
1223 if (out_buf[14] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 13))
1229 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1233 memcpy((uint8_t *)type, (uint8_t *)&out_buf[5], 9);
1239 memset(buf, 0,
sizeof(uint8_t) * 12);
1243 handle->
debug_print(
"sps30: read product type failed.\n");
1247 for (i = 0; i < 4; i++)
1249 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2))
1257 for (i = 0; i < 4; i++)
1259 type[j] = buf[i * 3 + 0];
1261 type[j] = buf[i * 3 + 1];
1296 uint8_t input_buf[6 + 1];
1297 uint8_t out_buf[7 + 17];
1299 input_buf[0] = 0x7E;
1300 input_buf[1] = 0x00;
1302 input_buf[3] = 0x01;
1303 input_buf[4] = 0x03;
1304 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4);
1305 input_buf[6] = 0x7E;
1306 memset(out_buf, 0,
sizeof(uint8_t) * 24);
1307 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 24);
1310 handle->
debug_print(
"sps30: write read failed.\n");
1314 if (out_buf[22] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 21))
1320 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1324 memcpy((uint8_t *)sn, (uint8_t *)&out_buf[5], 17);
1330 memset(buf, 0,
sizeof(uint8_t) * 24);
1334 handle->
debug_print(
"sps30: read serial number failed.\n");
1338 for (i = 0; i < 8; i++)
1340 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2))
1348 for (i = 0; i < 8; i++)
1350 sn[j] = buf[i * 3 + 0];
1352 sn[j] = buf[i * 3 + 1];
1389 uint8_t input_buf[6];
1390 uint8_t out_buf[7 + 7];
1392 input_buf[0] = 0x7E;
1393 input_buf[1] = 0x00;
1395 input_buf[3] = 0x00;
1396 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
1397 input_buf[5] = 0x7E;
1398 memset(out_buf, 0,
sizeof(uint8_t) * 14);
1399 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 14);
1402 handle->
debug_print(
"sps30: write read failed.\n");
1406 if (out_buf[12] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 11))
1412 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1416 *major = out_buf[5];
1417 *minor = out_buf[6];
1421 memset(buf, 0,
sizeof(uint8_t) * 3);
1425 handle->
debug_print(
"sps30: read version failed.\n");
1429 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2))
1468 uint8_t input_buf[6 + 1];
1469 uint8_t out_buf[7 + 5];
1471 input_buf[0] = 0x7E;
1472 input_buf[1] = 0x00;
1474 input_buf[3] = 0x01;
1475 input_buf[4] = 0x00;
1476 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4);
1477 input_buf[6] = 0x7E;
1478 memset(out_buf, 0,
sizeof(uint8_t) * 12);
1479 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 12);
1482 handle->
debug_print(
"sps30: write read failed.\n");
1486 if (out_buf[10] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 9))
1492 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1496 *status = ((uint32_t)out_buf[5] << 24) | ((uint32_t)out_buf[6] << 16) |
1497 ((uint32_t)out_buf[7] << 8) | ((uint32_t)out_buf[8] << 0);
1503 memset(buf, 0,
sizeof(uint8_t) * 6);
1505 (uint8_t *)buf, 6, 20);
1508 handle->
debug_print(
"sps30: get device status failed.\n");
1512 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2))
1518 if (buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2))
1524 *status = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1525 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0);
1556 uint8_t input_buf[6 + 1];
1557 uint8_t out_buf[7 + 5];
1559 input_buf[0] = 0x7E;
1560 input_buf[1] = 0x00;
1562 input_buf[3] = 0x01;
1563 input_buf[4] = 0x01;
1564 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4);
1565 input_buf[6] = 0x7E;
1566 memset(out_buf, 0,
sizeof(uint8_t) * 12);
1567 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 12);
1570 handle->
debug_print(
"sps30: write read failed.\n");
1574 if (out_buf[10] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 9))
1580 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1590 handle->
debug_print(
"sps30: clear device status failed.\n");
1624 uint8_t input_buf[6];
1627 input_buf[0] = 0x7E;
1628 input_buf[1] = 0x00;
1630 input_buf[3] = 0x00;
1631 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
1632 input_buf[5] = 0x7E;
1633 memset(out_buf, 0,
sizeof(uint8_t) * 7);
1634 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7);
1637 handle->
debug_print(
"sps30: write read failed.\n");
1641 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
1647 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1688 if ((handle == NULL) || (pm == NULL))
1701 uint8_t input_buf[6];
1702 uint8_t out_buf[7 + 40];
1704 input_buf[0] = 0x7E;
1705 input_buf[1] = 0x00;
1707 input_buf[3] = 0x00;
1708 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
1709 input_buf[5] = 0x7E;
1710 memset(out_buf, 0,
sizeof(uint8_t) * 47);
1711 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 47);
1714 handle->
debug_print(
"sps30: write read failed.\n");
1718 if (out_buf[45] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 44))
1724 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1728 f.i = (uint32_t)(out_buf[5 + 0]) << 24 | (uint32_t)(out_buf[5 + 1]) << 16 |
1729 (uint32_t)(out_buf[5 + 2]) << 8 | (uint32_t)(out_buf[5 + 3]) << 0;
1731 f.i = (uint32_t)(out_buf[5 + 4]) << 24 | (uint32_t)(out_buf[5 + 5]) << 16 |
1732 (uint32_t)(out_buf[5 + 6]) << 8 | (uint32_t)(out_buf[5 + 7]) << 0;
1734 f.i = (uint32_t)(out_buf[5 + 8]) << 24 | (uint32_t)(out_buf[5 + 9]) << 16 |
1735 (uint32_t)(out_buf[5 + 10]) << 8 | (uint32_t)(out_buf[5 + 11]) << 0;
1737 f.i = (uint32_t)(out_buf[5 + 12]) << 24 | (uint32_t)(out_buf[5 + 13]) << 16 |
1738 (uint32_t)(out_buf[5 + 14]) << 8 | (uint32_t)(out_buf[5 + 15]) << 0;
1740 f.i = (uint32_t)(out_buf[5 + 16]) << 24 | (uint32_t)(out_buf[5 + 17]) << 16 |
1741 (uint32_t)(out_buf[5 + 18]) << 8 | (uint32_t)(out_buf[5 + 19]) << 0;
1743 f.i = (uint32_t)(out_buf[5 + 20]) << 24 | (uint32_t)(out_buf[5 + 21]) << 16 |
1744 (uint32_t)(out_buf[5 + 22]) << 8 | (uint32_t)(out_buf[5 + 23]) << 0;
1746 f.i = (uint32_t)(out_buf[5 + 24]) << 24 | (uint32_t)(out_buf[5 + 25]) << 16 |
1747 (uint32_t)(out_buf[5 + 26]) << 8 | (uint32_t)(out_buf[5 + 27]) << 0;
1749 f.i = (uint32_t)(out_buf[5 + 28]) << 24 | (uint32_t)(out_buf[5 + 29]) << 16 |
1750 (uint32_t)(out_buf[5 + 30]) << 8 | (uint32_t)(out_buf[5 + 31]) << 0;
1752 f.i = (uint32_t)(out_buf[5 + 32]) << 24 | (uint32_t)(out_buf[5 + 33]) << 16 |
1753 (uint32_t)(out_buf[5 + 34]) << 8 | (uint32_t)(out_buf[5 + 35]) << 0;
1755 f.i = (uint32_t)(out_buf[5 + 36]) << 24 | (uint32_t)(out_buf[5 + 37]) << 16 |
1756 (uint32_t)(out_buf[5 + 38]) << 8 | (uint32_t)(out_buf[5 + 39]) << 0;
1761 uint8_t input_buf[6];
1762 uint8_t out_buf[7 + 20];
1764 input_buf[0] = 0x7E;
1765 input_buf[1] = 0x00;
1767 input_buf[3] = 0x00;
1768 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
1769 input_buf[5] = 0x7E;
1770 memset(out_buf, 0,
sizeof(uint8_t) * 27);
1771 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 27);
1774 handle->
debug_print(
"sps30: write read failed.\n");
1778 if (out_buf[25] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 24))
1784 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
1788 pm->
pm1p0_ug_m3 = (float)(((uint16_t)(out_buf[5 + 0]) << 8) | ((uint16_t)(out_buf[5 + 1]) << 0));
1789 pm->
pm2p5_ug_m3 = (float)(((uint16_t)(out_buf[5 + 2]) << 8) | ((uint16_t)(out_buf[5 + 3]) << 0));
1790 pm->
pm4p0_ug_m3 = (float)(((uint16_t)(out_buf[5 + 4]) << 8) | ((uint16_t)(out_buf[5 + 5]) << 0));
1791 pm->
pm10_ug_m3 = (float)(((uint16_t)(out_buf[5 + 6]) << 8) | ((uint16_t)(out_buf[5 + 7]) << 0));
1792 pm->
pm0p5_cm3 = (float)(((uint16_t)(out_buf[5 + 8]) << 8) | ((uint16_t)(out_buf[5 + 9]) << 0));
1793 pm->
pm1p0_cm3 = (float)(((uint16_t)(out_buf[5 + 10]) << 8) | ((uint16_t)(out_buf[5 + 11]) << 0));
1794 pm->
pm2p5_cm3 = (float)(((uint16_t)(out_buf[5 + 12]) << 8) | ((uint16_t)(out_buf[5 + 13]) << 0));
1795 pm->
pm4p0_cm3 = (float)(((uint16_t)(out_buf[5 + 14]) << 8) | ((uint16_t)(out_buf[5 + 15]) << 0));
1796 pm->
pm10_cm3 = (float)(((uint16_t)(out_buf[5 + 16]) << 8) | ((uint16_t)(out_buf[5 + 17]) << 0));
1797 pm->
typical_particle_um = (float)(((uint16_t)(out_buf[5 + 18]) << 8) | ((uint16_t)(out_buf[5 + 19]) << 0));
1811 memset(check, 0,
sizeof(uint8_t) * 3);
1815 handle->
debug_print(
"sps30: read data ready flag failed.\n");
1819 if (check[2] != a_sps30_generate_crc(handle, (uint8_t *)check, 2))
1821 handle->
debug_print(
"sps30: crc check failed.\n");
1825 if ((check[1] & 0x01) == 0)
1836 memset(buf, 0,
sizeof(uint8_t) * 60);
1840 handle->
debug_print(
"sps30: read measured values failed.\n");
1844 for (i = 0; i < 20; i++)
1846 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2))
1853 f.i = (uint32_t)(buf[0]) << 24 | (uint32_t)(buf[1]) << 16 |
1854 (uint32_t)(buf[3]) << 8 | (uint32_t)(buf[4]) << 0;
1856 f.i = (uint32_t)(buf[6]) << 24 | (uint32_t)(buf[7]) << 16 |
1857 (uint32_t)(buf[9]) << 8 | (uint32_t)(buf[10]) << 0;
1859 f.i = (uint32_t)(buf[12]) << 24 | (uint32_t)(buf[13]) << 16 |
1860 (uint32_t)(buf[15]) << 8 | (uint32_t)(buf[16]) << 0;
1862 f.i = (uint32_t)(buf[18]) << 24 | (uint32_t)(buf[19]) << 16 |
1863 (uint32_t)(buf[21]) << 8 | (uint32_t)(buf[22]) << 0;
1865 f.i = (uint32_t)(buf[24]) << 24 | (uint32_t)(buf[25]) << 16 |
1866 (uint32_t)(buf[27]) << 8 | (uint32_t)(buf[28]) << 0;
1868 f.i = (uint32_t)(buf[30]) << 24 | (uint32_t)(buf[31]) << 16 |
1869 (uint32_t)(buf[33]) << 8 | (uint32_t)(buf[34]) << 0;
1871 f.i = (uint32_t)(buf[36]) << 24 | (uint32_t)(buf[37]) << 16 |
1872 (uint32_t)(buf[39]) << 8 | (uint32_t)(buf[40]) << 0;
1874 f.i = (uint32_t)(buf[42]) << 24 | (uint32_t)(buf[43]) << 16 |
1875 (uint32_t)(buf[45]) << 8 | (uint32_t)(buf[46]) << 0;
1877 f.i = (uint32_t)(buf[48]) << 24 | (uint32_t)(buf[49]) << 16 |
1878 (uint32_t)(buf[51]) << 8 | (uint32_t)(buf[52]) << 0;
1880 f.i = (uint32_t)(buf[54]) << 24 | (uint32_t)(buf[55]) << 16 |
1881 (uint32_t)(buf[57]) << 8 | (uint32_t)(buf[58]) << 0;
1888 memset(buf, 0,
sizeof(uint8_t) * 30);
1892 handle->
debug_print(
"sps30: read measured values failed.\n");
1896 for (i = 0; i < 10; i++)
1898 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2))
1905 pm->
pm1p0_ug_m3 = (float)(((uint16_t)(buf[0]) << 8) | ((uint16_t)(buf[1]) << 0));
1906 pm->
pm2p5_ug_m3 = (float)(((uint16_t)(buf[3]) << 8) | ((uint16_t)(buf[4]) << 0));
1907 pm->
pm4p0_ug_m3 = (float)(((uint16_t)(buf[6]) << 8) | ((uint16_t)(buf[7]) << 0));
1908 pm->
pm10_ug_m3 = (float)(((uint16_t)(buf[9]) << 8) | ((uint16_t)(buf[10]) << 0));
1909 pm->
pm0p5_cm3 = (float)(((uint16_t)(buf[12]) << 8) | ((uint16_t)(buf[13]) << 0));
1910 pm->
pm1p0_cm3 = (float)(((uint16_t)(buf[15]) << 8) | ((uint16_t)(buf[16]) << 0));
1911 pm->
pm2p5_cm3 = (float)(((uint16_t)(buf[18]) << 8) | ((uint16_t)(buf[19]) << 0));
1912 pm->
pm4p0_cm3 = (float)(((uint16_t)(buf[21]) << 8) | ((uint16_t)(buf[22]) << 0));
1913 pm->
pm10_cm3 = (float)(((uint16_t)(buf[24]) << 8) | ((uint16_t)(buf[25]) << 0));
1914 pm->
typical_particle_um = (float)(((uint16_t)(buf[27]) << 8) | ((uint16_t)(buf[28]) << 0));
1953 handle->
debug_print(
"sps30: iic_init is null.\n");
1959 handle->
debug_print(
"sps30: iic_deinit is null.\n");
1965 handle->
debug_print(
"sps30: iic_write_cmd is null.\n");
1971 handle->
debug_print(
"sps30: iic_read_cmd is null.\n");
1977 handle->
debug_print(
"sps30: uart_init is null.\n");
1983 handle->
debug_print(
"sps30: uart_deinit is null.\n");
1989 handle->
debug_print(
"sps30: uart_read is null.\n");
1995 handle->
debug_print(
"sps30: uart_write is null.\n");
2001 handle->
debug_print(
"sps30: uart_flush is null.\n");
2007 handle->
debug_print(
"sps30: delay_ms is null.\n");
2014 uint8_t input_buf[6];
2019 handle->
debug_print(
"sps30: uart init failed.\n");
2023 input_buf[0] = 0x7E;
2024 input_buf[1] = 0x00;
2026 input_buf[3] = 0x00;
2027 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
2028 input_buf[5] = 0x7E;
2029 memset(out_buf, 0,
sizeof(uint8_t) * 7);
2030 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7);
2033 handle->
debug_print(
"sps30: write read failed.\n");
2038 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
2045 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
2100 uint8_t input_buf[6];
2103 input_buf[0] = 0x7E;
2104 input_buf[1] = 0x00;
2106 input_buf[3] = 0x00;
2107 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3);
2108 input_buf[5] = 0x7E;
2109 memset(out_buf, 0,
sizeof(uint8_t) * 7);
2110 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7);
2113 handle->
debug_print(
"sps30: write read failed.\n");
2117 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4))
2123 if (a_sps30_uart_error(handle, out_buf[3]) != 0)
2129 handle->
debug_print(
"sps30: uart deinit failed.\n");
2146 handle->
debug_print(
"sps30: iic deinit failed.\n");
2182 return a_sps30_uart_write_read(handle, input, in_len, 20, output, out_len);
2186 handle->
debug_print(
"sps30: iic interface is invalid.\n");
2218 handle->
debug_print(
"sps30: uart interface is invalid.\n");
2224 return a_sps30_iic_write(handle,
SPS30_ADDRESS, reg, buf, len, 20);
2254 handle->
debug_print(
"sps30: uart interface is invalid.\n");
2260 return a_sps30_iic_read(handle,
SPS30_ADDRESS, reg, buf, len, 20);
2282 strncpy(info->
interface,
"UART IIC", 16);
#define SPS30_UART_COMMAND_WAKE_UP
#define SPS30_UART_COMMAND_START_FAN_CLEANING
#define SPS30_IIC_COMMAND_READ_DATA_READY_FLAG
#define SPS30_UART_COMMAND_READ_MEASURED_VALUES
#define SPS30_IIC_COMMAND_CLEAR_DEVICE_STATUS_REG
#define SPS30_UART_COMMAND_SLEEP
#define SPS30_IIC_COMMAND_READ_SERIAL_NUMBER
#define SPS30_IIC_COMMAND_START_MEASUREMENT
chip command definition
#define SPS30_UART_COMMAND_READ_DEVICE_STATUS_REG
#define SPS30_UART_COMMAND_RESET
#define SPS30_UART_COMMAND_STOP_MEASUREMENT
#define SPS30_UART_COMMAND_READ_VERSION
#define SPS30_UART_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL
#define SPS30_UART_COMMAND_START_MEASUREMENT
#define SUPPLY_VOLTAGE_MAX
#define SPS30_IIC_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL
#define SPS30_IIC_COMMAND_SLEEP
#define SPS30_IIC_COMMAND_READ_PRODUCT_TYPE
#define SPS30_IIC_COMMAND_READ_VERSION
#define MANUFACTURER_NAME
#define SUPPLY_VOLTAGE_MIN
#define SPS30_IIC_COMMAND_STOP_MEASUREMENT
#define SPS30_IIC_COMMAND_READ_DEVICE_STATUS_REG
#define SPS30_IIC_COMMAND_RESET
#define SPS30_UART_COMMAND_READ_PRODUCT_TYPE
#define CHIP_NAME
chip information definition
#define SPS30_IIC_COMMAND_WAKE_UP
#define SPS30_IIC_COMMAND_READ_MEASURED_VALUES
#define SPS30_IIC_COMMAND_START_FAN_CLEANING
#define SPS30_ADDRESS
chip address definition
uint8_t sps30_get_interface(sps30_handle_t *handle, sps30_interface_t *interface)
get the chip interface
uint8_t sps30_set_auto_cleaning_interval(sps30_handle_t *handle, uint32_t second)
set the auto cleaning interval
sps30_data_ready_flag_t
sps30 data ready flag enumeration definition
uint8_t sps30_start_fan_cleaning(sps30_handle_t *handle)
start the fan cleaning
uint8_t sps30_get_auto_cleaning_interval(sps30_handle_t *handle, uint32_t *second)
get the auto cleaning interval
uint8_t sps30_read(sps30_handle_t *handle, sps30_pm_t *pm)
read the result
uint8_t sps30_wake_up(sps30_handle_t *handle)
wake up the chip
sps30_interface_t
sps30 interface enumeration definition
uint8_t sps30_start_measurement(sps30_handle_t *handle, sps30_format_t format)
start the measurement
uint8_t sps30_stop_measurement(sps30_handle_t *handle)
stop the measurement
sps30_format_t
sps30 format enumeration definition
uint8_t sps30_get_product_type(sps30_handle_t *handle, char type[9])
get the product type
uint8_t sps30_get_device_status(sps30_handle_t *handle, uint32_t *status)
get the device status
uint8_t sps30_disable_auto_cleaning_interval(sps30_handle_t *handle)
disable the auto cleaning interval
uint8_t sps30_reset(sps30_handle_t *handle)
reset the chip
uint8_t sps30_read_data_flag(sps30_handle_t *handle, sps30_data_ready_flag_t *flag)
read the data read flag
uint8_t sps30_info(sps30_info_t *info)
get chip information
uint8_t sps30_deinit(sps30_handle_t *handle)
close the chip
uint8_t sps30_init(sps30_handle_t *handle)
initialize the chip
uint8_t sps30_sleep(sps30_handle_t *handle)
enter the sleep mode
uint8_t sps30_set_interface(sps30_handle_t *handle, sps30_interface_t interface)
set the chip interface
uint8_t sps30_clear_device_status(sps30_handle_t *handle)
clear the device status
uint8_t sps30_get_version(sps30_handle_t *handle, uint8_t *major, uint8_t *minor)
get the version
uint8_t sps30_get_serial_number(sps30_handle_t *handle, char sn[17])
get the serial number
uint8_t sps30_get_reg_iic(sps30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
get the chip register with iic interface
uint8_t sps30_set_get_reg_uart(sps30_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 sps30_set_reg_iic(sps30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
set the chip register with iic interface
sps30 handle structure definition
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)
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_read_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
uint8_t(* uart_init)(void)
uint8_t(* iic_deinit)(void)
uint8_t(* iic_write_cmd)(uint8_t addr, uint8_t *buf, uint16_t len)
sps30 information structure definition
float supply_voltage_max_v
char manufacturer_name[32]
float supply_voltage_min_v
sps30 pm structure definition
float typical_particle_um