diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/ChangeLog ecos_dev/packages/hal/arm/lpc2xxx/var/current/ChangeLog
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/ChangeLog	2004-11-14 14:12:43.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/ChangeLog	2006-02-14 21:51:03.562500000 +0000
@@ -1,5 +1,24 @@
+2006-02-14  Andy Jackson <andy@grapevinetech.co.uk>
+
+	* cdl/hal_arm_lpc2xxx.cdl: Added CYGHWR_HAL_ARM_LPC2XXX_FAMILY,
+	CYGNUM_HAL_ARM_LPC2XXX_VPBDIV, CYGNUM_HAL_ARM_LPC2XXX_XCLKDIV
+	and CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE. Changed 
+	CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA to a bool.
+
+	* include/hal_var_ints.h: Removed lpc2xxx misc functions and
+	added an include for lpc2xxx_misc.h to avoid breaking things.
+
+	* include/lpc2xxx_misc.h: New header file for all the lpc2xxx
+	miscellaneous functions.
+
+	* include/var_arch.h: Made idle powerdown CDL controlled.
+
+	* include/var_io.h: Changed to use family CDL variables.
+
+	* src/lpc2xxx_misc.c: Changes to interrupt and VPBDIV code.
+
 2004-09-12  Jani Monoses <jani@iv.ro>
 
 	* src/hal_diag.c: 
 	* src/lpc2xxx_misc.c: 
 	* include/plf_stub.h: 
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl ecos_dev/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl	2004-11-14 14:12:44.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/cdl/hal_arm_lpc2xxx.cdl	2006-02-14 20:48:56.093750000 +0000
@@ -71,26 +71,76 @@
         puts $::cdl_header "#define CYGBLD_HAL_VAR_INTS_H <cyg/hal/hal_var_ints.h>"
         puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_IO_H"
         puts $::cdl_system_header "#define CYGBLD_HAL_ARM_VAR_ARCH_H"
     }
 
-    cdl_option CYGHWR_HAL_ARM_LPC2XXX {
+	# This is going to get really messy before long as the number of parts
+	# explodes. Its useful to know the actual part in use, but its just as
+	# useful to know which family it belongs to. LPC210x shouldn't really
+	# be in the list of devices, but will probably break something if removed.
+    cdl_component CYGHWR_HAL_ARM_LPC2XXX {
         display        "LPC2XXX variant used"
         flavor         data
-        default_value  {"LPC210x"}
-        legal_values   {"LPC210x" 
-			"LPC2114" "LPC2119" "LPC2124" "LPC2129" "LPC2132" 
-                        "LPC2138" "LPC2194" "LPC2212" "LPC2214" "LPC2290" 
-                        "LPC2292" "LPC2294"}
+        default_value  { "LPC210x" }
+        legal_values   { "LPC210x"
+				"LPC2101" "LPC2102" "LPC2103" "LPC2104" "LPC2105" "LPC2106"
+				"LPC2114" "LPC2119" "LPC2124" "LPC2129" "LPC2131" "LPC2132" 
+				"LPC2134" "LPC2136" "LPC2138" "LPC2141" "LPC2142" "LPC2144"
+				"LPC2146" "LPC2148" "LPC2194" "LPC2210" "LPC2212" "LPC2214"
+				"LPC2220" "LPC2290" "LPC2292" "LPC2294" }
 
         description    "The LPC2XXX microcontroller family has several
                         variants, the main differences being the amount of 
                         on-chip RAM, flash and peripherals. This option allows 
                         the platform HALs to select the specific 
                         microcontroller being used."
+
+        cdl_option CYGHWR_HAL_ARM_LPC2XXX_FAMILY {
+            display		"LPC2XXX variant family"
+            flavor		data
+            calculated	{
+						is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC22") ? "LPC22XX" :
+						is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC213") ? "LPC213X" :
+						is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC214") ? "LPC214X" :
+						is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC210") ? "LPC210X" :
+								"LPC21XX"
+						}
+			description	"This specifies the family that the processor
+						belongs to. This is useful as it defines certain common
+						characteristics (e.g lpc22xx has the external bus and
+						lpc214x has USB) which affect which features should be
+						available in the HAL."
+		}
     }
 
+	cdl_option CYGNUM_HAL_ARM_LPC2XXX_VPBDIV {
+		display       "VPB clock divisor"
+		flavor        data
+        legal_values   { 4 2 1 }
+		default_value { 4 }
+		description   "
+				This option sets the divisor for the VPB clock relative to
+				the processor clock. 4 means that the VPB clock runs at one 
+				fourth the processor clock, 2 means that it runs at one half
+				of the processor clock and 1 means that it is the same as
+				the processor clock."
+	}
+
+	cdl_option CYGNUM_HAL_ARM_LPC2XXX_XCLKDIV {
+		display			"XCLK clock divisor"
+		flavor			data
+        legal_values	{ 4 2 1 }
+		default_value	{ 4 }
+        active_if		{ CYGHWR_HAL_ARM_LPC2XXX_FAMILY == "LPC22XX" }
+		description   "
+				This option sets the divisor for the XCLK clock relative to
+				the processor clock. 4 means that the XCLK clock runs at one 
+				fourth the processor clock, 2 means that it runs at one half
+				of the processor clock and 1 means that it is the same as
+				the processor clock."
+	}
+
     cdl_component CYGNUM_HAL_RTC_CONSTANTS {
         display       "Real-time clock constants"
         flavor        none
 
         cdl_option CYGNUM_HAL_RTC_NUMERATOR {
@@ -109,15 +159,31 @@
             default_value { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED) / 
                               CYGNUM_HAL_RTC_DENOMINATOR) }
         }
     }
    
