1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/cpu/cc2538/periph/wdt.c
2020-10-22 11:13:08 +02:00

94 lines
2.3 KiB
C

/*
* Copyright (C) 2017 Technische Universität Berlin
*
* 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_cc2538
* @ingroup drivers_periph_wdt
* @{
*
* @file
* @brief WDT peripheral driver implementation for the cc2538
*
* @author Thomas Geithner <thomas.geithner@dai-labor.de>
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*
* @}
*/
#include <assert.h>
#include "cc2538.h"
#include "periph/wdt.h"
#define CC2538_WDT_CLK 32768
#define WTD_MS(cycles) (((cycles) * 1000 + CC2538_WDT_CLK/2) / CC2538_WDT_CLK)
typedef union {
cc2538_reg_t WDT;
struct {
cc2538_reg_t INT :2; /**< timer interval */
cc2538_reg_t RESERVED :1; /**< reserved */
cc2538_reg_t EN :1; /**< enable */
cc2538_reg_t CLR :4; /**< clear */
cc2538_reg_t RESERVED_2 :24; /**< reserved */
} WDTbits;
} cc2538_wdt_t;
cc2538_wdt_t * const WDT = (cc2538_wdt_t *) &SMWDTHROSC_WDCTL;
/*
* supported clock counter values by the cc2538
*
* The array index corresponds to the value in the INT field of the WDT register.
* According to the "CC2538 User's Guide" [1, pp. 370], the counter values and
* corresponding timings are:
* 64 -> 1.9 ms
* 512 -> 15.6 ms
* 8192 -> 250 ms
* 32768 -> 1000 ms
*
* [1] http://www.ti.com/lit/ug/swru319c/swru319c.pdf
*/
const uint16_t clk_values_ms[] = { WTD_MS(32768), WTD_MS(8192), WTD_MS(512), WTD_MS(64) };
void wdt_setup_reboot(uint32_t min_time, uint32_t max_time) {
/* window mode is not supported */
(void) min_time;
assert(min_time == 0);
/* check, if WDT is already enabled */
assert(WDT->WDTbits.EN != 1);
/* ensure valid range */
if (max_time < NWDT_TIME_LOWER_LIMIT) {
max_time = NWDT_TIME_LOWER_LIMIT;
}
/* get required clock count */
unsigned i;
for (i = 0; i < ARRAY_SIZE(clk_values_ms); ++i) {
if (max_time >= clk_values_ms[i]) {
break;
}
}
/* select the interval */
WDT->WDTbits.INT = i;
}
void wdt_start(void) {
WDT->WDTbits.EN = 1;
}
void wdt_kick(void) {
/* writing WDT clear sequence */
WDT->WDTbits.CLR = 0xa;
WDT->WDTbits.CLR = 0x5;
}