From 3a35dbba8e11c15343beffc003027dc660714cbf Mon Sep 17 00:00:00 2001 From: Dragos GALALAE Date: Thu, 5 Dec 2024 18:28:38 +0200 Subject: [PATCH] Handle recovery blanking as separate state, update docs, format code --- README.md | 5 ++- src/main.c | 129 ++++++++++++++++++++++++++++++++--------------------- 2 files changed, 80 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 1d0158b..1627f2f 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,10 @@ To flash MCU: 7) wait for program to flash, check messages in terminal for errors Current features: -- response time: 100ms - changes in conditions faster than this won't be detected +- response time: 100ms - changes in conditions faster than this won't be detected, limit to max 500ms - startup delay: 60s - the relay will not trip is PS_ON is disconnected (or 0) and power has just been applied - power off delay: 20s - time to allow the board/PC to shutdown cleanly -- recovery delay: 5s - recover with PS_ON after power off, blanking time to avoid fast power off/on cycle +- recovery delay: 30s - blanking time to avoid fast power off/on cycle, after which relay can recover with PS_ON (self-reset) Leds show state: - green off and red off - no power to the relay @@ -29,6 +29,7 @@ Leds show state: - green on and red blinking - startup delay, power to system, only SC is available - green on and red off - power to the system - green blinking and red off - PS_ON triggered, power off delay +- green and red blinking - no power to the system, wait for recovery delay - green off and red on - no power to the system, relay is in power off state - green alternate red blinking - SC triggered diff --git a/src/main.c b/src/main.c index 1c39a2a..077ae58 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ #include #include #include +#include #define LED_OFF P30 /* Power off led (red) */ #define LED_ON P31 /* Power on led (green) */ @@ -11,13 +12,9 @@ #define RESPONSE_DELAY 100 /* how fast the sofware responds to input changes */ #define START_DELAY_S 60 /* time at startup to ignore PS_DLY state */ #define STOP_DELAY_S 20 /* time to wait before power off after trigger by PS_DLY */ -#define RECOVER_DELAY_S 5 /* time to wait before power recovery after PS_DLY gets restored */ +#define RECOVER_DELAY_S 30 /* time to wait before power recovery after PS_DLY gets restored */ #define BLINKER_MUL 3 /* used for blinking LEDs, multiple of RESPONSE_DELAY */ -#if (RECOVER_DELAY_S > (STOP_DELAY_S-1)) -#error "RECOVER_DELAY_S must be at least 1 second smaller than STOP_DELAY_S" -#endif - #if (RESPONSE_DELAY > 500) #error "RESPONSE_DELAY must be lower than 500ms" #endif @@ -30,18 +27,38 @@ #define PWDN_DLY_TICKS (STOP_DELAY_S*1000UL/RESPONSE_DELAY*1UL) #define PWRE_DLY_TICKS (STOP_DELAY_S*1000UL/RESPONSE_DELAY*1UL) -/* stated of the device */ -typedef enum -{ +/* states of the device */ +typedef enum { powerup, /* first startup/reset will ignore PS_DLY state */ running, /* normal running state */ psdelay, /* PS_DLY was triggered, but we wait for power off delay */ + blanking, /* PS_DLY was triggered, power was cut, we wait recovery delay*/ tripped, /* PS_DLY trigger occurred */ tripped_sc, /* SCP trigger occurred */ }states_t; -void main(void) -{ +/* vars */ +states_t state = powerup; +uint32_t updelay = 0; +uint8_t blink = 0; + +/* things to always do when switching to new state */ +void goto_state(states_t new) { + /* reset leds */ + LED_ON = 0; + LED_OFF = 0; + /* if short, start with red led on */ + if (new == tripped_sc) + LED_OFF = 1; + /* reset timers */ + updelay = 0; + blink = 0; + /* set new state */ + state = new; +} + +/* setup and init i/o */ +void init_io(void) { /* setup i/o */ P3M1 = 0xB4; P3M0 = 0xB4; @@ -50,10 +67,11 @@ void main(void) RELAY = 0; LED_OFF = 0; LED_ON = 0; - /* vars */ - states_t state = powerup; - uint32_t updelay = 0; - uint8_t blink = 0; +} + +void main(void) { + /* setup i/o */ + init_io(); /* program loop */ while(1) { /* wait response time */ @@ -62,34 +80,34 @@ void main(void) if (SCP) state = tripped_sc; /* check states */ - switch (state) - { + switch (state) { case powerup: /* powering state */ RELAY = 0; + /* led state */ + LED_ON = 1; /* increase delay timers */ updelay += 1; blink += 1; + /* blink led */ if (blink > BLINKER_MUL) { /* leds */ LED_OFF = (!LED_OFF); - LED_ON = 1; blink = 0; } /* check power up delay */ if (updelay > PWUP_DLY_TICKS) { - updelay = 0; /* check PS_DLY */ if (PS_DLY) - state = running; - else - state = tripped; + goto_state(running); + /* PS_ON must have signal to continue ! */ + goto_state(blanking); } break; case running: /* powering state */ RELAY = 0; - /* leds */ + /* led state */ LED_OFF = 0; LED_ON = 1; /* reset timers */ @@ -97,27 +115,42 @@ void main(void) blink = 0; /* check PS_DLY */ if (PS_DLY) - state = psdelay; + goto_state(psdelay); break; case psdelay: /* powering state */ RELAY = 0; + /* led state */ + LED_OFF = 0; /* increase delay timers */ updelay += 1; blink += 1; + /* blink led */ if (blink > BLINKER_MUL) { /* leds */ - LED_OFF = 0; LED_ON = (!LED_ON); blink = 0; } /* check power down delay */ - if (updelay > PWDN_DLY_TICKS) { - /* reset timers */ + if (updelay > PWDN_DLY_TICKS) + goto_state(blanking); + break; + case blanking: + /* tripped state */ + RELAY = 1; + /* increase delay timers */ + updelay += 1; + blink += 1; + /* blink both leds */ + if (blink > BLINKER_MUL) { + /* leds */ + LED_OFF = (!LED_OFF); + LED_ON = (!LED_ON); blink = 0; - updelay = 0; - state = tripped; } + /* check power down delay */ + if (updelay > PWRE_DLY_TICKS) + goto_state(tripped); break; case tripped: /* tripped state */ @@ -125,40 +158,32 @@ void main(void) /* leds */ LED_OFF = 1; LED_ON = 0; - /* increase delay timers */ - updelay += 1; - /* power recovery */ - if (updelay > PWRE_DLY_TICKS) { - /* check PS_DLY pin */ - if (!PS_DLY) { - /* reset timers */ - blink = 0; - updelay = 0; - state = running; - } - updelay = PWRE_DLY_TICKS; - } + /* power recovery (self-reset) */ + if (!PS_DLY) + //goto_state(powerup); + reset(); break; default: /* tripped state */ RELAY = 1; /* increase delay timers */ blink += 1; - /* blinking leds alternatively, one it BLINKER_MUL on, then the other is BLINKER_MUL on */ - if (blink > (2*BLINKER_MUL)) - blink=0; + /* blinking leds alternating them */ if (blink > BLINKER_MUL) { /* leds */ - LED_OFF = 1; - LED_ON = 0; - } else { - /* leds */ - LED_OFF = 0; - LED_ON = 1; + if(LED_ON) { + LED_OFF = 1; + LED_ON = 0; + } else { + LED_OFF = 0; + LED_ON = 1; + } + /* reset blink timer */ + blink = 0; } - /* reset timers */ + /* reset other timers */ updelay = 0; break; - } + } } } \ No newline at end of file