-    cdl_option CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA {
-        display       "EXTINT.1 errata workaround"
-	flavor        data	       
-	default_value 0	       
+	# Enable this by default, as I believe it won't affect parts that
+	# don't have the problem (other than slowing them down slightly)
+	# but causes a lock-up on those that do...
+	cdl_option CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA {
+		display       "EXTINT.1 errata workaround"
+		flavor        bool       
+		default_value 1	       
         description    "On some chips writing to the EXTPOLAR or EXTMODE 
                         registers while VPBDIV is non-zero can corrupt the 
                         latter. Also reading them will yield incorrect values.
-		        Enable this option to work around the problem."
+						Enable this option to work around the problem."
     }
+
+	cdl_option CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE {
+		display       "Stop clock in idle loop to save power"
+		flavor        bool
+		default_value { is_active(CYGPKG_REDBOOT) ? 0 : 1 }
+		description   "
+				Select this option when it is desired to save power
+				by stoping the processor clock in the idle loop. This
+				is controlled by the PCON register. Generally this is
+				a good thing, but it may be necessary to disable this
+				when debugging via JTAG, as stopping the clock can
+				prevent the debugger getting control of the system."
+	}
 }
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/hal_var_ints.h ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/hal_var_ints.h
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/hal_var_ints.h	2004-11-14 14:12:44.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/hal_var_ints.h	2006-02-06 09:42:47.515625000 +0000
@@ -93,18 +93,13 @@
 #define CYGNUM_HAL_ISR_MIN           0
 #define CYGNUM_HAL_ISR_MAX           (31)
 
 #define CYGNUM_HAL_ISR_COUNT         (CYGNUM_HAL_ISR_MAX+1)
 
-__externC cyg_uint32 hal_lpc_get_pclk(void);
-#define CYG_HAL_ARM_LPC2XXX_PCLK() hal_lpc_get_pclk() 
-#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
-            (CYG_HAL_ARM_LPC2XXX_PCLK()/((baud)*16))
-
 //The vector used by the Real time clock
 #define CYGNUM_HAL_INTERRUPT_RTC     CYGNUM_HAL_INTERRUPT_TIMER0
 
