ENTS-tock
Environmental NeTworked Sensor firmware on Tock OS
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
5#include <libents/util/time.h>
6#include <libtock-sync/services/alarm.h>
7#include <libtock/kernel/ipc.h>
8#include <stdbool.h>
9#include <stdio.h>
10#include <ulog.h>
11
12static size_t core_service = 0;
13
14// buffer to share with core service
15static uint8_t core_buf[256] __attribute__((aligned(256)));
16
17// flag when ipc is don
18static bool done = false;
19
20static int meas_idx = 0;
21
22void ulog_prefix_handler(ulog_event* ev, char* prefix, size_t prefix_size);
23
31static void ipc_callback(int pid, int len, int buf, void* ud) {
32 (void)pid;
33 (void)len;
34 (void)buf;
35 (void)ud;
36
37 done = true;
38}
39
47typedef uint8_t (*SensorsPrototypeMeasure)(uint8_t* data, Metadata meta,
48 uint32_t idx);
49
51
52int load_userconfig(void);
53
54void wait_for_ready(void);
55
57 ulog_trace("measure_sensor");
58
59 // payload format
60 uint8_t* cmd = core_buf;
61 uint8_t* length = core_buf + 1;
62 uint8_t* data = core_buf + 2;
63
64 // send measurement command
65 *cmd = 2;
66
67 // get metadata
68 const UserConfiguration* cfg = UserConfigGet();
69
70 Metadata meta = {};
71 meta.ts = epoch();
72 meta.logger_id = cfg->logger_id;
73 meta.cell_id = cfg->cell_id;
74
75 // store measurement in buffer
76 *length = cb(data, meta, meas_idx++);
77
78 // check for errors in cb
79 if (*length < 255) {
80 // Send to core for upload and wait for completion
81 ipc_notify_service(core_service);
82 yield_for(&done);
83 done = false;
84
85 // Write to SD card
86#ifdef SAVE_TO_MICROSD
88#endif
89 }
90
91 return *length;
92}
93
94int load_userconfig(void) {
95 ulog_trace("load_userconfig");
96
97 // payload format
98 uint8_t* cmd = core_buf;
99 uint8_t* length = core_buf + 1;
100 uint8_t* data = core_buf + 2;
101
102 *cmd = 1;
103
104 // Send to core for upload
105 ipc_notify_service(core_service);
106 yield_for(&done);
107
108 UserConfigStatus uc_status = UserConfigLoadBytes(data, *length);
109
110 done = false;
111
112 return uc_status;
113}
114
115void wait_for_ready(void) {
116 ulog_trace("wait_for_ready");
117
118 bool ready = false;
119
120 core_buf[0] = 3;
121
122 while (!ready) {
123 // Send to core for upload
124 ipc_notify_service(core_service);
125 yield_for(&done);
126
127 // check ready flag
128 ready = (bool)core_buf[1];
129
130 done = false;
131
132 // wait 1 second before checking again
133 libtocksync_alarm_delay_ms(5000);
134 }
135}
136
137void ulog_prefix_handler(ulog_event* ev, char* prefix, size_t prefix_size) {
138 (void)ev;
139
140 snprintf(prefix, prefix_size, "Sensors\t");
141}
142
143int main() {
144 // This is required to delay the sensors app to start after core
145 libtocksync_alarm_delay_ms(500);
146
147 // set logging level and prefix
148 ulog_output_level_set_all(ULOG_LEVEL_TRACE);
149 ulog_prefix_set_fn(ulog_prefix_handler);
150 ulog_info("=== Sensors App Initialized ===");
151
152 // return code
153 int ret = 0;
154
155 // setup ipc for uplaods
156 ret = ipc_discover("org.ents.core", &core_service);
157 if (ret < 0) {
158 ulog_fatal("No core service %d", ret);
159 return -1;
160 } else {
161 ulog_info("Found core service");
162 }
163
164 // register ipc callback with buffer
165 ipc_register_client_callback(core_service, ipc_callback, NULL);
166 ipc_share(core_service, core_buf, 256);
167
168 // wait for network configuration to be ready
170
171 //
172 // Get user config code
173 //
174
175 ret = load_userconfig();
176 if (ret == USERCONFIG_OK) {
177 // print current user config
178 ulog_info("Current user config:");
180 } else {
181 ulog_error("Could not load user config.");
182 }
183
184 const UserConfiguration* cfg = UserConfigGet();
185
186 // currently not functional
187 // NOTE for initializing state
188 // FIFO_Init();
189
190 // setup repeating measurement call
191 uint32_t period_ms = (uint32_t)(cfg->Upload_interval * 1000);
192
193 //
194 // Infinite measurement loop
195 //
196
197 while (1) {
198 static bool init = false;
199
200 // configure enabled sensors
201 for (int i = 0; i < cfg->enabled_sensors_count; i++) {
202 EnabledSensor sensor = cfg->enabled_sensors[i];
203
204 if (sensor == EnabledSensor_Voltage || sensor == EnabledSensor_Current) {
205 if (!init) {
206 ret = ads1219_reset();
207 if (ret < 0) {
208 ulog_error("Could not reset ads1219.");
209 }
210 }
211 }
212
213 // Voltage channel is used by multiple different sensors
214 if (sensor == EnabledSensor_Voltage) {
215#if !defined(USE_FLOW_METER_SENSOR) && !defined(USE_WATER_PRESSURE_SENSOR) && \
216 !defined(USE_CAP_SOIL_SENSOR) && !defined(USE_PHYTOS31_SENSOR)
217#define DEFAULT
218#endif
219
220#ifdef DEFAULT
222 ulog_info("Measured Voltage");
223#endif
224
225#ifdef USE_FLOW_METER_SENSOR
226 if (!init) {
227 FlowInit();
228 ulog_info("Initialized flow meter");
229 }
230 measure_sensor(WatFlow_measure);
231 ulog_info("Measured Flow Meter");
232#endif
233
234#ifdef USE_WATER_PRESSURE_SENSOR
235 if (!init) {
236 PressureInit();
237 ulog_info("Initialized Water Pressure");
238 }
239 measure_sensor(WatPress_measure);
240 ulog_info("Measured Water Pressure Sensor");
241#endif
242
243#ifdef USE_CAP_SOIL_SENSOR
244 if (!init) {
245 CapSoilInit();
246 ulog_info("Initialized Cap Soil");
247 }
248 measure_sensor(SEN0308_measure);
249 ulog_info("Measured Cap Soil Sensor");
250#endif
251
252#ifdef USE_PHYTOS31_SENSOR
253
254#endif
255 }
256
257 if (sensor == EnabledSensor_Current) {
259 ulog_info("Measured Current");
260 }
261 // if (sensor == EnabledSensor_Teros12) {
262 // ulog_info("Teros12");
263 // measure_sensor(Teros12Measure);
264 // }
265 // if (sensor == EnabledSensor_Teros21) {
266 // measure_sensor(Teros21Measure);
267 // ulog_info("Teros21");
268 // }
269 if (sensor == EnabledSensor_BME280) {
270 if (!init) {
271 BME280Init();
272 ulog_info("Initialized BME280");
273 }
277 ulog_info("Measured BME280");
278 }
279 // if (sensor == EnabledSensor_Phytos31) {
280 // Phytos31Init();
281 // measure_sensor(Phytos31_measure);
282 // ulog_info("Phytos31");
283 // }
284 // if (sensor == EnabledSensor_SEN0308) {
285 // CapSoilInit();
286 // measure_sensor(SEN0308_measure);
287 // ulog_info("SEN0308 Cap Soil Sensor");
288 // }
289 // if (sensor == EnabledSensor_SEN0257) {
290 // PressureInit();
291 // measure_sensor(WatPress_measure);
292 // ulog_info("SEN0257 Water Pressure Sensor");
293 // }
294 // if (sensor == EnabledSensor_YFS210C) {
295 // FlowInit();
296 // measure_sensor(WatFlow_measure);
297 // ulog_info("YFS210C Flow Meter");
298 // }
299 // if (sensor == EnabledSensor_PCAP02) {
300 // pcap02_init();
301 // measure_sensor(pcap02_measure);
302 // ulog_info("PCAP02");
303 //}
304 // TODO add support for dummy sensor
305 }
306
307 // set initialized flag
308 init = true;
309
310 libtocksync_alarm_delay_ms(period_ms);
311 }
312
313 return 0;
314}
This file contains all the function prototypes for the ads.c file.
int main()
Definition main.c:4
void wait_for_ready(void)
Definition main.c:115
void ulog_prefix_handler(ulog_event *ev, char *prefix, size_t prefix_size)
Definition main.c:137
uint8_t(* SensorsPrototypeMeasure)(uint8_t *data, Metadata meta, uint32_t idx)
Function prototype for measure functions.
Definition main.c:47
int load_userconfig(void)
Definition main.c:94
int measure_sensor(SensorsPrototypeMeasure cb)
Definition main.c:56
BME280Status BME280Init(void)
uint8_t BME280MeasureHumidity(uint8_t *data, Metadata meta, uint32_t idx)
uint8_t BME280MeasureTemperature(uint8_t *data, Metadata meta, uint32_t idx)
BME280 sensor library function.
uint8_t BME280MeasurePressure(uint8_t *data, Metadata meta, uint32_t idx)
Sensor interface for the BME280 sensor.
const char data[]
uint8_t i
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
uint8_t ads1219_sensor_current(uint8_t *data, Metadata meta, uint32_t idx)
Definition ads1219.c:300
uint32_t ControllerMicroSDSave(const uint8_t *data, const uint16_t num_bytes)
Save data to the microSD card. Appends data to already-created files, otherwise creates a new file.
Definition microsd.c:12
void UserConfigPrint(void)
Prints the current user configuration over serial.
const UserConfiguration * UserConfigGet(void)
Gets a reference to the loaded user configuration data in RAM.
UserConfigStatus UserConfigLoadBytes(uint8_t *buffer, uint16_t length)
Load user config from bytes.
UserConfigStatus
Definition user_config.h:51
@ USERCONFIG_OK
Definition user_config.h:52
uint32_t epoch(void)
Gets the current unix epoch timestamp.
Definition time.c:19
Library for sensor measurement encoding/decoding.