drivers: watchdog: cc32xx: Add support
Impelement watchdog for ti_cc32xx family Signed-off-by: Pavlo Hamov <pasha.gamov@gmail.com>
This commit is contained in:
parent
d2280197ac
commit
5ae781d7d0
|
@ -302,6 +302,7 @@
|
|||
/drivers/watchdog/*gecko* @oanerer
|
||||
/drivers/watchdog/*sifive* @katsuster
|
||||
/drivers/watchdog/wdt_handlers.c @dcpleung @nashif
|
||||
/drivers/watchdog/*cc32xx* @pavlohamov
|
||||
/drivers/wifi/ @jukkar @tbursztyka @pfalcon
|
||||
/drivers/wifi/esp/ @mniestroj
|
||||
/drivers/wifi/eswifi/ @loicpoulain @nandojve
|
||||
|
|
|
@ -15,4 +15,5 @@ zephyr_sources_ifdef(CONFIG_WDT_XEC wdt_mchp_xec.c)
|
|||
zephyr_sources_ifdef(CONFIG_WDT_GECKO wdt_gecko.c)
|
||||
zephyr_sources_ifdef(CONFIG_WDT_SIFIVE wdt_sifive.c)
|
||||
zephyr_sources_ifdef(CONFIG_WDT_NPCX wdt_npcx.c)
|
||||
zephyr_sources_ifdef(CONFIG_WDT_CC32XX wdt_cc32xx.c)
|
||||
zephyr_sources_ifdef(CONFIG_USERSPACE wdt_handlers.c)
|
||||
|
|
|
@ -54,4 +54,6 @@ source "drivers/watchdog/Kconfig.sifive"
|
|||
|
||||
source "drivers/watchdog/Kconfig.npcx"
|
||||
|
||||
source "drivers/watchdog/Kconfig.cc32xx"
|
||||
|
||||
endif
|
||||
|
|
21
drivers/watchdog/Kconfig.cc32xx
Normal file
21
drivers/watchdog/Kconfig.cc32xx
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Copyright (c) 2021 Pavlo Hamov <pasha.gamov@gmail.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
DT_COMPAT_TI_CC32XX_WDG := ti,cc32xx-watchdog
|
||||
|
||||
config WDT_CC32XX
|
||||
bool "Watchdog Driver for cc32xx family of MCUs"
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_TI_CC32XX_WDG))
|
||||
depends on SOC_SERIES_CC32XX
|
||||
depends on SOC_FAMILY_TISIMPLELINK
|
||||
help
|
||||
Watchdog for cc32xx family of MCUs
|
||||
|
||||
config WDT_CC32XX_INITIAL_TIMEOUT
|
||||
int "Value for WDT timeout in ms"
|
||||
depends on WDT_CC32XX
|
||||
default 2000
|
||||
range 1 53687
|
||||
help
|
||||
Max value depend on system frequency.
|
||||
80 Mhz: 0xFFFFFFFF / (80e9 / 1000)
|
197
drivers/watchdog/wdt_cc32xx.c
Normal file
197
drivers/watchdog/wdt_cc32xx.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Pavlo Hamov <pasha.gamov@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ti_cc32xx_watchdog
|
||||
|
||||
#include <drivers/watchdog.h>
|
||||
#include <soc.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Driverlib includes */
|
||||
#include <inc/hw_types.h>
|
||||
#include <inc/hw_wdt.h>
|
||||
#include <driverlib/pin.h>
|
||||
#include <driverlib/rom.h>
|
||||
#include <driverlib/rom_map.h>
|
||||
#include <driverlib/prcm.h>
|
||||
#include <driverlib/wdt.h>
|
||||
|
||||
#define MAX_RELOAD_VALUE 0xFFFFFFFF
|
||||
|
||||
#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
#include <logging/log_ctrl.h>
|
||||
LOG_MODULE_REGISTER(wdt_cc32xx);
|
||||
|
||||
struct wdt_cc32xx_data {
|
||||
int reload;
|
||||
wdt_callback_t cb;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct wdt_cc32xx_cfg {
|
||||
const unsigned long reg;
|
||||
void (*irq_cfg_func)(void);
|
||||
};
|
||||
|
||||
static uint32_t wdt_cc32xx_msToTicks(uint32_t ms)
|
||||
{
|
||||
static const uint32_t ratio = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000;
|
||||
static const uint32_t maxMs = MAX_RELOAD_VALUE / ratio;
|
||||
|
||||
if (ms > maxMs) {
|
||||
return maxMs;
|
||||
}
|
||||
|
||||
return ms * ratio;
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_enable(const struct device *dev)
|
||||
{
|
||||
struct wdt_cc32xx_data *data = dev->data;
|
||||
const struct wdt_cc32xx_cfg *config = dev->config;
|
||||
const uint32_t reload = wdt_cc32xx_msToTicks(data->reload);
|
||||
|
||||
MAP_WatchdogIntClear(config->reg);
|
||||
MAP_WatchdogReloadSet(config->reg, reload);
|
||||
MAP_WatchdogEnable(config->reg);
|
||||
LOG_DBG("Enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_setup(const struct device *dev, uint8_t options)
|
||||
{
|
||||
const struct wdt_cc32xx_cfg *config = dev->config;
|
||||
int rv;
|
||||
|
||||
if (options & WDT_OPT_PAUSE_IN_SLEEP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
MAP_WatchdogUnlock(config->reg);
|
||||
if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
|
||||
MAP_WatchdogStallEnable(config->reg);
|
||||
} else {
|
||||
MAP_WatchdogStallDisable(config->reg);
|
||||
}
|
||||
rv = wdt_cc32xx_enable(dev);
|
||||
MAP_WatchdogLock(config->reg);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_disable(const struct device *dev)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_install_timeout(const struct device *dev,
|
||||
const struct wdt_timeout_cfg *cfg)
|
||||
{
|
||||
struct wdt_cc32xx_data *data = dev->data;
|
||||
|
||||
if (COND_CODE_1(CONFIG_WDT_MULTISTAGE, (cfg->next), (0))) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
data->reload = cfg->window.max;
|
||||
data->cb = cfg->callback;
|
||||
data->flags = cfg->flags;
|
||||
LOG_DBG("Reload time %d", data->reload);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_feed(const struct device *dev, int channel_id)
|
||||
{
|
||||
struct wdt_cc32xx_data *data = dev->data;
|
||||
const struct wdt_cc32xx_cfg *config = dev->config;
|
||||
const uint32_t reload = wdt_cc32xx_msToTicks(data->reload);
|
||||
bool inIsr = k_is_in_isr();
|
||||
|
||||
if (!inIsr) {
|
||||
MAP_WatchdogUnlock(config->reg);
|
||||
}
|
||||
MAP_WatchdogIntClear(config->reg);
|
||||
MAP_WatchdogReloadSet(config->reg, reload);
|
||||
if (!inIsr) {
|
||||
MAP_WatchdogLock(config->reg);
|
||||
}
|
||||
LOG_DBG("Feed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wdt_cc32xx_isr(const struct device *dev)
|
||||
{
|
||||
struct wdt_cc32xx_data *data = dev->data;
|
||||
|
||||
LOG_DBG("ISR");
|
||||
if (data->cb) {
|
||||
data->cb(dev, 0);
|
||||
}
|
||||
if (data->flags != WDT_FLAG_RESET_NONE) {
|
||||
LOG_PANIC();
|
||||
MAP_PRCMMCUReset(data->flags & WDT_FLAG_RESET_SOC);
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int wdt_cc32xx_init(const struct device *dev)
|
||||
{
|
||||
const struct wdt_cc32xx_cfg *config = dev->config;
|
||||
int rv;
|
||||
|
||||
LOG_DBG("init");
|
||||
config->irq_cfg_func();
|
||||
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
while (!MAP_PRCMPeripheralStatusGet(PRCM_WDT)) {
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MAP_WatchdogUnlock(config->reg);
|
||||
rv = wdt_cc32xx_enable(dev);
|
||||
MAP_WatchdogLock(config->reg);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const struct wdt_driver_api wdt_cc32xx_api = {
|
||||
.setup = wdt_cc32xx_setup,
|
||||
.disable = wdt_cc32xx_disable,
|
||||
.install_timeout = wdt_cc32xx_install_timeout,
|
||||
.feed = wdt_cc32xx_feed,
|
||||
};
|
||||
|
||||
#define cc32xx_WDT_INIT(index) \
|
||||
\
|
||||
static void wdt_cc32xx_irq_cfg_##index(void) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_INST_IRQN(index), \
|
||||
DT_INST_IRQ(index, priority), \
|
||||
wdt_cc32xx_isr, DEVICE_DT_INST_GET(index), 0); \
|
||||
irq_enable(DT_INST_IRQN(index)); \
|
||||
} \
|
||||
\
|
||||
static struct wdt_cc32xx_data wdt_cc32xx_data_##index = { \
|
||||
.reload = CONFIG_WDT_CC32XX_INITIAL_TIMEOUT, \
|
||||
.cb = NULL, \
|
||||
.flags = 0, \
|
||||
}; \
|
||||
\
|
||||
static struct wdt_cc32xx_cfg wdt_cc32xx_cfg_##index = { \
|
||||
.reg = (unsigned long)DT_INST_REG_ADDR(index), \
|
||||
.irq_cfg_func = wdt_cc32xx_irq_cfg_##index, \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(index, \
|
||||
&wdt_cc32xx_init, device_pm_control_nop, \
|
||||
&wdt_cc32xx_data_##index, &wdt_cc32xx_cfg_##index, \
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&wdt_cc32xx_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(cc32xx_WDT_INIT)
|
|
@ -12,6 +12,7 @@
|
|||
#define INT_ADCCH1 31 // ADC channel 1
|
||||
#define INT_ADCCH2 32 // ADC channel 2
|
||||
#define INT_ADCCH3 33 // ADC channel 3
|
||||
#define INT_WDT 34 // Watchdog Timer
|
||||
|
||||
/* Note: Zephyr uses exception numbers, vs the IRQ #s used by the CC32XX SDK */
|
||||
/* which are offset by 16: */
|
||||
|
@ -22,6 +23,7 @@
|
|||
#define EXP_ADCCH1 (INT_ADCCH1 - 16)
|
||||
#define EXP_ADCCH2 (INT_ADCCH2 - 16)
|
||||
#define EXP_ADCCH3 (INT_ADCCH3 - 16)
|
||||
#define EXP_WDT (INT_WDT - 16)
|
||||
#define EXC_GPIOA0 0 /* (INT_GPIOA0 - 16) = (16-16) */
|
||||
#define EXC_GPIOA1 1 /* (INT_GPIOA1 - 16) = (17-16) */
|
||||
#define EXC_GPIOA2 2 /* (INT_GPIOA2 - 16) = (18-16) */
|
||||
|
@ -128,6 +130,14 @@
|
|||
label = "ADC_0";
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
wdt0: watchdog@40000000 {
|
||||
compatible = "ti,cc32xx-watchdog";
|
||||
reg = <0x40000000 0x1000>;
|
||||
interrupts = <EXP_WDT 0>;
|
||||
label = "WDT_0";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
15
dts/bindings/watchdog/ti,cc32xx-watchdog.yaml
Normal file
15
dts/bindings/watchdog/ti,cc32xx-watchdog.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2021 Pavlo Hamov <pasha.gamov@gmail.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: cc32xx watchdog
|
||||
|
||||
compatible: "ti,cc32xx-watchdog"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
label:
|
||||
required: true
|
Loading…
Reference in a new issue