changeset 2131:3d5d996a9e29

* cdl/hal_arm_at9a.cdl: Add the AT91SAM7S variant and control for new timer and debug usart code. * include/var_io.h: Register definitions for AT91SAM7S * include/var_arch.h: Idle action for AT91SAM7S * src/at91_misc.c (hal_hardware_init): Call HAL_PLF_HARDWARE_INIT for any platform specific initialization * src/at91_misc.c (hal_at91_reset_cpu): Use the reset controller if it exists. * src/at91_misc.c (hal_IRQ_handler): Decode interrupts from the system controller if it exists. * src/timer_tc.c (NEW) eCos timer using the Timer Counter * src/timer_pit.c (NEW) eCos timer using Periodic Interval Timer * src/hal_diag_dbg.c (NEW) Debug output via debug UART. * src/hal_diag.h: Indicate hal_at91_reset_cpu() is a C function otherwise we have problems with the watchdog driver which is C++.
author asl
date Sun, 19 Feb 2006 19:08:28 +0000
parents 9a0cafc8b9bf
children c672aadf933a
files packages/hal/arm/at91/var/current/ChangeLog packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl packages/hal/arm/at91/var/current/include/hal_diag.h packages/hal/arm/at91/var/current/include/var_arch.h packages/hal/arm/at91/var/current/include/var_io.h packages/hal/arm/at91/var/current/src/at91_misc.c packages/hal/arm/at91/var/current/src/hal_diag_dbg.c packages/hal/arm/at91/var/current/src/timer_pit.c packages/hal/arm/at91/var/current/src/timer_tc.c
diffstat 9 files changed, 1278 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/packages/hal/arm/at91/var/current/ChangeLog
+++ b/packages/hal/arm/at91/var/current/ChangeLog
@@ -1,3 +1,21 @@
+2006-02-19  Andrew Lunn  <andrew.lunn@ascom.ch>
+           Oliver Munz  <munz@speag.ch>
+
+	* cdl/hal_arm_at9a.cdl: Add the AT91SAM7S variant and control
+ 	  for new timer and debug usart code.
+	* include/var_io.h: Register definitions for AT91SAM7S
+	* include/var_arch.h: Idle action for AT91SAM7S
+	* src/at91_misc.c (hal_hardware_init): Call HAL_PLF_HARDWARE_INIT 
+	  for any platform specific initialization
+	* src/at91_misc.c (hal_at91_reset_cpu): Use the reset controller 
+	  if it exists.
+	* src/at91_misc.c (hal_IRQ_handler): Decode interrupts from
+	  the system controller if it exists.
+	* src/timer_tc.c (NEW) eCos timer using the Timer Counter
+	* src/timer_pit.c (NEW) eCos timer using Periodic Interval Timer
+	* src/hal_diag_dbg.c (NEW) Debug output via debug UART.
+	* src/hal_diag.h: Indicate hal_at91_reset_cpu() is a C function
+	  otherwise we have problems with the watchdog driver which is C++.
 
 2005-05-30  Ezequiel Conde <ezeq@cc.isel.ipl.pt>
 
--- a/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl
+++ b/packages/hal/arm/at91/var/current/cdl/hal_arm_at91.cdl
@@ -59,7 +59,7 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
         The AT91 HAL package provides the support needed to run
         eCos on Atmel AT91 based targets."
 
-    compile       hal_diag.c at91_misc.c
+    compile       at91_misc.c
 
     implements    CYGINT_HAL_DEBUG_GDB_STUBS
     implements    CYGINT_HAL_DEBUG_GDB_STUBS_BREAK
@@ -78,7 +78,8 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
         display        "AT91 variant used"
         flavor         data
         default_value  {"R40807"}
-        legal_values   {"R40807" "R40008" "M42800A" "M55800A" "JTST"}
+        legal_values   {"R40807" "R40008" "M42800A" "M55800A" "JTST" 
+                        "AT91SAM7S" }
         description    "The AT91 microcontroller family has several variants,
                         the main differences being the amount of on-chip SRAM,
                         peripherals and their layout. This option allows the
@@ -95,4 +96,77 @@ cdl_package CYGPKG_HAL_ARM_AT91 {
             normal way, i.e. a FIQ interrupt will be treated as a normal IRQ 
             using the highest priority"
     }
