summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/examples/watchdog/watchdog_main.c8
-rw-r--r--nuttx/arch/arm/src/sama5/sam_boot.c17
-rw-r--r--nuttx/arch/arm/src/sama5/sam_wdt.c70
-rw-r--r--nuttx/arch/arm/src/sama5/sam_wdt.h21
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt17
5 files changed, 77 insertions, 56 deletions
diff --git a/apps/examples/watchdog/watchdog_main.c b/apps/examples/watchdog/watchdog_main.c
index 53099d21a..38b4fd241 100644
--- a/apps/examples/watchdog/watchdog_main.c
+++ b/apps/examples/watchdog/watchdog_main.c
@@ -148,7 +148,7 @@ static void parse_args(FAR struct wdog_example_s *wdog, int argc, FAR char **arg
long value;
int index;
int nargs;
-
+
wdog->pingtime = CONFIG_EXAMPLES_WATCHDOG_PINGTIME;
wdog->pingdelay = CONFIG_EXAMPLES_WATCHDOG_PINGDELAY;
wdog->timeout = CONFIG_EXAMPLES_WATCHDOG_TIMEOUT;
@@ -203,7 +203,7 @@ static void parse_args(FAR struct wdog_example_s *wdog, int argc, FAR char **arg
case 'h':
wdog_help();
exit(EXIT_SUCCESS);
-
+
default:
message("Unsupported option: %s\n", ptr);
wdog_help();
@@ -341,6 +341,10 @@ int wdog_main(int argc, char *argv[])
ret = ioctl(fd, WDIOC_STOP, 0);
if (ret < 0)
{
+ /* NOTE: This may not be an error. Some watchdog hardware does not
+ * support stopping the watchdog once it has been started.
+ */
+
message("wdog_main: ioctl(WDIOC_STOP) failed: %d\n", errno);
goto errout_with_dev;
}
diff --git a/nuttx/arch/arm/src/sama5/sam_boot.c b/nuttx/arch/arm/src/sama5/sam_boot.c
index ae34927f3..cedddefeb 100644
--- a/nuttx/arch/arm/src/sama5/sam_boot.c
+++ b/nuttx/arch/arm/src/sama5/sam_boot.c
@@ -494,14 +494,29 @@ static void sam_copyvectorblock(void)
* Name: sam_wdtdisable
*
* Description:
- * Disable the watchdog timer
+ * Disable the watchdog timer. The SAMA5 always boots with the watchdog
+ * timer enabled at its maximum timeout (16 seconds). The watchdog timer
+ * can disabled by writing to the Watchdog Mode Register (WDT_MR). The
+ * WDT_MR, however, can be written only one time after the CPU has been
+ * reset.
+ *
+ * So if no watchdog timer driver has been configured, the watchdog timer
+ * must be disabled as part of the start up logic. But, on the other
+ * hand, we must not write to the WDT_MR register if the watchdog timer
+ * driver is configured. In that case, some later application will
+ * configure the WDT and begin periodic pinging (within 16 seconds,
+ * hopefully).
*
****************************************************************************/
+#ifndef CONFIG_SAMA5_WDT
static inline void sam_wdtdisable(void)
{
putreg32(WDT_MR_WDDIS, SAM_WDT_MR);
}
+#else
+# define sam_wdtdisable()
+#endif
/****************************************************************************
* Public Functions
diff --git a/nuttx/arch/arm/src/sama5/sam_wdt.c b/nuttx/arch/arm/src/sama5/sam_wdt.c
index bd0bd12bc..e948f3c85 100644
--- a/nuttx/arch/arm/src/sama5/sam_wdt.c
+++ b/nuttx/arch/arm/src/sama5/sam_wdt.c
@@ -118,11 +118,11 @@ struct sam_lowerhalf_s
/* Register operations ******************************************************/
#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG)
-static uint16_t sam_getreg(uint32_t addr);
-static void sam_putreg(uint16_t val, uint32_t addr);
+static uint32_t sam_getreg(uintptr_t regaddr);
+static void sam_putreg(uint32_t regval, uintptr_t regaddr);
#else
-# define sam_getreg(addr) getreg32(addr)
-# define sam_putreg(val,addr) putreg32(val,addr)
+# define sam_getreg(regaddr) getreg32(regaddr)
+# define sam_putreg(regval,regaddr) putreg32(regval,regaddr)
#endif
/* Interrupt hanlding *******************************************************/
@@ -178,21 +178,21 @@ static struct sam_lowerhalf_s g_wdtdev;
****************************************************************************/
#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG)
-static uint16_t sam_getreg(uint32_t addr)
+static uint32_t sam_getreg(uintptr_t regaddr)
{
static uint32_t prevaddr = 0;
- static uint32_t count = 0;
- static uint16_t preval = 0;
+ static uint32_t count = 0;
+ static uint32_t preval = 0;
/* Read the value from the register */
- uint16_t val = getreg16(addr);
+ uint32_t regval = getreg32(regaddr);
/* Is this the same value that we read from the same registe last time? Are
* we polling the register? If so, suppress some of the output.
*/
- if (addr == prevaddr && val == preval)
+ if (regaddr == prevaddr && regval == preval)
{
if (count == 0xffffffff || ++count > 3)
{
@@ -200,7 +200,7 @@ static uint16_t sam_getreg(uint32_t addr)
{
lldbg("...\n");
}
- return val;
+ return regval;
}
}
@@ -219,15 +219,15 @@ static uint16_t sam_getreg(uint32_t addr)
/* Save the new address, value, and count */
- prevaddr = addr;
- preval = val;
+ prevaddr = regaddr;
+ preval = regval;
count = 1;
}
/* Show the register value read */
- lldbg("%08x->%04x\n", addr, val);
- return val;
+ lldbg("%08x->%048\n", regaddr, regval);
+ return regval;
}
#endif
@@ -240,15 +240,15 @@ static uint16_t sam_getreg(uint32_t addr)
****************************************************************************/
#if defined(CONFIG_SAMA5_WDT_REGDEBUG) && defined(CONFIG_DEBUG)
-static void sam_putreg(uint16_t val, uint32_t addr)
+static void sam_putreg(uint32_t regval, uintptr_t regaddr)
{
/* Show the register value being written */
- lldbg("%08x<-%04x\n", addr, val);
+ lldbg("%08x<-%08x\n", regaddr, regval);
/* Write the value */
- putreg16(val, addr);
+ putreg32(regval, regaddr);
}
#endif
@@ -304,6 +304,8 @@ static int sam_interrupt(int irq, FAR void *context)
static int sam_start(FAR struct watchdog_lowerhalf_s *lower)
{
+ FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower;
+
/* The watchdog timer is enabled or disabled by writing to the MR register.
*
* NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only
@@ -312,7 +314,7 @@ static int sam_start(FAR struct watchdog_lowerhalf_s *lower)
*/
wdvdbg("Entry\n");
- return -ENOSYS;
+ return priv->started ? OK : -ENOSYS;
}
/****************************************************************************
@@ -389,7 +391,7 @@ static int sam_keepalive(FAR struct watchdog_lowerhalf_s *lower)
****************************************************************************/
static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower,
- FAR struct watchdog_status_s *status)
+ FAR struct watchdog_status_s *status)
{
FAR struct sam_lowerhalf_s *priv = (FAR struct sam_lowerhalf_s *)lower;
@@ -403,7 +405,7 @@ static int sam_getstatus(FAR struct watchdog_lowerhalf_s *lower,
{
status->flags |= WDFLAGS_ACTIVE;
}
-
+
#ifdef CONFIG_SAMA5_WDT_INTERRUPT
if (priv->handler)
{
@@ -494,7 +496,7 @@ static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower,
wdvdbg("reload=%d timout: %d->%d\n",
reload, timeout, priv->timeout);
-
+
/* Set the WDT_MR according to calculated value
*
* NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only
@@ -624,7 +626,7 @@ static xcpt_t sam_capture(FAR struct watchdog_lowerhalf_s *lower,
static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd,
unsigned long arg)
{
- wdvdbg("Entry: cmd=%d arg=%ld\n", cmd, arg);
+ wdvdbg("cmd=%d arg=%ld\n", cmd, arg);
/* No ioctls are supported */
@@ -636,7 +638,7 @@ static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd,
****************************************************************************/
/****************************************************************************
- * Name: sam_wdtinitialize
+ * Name: up_wdginitialize
*
* Description:
* Initialize the WDT watchdog time. The watchdog timer is intialized and
@@ -644,21 +646,29 @@ static int sam_ioctl(FAR struct watchdog_lowerhalf_s *lower, int cmd,
* disabled.
*
* Input Parameters:
- * devpath - The full path to the watchdog. This should be of the form
- * /dev/watchdog0
+ * None
*
* Returned Values:
* None
*
****************************************************************************/
-void sam_wdtinitialize(FAR const char *devpath)
+int up_wdginitialize(void)
{
FAR struct sam_lowerhalf_s *priv = &g_wdtdev;
- wdvdbg("Entry: devpath=%s\n", devpath);
+ wdvdbg("Entry: CR: %08x MR: %08x SR: %08x\n",
+ sam_getreg(SAM_WDT_CR), sam_getreg(SAM_WDT_MR),
+ sam_getreg(SAM_WDT_SR));
+
+ /* Check if some previous logic was disabled the watchdog timer. Since the
+ * MR can be written only one time, we are out of business if that is the
+ * case.
+ */
- /* No clocking setup is required. The Watchdog Timer uses the Slow Clock
+ DEBUGASSERT((sam_getreg(SAM_WDT_MR) & WDT_MR_WDDIS) != 0);
+
+ /* No clock setup is required. The Watchdog Timer uses the Slow Clock
* divided by 128 to establish the maximum Watchdog period to be 16 seconds
* (with a typical Slow Clock of 32768 kHz).
*/
@@ -678,7 +688,9 @@ void sam_wdtinitialize(FAR const char *devpath)
/* Register the watchdog driver as /dev/watchdog0 */
- (void)watchdog_register(devpath, (FAR struct watchdog_lowerhalf_s *)priv);
+ (void)watchdog_register("/dev/watchdog0",
+ (FAR struct watchdog_lowerhalf_s *)priv);
+ return OK;
}
#endif /* CONFIG_WATCHDOG && CONFIG_SAMA5_WDT */
diff --git a/nuttx/arch/arm/src/sama5/sam_wdt.h b/nuttx/arch/arm/src/sama5/sam_wdt.h
index 5f160173f..41f139ee7 100644
--- a/nuttx/arch/arm/src/sama5/sam_wdt.h
+++ b/nuttx/arch/arm/src/sama5/sam_wdt.h
@@ -65,27 +65,6 @@ extern "C" {
* Public Functions
****************************************************************************/
-/****************************************************************************
- * Name: sam_wdtinitialize
- *
- * Description:
- * Initialize the WDT watchdog timer. The watchdog timer is intialized and
- * registered as 'devpath. The initial state of the watchdog time is
- * disabled.
- *
- * Input Parameters:
- * devpath - The full path to the watchdog. This should be of the form
- * /dev/watchdog0
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SAMA5_WDT
-void sam_wdtinitialize(FAR const char *devpath);
-#endif
-
#undef EXTERN
#if defined(__cplusplus)
}
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index 5a3051501..f272b9557 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -1006,7 +1006,7 @@ Configurations
5. The Real Time Clock/Calendar RTC) is enabled. These are the relevant
settings:
-
+
System Type:
CONFIG_SAMA5_RTC=y : Enable the RTC driver
@@ -2152,7 +2152,7 @@ Configurations
Defaults should be okay for all related settings.
17. The Real Time Clock/Calendar RTC) may be enabled with these settings:
-
+
System Type:
CONFIG_SAMA5_RTC=y : Enable the RTC driver
@@ -2182,13 +2182,24 @@ Configurations
CONFIG_WATCHDOG=y : Enables watchdog timer driver support
Application Configuration -> Eamples
- CONFIG_EXAMPLES_WATCHDOG=y : Enable the apps/examples/watchdog
+ CONFIG_EXAMPLES_WATCHDOG=y : Enable apps/examples/watchdog
The WDT timer is driven off the slow, 32768Hz clock divided by 128.
As a result, the watchdog a maximum timeout value of 16 seconds. The
SAMA5 WDT may also only be programmed one time; the processor must be
reset before the WDT can be reprogrammed.
+ The SAMA5 always boots with the watchdog timer enabled at its maximum
+ timeout (16 seconds). In the normal case where no watchdog timer driver
+ has been configured, the watchdog timer is disabled as part of the start
+ up logic. But, since we are permitted only one opportunity to program
+ the WDT, we cannot disable the watchdog time if CONFIG_SAMA5_WDT=y. So,
+ be forewarned: You have only 16 seconds to run your watchdog timer test!
+
+ NOTE: If you are using the norboot program to run from FLASH as I did,
+ beware that the default version also disables the watchdog. You will
+ need a special version of norboot with CONFIG_SAMA5_WDT=y.
+
STATUS:
PCK FREQUENCY