diff options
Diffstat (limited to 'os/hal/ports/TIVA/LLD/WDT')
-rw-r--r-- | os/hal/ports/TIVA/LLD/WDT/driver.mk | 9 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c | 244 | ||||
-rw-r--r-- | os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.h | 173 |
3 files changed, 426 insertions, 0 deletions
diff --git a/os/hal/ports/TIVA/LLD/WDT/driver.mk b/os/hal/ports/TIVA/LLD/WDT/driver.mk new file mode 100644 index 0000000..867d0e6 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/WDT/driver.mk @@ -0,0 +1,9 @@ +ifeq ($(USE_SMART_BUILD),yes) +ifneq ($(findstring HAL_USE_WDG TRUE,$(HALCONF)),) +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c +endif +else +PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c +endif + +PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/TIVA/LLD/WDT diff --git a/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c b/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c new file mode 100644 index 0000000..705fce6 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.c @@ -0,0 +1,244 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + 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 WDT/hal_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. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +#if TIVA_WDG_USE_WDT0 || defined(__DOXYGEN__) +WDGDriver WDGD1; +#endif /* TIVA_WDG_USE_WDT0 */ + +#if TIVA_WDG_USE_WDT1 || defined(__DOXYGEN__) +WDGDriver WDGD2; +#endif /* TIVA_WDG_USE_WDT1 */ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Shared IRQ handler. + * + * @param[in] wdgp pointer to @p WDGDriver object. + */ +static void serve_interrupt(WDGDriver *wdgp) +{ + uint32_t mis; + + mis = HWREG(wdgp->wdt + WDT_O_MIS); + + if (mis & WDT_MIS_WDTMIS) { + /* Invoke callback, if any */ + if (wdgp->config->callback) { + if (wdgp->config->callback(wdgp)) { + /* Clear interrupt */ + HWREG(wdgp->wdt + WDT_O_ICR) = 0; + wdgTivaSyncWrite(wdgp); + } + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if TIVA_WDG_USE_WDT0 || TIVA_WDG_USE_WDT1 +/** + * @brief WDT0/WDT1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(TIVA_WDT_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + +#if TIVA_WDG_USE_WDT0 + serve_interrupt(&WDGD1); +#endif + +#if TIVA_WDG_USE_WDT1 + serve_interrupt(&WDGD2); +#endif + + OSAL_IRQ_EPILOGUE(); +} +#endif /* TIVA_WDG_USE_WDT0 || TIVA_WDG_USE_WDT1 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level WDG driver initialization. + * + * @notapi + */ +void wdg_lld_init(void) +{ +#if TIVA_WDG_USE_WDT0 + WDGD1.state = WDG_STOP; + WDGD1.wdt = WATCHDOG0_BASE; +#endif /* TIVA_WDG_USE_WDT0 */ + +#if TIVA_WDG_USE_WDT1 + WDGD2.state = WDG_STOP; + WDGD2.wdt = WATCHDOG1_BASE; +#endif /* TIVA_WDG_USE_WDT1 */ + + /* The shared vector is initialized on driver initialization and never + disabled because it is shared between the Watchdog Timers.*/ + nvicEnableVector(TIVA_WDT_NUMBER, TIVA_WDG_WDT_IRQ_PRIORITY); +} + +/** + * @brief Configures and activates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_start(WDGDriver *wdgp) +{ +#if TIVA_WDG_USE_WDT0 + if (&WDGD1 == wdgp) { + HWREG(SYSCTL_RCGCWD) |= (1 << 0); + + while (!(HWREG(SYSCTL_PRWD) & (1 << 0))) + ; + } +#endif /* TIVA_WDG_USE_WDT0 */ + +#if TIVA_WDG_USE_WDT1 + if (&WDGD2 == wdgp) { + HWREG(SYSCTL_RCGCWD) |= (1 << 1); + + while (!(HWREG(SYSCTL_PRWD) & (1 << 1))) + ; + } +#endif /* TIVA_WDG_USE_WDT1 */ + + HWREG(wdgp->wdt + WDT_O_LOAD) = wdgp->config->load; + wdgTivaSyncWrite(wdgp); + + HWREG(wdgp->wdt + WDT_O_TEST) = wdgp->config->test; + wdgTivaSyncWrite(wdgp); + + HWREG(wdgp->wdt + WDT_O_CTL) |= WDT_CTL_RESEN; + wdgTivaSyncWrite(wdgp); + + HWREG(wdgp->wdt + WDT_O_CTL) |= WDT_CTL_INTEN; + wdgTivaSyncWrite(wdgp); +} + +/** + * @brief Deactivates the WDG peripheral. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @api + */ +void wdg_lld_stop(WDGDriver *wdgp) +{ +#if TIVA_WDG_USE_WDT0 + if (&WDGD1 == wdgp) { + HWREG(SYSCTL_SRWD) |= (1 << 0); + HWREG(SYSCTL_SRWD) &= ~(1 << 0); + } +#endif /* TIVA_WDG_USE_WDT0 */ + +#if TIVA_WDG_USE_WDT1 + if (&WDGD2 == wdgp) { + HWREG(SYSCTL_SRWD) |= (1 << 1); + HWREG(SYSCTL_SRWD) &= ~(1 << 1); + } +#endif /* TIVA_WDG_USE_WDT1 */ +} + +/** + * @brief Reloads WDG's counter. + * + * @param[in] wdgp pointer to the @p WDGDriver object + * + * @notapi + */ +void wdg_lld_reset(WDGDriver *wdgp) +{ +#if defined(TM4C123_USE_REVISION_6_FIX) || defined(TM4C123_USE_REVISION_7_FIX) + +#if TIVA_WDG_USE_WDT1 + if (&WDGD2 == wdgp) { + /* Number: WDT#02 + * Description: Periodically reloading the count value into the Watchdog + * Timer Load (WDTLOAD) register of the Watchdog Timer 1 + * module will not restart the count, as specified in the data + * sheet. + * Workaround: Disable the Watchdog Timer 1 module by setting the + * appropriate bit in the Watchdog Timer Software Reset (SRWD) + * register before reprogramming the counter.*/ + wdg_lld_stop(wdgp); + wdg_lld_start(wdgp); + return; + } +#endif /* TIVA_WDG_USE_WDT1 */ + +#endif /* defined(TM4C123_USE_REVISION_6_FIX) || + defined(TM4C123_USE_REVISION_7_FIX) */ + HWREG(wdgp->wdt + WDT_O_LOAD) = wdgp->config->load; + wdgTivaSyncWrite(wdgp); +} + +#endif /* HAL_USE_WDG */ + +#if TIVA_WDG_USE_WDT1 +/** + * @brief synchronize after a write to a watchdog register. + * + * @param[in] wdgp pointer to the @p WDGDriver object. + */ +void wdgTivaSyncWrite(WDGDriver *wdgp) +{ + if (&WDGD2 == wdgp) { + while (!(HWREG(wdgp->wdt + WDT_O_CTL) & CTL_WRC)) { + ; + } + } +} +#endif /* TIVA_WDG_USE_WDT1 */ + +/** @} */ diff --git a/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.h b/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.h new file mode 100644 index 0000000..0f694c5 --- /dev/null +++ b/os/hal/ports/TIVA/LLD/WDT/hal_wdg_lld.h @@ -0,0 +1,173 @@ +/* + Copyright (C) 2014..2017 Marco Veeneman + + 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 WDT/hal_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. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief WDT driver enable switch. + * @details If set to @p TRUE the support for WDT is included. + * @note The default is @p FALSE. + */ +#if !defined(TIVA_WDG_USE_WDT) || defined(__DOXYGEN__) +#define TIVA_WDG_USE_WDT FALSE +#endif + +/** + * @brief WDT interrupt priority level setting. + */ +#if !defined(TIVA_WDG_WDT_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define TIVA_WDG_WDT_IRQ_PRIORITY 5 +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if TIVA_WDG_USE_WDT0 && !TIVA_HAS_WDT0 +#error "WDT0 not present in the selected device" +#endif + +#if TIVA_WDG_USE_WDT1 && !TIVA_HAS_WDT1 +#error "WDT1 not present in the selected device" +#endif + +#if !TIVA_WDG_USE_WDT0 && !TIVA_WDG_USE_WDT1 +#error "WDG 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 WDG timeout callback type. + * + * @param[in] wdgp pointer to the @p WDGDriver object triggering the callback. + */ +typedef bool (*wdgcallback_t)(WDGDriver *wdgp); + +/** + * @brief Driver configuration structure. + * @note It could be empty on some architectures. + */ +typedef struct +{ + /** + * @brief Interval value used by the WDT. + */ + uint32_t load; + /** + * @brief Timeout callback pointer. + * @note This callback is invoked on the first WDT timeout. If set to + * @p NULL then the callback is disabled. + */ + wdgcallback_t callback; + /** + * @brief Test register configuration value. + */ + uint16_t test; +} 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 WDT registers block. + */ + uint32_t wdt; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +#if !TIVA_WDG_USE_WDT1 +#define wdgTivaSyncWrite(wdt) +#endif + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if TIVA_WDG_USE_WDT0 && !defined(__DOXYGEN__) +extern WDGDriver WDGD1; +#endif + +#if TIVA_WDG_USE_WDT1 && !defined(__DOXYGEN__) +extern WDGDriver WDGD2; +#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); +#if TIVA_WDG_USE_WDT1 + void wdgTivaSyncWrite(WDGDriver *wdgp); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_WDG */ + +#endif /* _WDG_LLD_H_ */ + +/** @} */ |