+
+    cdl_interface CYGINT_HAL_ARM_AT91_SYS_INTERRUPT {
+        display     "AT91 core has multiplexed system interrupts"    
+        description "
+            Some AT91 cores have a system controller which multiplexes
+            many interrupts onto the system interrupt. When this interface
+            is enabled the variant hal will perform a second level
+            expansion of these interrupts"
+    }
+
+    cdl_interface CYGINT_HAL_ARM_AT91_PIT_HW {
+        display     "Platform has a Periodic Interval Timer"
+        description "
+            This interface if implemented by HALs for CPU cores which
+            have the Periodic Interval Timer."
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91_TIMER_TC {
+        display       "Use Timer Counter for eCos Clock"
+        flavor        bool
+        default_value 1
+        requires      !CYGBLD_HAL_ARM_AT91_TIMER_PIT
+        compile       timer_tc.c
+        description   "
+            Use a Timer Counter Channel to generate the eCos Clock."
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91_TIMER_PIT {
+        display       "Use Periodic Interval Timer for eCos Clock"
+        flavor        bool
+        default_value !CYGBLD_HAL_ARM_AT91_TIMER_TC
+        requires      !CYGBLD_HAL_ARM_AT91_TIMER_TC
+        active_if     CYGINT_HAL_ARM_AT91_PIT_HW
+        compile       timer_pit.c
+        description   "
+            Use Periodic Interval Timer to generate the eCos Clock."
+    }
+
+    cdl_interface CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW {
+        display     "Platform has the DBG serial port"
+        description "
+            Some varients of the AT91 have a dedicated debug serial
+            port. The HALs of such a varient should implement this interface
+            so allowing the serial driver to the compiled"
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91_SERIAL_DBG {
+        display       "Enable the use of the DBG serial port"
+        flavor        bool
+        active_if     CYGINT_HAL_ARM_AT91_SERIAL_DBG_HW
+        active_if     !CYGBLD_HAL_ARM_AT91_SERIAL_UART
+        requires      CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+        default_value 1
+
+        compile       hal_diag_dbg.c 
+        requires      CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 0
+        requires      CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0
+
+        description   "
+            The driver for the dedicated DBG UART will be compiled in the
+            varient HAL when this option is enabled."
+    }
+
+    cdl_option CYGBLD_HAL_ARM_AT91_SERIAL_UART {
+        display       "Enable the use of the UARTS for debug output"
+        flavor        bool
+        default_value 1
+        compile       hal_diag.c 
+        requires      !CYGBLD_HAL_ARM_AT91_SERIAL_DBG
+        description   "        
+            The driver for using the UARTS will be compiled in the
+            varient HAL when this option is enabled."
+    }
 }
--- a/packages/hal/arm/at91/var/current/include/hal_diag.h
+++ b/packages/hal/arm/at91/var/current/include/hal_diag.h
@@ -79,7 +79,7 @@ externC void hal_delay_us(cyg_int32 usec
 //-----------------------------------------------------------------------------
 // reset
 
-extern void hal_at91_reset_cpu(void);
+externC void hal_at91_reset_cpu(void);
 
 //-----------------------------------------------------------------------------
 // end of hal_diag.h
--- a/packages/hal/arm/at91/var/current/include/var_arch.h
+++ b/packages/hal/arm/at91/var/current/include/var_arch.h
@@ -74,7 +74,8 @@ CYG_MACRO_START                         
 CYG_MACRO_END
 
 #elif defined(CYGHWR_HAL_ARM_AT91_M42800A) || \
-      defined(CYGHWR_HAL_ARM_AT91_M55800A)
+      defined(CYGHWR_HAL_ARM_AT91_M55800A) || \
+      defined(CYGHWR_HAL_ARM_AT91SAM7S)
 
 #define HAL_IDLE_THREAD_ACTION(_count_)                       \
 CYG_MACRO_START                                               \
--- a/packages/hal/arm/at91/var/current/include/var_io.h
+++ b/packages/hal/arm/at91/var/current/include/var_io.h
@@ -12,6 +12,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>
+// Copyright (C) 2005, 2006 Andrew Lunn (andrew.lunn@ascom.ch>
 //
 // 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
@@ -35,16 +36,13 @@
 //
 // This exception does not invalidate any other reasons why a work based on
 // this file might be covered by the GNU General Public License.
-//
-// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
-// at http://sources.redhat.com/ecos/ecos-license/
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //=============================================================================
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):   jskov
-// Contributors:jskov, gthomas, tkoeller, tdrury, nickg
+// Contributors:jskov, gthomas, tkoeller, tdrury, nickg, asl
 // Date:        2001-07-12
 // Purpose:     AT91 variant specific registers
 // Description: 
@@ -217,6 +215,81 @@
 #define AT91_PIO_PSR_TIOA2   0x04000000 // Timer 2 Signal A
 #define AT91_PIO_PSR_TIOB2   0x08000000 // Timer 2 Signal B
 
+#elif defined (CYGHWR_HAL_ARM_AT91SAM7S)
+#include <pkgconf/hal_arm_at91sam7s.h>
+
+// PIOA
+#define AT91_PIO_PSR_PWM0     0x00000001 // Pulse Width Modulation 0
+#define AT91_PIO_PSR_PWM1     0x00000002 // Pulse Width Modulation 1
+#define AT91_PIO_PSR_PWM2     0x00000004 // Pulse Width Modulation 2
+#define AT91_PIO_PSR_TWD      0x00000008 // Two Wire Data
+#define AT91_PIO_PSR_TWCK     0x00000010 // Two Wire Clock
+#define AT91_PIO_PSR_RXD0     0x00000020 // USART 0 Receive Data
+#define AT91_PIO_PSR_TXD0     0x00000040 // USART 0 Transmit Data
+#define AT91_PIO_PSR_RTS0     0x00000080 // USART 0 Ready To Send
+#define AT91_PIO_PSR_CTS0     0x00000100 // USART 0 Clear To Send
+#define AT91_PIO_PSR_DRXD     0x00000200 // Debug UART Receive
+#define AT91_PIO_PSR_DTXD     0x00000400 // Debug UAET Transmit
+#define AT91_PIO_PSR_NPCS0    0x00000800 // SPI Chip Select 0
+#define AT91_PIO_PSR_MISO     0x00001000 // SPI Input
+#define AT91_PIO_PSR_MOIS     0x00002000 // SPI Output
+#define AT91_PIO_PSR_SPCK     0x00004000 // SPI clock
+#define AT91_PIO_PSR_TF       0x00008000 // Transmit Frame Sync
+#define AT91_PIO_PSR_TK       0x00010000 // Transmit Clock
+#define AT91_PIO_PSR_TD       0x00020000 // Transmit Data
+#define AT91_PIO_PSR_RD       0x00040000 // Receive Data
+#define AT91_PIO_PSR_RK       0x00080000 // Receive Clock
+#define AT91_PIO_PSR_RF       0x00100000 // Receive Frame Sync
+#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32)
+#define AT91_PIO_PSR_RXD1     0x00200000 // USART 1 Receive Data
+#define AT91_PIO_PSR_TXD1     0x00400000 // USART 1 Transmit Data
+#define AT91_PIO_PSR_SCK1     0x00800000 // USART 1 Serial Clock
+#define AT91_PIO_PSR_RTS1     0x01000000 // USART 1 Ready To Send
+#define AT91_PIO_PSR_CTS1     0x02000000 // USART 1 Clear To Send
+#define AT91_PIO_PSR_DCD1     0x04000000 // USART 1 Data Carrier Detect
+#define AT91_PIO_PSR_DTR1     0x08000000 // USART 1 Data Terminal Ready
+#define AT91_PIO_PSR_DSR1     0x10000000 // USART 1 Data Set Ready
+#define AT91_PIO_PSR_RI1      0x20000000 // USART 2 Ring Indicator
+#define AT91_PIO_PSR_IRQ1     0x40000000 // Interrupt Request 1
+#define AT01_PIO_PSR_NPCS1    x800000000 // SPI Chip Select 1
+#endif // !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s64)
+
+// PIOB
+#define AT91_PIO_PSR_TIOA0     0x00000001 // Timer/Counter 0 IO Line A
+#define AT91_PIO_PSR_TIOB0     0x00000002 // Timer/Counter 0 IO Line B
+#define AT91_PIO_PSR_SCK0      0x00000004 // USART 0 Serial Clock
+#define AT91_PIO_PSR_NPCS3     0x00000008 // SPI Chip Select 3
+#define AT91_PIO_PSR_TCLK0     0x00000010 // Timer/Counter 0 Clock Input
+#define AT91_PIO_PSR_NPCS3X    0x00000020 // SPI Chip Select 3 (again)
+#define AT91_PIO_PSR_PCK0      0x00000040 // Programmable Clock Output 0
+#define AT91_PIO_PSR_PWM3      0x00000080 // Pulse Width Modulation #3
+#define AT91_PIO_PSR_ADTRG     0x00000100 // ADC Trigger
+#define AT91_PIO_PSR_NPCS1     0x00000200 // SPI Chip Select 1
+#define AT91_PIO_PSR_NPCS2     0x00000400 // SPI Chip Select 2
+#define AT91_PIO_PSR_PWMOX     0x00000800 // Pulse Width Modulation #0 (again)
+#define AT91_PIO_PSR_PWM1X     0x00001000 // Pulse Width Modulation #1 (again)
+#define AT91_PIO_PSR_PWM2X     0x00002000 // Pulse Width Modulation #2 (again)
+#define AT91_PIO_PSR_PWM3X     0x00004000 // Pulse Width Modulation #4 (again)
+#define AT91_PIO_PSR_TIOA1     0x00008000 // Timer/Counter 1 IO Line A
+#define AT91_PIO_PSR_TIOB1     0x00010000 // Timer/Counter 1 IO Line B
+#define AT91_PIO_PSR_PCK1      0x00020000 // Programmable Clock Output 1
+#define AT91_PIO_PSR_PCK2      0x00040000 // Programmable Clock Output 2
+#define AT91_PIO_PSR_FIQ       0x00080000 // Fast Interrupt Request
+#define AT91_PIO_PSR_IRQ0      0x00100000 // Interrupt Request 0
+#if !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s32)
+#define AT91_PIO_PSR_PCK1X     0x00200000 // Programmable Clock Output 1(again)
+#define AT91_PIO_PSR_NPCS3XX   0x00400000 // SPI Chip Select 3 (yet again)
+#define AT91_PIO_PSR_PWMOXX    0x00800000 // Pulse Width Modulation #0 (again)
+#define AT91_PIO_PSR_PWM1XX    0x01000000 // Pulse Width Modulation #1 (again)
+#define AT91_PIO_PSR_PWM2XX    0x02000000 // Pulse Width Modulation #2 (again)
+#define AT91_PIO_PSR_TIOA2     0x04000000 // Timer/Counter 2 IO Line A
+#define AT91_PIO_PSR_TIOB2     0x08000000 // Timer/Counter 2 IO Line B
+#define AT91_PIO_PSR_TCLK1     0x10000000 // External Clock Input 1
+#define AT91_PIO_PSR_TCLK2     0x20000000 // External Clock Input 2
+#define AT91_PIO_PSR_NPCS2X    0x40000000 // SPI Chip Select 2 (again)
+#define AT91_PIO_PSR_PCK2X     0x80000000 // Programmable Clock Output 2(again)
+#endif // !defined(CYGHWR_HAL_ARM_AT91SAM7S_at91sam7s64)
+
 #else
 
 #define AT91_PIO_PSR_TCLK0    0x00000001 // Timer #0 clock
@@ -269,6 +342,20 @@
 #define AT91_PIO_IMR  0x48  // Interrupt mask
 #define AT91_PIO_ISR  0x4C  // Interrupt status
 
+#ifdef CYGHWR_HAL_ARM_AT91SAM7S
+#define AT91_PIO_MDER  0x50  // Multi-drive Enable Register
+#define AT91_PIO_MDDR  0x54  // Multi-drive Disable Register
+#define AT91_PIO_MDSR  0x58  // Multi-drive Status Register
+#define AT91_PIO_PPUDR 0x60  // Pad Pull-up Disable Register
+#define AT91_PIO_PPUER 0x64  // Pad Pull-up Enable Register
+#define AT91_PIO_PPUSR 0x68  // Pad Pull-Up Status Register
+#define AT91_PIO_ASR   0x70  // Select A Register
+#define AT91_PIO_BSR   0x74  // Select B Regsiter
+#define AT91_PIO_ABS   0x78  // AB Select Regsiter
+#define AT91_PIO_OWER  0xa0  // Output Write Enable Register
+#define AT91_PIO_OWDR  0xa4  // Output Write Disable Register
+#define AT91_PIO_OWSR  0xa8  // Output Write Status Register
+#endif // CYGHWR_HAL_ARM_AT91SAM7S
 //=============================================================================
 // Advanced Interrupt Controller (AIC)
 
@@ -358,6 +445,13 @@
 #define AT91_AIC_EOI    0x130
 #define AT91_AIC_SVR    0x134
 
+#ifdef CYGHWR_HAL_ARM_AT91SAM7S
+#define AT91_AIC_DCR    0x138 // Debug Control Register
+#define AT91_AIC_FFER   0x140 // Fast Forcing Enable Register
+#define AT91_AIC_FFDR   0x144 // Fast Forcing Enable Register
+#define AT91_AIC_FFSR   0x148 // Fast Forcing Enable Register
+#endif 
+
 //=============================================================================
 // Timer / counter
 
@@ -535,7 +629,6 @@
 #define AT91_EBI_MCR_ALE_1M   0x7   // Address line enable
 #define AT91_EBI_MCR_DRP      (0x1 << 4)  // Data read protocol
 
-
 //=============================================================================
 // Power Saving or Management
 
@@ -555,7 +648,8 @@
 #define AT91_PS_PCSR      0x00c    // Peripheral clock status
 
 #elif defined(CYGHWR_HAL_ARM_AT91_M42800A) || \
-      defined(CYGHWR_HAL_ARM_AT91_M55800A)
+      defined(CYGHWR_HAL_ARM_AT91_M55800A) || \
+      defined(CYGHWR_HAL_ARM_AT91SAM7S)
 
 // (Advanced) Power Management
 
@@ -572,11 +666,22 @@
 #define AT91_PMC_PCSR           0x18
 
 #define AT91_PMC_CGMR           0x20
-    
+
+#ifndef AT91_PMC_SR
 #define AT91_PMC_SR             0x30
+#endif
+
+#ifndef AT91_PMC_IER
 #define AT91_PMC_IER            0x34
+#endif
+
+#ifndef AT91_PMC_IDR
 #define AT91_PMC_IDR            0x38
+#endif
+
+#ifndef AT91_PMC_IMR
 #define AT91_PMC_IMR            0x3c
+#endif
 
 #if defined(CYGHWR_HAL_ARM_AT91_M42800A)
 
@@ -683,16 +788,35 @@
 #define AT91_PMC_SR_MOSCS       0x01
 #define AT91_PMC_SR_LOCK        0x02
 
-#endif
+#elif defined(CYGHWR_HAL_ARM_AT91_JTST)
+// No power management control for the JTST
+
+#elif defined(CYGHWR_HAL_ARM_AT91SAM7S)
+#define AT91_PMC_SCER_PCK  (1 << 0) // Processor Clock
+#define AT91_PMC_SCER_UDP  (1 << 7) // USB Device Clock
+#define AT91_PMC_SCER_PCK0 (1 << 8) // Programmable Clock Output
+#define AT91_PMC_SCER_PCK1 (1 << 9) // Programmable Clock Output
+#define AT91_PMC_SCER_PCK2 (1 << 10) // Programmable Clock Output
+#define AT91_PMC_SCER_PCK3 (1 << 11) // Programmable Clock Output
 
-#elif defined(CYGHWR_HAL_ARM_AT91_JTST)
-// Now power management control for the JTST
+#define AT91_PMC_PCER_PIOA (1 << 2) // Parallel IO Controller
+#define AT91_PMC_PCER_ADC  (1 << 4) // Analog-to-Digital Conveter
+#define AT91_PMC_PCER_SPI  (1 << 5) // Serial Peripheral Interface
+#define AT91_PMC_PCER_US0  (1 << 6) // USART 0
+#define AT91_PMC_PCER_US1  (1 << 7) // USART 1
+#define AT91_PMC_PCER_SSC  (1 << 8) // Serial Synchronous Controller
+#define AT91_PMC_PCER_TWI  (1 << 9) // Two-Wire Interface
+#define AT91_PMC_PCER_PWMC (1 <<10) // PWM Controller
+#define AT91_PMC_PCER_UDP  (1 <<11) // USB Device Port
+#define AT91_PMC_PCER_TC0  (1 <<12) // Timer Counter 0
+#define AT91_PMC_PCER_TC1  (1 <<13) // Timer Counter 1
+#define AT91_PMC_PCER_TC2  (1 <<14) // Timer Counter 2
 #else
 
 #error Unknown AT91 variant
 
-#endif
-
+#endif 
+#endif 
 
 //=============================================================================
 // Watchdog
@@ -788,6 +912,272 @@
 #define AT91_SPI_PIO_NPCS(x) (((x)&0x0F)<<26)
 #endif
 
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+ 
+#define AT91_SPI_PIO         AT91_PIOA
+#define AT91_SPI_PIO_NPCS(x)                   \
+   ( (x & (1 << 0) ? AT91_PIO_PSR_NPCS0 : 0) | \
+     (x & (1 << 1) ? AT91_PIO_PSR_NPCS1 : 0) | \
+     (x & (1 << 2) ? AT91_PIO_PSR_NPCS2 : 0) | \
+     (x & (1 << 3) ? AT91_PIO_PSR_NPCS3 : 0))
+#endif
+
+//=============================================================================
+// Watchdog Timer Controller
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_WDTC
+#define AT91_WDTC 0xFFFFFD40
+#endif
+
+#define AT91_WDTC_WDCR 0x00 // Watchdog Control Register
+#define AT91_WDTC_WDCR_RELOAD  (1 << 0)  // Reload the watchdog
+#define AT91_WDTC_WDCR_KEY     (0xa5 << 24) // Password for the write op
+#define AT91_WDTC_WDMR 0x04 // Watchdog Mode Register
+#define AT91_WDTC_WDMR_FIEN    (1 << 12) // Fault Interrupt Mode Enable
+#define AT91_WDTC_WDMR_RSTEN   (1 << 13) // Reset Enable
+#define AT91_WDTC_WDMR_RPROC   (1 << 14) // Trigger a processor reset
+#define AT91_WDTC_WDMR_DIS     (1 << 15) // Disable
+#define AT91_WDTC_WDMR_WDD_SHIFT (16)    // Delta Value shift
+#define AT91_WDTC_WDMR_DBGHLT  (1 << 28) // Stop when in debug state
+#define AT91_WDTC_WDMR_IDLEHLT (1 << 29) // Stop when in idle more
+#define AT91_WDTC_WDSR 0x08 // Watchdog Status Register
+#define AT91_WDTC_WDSR_UNDER   (1 << 0)  // Underflow has occurred
+#define AT91_WDTC_WDSR_ERROR   (1 << 1)  // Error has occurred
+#endif //CYGHWR_HAL_ARM_AT91SAM7S 
+
+//=============================================================================
+// Reset Controller
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_RST
+#define AT91_RST 0xFFFFFD00
+#endif
+
+#define AT91_RST_RCR 0x00 // Reset Control Register
+#define AT91_RST_RCR_PROCRST  (1 << 0) // Processor Reset
+#define AT91_RST_RCR_ICERST   (1 << 1) // ICE Reset
+#define AT91_RST_RCR_PERRST   (1 << 2) // Peripheral Reset
+#define AT91_RST_RCR_EXTRST   (1 << 3) // External Reset
+#define AT91_RST_RCR_KEY      (0xA5 << 24) // Key
+#define AT91_RST_RSR 0x04 // Reset Status Register
+#define AT91_RST_RSR_USER          (1 << 0) // User Reset
+#define AT91_RST_RSR_BROWN         (1 << 1) // Brownout detected
+#define AT91_RST_RSR_TYPE_POWERUP  (0 << 8) // Power on Reset
+#define AT91_RST_RSR_TYPE_WATCHDOG (2 << 8) // Watchdog Reset
+#define AT91_RST_RSR_TYPE_SW       (3 << 8) // Software Reset
+#define AT91_RST_RSR_TYPE_USER     (4 << 8) // NRST pin Reset
+#define AT91_RST_RSR_TYPE_BROWNOUT (5 << 8) // Brown-out Reset
+#define AT91_RST_RSR_NRST_SET (1 << 16) // NRST pin set
+#define AT91_RST_RSR_SRCMP    (1 << 17) // Software reset in progress
+#define AT91_RST_RMR 0x08 // Reset Mode Register
+#define AT91_RST_RMR_URSTEN  (1 << 0)  // User Reset Enabled
+#define AT91_RST_RMR_URSTIEN (1 << 4)  // User Reset Interrupt Enabled
+#define AT91_RST_RMR_BODIEN  (1 << 16) // Brownout Dection Interrupt Enabled
+#define AT91_RST_RMR_KEY     (0xA5 << 24) // Key
+
+#endif
+
+//=============================================================================
+// Memory Controller
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_MC
+#define AT91_MC 0xFFFFFF00
+#endif
+
+#define AT91_MC_RCR  0x00 // Remap Control Register
+#define AT91_MC_ASR  0x04 // Abort Status Register
+#define AT91_MC_AASR 0x08 // Abort Address Status Register
+#define AT91_MC_FMR  0x60 // Flash Mode Register
+#define AT91_MC_FMR_FRDY  (1 << 0) // Enable interrupt for Flash Ready
+#define AT91_MC_FMR_LOCKE (1 << 2) // Enable interrupt for Flash Lock Error
+#define AT91_MC_FMR_PROGE (1 << 3) // Enable interrupt for Flash Prog Error
+#define AT91_MC_FMR_NEBP  (1 << 7) // No erase before programming
+#define AT91_MC_FMR_0FWS  (0 << 8) // 1R,2W wait states
+#define AT91_MC_FMR_1FWS  (1 << 8) // 2R,3W wait states
+#define AT91_MC_FMR_2FWS  (2 << 8) // 3R,4W wait states
+#define AT91_MC_FMR_3FWS  (3 << 8) // 4R,4W wait states
+#define AT91_MC_FMR_FMCN_MASK (0xff << 16)
+#define AT91_MC_FMR_FMCN_SHIFT 16
+#define AT91_MC_FCR  0x64 // Flash Command Register
+#define AT91_MC_FCR_START_PROG (0x1 << 0) // Start Programming of Page
+#define AT91_MC_FCR_LOCK       (0x2 << 0) // Lock sector
+#define AT91_MC_FCR_PROG_LOCK  (0x3 << 0) // Program and Lock
+#define AT91_MC_FCR_UNLOCK     (0x4 << 0) // Unlock a segment
+#define AT91_MC_FCR_ERASE_ALL  (0x8 << 0) // Erase everything
+#define AT91_MC_FCR_SET_GP_NVM (0xb << 0) // Set general purpose NVM bits
+#define AT91_MC_FCR_CLR_GP_NVM (0xd << 0) // Clear general purpose NVM bits
+#define AT91_MC_FCR_SET_SECURITY (0xf << 0) // Set security bit
+#define AT91_MC_FCR_PAGE_MASK  (0x3ff)
+#define AT91_MC_FCR_PAGE_SHIFT 8
+#define AT91_MC_FCR_KEY        (0x5a << 24) // Key to enable command
+#define AT91_MC_FSR  0x68 // Flash Status Register
+#define AT91_MC_FSR_FRDY       (1 << 0) // Flash Ready for next command
+#define AT91_MC_FSR_LOCKE      (1 << 2) // Programming of a locked block
+#define AT91_MC_FSR_PROGE      (1 << 3) // Programming error
+#define AT91_MC_FSR_SECURITY   (1 << 4) // Security bit is set
+#define AT91_MC_FSR_GPNVM0     (1 << 8) // General purpose NVM bit 0
+#define AT91_MC_FSR_GPNVM1     (1 << 9) // General purpose NVM bit 1
+#endif
+
+//=============================================================================
+// Debug Unit
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_DBG
+#define AT91_DBG 0xFFFFF200
+#endif
+
+#define AT91_DBG_CR   0x00 // Control Register
+#define AT91_DBG_CR_RSTRX  (0x1 << 2)   // Reset Receiver
+#define AT91_DBG_CR_RSTTX  (0x1 << 3)   // Reset Transmitter
+#define AT91_DBG_CR_RXEN   (0x1 << 4)   // Receiver Enable
+#define AT91_DBG_CR_RXDIS  (0x1 << 5)   // Receiver Disable
+#define AT91_DBG_CR_TXEN   (0x1 << 6)   // Transmitter Enable
+#define AT91_DBG_CR_TXDIS  (0x1 << 7)   // Transmitter Disable
+#define AT91_DBG_CR_RSTSTA (0x1 << 8)   // Reset Status Bits
+#define AT91_DBG_MR   0x04 // Mode Register
+#define AT91_DBG_MR_PAR_EVEN  (0x0 << 9) // Even Parity
+#define AT91_DBG_MR_PAR_ODD   (0x1 << 9) // Odd Parity
+#define AT91_DBG_MR_PAR_SPACE (0x2 << 9) // Parity forced to Space
+#define AT91_DBG_MR_PAR_MARK  (0x3 << 9) // Parity forced to Mark
+#define AT91_DBG_MR_PAR_NONE  (0x4 << 9) // No Parity
+#define AT91_DBG_MR_PAR_MULTI (0x6 << 9) // Multi-drop mode
+#define AT91_DBG_MR_CHMODE_NORMAL  (0x0 << 14) // Normal mode
+#define AT91_DBG_MR_CHMODE_AUTO    (0x1 << 14) // Automatic Echo
+#define AT91_DBG_MR_CHMODE_LOCAL   (0x2 << 14) // Local Loopback
+#define AT91_DBG_MR_CHMODE_REMOTE  (0x3 << 14) // Remote Loopback
+#define AT91_DBG_IER  0x08 // Interrupt Enable Register
+#define AT91_DBG_IDR  0x0c // Interrupt Disable Register
+#define AT91_DBG_IMR  0x10 // Interrupt Mask Register
+#define AT91_DBG_CSR  0x14 // Channel Status Register
+#define AT91_DBG_CSR_RXRDY  (1 << 0) // Receiver Ready
+#define AT91_DBG_CSR_TXRDY  (1 << 1) // Transmitter Ready
+#define AT91_DBG_RHR  0x18 // Receiver Holding Register
+#define AT91_DBG_THR  0x1c // Transmitter Holding Register
+#define AT91_DBG_BRGR 0x20 // Baud Rate Generator Register
+#define AT91_DBG_C1R  0x40 // Chip ID1 register
+#define AT91_DBG_C1R_ARM945ES (1 << 5) 
+#define AT91_DBG_C1R_ARM7TDMI (2 << 5)
+#define AT91_DBG_C1R_ARM920T  (4 << 5)
+#define AT91_DBG_C1R_ARM926EJ (5 << 5)
+#define AT91_DBG_C1R_CPU_MASK  (0x7 << 5)
+#define AT91_DBG_C1R_FLASH_0K    (0x0 << 8)
+#define AT91_DBG_C1R_FLASH_8K    (0x1 << 8)
+#define AT91_DBG_C1R_FLASH_16K   (0x2 << 8)
+#define AT91_DBG_C1R_FLASH_32K   (0x3 << 8)
+#define AT91_DBG_C1R_FLASH_64K   (0x5 << 8)
+#define AT91_DBG_C1R_FLASH_128K  (0x7 << 8)
+#define AT91_DBG_C1R_FLASH_256K  (0x9 << 8)
+#define AT91_DBG_C1R_FLASH_512K  (0xa << 8)
+#define AT91_DBG_C1R_FLASH_1024K (0xc << 8)
+#define AT91_DBG_C1R_FLASH_2048K (0xe << 8)
+#define AT91_DBG_C1R_FLASH_MASK  (0xf << 8)
+#define AT91_DBG_C1R_FLASH2_0K    (0x0 << 12)
+#define AT91_DBG_C1R_FLASH2_8K    (0x1 << 12)
+#define AT91_DBG_C1R_FLASH2_16K   (0x2 << 12)
+#define AT91_DBG_C1R_FLASH2_32K   (0x3 << 12)
+#define AT91_DBG_C1R_FLASH2_64K   (0x5 << 12)
+#define AT91_DBG_C1R_FLASH2_128K  (0x7 << 12)
+#define AT91_DBG_C1R_FLASH2_256K  (0x9 << 12)
+#define AT91_DBG_C1R_FLASH2_512K  (0xa << 12)
+#define AT91_DBG_C1R_FLASH2_1024K (0xc << 12)
+#define AT91_DBG_C1R_FLASH2_2048K (0xe << 12)
+#define AT91_DBG_C1R_FLASH2_MASK  (0xf << 12)
+#define AT91_DBG_C1R_SRAM_1K      (0x1 << 16)  
+#define AT91_DBG_C1R_SRAM_2K      (0x2 << 16)
+#define AT91_DBG_C1R_SRAM_112K    (0x4 << 16)
+#define AT91_DBG_C1R_SRAM_4K      (0x5 << 16)
+#define AT91_DBG_C1R_SRAM_80K     (0x6 << 16)
+#define AT91_DBG_C1R_SRAM_160K    (0x7 << 16)
+#define AT91_DBG_C1R_SRAM_8K      (0x8 << 16)
+#define AT91_DBG_C1R_SRAM_16K     (0x9 << 16)
+#define AT91_DBG_C1R_SRAM_32K     (0xa << 16)
+#define AT91_DBG_C1R_SRAM_64K     (0xb << 16)
+#define AT91_DBG_C1R_SRAM_128K    (0xc << 16)
+#define AT91_DBG_C1R_SRAM_256K    (0xd << 16)
+#define AT91_DBG_C1R_SRAM_96K     (0xe << 16)
+#define AT91_DBG_C1R_SRAM_512K    (0xf << 16)
+#define AT91_DBG_C1R_SRAM_MASK    (0xf << 16)
+#define AT91_DBG_C1R_ARCH_AT75Cxx (0xf0 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x40 (0x40 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x63 (0x63 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x55 (0x55 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x42 (0x42 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x92 (0x92 << 20)
+#define AT91_DBG_C1R_ARCH_AT91x34 (0x24 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7Axx  (0x60 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7Sxx  (0x70 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7XC   (0x71 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7SExx (0x72 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7Lxx  (0x73 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM7Xxx  (0x75 << 20)
+#define AT91_DBG_C1R_ARCH_AT91SAM9xx   (0x19 << 20)
+#define AT91_DBG_C1R_ARCH_MASK         (0xff << 20)
+#define AT91_DBG_C1R_NVPTYP_ROM      (0 << 28) // ROM only
+#define AT91_DBG_C1R_NVPTYP_RLOCF    (1 << 28) // ROMless of on chip Flash
+#define AT91_DBG_C1R_NVPTYP_SRAMROM  (4 << 28) // SRAM emulating ROM
+#define AT91_DBG_C1R_NVPTYP_EFLASH   (2 << 28) // Embedded Flash
+#define AT91_DBG_C1R_NVPTYP_ROMFLASH (3 << 28) // ROM & FLASH
+#define AT91_DBG_C1R_NVPTYP_MASK     (7 << 28)
+#define AT91_DBG_C1R_EXT (1 << 31) // Extension Register Exists
+#define AT91_DBG_C2R  0x44 // Chip ID2 register
+#define AT91_DBG_FNTR 0x48 // Force NTRST Register
+#define AT91_DBG_RPR  0x100 // Receiver Pointer Register
+#define AT91_DBG_RCR  0x104 // Receiver Counter Register
+#define AT91_DBG_TPR  0x108 // Transmit Pointer Register
+#define AT91_DBG_TCR  0x10c // Transmit Counter Register
+#define AT91_DBG_RNPR 0x110 // Receiver Next Pointer Register
+#define AT91_DBG_RNCR 0x114 // Receiver Next Counter Register
+#define AT91_DBG_TNPR 0x118 // Transmit Next Pointer Register
+#define AT91_DBG_TNCR 0x11c // Transmit Next Counter Register
+#define AT91_DBG_PTCR 0x120 // PDC Transfer Control Register
+#define AT91_DBG_PTSR 0x124 // PDC Transfer Status Register
+#endif
+
+//=============================================================================
+// Periodic Interval Timer Controller
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_PITC
+#define AT91_PITC 0xfffffd30
+#endif
+
+#define AT91_PITC_PIMR 0x00  // Period Interval Mode Register
+#define AT91_PITC_PIMR_PITEN  (1 << 24) // Periodic Interval Timer Enable
+#define AT91_PITC_PIMR_PITIEN (1 << 25) // Periodic Interval Timer Interrupt Enable
+#define AT91_PITC_PISR 0x04  // Period Interval Status Register
+#define AT91_PITC_PISR_PITS   (1 << 0)  // Periodic Interval Timer Status
+#define AT91_PITC_PIVR 0x08  // Period Interval Status Register
+#define AT91_PITC_PIIR 0x0C  // Period Interval Image Register
+#endif
+
+//=============================================================================
+// Real Time Timer Controller
+
+#if defined(CYGHWR_HAL_ARM_AT91SAM7S)
+
+#ifndef AT91_RTTC
+#define AT91_RTTC 0xFFFFFD20
+#endif
+
+#define AT91_RTTC_RTMR 0x00 // Real Time Mode Register
+#define AT91_RTTC_RTMR_ALMIEN    (1 << 16) // Alarm Interrupt Enable
+#define AT91_RTTC_RTMR_RTTINCIEN (1 << 17) // Timer Increment Interrupt Enable
+#define AT91_RTTC_RTMR_RTTRST    (1 << 18) // Timer Reset
+#define AT91_RTTC_RTAR 0x04 // Real Time Alarm Register
+#define AT91_RTTC_RTVR 0x08 // Real Time Value Register
+#define AT91_RTTC_RTSR 0x0C // Real Time Status Register
+#define AT91_RTTC_RTSR_ALMS      (1 << 0) // Alarm Status
+#define AT91_RTTC_RTSR_RTTINC    (1 << 1) // Timer Increment
+#endif
+
 //=============================================================================
 // FIQ interrupt vector which is shared by all HAL varients.
 
--- a/packages/hal/arm/at91/var/current/src/at91_misc.c
+++ b/packages/hal/arm/at91/var/current/src/at91_misc.c
@@ -70,97 +70,6 @@
 #include <cyg/hal/var_io.h>             // platform registers
 
 // -------------------------------------------------------------------------
-// Clock support
-
-static cyg_uint32 _period;
-
-void hal_clock_initialize(cyg_uint32 period)
-{
-    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
-
-    CYG_ASSERT(period < 0x10000, "Invalid clock period");
-
-    // Disable counter
-    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
-
-    // Set registers
-    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG |        // Reset counter on CPC
-                                        AT91_TC_CMR_CLKS_MCK32);    // 1 MHz
-    HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
-
-    // Start timer
-    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
-
-    // Enable timer 0 interrupt    
-    HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
-}
-
-void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
-{
-    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
-    cyg_uint32 sr;
-
-    CYG_ASSERT(period < 0x10000, "Invalid clock period");
-
-    HAL_READ_UINT32(timer+AT91_TC_SR, sr);  // Clear interrupt
-
-    if (period != _period) {
-        hal_clock_initialize(period);
-    }
-    _period = period;
-
-}
-
-void hal_clock_read(cyg_uint32 *pvalue)
-{
-    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
-    cyg_uint32 val;
-
-    HAL_READ_UINT32(timer+AT91_TC_CV, val);
-    *pvalue = val;
-}
-
-// -------------------------------------------------------------------------
-//
-// Delay for some number of micro-seconds
-//   Use timer #2 in MCLOCK/32 mode.
-//
-void hal_delay_us(cyg_int32 usecs)
-{
-    cyg_uint32 stat;
-    cyg_uint64 ticks;
-#if defined(CYGHWR_HAL_ARM_AT91_JTST)
-    // TC2 is reserved for AD/DA. Use TC1 instead. 
-    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1;
-#else
-    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
-#endif
-    // Calculate how many timer ticks the required number of
-    // microseconds equate to. We do this calculation in 64 bit
-    // arithmetic to avoid overflow.
-    ticks = (((cyg_uint64)usecs) * ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL;
-    
-    // Disable counter
-    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
-
-    // Set registers
-    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32);  // 1MHz
-    HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
-    HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks);
-
-	// Clear status flags
-    HAL_READ_UINT32(timer+AT91_TC_SR, stat);
-
-    // Start timer
-    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
-
-    // Wait for the compare
-    do {
-        HAL_READ_UINT32(timer+AT91_TC_SR, stat);
-    } while ((stat & AT91_TC_SR_CPC) == 0);
-}
-
-// -------------------------------------------------------------------------
 // Hardware init
 
 void hal_hardware_init(void)
