changeset 1015:d4f4e1fb283b

* src/watchdog_at91.cxx: * cdl/watchdog_at91.cdl: Modified driver to work for EB40, EB40A and EB55 boards. Generally tidied up a little.
author nickg
date Tue, 13 May 2003 18:34:08 +0000
parents d8106c7ccb64
children 09c58c54db2f
files packages/devs/watchdog/arm/at91/current/ChangeLog packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx
diffstat 3 files changed, 80 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/watchdog/arm/at91/current/ChangeLog
+++ b/packages/devs/watchdog/arm/at91/current/ChangeLog
@@ -1,3 +1,9 @@
+2003-05-12  Nick Garnett  <nickg@balti.calivar.com>
+
+	* src/watchdog_at91.cxx: 
+	* cdl/watchdog_at91.cdl: Modified driver to work for EB40, EB40A
+	and EB55 boards. Generally tidied up a little.
+
 2002-08-06  Thomas Koeller  <thomas@koeller.dyndns.org>
 
 	* Added watchdog driver for ARM AT91 board.
@@ -6,6 +12,7 @@ 2002-08-06  Thomas Koeller  <thomas@koel
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
--- a/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl
+++ b/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl
@@ -9,6 +9,7 @@
 ## -------------------------------------------
 ## This file is part of eCos, the Embedded Configurable Operating System.
 ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+## Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
 ##
 ## eCos is free software; you can redistribute it and/or modify it under
 ## the terms of the GNU General Public License as published by the Free
@@ -41,7 +42,7 @@
 ######DESCRIPTIONBEGIN####
 #
 # Author(s):      tkoeller
-# Contributors:   tkoeller
+# Contributors:   tkoeller, nickg
 # Date:           2000-05-05
 #
 #####DESCRIPTIONEND####
@@ -61,9 +62,13 @@ cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_
     active_if     CYGIMP_WATCHDOG_HARDWARE
     description   "
       This package uses the watchdog device integrated
-      in the ARM CPU to execute a predefined action if the
+      in the AT91 to execute a predefined action if the
       application fails to call the reset function for
-      longer than a given timeout interval."
+      longer than a given timeout interval. This package
+      currently only supports the AT91x408xx and AT91M55800A
+      devices found on the Atmel EB40, EB40A and EB55 evaluation
+      boards. The AT91M42800 found on the EB42 is not supported
+      since it uses a totally different watchdog device."
 
     cdl_option CYGIMP_WATCHDOG_HARDWARE {
         parent	      CYGPKG_IO_WATCHDOG_IMPLEMENTATION
@@ -72,7 +77,7 @@ cdl_package CYGPKG_DEVICES_WATCHDOG_ARM_
         implements    CYGINT_WATCHDOG_IMPLEMENTATIONS
     }
     
