This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Device drivers for LPC2xxx


Hi Folks

A year ago today, Hans Rosenfeld contributed some device drivers for
LPC2xxx targets. Included was wallclock, I2C, SPI and the internal
flash controller. At the time the copyright assignment was not in
place and the contribution got forgotten. Sorry Hans.

Recently Uwe Kindler asked about them. The copyright assignment is now
in place so i did the work to include them in eCos. Attached is the
patch. Currently no target actually uses them, so patches are welcome
to fix this...

Thanks Hans for your contribution. 

       Andrew
Index: NEWS
===================================================================
RCS file: /cvs/ecos/ecos/packages/NEWS,v
retrieving revision 1.109
diff -u -r1.109 NEWS
--- NEWS	12 Jul 2008 14:33:02 -0000	1.109
+++ NEWS	12 Jul 2008 15:52:07 -0000
@@ -1,3 +1,4 @@
+* drivers for LPC2xxx on-chip flash, RTC, I2C and SPI from Hans Rosenfeld.
 * Port to Embedded Artists LPC2468 OEM board by Uwe Kindler.
 * USB serial class driver by Frank Pagliughi.
 * FR30 arch, mb91301 variant and skmb91302 platform by Lars Poeschel.
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/ChangeLog,v
retrieving revision 1.185
diff -u -r1.185 ChangeLog
--- ChangeLog	12 Jul 2008 14:33:02 -0000	1.185
+++ ChangeLog	12 Jul 2008 15:52:08 -0000
@@ -1,3 +1,9 @@
+2008-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+	* NEWS:
+	* ecos.db: added drivers for LPC2xxx on-chip flash, RTC, I2C and
+	SPI units
+	
 2008-07-08   Uwe Kindler <uwe_kindler@web.de>
  
  	* NEWS:
Index: ecos.db
===================================================================
RCS file: /cvs/ecos/ecos/packages/ecos.db,v
retrieving revision 1.172
diff -u -r1.172 ecos.db
--- ecos.db	12 Jul 2008 14:33:02 -0000	1.172
+++ ecos.db	12 Jul 2008 15:52:12 -0000
@@ -826,6 +826,16 @@
            on the Fujitsu MB93093-PD00 Portable Development Kit."
 }
 
+package CYGPKG_DEVS_FLASH_ARM_LPC2XXX {
+        alias           { "Support for the internal flash memory of LPC2xxx devices" flash_arm_lpc2xxx }
+        directory       devs/flash/arm/lpc2xxx
+        script          flash_arm_lpc2xxx.cdl
+        hardware
+        description     "
+           This package contains hardware support for the internal
+           flash memory of the LPC2xxx devices."
+}
+
 package CYGPKG_DEVS_TOUCH_IPAQ {
 	alias 		{ "Touch screen support for iPAQ" touch_ipaq }
 	directory	devs/touch/arm/ipaq
@@ -2109,6 +2119,16 @@
            ARM Industrial Module AIM 711."
 }
 
+package CYGPKG_DEVICES_WALLCLOCK_ARM_LPC2XXX {
+        alias           { "Wallclock driver for LPC2xxx RTC module" }
+        directory       devs/wallclock/arm/lpc2xxx
+        script          lpc2xxx_wallclock.cdl
+        hardware
+        description "
+           This package provides a wallclock driver implementation for the
+           LPC2xxx RTC module."
+}
+
 package CYGPKG_DEVICES_WATCHDOG_ARM_AEB {
 	alias		{ "Watchdog driver for ARM/AEB board" devices_watchdog_aeb device_watchdog_aeb }
 	directory	devs/watchdog/arm/aeb
@@ -2243,6 +2263,15 @@
     description   "Atmel AT91EB55 spi devices."
 }
 
+package CYGPKG_DEVS_SPI_ARM_LPC2XXX {
+    alias         { "LPC2xxx SPI driver" }
+    hardware
+    directory     devs/spi/arm/lpc2xxx
+    script        spi_lpc2xxx.cdl
+    description "This package provides a driver for the I2C unit of the LPC2xxx
+                 controller family."
+}
+
 package CYGPKG_IO_SPI {
         alias      { "Generic SPI support" spi io_spi spi_io }
         directory  io/spi
@@ -2276,6 +2305,15 @@
 	        device provided by the MCF52xx coldfire processor family."
 }
 