@@ -173,11 +82,106 @@ void hal_hardware_init(void)
     // Flush internal priority level stack
     for (i = 0; i < 8; ++i)
         HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_EOI, 0xFFFFFFFF);
-    
+
+#ifdef HAL_PLF_HARDWARE_INIT
+    // Perform any platform specific initializations
+    HAL_PLF_HARDWARE_INIT();
+#endif
+
     // Set up eCos/ROM interfaces
     hal_if_init();
+}
 
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+// Decode a system interrupt. Not all systems have all interrupts. So
+// code will only be generated for those interrupts which have a
+// defined value.
+static int sys_irq_handler(void)
+{
+  cyg_uint32 sr, mr;
+
+#ifdef CYGNUM_HAL_INTERRUPT_PITC
+  // Periodic Interrupt Timer Controller
+  HAL_READ_UINT32((AT91_PITC+AT91_PITC_PISR), sr);
+  if (sr & AT91_PITC_PISR_PITS) {
+    return CYGNUM_HAL_INTERRUPT_PITC;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_DBG
+  // Debug Unit
+  HAL_READ_UINT32((AT91_DBG + AT91_DBG_CSR), sr);
+  HAL_READ_UINT32((AT91_DBG + AT91_DBG_IMR), mr);
+  if (sr & mr) {
+    return CYGNUM_HAL_INTERRUPT_DBG;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_RTTC
+  /* Real Time Timer. Check the interrupt is enabled, not that just
+     the status indicates there is an interrupt. It takes a while for
+     the status bit to clear. */
+  HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTSR), sr);
+  HAL_READ_UINT32((AT91_RTTC+AT91_RTTC_RTMR), mr);
+  if (((mr & AT91_RTTC_RTMR_ALMIEN) &&
+       (sr & AT91_RTTC_RTSR_ALMS)) ||
+      ((mr & AT91_RTTC_RTMR_RTTINCIEN) &&
+       (sr & AT91_RTTC_RTSR_RTTINC))) {
+    return CYGNUM_HAL_INTERRUPT_RTTC;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_PMC
+  // Power Management Controller
+  HAL_READ_UINT32((AT91_PMC+AT91_PMC_IMR), mr);
+  HAL_READ_UINT32((AT91_PMC+AT91_PMC_SR), sr);
+  if ((sr & mr) & 
+      (AT91_PMC_SR_MOSCS   |
+       AT91_PMC_SR_LOCK    |
+       AT91_PMC_SR_MCKRDY  |
+       AT91_PMC_SR_PCK0RDY |
+       AT91_PMC_SR_PCK1RDY |
+       AT91_PMC_SR_PCK2RDY |
+       AT91_PMC_SR_PCK3RDY)) {
+    return CYGNUM_HAL_INTERRUPT_PMC;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_MC
+  // Memory controller
+  HAL_READ_UINT32((AT91_MC+AT91_MC_FMR), mr);
+  HAL_READ_UINT32((AT91_MC+AT91_MC_FSR), sr);
+  if ((sr & mr) & 
+      (AT91_MC_FSR_FRDY  |
+       AT91_MC_FSR_LOCKE |
+       AT91_MC_FSR_PROGE)) {
+    return CYGNUM_HAL_INTERRUPT_MC;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_WDTC
+  // Watchdog Timer Controller
+  HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDSR), sr);
+  HAL_READ_UINT32((AT91_WDTC+AT91_WDTC_WDMR), mr);
+  if ((mr & AT91_WDTC_WDMR_FIEN) &&
+      sr & (AT91_WDTC_WDSR_UNDER |
+            AT91_WDTC_WDSR_ERROR)) {
+    return CYGNUM_HAL_INTERRUPT_WDTC;
+  }
+#endif
+
+#ifdef CYGNUM_HAL_INTERRUPT_RSTC
+  // Reset Controller
+  HAL_READ_UINT32((AT91_RST + AT91_RST_RSR), sr);
+  HAL_READ_UINT32((AT91_RST + AT91_RST_RMR), mr);
+  if (((mr & AT91_RST_RMR_URSTIEN) && (sr & AT91_RST_RSR_USER)) ||  
+      ((mr & AT91_RST_RMR_BODIEN) && (sr & AT91_RST_RSR_BROWN)))
+    return CYGNUM_HAL_INTERRUPT_RSTC;
+#endif
+  
+  return CYGNUM_HAL_INTERRUPT_NONE;
 }
+#endif
 
 // -------------------------------------------------------------------------
 // This routine is called to respond to a hardware interrupt (IRQ).  It
@@ -204,7 +208,13 @@ int hal_IRQ_handler(void)
 
     HAL_READ_UINT32(AT91_AIC+AT91_AIC_ISR, irq_num);
 
-    // An invalid interrrupt source is treated as a spurious interrupt    
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+    if (irq_num == CYGNUM_HAL_INTERRUPT_SYS) {
+      // determine the source of the system interrupt
+      irq_num = sys_irq_handler();
+    }
+#endif
+    // An invalid interrupt source is treated as a spurious interrupt    
     if (irq_num < CYGNUM_HAL_ISR_MIN || irq_num > CYGNUM_HAL_ISR_MAX)
       irq_num = CYGNUM_HAL_INTERRUPT_NONE;
     
@@ -220,6 +230,13 @@ void hal_interrupt_mask(int vector)
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
 
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+    if (vector >= 32) {
+      HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, 
+                       (1 << CYGINT_HAL_ARM_AT91_SYS_INTERRUPT));
+      return;
+    }
+#endif
     HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IDCR, (1<<vector));
 }
 
