mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14890 from benpicco/cpu/cc2538-wdt
cpu/cc2538: add Watchdog implementation
This commit is contained in:
commit
685efe83fb
@ -14,6 +14,7 @@ config CPU_FAM_CC2538
|
||||
select HAS_PERIPH_GPIO_IRQ
|
||||
select HAS_PERIPH_HWRNG
|
||||
select HAS_PERIPH_UART_MODECFG
|
||||
select HAS_PERIPH_WDT
|
||||
select HAS_CORTEXM_MPU
|
||||
select HAS_PUF_SRAM
|
||||
|
||||
|
@ -5,6 +5,7 @@ FEATURES_PROVIDED += periph_cpuid
|
||||
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
|
||||
FEATURES_PROVIDED += periph_hwrng
|
||||
FEATURES_PROVIDED += periph_uart_modecfg
|
||||
FEATURES_PROVIDED += periph_wdt
|
||||
|
||||
FEATURES_PROVIDED += cortexm_mpu
|
||||
FEATURES_PROVIDED += puf_sram
|
||||
|
@ -346,6 +346,16 @@ typedef gpio_t adc_conf_t;
|
||||
#define RTT_FREQUENCY (CLOCK_OSC32K)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name WDT upper and lower bound times in ms
|
||||
* @{
|
||||
*/
|
||||
/* Limits are in clock cycles according to data sheet.
|
||||
As the WDT is clocked by a 32 kHz clock and supports 4 intervals */
|
||||
#define NWDT_TIME_LOWER_LIMIT (2U)
|
||||
#define NWDT_TIME_UPPER_LIMIT (1000U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Radio peripheral configuration
|
||||
* @{
|
||||
|
91
cpu/cc2538/periph/wdt.c
Normal file
91
cpu/cc2538/periph/wdt.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 "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;
|
||||
}
|
@ -7,13 +7,27 @@
|
||||
# directory for more details.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pexpect
|
||||
import time
|
||||
import subprocess
|
||||
from testrunner import run
|
||||
|
||||
# nucleo-l152re is the default platform for this test
|
||||
BOARD = os.environ.get("BOARD", "nucleo-l152re")
|
||||
BOARD_CPU = subprocess.check_output([
|
||||
'make',
|
||||
'info-debug-variable-CPU',
|
||||
'BOARD={}'.format(BOARD),
|
||||
'--no-print-directory']).strip()
|
||||
|
||||
# We test only up to 10ms, with smaller times mcu doesn't have time to
|
||||
# print system time before resetting
|
||||
reset_times_ms = [128, 512, 1024, 8192]
|
||||
# cc2538 only supports 4 intervals [2ms, 16ms, 250ms, 1s]
|
||||
if BOARD_CPU.decode("utf-8") == 'cc2538':
|
||||
reset_times_ms = [16, 250, 1000]
|
||||
else:
|
||||
reset_times_ms = [128, 512, 1024, 8192]
|
||||
|
||||
# We don't check for accuracy, only order of magnitude. Some MCU use an
|
||||
# an internal un-calibrated clock as reference which can deviate in
|
||||
|
Loading…
Reference in New Issue
Block a user