-__externC void hal_lpc_watchdog_reset(void);
-#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
-#define HAL_PLATFORM_RESET_ENTRY 0
+// Other entries here moved to variant specific include file
+// This is included here to avoid breaking anything
+#include <cyg/hal/lpc2xxx_misc.h>
 
 #endif // CYGONCE_HAL_VAR_INTS_H
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/lpc2xxx_misc.h ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/lpc2xxx_misc.h
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/lpc2xxx_misc.h	1970-01-01 00:00:00.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/lpc2xxx_misc.h	2006-02-14 21:14:52.281250000 +0000
@@ -0,0 +1,77 @@
+#ifndef CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+#define CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
+//=============================================================================
+//
+//      lpc2xxx_misc.h
+//
+//      HAL misc variant support code for Philips LPC2xxx header file
+//
+//=============================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2006 eCosCentric Limited 
+//
+// 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):    andyj 
+// Contributors: jani
+// Date:         2006-02-04
+// Purpose:      LPC2XXX specific miscellaneous support header file
+// Description: 
+// Usage:        #include <cyg/hal/lpc2xxx_misc.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//-----------------------------------------------------------------------------
+// Functions to obtain the current processor clock settings
+//-----------------------------------------------------------------------------
+externC cyg_uint32 hal_lpc_get_cclk(void);
+externC cyg_uint32 hal_lpc_get_pclk(void);
+externC cyg_uint32 hal_lpc_get_xclk(void);
+
+//-----------------------------------------------------------------------------
+// Macros to derive the baudrate divider values for the internal UARTs
+//-----------------------------------------------------------------------------
+#define CYG_HAL_ARM_LPC2XXX_PCLK() hal_lpc_get_pclk() 
+#define CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(baud) \
+            (CYG_HAL_ARM_LPC2XXX_PCLK()/((baud)*16))
+
+//-----------------------------------------------------------------------------
+// LPX2xxx watchdog support
+//-----------------------------------------------------------------------------
+externC void hal_lpc_watchdog_reset(void);
+
+#define HAL_PLATFORM_RESET() hal_lpc_watchdog_reset()
+#define HAL_PLATFORM_RESET_ENTRY 0
+
+//-----------------------------------------------------------------------------
+// end of lpc2xxx_misc.h
+#endif // CYGONCE_HAL_ARM_LPC2XXX_VAR_LPC2XXX_MISC_H
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/var_arch.h ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/var_arch.h
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/var_arch.h	2004-11-14 14:12:44.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/var_arch.h	2006-02-01 08:17:11.156250000 +0000
@@ -57,21 +57,23 @@
 // Idle thread code.
 // This macro is called in the idle thread loop, and gives the HAL the
 // chance to insert code. Typical idle thread behaviour might be to halt the
 // processor. These implementations halt the system core clock.
 
-#ifndef HAL_IDLE_THREAD_ACTION
+#ifdef CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE
 
+#ifndef HAL_IDLE_THREAD_ACTION
 
 #define HAL_IDLE_THREAD_ACTION(_count_)                       \
 CYG_MACRO_START                                               \
 HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE +            \
                  CYGARC_HAL_LPC2XXX_REG_PCON,                 \
                  CYGARC_HAL_LPC2XXX_REG_PCON_IDL);            \
 CYG_MACRO_END
 
+#endif		// HAL_IDLE_THREAD_ACTION
 
-#endif
+#endif		// CYGHWR_HAL_ARM_LPC2XXX_IDLE_MODE
 
 //-----------------------------------------------------------------------------
 // end of var_arch.h
 #endif // CYGONCE_HAL_VAR_ARCH_H
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/var_io.h ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/var_io.h
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/include/var_io.h	2004-11-14 14:12:44.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/include/var_io.h	2006-01-31 12:05:17.671875000 +0000
@@ -372,12 +372,11 @@
 //=============================================================================
 // GPIO (IO)
 
 #define CYGARC_HAL_LPC2XXX_REG_IO_BASE                   0xE0028000
 
-
-#if defined(CYGHWR_HAL_ARM_LPC2XXX_LPC210x)
+#if defined(CYGHWR_HAL_ARM_LPC2XXX_FAMILY_LPC210X)
 
 // Registers are offsets from base of this subsystem
 #define CYGARC_HAL_LPC2XXX_REG_IOPIN                     0x000
 #define CYGARC_HAL_LPC2XXX_REG_IOSET                     0x004
 #define CYGARC_HAL_LPC2XXX_REG_IODIR                     0x008
@@ -492,12 +491,11 @@
 
 
 //=============================================================================
 // External Memory Controller
 
-#if defined(CYGHWR_HAL_ARM_LPC2XXX_LPC2212) || \
-    defined(CYGHWR_HAL_ARM_LPC2XXX_LPC2214)
+#if defined(CYGHWR_HAL_ARM_LPC2XXX_FAMILY_LPC22XX)
 
 #define CYGARC_HAL_LPC2XXX_REG_BCFG0                    0xFFE00000
 #define CYGARC_HAL_LPC2XXX_REG_BCFG1                    0xFFE00004
 #define CYGARC_HAL_LPC2XXX_REG_BCFG2                    0xFFE00008
 #define CYGARC_HAL_LPC2XXX_REG_BCFG3                    0xFFE0000C
