mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
88 lines
1.9 KiB
C
88 lines
1.9 KiB
C
/*
|
|
* Copyright (C) 2020 Bas Stottelaar <basstottelaar@gmail.com>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup cpu_efm32
|
|
* @ingroup drivers_periph_wdt
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Watchdog timer peripheral driver implementation for
|
|
* EFM32 Series 0 MCUs
|
|
*
|
|
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
|
* @}
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#include "cpu.h"
|
|
|
|
#include "periph/wdt.h"
|
|
|
|
#include "em_cmu.h"
|
|
#include "em_wdog.h"
|
|
|
|
#include "timex.h"
|
|
|
|
#define ENABLE_DEBUG 0
|
|
#include "debug.h"
|
|
|
|
static WDOG_PeriodSel_TypeDef _get_prescaler(uint32_t max_time)
|
|
{
|
|
const uint32_t cycles = (max_time * WDT_CLOCK_HZ) / 1000;
|
|
|
|
DEBUG("[wdt_series0] _get_prescaler: cycles=%" PRIu32 "\n", cycles);
|
|
|
|
return (WDOG_PeriodSel_TypeDef) (32 - __builtin_clz(cycles - 1) - 3);
|
|
}
|
|
|
|
void wdt_kick(void)
|
|
{
|
|
WDOGn_Feed(WDOG);
|
|
}
|
|
|
|
void wdt_start(void)
|
|
{
|
|
WDOGn_Enable(WDOG, true);
|
|
}
|
|
|
|
void wdt_stop(void)
|
|
{
|
|
WDOGn_Enable(WDOG, false);
|
|
}
|
|
|
|
void wdt_setup_reboot(uint32_t min_time, uint32_t max_time)
|
|
{
|
|
/* avoid compilation errors when NDEBUG is defined */
|
|
(void)min_time;
|
|
(void)max_time;
|
|
|
|
/* assert timings */
|
|
assert(min_time == 0);
|
|
assert(max_time > NWDT_TIME_LOWER_LIMIT ||
|
|
max_time < NWDT_TIME_UPPER_LIMIT);
|
|
|
|
/* initialize clock */
|
|
CMU_ClockEnable(cmuClock_HFLE, true);
|
|
|
|
/* initialize watchdog */
|
|
WDOG_Init_TypeDef init = WDOG_INIT_DEFAULT;
|
|
|
|
init.enable = false;
|
|
init.clkSel = wdogClkSelULFRCO;
|
|
init.perSel = _get_prescaler(max_time);
|
|
|
|
DEBUG("[wdt_series0] wdt_setup_reboot: prescaler=%d calculated_time=%" PRIu32 "\n",
|
|
(int) init.perSel,
|
|
((1 << (3 + (int)init.perSel)) + 1 ) / WDT_CLOCK_HZ * MS_PER_SEC);
|
|
|
|
WDOGn_Init(WDOG, &init);
|
|
}
|