SingingCat 0
application
sensor.c
Go to the documentation of this file.
1#include <sensors/sensor.h>
2#include <platform-header.h>
3//#include <string.h>
5
23struct sensordev sensors[] = {
24 { 0, &onewire_init, NULL, &onewire_reading_size, &onewire_run, NULL, "ow1:ds18b20", "temp", "celsius", "centi", 207 },
25 { 0, &onewire_init, NULL, &onewire_reading_size, &onewire_run, NULL, "ow2:ds18b20", "temp", "celsius", "centi", 211 },
26 { 0, &onewire_init, NULL, &onewire_reading_size, &onewire_run, NULL, "ow3:ds18b20", "temp", "celsius", "centi", 212 },
27 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
28 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
29 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
30 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
31 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
32 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
33 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
34 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
35 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
36 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
37 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
38 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
39 { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0 },
40};
41
46typedef struct sensorconfig {
47 const struct sensordev * sensor; /* pointer to the sensor in question */
48 long target; /* where to submit it to */
49 int readmillis; /* how many milliseconds between reads */
50 int submitsecs; /* how may seconds between submitting results to server */
51 int max_values; /* how many values to max read between submits. (buffersize) */
53
57static struct sensorconfig defaultconfig = { NULL, CLOUD_SERVER, 60000, 60, 1 };
58static uint8_t inited = 0;
59static void sensors_timer_irq();
60
66static struct sensorconfig sensorconfigs[15];
67
68#define SENSOR_FLAG_ENABLED 0
69#define SENSOR_FLAG_ISDUE 1
70#define SENSOR_FLAG_DETECTED 2
71#define SENSOR_FLAG_PROBED 3
72// used new-style if the server activated this sensor
73#define SENSOR_FLAG_ACTIVATED 4
74// if the sensor was registered by the userapp (so we can dynamically deregister it too)
75
79static struct sensorruntime runtime[10];
80
84#define SENSOR_TIMER_FREQUENCY 1000
88#define SENSOR_TIMER 4
89
93static byte irqstatus;
97static uint8_t runtime_invalid;
102static byte sensorbuf[1000];
106static byte sensors_enabled;
107
108
109#define isOldStyleEnabled (sensors_enabled & (1 << 0))
110#define isNewStyleEnabled (sensors_enabled & (1 << 1))
111#define isProbing (sensors_enabled & (1 << 2))
112
116static const struct sensorconfig *getconfig(const struct sensordev *sensor) {
117 const struct sensorconfig *res;
118 int i;
119
120 if (sensor == NULL) {
121 return NULL;
122 }
123 res = NULL;
124 for (i = 0; i < (sizeof(sensorconfigs) / sizeof(sensorconfigs[0])); i++) {
125 res = &sensorconfigs[i];
126 if (res->sensor == sensor) {
127 return res;
128 }
129 }
130 return &defaultconfig;
131}
132
133static void add_value(struct sensorruntime *sr, int val);
134static void reset_if_needed(struct sensorruntime *sr);
135
136static void disable_irq() {
137 irqstatus |= 2; // forbid irq
138 while (irqstatus & 1) {
139 // wait for irq to finish
140 }
141}
142
143static void addflagstr(char *res, int bufsize, byte flags, byte flag, char *truestr, char *falsestr) {
144 char *cpy = falsestr;
145
146 if (flags & (1 << flag)) {
147 cpy = truestr;
148 }
149 char *xr = res + strlen(res);
150
151 strncpy(xr, cpy, 100);
152 xr[strlen(cpy)] = ' ';
153 xr[strlen(cpy) + 1] = 0;
154}
155static void sensorflags2str(byte flags, char *res, int bufsize) {
156 res[0] = 0;
157 addflagstr(res, bufsize, flags, SENSOR_FLAG_ENABLED, "ENABLED", "DISABLED");
158 addflagstr(res, bufsize, flags, SENSOR_FLAG_ISDUE, "DUE", "IDLE");
159 addflagstr(res, bufsize, flags, SENSOR_FLAG_DETECTED, "DETECTED", "NOT_DETECTED");
160 addflagstr(res, bufsize, flags, SENSOR_FLAG_PROBED, "PROBED", "NOT_PROBED");
161 addflagstr(res, bufsize, flags, SENSOR_FLAG_ACTIVATED, "ACTIVATED", "NOT_ACTIVATED");
162}
163
164static void enable_irq() {
165 irqstatus &= ~2; // allow irq
166}
167
168static void enable_sensor(struct sensorruntime *sr) {
169 sr->flags |= (1 << SENSOR_FLAG_ENABLED);
170}
171static void disable_sensor(struct sensorruntime *sr) {
172 sr->flags &= ~(1 << SENSOR_FLAG_ENABLED);
173}
174static void clr_sensor_flag(struct sensorruntime *sr, int flag) {
175 sr->flags &= ~(1 << flag);
176}
177static void set_sensor_flag(struct sensorruntime *sr, int flag) {
178 sr->flags |= (1 << flag);
179}
180static int is_sensor_flag(struct sensorruntime *sr, int flag) {
181 return sr->flags & (1 << flag);
182}
183static void sensor_detected(struct sensorruntime *sr) {
184 set_sensor_flag(sr, SENSOR_FLAG_DETECTED);
185}
186
187
188static void add_value(struct sensorruntime *sr, int value) {
189 if (sr->valuesize == 1) {
190 sr->buf[sr->bytesinbuf++] = value & 0xFF;
191 sr->last_value_uint8 = value & 0xFF;
192 } else if (sr->valuesize == 2) {
193 sr->buf[sr->bytesinbuf++] = value & 0xFF;
194 sr->buf[sr->bytesinbuf++] = (value >> 8) & 0xFF;
195 sr->last_value_uint16 = value & 0xFFFF;
196 } else if (sr->valuesize == 4) {
197 sr->buf[sr->bytesinbuf++] = value & 0xFF;
198 sr->buf[sr->bytesinbuf++] = (value >> 8) & 0xFF;
199 sr->buf[sr->bytesinbuf++] = (value >> 16) & 0xFF;
200 sr->buf[sr->bytesinbuf++] = (value >> 24) & 0xFF;
201 sr->last_value_uint32 = value;
202 }
203 sr->values++;
204}
205
206static uint32_t get_value(struct sensorruntime *sr, int val) {
207 if (val >= sr->values) {
208 return 0;
209 }
210 uint32_t res = 0;
211
212 if (sr->valuesize == 1) {
213 byte b = sr->buf[val];
214 res = b;
215 } else if (sr->valuesize == 2) {
216 byte b = sr->buf[val * 2 + 1];
217 res = b;
218 res = res << 8;
219 res = res | ((sr->buf[val * 2]) & 0xFF);
220 } else if (sr->valuesize == 4) {
221 int i;
222 res = 0;
223 for (i = 0; i < 4; i++) {
224 uint32_t b = sr->buf[val * 4 + i];
225 res = res | (b << (8 * i));
226 }
227 }
228 return res;
229}
233static void clear_buf(struct sensorruntime *sr) {
234 disable_irq();
235 sr->bytesinbuf = 0;
236 sr->values = 0;
237 enable_irq();
238}
239
243static void init_runtime(const struct sensordev *sd, struct sensorruntime *sr) {
244 memset(sr, 0, sizeof(struct sensorruntime));
245 sr->sensor = sd;
246 sr->valuesize = (uint16_t)sr->sensor->get_reading_size(sd->sensorindex);
247}
248
249static int calc_bufsize(struct sensorruntime *sr) {
250 const struct sensorconfig *sc;
251
252 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
253 return 0;
254 }
255 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
256 return 0;
257 }
258 if (!is_sensor_flag(sr, SENSOR_FLAG_ACTIVATED)) {
259 return 0;
260 }
261
262 sc = getconfig(sr->sensor);
263 int size = sr->valuesize;
264 int vals = (sc->submitsecs * 1000) / sc->readmillis;
265
266 if (sc->max_values < vals) {
267 vals = sc->max_values;
268 }
269 int res = vals * size;
270
271 // only ever even sizes please.
272 if (res & 1) {
273 res++;
274 }
275 return res;
276}
277
282 const struct sensordev *sd;
283 struct sensorruntime *sr;
284
285 printf("[sensor] updating runtimes\r\n");
286 disable_irq();
287 memset(sensorbuf, 0, sizeof(sensorbuf));
288 int offset = 0;
289 int i;
290
291 // go through all known runtimes
292 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
293 sr = &runtime[i];
294 sd = sr->sensor;
295 sr->bufsize = 0;
296 sr->buf = NULL;
297 if (sd == NULL) {
298 continue;
299 }
300 if ((sd->power_on == NULL) || (sd->get_reading == NULL)) {
301 continue;
302 }
303 int bufsize = calc_bufsize(sr);
304 if (bufsize == 0) {
305 continue;
306 }
307 sr->bufsize = bufsize;
308 sr->buf = (sensorbuf + offset);
309 offset = offset + bufsize;
310 if (offset >= sizeof(sensorbuf)) {
311 enable_irq();
312 printf("At sensor %i, buf overflow: %i\r\n", i, offset);
313 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
314 sr = &runtime[i];
315 sd = sr->sensor;
316 if (sd == NULL) {
317 continue;
318 }
319 if ((sd->power_on == NULL) || (sd->get_reading == NULL)) {
320 continue;
321 }
322 int bufsize = calc_bufsize(sr);
323 printf("Sensor %i, bufsize: %i\r\n", i, bufsize);
324 }
325 return 5;
326 }
327 }
328 enable_irq();
329 runtime_invalid = 0;
330 return 0;
331}
332
337static void init_all_runtime() {
338 const struct sensordev *sd;
339 const struct sensorconfig *sc;
340
341 int r;
342 int t = 2;
343
344 disable_irq();
345 memset(runtime, 0, sizeof(runtime));
346 memset(sensorbuf, 0, sizeof(sensorbuf));
347
348 int offset = 0;
349
350 // go through all known sensors and init their runtime
351 t = 0;
352 r = 0;
353 while (((sd = &sensors[t])->power_on) != NULL) {
354 t++;
355 if (sd->get_reading == NULL) {
356 printf("[sensor] Sensor does not support reading a value - sensor skipped.\r\n");
357 continue;
358 }
359 init_runtime(sd, &runtime[r]);
360 sc = getconfig(sd);
361 int bufsize = calc_bufsize(&runtime[r]);
362 printf("[sensor] Sensor %s:\r\n", sd->name);
363 printf("[sensor] read every %i milliseconds\r\n", sc->readmillis);
364 printf("[sensor] submit every %i seconds\r\n", sc->submitsecs);
365 printf("[sensor] one reading is %i bytes\r\n", sd->get_reading_size(sd->sensorindex));
366 printf("[sensor] %i bytes between submits\r\n", bufsize);
367 runtime[r].bufsize = bufsize;
368 runtime[r].buf = (sensorbuf + offset);
369 disable_sensor(&runtime[r]);
370 reset_if_needed(&runtime[r]);
371
372 offset = offset + bufsize;
373 r++;
374 }
375 enable_irq();
376}
377
378
383 //printf("[sensor] Sensors disabled in code (timer issues)\r\n");
384 //return;
385 const struct sensordev *sd;
386 int r;
387
388 runtime_invalid = 0;
389 memset(sensorconfigs, 0, sizeof(sensorconfigs));
390 memset(runtime, 0, sizeof(runtime));
391 irqstatus = 0;
392 // go through all known sensors, power them up and init their runtime
393 int t = 0;
394
395 r = 0;
396 while (((sd = &sensors[t])->power_on) != NULL) {
397 t++;
398 if (sd->name != NULL) {
399 printf("[sensor] Initializing sensor #%i: %s\r\n", t, sd->name);
400 } else {
401 printf("[sensor] Initializing sensor #%i: [noname]\r\n", t);
402 }
403 if (sd->get_reading == NULL) {
404 printf("[sensor] Sensor does not support reading a value - sensor skipped.\r\n");
405 continue;
406 }
407 sd->power_on(sd->sensorindex);
408 r++;
409 }
410 init_all_runtime();
411 // last but not least - enable the timer
412 if ((r = mculib_timer_enable_simple(MAIN_MCULIBHANDLE, SENSOR_TIMER, SENSOR_TIMER_FREQUENCY, &sensors_timer_irq))) {
413 printf("[sensor] Failed to activate timer %i for TLI4970: %i\r\n", SENSOR_TIMER, r);
414 return;
415 }
416 sensors_enabled = 5; // enable old-style only and set it to probe mode
417 inited = 1;
418 printf("[sensor] Sensors initialized\r\n");
419}
423static void reset_if_needed(struct sensorruntime *sr) {
424 char buf[100];
425 int res;
426 const struct sensordev *sd;
427
428 sd = sr->sensor;
429 if (sd->get_status == NULL) {
430 enable_sensor(sr); // we can't check status, assume it's ok
431 return;
432 }
433 sd->get_status(sd->sensorindex, (char *)&buf, sizeof(buf), &res);
434 if (res == 0) {
435 enable_sensor(sr);
436 return;
437 }
438 disable_sensor(sr);
439 printf("[sensor] Status: %i (%s) - resetting\r\n", res, buf);
440 if (sd->power_down != NULL) {
441 printf("[sensor] power off\r\n");
442 sd->power_down(sd->sensorindex);
443 Delay(50);
444 }
445 if (sd->power_on != NULL) {
446 printf("[sensor] power on\r\n");
447 sd->power_on(sd->sensorindex);
448 Delay(30);
449 printf("[sensor] power cycle complete\r\n");
450 }
451 sd->get_status(sd->sensorindex, (char *)&buf, sizeof(buf), &res);
452 if (res == 0) {
453 enable_sensor(sr);
454 return;
455 }
456}
457
458static void send_values(const struct sensorconfig *sc, struct sensorruntime *sr) {
459 struct command *com = alloc_command();
460 const struct sensordev *sd;
461
462 sd = sr->sensor;
463 if (com == NULL) {
464 printf("[sensor] Cannot send command - no command space available\r\n");
465 return;
466 }
467 command_init(com);
468 com->recipient = 0;
469 com->target = sc->target;
470 com->flags = COMFLAGS_SUCCESS;
471 com->com = 22;
472 command_add_arg(com, sd->name);
473 command_add_arg(com, "1");
474 command_add_arg(com, sd->type);
475 command_add_arg(com, sd->unit);
476 command_add_arg(com, sd->unit_prefix);
477 char buf[150];
478 int k;
479
480 memset(buf, 0, sizeof(buf));
481 disable_irq();
482 for (k = 0; k < sr->values; k++) {
483 if (sr->valuesize < 4) {
484 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X;", get_value(sr, k));
485 } else {
486 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%N;", get_value(sr, k));
487 }
488 if (strlen(buf) >= sizeof(buf)) {
489 break;
490 }
491 }
492 enable_irq();
493 clear_buf(sr);
494 //printf("[sensor] Args: \"%s\"\r\n",buf);
495 command_add_arg(com, "%s", buf);
496 deliver_command(com, NULL);
497}
498
499void sensor_info() {
500 const struct sensordev *sd;
501 struct sensorruntime *sr;
502 int i;
503
504 char buf[100];
505 int status;
506
507 printf("[sensor] Sensor info at %i:\r\n", mculib_get_seconds_since_boot());
508 printf("[sensor] timerfrequency: %iHz\r\n", SENSOR_TIMER_FREQUENCY);
509 printf("[sensor] Enabled status: %i\r\n", sensors_enabled);
510 char flagstr[100];
511
512 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
513 sr = &runtime[i];
514 sd = sr->sensor;
515 if (sd == NULL) {
516 continue;
517 }
518 snprintf(buf, sizeof(buf), "n/a");
519 status = 0;
520 if (sd->get_status != NULL) {
521 sd->get_status(sd->sensorindex, (char *)&buf, sizeof(buf), &status);
522 }
523 sensorflags2str(sr->flags, (char *)&flagstr, sizeof(flagstr));
524 const struct sensorconfig *sc = getconfig(sd);
525 printf("[sensor] Sensor #%i: %s\r\n", i, sd->name);
526 printf("[sensor] status : %i (%s)\r\n", status, buf);
527 printf("[sensor] flags : %i (%s)\r\n", (int)sr->flags, flagstr);
528 printf("[sensor] values : %i\r\n", (int)sr->values);
529 printf("[sensor] bytes : %i\r\n", (int)sr->bytesinbuf);
530 printf("[sensor] bufsize : %i\r\n", sr->bufsize);
531 printf("[sensor] maxvals : %i\r\n", sc->max_values);
532 printf("[sensor] runsecs : %i\r\n", (int)sr->runsecs);
533 printf("[sensor] read : every %i millis\r\n", sc->readmillis);
534 pretty_node_to_str(sc->target, buf);
535 printf("[sensor] submit : every %i secs to %s\r\n", sc->submitsecs, buf);
536 }
537 printf("[sensor] End sensor info\r\n");
538}
539
540struct sensorruntime *get_runtime(int idx) {
541 struct sensorruntime *sr;
542
543 sr = &runtime[idx];
544 return sr;
545}
546
547/*
548 * \*brief set the configuration for a given sensor. idx=0..n return 0 if ok
549 */
550int sensor_update_config(const long nodeid, int idx, const int readmillis, const int submitsec, const int max_values) {
551 struct sensorruntime *sr;
552 const struct sensordev *sd;
553 struct sensorconfig *sc;
554 struct sensorconfig *res;
555 int i;
556
557 if ((readmillis == 0) || (submitsec == 0) || (max_values == 0)) {
558 return 1;
559 }
560 sr = get_runtime(idx);
561 if (sr == NULL) {
562 printf("[sensor] No such sensor \"%i\"\r\n", idx);
563 return 2;
564 }
565 sd = sr->sensor;
566 sc = (struct sensorconfig *)getconfig(sd);
567
568 if ((sc == NULL) || (sc == &defaultconfig)) {
569 // create new config entry!
570 sc = NULL;
571 for (i = 0; i < (sizeof(sensorconfigs) / sizeof(sensorconfigs[0])); i++) {
572 res = &sensorconfigs[i];
573 if (res->sensor == NULL) {
574 sc = res;
575 break;
576 }
577 }
578 if (sc == NULL) {
579 printf("[sensor] No more free sensor config entries.\r\n");
580 return 3;
581 }
582 }
583
584 // sc -> pointer to config to be updated to initialized
585 sc->sensor = sd;
586 sc->target = nodeid;
587 sc->readmillis = readmillis;
588 sc->submitsecs = submitsec;
589 sc->max_values = max_values;
590 int r = update_all_runtimes(); // recalculate buffers
591
592 if (r != 0) {
593 printf("[sensor] failed to update runtime (%i)\r\n", r);
594 return r;
595 }
596 // init_all_runtime(); // cannot do that, because it will overwrite flags
597 return 0;
598}
599
600int sensor_submit_request(const long nodeid, int idx, const int readmillis, const int submitsec, const int max_values) {
601 char buf[100];
602
603 pretty_node_to_str(nodeid, buf);
604 printf("[sensor] Got request from %s for sensor %i, read every %i millis, submit every %i seconds, maximum values %i\r\n",
605 buf,
606 idx,
607 readmillis,
608 submitsec,
609 max_values);
610 int x = sensor_update_config(nodeid, idx, readmillis, submitsec, max_values);
611
612 if (x != 0) {
613 printf("[sensor] Sensor request failed: %i\r\n", x);
614 return x;
615 }
616 return 1;
617}
622 sensors_enabled &= ~(1 << 0);
623 sensors_enabled |= (1 << 1);
624}
625
630 int r;
631
632 sensors_enabled &= ~(1 << 0);
633 if ((r = mculib_timer_disable(MAIN_MCULIBHANDLE, SENSOR_TIMER)) != 0) {
634 printf("[sensor] Failed to disable timer %i: %i\r\n", SENSOR_TIMER, r);
635 return;
636 }
637 printf("[sensor] Sensor timer disabled\r\n");
638}
639
644struct sensordev *sensor_register(struct sensordev *sensor) {
645 sensors_off();
646 int t = 0;
647
648 int max = sizeof(sensors) / sizeof(struct sensordev);
649
650 while ((sensors[t].power_on) != NULL) {
651 t++;
652 if (t >= max) {
653 printf("[sensor] No sensor entry available to register sensor. (max=%i,t=%i)\r\n", max, t);
654 return NULL;
655 }
656 }
657 int i;
658 byte *source = (void *)sensor;
659 byte *target = (void *)&sensors[t];
660
661 for (i = 0; i < sizeof(struct sensordev); i++) {
662 target[i] = source[i];
663 }
664 sensors_init();
665 if (sensor->name != NULL) {
666 printf("[sensor] Sensor %s registered\r\n", sensor->name);
667 } else {
668 printf("[sensor] extra sensor with no name registered\r\n");
669 }
670 return &sensors[t];
671}
672
673static int isDigit(char c) {
674 if ((c >= '0') && (c <= '9')) {
675 return 1;
676 }
677 return 0;
678}
679
683static int parse_numbers(const char *str, int bufcount, int buf[]) {
684 int res = 0;
685 int i;
686 int state = 0;
687
688 for (i = 0; i < strlen(str); i++) {
689 char c = str[i];
690 if (state == 0) {
691 if (!isDigit(c)) {
692 continue;
693 }
694 state = 1;
695 buf[res++] = atoi(str + i);
696 }
697 if (state == 1) {
698 if (!isDigit(c)) {
699 state = 0;
700 continue;
701 }
702 }
703 }
704 return res;
705}
706void sensor_run_str(const char *str) {
707 struct sensorruntime *sr;
708 const struct sensordev *sd;
709 int buf[3];
710
711 printf("[sensor] Sensor run \"%s\"\r\n", str);
712 int r = parse_numbers(str, (sizeof(buf) / sizeof(buf[0])), (int *)&buf);
713
714 if (r != 2) {
715 printf("[sensor] Need exactly 2 digits [s a] (s=sensor index, a=action]. got %i. Aborted.\r\n", r);
716 return;
717 }
718
719 int sensor = buf[0];
720 int action = buf[1];
721
722 int ms = (sizeof(runtime) / sizeof(runtime[0]));
723
724 if (sensor >= ms) {
725 printf("[sensor] Sensor index out of range: %i (0-%i)\r\n", sensor, ms);
726 return;
727 }
728 sr = &runtime[sensor];
729 sd = sr->sensor;
730 if (sd == NULL) {
731 printf("[sensor] No sensor #%i\r\n", sensor);
732 return;
733 }
734 printf("[sensor] Sensor \"%s\": %i\r\n", sd->name, action);
735 if (action == 0) {
736 printf("[sensor] power_on(): %i\r\n", sd->power_on(sd->sensorindex));
737 } else if (action == 1) {
738 printf("[sensor] power_down(): %i\r\n", sd->power_down(sd->sensorindex));
739 } else if (action == 2) {
740 printf("[sensor] get_reading_size() == %i\r\n", sd->get_reading_size(sd->sensorindex));
741 } else if (action == 3) {
742 byte error = 0;
743 printf("[sensor] get_reading() == %i\r\n", sd->get_reading(sd->sensorindex, &error));
744 } else if (action == 4) {
745 char buf[100];
746 int st;
747 sd->get_status(sd->sensorindex, (char *)&buf, 100, &st);
748 printf("[sensor] get_status() == %s %i\r\n", buf, st);
749 } else {
750 printf("[sensor] Invalid action (0=pwron,1=pwroff,2=readingsize,3=reading,4=status\r\n");
751 }
752}
753
754int all_sensors_probed() {
755 struct sensorruntime *sr;
756 int i;
757
758 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
759 sr = &runtime[i];
760 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
761 continue;
762 }
763 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
764 return 0;
765 }
766 }
767 return 1;
768}
769
770
771void sensor_activation(struct sensorruntime *sr, int activation) {
772 if (activation) {
773 sr->flags |= (1 << SENSOR_FLAG_ACTIVATED);
774 } else {
775 sr->flags &= ~(1 << SENSOR_FLAG_ACTIVATED);
776 }
777}
778
779/***************************************************************
780* functions to probe stuff
781***************************************************************/
782void sensor_probe() {
783 const struct sensordev *sd;
784 struct sensorruntime *sr;
785
786 int i;
787
788 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
789 sr = &runtime[i];
790 sd = sr->sensor;
791 if (sd == NULL) {
792 continue;
793 }
794 // only probe each sensor once
795 if (is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
796 continue;
797 }
798 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
799 disable_irq();
800 reset_if_needed(sr);
801 enable_irq();
802 }
803 // if sensor requires IRQ, don't process it here...
804 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
805 continue;
806 }
807 byte error = 0;
808 clr_sensor_flag(sr, SENSOR_FLAG_DETECTED);
809 sd->get_reading(sd->sensorindex, &error);
810 if (error == 0) {
811 sensor_detected(sr);
812 }
813 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
814 clr_sensor_flag(sr, SENSOR_FLAG_ISDUE);
815 }
816
817 // check if all are probed, if so, finish probemode
818 int done = 1;
819
820 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
821 sr = &runtime[i];
822 sd = sr->sensor;
823 if (sd == NULL) {
824 continue;
825 }
826 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
827 done = 0;
828 break;
829 }
830 }
831 if (done) {
832 sensors_enabled &= ~(1 << 2); // stop probing mode.
833 }
834}
835uint8_t sensors_inited() {
836 return inited;
837}
838/***************************************************************
839* functions to determine if sensors are due
840***************************************************************/
846 if (runtime_invalid) {
848 }
849 if (!sensors_inited()) {
850 return 0;
851 }
852 if (isProbing) {
853 sensor_probe();
854 return 0;
855 }
856 const struct sensordev *sd;
857 struct sensorruntime *sr;
858
859 int i;
860 int got_values = 0;
861
862 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
863 sr = &runtime[i];
864 sd = sr->sensor;
865 if (sd == NULL) {
866 continue;
867 }
868
869 const struct sensorconfig *sc = getconfig(sd);
870 // if sensor is disabled it might still need resetting!
871 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
872 if (!mculib_has_time_passed(sc->submitsecs < 30 ? 30 : sc->submitsecs, &sr->runsecs)) {
873 continue;
874 }
875 printf("[sensor] Sensor %s is disabled, resetting it.\r\n", sd->name);
876 reset_if_needed(sr);
877 continue;
878 }
879
880 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
881 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
882 byte error = 0;
883 int value = sd->get_reading(sd->sensorindex, &error);
884 if (error == 0) {
885 sensor_detected(sr);
886 add_value(sr, value);
887 }
888 clr_sensor_flag(sr, SENSOR_FLAG_ISDUE);
889 }
890
891 if (sr->values == 0) {
892 continue;
893 }
894
895 if (!mculib_has_time_passed(sc->submitsecs, &sr->runsecs)) {
896 continue;
897 }
898 printf("[sensor] Sensor %s has %i values ready to submit\r\n", sd->name, sr->values);
899 send_values(sc, sr);
900 got_values = 1;
901 reset_if_needed(sr);
902 }
903 return got_values;
904}
910static void sensors_timer_irq() {
911 if (irqstatus & 2) {
912 return;
913 }
914
915 if (isProbing) {
916 const struct sensordev *sd;
917 struct sensorruntime *sr;
918 /* probing - due are _any_ that are not yet probed*/
919 int i;
920 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
921 sr = &runtime[i];
922 sd = sr->sensor;
923 if (sd == NULL) {
924 continue;
925 }
926 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
927 continue;
928 }
929 if (is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
930 continue;
931 }
932 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
933 continue;
934 }
935 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
936 byte error = 0;
937 int value = sd->get_reading(sd->sensorindex, &error);
938 if (error == 0) {
939 sensor_detected(sr);
940 add_value(sr, value);
941 }
942 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
943 }
944 }
945 return;
946 }
947
948 /* not probing */
949 irqstatus |= 1;
950 const struct sensordev *sd;
951 struct sensorruntime *sr;
952 int i;
953
954 for (i = 0; i < (sizeof(runtime) / sizeof(runtime[0])); i++) {
955 sr = &runtime[i];
956 sd = sr->sensor;
957 if (sd == NULL) {
958 continue;
959 }
960 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
961 continue;
962 }
963 if (!isOldStyleEnabled && isNewStyleEnabled) {
964 if (!is_sensor_flag(sr, SENSOR_FLAG_ACTIVATED)) {
965 continue;
966 }
967 }
968
969 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
970 continue;
971 }
972 sr->runctr--;
973 if (sr->runctr > 0) {
974 continue;
975 }
976 const struct sensorconfig *sc = getconfig(sd);
977 sr->runctr = sc->readmillis;
978 if ((sr->buf == NULL) || (sr->bufsize == 0)) {
979 runtime_invalid = 1;
980 printf("[sensor] attempt to read sensor %i, but no buf (buf=%p,size=%i)\r\n", i, sr->buf, sr->bufsize);
981 continue;
982 }
983 if (sr->valuesize > (sr->bufsize - sr->bytesinbuf)) {
984 //printf("[sensor] %s sensor: buf overflow\r\n",sr->sensor->name);
985 continue; // buf is full!
986 }
987
988 if (sr->values >= sc->max_values) {
989 //printf("[sensor] %s sensor: values overflow (%i values, max=%i)\r\n",sr->sensor->name,sr->values,sc->max_values);
990 continue; // read enough values between submits...
991 }
992 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
993 byte error = 0;
994 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
995 int value = sd->get_reading(sd->sensorindex, &error);
996 if (error == 0) {
997 sensor_detected(sr);
998 add_value(sr, value);
999 }
1000 } else {
1001 set_sensor_flag(sr, SENSOR_FLAG_ISDUE);
1002 }
1003 //printf("[sensor] Value of sensor %s: %i\r\n",sd->name,value);
1004 }
1005 irqstatus &= ~1;
1006}
1007
1008void sensor_deregister(struct sensordev *sensor) {
1009 sensors_off();
1010 sensor->power_on = NULL; // without power-on function, it's not a valid sensor
1011 sensors_init();
1012}
int update_all_runtimes()
update runtimes (recalculate buffer positions). return 0 if ok (5 otherwise)
Definition: sensor.c:281
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
Definition: queue.c:651
void sensors_init()
initialize sensors, runtime, config, powerup each sensor in turn etc..
Definition: sensor.c:382
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
#define SENSOR_TIMER
timer to use
Definition: sensor.c:88
struct sensordev sensors[]
list of sensors...
Definition: sensor.c:23
void sensors_off()
disable sensors
Definition: sensor.c:629
struct sensorconfig _sensorconfig
definition of variable stuff for any one sensor this is seperate from runtime, because a copy will li...
int sensor_loop()
called periodically. this will either query sensors when they are due or will set the isdue flag for ...
Definition: sensor.c:845
void command_init(struct command *com)
initialize a command structure with default values
void sensors_newstyle()
enable new-style sensors (and disable old)
Definition: sensor.c:621
struct command * alloc_command()
allocate a free command
Definition: queue.c:173
struct sensordev * sensor_register(struct sensordev *sensor)
register a sensor, e.g. from userhook. The sensordev struct is COPIED, so it may be reused by the cal...
Definition: sensor.c:644
#define SENSOR_TIMER_FREQUENCY
frequency our timer runs on
Definition: sensor.c:84
int com
Definition: command.h:22
long target
Definition: command.h:16
long recipient
Definition: command.h:15
uint8_t flags
Definition: command.h:23
definition of variable stuff for any one sensor this is seperate from runtime, because a copy will li...
Definition: sensor.c:46
runtime data per sensor (in-ram)
Definition: sensor_dev.h:33