diff -r -u5 -N -x CVS ecos_orig/packages/hal/arm/lpc2xxx/var/current/src/lpc2xxx_misc.c ecos_dev/packages/hal/arm/lpc2xxx/var/current/src/lpc2xxx_misc.c
--- ecos_orig/packages/hal/arm/lpc2xxx/var/current/src/lpc2xxx_misc.c	2004-11-14 14:12:44.000000000 +0000
+++ ecos_dev/packages/hal/arm/lpc2xxx/var/current/src/lpc2xxx_misc.c	2006-02-06 19:45:14.125000000 +0000
@@ -65,21 +65,37 @@
 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
 #include <cyg/hal/drv_api.h>            // HAL ISR support
 #endif
 #include <cyg/hal/var_io.h>             // platform registers
 
-static cyg_uint32 lpc_cclk;	//CPU clock frequency
-static cyg_uint32 lpc_pclk;	//peripheral devices clock speed
-                                //(equal to, half, or quarter of CPU
-                                //clock)
+#include <cyg/infra/diag.h>     // For diagnostic printing
+
+// -------------------------------------------------------------------------
+// Processor clock configuration values and accessor functions
+static cyg_uint32 lpc_cclk;	// CPU clock frequency
+static cyg_uint32 lpc_pclk;	// peripheral devices clock speed
+                            // (equal to, half, or quarter of CPU clock)
+static cyg_uint32 lpc_xclk;	// XCLK speed (equal to, half, or quarter of
+                            // CPU clock)
+
+cyg_uint32 hal_lpc_get_cclk(void)
+{
+    return (lpc_cclk); 
+}
 
 cyg_uint32 hal_lpc_get_pclk(void)
 {
-    return lpc_pclk; 
+    return (lpc_pclk); 
+}
+
+cyg_uint32 hal_lpc_get_xclk(void)
+{
+    return (lpc_xclk); 
 }
+
 // -------------------------------------------------------------------------
-// Clock support
+// eCos clock support
 // Use TIMER0
 static cyg_uint32 _period;
 
 void hal_clock_initialize(cyg_uint32 period)
 {
@@ -170,144 +186,233 @@
 
 // Return value of VPBDIV register. According to errata doc
 // we need to read twice consecutively to get correct value
 cyg_uint32 lpc_get_vpbdiv(void)
 {   
-    cyg_uint32 div;	
+    cyg_uint32 vpbdiv_reg;
+	
     HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                    CYGARC_HAL_LPC2XXX_REG_VPBDIV, div);
+                    CYGARC_HAL_LPC2XXX_REG_VPBDIV, vpbdiv_reg);
     HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                    CYGARC_HAL_LPC2XXX_REG_VPBDIV, div);
+                    CYGARC_HAL_LPC2XXX_REG_VPBDIV, vpbdiv_reg);
 
-    return div;
+    return (vpbdiv_reg);
 }
 
-//Set the two bits in VPBDIV which control peripheral clock division
-//div must be 1,2 or 4
-void lpc_set_vpbdiv(int div)
-{   
-    cyg_uint8 orig = lpc_get_vpbdiv();
-    
-    // update VPBDIV register
-    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_VPBDIV, (div % 4) | (orig & 0xFC));
+// Set the VPBDIV register. The vpb bits are 1:0 and the xclk bits are 5:4. The
+// mapping of values passed to this routine to field values is:
+//		4 = divide by 4 (register bits 00)
+//		2 = divide by 2 (register bits 10)
+//		1 = divide by 1 (register bits 01)
+// This routine assumes that only these values can occur. As they are
+// generated in the CDL hopefully this should be the case. Fortunately
+// writing 11 merely causes the previous value to be retained.
+void lpc_set_vpbdiv(int vpbdiv, int xclkdiv)
+{
+    CYG_ASSERT(((vpbdiv & 0x3) != 3) && ((xclkdiv & 0x3) != 3),
+									"illegal VPBDIV register value");
+
+	// Update VPBDIV register
+#ifdef CYGHWR_HAL_ARM_LPC2XXX_FAMILY_LPC22XX
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE +
+							CYGARC_HAL_LPC2XXX_REG_VPBDIV,
+							((xclkdiv & 0x3) << 4) | (vpbdiv & 0x3));
+#else
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+                     CYGARC_HAL_LPC2XXX_REG_VPBDIV, vpbdiv & 0x3);
+#endif
     
