/* Reflow Oven Controller * * Copyright (C) 2020 Mario Hüttel * * This file is part of the Reflow Oven Controller Project. * * The reflow oven controller is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * The Reflow Oven Control Firmware is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the reflow oven controller project. * If not, see . */ #include #include #include #include #include #include #include #include static volatile uint64_t IN_SECTION(.ccm.bss) to_active_timestamp; static volatile enum button_state IN_SECTION(.ccm.bss) int_state; void button_init() { rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(BUTTON_RCC_MASK)); rcc_manager_enable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_SYSCFGEN)); BUTTON_PORT->MODER &= MODER_DELETE(BUTTON_PIN); BUTTON_PORT->PUPDR &= PUPDR_DELETE(BUTTON_PIN); BUTTON_PORT->PUPDR |= PULLUP(BUTTON_PIN); to_active_timestamp = 0ULL; int_state = BUTTON_IDLE; SYSCFG->EXTICR[1] |= 0x3; EXTI->IMR |= (1U<<4); EXTI->RTSR |= (1U<<4); EXTI->FTSR |= (1U<<4); NVIC_EnableIRQ(EXTI4_IRQn); } enum button_state button_read_event() { uint64_t time_delta; enum button_state temp_state; if (BUTTON_PORT->IDR & (1U<= BUTTON_LONG_ON_TIME_MS) return BUTTON_LONG; else if (time_delta >= BUTTON_SHORT_ON_TIME_MS) return BUTTON_SHORT; else return BUTTON_IDLE; } } void button_deinit() { BUTTON_PORT->MODER &= MODER_DELETE(BUTTON_PIN); BUTTON_PORT->PUPDR &= PUPDR_DELETE(BUTTON_PIN); rcc_manager_disable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(BUTTON_RCC_MASK)); EXTI->IMR &= ~(1U<<4); rcc_manager_disable_clock(&RCC->APB2ENR, BITMASK_TO_BITNO(RCC_APB2ENR_SYSCFGEN)); } void EXTI4_IRQHandler(void) { uint64_t time_delta; /* Clear interrupts */ EXTI->PR = EXTI->PR; __DSB(); if (BUTTON_PORT->IDR & (1U<= BUTTON_SHORT_ON_TIME_MS && time_delta < BUTTON_LONG_ON_TIME_MS) { int_state = BUTTON_SHORT_RELEASED; } else if (time_delta >= BUTTON_LONG_ON_TIME_MS) { int_state = BUTTON_LONG_RELEASED; } } else { to_active_timestamp = systick_get_global_tick(); } }