1#include <sensors/sensor.h>
2#include <platform-header.h>
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 },
57static struct sensorconfig defaultconfig = { NULL, CLOUD_SERVER, 60000, 60, 1 };
58static uint8_t inited = 0;
59static void sensors_timer_irq();
68#define SENSOR_FLAG_ENABLED 0
69#define SENSOR_FLAG_ISDUE 1
70#define SENSOR_FLAG_DETECTED 2
71#define SENSOR_FLAG_PROBED 3
73#define SENSOR_FLAG_ACTIVATED 4
84#define SENSOR_TIMER_FREQUENCY 1000
97static uint8_t runtime_invalid;
102static byte sensorbuf[1000];
106static byte sensors_enabled;
109#define isOldStyleEnabled (sensors_enabled & (1 << 0))
110#define isNewStyleEnabled (sensors_enabled & (1 << 1))
111#define isProbing (sensors_enabled & (1 << 2))
120 if (sensor == NULL) {
124 for (i = 0; i < (
sizeof(sensorconfigs) /
sizeof(sensorconfigs[0])); i++) {
125 res = &sensorconfigs[i];
126 if (res->sensor == sensor) {
130 return &defaultconfig;
136static void disable_irq() {
138 while (irqstatus & 1) {
143static void addflagstr(
char *res,
int bufsize,
byte flags,
byte flag,
char *truestr,
char *falsestr) {
144 char *cpy = falsestr;
146 if (flags & (1 << flag)) {
149 char *xr = res + strlen(res);
151 strncpy(xr, cpy, 100);
152 xr[strlen(cpy)] =
' ';
153 xr[strlen(cpy) + 1] = 0;
155static void sensorflags2str(
byte flags,
char *res,
int bufsize) {
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");
164static void enable_irq() {
169 sr->flags |= (1 << SENSOR_FLAG_ENABLED);
172 sr->flags &= ~(1 << SENSOR_FLAG_ENABLED);
174static void clr_sensor_flag(
struct sensorruntime *sr,
int flag) {
175 sr->flags &= ~(1 << flag);
177static void set_sensor_flag(
struct sensorruntime *sr,
int flag) {
178 sr->flags |= (1 << flag);
180static int is_sensor_flag(
struct sensorruntime *sr,
int flag) {
181 return sr->flags & (1 << flag);
184 set_sensor_flag(sr, SENSOR_FLAG_DETECTED);
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;
206static uint32_t get_value(
struct sensorruntime *sr,
int val) {
207 if (val >= sr->values) {
212 if (sr->valuesize == 1) {
213 byte b = sr->buf[val];
215 }
else if (sr->valuesize == 2) {
216 byte b = sr->buf[val * 2 + 1];
219 res = res | ((sr->buf[val * 2]) & 0xFF);
220 }
else if (sr->valuesize == 4) {
223 for (i = 0; i < 4; i++) {
224 uint32_t b = sr->buf[val * 4 + i];
225 res = res | (b << (8 * i));
246 sr->valuesize = (uint16_t)sr->sensor->get_reading_size(sd->sensorindex);
252 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
255 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
258 if (!is_sensor_flag(sr, SENSOR_FLAG_ACTIVATED)) {
262 sc = getconfig(sr->sensor);
263 int size = sr->valuesize;
264 int vals = (sc->submitsecs * 1000) / sc->readmillis;
266 if (sc->max_values < vals) {
267 vals = sc->max_values;
269 int res = vals * size;
285 printf(
"[sensor] updating runtimes\r\n");
287 memset(sensorbuf, 0,
sizeof(sensorbuf));
292 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
300 if ((sd->power_on == NULL) || (sd->get_reading == NULL)) {
303 int bufsize = calc_bufsize(sr);
307 sr->bufsize = bufsize;
308 sr->buf = (sensorbuf + offset);
309 offset = offset + bufsize;
310 if (offset >=
sizeof(sensorbuf)) {
312 printf(
"At sensor %i, buf overflow: %i\r\n", i, offset);
313 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
319 if ((sd->power_on == NULL) || (sd->get_reading == NULL)) {
322 int bufsize = calc_bufsize(sr);
323 printf(
"Sensor %i, bufsize: %i\r\n", i, bufsize);
337static void init_all_runtime() {
345 memset(runtime, 0,
sizeof(runtime));
346 memset(sensorbuf, 0,
sizeof(sensorbuf));
353 while (((sd = &
sensors[t])->power_on) != NULL) {
355 if (sd->get_reading == NULL) {
356 printf(
"[sensor] Sensor does not support reading a value - sensor skipped.\r\n");
359 init_runtime(sd, &runtime[r]);
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]);
372 offset = offset + bufsize;
389 memset(sensorconfigs, 0,
sizeof(sensorconfigs));
390 memset(runtime, 0,
sizeof(runtime));
396 while (((sd = &
sensors[t])->power_on) != NULL) {
398 if (sd->name != NULL) {
399 printf(
"[sensor] Initializing sensor #%i: %s\r\n", t, sd->name);
401 printf(
"[sensor] Initializing sensor #%i: [noname]\r\n", t);
403 if (sd->get_reading == NULL) {
404 printf(
"[sensor] Sensor does not support reading a value - sensor skipped.\r\n");
407 sd->power_on(sd->sensorindex);
413 printf(
"[sensor] Failed to activate timer %i for TLI4970: %i\r\n",
SENSOR_TIMER, r);
418 printf(
"[sensor] Sensors initialized\r\n");
429 if (sd->get_status == NULL) {
433 sd->get_status(sd->sensorindex, (
char *)&buf,
sizeof(buf), &res);
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);
445 if (sd->power_on != NULL) {
446 printf(
"[sensor] power on\r\n");
447 sd->power_on(sd->sensorindex);
449 printf(
"[sensor] power cycle complete\r\n");
451 sd->get_status(sd->sensorindex, (
char *)&buf,
sizeof(buf), &res);
464 printf(
"[sensor] Cannot send command - no command space available\r\n");
470 com->
flags = COMFLAGS_SUCCESS;
480 memset(buf, 0,
sizeof(buf));
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));
486 snprintf(buf + strlen(buf),
sizeof(buf) - strlen(buf),
"%N;", get_value(sr, k));
488 if (strlen(buf) >=
sizeof(buf)) {
507 printf(
"[sensor] Sensor info at %i:\r\n", mculib_get_seconds_since_boot());
509 printf(
"[sensor] Enabled status: %i\r\n", sensors_enabled);
512 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
518 snprintf(buf,
sizeof(buf),
"n/a");
520 if (sd->get_status != NULL) {
521 sd->get_status(sd->sensorindex, (
char *)&buf,
sizeof(buf), &status);
523 sensorflags2str(sr->flags, (
char *)&flagstr,
sizeof(flagstr));
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);
537 printf(
"[sensor] End sensor info\r\n");
550int sensor_update_config(
const long nodeid,
int idx,
const int readmillis,
const int submitsec,
const int max_values) {
557 if ((readmillis == 0) || (submitsec == 0) || (max_values == 0)) {
560 sr = get_runtime(idx);
562 printf(
"[sensor] No such sensor \"%i\"\r\n", idx);
568 if ((sc == NULL) || (sc == &defaultconfig)) {
571 for (i = 0; i < (
sizeof(sensorconfigs) /
sizeof(sensorconfigs[0])); i++) {
572 res = &sensorconfigs[i];
573 if (res->sensor == NULL) {
579 printf(
"[sensor] No more free sensor config entries.\r\n");
587 sc->readmillis = readmillis;
588 sc->submitsecs = submitsec;
589 sc->max_values = max_values;
593 printf(
"[sensor] failed to update runtime (%i)\r\n", r);
600int sensor_submit_request(
const long nodeid,
int idx,
const int readmillis,
const int submitsec,
const int max_values) {
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",
610 int x = sensor_update_config(nodeid, idx, readmillis, submitsec, max_values);
613 printf(
"[sensor] Sensor request failed: %i\r\n", x);
622 sensors_enabled &= ~(1 << 0);
623 sensors_enabled |= (1 << 1);
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);
637 printf(
"[sensor] Sensor timer disabled\r\n");
650 while ((
sensors[t].power_on) != NULL) {
653 printf(
"[sensor] No sensor entry available to register sensor. (max=%i,t=%i)\r\n", max, t);
658 byte *source = (
void *)sensor;
659 byte *target = (
void *)&
sensors[t];
661 for (i = 0; i <
sizeof(
struct sensordev); i++) {
662 target[i] = source[i];
665 if (sensor->name != NULL) {
666 printf(
"[sensor] Sensor %s registered\r\n", sensor->name);
668 printf(
"[sensor] extra sensor with no name registered\r\n");
673static int isDigit(
char c) {
674 if ((c >=
'0') && (c <=
'9')) {
683static int parse_numbers(
const char *str,
int bufcount,
int buf[]) {
688 for (i = 0; i < strlen(str); i++) {
695 buf[res++] = atoi(str + i);
706void sensor_run_str(
const char *str) {
711 printf(
"[sensor] Sensor run \"%s\"\r\n", str);
712 int r = parse_numbers(str, (
sizeof(buf) /
sizeof(buf[0])), (
int *)&buf);
715 printf(
"[sensor] Need exactly 2 digits [s a] (s=sensor index, a=action]. got %i. Aborted.\r\n", r);
722 int ms = (
sizeof(runtime) /
sizeof(runtime[0]));
725 printf(
"[sensor] Sensor index out of range: %i (0-%i)\r\n", sensor, ms);
728 sr = &runtime[sensor];
731 printf(
"[sensor] No sensor #%i\r\n", sensor);
734 printf(
"[sensor] Sensor \"%s\": %i\r\n", sd->name, action);
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) {
743 printf(
"[sensor] get_reading() == %i\r\n", sd->get_reading(sd->sensorindex, &error));
744 }
else if (action == 4) {
747 sd->get_status(sd->sensorindex, (
char *)&buf, 100, &st);
748 printf(
"[sensor] get_status() == %s %i\r\n", buf, st);
750 printf(
"[sensor] Invalid action (0=pwron,1=pwroff,2=readingsize,3=reading,4=status\r\n");
754int all_sensors_probed() {
758 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
760 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
763 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
771void sensor_activation(
struct sensorruntime *sr,
int activation) {
773 sr->flags |= (1 << SENSOR_FLAG_ACTIVATED);
775 sr->flags &= ~(1 << SENSOR_FLAG_ACTIVATED);
788 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
795 if (is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
798 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
804 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
808 clr_sensor_flag(sr, SENSOR_FLAG_DETECTED);
809 sd->get_reading(sd->sensorindex, &error);
813 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
814 clr_sensor_flag(sr, SENSOR_FLAG_ISDUE);
820 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
826 if (!is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
832 sensors_enabled &= ~(1 << 2);
835uint8_t sensors_inited() {
846 if (runtime_invalid) {
849 if (!sensors_inited()) {
862 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
871 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
872 if (!mculib_has_time_passed(sc->submitsecs < 30 ? 30 : sc->submitsecs, &sr->runsecs)) {
875 printf(
"[sensor] Sensor %s is disabled, resetting it.\r\n", sd->name);
880 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
881 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
883 int value = sd->get_reading(sd->sensorindex, &error);
886 add_value(sr, value);
888 clr_sensor_flag(sr, SENSOR_FLAG_ISDUE);
891 if (sr->values == 0) {
895 if (!mculib_has_time_passed(sc->submitsecs, &sr->runsecs)) {
898 printf(
"[sensor] Sensor %s has %i values ready to submit\r\n", sd->name, sr->values);
910static void sensors_timer_irq() {
920 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
926 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
929 if (is_sensor_flag(sr, SENSOR_FLAG_PROBED)) {
932 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
935 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
937 int value = sd->get_reading(sd->sensorindex, &error);
940 add_value(sr, value);
942 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
954 for (i = 0; i < (
sizeof(runtime) /
sizeof(runtime[0])); i++) {
960 if (!is_sensor_flag(sr, SENSOR_FLAG_ENABLED)) {
963 if (!isOldStyleEnabled && isNewStyleEnabled) {
964 if (!is_sensor_flag(sr, SENSOR_FLAG_ACTIVATED)) {
969 if (is_sensor_flag(sr, SENSOR_FLAG_ISDUE)) {
973 if (sr->runctr > 0) {
977 sr->runctr = sc->readmillis;
978 if ((sr->buf == NULL) || (sr->bufsize == 0)) {
980 printf(
"[sensor] attempt to read sensor %i, but no buf (buf=%p,size=%i)\r\n", i, sr->buf, sr->bufsize);
983 if (sr->valuesize > (sr->bufsize - sr->bytesinbuf)) {
988 if (sr->values >= sc->max_values) {
992 if (sd->cfg_flags & (1 << SENSOR_CONFIG_FLAG_IRQ)) {
994 set_sensor_flag(sr, SENSOR_FLAG_PROBED);
995 int value = sd->get_reading(sd->sensorindex, &error);
998 add_value(sr, value);
1001 set_sensor_flag(sr, SENSOR_FLAG_ISDUE);
1008void sensor_deregister(
struct sensordev *sensor) {
1010 sensor->power_on = NULL;
int update_all_runtimes()
update runtimes (recalculate buffer positions). return 0 if ok (5 otherwise)
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
void sensors_init()
initialize sensors, runtime, config, powerup each sensor in turn etc..
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
struct sensordev sensors[]
list of sensors...
void sensors_off()
disable sensors
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 ...
void command_init(struct command *com)
initialize a command structure with default values
void sensors_newstyle()
enable new-style sensors (and disable old)
struct command * alloc_command()
allocate a free command
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...
#define SENSOR_TIMER_FREQUENCY
frequency our timer runs on
definition of variable stuff for any one sensor this is seperate from runtime, because a copy will li...
runtime data per sensor (in-ram)