From 304c76dddd3f2a84062588c434c034d83f82fa52 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 3 Dec 2015 13:49:06 +0000 Subject: Added watchdog driver model (WDG), to be completed and tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8555 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/hal.mk | 6 +- os/hal/include/hal.h | 1 + os/hal/include/wdg.h | 89 ++++++++++++++++ os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c | 126 ++++++++++++++++++++++ os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.h | 176 +++++++++++++++++++++++++++++++ os/hal/ports/STM32/STM32F3xx/platform.mk | 9 +- os/hal/src/hal.c | 3 + os/hal/src/spi.c | 6 +- os/hal/src/wdg.c | 120 +++++++++++++++++++++ 9 files changed, 530 insertions(+), 6 deletions(-) create mode 100644 os/hal/include/wdg.h create mode 100644 os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c create mode 100644 os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.h create mode 100644 os/hal/src/wdg.c (limited to 'os/hal') diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 074970dc6..53da28525 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -64,6 +64,9 @@ endif ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),) HALSRC += $(CHIBIOS)/os/hal/src/usb.c endif +ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),) +HALSRC += $(CHIBIOS)/os/hal/src/wdg.c +endif else HALSRC = $(CHIBIOS)/os/hal/src/hal.c \ $(CHIBIOS)/os/hal/src/hal_queues.c \ @@ -87,7 +90,8 @@ HALSRC = $(CHIBIOS)/os/hal/src/hal.c \ $(CHIBIOS)/os/hal/src/spi.c \ $(CHIBIOS)/os/hal/src/st.c \ $(CHIBIOS)/os/hal/src/uart.c \ - $(CHIBIOS)/os/hal/src/usb.c + $(CHIBIOS)/os/hal/src/usb.c \ + $(CHIBIOS)/os/hal/src/wdg.c endif # Required include directories diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 9ececfe77..89ef9e08d 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -60,6 +60,7 @@ #include "spi.h" #include "uart.h" #include "usb.h" +#include "wdg.h" /* * The ST driver is a special case, it is only included if the OSAL is diff --git a/os/hal/include/wdg.h b/os/hal/include/wdg.h new file mode 100644 index 000000000..764e0b2b1 --- /dev/null +++ b/os/hal/include/wdg.h @@ -0,0 +1,89 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file wdg.h + * @brief WDG Driver macros and structures. + * + * @addtogroup WDG + * @{ + */ + +#ifndef _WDG_H_ +#define _WDG_H_ + +#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + WDG_UNINIT = 0, /**< Not initialized. */ + WDG_STOP = 1, /**< Stopped. */ + WDG_READY = 2, /**< Ready. */ +} wdgstate_t; + +#include "wdg_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Resets WDG's counter. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @iclass + */ +#define wdgResetI(wdgp) wdg_lld_reset(wdgp) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void wdgInit(void); + void wdgStart(WDGDriver *wdgp, const WDGConfig * config); + void wdgStop(WDGDriver *wdgp); + void wdgReset(WDGDriver *wdgp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_WDG == TRUE */ + +#endif /* _WDG_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c b/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c new file mode 100644 index 000000000..bdcfb383a --- /dev/null +++ b/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c @@ -0,0 +1,126 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file templates/wdg_lld.c + * @brief WDG Driver subsystem low level driver source. + * + * @addtogroup WDG + * @{ + */ + +#include "hal.h" + +#if HAL_USE_WDG || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define KR_KEY_RELOAD 0xAAAAU +#define KR_KEY_ENABLE 0xCCCCU +#define KR_KEY_WRITE 0x5555U +#define KR_KEY_PROTECT 0x0000U + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +#if STM32_WDG_USE_IWDG || defined(__DOXYGEN__) +WDGDriver WDGD1; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level WDG driver initialization. + * + * @notapi + */ +void wdg_lld_init(void) { + +#if STM32_WDG_USE_IWDG + WDGD1.state = WDG_STOP; + WDGD1.wdg = IWDG; +#endif +} + +/** + * @brief Configures and activates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_start(WDGDriver *wdgp) { + + /* Unlock IWDG.*/ + wdgp->wdg->KR = KR_KEY_WRITE; + + /* Write configuration.*/ + wdgp->wdg->PR = wdgp->config->pr; + wdgp->wdg->RLR = wdgp->config->rlr; + wdgp->wdg->WINR = wdgp->config->winr; + while (wdgp->wdg->SR != 0) + ; + + /* Start operations.*/ + wdgp->wdg->KR = KR_KEY_RELOAD; + wdgp->wdg->KR = KR_KEY_ENABLE; +} + +/** + * @brief Deactivates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @api + */ +void wdg_lld_stop(WDGDriver *wdgp) { + + osalDbgAssert(wdgp->state == WDG_STOP, + "IWDG cannot be stopped once activated"); +} + +/** + * @brief Reloads WDG's counter. + * + * @param[in] idwgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_reset(WDGDriver * wdgp) { + + wdgp->wdg->KR = KR_KEY_RELOAD; +} + +#endif /* HAL_USE_WDG */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.h b/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.h new file mode 100644 index 000000000..ba8accfe5 --- /dev/null +++ b/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.h @@ -0,0 +1,176 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file wdg_lld.h + * @brief WDG Driver subsystem low level driver header. + * + * @addtogroup WDG + * @{ + */ + +#ifndef _WDG_LLD_H_ +#define _WDG_LLD_H_ + +#if HAL_USE_WDG || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name RLR register definitions + * @{ + */ +#define STM32_IWDG_RL_MASK (0x00000FFF << 0) +#define STM32_IWDG_RL(n) ((n) << 0) +/** @} */ + +/** + * @name PR register definitions + * @{ + */ +#define STM32_IWDG_PR_MASK (7 << 0) +#define STM32_IWDG_PR_4 0U +#define STM32_IWDG_PR_8 1U +#define STM32_IWDG_PR_16 2U +#define STM32_IWDG_PR_32 3U +#define STM32_IWDG_PR_64 4U +#define STM32_IWDG_PR_128 5U +#define STM32_IWDG_PR_256 6U +/** @} */ + +/** + * @name WINR register definitions + * @{ + */ +#define STM32_IWDG_WIN_MASK (0x00000FFF << 0) +#define STM32_IWDG_WIN(n) ((n) << 0) +#define STM32_IWDG_WIN_DISABLED STM32_IWDG_WIN(0x00000FFF) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief IWDG driver enable switch. + * @details If set to @p TRUE the support for IWDG is included. + * @note The default is @p FALSE. + */ +#if !defined(STM32_WDG_USE_IWDG) || defined(__DOXYGEN__) +#define STM32_WDG_USE_IWDG FALSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !STM32_WDG_USE_IWDG +#error "WDG driver activated but no xWDG peripheral assigned" +#endif + +#if !defined(STM32_LSI_ENABLED) +#error "STM32_LSI_ENABLED not defined" +#endif + +#if STM32_LSI_ENABLED == FALSE +#error "IWDG requires LSI clock" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an WDG driver. + */ +typedef struct WDGDriver WDGDriver; + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct { + /** + * @brief Configuration of the IWDG_PR register. + * @details See the STM32 reference manual for details. + */ + uint8_t pr; + /** + * @brief Configuration of the IWDG_RLR register. + * @details See the STM32 reference manual for details. + */ + uint16_t rlr; + /** + * @brief Configuration of the IWDG_WINR register. + * @details See the STM32 reference manual for details. + */ + uint16_t winr; +} WDGConfig; + +/** + * @brief Structure representing an WDG driver. + */ +struct WDGDriver { + /** + * @brief Driver state. + */ + wdgstate_t state; + /** + * @brief Current configuration data. + */ + const WDGConfig *config; + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the IWDG registers block. + */ + IWDG_TypeDef *wdg; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_WDG_USE_IWDG && !defined(__DOXYGEN__) +extern WDGDriver WDGD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void wdg_lld_init(void); + void wdg_lld_start(WDGDriver *wdgp); + void wdg_lld_stop(WDGDriver *wdgp); + void wdg_lld_reset(WDGDriver *wdgp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_WDG */ + +#endif /* _WDG_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F3xx/platform.mk b/os/hal/ports/STM32/STM32F3xx/platform.mk index 78fbaaa4c..43fff73c7 100644 --- a/os/hal/ports/STM32/STM32F3xx/platform.mk +++ b/os/hal/ports/STM32/STM32F3xx/platform.mk @@ -49,6 +49,9 @@ endif ifneq ($(findstring HAL_USE_USB TRUE,$(HALCONF)),) PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/usb_lld.c endif +ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c +endif else PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ $(CHIBIOS)/os/hal/ports/STM32/STM32F3xx/hal_lld.c \ @@ -68,7 +71,8 @@ PLATFORMSRC := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/st_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/serial_lld.c \ $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/uart_lld.c \ - $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/usb_lld.c + $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1/usb_lld.c \ + $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1/wdg_lld.c endif # Required include directories @@ -84,4 +88,5 @@ PLATFORMINC := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1 \ $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2 \ - $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1 + $(CHIBIOS)/os/hal/ports/STM32/LLD/USBv1 \ + $(CHIBIOS)/os/hal/ports/STM32/LLD/xWDGv1 diff --git a/os/hal/src/hal.c b/os/hal/src/hal.c index 9654ac84d..055cde8a6 100644 --- a/os/hal/src/hal.c +++ b/os/hal/src/hal.c @@ -118,6 +118,9 @@ void halInit(void) { #if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__) rtcInit(); #endif +#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) + wdgInit(); +#endif /* Community driver overlay initialization.*/ #if defined(HAL_USE_COMMUNITY) || defined(__DOXYGEN__) diff --git a/os/hal/src/spi.c b/os/hal/src/spi.c index dfa7f91a9..ac7ff2c13 100644 --- a/os/hal/src/spi.c +++ b/os/hal/src/spi.c @@ -102,9 +102,9 @@ void spiStart(SPIDriver *spip, const SPIConfig *config) { } /** - * @brief Deactivates the SPI peripheral. - * @note Deactivating the peripheral also enforces a release of the slave - * select line. + * @brief Deactivates the SPI peripheral. + * @note Deactivating the peripheral also enforces a release of the slave + * select line. * * @param[in] spip pointer to the @p SPIDriver object * diff --git a/os/hal/src/wdg.c b/os/hal/src/wdg.c new file mode 100644 index 000000000..deb8e0ce9 --- /dev/null +++ b/os/hal/src/wdg.c @@ -0,0 +1,120 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file wdg.c + * @brief WDG Driver code. + * + * @addtogroup WDG + * @{ + */ + +#include "hal.h" + +#if HAL_USE_WDG || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief WDG Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void wdgInit(void) { + + wdg_lld_init(); +} + +/** + * @brief Configures and activates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * @param[in] config pointer to the @p WDGConfig object + * + * @api + */ +void wdgStart(WDGDriver *wdgp, const WDGConfig *config) { + + osalDbgCheck((wdgp != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert((wdgp->state == WDG_STOP) || (wdgp->state == WDG_READY), + "invalid state"); + wdgp->config = config; + wdg_lld_start(wdgp); + wdgp->state = WDG_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @api + */ +void wdgStop(WDGDriver *wdgp) { + + osalDbgCheck(wdgp != NULL); + + osalSysLock(); + osalDbgAssert((wdgp->state == WDG_STOP) || (wdgp->state == WDG_READY), + "invalid state"); + wdg_lld_stop(wdgp); + wdgp->state = WDG_STOP; + osalSysUnlock(); +} + +/** + * @brief Resets WDG's counter. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @api + */ +void wdgReset(WDGDriver *wdgp) { + + osalDbgCheck(wdgp != NULL); + + osalSysLock(); + osalDbgAssert(wdgp->state == WDG_READY, "not ready"); + wdgResetI(wdgp); + osalSysUnlock(); +} + +#endif /* HAL_USE_WDG */ + +/** @} */ -- cgit v1.2.3