-    lpc_pclk = lpc_cclk/div;
+    lpc_pclk = lpc_cclk / vpbdiv;
+    lpc_xclk = lpc_cclk / xclkdiv;
 }
 
+// Perform variant setup
 void hal_hardware_init(void)
 {
     lpc_cclk = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED;
-    lpc_set_vpbdiv(4);
+    lpc_set_vpbdiv(CYGNUM_HAL_ARM_LPC2XXX_VPBDIV,
+											CYGNUM_HAL_ARM_LPC2XXX_XCLKDIV);
     // Set up eCos/ROM interfaces
     hal_if_init();
-
 }
 
 // -------------------------------------------------------------------------
 // This routine is called to respond to a hardware interrupt (IRQ).  It
 // should interrogate the hardware and return the IRQ vector number.
 int hal_IRQ_handler(void)
 {
-    cyg_uint32 irq_num,irq_stat;
-    // Find out which interrupt caused the IRQ
-    // picks the lowest if there are more.
+    cyg_uint32 irq_num, irq_stat;
+
+    // Find out which interrupt caused the IRQ. This picks the lowest
+	// if there are more than 1.
     // FIXME:try to make use of the VIC for better latency.
     //       That will probably need changes to vectors.S and 
     //       other int-related code
     HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_VIC_BASE + 
                     CYGARC_HAL_LPC2XXX_REG_VICIRQSTAT, irq_stat);
     for (irq_num = 0; irq_num < 32; irq_num++)
-	    if (irq_stat & (1<<irq_num)) break;
-    // No valid interrrupt source, treat as spurious interrupt    
+		if (irq_stat & (1 << irq_num))
+			break;
+
+    // If not a valid interrrupt source, treat as spurious interrupt    
     if (irq_num < CYGNUM_HAL_ISR_MIN || irq_num > CYGNUM_HAL_ISR_MAX)
-      irq_num = CYGNUM_HAL_INTERRUPT_NONE;
+		irq_num = CYGNUM_HAL_INTERRUPT_NONE;
     
-    return irq_num;
+    return (irq_num);
 }
 
 // -------------------------------------------------------------------------
 // Interrupt control
 //
 
+// Block the the interrupt associated with the vector
 void hal_interrupt_mask(int vector)
 {
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
 
     HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_VIC_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_VICINTENCLEAR, 1<<vector);
+                     CYGARC_HAL_LPC2XXX_REG_VICINTENCLEAR, 1 << vector);
 }
 
+// Unblock the the interrupt associated with the vector
 void hal_interrupt_unmask(int vector)
 {
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
 
     HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_VIC_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_VICINTENABLE, 1<<vector);
+                     CYGARC_HAL_LPC2XXX_REG_VICINTENABLE, 1 << vector);
 }
 
+// Acknowledge the the interrupt associated with the vector. This clears the interrupt
+// but may result in another interrupt being delivered
 void hal_interrupt_acknowledge(int vector)
 {
+
+    // External interrupts have to be cleared from the EXTINT register
+    if (vector >= CYGNUM_HAL_INTERRUPT_EINT0 &&
+						vector <= CYGNUM_HAL_INTERRUPT_EINT3)
+	{
+	    // Map int vector to corresponding bit (0..3)
+	    vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
+
+		// Clear the external interrupt
+		HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTINT, vector);
+	}
+
+	//
     HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_VIC_BASE + 
                      CYGARC_HAL_LPC2XXX_REG_VICVECTADDR, 0);  
 }
 
