ENTS-tock
Environmental NeTworked Sensor firmware on Tock OS
Loading...
Searching...
No Matches
ads1219.c
Go to the documentation of this file.
1
16#include "ads1219.h"
17
18#include <libtock-sync/services/alarm.h>
19#include <libtock/peripherals/i2c_master.h>
20#include <libtock/tock.h>
21
22#include "../proto/sensor.h"
23
24// Generic calibration values that give rough estimate
25static const double voltage_calibration_m = -0.00039326;
26static const double voltage_calibration_b = 4.92916378e-05;
27static const double current_calibration_m = -1.18693164e-10;
28static const double current_calibration_b = 4.14518594e-05;
29
30static const uint8_t addr = 0x40;
32static uint8_t addrls = addr << 1;
33
35typedef enum {
37 cmd_reset = 0x06,
39 cmd_start = 0x08,
43 cmd_rdata = 0x10,
45 // prev 0x80
46 cmd_rreg = 0x20,
48 cmd_wreg = 0x40
50
63typedef union {
64 uint8_t value;
65 struct {
66 uint8_t vref : 1;
67 uint8_t mode : 1;
68 uint8_t dr : 2;
69 uint8_t gain : 1;
70 uint8_t mux : 3;
71 } bits;
72} ConfigReg;
73
79// const GPIO_TypeDef *data_ready_port = GPIOC;
80
85// const uint16_t data_ready_pin = GPIO_PIN_0;
86
100void power_on(void);
101
107void power_off(void);
108
116int measure(uint32_t* meas);
117
124int configure(const ConfigReg reg_data);
125
126int ads1219_reset(void) {
127 int ret = RETURNCODE_SUCCESS;
128
129 // Send the reset code
130 uint8_t write_buf[1] = {cmd_reset};
131 ret = i2c_master_write_sync(addrls, write_buf, 1);
132 if (ret != RETURNCODE_SUCCESS) {
133 return ADS1219_ERROR;
134 }
135
136 // wait minimum 500 us to reach steady state
137 libtocksync_alarm_delay_ms(1);
138
139 return ADS1219_SUCCESS;
140}
141
142int configure(const ConfigReg reg_data) {
143 int ret = RETURNCODE_SUCCESS;
144 uint8_t i2c_data[2] = {cmd_wreg, reg_data.value};
145 ret = i2c_master_write_sync(addrls, (uint8_t*)i2c_data, sizeof(i2c_data));
146 if (ret != RETURNCODE_SUCCESS) {
147 return ADS1219_CONFIGURE;
148 }
149
150 return ADS1219_SUCCESS;
151}
152
153int ads1219_voltage_raw(uint32_t* voltage) {
154 int ret = ADS1219_SUCCESS;
155
156 ConfigReg reg_data = {0};
157 reg_data.bits.vref = 1;
158
159 // 0x21 is single shot and 0x23 is continuos
160 // configure to read voltage
161 ret = configure(reg_data);
162 if (ret != ADS1219_SUCCESS) {
163 return ret;
164 }
165
166 ret = measure(voltage);
167 if (ret != ADS1219_SUCCESS) {
168 return ret;
169 }
170
171 return ret;
172}
173
174int ads1219_voltage(double* voltage) {
175 int ret = ADS1219_SUCCESS;
176
177 uint32_t raw = 0;
178 ret = ads1219_voltage_raw(&raw);
179
180 *voltage = (voltage_calibration_m * (double)raw) + voltage_calibration_b;
181 *voltage /= 1000;
182
183 return ret;
184}
185
186int ads1219_current_raw(uint32_t* current) {
187 int ret = ADS1219_SUCCESS;
188 double meas = 0.0;
189
190 ConfigReg reg_data = {0};
191 reg_data.bits.mux = 0b001;
192 reg_data.bits.vref = 1;
193
194 // 0x21 is single shot and 0x23 is continuos
195 // configure to read voltage
196 ret = configure(reg_data);
197 if (ret != ADS1219_SUCCESS) {
198 return -1;
199 }
200
201 ret = measure(current);
202 if (ret != ADS1219_SUCCESS) {
203 return -1;
204 }
205
206 return meas;
207}
208
209int ads1219_current(double* current) {
210 int ret = ADS1219_SUCCESS;
211
212 uint32_t raw = 0;
213 ret = ads1219_current_raw(&raw);
214
215 *current = (current_calibration_m * (double)raw) + current_calibration_b;
216 return ret;
217}
218
219void power_on(void) {
221 // HAL_GPIO_WritePin(POWERDOWN_GPIO_Port, POWERDOWN_Pin, GPIO_PIN_SET);
223 // HAL_Delay(1);
224}
225
226void power_off(void) {
228 // HAL_GPIO_WritePin(POWERDOWN_GPIO_Port, POWERDOWN_Pin, GPIO_PIN_RESET);
229}
230
231int measure(uint32_t* meas) {
232 int ret = RETURNCODE_SUCCESS;
233
234 uint8_t rx_data[3] = {0x00, 0x00, 0x00};
235
236 power_on();
237
238 // start conversion
239 uint8_t buf[1] = {cmd_start};
240 ret = i2c_master_write_sync(addrls, buf, 1);
241 if (ret != RETURNCODE_SUCCESS) {
242 return ADS1219_CONVERSION;
243 }
244
245 // constant delay
246 libtocksync_alarm_delay_ms(100);
247
248 // TODO(jmadden173) implement data ready pin wait
249 // Wait for the DRDY pin on the ADS12 to go low, this means data is ready
250 // while (HAL_GPIO_ReadPin(data_ready_port, data_ready_pin)) {}
251
252 // send read data command
253 buf[0] = cmd_rdata;
254 ret = i2c_master_write_sync(addrls, buf, 1);
255 if (ret != RETURNCODE_SUCCESS) {
256 return ADS1219_MEASURE;
257 }
258
259 // read 3 bytes of data
260 ret = i2c_master_read_sync(addrls, rx_data, 3);
261 if (ret != RETURNCODE_SUCCESS) {
262 return ADS1219_MEASURE;
263 }
264
265 power_off();
266
267 // Combine the 3 bytes into a 24-bit value
268 *meas = ((int32_t)rx_data[0] << 16) | ((int32_t)rx_data[1] << 8) |
269 ((int32_t)rx_data[2]);
270 // Check if the sign bit (24th bit) is set
271 if (*meas & 0x800000) {
272 // Extend the sign to 32 bits
273 *meas |= 0xFF000000;
274 }
275
276 return ADS1219_SUCCESS;
277}
278
279uint8_t ads1219_sensor_voltage(uint8_t* data, Metadata meta, uint32_t idx) {
280 (void)idx;
281
282 double voltage = 0.;
283 ads1219_voltage(&voltage);
284
285 // meta.logger_id = cfg->logger_id;
286 // meta.cell_id = cfg->cell_id;
287
288 size_t data_len = 0;
289
290 SensorStatus status = SENSOR_OK;
291 status = EncodeDoubleMeasurement(meta, voltage, SensorType_POWER_VOLTAGE,
292 data, &data_len);
293 if (status != SENSOR_OK) {
294 return -1;
295 }
296
297 return data_len;
298}
299
300uint8_t ads1219_sensor_current(uint8_t* data, Metadata meta, uint32_t idx) {
301 (void)idx;
302
303 double current = 0.;
304 ads1219_current(&current);
305
306 size_t data_len = 0;
307
308 SensorStatus status = SENSOR_OK;
309 status = EncodeDoubleMeasurement(meta, current, SensorType_POWER_CURRENT,
310 data, &data_len);
311 if (status != SENSOR_OK) {
312 return -1;
313 }
314
315 return data_len;
316}
void power_on(void)
GPIO port for adc data ready line.
Definition ads1219.c:219
void power_off(void)
Turn off power to analog circuit.
Definition ads1219.c:226
int measure(uint32_t *meas)
Measure from the adc.
Definition ads1219.c:231
ads1219_cmd_t
Definition ads1219.c:35
@ cmd_wreg
Definition ads1219.c:48
@ cmd_rreg
Definition ads1219.c:46
@ cmd_reset
Definition ads1219.c:37
@ cmd_start
Definition ads1219.c:39
@ cmd_rdata
Definition ads1219.c:43
@ cmd_powerdown
Definition ads1219.c:41
int configure(const ConfigReg reg_data)
This function reconfigures the ADS1219 based on the parameter reg_data.
Definition ads1219.c:142
This file contains all the function prototypes for the ads.c file.
const size_t data_len
const char data[]
int ads1219_current(double *current)
This function reads the current ADC ampere value.
Definition ads1219.c:209
uint8_t ads1219_sensor_voltage(uint8_t *data, Metadata meta, uint32_t idx)
Sensor measure functions.
Definition ads1219.c:279
int ads1219_reset(void)
This function starts up the ADS1219.
Definition ads1219.c:126
int ads1219_voltage_raw(uint32_t *voltage)
Definition ads1219.c:153
uint8_t ads1219_sensor_current(uint8_t *data, Metadata meta, uint32_t idx)
Definition ads1219.c:300
int ads1219_voltage(double *voltage)
This function reads the current ADC voltage value.
Definition ads1219.c:174
int ads1219_current_raw(uint32_t *current)
Definition ads1219.c:186
@ ADS1219_ERROR
Definition ads1219.h:46
@ ADS1219_CONFIGURE
Definition ads1219.h:47
@ ADS1219_CONVERSION
Definition ads1219.h:49
@ ADS1219_MEASURE
Definition ads1219.h:48
@ ADS1219_SUCCESS
Definition ads1219.h:45
SensorStatus EncodeDoubleMeasurement(Metadata meta, double value, SensorType type, uint8_t *buffer, size_t *size)
Encodes a double sensor measurement into a buffer.
Definition sensor.c:244
enum _SensorStatus SensorStatus
@ SENSOR_OK
Definition sensor.h:41
uint8_t vref
Definition ads1219.c:66
uint8_t gain
Definition ads1219.c:69
uint8_t value
Definition ads1219.c:64
uint8_t mode
Definition ads1219.c:67
uint8_t mux
Definition ads1219.c:70
struct ConfigReg::@0 bits
uint8_t dr
Definition ads1219.c:68