# HG changeset patch # User nickg # Date 1052850848 0 # Node ID d4f4e1fb283b4f488e71b909addd41b7f63195b5 # Parent d8106c7ccb64eeb67ee054c2b47f443249d5fcd8 * src/watchdog_at91.cxx: * cdl/watchdog_at91.cdl: Modified driver to work for EB40, EB40A and EB55 boards. Generally tidied up a little. diff --git a/packages/devs/watchdog/arm/at91/current/ChangeLog b/packages/devs/watchdog/arm/at91/current/ChangeLog --- 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 + + * 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 * Added watchdog driver for ARM AT91 board. @@ -6,6 +12,7 @@ 2002-08-06 Thomas Koeller // // 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 diff --git a/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl b/packages/devs/watchdog/arm/at91/current/cdl/watchdog_at91.cdl --- 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 ## ## 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 diff --git a/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx b/packages/devs/watchdog/arm/at91/current/src/watchdog_at91.cxx --- 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 // // 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 #include #include + #include #include #include #include -#include #include + #include + #if !defined(CYGSEM_WATCHDOG_RESETS_ON_TIMEOUT) #include #include #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