+// This provides control over how an interrupt signal is detected.
+// Options are between level or edge sensitive (level) and high/low
+// level or rising/falling edge triggered (up).
+//
+// This should be simple, but unfortunately on some processor revisions,
+// it trips up on two errata issues (for the LPC2294 Rev.A these are
+// EXTINT.1 and VPBDIV.1) and so on these devices a somewhat convoluted
+// sequence in order to work properly. There is nothing in the errata
+// sequence that won't work on a processor without these issues.
 void hal_interrupt_configure(int vector, int level, int up)
 {
-    cyg_uint32 mode;
-    cyg_uint32 pol;
-    // only external interrupts are configurable	
+    cyg_uint32 regval, saved_vpbdiv;
+
+    // Only external interrupts are configurable	
     CYG_ASSERT(vector <= CYGNUM_HAL_INTERRUPT_EINT3 &&
                vector >= CYGNUM_HAL_INTERRUPT_EINT0 , "Invalid vector");
-#if CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA
-    // Errata sheet says VPBDIV is corrupted when accessing EXTPOL or EXTMOD
-    // Must be written as 0 and at the end restored to original value
-    
-    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_VPBDIV, 0);
-#endif    
-    HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                    CYGARC_HAL_LPC2XXX_REG_EXTMODE, mode);
-    HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                    CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, pol);
-    
-    // map int vector to corresponding bit (0..3)
+
+    // Map int vector to corresponding bit (0..3)
     vector = 1 << (vector - CYGNUM_HAL_INTERRUPT_EINT0);
-    
-    // level or edge
-    if (level) {
-	mode &= ~vector;   
-    } else {
-	mode |= vector;   
-    }
-    
-    // high/low or falling/rising
-    if (up) {
-	pol |= vector;   
-    } else {
-	pol &= ~vector;   
-    }
-    
-    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_EXTMODE, mode);
-    HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
-                     CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, pol);
-    
-#if CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA    
-    // we know this was the original value
-    lpc_set_vpbdiv(lpc_cclk/lpc_pclk);
+
+#ifdef CYGHWR_HAL_ARM_LPC2XXX_EXTINT_ERRATA
+	// From discussions with the Philips applications engineers on the
+	// Yahoo LPC2000 forum, it appears that in order up change both
+	// EXTMODE and EXTPOLAR, the operations have to be performed in
+	// two passes as follows:
+	// old=VPBDIV (x2),
+	//     VPBDIV=0, EXTMODE=n, VPBDIV=n, VPBDIV=0, EXTPOLAR=y, VPBDIV=y
+	// VPCDIV=old
+
+	// Save current VPBDIV register settings
+	saved_vpbdiv = lpc_get_vpbdiv();
+
+	// Clear VPBDIV register
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_VPBDIV, 0);
+
+	// Read current mode and update for level (0) or edge detection (1)
+	HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTMODE, regval);
+    if (level)
+		regval &= ~vector;
+	else
+		regval |= vector;
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTMODE, regval);
+
+	// Set VPBDIV register to same value as mode
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_VPBDIV, regval);
+
+	// Clear VPBDIV register
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_VPBDIV, 0);
+
+	// Read current polarity and update for trigger level or edge
+	// level: high (1), low (0) edge: rising (1), falling (0)
+	HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, regval);
+	if (up)
+		regval |= vector;
+	else
+		regval &= ~vector;
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, regval);
+
+	// Set VPBDIV register to same value as mode
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_VPBDIV, regval);
+
+	// Restore saved VPBDIV register
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+						CYGARC_HAL_LPC2XXX_REG_VPBDIV, saved_vpbdiv);
+#else
+	// Read current mode and update for level (0) or edge detection (1)
+	HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTMODE, regval);
+	if (level)
+		regval &= ~vector;
+	else
+		regval |= vector;
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTMODE, regval);
+
+	// Read current polarity and update for trigger level or edge
+	// level: high (1), low (0) edge: rising (1), falling (0)
+	HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, regval);
+	if (up)
+		regval |= vector;
+	else
+		regval &= ~vector;
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTPOLAR, regval);
 #endif
+	// Clear any spurious interrupt that might have been generated
+	HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_SCB_BASE + 
+							CYGARC_HAL_LPC2XXX_REG_EXTINT, vector);
 }
 
+// Change interrupt level. This is a non-operation on the LPC2XXX
 void hal_interrupt_set_level(int vector, int level)
 {
     CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
                vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
     CYG_ASSERT(level >= 0 && level <= 15, "Invalid level");
-
 }
 
 // Use the watchdog to generate a reset
 void hal_lpc_watchdog_reset(void)
 {
@@ -324,10 +429,11 @@
                      CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC1);	
     HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_WD_BASE + 
                      CYGARC_HAL_LPC2XXX_REG_WDFEED, 
                      CYGARC_HAL_LPC2XXX_REG_WDFEED_MAGIC2);
     
-    while(1);
+    while(1)
+		continue;
 }
 
 //--------------------------------------------------------------------------
 // EOF lpc_misc.c
