Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_module_co2.c
1 #include <bc_module_co2.h>
2 #include <bc_scheduler.h>
3 #include <bc_i2c.h>
4 #include <bc_tca9534a.h>
5 #include <bc_sc16is740.h>
6 
7 #define _BC_MODULE_CO2_I2C_GPIO_EXPANDER_ADDRESS 0x38
8 #define _BC_MODULE_CO2_I2C_UART_ADDRESS 0x4d
9 #define _BC_MODULE_CO2_PIN_DEFAULT (~(1 << 0) & ~(1 << 4))
10 #define _BC_MODULE_CO2_PIN_CAP_ON (~(1 << 1))
11 #define _BC_MODULE_CO2_PIN_VDD2_ON (~(1 << 2))
12 #define _BC_MODULE_CO2_PIN_EN (~(1 << 3))
13 #define _BC_MODULE_CO2_PIN_UART_RESET (~(1 << 6))
14 #define _BC_MODULE_CO2_PIN_RDY BC_TCA9534A_PIN_P7
15 
16 typedef enum
17 {
18  BC_MODULE_CO2_STATE_ERROR = -1,
19  BC_MODULE_CO2_STATE_INITIALIZE = 0,
20  BC_MODULE_CO2_STATE_INITIALIZE1,
21  BC_MODULE_CO2_STATE_INITIALIZE2,
22  BC_MODULE_CO2_STATE_READY,
23  BC_MODULE_CO2_STATE_CHARGE,
24  BC_MODULE_CO2_STATE_BOOT,
25  BC_MODULE_CO2_STATE_BOOT_READ,
26  BC_MODULE_CO2_STATE_MEASURE,
27  BC_MODULE_CO2_STATE_MEASURE_READ,
28 
29 } bc_module_co2_state_t;
30 
31 static bool _bc_module_co2_init(void);
32 static bool _bc_module_co2_charge_enable(bool state);
33 static bool _bc_module_co2_device_enable(bool state);
34 static bool _bc_module_co2_read_signal_rdy(int *value);
35 static bool _bc_module_co2_uart_enable(bool state);
36 static size_t _bc_module_co2_uart_write(uint8_t *buffer, size_t length);
37 static size_t _bc_module_co2_uart_read(uint8_t *buffer, size_t length);
38 
39 static struct
40 {
41  bc_tca9534a_t tca9534a;
42  bc_sc16is740_t sc16is740;
43  bc_lp8_t sensor;
44  const bc_lp8_driver_t driver;
45 
46 } _bc_module_co2 = {
47  .driver = {
48  .init = _bc_module_co2_init,
49  .charge_enable = _bc_module_co2_charge_enable,
50  .device_enable = _bc_module_co2_device_enable,
51  .read_signal_rdy = _bc_module_co2_read_signal_rdy,
52  .uart_enable = _bc_module_co2_uart_enable,
53  .uart_write = _bc_module_co2_uart_write,
54  .uart_read = _bc_module_co2_uart_read
55  }
56 };
57 
59 {
60  bc_lp8_init(&_bc_module_co2.sensor, &_bc_module_co2.driver);
61 }
62 
63 void bc_module_co2_set_event_handler(void (*event_handler)(bc_module_co2_event_t, void *), void *event_param)
64 {
65  bc_lp8_set_event_handler(&_bc_module_co2.sensor, (void (*)(bc_lp8_event_t, void *)) event_handler, event_param);
66 }
67 
69 {
70  bc_lp8_set_update_interval(&_bc_module_co2.sensor, interval);
71 }
72 
74 {
75  return bc_lp8_measure(&_bc_module_co2.sensor);
76 }
77 
79 {
80  return bc_lp8_get_concentration_ppm(&_bc_module_co2.sensor, ppm);
81 }
82 
83 bool bc_module_co2_get_error(bc_lp8_error_t *error)
84 {
85  return bc_lp8_get_error(&_bc_module_co2.sensor, error);
86 }
87 
89 {
90  bc_lp8_calibration(&_bc_module_co2.sensor, calibration);
91 }
92 
93 static bool _bc_module_co2_init(void)
94 {
95  if (!bc_tca9534a_init(&_bc_module_co2.tca9534a, BC_I2C_I2C0, _BC_MODULE_CO2_I2C_GPIO_EXPANDER_ADDRESS))
96  {
97  return false;
98  }
99 
100  if (!bc_tca9534a_write_port(&_bc_module_co2.tca9534a, 0x00))
101  {
102  return false;
103  }
104 
105  // Reset SC16IS740
106  if (!bc_tca9534a_set_port_direction(&_bc_module_co2.tca9534a, _BC_MODULE_CO2_PIN_DEFAULT & _BC_MODULE_CO2_PIN_UART_RESET))
107  {
108  return false;
109  }
110 
111  // Reset pulse width > 3us
112  for (volatile int i = 0; i < 100; i++)
113  {
114  continue;
115  }
116 
117  if (!bc_tca9534a_set_port_direction(&_bc_module_co2.tca9534a, _BC_MODULE_CO2_PIN_DEFAULT))
118  {
119  return false;
120  }
121 
122  // Delay time width > 10us
123  for (volatile int i = 0; i < 1000; i++)
124  {
125  continue;
126  }
127 
128  if (!bc_sc16is740_init(&_bc_module_co2.sc16is740, BC_I2C_I2C0, _BC_MODULE_CO2_I2C_UART_ADDRESS))
129  {
130  return false;
131  }
132 
133  return true;
134 }
135 
136 static bool _bc_module_co2_charge_enable(bool state)
137 {
138  uint8_t direction = _BC_MODULE_CO2_PIN_DEFAULT;
139 
140  if (state)
141  {
142  direction &= _BC_MODULE_CO2_PIN_VDD2_ON & _BC_MODULE_CO2_PIN_CAP_ON;
143  }
144 
145  return bc_tca9534a_set_port_direction(&_bc_module_co2.tca9534a, direction);
146 }
147 
148 static bool _bc_module_co2_device_enable(bool state)
149 {
150  uint8_t direction = _BC_MODULE_CO2_PIN_DEFAULT;
151 
152  if (state)
153  {
154  direction &= _BC_MODULE_CO2_PIN_VDD2_ON & _BC_MODULE_CO2_PIN_CAP_ON & _BC_MODULE_CO2_PIN_EN;
155  }
156 
157  return bc_tca9534a_set_port_direction(&_bc_module_co2.tca9534a, direction);
158 }
159 
160 static bool _bc_module_co2_read_signal_rdy(int *value)
161 {
162  if (!bc_tca9534a_read_pin(&_bc_module_co2.tca9534a, _BC_MODULE_CO2_PIN_RDY, value))
163  {
164  return false;
165  }
166 
167  return true;
168 }
169 
170 static bool _bc_module_co2_uart_enable(bool state)
171 {
172  if (state)
173  {
174  return bc_sc16is740_reset_fifo(&_bc_module_co2.sc16is740, BC_SC16IS740_FIFO_RX);
175  }
176 
177  return true;
178 }
179 
180 static size_t _bc_module_co2_uart_write(uint8_t *buffer, size_t length)
181 {
182  return bc_sc16is740_write(&_bc_module_co2.sc16is740, buffer, length);
183 }
184 
185 static size_t _bc_module_co2_uart_read(uint8_t *buffer, size_t length)
186 {
187  return bc_sc16is740_read(&_bc_module_co2.sc16is740, buffer, length, 0);
188 }
uint64_t bc_tick_t
Timestamp data type.
Definition: bc_tick.h:16
bool bc_lp8_get_error(bc_lp8_t *self, bc_lp8_error_t *error)
Get last error code.
Definition: bc_lp8.c:90
bc_lp8_event_t
Callback events.
Definition: bc_lp8.h:13
bool bc_tca9534a_set_port_direction(bc_tca9534a_t *self, uint8_t direction)
Set direction of all pins.
Definition: bc_tca9534a.c:87
I2C channel I2C0.
Definition: bc_i2c.h:18
void bc_module_co2_init(void)
Initialize BigClown CO2 Module.
Definition: bc_module_co2.c:58
void bc_module_co2_calibration(bc_lp8_calibration_t calibration)
Request sensor calibration.
Definition: bc_module_co2.c:88
Pin state.
Definition: bc_tca9534a.h:42
bool bc_lp8_get_concentration_ppm(bc_lp8_t *self, float *ppm)
Get CO2 concentration in ppm (parts per million)
Definition: bc_lp8.c:76
bool bc_tca9534a_write_port(bc_tca9534a_t *self, uint8_t state)
Write state to all pins.
Definition: bc_tca9534a.c:35
bc_lp8_calibration_t
Calibration.
Definition: bc_lp8.h:25
size_t bc_sc16is740_read(bc_sc16is740_t *self, uint8_t *buffer, size_t length, bc_tick_t timeout)
Read.
Definition: bc_sc16is740.c:150
bc_module_co2_event_t
Callback events.
Definition: bc_module_co2.h:13
void bc_lp8_set_event_handler(bc_lp8_t *self, void(*event_handler)(bc_lp8_event_t, void *), void *event_param)
Set callback function.
Definition: bc_lp8.c:36
void bc_module_co2_set_event_handler(void(*event_handler)(bc_module_co2_event_t, void *), void *event_param)
Set callback function.
Definition: bc_module_co2.c:63
void bc_lp8_set_update_interval(bc_lp8_t *self, bc_tick_t interval)
Set measurement interval.
Definition: bc_lp8.c:42
void bc_module_co2_set_update_interval(bc_tick_t interval)
Set measurement interval.
Definition: bc_module_co2.c:68
bool bc_tca9534a_read_pin(bc_tca9534a_t *self, bc_tca9534a_pin_t pin, int *state)
Read pin state.
Definition: bc_tca9534a.c:47
void bc_lp8_init(bc_lp8_t *self, const bc_lp8_driver_t *driver)
Initialize LP8.
Definition: bc_lp8.c:20
bool bc_sc16is740_init(bc_sc16is740_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
SC16IS740 instance.
Definition: bc_sc16is740.c:23
bool bc_lp8_measure(bc_lp8_t *self)
Start measurement manually.
Definition: bc_lp8.c:58
bool bc_tca9534a_init(bc_tca9534a_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize TCA9534A.
Definition: bc_tca9534a.c:8
bool bc_module_co2_get_concentration_ppm(float *ppm)
Get CO2 concentration in ppm (parts per million)
Definition: bc_module_co2.c:78
size_t bc_sc16is740_write(bc_sc16is740_t *self, uint8_t *buffer, size_t length)
Write.
Definition: bc_sc16is740.c:102
bool bc_module_co2_measure(void)
Start measurement manually.
Definition: bc_module_co2.c:73
LP8 driver.
Definition: bc_lp8.h:53
void bc_lp8_calibration(bc_lp8_t *self, bc_lp8_calibration_t calibration)
Request sensor calibration.
Definition: bc_lp8.c:97
struct bc_lp8_t bc_lp8_t
LP8 instance.
Definition: bc_lp8.h:49
bool bc_sc16is740_reset_fifo(bc_sc16is740_t *self, bc_sc16is740_fifo_t fifo)
Reset FIFO.
Definition: bc_sc16is740.c:79
bool bc_module_co2_get_error(bc_lp8_error_t *error)
Get last error code.
Definition: bc_module_co2.c:83