-    cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TMEOUT_MS {
+    cdl_option CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TIMEOUT_MS {
       	display       	"Desired timeout value"
 	flavor        	data
 	legal_values  	1 to 2047
--- a/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx
+++ b/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx
@@ -9,6 +9,7 @@
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
@@ -41,7 +42,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    tkoeller
-// Contributors: tkoeller
+// Contributors: tkoeller, nickg
 // Date:         2002-05-05
 // Purpose:      Watchdog class implementation
 // Description:  Contains an implementation of the Watchdog class for use
@@ -56,21 +57,28 @@
 #include <pkgconf/kernel.h>
 #include <pkgconf/watchdog.h>
 #include <pkgconf/devs_watchdog_arm_at91.h>
+
 #include <cyg/infra/cyg_type.h>
 #include <cyg/infra/cyg_ass.h>
 #include <cyg/infra/cyg_trac.h>
 #include <cyg/hal/hal_io.h>
-#include <cyg/hal/plf_io.h>
 #include <cyg/hal/hal_diag.h>
+
 #include <cyg/io/watchdog.hxx>
+
 #if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
 #include <cyg/hal/hal_platform_ints.h>
 #include <cyg/kernel/intr.hxx>
 #endif
 
-#define MCLK_FREQUENCY_KHZ  32768
+//==========================================================================
+
+#define MCLK_FREQUENCY_KHZ  (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED/1000)
 #define MAX_TICKS     	    0x0000ffff
-#define BASE_TICKS    	    (MCLK_FREQUENCY_KHZ * CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TMEOUT_MS)
+#define BASE_TICKS    	    (MCLK_FREQUENCY_KHZ * CYGNUM_DEVS_WATCHDOG_ARM_AT91_DESIRED_TIMEOUT_MS)
+
+#if defined(CYGHWR_HAL_ARM_AT91_R40008) || \
+    defined(CYGHWR_HAL_ARM_AT91_R40807)
 
 #if   BASE_TICKS / 8 <= MAX_TICKS
 #define DIVIDER 0
@@ -88,10 +96,31 @@
 #error Desired resolution beyond hardware capabilities
 #endif
 
+#elif defined(CYGHWR_HAL_ARM_AT91_M55800A)
+
+#if   BASE_TICKS / 32 <= MAX_TICKS
+#define DIVIDER 0
+#define DIV_FACTOR 32
+#elif BASE_TICKS / 128 <= MAX_TICKS
+#define DIVIDER 1
+#define DIV_FACTOR 128
+#elif BASE_TICKS / 1024 <= MAX_TICKS
+#define DIVIDER 2
+#define DIV_FACTOR 1024
+#elif BASE_TICKS / 4096 <= MAX_TICKS
+#define DIVIDER 3
+#define DIV_FACTOR 4096
+#else
+#error Desired resolution beyond hardware capabilities
+#endif
+
+
+#endif
+
 #define TICKS 	    ((BASE_TICKS / DIV_FACTOR) | 0xfff)
 #define RESOLUTION  ((cyg_uint64) (TICKS * DIV_FACTOR ) * 1000000 / MCLK_FREQUENCY_KHZ)
 
-
+//==========================================================================
 
 #if defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT)
 
@@ -108,36 +137,40 @@ Cyg_Watchdog::init_hw(void)
 
 #else /* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
 
+//==========================================================================
+
 #define OMRVAL	(AT91_WD_OMR_OKEY | AT91_WD_OMR_IRQEN | AT91_WD_OMR_WDEN)
 #define INT_PRIO    7
 
+//==========================================================================
 
-static void *
-operator new(size_t size)
-{
-  static cyg_uint8 buf[sizeof (Cyg_Interrupt)];
-  CYG_REPORT_FUNCTION();
-  CYG_REPORT_FUNCARG1XV(size);
-  CYG_ASSERTC(size == sizeof buf);
-  CYG_REPORT_RETVAL(buf);
-  return buf;
-}
+static Cyg_Watchdog *wd;
+
+//==========================================================================
 
 static cyg_uint32
 isr(cyg_vector vector, CYG_ADDRWORD data)
 {
-  Cyg_Watchdog &wd = *(Cyg_Watchdog *) data;
-
   CYG_REPORT_FUNCTION();
   CYG_REPORT_FUNCARG2XV(vector, data);
 
-  wd.trigger();
+  wd->trigger();
   Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
   CYG_REPORT_RETVAL(Cyg_Interrupt::HANDLED);
   return Cyg_Interrupt::HANDLED;
 }
 
-static Cyg_Interrupt * wdint;
+//==========================================================================
+
+static Cyg_Interrupt wdint(
+    CYGNUM_HAL_INTERRUPT_WATCHDOG,
+    INT_PRIO,
+    0,
+    isr,
+    NULL
+  );
+
+//==========================================================================
 
 void
 Cyg_Watchdog::init_hw(void)
@@ -145,29 +178,23 @@ Cyg_Watchdog::init_hw(void)
   CYG_REPORT_FUNCTION();
   CYG_REPORT_FUNCARGVOID();
 
+  wd = this;
   resolution = RESOLUTION;
-  wdint = new Cyg_Interrupt(
-    CYGNUM_HAL_INTERRUPT_WATCHDOG,
-    INT_PRIO,
-    (CYG_ADDRWORD) this,
-    isr,
-    NULL
-  );
-  wdint->configure_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG, false, true);
-  wdint->attach();
-  wdint->acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
-  wdint->unmask_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
+  wdint.configure_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG, false, true);
+  wdint.attach();
+  wdint.acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
+  wdint.unmask_interrupt(CYGNUM_HAL_INTERRUPT_WATCHDOG);
   CYG_REPORT_RETURN();
 }
 
 #endif	/* defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) */
 
-
-
+//==========================================================================
 /*
  * Reset watchdog timer. This needs to be called regularly to prevent
  * the watchdog from firing.
  */
+
 void
 Cyg_Watchdog::reset(void)
 {
@@ -179,10 +206,12 @@ Cyg_Watchdog::reset(void)
   CYG_REPORT_RETURN();
 }
 
+//==========================================================================
 /*
  * Start watchdog to generate a hardware reset
  * or interrupt when expiring.
  */
+
 void
 Cyg_Watchdog::start(void)
 {
@@ -198,3 +227,6 @@ Cyg_Watchdog::start(void)
   HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, OMRVAL);
   CYG_REPORT_RETURN();
 }
+
+//==========================================================================
+// End of watchdog_at91.cxx