@@ -228,6 +245,14 @@ void hal_interrupt_unmask(int vector)
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
 
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+    if (vector >= 32) {
+      hal_interrupt_configure(CYGINT_HAL_ARM_AT91_SYS_INTERRUPT, true, true);
+      HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, 
+                       (1 <<CYGINT_HAL_ARM_AT91_SYS_INTERRUPT));
+      return;
+    }
+#endif
     HAL_WRITE_UINT32(AT91_AIC+AT91_AIC_IECR, (1<<vector));
 }
 
@@ -245,6 +270,10 @@ void hal_interrupt_configure(int vector,
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
 
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+    if (vector >= 32) 
+      return;
+#endif
     if (level) {
         if (up) {
             mode = AT91_AIC_SMR_LEVEL_HI;
@@ -270,6 +299,11 @@ void hal_interrupt_set_level(int vector,
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
     CYG_ASSERT(level >= 0 && level <= 7, "Invalid level");
 
+#if CYGINT_HAL_ARM_AT91_SYS_INTERRUPT
+    if (vector >= 32) 
+      return;
+#endif
+
     HAL_READ_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
     mode = (mode & ~AT91_AIC_SMR_PRIORITY) | level;
     HAL_WRITE_UINT32(AT91_AIC+(AT91_AIC_SMR0+(vector*4)), mode);
@@ -281,15 +315,30 @@ void hal_show_IRQ(int vector, int data, 
 }
 
 
+#ifndef AT91_RST
 /* Use the watchdog to generate a reset */
 void hal_at91_reset_cpu(void)
 {
     HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY);
     HAL_WRITE_UINT32(AT91_WD + AT91_WD_CMR, AT91_WD_CMR_CKEY);
     HAL_WRITE_UINT32(AT91_WD + AT91_WD_CR, AT91_WD_CR_RSTKEY);
-    HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, AT91_WD_OMR_OKEY | AT91_WD_OMR_RSTEN | AT91_WD_OMR_WDEN);
+    HAL_WRITE_UINT32(AT91_WD + AT91_WD_OMR, 
+                     (AT91_WD_OMR_OKEY | 
+                      AT91_WD_OMR_RSTEN |
+                      AT91_WD_OMR_WDEN));
     while(1) CYG_EMPTY_STATEMENT;
 }
-
+#else
+/* Use the Reset Controller to generate a reset */
+void hal_at91_reset_cpu(void)
+{
+  HAL_WRITE_UINT32(AT91_RST + AT91_RST_RCR,
+                   AT91_RST_RCR_PROCRST |                   
+                   AT91_RST_RCR_ICERST  |
+                   AT91_RST_RCR_PERRST  |
+                   AT91_RST_RCR_KEY);
+  while(1) CYG_EMPTY_STATEMENT;
+}
+#endif
 //--------------------------------------------------------------------------
 // EOF at91_misc.c
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/at91/var/current/src/hal_diag_dbg.c
@@ -0,0 +1,343 @@
+/*=============================================================================
+//
+//      hal_diag_dbg.c
+//
+//      HAL diagnostic output code using the debug serial port
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2006 eCosCentric Ltd.
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   jskov
+// Contributors:jskov, gthomas
+// Date:        2001-07-12
+// Purpose:     HAL diagnostic output
+// Description: Implementations of HAL diagnostic output support.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================*/
+
+
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm_at91.h>
+
+#include CYGBLD_HAL_PLATFORM_H
+
+#include <cyg/infra/cyg_type.h>         // base types
+
+#include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_if.h>             // interface API
+#include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
+#include <cyg/hal/hal_misc.h>           // Helper functions
+#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
+#include <cyg/hal/hal_diag.h>
+
+#include <cyg/hal/var_io.h>             // Device registers
+
+//-----------------------------------------------------------------------------
+typedef struct {
+    cyg_uint8* base;
+    cyg_int32 msec_timeout;
+    int isr_vector;
+    cyg_uint32 baud_rate;
+} channel_data_t;
+
+//-----------------------------------------------------------------------------
+
+static void
+cyg_hal_plf_serial_dbg_init_channel(void* __ch_data)
+{
+    cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
+
+    cyg_uint32 baud_value = 0;
+    cyg_uint32 baud_rate  = ((channel_data_t*)__ch_data)->baud_rate;
+    
+    /* Enable pins to be driven by peripheral, using peripheral A. */
+    HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_ASR),
+                     (AT91_PIO_PSR_DRXD | 
+                      AT91_PIO_PSR_DTXD));
+
+    /* Disables the PIO from controlling the corresponding pin
+      (enables peripheral control of the pin). */
+    HAL_WRITE_UINT32((AT91_PIO+AT91_PIO_PDR),
+                     (AT91_PIO_PSR_DRXD | 
+                      AT91_PIO_PSR_DTXD));
+
+    /* Disable interrupt */
+    HAL_WRITE_UINT32((base+AT91_DBG_IDR), 0xFFFFFFFF);
+
+    /* Reset receiver and transmitter */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR),
+                     (AT91_DBG_CR_RSTRX | AT91_DBG_CR_RSTTX | 
+                      AT91_DBG_CR_RXDIS | AT91_DBG_CR_TXDIS));
+
+    baud_value = AT91_US_BAUD(baud_rate);
+
+    HAL_WRITE_UINT32((base+AT91_DBG_BRGR), baud_value);
+
+    /* Define the USART mode */
+    /* (USART) Normal, 1 stop bit, No Parity, Character Length: 8 bits, Clock */
+    HAL_WRITE_UINT32(base+AT91_DBG_MR, 
+                     (AT91_DBG_MR_CHMODE_NORMAL |
+                      AT91_DBG_MR_PAR_NONE));
+    
+    /* Enable Transmitter */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_TXEN);
+
+    /* Enable Receiver */
+    HAL_WRITE_UINT32((base+AT91_DBG_CR), AT91_DBG_CR_RXEN);
+}
+
+void
+cyg_hal_plf_serial_dbg_putc(void* __ch_data, char c)
+{
+    cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint32 status;
+    CYGARC_HAL_SAVE_GP();
+
+    // Wait for Tx FIFO not full
+    do
+    {
+        HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+    }
+    while (!(status & AT91_DBG_CSR_TXRDY)) ;
+
+    //UART TX data register
+    HAL_WRITE_UINT8((base+AT91_DBG_THR), c);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static cyg_bool
+cyg_hal_plf_serial_dbg_getc_nonblock(void* __ch_data, cyg_uint8* ch)
+{
+    cyg_uint8 * base = ((channel_data_t*)__ch_data)->base;
+    cyg_uint32 status;
+
+    HAL_READ_UINT32((base+AT91_DBG_CSR), status);
+    if (status & AT91_DBG_CSR_RXRDY)
+      {
+        HAL_READ_UINT8((base+AT91_DBG_RHR), *ch);
+        return true;
+    }
+    return false;
+}
+
+cyg_uint8
+cyg_hal_plf_serial_dbg_getc(void* __ch_data)
+{
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    while (!cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, &ch));
+
+    CYGARC_HAL_RESTORE_GP();
+    return ch;
+}
+
+static void
+cyg_hal_plf_serial_dbg_write(void* __ch_data, const cyg_uint8* __buf,
+                             cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while (__len-- > 0)
+        cyg_hal_plf_serial_dbg_putc(__ch_data, *__buf++);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+static void
+cyg_hal_plf_serial_dbg_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
+{
+    CYGARC_HAL_SAVE_GP();
+
+    while (__len-- > 0)
+        *__buf++ = cyg_hal_plf_serial_dbg_getc(__ch_data);
+
+    CYGARC_HAL_RESTORE_GP();
+}
+
+cyg_bool
+cyg_hal_plf_serial_dbg_getc_timeout(void* __ch_data, cyg_uint8* ch)
+{
+    int delay_count;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_bool res;
+    CYGARC_HAL_SAVE_GP();
+
+    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
+
+    for (;;) {
+        res = cyg_hal_plf_serial_dbg_getc_nonblock(__ch_data, ch);
+        if (res || 0 == delay_count--)
+            break;
+
+        CYGACC_CALL_IF_DELAY_US(100);
+    }
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static int
+cyg_hal_plf_serial_dbg_control(void *__ch_data, __comm_control_cmd_t __func, ...)
+{
+    static int irq_state = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    int ret = 0;
+    va_list ap;
+
+    CYGARC_HAL_SAVE_GP();
+    va_start(ap, __func);
+
+    switch (__func) {
+      case __COMMCTL_GETBAUD:
+        ret = chan->baud_rate;
+        break;
+      case __COMMCTL_SETBAUD:
+        chan->baud_rate = va_arg(ap, cyg_int32);
+        // Should we verify this value here?
+        cyg_hal_plf_serial_dbg_init_channel(chan);
+        ret = 0;
+        break;
+      case __COMMCTL_IRQ_ENABLE:
+        irq_state = 1;
+        HAL_INTERRUPT_UNMASK(chan->isr_vector);
+        HAL_WRITE_UINT32((chan->base+AT91_DBG_IER), AT91_DBG_CSR_RXRDY);
+        break;
+      case __COMMCTL_IRQ_DISABLE:
+        ret = irq_state;
+        irq_state = 0;
+        HAL_WRITE_UINT32((chan->base+AT91_DBG_IDR), AT91_DBG_CSR_RXRDY);
+        HAL_INTERRUPT_MASK(chan->isr_vector);
+        break;
+      case __COMMCTL_DBG_ISR_VECTOR:
+        ret = chan->isr_vector;
+        break;
+      case __COMMCTL_SET_TIMEOUT:
+        ret = chan->msec_timeout;
+        chan->msec_timeout = va_arg(ap, cyg_uint32);
+      default:
+        break;
+    }
+    CYGARC_HAL_RESTORE_GP();
+    return ret;
+}
+
+static int
+cyg_hal_plf_serial_dbg_isr(void *__ch_data, int* __ctrlc,
+                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
+{
+    int res = 0;
+    channel_data_t* chan = (channel_data_t*)__ch_data;
+    cyg_uint32 status;
+    cyg_uint32 c;
+    cyg_uint8 ch;
+    CYGARC_HAL_SAVE_GP();
+
+    *__ctrlc = 0;
+    HAL_READ_UINT32(chan->base+AT91_DBG_CSR, status);
+    if ( (status & AT91_DBG_CSR_RXRDY) != 0 ) {
+
+      HAL_READ_UINT32(chan->base+AT91_DBG_RHR, c);
+      ch = (cyg_uint8)(c & 0xff);
+      if( cyg_hal_is_break( &ch , 1 ) )
+        *__ctrlc = 1;
+      
+      res = CYG_ISR_HANDLED;
+    }
+
+    HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
+
+    CYGARC_HAL_RESTORE_GP();
+    return res;
+}
+
+static channel_data_t at91_ser_channels[1] = {
+    { (cyg_uint8*)AT91_DBG, 1000, CYGNUM_HAL_INTERRUPT_DBG, 
+      CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD}
+};
+
+static void
+cyg_hal_plf_serial_init(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur;
+
+    cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    // Init channels
+    cyg_hal_plf_serial_dbg_init_channel(&at91_ser_channels[0]);
+
+    // Setup procs in the vector table
+
+    // Set channel 0
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_CH_DATA_SET(*comm, &at91_ser_channels[0]);
+    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_dbg_write);
+    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_dbg_read);
+    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_dbg_putc);
+    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_dbg_getc);
+    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_dbg_control);
+    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_dbg_isr);
+    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_dbg_getc_timeout);
+
+    // Restore original console
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}
+
+void
+cyg_hal_plf_comms_init(void)
+{
+    static int initialized = 0;
+
+    if (initialized)
+        return;
+
+    initialized = 1;
+
+    cyg_hal_plf_serial_init();
+}
+
+void
+hal_diag_led(int mask)
+{
+    hal_at91_set_leds(mask);
+}
+
+//-----------------------------------------------------------------------------
+// End of hal_diag_dbg.c
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/at91/var/current/src/timer_pit.c
@@ -0,0 +1,138 @@
+/*==========================================================================
+//
+//      timer_pit.c
+//
+//      HAL timer code using the Periodic Interval Timer
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Ltd
+//
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    asl, Oliver Munz
+// Contributors: asl, Oliver Munz
+// Date:         2006-02-12
+// Purpose:      Clock support using the PIT
+// Description:  
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_platform_ints.h>
+// -------------------------------------------------------------------------
+// Use system clock
+void
+hal_clock_initialize(cyg_uint32 period)
+{
+  cyg_uint32 sr;
+  
+  CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC,
+             "Invalid timer interrupt");
+  
+  /* Set Period Interval timer and enable interrupt */
+  HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), 
+                   period |  
+                   AT91_PITC_PIMR_PITEN |
+                   AT91_PITC_PIMR_PITIEN);
+  
+  // Read the status register to clear any pending interrupt
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, sr);
+}
+
+// This routine is called during a clock interrupt.
+void
+hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+  cyg_uint32 reg;
+  
+  /* Read the value register so that we clear the interrupt */
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIVR, reg);
+}
+
+// Read the current value of the clock, returning the number of hardware
+// "ticks" that have occurred (i.e. how far away the current value is from
+// the start)
+void
+hal_clock_read(cyg_uint32 *pvalue)
+{
+  cyg_uint32 ir;
+  
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir);
+  *pvalue = ir & 0xfffff;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+// PIT is clocked at MCLK / 16
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+  cyg_int64 ticks;
+  cyg_uint32 val1, val2;
+  cyg_uint32 piv;
+  
+  // Calculate how many PIT ticks the required number of microseconds
+  // equate to. We do this calculation in 64 bit arithmetic to avoid
+  // overflow.
+  ticks = (((cyg_uint64)usecs) * 
+           ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL;
+  
+  // I've no idea why, but waiting for the number of ticks calculated
+  // above does not work by about a factor or 3. If anybody works out
+  // why, please let me know!
+  ticks = ticks / 3;
+  
+  HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv);
+  
+  while (ticks > 0) {
+    hal_clock_read(&val1);
+    do {
+      hal_clock_read(&val2);
+    } while (val1 == val2);
+    // Sometimes we miss a tick, maybe because of interrupt handling?
+    // So calculate the number of ticks, without making a big error
+    // with wrap around.
+    if (val2 > val1)
+      ticks -= (val2 - val1);
+    else 
+      ticks--;
+  }
+}
+
+// timer_pit.c
new file mode 100644
--- /dev/null
+++ b/packages/hal/arm/at91/var/current/src/timer_tc.c
@@ -0,0 +1,154 @@
+/*==========================================================================
+//
+//      timer_tc.c
+//
+//      HAL timer code using the Timer Counter
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// 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
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas
+// Contributors: gthomas, jskov, nickg, tkoeller
+// Date:         2001-07-12
+// Purpose:      HAL board support
+// Description:  Implementations of HAL board interfaces
+//
+//####DESCRIPTIONEND####
+//
+//========================================================================*/
+
+#include <pkgconf/hal.h>
+
+#include <cyg/infra/cyg_type.h>         // base types
+#include <cyg/infra/cyg_ass.h>          // assertion macros
+
+#include <cyg/hal/hal_io.h>             // IO macros
+#include <cyg/hal/hal_arch.h>           // Register state info
+#include <cyg/hal/hal_intr.h>           // necessary?
+
+// -------------------------------------------------------------------------
+// Clock support
+
+static cyg_uint32 _period;
+
+void hal_clock_initialize(cyg_uint32 period)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+
+    CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+    // Disable counter
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    // Set registers
+    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CPCTRG |        // Reset counter on CPC
+                                        AT91_TC_CMR_CLKS_MCK32);    // 1 MHz
+    HAL_WRITE_UINT32(timer+AT91_TC_RC, period);
+
+    // Start timer
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+
+    // Enable timer 0 interrupt    
+    HAL_WRITE_UINT32(timer+AT91_TC_IER, AT91_TC_IER_CPC);
+}
+
+void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+    cyg_uint32 sr;
+
+    CYG_ASSERT(period < 0x10000, "Invalid clock period");
+
+    HAL_READ_UINT32(timer+AT91_TC_SR, sr);  // Clear interrupt
+
+    if (period != _period) {
+        hal_clock_initialize(period);
+    }
+    _period = period;
+
+}
+
+void hal_clock_read(cyg_uint32 *pvalue)
+{
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC0;
+    cyg_uint32 val;
+
+    HAL_READ_UINT32(timer+AT91_TC_CV, val);
+    *pvalue = val;
+}
+
+// -------------------------------------------------------------------------
+//
+// Delay for some number of micro-seconds
+//   Use timer #2 in MCLOCK/32 mode.
+//
+void hal_delay_us(cyg_int32 usecs)
+{
+    cyg_uint32 stat;
+    cyg_uint64 ticks;
+#if defined(CYGHWR_HAL_ARM_AT91_JTST)
+    // TC2 is reserved for AD/DA. Use TC1 instead. 
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC1;
+#else
+    CYG_ADDRESS timer = AT91_TC+AT91_TC_TC2;
+#endif
+    // Calculate how many timer ticks the required number of
+    // microseconds equate to. We do this calculation in 64 bit
+    // arithmetic to avoid overflow.
+    ticks = (((cyg_uint64)usecs) * 
+             ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/32000000LL;
+    
+    CYG_ASSERT(ticks < (1 << 16), "Timer overflow");
+    
+    // Disable counter
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_CLKDIS);
+
+    // Set registers
+    HAL_WRITE_UINT32(timer+AT91_TC_CMR, AT91_TC_CMR_CLKS_MCK32);  // 1MHz
+    HAL_WRITE_UINT32(timer+AT91_TC_RA, 0);
+    HAL_WRITE_UINT32(timer+AT91_TC_RC, ticks);
+
+    // Clear status flags
+    HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+    
+    // Start timer
+    HAL_WRITE_UINT32(timer+AT91_TC_CCR, AT91_TC_CCR_TRIG | AT91_TC_CCR_CLKEN);
+    
+    // Wait for the compare
+    do {
+      HAL_READ_UINT32(timer+AT91_TC_SR, stat);
+    } while ((stat & AT91_TC_SR_CPC) == 0);
+}
+
+// timer_tc.c