application: commit dachtuer application
This commit is contained in:
parent
aaeed65c18
commit
7d425f6cfb
366
application.c
366
application.c
@ -12,7 +12,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/** STM32F1 application example
|
||||
/** dachboden front panel access control
|
||||
* @file
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016-2020
|
||||
@ -76,6 +76,48 @@ static time_t time_start = 0;
|
||||
volatile bool rtc_internal_tick_flag = false; /**< flag set when internal RTC ticked */
|
||||
/** @} */
|
||||
|
||||
/** GPIO pin connected to relay, used to control button connection to panel */
|
||||
#define RELAY_PANEL_PIN PB6
|
||||
/** GPIO pin connected to relay, used to simulate button press */
|
||||
#define RELAY_BUTTON_PIN PB7
|
||||
/** GPIO for button 1 */
|
||||
#define BUTTON1_PIN PB8
|
||||
/** GPIO for button 2 */
|
||||
#define BUTTON2_PIN PB9
|
||||
|
||||
/** which button has been pressed */
|
||||
volatile uint8_t button_pressed = 0;
|
||||
|
||||
/** if we apply the opening policy */
|
||||
bool opening_apply = false;
|
||||
|
||||
static struct opening_settings_t {
|
||||
uint8_t days; /**< which days of the week it door access applies (bit 7 = Monday) */
|
||||
uint16_t start_time; /**< at which minutes of the day to start */
|
||||
uint16_t stop_time; /**< at which minutes of the day to stop */
|
||||
uint8_t button_pattern[10]; /**< sequence of buttons to press to open the door */
|
||||
} opening_settings;
|
||||
|
||||
/** save current opening_settings into SRAM */
|
||||
static void save_opening_settings(void)
|
||||
{
|
||||
BKP_DR1 = 0; // invalid saved settings
|
||||
BKP_DR2 = opening_settings.days & 0x7f;
|
||||
BKP_DR3 = opening_settings.start_time;
|
||||
BKP_DR4 = opening_settings.stop_time;
|
||||
BKP_DR5 = opening_settings.button_pattern[0];
|
||||
BKP_DR6 = opening_settings.button_pattern[1];
|
||||
BKP_DR7 = opening_settings.button_pattern[2];
|
||||
BKP_DR8 = opening_settings.button_pattern[3];
|
||||
BKP_DR9 = opening_settings.button_pattern[4];
|
||||
BKP_DR10 = opening_settings.button_pattern[5];
|
||||
BKP_DR11 = opening_settings.button_pattern[6];
|
||||
BKP_DR12 = opening_settings.button_pattern[7];
|
||||
BKP_DR13 = opening_settings.button_pattern[8];
|
||||
BKP_DR14 = opening_settings.button_pattern[9];
|
||||
BKP_DR1 = 0x4223; //validate saved setting
|
||||
}
|
||||
|
||||
size_t putc(char c)
|
||||
{
|
||||
size_t length = 0; // number of characters printed
|
||||
@ -135,6 +177,148 @@ static void command_bootloader_dfu(void* argument);
|
||||
*/
|
||||
static void command_bootloader_embedded(void* argument);
|
||||
|
||||
/** show/set on which days the access policy applies
|
||||
* @param[in] argument 7x0/1 to enable day of the week, starting with Monday (optional)
|
||||
*/
|
||||
static void command_days(void* argument)
|
||||
{
|
||||
const char* days = (char*)argument; // argument is optional days
|
||||
if (NULL != argument) { // days are provided, parse and save them
|
||||
bool valid = (7 == strlen(days)); // verify input string
|
||||
for (uint8_t day = 0; day < 7 && valid; day++) {
|
||||
if (days[day] != '0' && days[day] != '1') {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (valid) { // save provided settings
|
||||
// parse new days
|
||||
opening_settings.days = 0;
|
||||
for (uint8_t day = 0; day < 7; day++) {
|
||||
if ('1' == days[day]) {
|
||||
opening_settings.days |= (1 << (6 - day));
|
||||
}
|
||||
}
|
||||
save_opening_settings(); // save days
|
||||
puts("days saved\n");
|
||||
} else {
|
||||
puts("provide exactly 7 times 0 (off) or 1 (on). 1st digit for Monday, 7th digit for Sunday\n");
|
||||
}
|
||||
}
|
||||
// display current days
|
||||
printf("opening days: %07b\n", opening_settings.days);
|
||||
const char* day_names[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
|
||||
for (uint8_t day = 0; day < LENGTH(day_names); day++) {
|
||||
printf("- %s: %s\n", day_names[day], (opening_settings.days & (1 << (6 - day))) ? "on" : "off");
|
||||
}
|
||||
}
|
||||
|
||||
/** show/set on which time the access policy starts applying
|
||||
* @param[in] argument string with time of day, optional
|
||||
*/
|
||||
static void command_start(void* argument)
|
||||
{
|
||||
const char* time = (char*)argument; // argument is optional time
|
||||
if (NULL != argument) { // days are provided, parse and save them
|
||||
bool valid = (5 == strlen(time)); // verify input string
|
||||
if (!(valid && isdigit((int8_t)time[0]) && isdigit((int8_t)time[1]) && ':' == time[2] && isdigit((int8_t)time[3]) && isdigit((int8_t)time[4]))) {
|
||||
valid = false;
|
||||
}
|
||||
if (valid) { // save provided settings
|
||||
opening_settings.start_time = 0;
|
||||
opening_settings.start_time += (time[4] - '0') * 1;
|
||||
opening_settings.start_time += (time[3] - '0') * 10;
|
||||
opening_settings.start_time += (time[1] - '0') * 60;
|
||||
opening_settings.start_time += (time[0] - '0') * 600;
|
||||
save_opening_settings(); // save days
|
||||
puts("start time saved\n");
|
||||
} else {
|
||||
puts("provide time in HH:MM format\n");
|
||||
}
|
||||
}
|
||||
printf("start time: %02u:%02u\n", opening_settings.start_time / 60, opening_settings.start_time % 60);
|
||||
}
|
||||
|
||||
/** show/set on which time the access policy stops applying
|
||||
* @param[in] argument string with time of day, optional
|
||||
*/
|
||||
static void command_stop(void* argument)
|
||||
{
|
||||
const char* time = (char*)argument; // argument is optional time
|
||||
if (NULL != argument) { // days are provided, parse and save them
|
||||
bool valid = (5 == strlen(time)); // verify input string
|
||||
if (!(valid && isdigit((int8_t)time[0]) && isdigit((int8_t)time[1]) && ':' == time[2] && isdigit((int8_t)time[3]) && isdigit((int8_t)time[4]))) {
|
||||
valid = false;
|
||||
}
|
||||
if (valid) { // save provided settings
|
||||
opening_settings.stop_time = 0;
|
||||
opening_settings.stop_time += (time[4] - '0') * 1;
|
||||
opening_settings.stop_time += (time[3] - '0') * 10;
|
||||
opening_settings.stop_time += (time[1] - '0') * 60;
|
||||
opening_settings.stop_time += (time[0] - '0') * 600;
|
||||
save_opening_settings(); // save days
|
||||
puts("stop time saved\n");
|
||||
} else {
|
||||
puts("provide time in HH:MM format\n");
|
||||
}
|
||||
}
|
||||
printf("stop time: %02u:%02u\n", opening_settings.stop_time / 60, opening_settings.stop_time % 60);
|
||||
}
|
||||
|
||||
/** open door by simulating button press
|
||||
* @param[in] argument not used
|
||||
*/
|
||||
static void command_open(void* argument)
|
||||
{
|
||||
(void)argument; // we won't use the argument
|
||||
gpio_set(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN)); // set high to activate relay and take control over the button
|
||||
gpio_set(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set high to activate relay an simulate button press
|
||||
sleep_ms(1000); // hold button a bit
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set low to deactivate relay and release button
|
||||
if (!opening_apply) {
|
||||
gpio_clear(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN)); // set low to deactivate relay and git control back to button
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** show/set button pattern
|
||||
* @param[in] argument sequence of 1/2
|
||||
*/
|
||||
static void command_pattern(void* argument)
|
||||
{
|
||||
const char* pattern = (char*)argument; // argument is optional pattern
|
||||
if (NULL != argument) { // pattern provided
|
||||
bool valid = (LENGTH(opening_settings.button_pattern) >= strlen(pattern)); // verify input string
|
||||
for (uint8_t i = 0; i < strlen(pattern) && valid; i++) {
|
||||
if ('1' != pattern[i] && '2' != pattern[i]) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (valid) { // save provided settings
|
||||
// reset pattern
|
||||
for (uint8_t i = 0; i < LENGTH(opening_settings.button_pattern); i++) {
|
||||
opening_settings.button_pattern[i] = 0;
|
||||
}
|
||||
// save new pattern
|
||||
for (uint8_t i = 0; i < strlen(pattern); i++) {
|
||||
opening_settings.button_pattern[i] = pattern[i] - '0';
|
||||
}
|
||||
save_opening_settings(); // save days
|
||||
puts("button sequence saved\n");
|
||||
} else {
|
||||
printf("provide buttons sequence of up to %u 1 or 2\n", LENGTH(opening_settings.button_pattern));
|
||||
}
|
||||
}
|
||||
if (0 == opening_settings.button_pattern[0]) {
|
||||
puts("no button sequence set\n");
|
||||
} else {
|
||||
puts("button sequence: ");
|
||||
for (uint8_t i = 0; i < LENGTH(opening_settings.button_pattern) && opening_settings.button_pattern[i]; i++) {
|
||||
putc(opening_settings.button_pattern[i] + '0');
|
||||
}
|
||||
putc('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/** list of all supported commands */
|
||||
static const struct menu_command_t menu_commands[] = {
|
||||
{
|
||||
@ -163,7 +347,7 @@ static const struct menu_command_t menu_commands[] = {
|
||||
},
|
||||
#if RTC_DATE_TIME
|
||||
{
|
||||
.shortcut = 'd',
|
||||
.shortcut = 'D',
|
||||
.name = "date",
|
||||
.command_description = "show/set date and time",
|
||||
.argument = MENU_ARGUMENT_STRING,
|
||||
@ -195,6 +379,46 @@ static const struct menu_command_t menu_commands[] = {
|
||||
.argument_description = NULL,
|
||||
.command_handler = &command_bootloader_embedded,
|
||||
},
|
||||
{
|
||||
.shortcut = 'd',
|
||||
.name = "days",
|
||||
.command_description = "on which days to apply the access policy",
|
||||
.argument = MENU_ARGUMENT_STRING,
|
||||
.argument_description = "[0001000, 0/1 for Monday to Sunday]",
|
||||
.command_handler = &command_days,
|
||||
},
|
||||
{
|
||||
.shortcut = 's',
|
||||
.name = "start",
|
||||
.command_description = "on which time to start the access policy",
|
||||
.argument = MENU_ARGUMENT_STRING,
|
||||
.argument_description = "[HH:MM]",
|
||||
.command_handler = &command_start,
|
||||
},
|
||||
{
|
||||
.shortcut = 'S',
|
||||
.name = "stop",
|
||||
.command_description = "on which time to stop the access policy",
|
||||
.argument = MENU_ARGUMENT_STRING,
|
||||
.argument_description = "[HH:MM]",
|
||||
.command_handler = &command_stop,
|
||||
},
|
||||
{
|
||||
.shortcut = 'o',
|
||||
.name = "open",
|
||||
.command_description = "open door",
|
||||
.argument = MENU_ARGUMENT_NONE,
|
||||
.argument_description = NULL,
|
||||
.command_handler = &command_open,
|
||||
},
|
||||
{
|
||||
.shortcut = 'p',
|
||||
.name = "password",
|
||||
.command_description = "set/show password button sequence",
|
||||
.argument = MENU_ARGUMENT_STRING,
|
||||
.argument_description = "[sequence of 1/2]",
|
||||
.command_handler = &command_pattern,
|
||||
},
|
||||
};
|
||||
|
||||
static void command_help(void* argument)
|
||||
@ -490,6 +714,9 @@ static void command_reset(void* argument)
|
||||
static void command_bootloader_dfu(void* argument)
|
||||
{
|
||||
(void)argument; // we won't use the argument
|
||||
// disable relays
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN));
|
||||
gpio_clear(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN));
|
||||
// set DFU magic to specific RAM location
|
||||
__dfu_magic[0] = 'D';
|
||||
__dfu_magic[1] = 'F';
|
||||
@ -502,6 +729,9 @@ static void command_bootloader_dfu(void* argument)
|
||||
static void command_bootloader_embedded(void* argument)
|
||||
{
|
||||
(void)argument; // we won't use the argument
|
||||
// disable relays
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN));
|
||||
gpio_clear(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN));
|
||||
// set watchdog to exit system memory after some time
|
||||
iwdg_set_period_ms(25000); // set independent watchdog period (26214.4 ms if the max timeout)
|
||||
iwdg_start(); // start independent watchdog
|
||||
@ -562,7 +792,7 @@ void main(void)
|
||||
uart_setup(); // setup USART (for printing)
|
||||
#endif
|
||||
usb_cdcacm_setup(); // setup USB CDC ACM (for printing)
|
||||
puts("\nwelcome to the CuVoodoo STM32F1 example application\n"); // print welcome message
|
||||
puts("\nwelcome to the dachboden door panel\n"); // print welcome message
|
||||
|
||||
#if DEBUG
|
||||
// show reset cause
|
||||
@ -611,6 +841,62 @@ void main(void)
|
||||
time_start = rtc_get_counter_val(); // get start time from internal RTC
|
||||
puts("OK\n");
|
||||
|
||||
// setup relays
|
||||
puts("setup relays: ");
|
||||
rcc_periph_clock_enable(GPIO_RCC(RELAY_PANEL_PIN)); // enable clock for GPIO domain
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set low to leave per default
|
||||
gpio_set_mode(GPIO_PORT(RELAY_PANEL_PIN), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_PIN(RELAY_PANEL_PIN)); // set as output to control the transistor controlling the relay
|
||||
rcc_periph_clock_enable(GPIO_RCC(RELAY_BUTTON_PIN)); // enable clock for GPIO domain
|
||||
gpio_clear(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN)); // set low to leave per default
|
||||
gpio_set_mode(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO_PIN(RELAY_BUTTON_PIN)); // set as output to control the transistor controlling the relay
|
||||
puts("OK\n");
|
||||
|
||||
// setup buttons
|
||||
puts("setup buttons: ");
|
||||
rcc_periph_clock_enable(RCC_AFIO); // enable alternate function clock for external interrupt
|
||||
rcc_periph_clock_enable(GPIO_RCC(BUTTON1_PIN)); // enable clock for button
|
||||
gpio_set(GPIO_PORT(BUTTON1_PIN), GPIO_PIN(BUTTON1_PIN)); // pull up to be able to detect button push (go low)
|
||||
gpio_set_mode(GPIO_PORT(BUTTON1_PIN), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN(BUTTON1_PIN)); // set button pin to input
|
||||
exti_select_source(GPIO_EXTI(BUTTON1_PIN), GPIO_PORT(BUTTON1_PIN)); // mask external interrupt of this pin only for this port
|
||||
exti_set_trigger(GPIO_EXTI(BUTTON1_PIN), EXTI_TRIGGER_RISING); // trigger when button is released
|
||||
exti_enable_request(GPIO_EXTI(BUTTON1_PIN)); // enable external interrupt
|
||||
nvic_enable_irq(GPIO_NVIC_EXTI_IRQ(BUTTON1_PIN)); // enable interrupt
|
||||
rcc_periph_clock_enable(GPIO_RCC(BUTTON2_PIN)); // enable clock for button
|
||||
gpio_set(GPIO_PORT(BUTTON2_PIN), GPIO_PIN(BUTTON2_PIN)); // pull up to be able to detect button push (go low)
|
||||
gpio_set_mode(GPIO_PORT(BUTTON2_PIN), GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_PIN(BUTTON2_PIN)); // set button pin to input
|
||||
exti_select_source(GPIO_EXTI(BUTTON2_PIN), GPIO_PORT(BUTTON2_PIN)); // mask external interrupt of this pin only for this port
|
||||
exti_set_trigger(GPIO_EXTI(BUTTON2_PIN), EXTI_TRIGGER_RISING); // trigger when button is released
|
||||
exti_enable_request(GPIO_EXTI(BUTTON2_PIN)); // enable external interrupt
|
||||
nvic_enable_irq(GPIO_NVIC_EXTI_IRQ(BUTTON2_PIN)); // enable interrupt
|
||||
puts("OK\n");
|
||||
|
||||
// read opening settings from SRAM
|
||||
puts("reading access settings: ");
|
||||
RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); // enable power
|
||||
PWR_CR |= PWR_CR_DBP; // enable access
|
||||
if (0x4223 == BKP_DR1) { // the magic header is present
|
||||
opening_settings.days = BKP_DR2 & 0x7f;
|
||||
opening_settings.start_time = BKP_DR3;
|
||||
opening_settings.stop_time = BKP_DR4;
|
||||
opening_settings.button_pattern[0] = BKP_DR5;
|
||||
opening_settings.button_pattern[1] = BKP_DR6;
|
||||
opening_settings.button_pattern[2] = BKP_DR7;
|
||||
opening_settings.button_pattern[3] = BKP_DR8;
|
||||
opening_settings.button_pattern[4] = BKP_DR9;
|
||||
opening_settings.button_pattern[5] = BKP_DR10;
|
||||
opening_settings.button_pattern[6] = BKP_DR11;
|
||||
opening_settings.button_pattern[7] = BKP_DR12;
|
||||
opening_settings.button_pattern[8] = BKP_DR13;
|
||||
opening_settings.button_pattern[9] = BKP_DR14;
|
||||
puts("loaded\n");
|
||||
} else { // there are no settings saved
|
||||
memset(&opening_settings, 0, sizeof(struct opening_settings_t)); // clear all values
|
||||
puts("default\n");
|
||||
}
|
||||
// figure out how many button need to be pressed
|
||||
uint8_t pattern_length;
|
||||
for (pattern_length = 0; pattern_length < LENGTH(opening_settings.button_pattern) && opening_settings.button_pattern[pattern_length]; pattern_length++);
|
||||
|
||||
// setup terminal
|
||||
terminal_prefix = ""; // set default prefix
|
||||
terminal_process = &process_command; // set central function to process commands
|
||||
@ -619,6 +905,9 @@ void main(void)
|
||||
// start main loop
|
||||
bool action = false; // if an action has been performed don't go to sleep
|
||||
button_flag = false; // reset button flag
|
||||
uint32_t last_button_action = 0; // the last time a button has been pressed
|
||||
uint8_t button_pattern[LENGTH(opening_settings.button_pattern)]; // to store the input button pattern
|
||||
uint8_t button_input = 0; // how many buttons have been pressed
|
||||
while (true) { // infinite loop
|
||||
iwdg_reset(); // kick the dog
|
||||
if (user_input_available) { // user input is available
|
||||
@ -627,19 +916,71 @@ void main(void)
|
||||
char c = user_input_get(); // store receive character
|
||||
terminal_send(c); // send received character to terminal
|
||||
}
|
||||
if (button_flag) { // user pressed button
|
||||
if (button_flag || button_pressed) { // user pressed button
|
||||
action = true; // action has been performed
|
||||
puts("button pressed\n");
|
||||
printf("button released: %u\n", button_pressed);
|
||||
led_toggle(); // toggle LED
|
||||
if (pattern_length > 0 && opening_apply) { // only check pattern if there is one to compare to
|
||||
// store button
|
||||
if (button_input < LENGTH(button_pattern)) {
|
||||
button_pattern[button_input++] = button_pressed;
|
||||
last_button_action = rtc_get_counter_val(); // remember last button action
|
||||
}
|
||||
// compare pattern
|
||||
if (button_input >= pattern_length) {
|
||||
bool pattern_valid = true;
|
||||
for (uint8_t i = 0; i < pattern_length; i++) {
|
||||
if (button_pattern[i] != opening_settings.button_pattern[i]) {
|
||||
pattern_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if the correct pattern has been input, press button
|
||||
if (pattern_valid) {
|
||||
puts("button sequence valid\n");
|
||||
gpio_set(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set high to activate relay an simulate button press
|
||||
sleep_ms(1000); // hold button a bit
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set low to deactivate relay and release button
|
||||
}
|
||||
button_input = 0; // restart from scratch
|
||||
last_button_action = 0; // restart sequence
|
||||
}
|
||||
} else { // ignore all button entry when not within the opening hours
|
||||
button_input = 0;
|
||||
last_button_action = 0;
|
||||
}
|
||||
sleep_ms(100); // wait a bit to remove noise and double trigger
|
||||
button_pressed = 0; // reset button pressed
|
||||
button_flag = false; // reset flag
|
||||
}
|
||||
if (rtc_internal_tick_flag) { // the internal RTC ticked
|
||||
rtc_internal_tick_flag = false; // reset flag
|
||||
action = true; // action has been performed
|
||||
if (0 == (rtc_get_counter_val() % RTC_TICKS_SECOND)) { // one seond has passed
|
||||
if (0 == (rtc_get_counter_val() % RTC_TICKS_SECOND)) { // one second has passed
|
||||
led_toggle(); // toggle LED (good to indicate if main function is stuck)
|
||||
}
|
||||
if (last_button_action && last_button_action + 5 * RTC_TICKS_SECOND <= rtc_get_counter_val()) { // pattern entry timeout
|
||||
puts("button sequence entry timeout\n");
|
||||
last_button_action = 0; // reset last button time
|
||||
button_input = 0; // reset pattern input
|
||||
}
|
||||
// always enforce the right state
|
||||
gpio_clear(GPIO_PORT(RELAY_PANEL_PIN), GPIO_PIN(RELAY_PANEL_PIN)); // set low to not simulate button press
|
||||
// verify if day matches
|
||||
const time_t time_rtc = rtc_get_counter_val() / RTC_TICKS_SECOND + rtc_offset; // get time from internal RTC
|
||||
const struct tm* time_tm = localtime(&time_rtc); // convert time
|
||||
const uint16_t current_time = time_tm->tm_hour * 60 + time_tm->tm_min; // get time of day in minutes
|
||||
const uint8_t day = 6 - ((time_tm->tm_wday + 6) % 7); // get bit for the current day of week
|
||||
if (opening_settings.stop_time > opening_settings.start_time) { // stop time is on same day
|
||||
opening_apply = ((opening_settings.days & (1 << day)) && current_time > opening_settings.start_time && current_time < opening_settings.stop_time);
|
||||
} else { // stop time is on next day
|
||||
opening_apply = ((opening_settings.days & (1 << day)) && current_time > opening_settings.start_time) || (opening_settings.days & (1 << (day + 1 % 7)) && current_time < opening_settings.stop_time);
|
||||
}
|
||||
if (opening_apply) { // we are in the opening hours
|
||||
gpio_set(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN)); // set high to activate relay and disconnect button
|
||||
} else {
|
||||
gpio_clear(GPIO_PORT(RELAY_BUTTON_PIN), GPIO_PIN(RELAY_BUTTON_PIN)); // set high to release relay and connect button
|
||||
}
|
||||
}
|
||||
if (action) { // go to sleep if nothing had to be done, else recheck for activity
|
||||
action = false;
|
||||
@ -655,3 +996,16 @@ void rtc_isr(void)
|
||||
rtc_clear_flag(RTC_SEC); // clear flag
|
||||
rtc_internal_tick_flag = true; // notify to show new time
|
||||
}
|
||||
|
||||
void GPIO_EXTI_ISR(BUTTON1_PIN)(void) // it's the same at BUTTON2_PIN: EXT9_5
|
||||
{
|
||||
if (exti_get_flag_status(GPIO_EXTI(BUTTON1_PIN))) {
|
||||
exti_reset_request(GPIO_EXTI(BUTTON1_PIN)); // reset interrupt
|
||||
button_pressed = 1; // remember which button has been released
|
||||
}
|
||||
if (exti_get_flag_status(GPIO_EXTI(BUTTON2_PIN))) {
|
||||
exti_reset_request(GPIO_EXTI(BUTTON2_PIN)); // reset interrupt
|
||||
button_pressed = 2; // remember which button has been released
|
||||
}
|
||||
button_flag = true; // perform button action
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user