From f26587571f5d63cd1084aa5fd190b7cc7a52edd3 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Wed, 10 Dec 2014 18:03:00 +0100 Subject: Add message for global state Signed-off-by: Michael Buesch --- firmware/controller.c | 8 +++--- firmware/controller.h | 3 +-- firmware/main.c | 35 +++++++++++++++++++++---- firmware/notify_led.c | 5 ++++ firmware/notify_led.h | 1 + firmware/onoffswitch.c | 69 ++++++++++++++++++++++++++++++++------------------ firmware/onoffswitch.h | 1 + 7 files changed, 86 insertions(+), 36 deletions(-) diff --git a/firmware/controller.c b/firmware/controller.c index 42aba13..fb8f311 100644 --- a/firmware/controller.c +++ b/firmware/controller.c @@ -26,6 +26,7 @@ #include "ioext.h" #include "log.h" #include "notify_led.h" +#include "onoffswitch.h" #include @@ -827,12 +828,11 @@ void controller_freeze(bool freeze) cont.freeze_timeout = jiffies_get() + sec_to_jiffies(5); } -/* The main controller routine. - * hw_switch: The state of the hardware on/off-switch. - */ -void controller_work(enum onoff_state hw_switch) +/* The main controller routine. */ +void controller_work(void) { jiffies_t now = jiffies_get(); + enum onoff_state hw_switch = onoffswitch_get_state(); if (cont.eeprom_update_required && !time_before(now, cont.eeprom_update_time)) { diff --git a/firmware/controller.h b/firmware/controller.h index 44ec3fd..e6cff42 100644 --- a/firmware/controller.h +++ b/firmware/controller.h @@ -3,7 +3,6 @@ #include "util.h" #include "datetime.h" -#include "onoffswitch.h" /* The maximum possible number of flower-pots. */ @@ -132,7 +131,7 @@ void controller_manual_mode(uint8_t force_stop_watering_mask, void controller_freeze(bool freeze); -void controller_work(enum onoff_state hw_switch); +void controller_work(void); void controller_init(void); #endif /* CONTROLLER_H_ */ diff --git a/firmware/main.c b/firmware/main.c index 1eb8328..a45dd40 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -55,6 +55,8 @@ enum user_message_id { MSG_CONTR_POT_REM_STATE_FETCH, /* Pot remanent state request */ MSG_MAN_MODE, /* Manual mode settings */ MSG_MAN_MODE_FETCH, /* Manual mode settings request */ + MSG_CONTR_STATE, /* Global state */ + MSG_CONTR_STATE_FETCH, /* Global state request */ }; enum man_mode_flags { @@ -64,6 +66,11 @@ enum man_mode_flags { MANFLG_NOTIFY_ENABLE = 1 << 3, /* LED-status on/off */ }; +enum contr_state_flags { + CONTRSTAT_ONOFFSWITCH = 1 << 0, /* Hardware on/off-switch state. */ + CONTRSTAT_NOTIFLED = 1 << 1, /* Notification LED state. */ +}; + /* Payload of host communication messages. */ struct msg_payload { /* The ID number. (enum user_message_id) */ @@ -110,10 +117,13 @@ struct msg_payload { uint8_t valve_manual_state; uint8_t flags; } _packed manual_mode; + + /* Global controller state. */ + struct { + uint8_t flags; + } _packed contr_state; } _packed; } _packed; -// TODO: add global state message with LED state -// TODO: add global state message with hw switch state /* The current timekeeping count. */ @@ -300,6 +310,21 @@ bool comm_handle_rx_message(const struct comm_message *msg, break; } + case MSG_CONTR_STATE_FETCH: { + /* Fetch global state. */ + + enum onoff_state hw_switch; + + reply->id = MSG_CONTR_STATE; + reply->contr_state.flags = 0; + hw_switch = onoffswitch_get_state(); + if (hw_switch == ONOFF_IS_ON || hw_switch == ONOFF_SWITCHED_ON) + reply->contr_state.flags |= CONTRSTAT_ONOFFSWITCH; + if (notify_led_get()) + reply->contr_state.flags |= CONTRSTAT_NOTIFLED; + + break; + } default: /* Unsupported message. Return failure. */ return 0; @@ -365,6 +390,7 @@ static enum onoff_state handle_onoffswitch(void) { enum onoff_state hw_switch; + onoffswitch_work(); hw_switch = onoffswitch_get_state(); if (hw_switch == ONOFF_IS_OFF || @@ -395,7 +421,6 @@ int main(void) _mainfunc; int main(void) { jiffies_t now; - enum onoff_state hw_switch; irq_disable(); @@ -424,7 +449,7 @@ int main(void) now = jiffies_get(); /* Handle the state of the hardware on/off-switch. */ - hw_switch = handle_onoffswitch(); + handle_onoffswitch(); /* Handle serial host communication. */ comm_work(); @@ -437,7 +462,7 @@ int main(void) handle_rtc(now); /* Run the controller state machine. */ - controller_work(hw_switch); + controller_work(); /* Handle notification LED state. */ notify_led_work(); diff --git a/firmware/notify_led.c b/firmware/notify_led.c index dc3057d..a518816 100644 --- a/firmware/notify_led.c +++ b/firmware/notify_led.c @@ -68,6 +68,11 @@ void notify_led_set(bool on) irq_restore(sreg); } +bool notify_led_get(void) +{ + return led.state; +} + void notify_led_work(void) { jiffies_t now = jiffies_get(); diff --git a/firmware/notify_led.h b/firmware/notify_led.h index 2f49fd8..4f1ba18 100644 --- a/firmware/notify_led.h +++ b/firmware/notify_led.h @@ -5,6 +5,7 @@ void notify_led_set(bool on); +bool notify_led_get(void); void notify_led_work(void); void notify_led_init(void); diff --git a/firmware/onoffswitch.c b/firmware/onoffswitch.c index 469c8d6..fc0428d 100644 --- a/firmware/onoffswitch.c +++ b/firmware/onoffswitch.c @@ -32,32 +32,22 @@ #define ONOFFSWITCH_BIT PD3 /* Saved state. */ -static bool onoffswitch_state; +static enum onoff_state onoffswitch_state = ONOFF_IS_OFF; /* Timestamp for the next check. */ static jiffies_t next_check; -/* Initialize the on/off-switch. */ -void onoffswitch_init(void) +static void onoffswitch_eliminate_edge_states(void) { - ONOFFSWITCH_DDR &= ~(1 << ONOFFSWITCH_BIT); - ONOFFSWITCH_PORT |= (1 << ONOFFSWITCH_BIT); - _delay_ms(20); /* Wait for pull-up. */ + if (onoffswitch_state == ONOFF_SWITCHED_ON) + onoffswitch_state = ONOFF_IS_ON; + else if (onoffswitch_state == ONOFF_SWITCHED_OFF) + onoffswitch_state = ONOFF_IS_OFF; } -/* Get the on/off-switch state. */ -enum onoff_state onoffswitch_get_state(void) +static void onoffswitch_update(void) { bool new_state, old_state; - jiffies_t now = jiffies_get(); - - /* Debounce time. */ - if (time_before(now, next_check)) { - if (onoffswitch_state) - return ONOFF_IS_ON; - return ONOFF_IS_OFF; - } - next_check = now + msec_to_jiffies(100); /* Get the state. */ new_state = !!(ONOFFSWITCH_PIN & (1 << ONOFFSWITCH_BIT)); @@ -65,13 +55,42 @@ enum onoff_state onoffswitch_get_state(void) new_state = !new_state; /* Detect state and edges. */ - old_state = onoffswitch_state; - onoffswitch_state = new_state; + old_state = (onoffswitch_state != ONOFF_IS_OFF); if (new_state && !old_state) - return ONOFF_SWITCHED_ON; - if (!new_state && old_state) - return ONOFF_SWITCHED_OFF; - if (new_state) - return ONOFF_IS_ON; - return ONOFF_IS_OFF; + onoffswitch_state = ONOFF_SWITCHED_ON; + else if (!new_state && old_state) + onoffswitch_state = ONOFF_SWITCHED_OFF; + else if (new_state) + onoffswitch_state = ONOFF_IS_ON; + else + onoffswitch_state = ONOFF_IS_OFF; +} + +/* Initialize the on/off-switch. */ +void onoffswitch_init(void) +{ + ONOFFSWITCH_DDR &= ~(1 << ONOFFSWITCH_BIT); + ONOFFSWITCH_PORT |= (1 << ONOFFSWITCH_BIT); + _delay_ms(20); /* Wait for pull-up. */ + onoffswitch_update(); + onoffswitch_eliminate_edge_states(); +} + +/* Periodic work. */ +void onoffswitch_work(void) +{ + jiffies_t now = jiffies_get(); + + onoffswitch_eliminate_edge_states(); + + if (!time_before(now, next_check)) { + next_check = now + msec_to_jiffies(100); + onoffswitch_update(); + } +} + +/* Get the on/off-switch state. */ +enum onoff_state onoffswitch_get_state(void) +{ + return onoffswitch_state; } diff --git a/firmware/onoffswitch.h b/firmware/onoffswitch.h index 0f36a3b..3fdc910 100644 --- a/firmware/onoffswitch.h +++ b/firmware/onoffswitch.h @@ -9,6 +9,7 @@ enum onoff_state { }; void onoffswitch_init(void); +void onoffswitch_work(void); enum onoff_state onoffswitch_get_state(); #endif /* ONOFFSWITCH_H_ */ -- cgit v1.2.3