LibDriver SPS30
Loading...
Searching...
No Matches
driver_sps30.c
Go to the documentation of this file.
1
36
37#include "driver_sps30.h"
38
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
50
54#define SPS30_ADDRESS (0x69 << 1)
55
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
84
93static uint8_t a_sps30_generate_crc(sps30_handle_t *handle, uint8_t* data, uint8_t count)
94{
95 if (handle->iic_uart == SPS30_INTERFACE_IIC)
96 {
97 uint8_t current_byte;
98 uint8_t crc = 0xFF;
99 uint8_t crc_bit;
100
101 for (current_byte = 0; current_byte < count; ++current_byte) /* calculate crc */
102 {
103 crc ^= (data[current_byte]); /* xor data */
104 for (crc_bit = 8; crc_bit > 0; --crc_bit) /* 8 bit */
105 {
106 if ((crc & 0x80) != 0) /* if 7th bit is 1 */
107 {
108 crc = (crc << 1) ^ 0x31; /* xor */
109 }
110 else
111 {
112 crc = crc << 1; /* left shift 1 */
113 }
114 }
115 }
116
117 return crc; /* return crc */
118 }
119 else
120 {
121 uint8_t i;
122 uint32_t crc = 0x00;
123
124 for (i = 0; i < count; i++) /* sum */
125 {
126 crc += data[i]; /* sum */
127 }
128
129 return (uint8_t)(~(crc & 0xFF)); /* take the least significant byte of the result and invert it */
130 }
131}
132
146static 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)
147{
148 uint8_t buf[2];
149
150 buf[0] = (reg >> 8) & 0xFF; /* set msb */
151 buf[1] = (reg >> 0) & 0xFF; /* set lsb */
152 if (handle->iic_write_cmd(addr, (uint8_t *)buf, 2) != 0) /* write data */
153 {
154 return 1; /* return error */
155 }
156 handle->delay_ms(delay_ms); /* delay ms */
157 if (handle->iic_read_cmd(addr, (uint8_t *)data, len) != 0) /* read data */
158 {
159 return 1; /* return error */
160 }
161
162 return 0; /* success return 0 */
163}
164
178static 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)
179{
180 uint8_t buf[16];
181
182 if (len > 14) /* check length */
183 {
184 return 1; /* return error */
185 }
186 buf[0] = (reg >> 8) & 0xFF; /* set msb */
187 buf[1] = (reg >> 0) & 0xFF; /* set lsb */
188 memcpy((uint8_t *)&buf[2], data, len); /* copy data */
189 if (handle->iic_write_cmd(addr, (uint8_t *)buf, len + 2) != 0) /* write data */
190 {
191 return 1; /* return error */
192 }
193 handle->delay_ms(delay_ms); /* delay ms */
194
195 return 0; /* success return 0 */
196}
197
209static uint8_t a_sps30_uart_get_rx_frame(sps30_handle_t *handle, uint16_t len, uint8_t *output, uint16_t out_len)
210{
211 uint16_t i, point;
212
213 output[0] = handle->buf[0]; /* set buf[0] */
214 point = 1; /* set point 1 */
215 for (i = 1; i < (len - 1); i++) /* run n -2 times */
216 {
217 if (point >= (out_len - 1)) /* check length */
218 {
219 return 1; /* return error */
220 }
221 if (((handle->buf[i] == 0x7D) && (handle->buf[i + 1]) == 0x5E) || /* check buffer */
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)
225 )
226 {
227 switch (handle->buf[i + 1]) /* judge */
228 {
229 case 0x5E : /* 0x5E */
230 {
231 output[point] = 0x7E; /* set output */
232 point++; /* point++ */
233 i++; /* i++ */
234
235 break; /* break */
236 }
237 case 0x5D : /* 0x5D */
238 {
239 output[point] = 0x7D; /* set output */
240 point++; /* point++ */
241 i++; /* i++ */
242
243 break; /* break */
244 }
245 case 0x31 : /* 0x31 */
246 {
247 output[point] = 0x11; /* set output */
248 point++; /* point++ */
249 i++; /* i++ */
250
251 break; /* break */
252 }
253 case 0x33 : /* 0x33 */
254 {
255 output[point] = 0x13; /* set output */
256 point++; /* point++ */
257 i++; /* i++ */
258
259 break; /* break */
260 }
261 default :
262 {
263 break; /* break */
264 }
265 }
266 }
267 else
268 {
269 output[point] = handle->buf[i]; /* set output */
270 point++; /* point++ */
271 }
272 }
273 output[point] = handle->buf[len - 1]; /* set the end part */
274 point++; /* point++ */
275 if (point != out_len) /* check point */
276 {
277 return 1; /* return error */
278 }
279
280 return 0; /* success return 0 */
281}
282
294static uint8_t a_sps30_uart_set_tx_frame(sps30_handle_t *handle, uint8_t *input, uint16_t in_len, uint16_t *out_len)
295{
296 uint16_t i;
297
298 memset(handle->buf, 0, sizeof(uint8_t) * 256); /* clear buffer */
299 handle->buf[0] = input[0]; /* set buf[0] */
300 *out_len = 1; /* set output length */
301 for (i = 1; i < (in_len - 1); i++)
302 {
303 if ((*out_len) >= 255) /* check output length */
304 {
305 return 1; /* return error */
306 }
307 if ((input[i] == 0x7E) || (input[i] == 0x7D) || /* check data */
308 (input[i] == 0x11) || (input[i] == 0x13)
309 )
310 {
311 switch (input[i]) /* judge input */
312 {
313 case 0x7E : /* 0x7E */
314 {
315 handle->buf[*out_len] = 0x7D; /* 0x7D */
316 (*out_len)++; /* output length++ */
317 handle->buf[*out_len] = 0x5E; /* 0x5E */
318 (*out_len)++; /* output length++ */
319
320 break; /* break */
321 }
322 case 0x7D : /* 0x7D */
323 {
324 handle->buf[*out_len] = 0x7D; /* set 0x7D */
325 (*out_len)++; /* output length++ */
326 handle->buf[*out_len] = 0x5D; /* set 0x5D */
327 (*out_len)++; /* output length++ */
328
329 break; /* break */
330 }
331 case 0x11 : /* 0x11 */
332 {
333 handle->buf[*out_len] = 0x7D; /* set 0x7D */
334 (*out_len)++; /* output length++ */
335 handle->buf[*out_len] = 0x31; /* set 0x31 */
336 (*out_len)++; /* output length++ */
337
338 break; /* break */
339 }
340 case 0x13 : /* 0x13 */
341 {
342 handle->buf[*out_len] = 0x7D; /* set 0x7D */
343 (*out_len)++; /* output length++ */
344 handle->buf[*out_len] = 0x33; /* set 0x33 */
345 (*out_len)++; /* output length++ */
346
347 break; /* break */
348 }
349 default :
350 {
351 break; /* break */
352 }
353 }
354 }
355 else
356 {
357 handle->buf[*out_len] = input[i]; /* set the buffer */
358 (*out_len)++; /* output length++ */
359 }
360 }
361 handle->buf[*out_len] = input[in_len - 1];
362 (*out_len)++; /* copy the end frame */
363
364 return 0; /* success return 0 */
365}
366
380static 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)
382{
383 uint16_t len;
384
385 if (a_sps30_uart_set_tx_frame(handle, input, in_len, (uint16_t *)&len) != 0) /* set tx frame */
386 {
387 return 1; /* return error */
388 }
389 if (handle->uart_flush() != 0) /* uart flush */
390 {
391 return 1; /* return error */
392 }
393 if (handle->uart_write(handle->buf, len) != 0) /* write data */
394 {
395 return 1; /* return error */
396 }
397 handle->delay_ms(delay_ms); /* delay ms */
398 len = handle->uart_read(handle->buf, 256); /* read data */
399 if (a_sps30_uart_get_rx_frame(handle, len, output, out_len) != 0) /* get rx frame */
400 {
401 return 1; /* return error */
402 }
403
404 return 0; /* success return 0 */
405}
406
414static uint8_t a_sps30_uart_error(sps30_handle_t *handle, uint8_t e)
415{
416 switch (e)
417 {
418 case 0x00 :
419 {
420 break;
421 }
422 case 0x01 :
423 {
424 handle->debug_print("sps30: wrong data length for this command error.\n"); /* wrong data length for this command error */
425
426 break;
427 }
428 case 0x02 :
429 {
430 handle->debug_print("sps30: unknown command.\n"); /* unknown command */
431
432 break;
433 }
434 case 0x03 :
435 {
436 handle->debug_print("sps30: no access right for command.\n"); /* no access right for command */
437
438 break;
439 }
440 case 0x04 :
441 {
442 handle->debug_print("sps30: illegal command parameter or parameter "
443 "out of allowed range.\n"); /* illegal command parameter or parameter out of allowed range */
444
445 break;
446 }
447 case 0x28 :
448 {
449 handle->debug_print("sps30: internal function argument out of range.\n"); /* internal function argument out of range */
450
451 break;
452 }
453 case 0x43 :
454 {
455 handle->debug_print("sps30: command not allowed in current state.\n"); /* command not allowed in current state */
456
457 break;
458 }
459 default :
460 {
461 handle->debug_print("sps30: unknown code.\n"); /* unknown code */
462
463 break;
464 }
465 }
466
467 return e; /* return error code */
468}
469
480{
481 if (handle == NULL) /* check handle */
482 {
483 return 2; /* return error */
484 }
485
486 handle->iic_uart = (uint8_t)interface; /* set interface */
487
488 return 0; /* success return 0 */
489}
490
501{
502 if (handle == NULL) /* check handle */
503 {
504 return 2; /* return error */
505 }
506
507 *interface = (sps30_interface_t)(handle->iic_uart); /* get interface */
508
509 return 0; /* success return 0 */
510}
511
524{
525 uint8_t res;
526
527 if (handle == NULL) /* check handle */
528 {
529 return 2; /* return error */
530 }
531 if (handle->inited != 1) /* check handle initialization */
532 {
533 return 3; /* return error */
534 }
535
536 if (handle->iic_uart != 0) /* uart */
537 {
538 uint8_t input_buf[6 + 2];
539 uint8_t out_buf[7];
540
541 input_buf[0] = 0x7E; /* set start */
542 input_buf[1] = 0x00; /* set addr */
543 input_buf[2] = SPS30_UART_COMMAND_START_MEASUREMENT; /* set command */
544 input_buf[3] = 0x02; /* set length */
545 input_buf[4] = 0x01; /* set 0x01 */
546 input_buf[5] = format; /* set format */
547 handle->format = format; /* save format */
548 input_buf[6] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 5); /* set crc */
549 input_buf[7] = 0x7E; /* set stop */
550 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
551 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 8, 20, (uint8_t *)out_buf, 7); /* write read frame */
552 if (res != 0) /* check result */
553 {
554 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
555
556 return 1; /* return error */
557 }
558 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
559 {
560 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
561
562 return 1; /* return error */
563 }
564 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
565 {
566 return 1; /* return error */
567 }
568 }
569 else /* iic */
570 {
571 uint8_t buf[3];
572
573 buf[0] = format; /* set format */
574 handle->format = format; /* save format */
575 buf[1] = 0x00; /* set dummy */
576 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)buf, 2); /* generate crc */
577 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_START_MEASUREMENT, (uint8_t *)buf, 3, 20); /* start measurement command */
578 if (res != 0) /* check result */
579 {
580 handle->debug_print("sps30: start measurement failed.\n"); /* start measurement failed */
581
582 return 1; /* return error */
583 }
584 }
585
586 return 0; /* success return 0 */
587}
588
600{
601 uint8_t res;
602
603 if (handle == NULL) /* check handle */
604 {
605 return 2; /* return error */
606 }
607 if (handle->inited != 1) /* check handle initialization */
608 {
609 return 3; /* return error */
610 }
611
612 if (handle->iic_uart != 0) /* uart */
613 {
614 uint8_t input_buf[6 + 0];
615 uint8_t out_buf[7];
616
617 input_buf[0] = 0x7E; /* set start */
618 input_buf[1] = 0x00; /* set addr */
619 input_buf[2] = SPS30_UART_COMMAND_STOP_MEASUREMENT; /* set command */
620 input_buf[3] = 0x00; /* set length */
621 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
622 input_buf[5] = 0x7E; /* set stop */
623 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
624 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 7); /* write read frame */
625 if (res != 0) /* check result */
626 {
627 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
628
629 return 1; /* return error */
630 }
631 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
632 {
633 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
634
635 return 1; /* return error */
636 }
637 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
638 {
639 return 1; /* return error */
640 }
641 }
642 else /* iic */
643 {
644 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_STOP_MEASUREMENT, NULL, 0, 20); /* stop measurement command */
645 if (res != 0) /* check result */
646 {
647 handle->debug_print("sps30: stop measurement failed.\n"); /* stop measurement failed */
648
649 return 1; /* return error */
650 }
651 }
652
653 return 0; /* success return 0 */
654}
655
668{
669 uint8_t res;
670
671 if (handle == NULL) /* check handle */
672 {
673 return 2; /* return error */
674 }
675 if (handle->inited != 1) /* check handle initialization */
676 {
677 return 3; /* return error */
678 }
679
680 if (handle->iic_uart != 0) /* uart */
681 {
682 handle->debug_print("sps30: uart has no command.\n"); /* uart has no command */
683
684 return 1; /* return error */
685 }
686 else /* iic */
687 {
688 uint8_t buf[3];
689
690 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
691 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_DATA_READY_FLAG, (uint8_t *)buf, 3, 20); /* read data ready flag command */
692 if (res != 0) /* check result */
693 {
694 handle->debug_print("sps30: read data ready flag failed.\n"); /* read data ready flag failed */
695
696 return 1; /* return error */
697 }
698 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)buf, 2)) /* check crc */
699 {
700 handle->debug_print("sps30: crc check failed.\n"); /* crc check failed */
701
702 return 1; /* return error */
703 }
704 *flag = (sps30_data_ready_flag_t)(buf[1] & 0x01); /* get the data ready flag */
705 }
706
707 return 0; /* success return 0 */
708}
709
721{
722 uint8_t res;
723
724 if (handle == NULL) /* check handle */
725 {
726 return 2; /* return error */
727 }
728 if (handle->inited != 1) /* check handle initialization */
729 {
730 return 3; /* return error */
731 }
732
733 if (handle->iic_uart != 0) /* uart */
734 {
735 uint8_t input_buf[6 + 0];
736 uint8_t out_buf[7];
737
738 input_buf[0] = 0x7E; /* set start */
739 input_buf[1] = 0x00; /* set addr */
740 input_buf[2] = SPS30_UART_COMMAND_SLEEP; /* set command */
741 input_buf[3] = 0x00; /* set length */
742 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
743 input_buf[5] = 0x7E; /* set stop */
744 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
745 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 5, (uint8_t *)out_buf, 7); /* write read frame */
746 if (res != 0) /* check result */
747 {
748 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
749
750 return 1; /* return error */
751 }
752 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
753 {
754 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
755
756 return 1; /* return error */
757 }
758 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
759 {
760 return 1; /* return error */
761 }
762 }
763 else /* iic */
764 {
765 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_SLEEP, NULL, 0, 5); /* sleep command */
766 if (res != 0) /* check result */
767 {
768 handle->debug_print("sps30: sleep failed.\n"); /* sleep failed */
769
770 return 1; /* return error */
771 }
772 }
773
774 return 0; /* success return 0 */
775}
776
788{
789 uint8_t res;
790
791 if (handle == NULL) /* check handle */
792 {
793 return 2; /* return error */
794 }
795 if (handle->inited != 1) /* check handle initialization */
796 {
797 return 3; /* return error */
798 }
799
800 if (handle->iic_uart != 0) /* uart */
801 {
802 uint8_t input_buf[6 + 0];
803 uint8_t out_buf[7];
804 uint8_t wake_up = 0xFF;
805
806 input_buf[0] = 0x7E; /* set start */
807 input_buf[1] = 0x00; /* set addr */
808 input_buf[2] = SPS30_UART_COMMAND_WAKE_UP; /* set command */
809 input_buf[3] = 0x00; /* set length */
810 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
811 input_buf[5] = 0x7E; /* set stop */
812 if (handle->uart_write((uint8_t *)&wake_up, 1) != 0) /* write data */
813 {
814 return 1; /* return error */
815 }
816 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
817 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7); /* write read frame */
818 if (res != 0) /* check result */
819 {
820 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
821
822 return 1; /* return error */
823 }
824 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
825 {
826 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
827
828 return 1; /* return error */
829 }
830 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
831 {
832 return 1; /* return error */
833 }
834 }
835 else /* iic */
836 {
837 (void)a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_WAKE_UP, NULL, 0, 0); /* wake up command */
838 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_WAKE_UP, NULL, 0, 100); /* wake up command */
839 if (res != 0) /* check result */
840 {
841 handle->debug_print("sps30: wake up failed.\n"); /* wake up failed */
842
843 return 1; /* return error */
844 }
845 }
846
847 return 0; /* success return 0 */
848}
849
861{
862 uint8_t res;
863
864 if (handle == NULL) /* check handle */
865 {
866 return 2; /* return error */
867 }
868 if (handle->inited != 1) /* check handle initialization */
869 {
870 return 3; /* return error */
871 }
872
873 if (handle->iic_uart != 0) /* uart */
874 {
875 uint8_t input_buf[6 + 0];
876 uint8_t out_buf[7];
877
878 input_buf[0] = 0x7E; /* set start */
879 input_buf[1] = 0x00; /* set addr */
880 input_buf[2] = SPS30_UART_COMMAND_START_FAN_CLEANING; /* set command */
881 input_buf[3] = 0x00; /* set length */
882 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
883 input_buf[5] = 0x7E; /* set stop */
884 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
885 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 7); /* write read frame */
886 if (res != 0) /* check result */
887 {
888 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
889
890 return 1; /* return error */
891 }
892 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
893 {
894 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
895
896 return 1; /* return error */
897 }
898 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
899 {
900 return 1; /* return error */
901 }
902 }
903 else /* iic */
904 {
905 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_START_FAN_CLEANING, NULL, 0, 20); /* start the fan cleaning command */
906 if (res != 0) /* check result */
907 {
908 handle->debug_print("sps30: start the fan cleaning failed.\n"); /* start the fan cleaning failed */
909
910 return 1; /* return error */
911 }
912 }
913
914 return 0; /* success return 0 */
915}
916
929uint8_t sps30_set_auto_cleaning_interval(sps30_handle_t *handle, uint32_t second)
930{
931 uint8_t res;
932
933 if (handle == NULL) /* check handle */
934 {
935 return 2; /* return error */
936 }
937 if (handle->inited != 1) /* check handle initialization */
938 {
939 return 3; /* return error */
940 }
941 if ((second < 10) || (second > 604800)) /* check second */
942 {
943 handle->debug_print("sps30: second is invalid.\n"); /* second is invalid */
944
945 return 4; /* return error */
946 }
947
948 if (handle->iic_uart != 0) /* uart */
949 {
950 uint8_t input_buf[6 + 5];
951 uint8_t out_buf[7];
952
953 input_buf[0] = 0x7E; /* set start */
954 input_buf[1] = 0x00; /* set addr */
955 input_buf[2] = SPS30_UART_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL; /* set command */
956 input_buf[3] = 0x05; /* set length */
957 input_buf[4] = 0x00; /* set 0x00 */
958 input_buf[5] = (second >> 24) & 0xFF; /* set 32 - 24 bits */
959 input_buf[6] = (second >> 16) & 0xFF; /* set 24 - 16 bits */
960 input_buf[7] = (second >> 8) & 0xFF; /* set 16 - 8 bits */
961 input_buf[8] = (second >> 0) & 0xFF; /* set 8 - 0 bits */
962 input_buf[9] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 8); /* set crc */
963 input_buf[10] = 0x7E; /* set stop */
964 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
965 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 11, 20, (uint8_t *)out_buf, 7); /* write read frame */
966 if (res != 0) /* check result */
967 {
968 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
969
970 return 1; /* return error */
971 }
972 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
973 {
974 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
975
976 return 1; /* return error */
977 }
978 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
979 {
980 return 1; /* return error */
981 }
982 }
983 else /* iic */
984 {
985 uint8_t buf[6];
986
987 buf[0] = (second >> 24) & 0xFF; /* set byte 4 */
988 buf[1] = (second >> 16) & 0xFF; /* set byte 3 */
989 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2); /* set crc */
990 buf[3] = (second >> 8) & 0xFF; /* set byte 2 */
991 buf[4] = (second >> 0) & 0xFF; /* set byte 1 */
992 buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2); /* set crc */
994 (uint8_t *)buf, 6, 20); /* set auto cleaning interval command */
995 if (res != 0) /* check result */
996 {
997 handle->debug_print("sps30: set auto cleaning interval failed.\n"); /* set auto cleaning interval failed */
998
999 return 1; /* return error */
1000 }
1001 }
1002
1003 return 0; /* success return 0 */
1004}
1005
1017uint8_t sps30_get_auto_cleaning_interval(sps30_handle_t *handle, uint32_t *second)
1018{
1019 uint8_t res;
1020
1021 if (handle == NULL) /* check handle */
1022 {
1023 return 2; /* return error */
1024 }
1025 if (handle->inited != 1) /* check handle initialization */
1026 {
1027 return 3; /* return error */
1028 }
1029
1030 if (handle->iic_uart != 0) /* uart */
1031 {
1032 uint8_t input_buf[6 + 1];
1033 uint8_t out_buf[7 + 4];
1034
1035 input_buf[0] = 0x7E; /* set start */
1036 input_buf[1] = 0x00; /* set addr */
1037 input_buf[2] = SPS30_UART_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL; /* set command */
1038 input_buf[3] = 0x01; /* set length */
1039 input_buf[4] = 0x00; /* set length */
1040 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4); /* set crc */
1041 input_buf[6] = 0x7E; /* set stop */
1042 memset(out_buf, 0, sizeof(uint8_t) * 11); /* clear the buffer */
1043 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 11); /* write read frame */
1044 if (res != 0) /* check result */
1045 {
1046 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1047
1048 return 1; /* return error */
1049 }
1050 if (out_buf[9] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 8)) /* check crc */
1051 {
1052 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1053
1054 return 1; /* return error */
1055 }
1056 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1057 {
1058 return 1; /* return error */
1059 }
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); /* get second */
1062 }
1063 else /* iic */
1064 {
1065 uint8_t buf[6];
1066
1067 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
1069 (uint8_t *)buf, 6, 20); /* get auto cleaning interval command */
1070 if (res != 0) /* check result */
1071 {
1072 handle->debug_print("sps30: get auto cleaning interval failed.\n"); /* get auto cleaning interval failed */
1073
1074 return 1; /* return error */
1075 }
1076 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2)) /* check crc */
1077 {
1078 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1079
1080 return 1; /* return error */
1081 }
1082 if (buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2)) /* check crc */
1083 {
1084 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1085
1086 return 1; /* return error */
1087 }
1088 *second = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1089 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* get second */
1090 }
1091
1092 return 0; /* success return 0 */
1093}
1094
1106{
1107 uint8_t res;
1108 uint32_t second;
1109
1110 if (handle == NULL) /* check handle */
1111 {
1112 return 2; /* return error */
1113 }
1114 if (handle->inited != 1) /* check handle initialization */
1115 {
1116 return 3; /* return error */
1117 }
1118
1119 if (handle->iic_uart != 0) /* uart */
1120 {
1121 uint8_t input_buf[6 + 5];
1122 uint8_t out_buf[7];
1123
1124 second = 0; /* disable second */
1125 input_buf[0] = 0x7E; /* set start */
1126 input_buf[1] = 0x00; /* set addr */
1127 input_buf[2] = SPS30_UART_COMMAND_READ_WRITE_AUTO_CLEANING_INTERVAL; /* set command */
1128 input_buf[3] = 0x05; /* set length */
1129 input_buf[4] = 0x00; /* set length */
1130 input_buf[5] = (second >> 24) & 0xFF; /* set 32 - 24 bits */
1131 input_buf[6] = (second >> 16) & 0xFF; /* set 24 - 16 bits */
1132 input_buf[7] = (second >> 8) & 0xFF; /* set 16 - 8 bits */
1133 input_buf[8] = (second >> 0) & 0xFF; /* set 8 - 0 bits */
1134 input_buf[9] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 8); /* set crc */
1135 input_buf[10] = 0x7E; /* set stop */
1136 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
1137 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 11, 20, (uint8_t *)out_buf, 7); /* write read frame */
1138 if (res != 0) /* check result */
1139 {
1140 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1141
1142 return 1; /* return error */
1143 }
1144 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
1145 {
1146 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1147
1148 return 1; /* return error */
1149 }
1150 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1151 {
1152 return 1; /* return error */
1153 }
1154 }
1155 else /* iic */
1156 {
1157 uint8_t buf[6];
1158
1159 second = 0; /* disable second */
1160 buf[0] = (second >> 24) & 0xFF; /* set byte 4 */
1161 buf[1] = (second >> 16) & 0xFF; /* set byte 3 */
1162 buf[2] = a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2); /* set crc */
1163 buf[3] = (second >> 8) & 0xFF; /* set byte 2 */
1164 buf[4] = (second >> 0) & 0xFF; /* set byte 1 */
1165 buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2); /* set crc */
1167 (uint8_t *)buf, 6, 20); /* set auto cleaning interval command */
1168 if (res != 0) /* check result */
1169 {
1170 handle->debug_print("sps30: set auto cleaning interval failed.\n"); /* set auto cleaning interval failed */
1171
1172 return 1; /* return error */
1173 }
1174 }
1175
1176 return 0; /* success return 0 */
1177}
1178
1190uint8_t sps30_get_product_type(sps30_handle_t *handle, char type[9])
1191{
1192 uint8_t res, i, j;
1193
1194 if (handle == NULL) /* check handle */
1195 {
1196 return 2; /* return error */
1197 }
1198 if (handle->inited != 1) /* check handle initialization */
1199 {
1200 return 3; /* return error */
1201 }
1202
1203 if (handle->iic_uart != 0) /* uart */
1204 {
1205 uint8_t input_buf[6 + 1];
1206 uint8_t out_buf[7 + 9];
1207
1208 input_buf[0] = 0x7E; /* set start */
1209 input_buf[1] = 0x00; /* set addr */
1210 input_buf[2] = SPS30_UART_COMMAND_READ_PRODUCT_TYPE; /* set command */
1211 input_buf[3] = 0x01; /* set length */
1212 input_buf[4] = 0x00; /* set length */
1213 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4); /* set crc */
1214 input_buf[6] = 0x7E; /* set stop */
1215 memset(out_buf, 0, sizeof(uint8_t) * 16); /* clear the buffer */
1216 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 16); /* write read frame */
1217 if (res != 0) /* check result */
1218 {
1219 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1220
1221 return 1; /* return error */
1222 }
1223 if (out_buf[14] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 13)) /* check crc */
1224 {
1225 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1226
1227 return 1; /* return error */
1228 }
1229 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1230 {
1231 return 1; /* return error */
1232 }
1233 memcpy((uint8_t *)type, (uint8_t *)&out_buf[5], 9); /* copy data*/
1234 }
1235 else /* iic */
1236 {
1237 uint8_t buf[12];
1238
1239 memset(buf, 0, sizeof(uint8_t) * 12); /* clear the buffer */
1240 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_PRODUCT_TYPE, (uint8_t *)buf, 12, 20); /* read product type command */
1241 if (res != 0) /* check result */
1242 {
1243 handle->debug_print("sps30: read product type failed.\n"); /* read product type failed */
1244
1245 return 1; /* return error */
1246 }
1247 for (i = 0; i < 4; i++) /* check crc */
1248 {
1249 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2)) /* check crc */
1250 {
1251 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1252
1253 return 1; /* return error */
1254 }
1255 }
1256 j = 0; /* set zero */
1257 for (i = 0; i < 4; i++) /* copy type */
1258 {
1259 type[j] = buf[i * 3 + 0]; /* set type */
1260 j++; /* j++ */
1261 type[j] = buf[i * 3 + 1]; /* set type */
1262 j++; /* j++ */
1263 }
1264 type[j] = 0; /* set type */
1265 }
1266
1267 return 0; /* success return 0 */
1268}
1269
1281uint8_t sps30_get_serial_number(sps30_handle_t *handle, char sn[17])
1282{
1283 uint8_t res, i, j;
1284
1285 if (handle == NULL) /* check handle */
1286 {
1287 return 2; /* return error */
1288 }
1289 if (handle->inited != 1) /* check handle initialization */
1290 {
1291 return 3; /* return error */
1292 }
1293
1294 if (handle->iic_uart != 0) /* uart */
1295 {
1296 uint8_t input_buf[6 + 1];
1297 uint8_t out_buf[7 + 17];
1298
1299 input_buf[0] = 0x7E; /* set start */
1300 input_buf[1] = 0x00; /* set addr */
1301 input_buf[2] = SPS30_UART_COMMAND_READ_PRODUCT_TYPE; /* set command */
1302 input_buf[3] = 0x01; /* set length */
1303 input_buf[4] = 0x03; /* set command */
1304 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4); /* set crc */
1305 input_buf[6] = 0x7E; /* set stop */
1306 memset(out_buf, 0, sizeof(uint8_t) * 24); /* clear the buffer */
1307 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 24); /* write read frame */
1308 if (res != 0) /* check result */
1309 {
1310 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1311
1312 return 1; /* return error */
1313 }
1314 if (out_buf[22] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 21)) /* check crc */
1315 {
1316 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1317
1318 return 1; /* return error */
1319 }
1320 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1321 {
1322 return 1; /* return error */
1323 }
1324 memcpy((uint8_t *)sn, (uint8_t *)&out_buf[5], 17); /* copy data*/
1325 }
1326 else /* iic */
1327 {
1328 uint8_t buf[24];
1329
1330 memset(buf, 0, sizeof(uint8_t) * 24); /* clear the buffer */
1331 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_SERIAL_NUMBER, (uint8_t *)buf, 24, 20); /* read serial number command */
1332 if (res != 0) /* check result */
1333 {
1334 handle->debug_print("sps30: read serial number failed.\n"); /* read serial number failed */
1335
1336 return 1; /* return error */
1337 }
1338 for (i = 0; i < 8; i++) /* check crc */
1339 {
1340 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2)) /* check crc */
1341 {
1342 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1343
1344 return 1; /* return error */
1345 }
1346 }
1347 j = 0; /* set zero */
1348 for (i = 0; i < 8; i++) /* copy serial number */
1349 {
1350 sn[j] = buf[i * 3 + 0]; /* set serial number */
1351 j++; /* j++ */
1352 sn[j] = buf[i * 3 + 1]; /* set serial number */
1353 j++; /* j++ */
1354 }
1355 sn[j] = 0; /* set NULL */
1356 }
1357
1358 return 0; /* success return 0 */
1359}
1360
1373uint8_t sps30_get_version(sps30_handle_t *handle, uint8_t *major, uint8_t *minor)
1374{
1375 uint8_t res;
1376 uint8_t buf[3];
1377
1378 if (handle == NULL) /* check handle */
1379 {
1380 return 2; /* return error */
1381 }
1382 if (handle->inited != 1) /* check handle initialization */
1383 {
1384 return 3; /* return error */
1385 }
1386
1387 if (handle->iic_uart != 0) /* uart */
1388 {
1389 uint8_t input_buf[6];
1390 uint8_t out_buf[7 + 7];
1391
1392 input_buf[0] = 0x7E; /* set start */
1393 input_buf[1] = 0x00; /* set addr */
1394 input_buf[2] = SPS30_UART_COMMAND_READ_VERSION; /* set command */
1395 input_buf[3] = 0x00; /* set length */
1396 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
1397 input_buf[5] = 0x7E; /* set stop */
1398 memset(out_buf, 0, sizeof(uint8_t) * 14); /* clear the buffer */
1399 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 14); /* write read frame */
1400 if (res != 0) /* check result */
1401 {
1402 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1403
1404 return 1; /* return error */
1405 }
1406 if (out_buf[12] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 11)) /* check crc */
1407 {
1408 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1409
1410 return 1; /* return error */
1411 }
1412 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1413 {
1414 return 1; /* return error */
1415 }
1416 *major = out_buf[5]; /* set major */
1417 *minor = out_buf[6]; /* set minor */
1418 }
1419 else /* iic */
1420 {
1421 memset(buf, 0, sizeof(uint8_t) * 3); /* clear the buffer */
1422 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_VERSION, (uint8_t *)buf, 3, 20); /* read version command */
1423 if (res != 0) /* check result */
1424 {
1425 handle->debug_print("sps30: read version failed.\n"); /* read version failed */
1426
1427 return 1; /* return error */
1428 }
1429 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2)) /* check crc */
1430 {
1431 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1432
1433 return 1; /* return error */
1434 }
1435 *major = buf[0]; /* set major */
1436 *minor = buf[1]; /* set minor */
1437 }
1438
1439 return 0; /* success return 0 */
1440}
1441
1453uint8_t sps30_get_device_status(sps30_handle_t *handle, uint32_t *status)
1454{
1455 uint8_t res;
1456
1457 if (handle == NULL) /* check handle */
1458 {
1459 return 2; /* return error */
1460 }
1461 if (handle->inited != 1) /* check handle initialization */
1462 {
1463 return 3; /* return error */
1464 }
1465
1466 if (handle->iic_uart != 0) /* uart */
1467 {
1468 uint8_t input_buf[6 + 1];
1469 uint8_t out_buf[7 + 5];
1470
1471 input_buf[0] = 0x7E; /* set start */
1472 input_buf[1] = 0x00; /* set addr */
1473 input_buf[2] = SPS30_UART_COMMAND_READ_DEVICE_STATUS_REG; /* set command */
1474 input_buf[3] = 0x01; /* set length */
1475 input_buf[4] = 0x00; /* set 0x00 */
1476 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4); /* set crc */
1477 input_buf[6] = 0x7E; /* set stop */
1478 memset(out_buf, 0, sizeof(uint8_t) * 12); /* clear the buffer */
1479 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 12); /* write read frame */
1480 if (res != 0) /* check result */
1481 {
1482 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1483
1484 return 1; /* return error */
1485 }
1486 if (out_buf[10] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 9)) /* check crc */
1487 {
1488 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1489
1490 return 1; /* return error */
1491 }
1492 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1493 {
1494 return 1; /* return error */
1495 }
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); /* get status */
1498 }
1499 else /* iic */
1500 {
1501 uint8_t buf[6];
1502
1503 memset(buf, 0, sizeof(uint8_t) * 6); /* clear the buffer */
1504 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_DEVICE_STATUS_REG,
1505 (uint8_t *)buf, 6, 20); /* get device status command */
1506 if (res != 0) /* check result */
1507 {
1508 handle->debug_print("sps30: get device status failed.\n"); /* get device status failed */
1509
1510 return 1; /* return error */
1511 }
1512 if (buf[2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[0], 2)) /* check crc */
1513 {
1514 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1515
1516 return 1; /* return error */
1517 }
1518 if (buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&buf[3], 2)) /* check crc */
1519 {
1520 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1521
1522 return 1; /* return error */
1523 }
1524 *status = ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
1525 ((uint32_t)buf[3] << 8) | ((uint32_t)buf[4] << 0); /* get status */
1526 }
1527
1528 return 0; /* success return 0 */
1529}
1530
1542{
1543 uint8_t res;
1544
1545 if (handle == NULL) /* check handle */
1546 {
1547 return 2; /* return error */
1548 }
1549 if (handle->inited != 1) /* check handle initialization */
1550 {
1551 return 3; /* return error */
1552 }
1553
1554 if (handle->iic_uart != 0) /* uart */
1555 {
1556 uint8_t input_buf[6 + 1];
1557 uint8_t out_buf[7 + 5];
1558
1559 input_buf[0] = 0x7E; /* set start */
1560 input_buf[1] = 0x00; /* set addr */
1561 input_buf[2] = SPS30_UART_COMMAND_READ_DEVICE_STATUS_REG; /* set command */
1562 input_buf[3] = 0x01; /* set length */
1563 input_buf[4] = 0x01; /* set 0x01 */
1564 input_buf[5] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 4); /* set crc */
1565 input_buf[6] = 0x7E; /* set stop */
1566 memset(out_buf, 0, sizeof(uint8_t) * 12); /* clear the buffer */
1567 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 7, 20, (uint8_t *)out_buf, 12); /* write read frame */
1568 if (res != 0) /* check result */
1569 {
1570 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1571
1572 return 1; /* return error */
1573 }
1574 if (out_buf[10] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 9)) /* check crc */
1575 {
1576 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1577
1578 return 1; /* return error */
1579 }
1580 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1581 {
1582 return 1; /* return error */
1583 }
1584 }
1585 else /* iic */
1586 {
1587 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_CLEAR_DEVICE_STATUS_REG, NULL, 0, 20); /* clear device status command */
1588 if (res != 0) /* check result */
1589 {
1590 handle->debug_print("sps30: clear device status failed.\n"); /* clear device status failed */
1591
1592 return 1; /* return error */
1593 }
1594 }
1595
1596 return 0; /* success return 0 */
1597}
1598
1610{
1611 uint8_t res;
1612
1613 if (handle == NULL) /* check handle */
1614 {
1615 return 2; /* return error */
1616 }
1617 if (handle->inited != 1) /* check handle initialization */
1618 {
1619 return 3; /* return error */
1620 }
1621
1622 if (handle->iic_uart != 0) /* uart */
1623 {
1624 uint8_t input_buf[6];
1625 uint8_t out_buf[7];
1626
1627 input_buf[0] = 0x7E; /* set start */
1628 input_buf[1] = 0x00; /* set addr */
1629 input_buf[2] = SPS30_UART_COMMAND_RESET; /* set command */
1630 input_buf[3] = 0x00; /* set length */
1631 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
1632 input_buf[5] = 0x7E; /* set stop */
1633 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
1634 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7); /* write read frame */
1635 if (res != 0) /* check result */
1636 {
1637 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1638
1639 return 1; /* return error */
1640 }
1641 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
1642 {
1643 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1644
1645 return 1; /* return error */
1646 }
1647 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1648 {
1649 return 1; /* return error */
1650 }
1651 }
1652 else /* iic */
1653 {
1654 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_RESET, NULL, 0, 100); /* reset command */
1655 if (res != 0) /* check result */
1656 {
1657 handle->debug_print("sps30: reset failed.\n"); /* reset failed */
1658
1659 return 1; /* return error */
1660 }
1661 }
1662
1663 return 0; /* success return 0 */
1664}
1665
1679{
1680 union float_u
1681 {
1682 float f;
1683 uint32_t i;
1684 };
1685 uint8_t res, i;
1686 union float_u f;
1687
1688 if ((handle == NULL) || (pm == NULL)) /* check handle */
1689 {
1690 return 2; /* return error */
1691 }
1692 if (handle->inited != 1) /* check handle initialization */
1693 {
1694 return 3; /* return error */
1695 }
1696
1697 if (handle->iic_uart != 0) /* uart */
1698 {
1699 if (handle->format == SPS30_FORMAT_IEEE754) /* float */
1700 {
1701 uint8_t input_buf[6];
1702 uint8_t out_buf[7 + 40];
1703
1704 input_buf[0] = 0x7E; /* set start */
1705 input_buf[1] = 0x00; /* set addr */
1706 input_buf[2] = SPS30_UART_COMMAND_READ_MEASURED_VALUES; /* set command */
1707 input_buf[3] = 0x00; /* set length */
1708 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
1709 input_buf[5] = 0x7E; /* set stop */
1710 memset(out_buf, 0, sizeof(uint8_t) * 47); /* clear the buffer */
1711 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 47); /* write read frame */
1712 if (res != 0) /* check result */
1713 {
1714 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1715
1716 return 1; /* return error */
1717 }
1718 if (out_buf[45] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 44)) /* check crc */
1719 {
1720 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1721
1722 return 1; /* return error */
1723 }
1724 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1725 {
1726 return 1; /* return error */
1727 }
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; /* copy data */
1730 pm->pm1p0_ug_m3 = f.f; /* copy pm1.0 ug/m3 */
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; /* copy data */
1733 pm->pm2p5_ug_m3 = f.f; /* copy pm2.5 ug/m3 */
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; /* copy data */
1736 pm->pm4p0_ug_m3 = f.f; /* copy pm4.0 ug/m3 */
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; /* copy data */
1739 pm->pm10_ug_m3 = f.f; /* copy pm10.0 ug/m3 */
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; /* copy data */
1742 pm->pm0p5_cm3 = f.f; /* copy pm0.5 cm3 */
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; /* copy data */
1745 pm->pm1p0_cm3 = f.f; /* copy pm1.0 cm3 */
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; /* copy data */
1748 pm->pm2p5_cm3 = f.f; /* copy pm2.5 cm3 */
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; /* copy data */
1751 pm->pm4p0_cm3 = f.f; /* copy pm4.0 cm3 */
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; /* copy data */
1754 pm->pm10_cm3 = f.f; /* copy pm10.0 cm3 */
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; /* copy data */
1757 pm->typical_particle_um = f.f; /* copy typical particle um */
1758 }
1759 else if (handle->format == SPS30_FORMAT_UINT16) /* uint16 */
1760 {
1761 uint8_t input_buf[6];
1762 uint8_t out_buf[7 + 20];
1763
1764 input_buf[0] = 0x7E; /* set start */
1765 input_buf[1] = 0x00; /* set addr */
1766 input_buf[2] = SPS30_UART_COMMAND_READ_MEASURED_VALUES; /* set command */
1767 input_buf[3] = 0x00; /* set length */
1768 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
1769 input_buf[5] = 0x7E; /* set stop */
1770 memset(out_buf, 0, sizeof(uint8_t) * 27); /* clear the buffer */
1771 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 20, (uint8_t *)out_buf, 27); /* write read frame */
1772 if (res != 0) /* check result */
1773 {
1774 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
1775
1776 return 1; /* return error */
1777 }
1778 if (out_buf[25] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 24)) /* check crc */
1779 {
1780 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
1781
1782 return 1; /* return error */
1783 }
1784 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
1785 {
1786 return 1; /* return error */
1787 }
1788 pm->pm1p0_ug_m3 = (float)(((uint16_t)(out_buf[5 + 0]) << 8) | ((uint16_t)(out_buf[5 + 1]) << 0)); /* copy pm1.0 ug/m3 */
1789 pm->pm2p5_ug_m3 = (float)(((uint16_t)(out_buf[5 + 2]) << 8) | ((uint16_t)(out_buf[5 + 3]) << 0)); /* copy pm2.5 ug/m3 */
1790 pm->pm4p0_ug_m3 = (float)(((uint16_t)(out_buf[5 + 4]) << 8) | ((uint16_t)(out_buf[5 + 5]) << 0)); /* copy pm4.0 ug/m3 */
1791 pm->pm10_ug_m3 = (float)(((uint16_t)(out_buf[5 + 6]) << 8) | ((uint16_t)(out_buf[5 + 7]) << 0)); /* copy pm10 ug/m3 */
1792 pm->pm0p5_cm3 = (float)(((uint16_t)(out_buf[5 + 8]) << 8) | ((uint16_t)(out_buf[5 + 9]) << 0)); /* copy pm0.5 cm3 */
1793 pm->pm1p0_cm3 = (float)(((uint16_t)(out_buf[5 + 10]) << 8) | ((uint16_t)(out_buf[5 + 11]) << 0)); /* copy pm1.0 cm3 */
1794 pm->pm2p5_cm3 = (float)(((uint16_t)(out_buf[5 + 12]) << 8) | ((uint16_t)(out_buf[5 + 13]) << 0)); /* copy pm2.5 cm3 */
1795 pm->pm4p0_cm3 = (float)(((uint16_t)(out_buf[5 + 14]) << 8) | ((uint16_t)(out_buf[5 + 15]) << 0)); /* copy pm4.0 cm3 */
1796 pm->pm10_cm3 = (float)(((uint16_t)(out_buf[5 + 16]) << 8) | ((uint16_t)(out_buf[5 + 17]) << 0)); /* copy pm10 cm3 */
1797 pm->typical_particle_um = (float)(((uint16_t)(out_buf[5 + 18]) << 8) | ((uint16_t)(out_buf[5 + 19]) << 0)); /* copy typical particle */
1798 pm->typical_particle_um /= 1000.0f; /* div 1000 */
1799 }
1800 else
1801 {
1802 handle->debug_print("sps30: mode is invalid.\n"); /* mode is invalid */
1803
1804 return 4; /* return error */
1805 }
1806 }
1807 else /* iic */
1808 {
1809 uint8_t check[3];
1810
1811 memset(check, 0, sizeof(uint8_t) * 3); /* clear the buffer */
1812 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_DATA_READY_FLAG, (uint8_t *)check, 3, 20); /* read data ready flag command */
1813 if (res != 0) /* check result */
1814 {
1815 handle->debug_print("sps30: read data ready flag failed.\n"); /* read data ready flag failed */
1816
1817 return 1; /* return error */
1818 }
1819 if (check[2] != a_sps30_generate_crc(handle, (uint8_t *)check, 2)) /* check crc */
1820 {
1821 handle->debug_print("sps30: crc check failed.\n"); /* crc check failed */
1822
1823 return 1; /* return error */
1824 }
1825 if ((check[1] & 0x01) == 0) /* check flag */
1826 {
1827 handle->debug_print("sps30: data not ready.\n"); /* data not ready */
1828
1829 return 1; /* return error */
1830 }
1831
1832 if (handle->format == SPS30_FORMAT_IEEE754) /* float */
1833 {
1834 uint8_t buf[60];
1835
1836 memset(buf, 0, sizeof(uint8_t) * 60); /* clear the buffer */
1837 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_MEASURED_VALUES, (uint8_t *)buf, 60, 20); /* read measured values command */
1838 if (res != 0) /* check result */
1839 {
1840 handle->debug_print("sps30: read measured values failed.\n"); /* read measured values failed */
1841
1842 return 1; /* return error */
1843 }
1844 for (i = 0; i < 20; i++) /* check crc */
1845 {
1846 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2)) /* check crc */
1847 {
1848 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1849
1850 return 1; /* return error */
1851 }
1852 }
1853 f.i = (uint32_t)(buf[0]) << 24 | (uint32_t)(buf[1]) << 16 |
1854 (uint32_t)(buf[3]) << 8 | (uint32_t)(buf[4]) << 0; /* copy data */
1855 pm->pm1p0_ug_m3 = f.f; /* copy pm1.0 ug/m3 */
1856 f.i = (uint32_t)(buf[6]) << 24 | (uint32_t)(buf[7]) << 16 |
1857 (uint32_t)(buf[9]) << 8 | (uint32_t)(buf[10]) << 0; /* copy data */
1858 pm->pm2p5_ug_m3 = f.f; /* copy pm2.5 ug/m3 */
1859 f.i = (uint32_t)(buf[12]) << 24 | (uint32_t)(buf[13]) << 16 |
1860 (uint32_t)(buf[15]) << 8 | (uint32_t)(buf[16]) << 0; /* copy data */
1861 pm->pm4p0_ug_m3 = f.f; /* copy pm4.0 ug/m3 */
1862 f.i = (uint32_t)(buf[18]) << 24 | (uint32_t)(buf[19]) << 16 |
1863 (uint32_t)(buf[21]) << 8 | (uint32_t)(buf[22]) << 0; /* copy data */
1864 pm->pm10_ug_m3 = f.f; /* copy pm10.0 ug/m3 */
1865 f.i = (uint32_t)(buf[24]) << 24 | (uint32_t)(buf[25]) << 16 |
1866 (uint32_t)(buf[27]) << 8 | (uint32_t)(buf[28]) << 0; /* copy data */
1867 pm->pm0p5_cm3 = f.f; /* copy pm0.5 cm3 */
1868 f.i = (uint32_t)(buf[30]) << 24 | (uint32_t)(buf[31]) << 16 |
1869 (uint32_t)(buf[33]) << 8 | (uint32_t)(buf[34]) << 0; /* copy data */
1870 pm->pm1p0_cm3 = f.f; /* copy pm1.0 cm3 */
1871 f.i = (uint32_t)(buf[36]) << 24 | (uint32_t)(buf[37]) << 16 |
1872 (uint32_t)(buf[39]) << 8 | (uint32_t)(buf[40]) << 0; /* copy data */
1873 pm->pm2p5_cm3 = f.f; /* copy pm2.5 cm3 */
1874 f.i = (uint32_t)(buf[42]) << 24 | (uint32_t)(buf[43]) << 16 |
1875 (uint32_t)(buf[45]) << 8 | (uint32_t)(buf[46]) << 0; /* copy data */
1876 pm->pm4p0_cm3 = f.f; /* copy pm4.0 cm3 */
1877 f.i = (uint32_t)(buf[48]) << 24 | (uint32_t)(buf[49]) << 16 |
1878 (uint32_t)(buf[51]) << 8 | (uint32_t)(buf[52]) << 0; /* copy data */
1879 pm->pm10_cm3 = f.f; /* copy pm10.0 cm3 */
1880 f.i = (uint32_t)(buf[54]) << 24 | (uint32_t)(buf[55]) << 16 |
1881 (uint32_t)(buf[57]) << 8 | (uint32_t)(buf[58]) << 0; /* copy data */
1882 pm->typical_particle_um = f.f; /* copy typical particle um */
1883 }
1884 else if (handle->format == SPS30_FORMAT_UINT16) /* uint16 */
1885 {
1886 uint8_t buf[30];
1887
1888 memset(buf, 0, sizeof(uint8_t) * 30); /* clear the buffer */
1889 res = a_sps30_iic_read(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_READ_MEASURED_VALUES, (uint8_t *)buf, 30, 20); /* read measured values command */
1890 if (res != 0) /* check result */
1891 {
1892 handle->debug_print("sps30: read measured values failed.\n"); /* read measured values failed */
1893
1894 return 1; /* return error */
1895 }
1896 for (i = 0; i < 10; i++) /* check crc */
1897 {
1898 if (buf[i * 3 + 2] != a_sps30_generate_crc(handle, (uint8_t *)&buf[i * 3], 2)) /* check crc */
1899 {
1900 handle->debug_print("sps30: crc is error.\n"); /* crc is error */
1901
1902 return 1; /* return error */
1903 }
1904 }
1905 pm->pm1p0_ug_m3 = (float)(((uint16_t)(buf[0]) << 8) | ((uint16_t)(buf[1]) << 0)); /* copy pm1.0 ug/m3 */
1906 pm->pm2p5_ug_m3 = (float)(((uint16_t)(buf[3]) << 8) | ((uint16_t)(buf[4]) << 0)); /* copy pm2.5 ug/m3 */
1907 pm->pm4p0_ug_m3 = (float)(((uint16_t)(buf[6]) << 8) | ((uint16_t)(buf[7]) << 0)); /* copy pm4.0 ug/m3 */
1908 pm->pm10_ug_m3 = (float)(((uint16_t)(buf[9]) << 8) | ((uint16_t)(buf[10]) << 0)); /* copy pm10 ug/m3 */
1909 pm->pm0p5_cm3 = (float)(((uint16_t)(buf[12]) << 8) | ((uint16_t)(buf[13]) << 0)); /* copy pm0.5 cm3 */
1910 pm->pm1p0_cm3 = (float)(((uint16_t)(buf[15]) << 8) | ((uint16_t)(buf[16]) << 0)); /* copy pm1.0 cm3 */
1911 pm->pm2p5_cm3 = (float)(((uint16_t)(buf[18]) << 8) | ((uint16_t)(buf[19]) << 0)); /* copy pm2.5 cm3 */
1912 pm->pm4p0_cm3 = (float)(((uint16_t)(buf[21]) << 8) | ((uint16_t)(buf[22]) << 0)); /* copy pm4.0 cm3 */
1913 pm->pm10_cm3 = (float)(((uint16_t)(buf[24]) << 8) | ((uint16_t)(buf[25]) << 0)); /* copy pm10 cm3 */
1914 pm->typical_particle_um = (float)(((uint16_t)(buf[27]) << 8) | ((uint16_t)(buf[28]) << 0)); /* copy typical particle */
1915 pm->typical_particle_um /= 1000.0f; /* div 1000 */
1916 }
1917 else
1918 {
1919 handle->debug_print("sps30: mode is invalid.\n"); /* mode is invalid */
1920
1921 return 4; /* return error */
1922 }
1923 }
1924
1925 return 0; /* success return 0 */
1926}
1927
1940{
1941 uint8_t res;
1942
1943 if (handle == NULL) /* check handle */
1944 {
1945 return 2; /* return error */
1946 }
1947 if (handle->debug_print == NULL) /* check debug_print */
1948 {
1949 return 3; /* return error */
1950 }
1951 if (handle->iic_init == NULL) /* check iic_init */
1952 {
1953 handle->debug_print("sps30: iic_init is null.\n"); /* iic_init is null */
1954
1955 return 3; /* return error */
1956 }
1957 if (handle->iic_deinit == NULL) /* check iic_deinit */
1958 {
1959 handle->debug_print("sps30: iic_deinit is null.\n"); /* iic_deinit is null */
1960
1961 return 3; /* return error */
1962 }
1963 if (handle->iic_write_cmd == NULL) /* check iic_write_cmd */
1964 {
1965 handle->debug_print("sps30: iic_write_cmd is null.\n"); /* iic_write_cmd is null */
1966
1967 return 3; /* return error */
1968 }
1969 if (handle->iic_read_cmd == NULL) /* check iic_read_cmd */
1970 {
1971 handle->debug_print("sps30: iic_read_cmd is null.\n"); /* iic_read_cmd is null */
1972
1973 return 3; /* return error */
1974 }
1975 if (handle->uart_init == NULL) /* check uart_init */
1976 {
1977 handle->debug_print("sps30: uart_init is null.\n"); /* uart_init is null */
1978
1979 return 3; /* return error */
1980 }
1981 if (handle->uart_deinit == NULL) /* check uart_deinit */
1982 {
1983 handle->debug_print("sps30: uart_deinit is null.\n"); /* uart_deinit is null */
1984
1985 return 3; /* return error */
1986 }
1987 if (handle->uart_read == NULL) /* check uart_read */
1988 {
1989 handle->debug_print("sps30: uart_read is null.\n"); /* uart_read is null */
1990
1991 return 3; /* return error */
1992 }
1993 if (handle->uart_write == NULL) /* check uart_write */
1994 {
1995 handle->debug_print("sps30: uart_write is null.\n"); /* uart_write is null */
1996
1997 return 3; /* return error */
1998 }
1999 if (handle->uart_flush == NULL) /* check uart_flush */
2000 {
2001 handle->debug_print("sps30: uart_flush is null.\n"); /* uart_flush is null */
2002
2003 return 3; /* return error */
2004 }
2005 if (handle->delay_ms == NULL) /* check delay_ms */
2006 {
2007 handle->debug_print("sps30: delay_ms is null.\n"); /* delay_ms is null */
2008
2009 return 3; /* return error */
2010 }
2011
2012 if (handle->iic_uart != 0)
2013 {
2014 uint8_t input_buf[6];
2015 uint8_t out_buf[7];
2016
2017 if (handle->uart_init() != 0) /* uart init */
2018 {
2019 handle->debug_print("sps30: uart init failed.\n"); /* uart init failed */
2020
2021 return 1; /* return error */
2022 }
2023 input_buf[0] = 0x7E; /* set start */
2024 input_buf[1] = 0x00; /* set addr */
2025 input_buf[2] = SPS30_UART_COMMAND_RESET; /* set command */
2026 input_buf[3] = 0x00; /* set length */
2027 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
2028 input_buf[5] = 0x7E; /* set stop */
2029 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
2030 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7); /* write read frame */
2031 if (res != 0) /* check result */
2032 {
2033 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
2034 (void)handle->uart_deinit(); /* uart deinit */
2035
2036 return 4; /* return error */
2037 }
2038 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
2039 {
2040 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
2041 (void)handle->uart_deinit(); /* uart deinit */
2042
2043 return 4; /* return error */
2044 }
2045 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
2046 {
2047 (void)handle->uart_deinit(); /* uart deinit */
2048
2049 return 4; /* return error */
2050 }
2051 }
2052 else
2053 {
2054 if (handle->iic_init() != 0) /* iic init */
2055 {
2056 handle->debug_print("sps30: iic init failed.\n"); /* iic init failed */
2057
2058 return 1; /* return error */
2059 }
2060 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_RESET, NULL, 0, 100); /* reset command */
2061 if (res != 0) /* check result */
2062 {
2063 handle->debug_print("sps30: reset failed.\n"); /* reset failed */
2064 (void)handle->iic_deinit(); /* iic deinit */
2065
2066 return 4; /* return error */
2067 }
2068 }
2069 handle->inited = 1; /* flag finish initialization */
2070
2071 return 0; /* success return 0 */
2072}
2073
2086{
2087 uint8_t res;
2088
2089 if (handle == NULL) /* check handle */
2090 {
2091 return 2; /* return error */
2092 }
2093 if (handle->inited != 1) /* check handle initialization */
2094 {
2095 return 3; /* return error */
2096 }
2097
2098 if (handle->iic_uart != 0)
2099 {
2100 uint8_t input_buf[6];
2101 uint8_t out_buf[7];
2102
2103 input_buf[0] = 0x7E; /* set start */
2104 input_buf[1] = 0x00; /* set addr */
2105 input_buf[2] = SPS30_UART_COMMAND_RESET; /* set command */
2106 input_buf[3] = 0x00; /* set length */
2107 input_buf[4] = a_sps30_generate_crc(handle, (uint8_t *)&input_buf[1], 3); /* set crc */
2108 input_buf[5] = 0x7E; /* set stop */
2109 memset(out_buf, 0, sizeof(uint8_t) * 7); /* clear the buffer */
2110 res = a_sps30_uart_write_read(handle, (uint8_t *)input_buf, 6, 100, (uint8_t *)out_buf, 7); /* write read frame */
2111 if (res != 0) /* check result */
2112 {
2113 handle->debug_print("sps30: write read failed.\n"); /* write read failed */
2114
2115 return 4; /* return error */
2116 }
2117 if (out_buf[5] != a_sps30_generate_crc(handle, (uint8_t *)&out_buf[1], 4)) /* check crc */
2118 {
2119 handle->debug_print("sps30: crc check error.\n"); /* crc check error */
2120
2121 return 4; /* return error */
2122 }
2123 if (a_sps30_uart_error(handle, out_buf[3]) != 0) /* check status */
2124 {
2125 return 4; /* return error */
2126 }
2127 if (handle->uart_deinit() != 0) /* uart deinit */
2128 {
2129 handle->debug_print("sps30: uart deinit failed.\n"); /* uart deinit failed */
2130
2131 return 1; /* return error */
2132 }
2133 }
2134 else
2135 {
2136 res = a_sps30_iic_write(handle, SPS30_ADDRESS, SPS30_IIC_COMMAND_RESET, NULL, 0, 100); /* reset command */
2137 if (res != 0) /* check result */
2138 {
2139 handle->debug_print("sps30: reset failed.\n"); /* reset failed */
2140
2141 return 4; /* return error */
2142 }
2143 res = handle->iic_deinit(); /* iic deinit */
2144 if (res != 0) /* check result */
2145 {
2146 handle->debug_print("sps30: iic deinit failed.\n"); /* iic deinit */
2147
2148 return 1; /* return error */
2149 }
2150 }
2151
2152 handle->inited = 0; /* flag close initialization */
2153
2154 return 0; /* success return 0 */
2155}
2156
2169uint8_t sps30_set_get_reg_uart(sps30_handle_t *handle, uint8_t *input, uint16_t in_len, uint8_t *output, uint16_t out_len)
2170{
2171 if (handle == NULL) /* check handle */
2172 {
2173 return 2; /* return error */
2174 }
2175 if (handle->inited != 1) /* check handle initialization */
2176 {
2177 return 3; /* return error */
2178 }
2179
2180 if (handle->iic_uart != 0)
2181 {
2182 return a_sps30_uart_write_read(handle, input, in_len, 20, output, out_len); /* write and read with the uart interface */
2183 }
2184 else
2185 {
2186 handle->debug_print("sps30: iic interface is invalid.\n"); /* iic interface is invalid */
2187
2188 return 1; /* return error */
2189 }
2190}
2191
2205uint8_t sps30_set_reg_iic(sps30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
2206{
2207 if (handle == NULL) /* check handle */
2208 {
2209 return 2; /* return error */
2210 }
2211 if (handle->inited != 1) /* check handle initialization */
2212 {
2213 return 3; /* return error */
2214 }
2215
2216 if (handle->iic_uart != 0)
2217 {
2218 handle->debug_print("sps30: uart interface is invalid.\n"); /* uart interface is invalid */
2219
2220 return 1; /* return error */
2221 }
2222 else
2223 {
2224 return a_sps30_iic_write(handle, SPS30_ADDRESS, reg, buf, len, 20); /* write the data */
2225 }
2226}
2227
2241uint8_t sps30_get_reg_iic(sps30_handle_t *handle, uint16_t reg, uint8_t *buf, uint16_t len)
2242{
2243 if (handle == NULL) /* check handle */
2244 {
2245 return 2; /* return error */
2246 }
2247 if (handle->inited != 1) /* check handle initialization */
2248 {
2249 return 3; /* return error */
2250 }
2251
2252 if (handle->iic_uart != 0)
2253 {
2254 handle->debug_print("sps30: uart interface is invalid.\n"); /* uart interface is invalid */
2255
2256 return 1;
2257 }
2258 else
2259 {
2260 return a_sps30_iic_read(handle, SPS30_ADDRESS, reg, buf, len, 20); /* read the data */
2261 }
2262}
2263
2273{
2274 if (info == NULL) /* check handle */
2275 {
2276 return 2; /* return error */
2277 }
2278
2279 memset(info, 0, sizeof(sps30_info_t)); /* initialize sps30 info structure */
2280 strncpy(info->chip_name, CHIP_NAME, 32); /* copy chip name */
2281 strncpy(info->manufacturer_name, MANUFACTURER_NAME, 32); /* copy manufacturer name */
2282 strncpy(info->interface, "UART IIC", 16); /* copy interface name */
2283 info->supply_voltage_min_v = SUPPLY_VOLTAGE_MIN; /* set minimal supply voltage */
2284 info->supply_voltage_max_v = SUPPLY_VOLTAGE_MAX; /* set maximum supply voltage */
2285 info->max_current_ma = MAX_CURRENT; /* set maximum current */
2286 info->temperature_max = TEMPERATURE_MAX; /* set minimal temperature */
2287 info->temperature_min = TEMPERATURE_MIN; /* set maximum temperature */
2288 info->driver_version = DRIVER_VERSION; /* set driver version */
2289
2290 return 0; /* success return 0 */
2291}
#define SPS30_UART_COMMAND_WAKE_UP
#define SPS30_UART_COMMAND_START_FAN_CLEANING
#define MAX_CURRENT
#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 TEMPERATURE_MAX
#define MANUFACTURER_NAME
#define TEMPERATURE_MIN
#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 DRIVER_VERSION
#define SPS30_IIC_COMMAND_START_FAN_CLEANING
#define SPS30_ADDRESS
chip address definition
driver sps30 header file
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
struct sps30_info_s sps30_info_t
sps30 information structure definition
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
struct sps30_handle_s sps30_handle_t
sps30 handle structure definition
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
struct sps30_pm_s sps30_pm_t
sps30 pm structure definition
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
@ SPS30_INTERFACE_IIC
@ SPS30_FORMAT_UINT16
@ SPS30_FORMAT_IEEE754
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
uint8_t(* uart_flush)(void)
uint8_t buf[256]
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)
float temperature_max
float supply_voltage_max_v
uint32_t driver_version
char interface[16]
float temperature_min
float max_current_ma
char manufacturer_name[32]
float supply_voltage_min_v
char chip_name[32]
float pm1p0_cm3
float typical_particle_um
float pm4p0_cm3
float pm1p0_ug_m3
float pm0p5_cm3
float pm4p0_ug_m3
float pm10_ug_m3
float pm2p5_cm3
float pm2p5_ug_m3