From 18a083a0f2856e74eb2590d91a714bdd34e50356 Mon Sep 17 00:00:00 2001 From: Theodore Ateba Date: Mon, 19 Feb 2018 20:49:44 +0000 Subject: AVR: Add the support of the Watchdog low level driver to the XMEGA128A4U. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@11513 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/AVR/XMEGA/LLD/WDGv1/driver.mk | 9 + os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c | 268 +++++++++++++++++++++++++ os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.h | 139 +++++++++++++ 3 files changed, 416 insertions(+) create mode 100644 os/hal/ports/AVR/XMEGA/LLD/WDGv1/driver.mk create mode 100644 os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c create mode 100644 os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.h (limited to 'os/hal/ports') diff --git a/os/hal/ports/AVR/XMEGA/LLD/WDGv1/driver.mk b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/driver.mk new file mode 100644 index 000000000..70ba572bb --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c +endif + +PLATFORMINC += $(CHIBIOS)/os/hal/ports/AVR/XMEGA/LLD/WDGv1 diff --git a/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c new file mode 100644 index 000000000..505c20d72 --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.c @@ -0,0 +1,268 @@ +/* + ChibiOS - Copyright (C) 2016..2018 Theodore Ateba + + 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 hal_wdg_lld.c + * @brief AVR WDG Driver subsystem low level driver source. + * + * @addtogroup WDG + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) + +/*==========================================================================*/ +/* Driver local definitions. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* Driver exported variables. */ +/*==========================================================================*/ + +#if (AVR_WDG_USE_WDT == TRUE) || defined(__DOXYGEN__) +WDGDriver WDTD1; +#endif + +/*==========================================================================*/ +/* Driver local variables. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* Driver local functions. */ +/*==========================================================================*/ + +/** + * @brief Check if Synchronisation busy flag is set. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * @return synchronisazion busy flag value + * @retval true The synchronisation is in process. + * @retval false The synchronisation is done. + */ +static bool wdg_get_sync_busy_flag(WDGDriver *wdgp) { + + if (wdgp->wdg->STATUS & WDT_SYNCBUSY_bm) + return true; + else + return false; +} + +/** + * @brief Enable Watchdog module. + * + * @param[in] wdgp pointer to the @p WDGDriver object + */ +static void wdg_enable(WDGDriver *wdgp) { + + uint8_t cfg = wdgp->wdg->CTRL | WDT_ENABLE_bm | WDT_CEN_bm; + CCP = CCP_IOREG_gc; + wdgp->wdg->CTRL = cfg; + + while (wdg_get_sync_busy_flag(wdgp)); +} + +/** + * @brief Set the watchdog period for the reset operation. + * + * @param[in] wdgp pointer to the @p WDGDriver object + */ +static void wdg_set_period(WDGDriver *wdgp) { + + uint8_t cfg = WDT_ENABLE_bm | WDT_CEN_bm | wdgp->config->ntp; + CCP = CCP_IOREG_gc; + wdgp->wdg->CTRL = cfg; + + while (wdg_get_sync_busy_flag(wdgp)); +} + +/** + * @brief Disable Watchdog module. + * + * @param[in] wdgp pointer to the @p WDGDriver object + */ +static void wdg_disable(WDGDriver *wdgp) { + + uint8_t cfg = (wdgp->wdg->CTRL & ~WDT_ENABLE_bm) | WDT_CEN_bm; + CCP = CCP_IOREG_gc; + wdgp->wdg->CTRL = cfg; +} + +/** + * @brief Return status of window mode enable bit. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * @return The status of the watchdog module + * @retval true The WD Window Mode is enabled. + * @retval false The WD Eindow Mode is not enabled. + */ +/*static bool wdg_is_window_mode_enabled(WDGDriver *wdgp) { + + if (wdgp->wdg->WINCTRL & WDT_WEN_bm) + return true; + else + return false; +} +*/ + +/** + * @brief Enable watchdog window mode. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * @return wd_enble status of the watchdog before the operation + * @retval true The WD is enabled before enabling window mode. + * @retval false The WD is not enabled before enabling window mode. + */ +static bool wdg_enable_window_mode(WDGDriver *wdgp) { + + uint8_t wdStatus = wdgp->wdg->CTRL & WDT_ENABLE_bm; + uint8_t cfg = wdgp->wdg->WINCTRL | WDT_WEN_bm | WDT_WCEN_bm; + + CCP = CCP_IOREG_gc; + wdgp->wdg->WINCTRL = cfg; + + while (wdg_get_sync_busy_flag(wdgp)); + + return wdStatus; +} + +/** + * @brief Enable window mode and set period. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * @return The satus of the watchdog before this operation + * @retval true The WD is enabled before enabling window mode. + * @retval false The WD is not enabled before enabling window mode. + */ +static bool wdg_set_window_period(WDGDriver *wdgp) { + + uint8_t wdStatus = wdgp->wdg->CTRL & WDT_ENABLE_bm; + uint8_t cfg = WDT_WEN_bm | WDT_WCEN_bm | wdgp->config->ntp; + + CCP = CCP_IOREG_gc; + wdgp->wdg->WINCTRL = cfg; + + while (wdg_get_sync_busy_flag(wdgp)); + + return wdStatus; +} + +/** + * @brief Disable window mode. + * + * @param[in] wdgp pointer to the @p WDGDriver object + */ +static void wdg_disable_window_mode(WDGDriver *wdgp) { + + uint8_t cfg = (wdgp->wdg->WINCTRL & ~WDT_WEN_bm) | WDT_WCEN_bm; + + CCP = CCP_IOREG_gc; + wdgp->wdg->WINCTRL = cfg; +} + +/** + * @brief Low level reset of the Watchgot timer by software. + * + * @param[in] wdgp pointer to the @p WDGDriver object + */ +static void wdg_reset(WDGDriver *wdgp) { + + (void)wdgp; + asm("wdr"); /* The reset is made by calling WDR instruction. */ +} + +/*==========================================================================*/ +/* Driver interrupt handlers. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* Driver exported functions. */ +/*==========================================================================*/ + +/** + * @brief Low level WDG driver initialization. + * + * @notapi + */ +void wdg_lld_init(void) { + +#if AVR_WDG_USE_WDT + WDTD1.state = WDG_STOP; + WDTD1.wdg = &WDT; +#endif + /* TODO: See if the configuration of the watchgod must + * be done with a default configuration. + */ +} + +/** + * @brief Configures and activates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_start(WDGDriver *wdgp) { + + /* TODO: Use the wdgp->state to see if it is a start or a restart + * and look what to do + */ + + if (wdgp->config->mode) { + wdg_set_window_period(wdgp); + wdg_enable_window_mode(wdgp); + } + else { + wdg_set_period(wdgp); + wdg_enable(wdgp); + } + + while (wdg_get_sync_busy_flag(wdgp)); +} + +/** + * @brief Deactivates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_stop(WDGDriver *wdgp) { + + if (wdgp->config->mode) { + wdg_disable_window_mode(wdgp); + } + else { + wdg_disable(wdgp); + } +} + +/** + * @brief Reloads WDG's counter. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_reset(WDGDriver *wdgp) { + + wdg_reset(wdgp); +} + +#endif /* HAL_USE_WDG */ + +/** @} */ diff --git a/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.h b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.h new file mode 100644 index 000000000..594758c5b --- /dev/null +++ b/os/hal/ports/AVR/XMEGA/LLD/WDGv1/hal_wdg_lld.h @@ -0,0 +1,139 @@ +/* + ChibiOS - Copyright (C) 2016..2018 Theodore Ateba + + 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 WDGv1/hal_wdg_lld.h + * @brief WDG Driver subsystem low level driver header. + * + * @addtogroup WDG + * @{ + */ + +#ifndef HAL_WDG_LLD_H +#define HAL_WDG_LLD_H + +#if (HAL_USE_WDG == TRUE) || defined(__DOXYGEN__) + +/*==========================================================================*/ +/* Driver constants. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* Driver pre-compile time settings. */ +/*==========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief WDT driver enable switch. + * @note The default is @p FALSE. + */ +#if !defined(AVR_WDG_USE_WDT) || defined(__DOXYGEN__) +#define AVR_WDG_USE_WDT FALSE +#endif +/** @} */ + +/*==========================================================================*/ +/* Derived constants and error checks. */ +/*==========================================================================*/ + +#define AVR_HAS_WDG TRUE + +#if AVR_WDG_USE_WDT && !AVR_HAS_WDG +#error "WDT not present in the selected device" +#endif + +#if !AVR_WDG_USE_WDT +#error "WDT driver activated but no WDT peripheral assigned" +#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 WDT driver mode. + */ + bool mode; + /** + * @brief Configuration of the WDT driver Nomal timeout period. + */ + WDT_PER_t ntp; + /** + * @brief Configuration of the WDT driver Closed timeout period. + */ + WDT_WPER_t ctp; +} 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 WDG*T registers block. + */ + WDT_t *wdg; +}; + +/*==========================================================================*/ +/* Driver macros. */ +/*==========================================================================*/ + +/*==========================================================================*/ +/* External declarations. */ +/*==========================================================================*/ + +#if (AVR_WDG_USE_WDT == TRUE) && !defined(__DOXYGEN__) +extern WDGDriver WDTD1; +#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 == TRUE */ + +#endif /* HAL_WDG_LLD_H */ + +/** @} */ -- cgit v1.2.3