1
0
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:
benpicco 2020-09-02 11:06:18 +02:00 committed by GitHub
commit 685efe83fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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
View 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;
}

View File

@ -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