/* 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 . */ /** * @addtogroup watchdog * @{ */ #include #include /** * @brief This key is expected by hardware to be written to the IWDG_KR register in order to reset the watchdog */ #define STM32_WATCHDOG_RESET_KEY 0xAAAA /** * @brief This key is expected by hardware to be written to the IWDG_KR register in order to enable the watchdog */ #define STM32_WATCHDOG_ENABLE_KEY 0xCCCC /** * @brief This key is expected by hardware to be written to the IWDG_KR register in order to enable access to config * registers */ #define STM32_WATCHDOG_REGISTER_ACCESS_KEY 0x5555 int watchdog_setup(uint8_t prescaler) { uint32_t prescaler_reg_val; /** - Activate the LSI oscillator */ RCC->CSR |= RCC_CSR_LSION; __DSB(); /** - Wait for the oscillator to be ready */ while (!(RCC->CSR & RCC_CSR_LSIRDY)); if (prescaler == 4) prescaler_reg_val = 0UL; else if (prescaler == 8) prescaler_reg_val = 1UL; else if (prescaler == 16) prescaler_reg_val = 2UL; else if (prescaler == 32) prescaler_reg_val = 3UL; else if (prescaler == 64) prescaler_reg_val = 4UL; else if (prescaler == 128) prescaler_reg_val = 5UL; else prescaler_reg_val = 6UL; /** - Unlock registers */ IWDG->KR = STM32_WATCHDOG_REGISTER_ACCESS_KEY; /** - Wait until prescaler can be written */ while (IWDG->SR & IWDG_SR_PVU); /** - Write prescaler value */ IWDG->PR = prescaler_reg_val; /* - Wait until reload value can be written */ while (IWDG->SR & IWDG_SR_RVU); /** - Set reload value fixed to 0xFFF */ IWDG->RLR = 0xFFFU; /** - Write enable key */ IWDG->KR = STM32_WATCHDOG_ENABLE_KEY; /** - Do a first reset of the counter. This also locks the config regs */ watchdog_ack(WATCHDOG_MAGIC_KEY); return 0; } int watchdog_ack(uint32_t magic) { int ret = -1; /** - Check if magic key is correct */ if (magic == WATCHDOG_MAGIC_KEY) { /** - Write reset key to watchdog */ IWDG->KR = STM32_WATCHDOG_RESET_KEY; ret = 0; } return ret; } bool watchdog_check_reset_source(void) { bool ret; ret = !!(RCC->CSR & RCC_CSR_WDGRSTF); if (ret) RCC->CSR |= RCC_CSR_RMVF; return ret; } /** @} */