1 /*
2  * Copyright (c) 2021 G-Technologies Sdn. Bhd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B
8 #define ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/uart.h>
13 
14 #define MHZ19B_BUF_LEN 9
15 
16 #define MHZ19B_TX_CMD_IDX 2
17 #define MHZ19B_RX_CMD_IDX 1
18 #define MHZ19B_CHECKSUM_IDX 8
19 
20 /* Arbitrary max duration to wait for the response */
21 #define MHZ19B_WAIT K_SECONDS(1)
22 
23 enum mhz19b_cmd_idx {
24 	/* Command to poll for CO2 */
25 	MHZ19B_CMD_IDX_GET_CO2,
26 	/* Read range */
27 	MHZ19B_CMD_IDX_GET_RANGE,
28 	/* Get ABC status */
29 	MHZ19B_CMD_IDX_GET_ABC,
30 	/* Enable ABC */
31 	MHZ19B_CMD_IDX_SET_ABC_ON,
32 	/* Disable ABC */
33 	MHZ19B_CMD_IDX_SET_ABC_OFF,
34 	/* Set detection range to 2000 ppm */
35 	MHZ19B_CMD_IDX_SET_RANGE_2000,
36 	/* Set detection range to 5000 ppm */
37 	MHZ19B_CMD_IDX_SET_RANGE_5000,
38 	/* Set detection range to 10000 ppm */
39 	MHZ19B_CMD_IDX_SET_RANGE_10000,
40 	/* Number of supported commands */
41 	MHZ19B_CMD_IDX_MAX,
42 };
43 
44 struct mhz19b_data {
45 	/* Max data length is 16 bits */
46 	uint16_t data;
47 	/* Command buf length is 9 */
48 	uint8_t xfer_bytes;
49 	bool has_rsp;
50 
51 	uint8_t rd_data[MHZ19B_BUF_LEN];
52 
53 	struct k_sem tx_sem;
54 	struct k_sem rx_sem;
55 
56 	enum mhz19b_cmd_idx cmd_idx;
57 };
58 
59 struct mhz19b_cfg {
60 	const struct device *uart_dev;
61 	uint16_t range;
62 	bool abc_on;
63 	uart_irq_callback_user_data_t cb;
64 };
65 
66 #define MHZ19B_HEADER 0xff
67 #define MHZ19B_RESERVED 0x01
68 #define MHZ19B_NULL 0x00
69 #define MHZ19B_NULL_1 MHZ19B_NULL
70 #define MHZ19B_NULL_2 MHZ19B_NULL, MHZ19B_NULL_1
71 #define MHZ19B_NULL_3 MHZ19B_NULL, MHZ19B_NULL_2
72 #define MHZ19B_NULL_4 MHZ19B_NULL, MHZ19B_NULL_3
73 #define MHZ19B_NULL_5 MHZ19B_NULL, MHZ19B_NULL_4
74 #define MHZ19B_NULL_COUNT(c) MHZ19B_NULL_##c
75 
76 #define MHZ19B_ABC_ON 0xA0
77 #define MHZ19B_ABC_OFF 0x00
78 #define MHZ19B_RANGE_2000 0x07, 0xD0
79 #define MHZ19B_RANGE_5000 0x13, 0x88
80 #define MHZ19B_RANGE_10000 0x27, 0x10
81 
82 enum mhz19b_cmd {
83 	MHZ19B_CMD_SET_ABC = 0x79,
84 	MHZ19B_CMD_GET_ABC = 0x7D,
85 	MHZ19B_CMD_GET_CO2 = 0x86,
86 	MHZ19B_CMD_SET_RANGE = 0x99,
87 	MHZ19B_CMD_GET_RANGE = 0x9B,
88 };
89 
90 #endif /* ZEPHYR_DRIVERS_SENSOR_MHZ19B_MHZ19B */
91