+package CYGPKG_DEVS_I2C_ARM_LPC2XXX {
+    alias           { "LPC2xxx I2C driver" }
+    hardware
+    directory       devs/i2c/arm/lpc2xxx
+    script          i2c_lpc2xxx.cdl
+    description "This package provides a driver for the I2C unit of the LPC2xxx
+                 controller family."
+}
+
 package CYGPKG_KERNEL {
 	alias		{ "eCos kernel" kernel }
 	directory	kernel
Index: devs/flash/arm/lpc2xxx/current/ChangeLog
===================================================================
RCS file: devs/flash/arm/lpc2xxx/current/ChangeLog
diff -N devs/flash/arm/lpc2xxx/current/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/flash/arm/lpc2xxx/current/ChangeLog	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+	* lpc2xxx: driver for on-chip flash memory
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// 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####
+//===========================================================================
Index: devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl
===================================================================
RCS file: devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl
diff -N devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/flash/arm/lpc2xxx/current/cdl/flash_arm_lpc2xxx.cdl	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,83 @@
+# ====================================================================
+#
+#      flash_arm_lpc2xxx.cdl
+#
+#      Philips LPC2XXX flash memory package
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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):      Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:   
+# Date:           2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_FLASH_ARM_LPC2XXX {
+    display     "LPC2xxx internal FLASH memory support"
+    description "Support for the internal FLASH memory of LPC2xxx controllers"
+    
+    parent      CYGPKG_IO_FLASH
+    active_if   CYGPKG_IO_FLASH
+    requires    CYGPKG_HAL_ARM_LPC2XXX
+    implements  CYGHWR_IO_FLASH_DEVICE
+
+    # These chips use two erase block sizes, the access to flash is
+    # limited to the last few of the 8k blocks. I don't have a chip
+    # using only 8k block sizes, so I can't test and therefore won't
+    # implement support for these devices.
+    active_if   {
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2124" ||
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2129" ||
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2194" ||
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2214" ||
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2292" ||
+        CYGHWR_HAL_ARM_LPC2XXX == "LPC2294"
+    }
+
+    compile     flash_arm_lpc2xxx.c
+    include_dir .
+
+    cdl_option CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE {
+        display       "copy buffer size"
+        description   "
+            Size of the buffer reserved at the end of the internal
+            SRAM area for flash writing (copy) operations.  Additional
+            32 bytes are reserved for use by the IAP routine."
+        flavor        data
+        legal_values  512 1024 4096 8192
+        default_value 8192
+    }
+}
Index: devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h
===================================================================
RCS file: devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h
diff -N devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/flash/arm/lpc2xxx/current/include/flash_arm_lpc2xxx.h	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,81 @@
+#ifndef CYGONCE_FLASH_ARM_LPC2XXX_H
+#define CYGONCE_FLASH_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+//      flash_arm_lpc2xxx.h
+//
+//      Flash programming for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: 
+// Date:         2007-07-12
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+struct iap_param {
+        cyg_uint32 code;
+        cyg_uint32 p[4];
+};
+
+#define IAP_PREPARE 50
+#define IAP_COPY    51
+#define IAP_ERASE   52
+#define IAP_CHECK   53
+#define IAP_PARTID  54
+#define IAP_VERSION 55
+#define IAP_COMPARE 56
+
+#define IAP_CMD_SUCCESS 0
+#define IAP_CMD_INVALID 1
+#define IAP_SRC_ADDRERR 2
+#define IAP_DST_ADDRERR 3
+#define IAP_SRC_ADDRMAP 4
+#define IAP_DST_ADDRMAP 5
+#define IAP_CNT_INVALID 6
+#define IAP_SEC_INVALID 7
+#define IAP_SEC_NOTBLNK 8
+#define IAP_SEC_NOTPREP 9
+#define IAP_CMP_INEQUAL 10
+#define IAP_BSY 11
+
+#define IAP_LOCATION 0x7ffffff1
+
+#endif
Index: devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c
===================================================================
RCS file: devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c
diff -N devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/flash/arm/lpc2xxx/current/src/flash_arm_lpc2xxx.c	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,216 @@
+//==========================================================================
+//
+//      flash_arm_lpc2xxx.c
+//
+//      Flash programming for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: 
+// Date:         2007-07-12
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_flash_arm_lpc2xxx.h>
+#include <pkgconf/hal.h>
+#include <pkgconf/hal_arm.h>
+#include <cyg/hal/hal_intr.h>
+
+#define _FLASH_PRIVATE_
+#include <cyg/io/flash.h>
+
+#include "flash_arm_lpc2xxx.h"
+
+/* gcc builtins */
+extern void* memcpy(void *, const void *, size_t);
+extern void* memset(void *, int, size_t);
+
+/* wrapper for simpler IAP access */
+static void
+iap(struct iap_param *param, struct iap_param *result)
+{
+  static void (* const iap)(struct iap_param *, struct iap_param *)
+    = (void (*)(struct iap_param *, struct iap_param *)) IAP_LOCATION;
+  cyg_uint32 cpsr;
+  
+  HAL_DISABLE_INTERRUPTS(cpsr);
+  iap(param, result);
+  HAL_RESTORE_INTERRUPTS(cpsr);
+}
+
+void 
+flash_query(void *data)
+{
+  /* nothing to do here */
+}
+
+/*
+ * 248k in 31 blocks by 8k there actually less blocks since two of
+ * them are 64k, but accessing anything but the last few 8k blocks is
+ * not supported anyway
+ */
+int 
+flash_hwr_init(void)
+{
+  flash_info.block_size = 8 * 1024;
+  flash_info.blocks = 31;
+  flash_info.start = (void *) 0;
+  flash_info.end = (void *) (248 * 1024);
+  
+  return FLASH_ERR_OK;
+}
+
+
+static const cyg_uint8 flash_errors[12] = {
+  FLASH_ERR_OK,          /* IAP_CMD_SUCCESS */
+  FLASH_ERR_PROTOCOL,    /* IAP_INV_COMMAND */
+  FLASH_ERR_INVALID,     /* IAP_SRC_ADDRERR */
+  FLASH_ERR_INVALID,     /* IAP_DST_ADDRERR */
+  FLASH_ERR_INVALID,     /* IAP_SRC_ADDRMAP */
+  FLASH_ERR_INVALID,     /* IAP_DST_ADDRMAP */
+  FLASH_ERR_INVALID,     /* IAP_CNT_INVALID */
+  FLASH_ERR_INVALID,     /* IAP_SEC_INVALID */
+  FLASH_ERR_PROTOCOL,    /* IAP_SEC_NOTBLNK */
+  FLASH_ERR_PROTOCOL,    /* IAP_SEC_NOTPREP */
+  FLASH_ERR_DRV_VERIFY,  /* IAP_CMP_INEQUAL */
+  FLASH_ERR_DRV_TIMEOUT, /* IAP_BSY         */
+};
+
+int
+flash_hwr_map_error(e)
+{
+  if(e > 11)
+    return FLASH_ERR_PROTOCOL;
+  return flash_errors[e];
+}
+
+/* this will not work for flash addresses < 0x30000 */
+static int
+block_by_addr(cyg_uint32 addr)
+{
+  int block;
+  
+  block = (addr >> 13) & 0x1f;
+  block -= 14;
+  
+  return block;
+}
+
+int
+flash_erase_block(void *block, unsigned int size)
+{
+  struct iap_param param, result;
+  
+  param.code = IAP_PREPARE;
+  
+  param.p[0] = param.p[1] = block_by_addr((cyg_uint32) block);
+  if(param.p[0] < 10)
+    return FLASH_ERR_INVALID;
+  
+  /* prepare sector(s) */
+  iap(&param, &result);
+  if(result.code != IAP_CMD_SUCCESS)
+    return result.code;
+  
+  param.code = IAP_ERASE;
+  param.p[2] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+  
+  /* erase sector(s) */
+  iap(&param, &result);
+  return result.code;
+}
+
+int
+flash_program_buf(void *addr, void *data, int len)
+{
+  static const int size = CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE;
+  static const cyg_uint32 b = (0x40004000 - 32 - 
+                               CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+  static void * const buf = (void *) (0x40004000 - 32 - 
+                                      CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
+  cyg_uint32 a = (cyg_uint32) addr;
+  char *d = (char *) data;
+  struct iap_param param, result;
+  
+  param.code = IAP_PREPARE;
+  param.p[0] = block_by_addr(a);
+  param.p[1] = block_by_addr(a + len - 1);
+  if(param.p[0] < 10 || param.p[1] > 16)
+    return FLASH_ERR_INVALID;
+  
+  do {
+    /* prepare sector(s) */
+    iap(&param, &result);
+    if(result.code != IAP_CMD_SUCCESS)
+      return result.code;
+    
+    if(len < size)
+      memset(buf, 0xff, size);
+    memcpy(buf, d, size);
+    
+    param.code = IAP_COPY;
+    param.p[0] = a;
+    param.p[1] = b;
+    param.p[2] = size;
+    param.p[3] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
+    
+    /* copy ram to flash */
+    iap(&param, &result);
+    if(result.code != IAP_CMD_SUCCESS)
+      return result.code;
+    
+    len -= size;
+    a += size;
+    d += size;
+  } while(len > 0);
+  
+  return(result.code);
+}
+
+bool
+flash_code_overlaps(void *start, void *end)
+{
+  extern unsigned char _stext[], _etext[];
+  
+  return ((((unsigned long)&_stext >= (unsigned long)start) &&
+           ((unsigned long)&_stext < (unsigned long)end)) ||
+          (((unsigned long)&_etext >= (unsigned long)start) &&
+           ((unsigned long)&_etext < (unsigned long)end)));
+}
Index: devs/i2c/arm/lpc2xxx/current/ChangeLog
===================================================================
RCS file: devs/i2c/arm/lpc2xxx/current/ChangeLog
diff -N devs/i2c/arm/lpc2xxx/current/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/i2c/arm/lpc2xxx/current/ChangeLog	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+	* lpc2xxx: driver for on-chip I2C unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// 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####
+//===========================================================================
Index: devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl
===================================================================
RCS file: devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl
diff -N devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/i2c/arm/lpc2xxx/current/cdl/i2c_lpc2xxx.cdl	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,59 @@
+# ====================================================================
+#
+#      i2c_lpc2xxx.cdl
+#
+#      I2C driver for LPC2xxx
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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):      Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:   
+# Date:           2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_I2C_ARM_LPC2XXX {
+    display     "I2C driver for LPC2xxx family of ARM controllers"
+    
+    parent      CYGPKG_IO_I2C
+    active_if   CYGPKG_IO_I2C
+    active_if   CYGPKG_HAL_ARM_LPC2XXX
+
+    description "This package provides a driver for the I2C module found in
+                 Philips LPC2xxx controllers."
+
+    compile     i2c_lpc2xxx.c
+}
\ No newline at end of file
Index: devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c
===================================================================
RCS file: devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c
diff -N devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/i2c/arm/lpc2xxx/current/src/i2c_lpc2xxx.c	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,414 @@
+//==========================================================================
+//
+//      i2c_lpc2xxx.c
+//
+//      I2C driver for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: 
+// Date:         2007-07-12
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/system.h>
+#include <pkgconf/devs_i2c_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/io/i2c.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+/* 
+ * According to the Users Manual the LPC2xxx I2C module is very
+ * similar to the I2C module of the Philips 8xC552/556 controllers. I
+ * guess it is used in other Philips/NXP controllers, too. Using these
+ * macros should make it easier to split off the common parts of the
+ * driver once it's necessary.
+ */
+
+#define I2C_XFER        8
+#define I2C_INTR        CYGNUM_HAL_INTERRUPT_I2C
+#define I2C_FREQ        (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / \
+                         CYGNUM_HAL_ARM_LPC2XXX_VPBDIV)
+#define I2C_BASE        CYGARC_HAL_LPC2XXX_REG_I2_BASE
+
+#define I2C_CONSET      CYGARC_HAL_LPC2XXX_REG_I2CONSET
+#define I2C_CONCLR      CYGARC_HAL_LPC2XXX_REG_I2CONCLR
+#define I2C_CON         I2C_CONSET
+#define I2C_STAT        CYGARC_HAL_LPC2XXX_REG_I2STAT
+#define I2C_DAT         CYGARC_HAL_LPC2XXX_REG_I2DAT
+#define I2C_ADR         CYGARC_HAL_LPC2XXX_REG_I2ADR
+#define I2C_SCLH        CYGARC_HAL_LPC2XXX_REG_I2SCLH
+#define I2C_SCLL        CYGARC_HAL_LPC2XXX_REG_I2SCLL
+
+#define I2C_R8(r, x)    HAL_READ_UINT8  (I2C_BASE + (r), (x))
+#define I2C_W8(r, x)    HAL_WRITE_UINT8 (I2C_BASE + (r), (x))
+#define I2C_R16(r, x)   HAL_READ_UINT16 (I2C_BASE + (r), (x))
+#define I2C_W16(r, x)   HAL_WRITE_UINT16(I2C_BASE + (r), (x))
+
+/* Special case for setting/clearing bits in I2C_CON */
+#define SET_CON(x)      I2C_W8(I2C_CONSET, (x))
+#define CLR_CON(x)      I2C_W8(I2C_CONCLR, (x))
+
+#define CON_EN          CYGARC_HAL_LPC2XXX_REG_I2CONSET_I2EN
+#define CON_STA         CYGARC_HAL_LPC2XXX_REG_I2CONSET_STA
+#define CON_STO         CYGARC_HAL_LPC2XXX_REG_I2CONSET_STO
+#define CON_SI          CYGARC_HAL_LPC2XXX_REG_I2CONSET_SI
+#define CON_AA          CYGARC_HAL_LPC2XXX_REG_I2CONSET_AA
+
+static cyg_uint8        i2c_addr;
+static cyg_uint32       i2c_count = 0;
+static const cyg_uint8* i2c_txbuf = NULL;
+static cyg_uint8*       i2c_rxbuf = NULL;
+static cyg_bool         i2c_rxnak;
+
+volatile
+static cyg_uint32       i2c_flag = 0;
+static cyg_uint32       i2c_delay;
+
+static cyg_drv_mutex_t  i2c_lock;
+static cyg_drv_cond_t   i2c_wait;
+static cyg_handle_t     i2c_hand;
+static cyg_interrupt    i2c_data;
+
+#define I2C_FLAG_FINISH 1       /* transfer finished                        */
+#define I2C_FLAG_ACT    2       /* bus still active, no STOP condition sent */
+#define I2C_FLAG_ERROR  (1<<31) /* one of the following errors occured:     */
+#define I2C_FLAG_ADDR   (1<<30) /* - address was not ACKed                  */
+#define I2C_FLAG_DATA   (1<<29) /* - data was not ACKed                     */
+#define I2C_FLAG_LOST   (1<<28) /* - bus arbitration was lost               */
+#define I2C_FLAG_BUF    (1<<27) /* - no buffer for reading or writing       */
+#define I2C_FLAG_UNK    (1<<26) /* - unknown I2C status                     */
+
+/*
+ * set up I2C bus timing
+ * I2C clock period is in PCLK ticks
+ */
+static void
+i2c_lpc2xxx_delay(cyg_uint32 delay)
+{
+  cyg_uint32 period;
+  
+  if(delay == i2c_delay)
+    return;
+  
+  period = I2C_FREQ / (1000000000 / delay);
+  period /= 2;
+  
+  I2C_W16(I2C_SCLL, period);
+  I2C_W16(I2C_SCLH, period);
+  i2c_delay = delay;
+}
+
+/*
+ * The ISR does the actual work. It is not that much work to justify
+ * putting it in the DSR, and it is also not clear whether this would
+ * even work.  If an error occurs we try to leave the bus in the same
+ * state as we would if there was no error.
+ */
+static cyg_uint32
+i2c_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+  cyg_uint8 status;
+  I2C_R8(I2C_STAT, status);
+  
+  switch(status) {
+    case 0x08: /* START sent, send Addr+R/W   */
+    case 0x10: /* ReSTART sent, send Addr+R/W */
+      CLR_CON(CON_STA);
+      I2C_W8(I2C_DAT, i2c_addr);
+      break;
+      
+    case 0x18: /* Addr ACKed, send data       */
+    case 0x28: /* Data ACKed, send more       */
+      if(i2c_count == 0) {
+        i2c_flag = I2C_FLAG_FINISH;
+        cyg_drv_interrupt_mask_intunsafe(vec);
+        cyg_drv_interrupt_acknowledge(vec);
+        return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      }
+      
+      if(i2c_txbuf == NULL) {
+        i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+        cyg_drv_interrupt_mask_intunsafe(vec);
+        cyg_drv_interrupt_acknowledge(vec);
+        return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      }
+      
+      I2C_W8(I2C_DAT, *i2c_txbuf);
+      i2c_txbuf++;
+      i2c_count--;
+      break;
+      
+    case 0x50: /* Data ACKed, receive more    */
+    case 0x58: /* Data not ACKed, end reception */
+      if(i2c_rxbuf == NULL) {
+        i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_BUF;
+        cyg_drv_interrupt_mask_intunsafe(vec);
+        cyg_drv_interrupt_acknowledge(vec);
+        return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      }
+      
+      I2C_R8(I2C_DAT, *i2c_rxbuf);
+      i2c_rxbuf++;
+      i2c_count--;
+    case 0x40: /* Addr ACKed, receive data    */
+      if(status == 0x58 || i2c_count == 0) {
+        i2c_flag = I2C_FLAG_FINISH;
+        cyg_drv_interrupt_mask_intunsafe(vec);
+        cyg_drv_interrupt_acknowledge(vec);
+        return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      }
+      
+      if(i2c_count == 1 && i2c_rxnak)
+        CLR_CON(CON_AA);
+      else    
+        SET_CON(CON_AA);
+      break;
+      
+    case 0x20: /* Addr not ACKed */
+    case 0x48:
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_ADDR;
+      cyg_drv_interrupt_mask_intunsafe(vec);
+      cyg_drv_interrupt_acknowledge(vec);
+      return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      break;
+    case 0x30: /* Data not ACKed */
+      i2c_count++;
+      i2c_txbuf--;
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_DATA;
+      cyg_drv_interrupt_mask_intunsafe(vec);
+      cyg_drv_interrupt_acknowledge(vec);
+      return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+      break;
+    case 0x38: /* Arbitration lost */
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_LOST;
+      break;
+    default: /* lots of unused states... */
+      i2c_flag = I2C_FLAG_ERROR | I2C_FLAG_UNK;
+      break;
+  }
+  
+  CLR_CON(CON_SI);
+  cyg_drv_interrupt_acknowledge(vec);
+  return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void
+i2c_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+  if(i2c_flag)
+    cyg_drv_cond_signal(&i2c_wait);
+}
+
+/*
+ * Initialize driver & hardware state
+ */
+static void
+i2c_lpc2xxx_init(struct cyg_i2c_bus *bus)
+{
+  cyg_uint32 addr, tmp;
+  
+  /* enable I2C pins */
+  addr = CYGARC_HAL_LPC2XXX_REG_PIN_BASE + CYGARC_HAL_LPC2XXX_REG_PINSEL0;
+  HAL_READ_UINT32(addr, tmp);
+  tmp |= 0x50;
+  HAL_WRITE_UINT32(addr, tmp);
+  
+  cyg_drv_mutex_init(&i2c_lock);
+  cyg_drv_cond_init(&i2c_wait, &i2c_lock);
+  cyg_drv_interrupt_create(I2C_INTR, 0, (cyg_addrword_t) 0, &i2c_lpc2xxx_isr,
+                           &i2c_lpc2xxx_dsr, &i2c_hand, &i2c_data);
+  cyg_drv_interrupt_attach(i2c_hand);
+  
+  CLR_CON(CON_EN | CON_STA | CON_SI | CON_AA);
+  I2C_W8(I2C_ADR, 0);
+  SET_CON(CON_EN);
+}
+
+/*
+ * transmit a buffer to a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_tx(const cyg_i2c_device *dev, 
+               cyg_bool send_start, 
+               const cyg_uint8 *tx_data, 
+               cyg_uint32 count, 
+               cyg_bool send_stop)
+{
+  i2c_lpc2xxx_delay(dev->i2c_delay);
+  
+  i2c_addr  = dev->i2c_address << 1;
+  i2c_count = count;
+  i2c_txbuf = tx_data;
+  
+  /*
+   * for a repeated start the SI bit has to be reset
+   * if we continue a previous transfer, load the next byte
+   */
+  if(send_start && i2c_flag == I2C_FLAG_ACT) {
+    SET_CON(CON_STA);
+    CLR_CON(CON_SI);
+  } else if(send_start) {
+    SET_CON(CON_STA);
+  } else {
+    I2C_W8(I2C_DAT, *i2c_txbuf);
+    i2c_txbuf++;
+    i2c_count--;
+    CLR_CON(CON_SI);
+  }
+  
+  i2c_flag  = 0;
+  
+  /*
+   * the isr will do most of the work, and the dsr will signal when an
+   * error occured or the transfer finished
+   */
+  cyg_drv_mutex_lock(&i2c_lock);
+  cyg_drv_dsr_lock();
+  cyg_drv_interrupt_unmask(I2C_INTR);
+  while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+    cyg_drv_cond_wait(&i2c_wait);
+  cyg_drv_interrupt_mask(I2C_INTR);
+  cyg_drv_dsr_unlock();
+  cyg_drv_mutex_unlock(&i2c_lock);
+  
+  /* too bad we have no way to tell the caller */
+  if(i2c_flag & I2C_FLAG_ERROR)
+    diag_printf("I2C TX error flag: %x\n", i2c_flag);
+  
+  if(send_stop) {
+    SET_CON(CON_STO);
+    CLR_CON(CON_SI | CON_STA);
+  } else  i2c_flag = I2C_FLAG_ACT;
+  
+  count -= i2c_count;
+  
+  i2c_addr  = 0;
+  i2c_count = 0;
+  i2c_txbuf = NULL;
+  
+  return count;
+}
+
+/*
+ * receive into a buffer from a device
+ */
+static cyg_uint32
+i2c_lpc2xxx_rx(const cyg_i2c_device *dev,
+               cyg_bool send_start,
+               cyg_uint8 *rx_data,
+               cyg_uint32 count,
+               cyg_bool send_nak,
+               cyg_bool send_stop)
+{
+  i2c_lpc2xxx_delay(dev->i2c_delay);
+  
+  i2c_addr  = dev->i2c_address << 1 | 1;
+  i2c_count = count;
+  i2c_rxbuf = rx_data;
+  i2c_rxnak = send_nak;
+  
+  /*
+   * for a repeated start the SI bit has to be reset
+   * if we continue a previous transfer, start reception
+   */
+  if(send_start && i2c_flag == I2C_FLAG_ACT) {
+    SET_CON(CON_STA);
+    CLR_CON(CON_SI);
+  } else if(send_start)
+    SET_CON(CON_STA);
+  
+  i2c_flag  = 0;
+  
+  /*
+   * the isr will do most of the work, and the dsr will signal when an
+   * error occured or the transfer finished
+   */
+  cyg_drv_mutex_lock(&i2c_lock);
+  cyg_drv_dsr_lock();
+  cyg_drv_interrupt_unmask(I2C_INTR);
+  while(!(i2c_flag & (I2C_FLAG_FINISH|I2C_FLAG_ERROR)))
+    cyg_drv_cond_wait(&i2c_wait);
+  cyg_drv_interrupt_mask(I2C_INTR);
+  cyg_drv_dsr_unlock();
+  cyg_drv_mutex_unlock(&i2c_lock);
+  
+  /* too bad we have no way to tell the caller */
+  if(i2c_flag & I2C_FLAG_ERROR)
+    diag_printf("I2C RX error flag: %x\n", i2c_flag);
+  
+  if(send_stop) {
+    SET_CON(CON_STO);
+    CLR_CON(CON_SI | CON_STA);
+  } else  i2c_flag = I2C_FLAG_ACT;
+  
+  count -= i2c_count;
+  
+  i2c_addr  = 0;
+  i2c_count = 0;
+  i2c_rxbuf = NULL;
+  
+  return count;
+  
+}
+
+
+/*
+ * generate a STOP
+ */
+static void
+i2c_lpc2xxx_stop(const cyg_i2c_device *dev)
+{
+  SET_CON(CON_STO);
+}
+
+CYG_I2C_BUS(cyg_i2c_lpc2xxx_bus,
+            &i2c_lpc2xxx_init,
+            &i2c_lpc2xxx_tx,
+            &i2c_lpc2xxx_rx,
+            &i2c_lpc2xxx_stop,
+            (void *) 0);
Index: devs/spi/arm/lpc2xxx/current/ChangeLog
===================================================================
RCS file: devs/spi/arm/lpc2xxx/current/ChangeLog
diff -N devs/spi/arm/lpc2xxx/current/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/spi/arm/lpc2xxx/current/ChangeLog	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,35 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+	* lpc2xxx: driver for on-chip SPI units
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// 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####
+//===========================================================================
Index: devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl
===================================================================
RCS file: devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl
diff -N devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/spi/arm/lpc2xxx/current/cdl/spi_lpc2xxx.cdl	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,73 @@
+# ====================================================================
+#
+#      spi_lpc2xxx.cdl
+#
+#      SPI driver for LPC2xxx
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## 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):      Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:   
+# Date:           2007-07-12
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_SPI_ARM_LPC2XXX {
+    display     "LPC2xxx SPI driver"
+    requires    CYGPKG_HAL_ARM_LPC2XXX
+
+    parent      CYGPKG_IO_SPI
+    active_if   CYGPKG_IO_SPI
+
+    include_dir cyg/io
+    compile     spi_lpc2xxx.cxx
+
+    cdl_option CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0 {
+        display       "Enable SPI interface 0"
+        flavor        bool
+        default_value 1
+        description   "The LPC2xxx controllers contain two SPI interfaces.
+                       Enable this option to get support for SPI interface 0."
+    }
+
+    cdl_option CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1 {
+        display       "Enable SPI interface 1"
+        flavor        bool
+        default_value 1
+        description   "The LPC2xxx controllers contain two SPI interfaces.
+                       Enable this option to get support for SPI interface 1."
+    }
+}
\ No newline at end of file
Index: devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h
===================================================================
RCS file: devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h
diff -N devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/spi/arm/lpc2xxx/current/include/spi_lpc2xxx.h	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,105 @@
+#ifndef CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+#define CYGONCE_DEVS_SPI_ARM_LPC2XXX_H
+
+//==========================================================================
+//
+//      spi_lpc2xxx.h
+//
+//      SPI driver for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: 
+// Date:         2007-07-12
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+struct spi_dev {
+  volatile cyg_uint32 spcr;
+  volatile cyg_uint32 spsr;
+  volatile cyg_uint32 spdr;
+  volatile cyg_uint32 spccr;
+  cyg_uint32 d1, d2, d3;
+  volatile cyg_uint32 spint;
+};
+
+typedef struct {
+  cyg_spi_bus     spi_bus;
+  
+  cyg_interrupt   spi_intr;
+  cyg_handle_t    spi_hand;
+  cyg_vector_t    spi_vect;
+  cyg_drv_mutex_t spi_lock;
+  cyg_drv_cond_t  spi_wait;
+  
+  struct spi_dev *spi_dev;
+  
+  volatile cyg_uint32       count;
+  volatile const cyg_uint8 *tx;
+  volatile cyg_uint8       *rx;
+} cyg_spi_lpc2xxx_bus_t;
+
+typedef struct {
+  cyg_spi_device  spi_device;
+  
+  cyg_uint8       spi_cpha;
+  cyg_uint8       spi_cpol;
+  cyg_uint8       spi_lsbf;
+  cyg_uint32      spi_baud;
+  
+  void            (*spi_cs)(int);
+} cyg_spi_lpc2xxx_dev_t;
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+#endif
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+externC cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+#endif
+
+#endif
Index: devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx
===================================================================
RCS file: devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx
diff -N devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/spi/arm/lpc2xxx/current/src/spi_lpc2xxx.cxx	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,364 @@
+//==========================================================================
+//
+//      spi_lpc2xxx.cxx
+//
+//      SPI driver for LPC2xxx
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors: 
+// Date:         2007-07-12
+// Purpose:      
+// Description:  
+//              
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_arm_lpc2xxx.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_lpc2xxx.h>
+#include <cyg/error/codes.h>
+
+#define SPI_SPCR_SPIE 0x80
+#define SPI_SPCR_LSBF 0x40
+#define SPI_SPCR_MSTR 0x20
+#define SPI_SPCR_CPOL 0x10
+#define SPI_SPCR_CPHA 0x08
+
+#define SPI_SPSR_SPIF 0x80
+#define SPI_SPSR_WCOL 0x40
+#define SPI_SPSR_ROVR 0x20
+#define SPI_SPSR_MODF 0x10
+#define SPI_SPSR_ABRT 0x08
+
+#define SPI_SPINT     0x01
+
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus0;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 0);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+cyg_spi_lpc2xxx_bus_t cyg_spi_lpc2xxx_bus1;
+CYG_SPI_DEFINE_BUS_TABLE(cyg_spi_lpc2xxx_dev_t, 1);
+#endif
+
+/*
+ * Interrupt routine
+ * read & write the next byte until count reaches zero
+ */
+static cyg_uint32
+spi_lpc2xxx_isr(cyg_vector_t vec, cyg_addrword_t data)
+{
+  cyg_spi_lpc2xxx_bus_t *bus = (cyg_spi_lpc2xxx_bus_t *) data;
+  cyg_uint8 tmp;
+  
+  tmp = bus->spi_dev->spsr;
+  
+  if(tmp & SPI_SPSR_MODF)
+    bus->spi_dev->spcr = bus->spi_dev->spcr | SPI_SPCR_MSTR;
+  
+  tmp = bus->spi_dev->spdr;
+  
+  if(bus->count) {
+    if(bus->rx)
+      *bus->rx++ = tmp;
+    if(--bus->count) {
+      bus->spi_dev->spint = SPI_SPINT;
+      bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+      cyg_drv_interrupt_acknowledge(bus->spi_vect);
+      return CYG_ISR_HANDLED;
+    }
+  }
+  
+  bus->count = 0;
+  bus->tx = NULL;
+  bus->rx = NULL;
+  
+  bus->spi_dev->spint = SPI_SPINT;
+  cyg_drv_interrupt_acknowledge(bus->spi_vect);
+  return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
+}
+
+static void 
+spi_lpc2xxx_dsr(cyg_vector_t vec, cyg_ucount32 count, cyg_addrword_t data)
+{
+  cyg_drv_cond_signal(&((cyg_spi_lpc2xxx_bus_t *) data)->spi_wait);
+}
+
+
+/*
+ * Configure bus for a specific baud rate
+ */
+static void
+spi_lpc2xxx_baud(cyg_spi_lpc2xxx_bus_t *bus, cyg_uint32 baud)
+{
+  cyg_uint32 ccr = 8;
+  
+  if(baud) {
+    ccr = (CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED 
+           / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / baud;
+    if(((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED 
+         / CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / ccr) > baud)
+      ccr++;
+    ccr++;
+    ccr &= 0xfe;
+  }
+  
+  bus->spi_dev->spccr = ccr < 8 ? 8 : ccr;
+}
+
+/*
+ * get/set configuration
+ */
+static int
+spi_lpc2xxx_get_config(cyg_spi_device *device, cyg_uint32 key, void *buf, 
+                       cyg_uint32 *len)
+{
+  cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+  
+  switch(key) {
+    case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+      if(*len == sizeof(cyg_uint32)) {
+        cyg_uint32 *b = (cyg_uint32 *) buf;
+        *b = dev->spi_baud;
+      } else return -EINVAL;
+      break;
+    default:
+      return -EINVAL;
+  }
+  
+  return ENOERR;
+}
+
+static int
+spi_lpc2xxx_set_config(cyg_spi_device *device, cyg_uint32 key, const void *buf, 
+                       cyg_uint32 *len)
+{
+  cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+  
+  switch(key) {
+    case CYG_IO_GET_CONFIG_SPI_CLOCKRATE:
+      if(*len == sizeof(cyg_uint32)) {
+        dev->spi_baud = * (cyg_uint32 *) buf;
+        spi_lpc2xxx_baud((cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus, 
+                         dev->spi_baud);
+      }
+      else return -EINVAL;
+      break;
+    default:
+      return -EINVAL;
+  }
+  
+  return ENOERR;
+}
+
+
+/*
+ * Begin transaction
+ * configure bus for device and drive CS by calling device cs() function
+ */
+static void
+spi_lpc2xxx_begin(cyg_spi_device *device)
+{
+  cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+  cyg_spi_lpc2xxx_bus_t *bus = 
+    (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+  
+  cyg_uint8 cr = 
+    (dev->spi_cpha ? SPI_SPCR_CPHA : 0) |
+    (dev->spi_cpol ? SPI_SPCR_CPOL : 0) |
+    (dev->spi_lsbf ? SPI_SPCR_LSBF : 0);
+  
+  bus->spi_dev->spcr = SPI_SPCR_MSTR | cr;
+  
+  spi_lpc2xxx_baud(bus, dev->spi_baud);
+  
+  dev->spi_cs(1);
+}
+
+
+/*
+ * Transfer a buffer to a device,
+ * fill another buffer with data from the device
+ */
+static void
+spi_lpc2xxx_transfer(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count,
+                     const cyg_uint8 *tx_data, cyg_uint8 *rx_data,
+                     cyg_bool drop_cs)
+{
+  cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+  cyg_spi_lpc2xxx_bus_t *bus = 
+    (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+  cyg_uint8 tmp;
+  
+  if(!count) return;
+  
+  if(!polled) {
+    bus->count = count;
+    bus->tx = tx_data;
+    bus->rx = rx_data;
+    
+    bus->spi_dev->spcr |= SPI_SPCR_SPIE;
+    bus->spi_dev->spdr = bus->tx ? *bus->tx++ : 0;
+    
+    cyg_drv_mutex_lock(&bus->spi_lock);
+    cyg_drv_dsr_lock();
+    cyg_drv_interrupt_unmask(bus->spi_vect);
+    while(bus->count)
+      cyg_drv_cond_wait(&bus->spi_wait);
+    cyg_drv_interrupt_mask(bus->spi_vect);
+    cyg_drv_dsr_unlock();
+    cyg_drv_mutex_unlock(&bus->spi_lock);
+  } else do {
+      bus->spi_dev->spdr = tx_data ? *tx_data++ : 0;
+      while(!(bus->spi_dev->spsr & SPI_SPSR_SPIF));
+      tmp = bus->spi_dev->spdr;
+      if(rx_data)
+        *rx_data++ = tmp;
+      count--;
+    } while(count);
+  
+  if(drop_cs)
+    dev->spi_cs(0);
+  
+  return;
+}
+
+
+/*
+ * Tick
+ */
+static void
+spi_lpc2xxx_tick(cyg_spi_device *device, cyg_bool polled, cyg_uint32 count)
+{
+  spi_lpc2xxx_transfer(device, polled, count, NULL, NULL, false);
+}
+
+
+/*
+ * End transaction
+ * disable SPI bus, drop CS, reset transfer variables
+ */
+static void
+spi_lpc2xxx_end(cyg_spi_device *device)
+{
+  cyg_spi_lpc2xxx_dev_t *dev = (cyg_spi_lpc2xxx_dev_t *) device;
+  cyg_spi_lpc2xxx_bus_t *bus = 
+    (cyg_spi_lpc2xxx_bus_t *) dev->spi_device.spi_bus;
+  
+  bus->spi_dev->spcr = 0;
+  dev->spi_cs(0);
+  
+  bus->count = 0;
+  bus->tx = NULL;
+  bus->rx = NULL;
+}
+
+
+/*
+ * Driver & bus initialization
+ */
+static void 
+spi_lpc2xxx_init_bus(cyg_spi_lpc2xxx_bus_t *bus, 
+                     cyg_addrword_t dev,
+                     cyg_vector_t vec)
+{
+  bus->spi_bus.spi_transaction_begin    = spi_lpc2xxx_begin;
+  bus->spi_bus.spi_transaction_transfer = spi_lpc2xxx_transfer;
+  bus->spi_bus.spi_transaction_tick     = spi_lpc2xxx_tick;
+  bus->spi_bus.spi_transaction_end      = spi_lpc2xxx_end;
+  bus->spi_bus.spi_get_config           = spi_lpc2xxx_get_config;
+  bus->spi_bus.spi_set_config           = spi_lpc2xxx_set_config;
+  CYG_SPI_BUS_COMMON_INIT(&bus->spi_bus);
+  
+  cyg_drv_mutex_init(&bus->spi_lock);
+  cyg_drv_cond_init(&bus->spi_wait, &bus->spi_lock);
+  
+  bus->spi_dev = (struct spi_dev *) dev;
+  bus->spi_vect = vec;
+  cyg_drv_interrupt_create(
+                           vec, 0, (cyg_addrword_t) bus,
+                           &spi_lpc2xxx_isr, &spi_lpc2xxx_dsr,
+                           &bus->spi_hand, &bus->spi_intr);
+  cyg_drv_interrupt_attach(bus->spi_hand);
+}
+
+/*
+ * initialization class
+ */
+class cyg_spi_lpc2xxx_init_class {
+public:
+  cyg_spi_lpc2xxx_init_class(void) {
+    cyg_uint32 addr, tmp;
+    
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS0
+    addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+            + CYGARC_HAL_LPC2XXX_REG_PINSEL0);
+    HAL_READ_UINT32(addr, tmp);
+    tmp |= 0x5500;
+    HAL_WRITE_UINT32(addr, tmp);
+    
+    spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus0,
+                         CYGARC_HAL_LPC2XXX_REG_SPI0_BASE,
+                         CYGNUM_HAL_INTERRUPT_SPI0);
+#endif
+#ifdef CYGPKG_DEVS_SPI_ARM_LPC2XXX_BUS1
+    addr = (CYGARC_HAL_LPC2XXX_REG_PIN_BASE
+            + CYGARC_HAL_LPC2XXX_REG_PINSEL1);
+    HAL_READ_UINT32(addr, tmp);
+    tmp |= 0x2a8;
+    HAL_WRITE_UINT32(addr, tmp);
+    spi_lpc2xxx_init_bus(&cyg_spi_lpc2xxx_bus1,
+                         CYGARC_HAL_LPC2XXX_REG_SPI1_BASE,
+                         CYGNUM_HAL_INTERRUPT_SPI1);
+#endif
+  }
+};
+
+static cyg_spi_lpc2xxx_init_class spi_lpc2xxx_init 
+    CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+
Index: devs/wallclock/arm/lpc2xxx/current/ChangeLog
===================================================================
RCS file: devs/wallclock/arm/lpc2xxx/current/ChangeLog
diff -N devs/wallclock/arm/lpc2xxx/current/ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/wallclock/arm/lpc2xxx/current/ChangeLog	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,37 @@
+2007-07-12  Hans Rosenfeld  <rosenfeld@grumpf.hope-2000.org>
+
+	* lpc2xxx: driver for on-chip RTC unit
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+//
+// 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####
+//===========================================================================
+
+
Index: devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl
===================================================================
RCS file: devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl
diff -N devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/wallclock/arm/lpc2xxx/current/cdl/lpc2xxx_wallclock.cdl	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,86 @@
+# ====================================================================
+#
+#      lpc2xxx_wallclock.cdl
+#
+#      eCos configuration data for LPC2xxx internal RTC
+#
+# ====================================================================
+#####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 Gary Thomas
+## Copyright (C) 2004 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):      Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+# Contributors:   jskov
+# Date:           2007-06-19
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVICES_WALLCLOCK_ARM_LPC2XXX {
+    display       "LPC2xxx Real-time clock"
+    description   "RTC driver for the LPC2xxx controller"
+
+    parent        CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_IO_WALLCLOCK
+    active_if     CYGPKG_HAL_ARM_LPC2XXX
+
+    requires      { CYGHWR_HAL_ARM_LPC2XXX_IDLE_PWRSAVE == 0 }
+    compile       lpc2xxx_wallclock.cxx
+
+    implements    CYGINT_WALLCLOCK_HW_IMPLEMENTATIONS
+    active_if     CYGIMP_WALLCLOCK_HARDWARE
+    implements    CYGINT_WALLCLOCK_SET_GET_MODE_SUPPORTED
+
+    cdl_option CYGIMP_WALLCLOCK_HARDWARE {
+        parent        CYGPKG_IO_WALLCLOCK_IMPLEMENTATION
+        display       "Hardware wallclock"
+        default_value 1
+        implements    CYGINT_WALLCLOCK_IMPLEMENTATIONS
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT {
+        display    "RTC prescaler integer portion"
+        flavor     data
+        calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 
+                       CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) / 32768) - 1 }
+    }
+
+    cdl_option CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC {
+        display    "RTC prescaler fractional portion"
+        flavor     data
+        calculated { ((CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 
+                       CYGNUM_HAL_ARM_LPC2XXX_VPBDIV) -
+                      ((CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT + 1) * 32768)) }
+    }
+}
Index: devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx
===================================================================
RCS file: devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx
diff -N devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ devs/wallclock/arm/lpc2xxx/current/src/lpc2xxx_wallclock.cxx	12 Jul 2008 15:52:12 -0000
@@ -0,0 +1,161 @@
+//==========================================================================
+//
+//      lpc2xxx_wallclock.cxx
+//
+//      Wallclock implementation for LPC2xxx
+//
+//==========================================================================
+//####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 Gary Thomas
+// Copyright (C) 2004 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):     Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
+// Contributors:  
+// Date:          2007-06-19
+// Purpose:       Wallclock driver for LPC2xxx
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/wallclock.h>
+#include <pkgconf/devices_wallclock_arm_lpc2xxx.h>
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/io/wallclock.hxx>
+#include <cyg/io/wallclock/wallclock.inl>
+
+/*
+ * I don't like to write LOTS OF CAPITALIZED TEXT.
+ * This code is intended for LPC2xxx processors _only_, so there is nothing
+ * wrong with accessing this device directly without using the HAL macros.
+ */
+
+struct time {
+  volatile cyg_uint32 sec;
+  volatile cyg_uint32 min;
+  volatile cyg_uint32 hour;
+  volatile cyg_uint32 dom;
+  volatile cyg_uint32 dow;
+  volatile cyg_uint32 doy;
+  volatile cyg_uint32 month;
+  volatile cyg_uint32 year;
+};
+
+struct rtcdev {
+  volatile cyg_uint32 ilr;
+  volatile cyg_uint32 ctc;
+  volatile cyg_uint32 ccr;
+  volatile cyg_uint32 ciir;
+  volatile cyg_uint32 amr;
+  volatile cyg_uint32 ctime[3];
+  struct time time;
+  cyg_uint32 dummy[8];
+  struct time alarm;
+  volatile cyg_uint32 preint;
+  volatile cyg_uint32 prefrac;
+};
+
+static struct rtcdev * const rtc = 
+  (struct rtcdev *) CYGARC_HAL_LPC2XXX_REG_RTC_BASE;
+
+void
+Cyg_WallClock::init_hw_seconds(void)
+{
+  /* halt clock, disable interrupts, disable alarm */
+  rtc->ccr  = 0x2;
+  rtc->ciir = 0x0;
+  rtc->amr  = 0xf;
+  
+  /* initialize prescaler */
+  rtc->preint  = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREINT;
+  rtc->prefrac = CYGNUM_HAL_ARM_LPC2XXX_RTCDEV_PREFRAC;
+  
+#ifndef CYGSEM_WALLCLOCK_SET_GET_MODE
+  /* reset time to the Unix Epoch */
+  rtc->time.year  = 1970;
+  rtc->time.month = 1;
+  rtc->time.dom   = 1;
+  rtc->time.doy   = 1;
+  rtc->time.dow   = 4;
+  rtc->time.hour  = 0;
+  rtc->time.min   = 0;
+  rtc->time.sec   = 0;
+#endif
+  
+  /* reset alarm */
+  rtc->alarm.year = rtc->alarm.month = rtc->alarm.dom = rtc->alarm.doy =
+    rtc->alarm.dow = rtc->alarm.hour = rtc->alarm.min = 
+    rtc->alarm.sec = 0;
+  
+  /* start clock */
+  rtc->ccr = 0x1;
+}
+
+cyg_uint32
+Cyg_WallClock::get_hw_seconds(void)
+{
+  return _simple_mktime(rtc->time.year,
+                        rtc->time.month,
+                        rtc->time.dom,
+                        rtc->time.hour,
+                        rtc->time.min,
+                        rtc->time.sec);
+}
+
+#ifdef CYGSEM_WALLCLOCK_SET_GET_MODE
+void
+Cyg_WallClock::set_hw_seconds(cyg_uint32 secs)
+{
+  cyg_uint32 year, month, dom, hour, min, sec;
+  
+  /* halt clock, reset counter */
+  rtc->ccr = 0x2;
+  
+  /* set time */
+  _simple_mkdate(secs, &year, &month, &dom, &hour, &min, &sec);
+  rtc->time.year  = year;
+  rtc->time.month = month;
+  rtc->time.dom   = dom;
+  rtc->time.hour  = hour;
+  rtc->time.min   = min;
+  rtc->time.sec   = sec;
+  
+  /* restart clock */
+  rtc->ccr = 0x1;
+}
+#endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]