Fork of the official mbed C/C++ SDK provides the software platform and libraries to build your applications. The fork has the documentation converted to Doxygen format

Dependents:   NervousPuppySprintOne NervousPuppySprint2602 Robot WarehouseBot1 ... more

Fork of mbed by mbed official

Files at this revision

API Documentation at this revision

Comitter:
simon.ford@mbed.co.uk
Date:
Thu Jan 22 18:32:40 2009 +0000
Parent:
4:5d1359a283bc
Child:
6:3fd6a337c7cc
Commit message:
* Added initial RPC release
* Added RTC and helper functions
* Added read_u16()/write_u16() to AnalogIn/Out
* Ticker/Timeout timing fixed!
* mbedinfo() helper added
* error() and printf() added to replace DEBUG() and ERROR()
* DigitalIn supports methods on rise/fall
* SPI and Serial support NC
* LED1-4 also map to 1-4
* Timer object reset fixed
* SPI uses single mode
* SPI3 added

Changed in this revision

AnalogIn.h Show annotated file Show diff for this revision Revisions of this file
AnalogOut.h Show annotated file Show diff for this revision Revisions of this file
Base.h Show annotated file Show diff for this revision Revisions of this file
BusIn.h Show annotated file Show diff for this revision Revisions of this file
BusOut.h Show annotated file Show diff for this revision Revisions of this file
Debug.h Show annotated file Show diff for this revision Revisions of this file
DebugTracer.h Show diff for this revision Revisions of this file
DigitalIn.h Show annotated file Show diff for this revision Revisions of this file
DigitalOut.h Show annotated file Show diff for this revision Revisions of this file
FileSystemLike.h Show annotated file Show diff for this revision Revisions of this file
LPC2300_MAP.h Show annotated file Show diff for this revision Revisions of this file
PwmOut.h Show annotated file Show diff for this revision Revisions of this file
SPI.h Show annotated file Show diff for this revision Revisions of this file
SPI3.h Show annotated file Show diff for this revision Revisions of this file
Serial.h Show annotated file Show diff for this revision Revisions of this file
Timer.h Show annotated file Show diff for this revision Revisions of this file
mbed.ar Show annotated file Show diff for this revision Revisions of this file
mbed.h Show annotated file Show diff for this revision Revisions of this file
rpc.h Show annotated file Show diff for this revision Revisions of this file
rtc.h Show annotated file Show diff for this revision Revisions of this file
--- a/AnalogIn.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/AnalogIn.h	Thu Jan 22 18:32:40 2009 +0000
@@ -1,6 +1,7 @@
 /* mbed Microcontroller Library - AnalogIn
- * Copyright (c) 2007-2008, sford
- */
+ * Copyright (c) 2006-2009 ARM Limited. All rights reserved.
+ * sford
+ */ 
 
 #ifndef MBED_ANALOGIN_H
 #define MBED_ANALOGIN_H
@@ -10,63 +11,75 @@
 namespace mbed {
 
 /* Class: AnalogIn
- *  An analog input, used for reading the voltage on a pin  
+ *  An analog input, used for reading the voltage on a pin 
+ *
+ * Example:
+ * > // Print messages when the AnalogIn is greater than 50%
+ * >
+ * > #include "mbed.h"
+ * >
+ * > AnalogIn temperature(20);
+ * >
+ * > int main() {
+ * >     while(1) {
+ * >         if(temperature > 0.5) {
+ * >             printf("Too hot! (%f)", temperature.read());             
+ * >         }
+ * >     }
+ * > }
  */
 class AnalogIn :  public Base {
 
 public:
 
-	/* Group: Configuration Methods */	
-	
-	/* Constructor: AnalogIn
-	 *  Create an AnalogIn connected to the specified pin
-	 *
-	 * Variables:
-	 *  pin - AnalogIn pin to connect to (15-20)
-	 */
+    /* Constructor: AnalogIn
+     *  Create an AnalogIn, connected to the specified pin
+     *
+     * Variables:
+     *  pin - AnalogIn pin to connect to (15 - 20)
+     *  name - (optional) A string to identify the object
+     */
 	AnalogIn(int pin, const char *name = NULL);
 	
-	/* Group: Access Methods */
-		
-	/* Function: read
-	 *  Read the input, measured as a percentage (float)
-	 *
-	 * Variables:
-	 *  returns - A floating-point value representing the current input voltage, 
-	 *      measured as a percentage. The returned value will lie between
-	 *      0.0f (representing 0v / 0%) and 1.0f (representing 3.3v / 100%).
-	 */
-    float read();
-    
-	/* Function: read_v
-	 *  Read the input, measured in volts (float)
-	 * 
-	 * Variables:
-	 *  returns - A floating-point value representing the current input voltage, 
-	 *      measured in volts. The returned value will lie between
-	 *      0.0f (representing 0v / 0%) and 3.3f (representing 3.3v / 100%).
-	 */
+    /* Function: read
+     * Read the input voltage, represented as a float in the range [0.0, 1.0]
+     *
+     * Variables:
+     *  returns - A floating-point value representing the current input voltage,
+     *            measured as a percentage (0.0 = 0v, 1.0 = 3.3v)
+     */
+    float read();	
+
+    /* Function: read_u16
+     *  Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
+     *
+     * Variables:
+     *  returns - 16-bit unsigned short representing the current input voltage,
+     *            normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v)
+     */
+    unsigned short read_u16();
+
+    // functions to be removed in time...
     float read_v();
-    
-    /* Function: read_mv
-     *  Read the input, measured in milli-volts (int)
-	 *
-	 * Variables:
-	 *  returns - An integer value representing the current input voltage, 
-	 *      measured in milli-volts. The returned value will lie between
-	 *      0 (representing 0v / 0%) and 3300 (representing 3.3v / 100%).
-	 */
     int read_mv();
-    
-	/* Group: Access Methods Shorthand */
 	
     /* Function: operator float
-     *  A shorthand for <read>
+     *  An operator shorthand for <read()>
+     *
+     * The float() operator can be used as a shorthand for <read()> to simplify common code sequences
+     *
+     * Example:
+     * > float x = volume.read();
+     * > float x = volume;
+     * >
+     * > if(volume.read() > 0.25) { ... }
+     * > if(volume > 0.25) { ... }
      */
 	operator float();
 
-    virtual const struct rpc_method *rpc_methods();
-	
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 protected:
 	
 	int _id;
--- a/AnalogOut.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/AnalogOut.h	Thu Jan 22 18:32:40 2009 +0000
@@ -1,6 +1,7 @@
 /* mbed Microcontroller Library - AnalogOut
- * Copyright (c) 2007-2008, sford
- */
+ * Copyright (c) 2006-2009 ARM Limited. All rights reserved.
+ * sford
+ */ 
  
 #ifndef MBED_ANALOGOUT_H
 #define MBED_ANALOGOUT_H
@@ -16,8 +17,6 @@
 
 public:
 
-	/* Group: Configuration Methods */
-	
 	/* Constructor: AnalogOut
 	 *  Create an AnalogOut connected to the specified pin
 	 * 
@@ -26,8 +25,6 @@
 	 */
 	AnalogOut(int pin, const char *name = NULL);
 	
-	/* Group: Access Methods */
-		
 	/* Function: write
 	 *  Set the output voltage, specified as a percentage (float)
 	 *
@@ -39,26 +36,16 @@
 	 */
     void write(float percent);
     
-	/* Function: write_v
-	 *  Set the output voltage, specified in volts (float)
-	 *
-	 * Variables:
-	 *  v - A floating-point value representing the output voltage, 
-	 *    specified in volts. The value should lie between
-	 *    0.0f (representing 0v / 0%) and 3.3f (representing 3.3v / 100%).
-	 *    Values outside this range will be saturated to 0.0f or 3.3f.	 
-	 */	
+    /* Function: write_u16
+     *  Set the output voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
+     *
+     * Variables:
+     *  value - 16-bit unsigned short representing the output voltage,
+     *            normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v)
+     */
+    void write_u16(unsigned short value);
+
     void write_v(float v);
-
-	/* Function: write_mv
-	 *  Set the output voltage, specified in mili-volts (int)
-	 *
-	 * Variables:
-	 *  mv - An integer value representing the output voltage, 
-	 *    specified in milli-volts. The value should lie between
-	 *    0 (representing 0v / 0%) and 3300 (representing 3.3v / 100%).
-	 *    Values outside this range will be saturated to 0 or 3300.	 
-	 */	
     void write_mv(int mv);
     
     /* Function: read
@@ -74,21 +61,20 @@
 	 */	
     float read();
 
-   	/* Group: Access Method Shorthand */ 
-
     /* Function: operator=
-     *  A shorthand for <write>
+     *  An operator shorthand for <write()>
      */
 	AnalogOut& operator= (float percent);
 	AnalogOut& operator= (AnalogOut& rhs);
 
     /* Function: operator float()
-	 *  A shorthand for <read>
+	 *  An operator shorthand for <read()>
 	 */	
 	operator float();
 
-    virtual const struct rpc_method *rpc_methods();
-		
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 };
 
 }
--- a/Base.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/Base.h	Thu Jan 22 18:32:40 2009 +0000
@@ -10,6 +10,17 @@
 
 namespace mbed {
 
+struct rpc_function {
+    const char *name;
+    void (*caller)(const char*, char*);
+};
+
+struct rpc_class {
+    const char *name;
+    const rpc_function *static_functions;
+    struct rpc_class *next;
+};
+
 /* Class Base
  *  The base class for most things
  */
@@ -52,24 +63,27 @@
      */
     virtual bool rpc(const char *method, const char *arguments, char *result);	
 
-    /* Function rpc_method
+    /* Function get_rpc_methods
      *  Returns a pointer to an array describing the rpc methods
-     *  supported by this object, terminated by RPC_METHOD_END.
+     *  supported by this object, terminated by either
+     *  RPC_METHOD_END or RPC_METHOD_SUPER(Superclass).
      *
      * Example
      *
      * > class Example : public Base {
      * >   int foo(int a, int b) { return a + b; }
-     * >   virtual const struct rpc_method *rpc_methods() {
+     * >   virtual const struct rpc_method *get_rpc_methods() {
      * >     static const rpc_method rpc_methods[] = {
      * >       { "foo", generic_caller<int, Example, int, int, &Example::foo> },
-     * >       RPC_METHOD_END
+     * >       RPC_METHOD_SUPER(Base)
      * >     };
      * >     return rpc_methods;
      * >   }
      * > };
      */
-    virtual const struct rpc_method *rpc_methods();
+    virtual const struct rpc_method *get_rpc_methods();
+
+    static struct rpc_class *get_rpc_class();
 
     /* Function rpc
      *  Use the lookup function to lookup an object and, if
@@ -96,6 +110,81 @@
     static Base *_head;
     Base *_next;
     const char *_name;
+    bool _from_construct;
+
+private:
+
+    static rpc_class *_classes;
+
+    void delete_self();
+    static void list_objs(const char *arguments, char *result);
+    static void clear(const char*,char*);
+
+    static char *new_name(Base *p);
+
+public:
+
+    /* Function add_rpc_class
+     *  Add the class to the list of classes which can have static
+     *  methods called via rpc (the static methods which can be called
+     *  are defined by that class' get_rpc_class() static method).
+     */
+    template<class C>
+    static void add_rpc_class() {
+        rpc_class *c = C::get_rpc_class();
+        c->next = _classes;
+        _classes = c;
+    }
+
+    template<class C> 
+    static const char *construct() {
+        Base *p = new C();
+        p->_from_construct = true;
+        if(p->_name==NULL) {
+            p->register_object(new_name(p));
+        }
+        return p->_name;
+    }
+
+    template<class C, typename A1> 
+    static const char *construct(A1 arg1) {
+        Base *p = new C(arg1);
+        p->_from_construct = true;
+        if(p->_name==NULL) {
+            p->register_object(new_name(p));
+        }
+        return p->_name;
+    }
+
+    template<class C, typename A1, typename A2> 
+    static const char *construct(A1 arg1, A2 arg2) {
+        Base *p = new C(arg1,arg2);
+        p->_from_construct = true;
+        if(p->_name==NULL) {
+            p->register_object(new_name(p));
+        }
+        return p->_name;
+    }
+
+    template<class C, typename A1, typename A2, typename A3> 
+    static const char *construct(A1 arg1, A2 arg2, A3 arg3) {
+        Base *p = new C(arg1,arg2,arg3);
+        p->_from_construct = true;
+        if(p->_name==NULL) {
+            p->register_object(new_name(p));
+        }
+        return p->_name;
+    }
+
+    template<class C, typename A1, typename A2, typename A3, typename A4> 
+    static const char *construct(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
+        Base *p = new C(arg1,arg2,arg3,arg4);
+        p->_from_construct = true;
+        if(p->_name==NULL) {
+            p->register_object(new_name(p));
+        }
+        return p->_name;
+    }
 
 };
 
--- a/BusIn.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/BusIn.h	Thu Jan 22 18:32:40 2009 +0000
@@ -34,6 +34,8 @@
           int p8 = NOT_CONNECTED, int p9 = NOT_CONNECTED, int p10 = NOT_CONNECTED, int p11 = NOT_CONNECTED,
           int p12 = NOT_CONNECTED, int p13 = NOT_CONNECTED, int p14 = NOT_CONNECTED, int p15 = NOT_CONNECTED, 
           const char *name = NULL);
+
+    BusIn(int pins[16], const char *name = NULL);
 		
 	virtual ~BusIn();
 	
@@ -54,11 +56,14 @@
 	 */
 	operator int();
 
-    virtual const struct rpc_method *rpc_methods();
-		
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 protected:
 	
 	DigitalIn* _pin[16];
+
+        static void construct(const char *arguments, char *res);
 	
 };
 
--- a/BusOut.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/BusOut.h	Thu Jan 22 18:32:40 2009 +0000
@@ -35,6 +35,8 @@
            int p12 = NOT_CONNECTED, int p13 = NOT_CONNECTED, int p14 = NOT_CONNECTED, int p15 = NOT_CONNECTED, 
            const char *name = NULL);
 
+    BusOut(int pins[16], const char *name = NULL);
+
 	virtual ~BusOut();
 
 	/* Group: Access Methods */
@@ -69,11 +71,14 @@
 	 */
 	operator int();
 
-    virtual const struct rpc_method *rpc_methods();
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
 
 protected:
 
 	DigitalOut* _pin[16];
+
+        static void construct(const char *arguments, char *res);
 			
 };
 
--- a/Debug.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/Debug.h	Thu Jan 22 18:32:40 2009 +0000
@@ -5,63 +5,36 @@
 #ifndef MBED_DEBUG_H
 #define MBED_DEBUG_H
 
+#include <cstdio>
+#include <cstdlib>
+#define __ASSERT_MSG
+#include <assert.h>
+
 namespace mbed {
 
 /* Section: debug
  *  Error reporting and debugging functions 
  */
 
+void mbedinfo(std::FILE *fp = stdout);
+
+#define error(...) (std::fprintf(stderr, __VA_ARGS__), std::abort())
+
 // As seen by user, for documentation purposes only
 #if 0 
-/* Function: ERROR
+/* Function: error
  *  Report a fatal runtime error. Attempts to report the specified error message through the
  * USB serial port, then dies with a fatal runtime error (siren lights)
  *
  * Variables:
  *  format - printf-style format string, followed by associated variables
  */
-void ERROR(const char* format, ...);
+void error(const char* format, ...);
 #endif 
 
-#define ERROR(FMT, ...) mbed_error(__FILE__, __LINE__, FMT, ##__VA_ARGS__) 
-void mbed_error(const char* file, int line, const char* fmt=0, ...) __attribute__((noreturn));
-
-// Internal use for "official" errors
-void mbed_error(const char* file, int line, int code, const char* fmt=0, ...) __attribute__((noreturn));
-
-// As seen by user, for documentation purposes only
-#if 0
-/* Function: ASSERT
- *  Assert a condition is true, and report a fatal runtime error on failure. If
- * the condition is true (non-zero), the function simply returns. If the
- * condition is false (0), it attempts to report the specified error message through the
- * USB serial port, then dies with a fatal runtime error (siren lights)
- *
- * Variables:
- *  condition - The condition variable to be tested. 0 causes an error to be reported
- *  format - printf-style format string, followed by associated variables
- */
-void ASSERT(int condition, const char* fmt = 0, ...);
-#endif
-
-#define ASSERT(COND, ...) (COND ? (void)0 : mbed_error(__FILE__, __LINE__, ##__VA_ARGS__))
-
-// As seen by user, for documentation purposes only
-#if 0 
-/* Function: DEBUG
- *  Report a debug message. Attempts to report the specified 
- * debug message through the USB serial port.
- *
- * Variables:
- *  format - printf-style format string, followed by associated variables
- */
-void DEBUG(const char* format, ...);
-#endif
-
-// Actual macro and prototype
-#define DEBUG(...) mbed_debug(__FILE__, __LINE__, __VA_ARGS__)
-void mbed_debug(const char* file, int line, const char* format, ...);
-
+void ERROR(const char* format, ...);// __attribute__((deprecated));
+void ASSERT(int condition, const char* format = 0, ...);// __attribute__((deprecated));
+void DEBUG(const char* format, ...);// __attribute__((deprecated));
 
 /* Function: DEBUG_LED1
  *  Set the state of LED1
--- a/DebugTracer.h	Thu Nov 27 16:23:24 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/* mbed Microcontroller Library - DebugTracer
- * Copyright (c) 2007-2008, sford
- */
-
-#ifndef MBED_DEBUGTRACER_H
-#define MBED_DEBUGTRACER_H
-
-#include "Base.h"
-#include <cstdio>
-
-#define MAX_TRACER_DEPTH 32
-
-namespace mbed {
-
-//#define METHOD(name) 	
-//#define FUNCTION(name)	
-#define METHOD(name) 	DebugTracer _tracer_instance(name, this)
-#define FUNCTION(name)	DebugTracer _tracer_instance(name)
-
-/* Class DebugTracer
- *  A code instrumentation utility
- * 
- * This object adds a function name or methodname/object instance 
- * to a stack on construction, and removes it on destruvtion. It 
- * can therefore be used at the start of functions to trace entry, exit
- * and the call graph/stack.
- *
- * Wrapped in macros and with altered implementations, the same instrumentation can:
- *  - be #defined away to nothing
- *  - provide the call stack on encountering an error
- *  - trace the runtime call graph (for the whole program run, or programatically on/off) 
- *
- *
- * Example
- *
- * Function example
- * > void foo(int x) { FUNCTION("foo");
- * >    // normal code
- *
- * Class method example
- * > void Foo::bar(int x) { METHOD("bar");
- * >     // normal code
- */
-class DebugTracer {
-
-public:
-
-	/* Constructor DebugTracer
-	 *  Record the method and object instance it is called on
-	 *  to the call stack
-	 */
-	DebugTracer(char* method, Base* object = 0) {
-		_functions[_depth] = method;
-		_objects[_depth] = object;
-		_depth++;
-	}
-	
-	/* Destructor ~DebugTracer
-	 *  Pop from the call stack
-	 */
-	~DebugTracer() {
-		_depth--;
-	}
-
-	static void stack() {
-		std::fprintf(stderr, "Trace (depth = %d):\n", _depth);
-		for(int i=0; i<_depth; i++) { 
-			// indent
-			for(int j=0; j<i; j++) {
-				std::fprintf(stderr, "  ");
-			}
-			if(_objects[i]) {
-//				std::fprintf(stderr, "%s::", _objects[i]->type());
-			}
-			std::fprintf(stderr, "%s\n", _functions[i]);
-		}
-	}
-
-	static int enabled;
-	
-protected:
-	
-	static Base* _objects[MAX_TRACER_DEPTH];
-	static char* _functions[MAX_TRACER_DEPTH];
-	static int _depth;
-
-};
-
-} // namespace mbed
-
-#endif
-
--- a/DigitalIn.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/DigitalIn.h	Thu Jan 22 18:32:40 2009 +0000
@@ -1,53 +1,53 @@
 /* mbed Microcontroller Library - DigitalIn
- * Copyright (c) 2007-2008, sford
- */
+ * Copyright (c) 2006-2009 ARM Limited. All rights reserved.
+ * sford
+ */ 
  
 #ifndef MBED_DIGITALIN_H
 #define MBED_DIGITALIN_H
 
 #include "Base.h"
 #include "LPC2300.h"
-
-typedef void (*VoidFunctionPointer)(void);
+#include "FunctionPointer.h"
 
 namespace mbed {
 
 /* Class: DigitalIn
  *  A digital input, used for reading the state of a pin
+ *
+ * Example:
+ * > // Flash an LED while a DigitalIn is true
+ * >
+ * > #include "mbed.h"
+ * >
+ * > DigitalIn enable(5);
+ * > DigitalOut led(1);
+ * >
+ * > int main() {
+ * >     while(1) {
+ * >         if(enable) {
+ * >             led = !led;
+ * >         }
+ * >         wait(0.25);
+ * >     }
+ * > }
+ *
+ * Implementation Note:
+ *  pin 19 and 20 can not be used with the rise/fall methods
  */
- 
 class DigitalIn : public Base {
 
 public:
 
-	/* Group: Configuration Methods */
-	
 	/* Constructor: DigitalIn
 	 *  Create a DigitalIn connected to the specified pin
 	 *
 	 * Variables:
 	 *  pin - DigitalIn pin to connect to (5-30)
+     *  name - (optional) A string to identify the object
 	 */
 	DigitalIn(int pin, const char *name = NULL);
 
-	/* Function: rise
-	 *  Attach a function to call when a rising edge occurs on the input
-	 *
-	 * Variables:
-	 *  fptr - A pointer to a void function, or 0 to set as none
-	 */
-	void rise(void (*fptr)(void));
-
-	/* Function: fall
-	 *  Attach a function to call when a falling edge occurs on the input
-	 *
-	 * Variables:
-	 *  fptr - A pointer to a void function, or 0 to set as none
-	 */
-	void fall(void (*fptr)(void));
-		
-   	/* Group: Access Methods */ 
-
 	/* Function: read
 	 *  Read the input, represented as 0 or 1 (int)
 	 *
@@ -56,28 +56,71 @@
 	 *      0 for logical 0 (0v) and 1 for logical 1 (3.3v)
 	 */	
     int read();
-    
+ 
+	/* Function: rise
+	 *  Attach a function to call when a rising edge occurs on the input
+	 *
+	 * Variables:
+	 *  fptr - A pointer to a void function, or 0 to set as none
+	 */
+	void rise(void (*fptr)(void));
+
+	/* Function: rise
+	 *  Attach a member function to call when a rising edge occurs on the input
+     *     
+     * Variables:
+     *  tptr - pointer to the object to call the member function on
+     *  mptr - pointer to the member function to be called
+     */
+    template<typename T>
+    void rise(T* tptr, void (T::*mptr)(void)) {
+		_rise.attach(tptr, mptr);
+		setup_interrupt(1, 1);
+    }
 
-	/* Group: Access Method Shorthand */
+	/* Function: fall
+	 *  Attach a function to call when a falling edge occurs on the input
+	 *
+	 * Variables:
+	 *  fptr - A pointer to a void function, or 0 to set as none
+	 */
+	void fall(void (*fptr)(void));
 
+	/* Function: fall
+	 *  Attach a member function to call when a falling edge occurs on the input
+     *     
+     * Variables:
+     *  tptr - pointer to the object to call the member function on
+     *  mptr - pointer to the member function to be called
+     */
+    template<typename T>
+    void fall(T* tptr, void (T::*mptr)(void)) {
+		_fall.attach(tptr, mptr);
+		setup_interrupt(0, 1);
+	}
+		
     /* Function: operator int()
-     *  A shorthand for <read>
+     *  An operator shorthand for <read()>
      */
 	operator int();
  	
- 	static void _irq(); // Called on a GPIO interrupt
+ 	// interrupt
+ 	static void _irq(); 
+	static DigitalIn *_irq_objects[48];
 
-    virtual const struct rpc_method *rpc_methods();
- 	
+	// rpc
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 protected:
 
 	LPC2300::GPIORF* _rf;
 	unsigned int _mask;
 	int _id;
 
-	static VoidFunctionPointer _rising[48];
-	static VoidFunctionPointer _falling[48];
-
+	void setup_interrupt(int rising, int enable);
+	FunctionPointer _rise;
+	FunctionPointer _fall;
 };
 
 }
--- a/DigitalOut.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/DigitalOut.h	Thu Jan 22 18:32:40 2009 +0000
@@ -47,7 +47,8 @@
 	 */
     int read();
 
-    virtual const struct rpc_method *rpc_methods();
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
 
    	/* Group: Access Method Shorthand */
    	 
--- a/FileSystemLike.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/FileSystemLike.h	Thu Jan 22 18:32:40 2009 +0000
@@ -10,6 +10,7 @@
 # define O_WRONLY 1
 # define O_RDWR   2
 # define O_CREAT  0x0200
+# define O_TRUNC  0x0400
 # define O_APPEND 0x0008
 #else
 # include <sys/fcntl.h>
@@ -39,8 +40,8 @@
      *
      * Variables
      *  filename - The name of the file to open.
-     *  flags - One of O_RDONLY, O_WRONLY, or O_RDWR, possibly OR'd
-     *    with O_CREAT or O_APPEND.
+     *  flags - One of O_RDONLY, O_WRONLY, or O_RDWR, OR'd with
+     *    zero or more of O_CREAT, O_TRUNC, or O_APPEND.
      *  returns - A pointer to a FileHandle object representing the
      *   file on success, or NULL on failure.
      */
--- a/LPC2300_MAP.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/LPC2300_MAP.h	Thu Jan 22 18:32:40 2009 +0000
@@ -35,7 +35,8 @@
 
 #elif TARGET_PHAT40
 
-enum {
+enum {  
+  NC = 0,   // Not Connected 
 	LED1 = 32,
 	LED2 = 33,
 	LED3 = 34,
@@ -65,8 +66,10 @@
 	unsigned char function;	// Pin function
 };
 
+/* returns NOT_AVAILABLE if no port matches the pin */
 int pin_to_port(int pin);
 
+/* returns NULL if no map matches the pin */
 const PortMap* get_port_map(const PortMap* map, int pin);
 
 extern const PortMap ADC_PORTMAP[];
--- a/PwmOut.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/PwmOut.h	Thu Jan 22 18:32:40 2009 +0000
@@ -11,13 +11,14 @@
 
 /* Class: PwmOut
  *  A pulse-width modulation digital output
+ *
+ * Implementation Note:
+ *  The period is is common to all PwmOut's, so changing it on one PwmOut will change them all!
  */
 class PwmOut : public Base {
 
 public:
 
-	/* Group: Configuration Methods */
-	
 	/* Constructor: PwmOut
 	 *  Create a PwmOut connected to the specified pin
 	 *
@@ -26,8 +27,6 @@
 	 */	
 	PwmOut(int pin, const char *name = NULL);
 
-	/* Group: Access Methods (Analog-like) */
-		
 	/* Function: write
 	 *  Set the ouput duty-cycle, specified as a percentage (float)
 	 *
@@ -39,27 +38,6 @@
 	 */
     void write(float percent);
 
-	/* Function: write_v
-	 *  Set the output duty-cycle, specified in volts (float)
-	 *
-	 * Variables:
-	 *  v - A floating-point value representing the output duty-cycle, 
-	 *    specified in volts. The value should lie between
-	 *    0.0f (representing 0v / 0% on) and 3.3f (representing 3.3v / 100% on).
-	 *    Values outside this range will be saturated to 0.0f or 3.3f.	 
-	 */	
-	void write_v(float v);
-
-	/* Function: write_mv
-	 *  Set the output duty-cycle, specified in mili-volts (int)
-	 *
-	 * Variables:
-	 *  mv - An integer value representing the output duty-cycle, 
-	 *    specified in milli-volts. The value should lie between
-	 *    0 (representing 0v / 0% on) and 3300 (representing 3.3v / 100% on).
-	 *    Values outside this range will be saturated to 0 or 3300.	 
-	 */	
-	void write_mv(int mv);
 
 	/* Function: read
 	 *  Return the current output duty-cycle setting, measured as a percentage (float)
@@ -73,62 +51,55 @@
 	 *  This value may not match exactly the value set by a previous <write>.
 	 */	
     float read();
-
-	/* Group: Access Methods (Pulse-width) */
 	
 	/* Function: period
 	 *  Set the PWM period, specified in seconds (float)
-	 *
-	 * Note:
-	 *  This is common to all PwmOut's, so changing it on one will change them all
 	 */
 	void period(float seconds);
 
+	/* Function: period_ms
+	 *  Set the PWM period, specified in milli-seconds (int)
+	 */
+	void period_ms(int ms);
+
+	/* Function: period_us
+	 *  Set the PWM period, specified in micro-seconds (int)
+	 */
+	void period_us(int us);
+
 	/* Function: pulsewidth
 	 *  Set the PWM pulsewidth, specified in seconds (float)
 	 */	
 	void pulsewidth(float seconds);
 		
-	/* Function: period_ms
-	 *  Set the PWM period, specified in milli-seconds (int)
-	 *
-	 * Note:
-	 *  This is common to all PwmOut's, so changing it on one will change them all
-	 */
-	void period_ms(int ms);
-
 	/* Function: pulsewidth_ms
 	 *  Set the PWM pulsewidth, specified in milli-seconds (int)
 	 */	
 	void pulsewidth_ms(int ms);
 	
-	/* Function: period_us
-	 *  Set the PWM period, specified in micro-seconds (int)
-	 *
-	 * Note:
-	 *  This is common to all PwmOut's, so changing it on one will change them all
-	 */
-	void period_us(int us);
-	
 	/* Function: pulsewidth_us
 	 *  Set the PWM pulsewidth, specified in micro-seconds (int)
 	 */	
 	void pulsewidth_us(int us);
 
-	/* Group: Access Method Shorthand */
-
 	/* Function: operator=
-	 *  A shorthand for <write>
+	 *  A operator shorthand for <write()>
 	 */
 	PwmOut& operator= (float percent);
 	PwmOut& operator= (PwmOut& rhs);
 
 	/* Function: operator float()
-	 *  A shorthand for <read>
+	 *  An operator shorthand for <read()>
 	 */
 	operator float();
 
-    virtual const struct rpc_method *rpc_methods();
+	// functions to be dropped in time...
+	void write_v(float v);
+	void write_mv(int mv);
+
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 	
 protected:
 
--- a/SPI.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/SPI.h	Thu Jan 22 18:32:40 2009 +0000
@@ -1,7 +1,8 @@
 /* mbed Microcontroller Library - SPI
- * Copyright (c) 2007-2008, sford
+ * Copyright (c) 2006-2009 ARM Limited. All rights reserved. 
+ * sford
  */
- 
+
 #ifndef MBED_SPI_H
 #define MBED_SPI_H
 
@@ -12,13 +13,27 @@
 
 /* Class: SPI
  *  A SPI Master, used for communicating with SPI slave devices
+ *
+ * The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
+ *
+ * Most SPI devices will also require Chip Select and Reset signals. These
+ * can be controlled using <DigitalOut> pins
+ *
+ * Example:
+ * > // Send a byte to a SPI slave, and record the response
+ * >
+ * > #include "mbed.h"
+ * >
+ * > SPI device(5, 6, 7); // mosi, miso, sclk
+ * >
+ * > int main() {
+ * >     int response = device.write(0xFF);
+ * > }
  */ 
 class SPI : public Base {
 
 public:
 
-	/* Group: Configuration Methods */
-	
 	/* Constructor: SPI
 	 *  Create a SPI master connected to the specified pins
 	 *
@@ -26,21 +41,33 @@
 	 *  mosi - SPI Master Out, Slave In pin
 	 *  miso - SPI Master In, Slave Out pin
 	 *  sclk - SPI Clock pin
+     *  name - (optional) A string to identify the object     
      *
 	 * Pin Options:
 	 *  (5, 6, 7) or (11, 12, 13)
+	 *
+	 *  mosi and miso can each be specfied as NC (not connected) e.g. (5, NC, 7)
 	 */
 	SPI(int mosi, int miso, int sclk, const char *name = NULL);
 	
 	/* Function: format
-	 *  Set the transmission format
+	 *  Configure the data transmission format
 	 *
 	 * Variables:
-	 *  bits - Number of bits per frame (4 - 16, default = 8)
-	 *  polarity - Clock polarity, 0 = Steady state low (default), 1 = Steady state high  
-	 *  phase - Clock phase, 0 = Capture on first edge (default), 1 = Capture on second edge
+	 *  bits - Number of bits per SPI frame (4 - 16)
+	 *  mode - Clock polarity and phase mode (0 - 3)
+     *
+ 	 * > mode | POL PHA 
+     * > -----+--------	 
+     * >   0  |  0   0 
+	 * >   1  |  0   1
+     * >   2  |  1   0 
+	 * >   3  |  1   1
 	 */
-	void format(int bits = 8, int polarity = 0, int phase = 0);
+	void format(int bits, int mode = 0);
+
+    // old one, to be removed over time...
+	void format(int bits, int polarity, int phase) __attribute__((deprecated));
 	
 	/* Function: frequency
 	 *  Set the bus clock frequency
@@ -50,8 +77,6 @@
 	 */
 	void frequency(int hz = 1000000);
 	
-	/* Group: Access Methods */
-		
 	/* Function: write
 	 *  Write to the SPI Slave and return the response
 	 *
@@ -61,6 +86,9 @@
 	 */
   	int write(int value);
 
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 protected:
 
 	void configure();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SPI3.h	Thu Jan 22 18:32:40 2009 +0000
@@ -0,0 +1,100 @@
+/* mbed Microcontroller Library - SPI3
+ * Copyright (c) 2007-2009, sford
+ */
+ 
+#ifndef MBED_SPI3_H
+#define MBED_SPI3_H
+
+#include "Base.h"
+#include "LPC2300.h"
+
+namespace mbed {
+
+/* Class: SPI3
+ *  A SPI Master, used for communicating with 3-wire SPI slave devices 
+ *
+ *  3-wire SPI devices use the same line for input an output, and should be connected to both
+ *  the mosi and miso pins on the mbed Microcontroller
+ */ 
+
+class SPI3 : public Base {
+
+public:
+	
+	/* Constructor: SPI3
+	 *  Create a 3-wire SPI master connected to the specified pins
+	 *
+	 * Variables:
+	 *  mosi - SPI Master Out, Slave In pin
+	 *  miso - SPI Master In, Slave Out pin
+	 *  sclk - SPI Clock pin
+     *
+	 * Pin Options:
+	 *  (5, 6, 7) or (11, 12, 13)
+	 */
+	SPI3(int mosi, int miso, int sclk, const char *name=NULL);
+	
+	/* Function: format
+	 *  Configure the data transmission format
+	 *
+	 * Variables:
+	 *  bits - Number of bits per SPI frame (4 - 16, default = 8)
+	 *  mode - Clock polarity and phase mode (0 - 3, default = 0)
+     *
+ 	 * > mode | POL PHA 
+     * > -----+--------	 
+     * >   0  |  0   0 
+	 * >   1  |  0   1
+     * >   2  |  1   0 
+	 * >   3  |  1   1
+	 */
+	void format(int bits = 8, int mode = 0);
+
+	// old one...
+	void format(int bits = 8, int polarity = 0, int phase = 0);
+	
+	/* Function: frequency
+	 *  Set the bus clock frequency
+	 *
+	 * Variables:
+	 *  hz - SCLK frequency in hz (default = 1MHz)
+	 */
+	void frequency(int hz = 1000000);
+			
+	/* Function: write
+	 *  Set the direction to output and write to the SPI Slave
+	 *
+     * Variables:
+     *  value - Data to be sent to the SPI slave
+	 */
+  	void write(int value);
+
+	/* Function: read
+ 	 *  Set the direction to input, read from the SPI Slave
+	 *
+     * Variables:
+     *  returns - Response from the SPI slave
+	 */
+	int read();
+	
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
+protected:
+
+	void configure();
+	
+	int _id;
+
+	int _uid;
+	static int _uidcounter;
+		
+	int _bits, _polarity, _phase, _hz;
+	static int _config[2];	
+ 	const LPC2300::PortMap*  mosi_portmap; 
+};
+
+}
+
+#endif
+
--- a/Serial.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/Serial.h	Thu Jan 22 18:32:40 2009 +0000
@@ -16,8 +16,6 @@
 
 public:
 
-	/* Group: Configuration Methods */
-	 
 	/* Constructor: Serial
 	 *  Create a Serial port, connected to the specified transmit and receive pins
 	 *
@@ -26,7 +24,9 @@
 	 *  rx - Receive pin
 	 *
 	 * Pin Options:
-	 *  (9, 10) or (13, 14) or (28, 27)
+	 *  (USBTX, USBRX) or (9, 10) or (13, 14) or (28, 27)
+	 *
+	 *  Either tx or rx may be specified as NC (not connected) e.g. (9, NC)
      */
 	Serial(int tx, int rx, const char *name = NULL);
 
@@ -59,8 +59,6 @@
 	void format(int bits, int parity, int stop); 
 
 	
-	/* Group: Access Methods */
-
 #if 0 // Inhereted from Stream, for documentation only
 
 	/* Function: putc
--- a/Timer.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/Timer.h	Thu Jan 22 18:32:40 2009 +0000
@@ -56,10 +56,13 @@
 
 	int slicetime();
 	
-int _running;          // whether the timer is running
+        int _running;          // whether the timer is running
 	unsigned int _start;   // the start time of the latest slice
 	int _time;             // any accumulated time from previous slices
 
+    virtual const struct rpc_method *get_rpc_methods();
+    static struct rpc_class *get_rpc_class();
+
 };
 
 }
Binary file mbed.ar has changed
--- a/mbed.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/mbed.h	Thu Jan 22 18:32:40 2009 +0000
@@ -4,6 +4,8 @@
 
 #ifndef MBED_H
 #define MBED_H
+
+#define MBED_LIBRARY_VERSION 6
  
 // Useful C libraries
 #include <stdio.h>
@@ -27,6 +29,7 @@
 #include "PwmOut.h"
 #include "Serial.h"
 #include "SPI.h"
+#include "SPI3.h"
 #include "I2C.h"
 
 // mbed Internal components
@@ -35,6 +38,8 @@
 #include "Ticker.h"
 #include "Timeout.h"
 #include "LocalFileSystem.h"
+#include "rpc.h"
+#include "rtc.h"
 
 using namespace mbed; 
 
--- a/rpc.h	Thu Nov 27 16:23:24 2008 +0000
+++ b/rpc.h	Thu Jan 22 18:32:40 2009 +0000
@@ -75,9 +75,13 @@
 /* floating types */
 
 template<> inline float parse_arg<float>(const char *arg, const char **next) {
-#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 310000
+#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 410000
     return strtof(arg,const_cast<char**>(next));
+#elif __ARMCC_VERSION >= 310000
+    /* bug in header means no using declaration for strtof */
+    return std::strtof(arg,const_cast<char**>(next));    
 #else
+    /* strtof not supported */
     return strtod(arg,const_cast<char**>(next));
 #endif
 }
@@ -90,6 +94,32 @@
     return strtod(arg,const_cast<char**>(next));
 }
 
+/* string */
+
+template<> inline char *parse_arg<char*>(const char *arg, const char **next) {
+    const char *ptr = arg;
+    while(*ptr != 0 && *ptr != ' ' && *ptr != ',') {
+        ptr++;
+    }
+    int len = ptr-arg;
+    char *p;
+    if(len==0) {
+        p = NULL;
+    } else {
+        p = new char[len+1];
+        memcpy(p, arg, len);
+        p[len] = 0;
+    }
+    if(next != NULL) {
+        *next = ptr;
+    }
+    return p;
+}
+
+template<> inline const char *parse_arg<const char*>(const char *arg, const char **next) {
+    return parse_arg<char*>(arg,next);
+}
+
 
 /* Function write_result
  *  Writes a value in to a result string in an appropriate manner
@@ -161,10 +191,35 @@
 }
 
 
-/* Function generic_caller
+/* string */
+
+template<> inline void write_result<char*>(char *val, char *result) {
+    strcpy(result, val);
+}
+
+template<> inline void write_result<const char*>(const char *val, char *result) {
+    strcpy(result, val);
+}
+
+
+inline const char *next_arg(const char* next) {
+    if(*next == ',' || *next == ' ') next++;
+    return next;
+}
+
+
+/* Function rpc_method_caller
+ */
+template<class T, void (T::*member)(const char *,char *)> 
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
+    (static_cast<T*>(this_ptr)->*member)(arguments,result); 
+}
+
+
+/* Function rpc_method_caller
  */
 template<class T, void (T::*member)()> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) { 
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) { 
     (static_cast<T*>(this_ptr)->*member)(); 
     if(result != NULL) {
     	result[0] = '\0';
@@ -172,14 +227,13 @@
 }
 
 
-/* Function generic_caller
+/* Function rpc_method_caller
  */
 template<class T, typename A1, void (T::*member)(A1)> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
-    const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
 
-    if(*next == ',' || *next == ' ') next++;
-    A1 arg1 = parse_arg<A1>(next,NULL);
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
 
     (static_cast<T*>(this_ptr)->*member)(arg1); 
     if(result != NULL) {
@@ -188,17 +242,14 @@
 }
 
 
-/* Function generic_caller
+/* Function rpc_method_caller
  */
 template<class T, typename A1, typename A2, void (T::*member)(A1,A2)> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
-    const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
 
-    if(*next == ',' || *next == ' ') next++;
-    A1 arg1 = parse_arg<A1>(next,&next);
-
-    if(*next == ',' || *next == ' ') next++;
-    A2 arg2 = parse_arg<A2>(next,NULL);
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
 
     (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
     if(result != NULL) {
@@ -207,10 +258,10 @@
 }
 
 
-/* Function generic_caller
+/* Function rpc_method_caller
  */
 template<typename R, class T, R (T::*member)()> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) { 
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) { 
     R res = (static_cast<T*>(this_ptr)->*member)();
     if(result != NULL) {
         write_result<R>(res, result);
@@ -218,14 +269,13 @@
 }
 
 
-/* Function generic_caller
+/* Function rpc_method_caller
  */
 template<typename R, class T, typename A1, R (T::*member)(A1)> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
-    const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
 
-    if(*next == ',' || *next == ' ') next++;
-    A1 arg1 = parse_arg<A1>(next,NULL);
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),NULL);
 
     R res = (static_cast<T*>(this_ptr)->*member)(arg1);
     if(result != NULL) {
@@ -234,17 +284,14 @@
 }
 
 
-/* Function generic_caller
+/* Function rpc_method_caller
  */
 template<typename R, class T, typename A1, typename A2, R (T::*member)(A1,A2)> 
-void generic_caller(Base *this_ptr, const char *arguments, char *result) {
-    const char *next = arguments;
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
 
-    if(*next == ',' || *next == ' ') next++;
-    A1 arg1 = parse_arg<A1>(next,&next);
-
-    if(*next == ',' || *next == ' ') next++;
-    A2 arg2 = parse_arg<A2>(next,NULL);
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
 
     R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2);
     if(result != NULL) {
@@ -252,13 +299,115 @@
     }
 }
 
+
+/* Function rpc_method_caller
+ */
+template<typename R, class T, typename A1, typename A2, typename A3, R (T::*member)(A1,A2,A3)> 
+void rpc_method_caller(Base *this_ptr, const char *arguments, char *result) {
+
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+    A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
+
+    R res = (static_cast<T*>(this_ptr)->*member)(arg1,arg2,arg3);
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, R (*func)()>
+void rpc_function_caller(const char *arguments, char *result) {
+    R res = (*func)();
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, R (*func)(A1)>
+void rpc_function_caller(const char *arguments, char *result) {
+    A1 arg1 = parse_arg<A1>(next_arg(arguments),NULL);
+    R res = (*func)(arg1);
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, R (*func)(A1,A2)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),NULL);
+
+    R res = (*func)(arg1,arg2);
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, typename A3, R (*func)(A1,A2,A3)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+    A3 arg3 = parse_arg<A3>(next_arg(next),NULL);
+
+    R res = (*func)(arg1,arg2,arg3);
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
+/* Function rpc_function caller
+ */
+template<typename R, typename A1, typename A2, typename A3, typename A4, R (*func)(A1,A2,A3,A4)>
+void rpc_function_caller(const char *arguments, char *result) {
+
+    const char *next = arguments;
+    A1 arg1 = parse_arg<A1>(next_arg(next),&next);
+    A2 arg2 = parse_arg<A2>(next_arg(next),&next);
+    A3 arg3 = parse_arg<A3>(next_arg(next),&next);
+    A4 arg4 = parse_arg<A4>(next_arg(next),NULL);
+
+    R res = (*func)(arg1,arg2,arg3,arg4);
+    if(result != NULL) {
+        write_result<R>(res, result);
+    }
+}
+
+
 struct rpc_method { 
     const char *name;
-    void (*caller)(Base*, const char*, char*);
+    typedef void (*caller_t)(Base*, const char*, char*);
+    typedef const struct rpc_method *(*super_t)(Base*);
+    union {
+        caller_t caller;
+        super_t super;
+    };
 };
-    
+
+template<class C>
+const struct rpc_method *rpc_super(Base *this_ptr) {
+    return static_cast<C*>(this_ptr)->C::get_rpc_methods();
+}
+
 #define RPC_METHOD_END { NULL, NULL }
-
+#define RPC_METHOD_SUPER(C) { NULL, (rpc_method::caller_t)(rpc_method::super_t)rpc_super<C> }
 
 /* Function rpc
  *  Parse a string describing a call and then do it
@@ -272,6 +421,7 @@
  */
 bool rpc(const char *buf, char *result = 0);
 
+
 } /* namespace mbed */
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rtc.h	Thu Jan 22 18:32:40 2009 +0000
@@ -0,0 +1,77 @@
+/* mbed Microcontroller Library - rtc
+ * Copyright (c) 2008, sford
+ */
+ 
+#ifndef MBED_RTC_TIME_H
+#define MBED_RTC_TIME_H
+
+#include <time.h>
+
+#ifdef __ARMCC_VERSION
+
+typedef unsigned long clockid_t;
+struct timespec {
+    time_t tv_sec;
+    long tv_nsec;
+};
+#define CLOCK_REALTIME (clockid_t)1
+
+#endif
+
+/* Section: rtc
+ *  Functions for manipulating the RTC (real-time clock).
+ */
+
+extern "C" {
+
+/* Function: time
+ *  Returns the number of seconds since the epoch (00:00:00 UTC,
+ *  January 1, 1970), and also stores the return value in the address
+ *  pointed to by timer if it is non-NULL.
+ */
+time_t time(time_t *timer);
+
+/* Function: time_str
+ *  Returns a pointer to a string representing the current time
+ *  in human readable form, as generated by ctime()
+ */
+char *time_str();
+
+/* Function: stime
+ *  Sets the current time, measured in seconds since the epoch, using
+ *  the value pointed to by timer.
+ */
+void stime(const time_t *timer);
+
+/* Function: set_time
+ *  Sets the current time, specifying year through to day
+ */
+void set_time(int year, int month, int day, int hour, int minute, int second);
+
+/* Function: clock_settime
+ *  Sets the time of the clock specified by clock_id, which must be
+ *  CLOCK_REALTIME, according to the value of *tp.
+ */
+int clock_settime(clockid_t clock_id, const struct timespec *tp);
+
+/* Function: clock_gettime
+ *  Sets *tp to be the current time of the clock specified by
+ *  clock_id, which must be CLOCK_REALTIME.
+ */
+int clock_gettime(clockid_t clock_id, struct timespec *tp);
+
+/* Function: clock_getres
+ *  Sets *tp to be the resolution of the clock specified by clock_id,
+ *  which must be CLOCK_REALTIME.
+ */
+int clock_getres(clockid_t clock_id, struct timespec *tp);
+
+/* Function: create_time
+ *  A convenience function for constructing a time_t value.
+ */
+time_t create_time(int year, int month, int day, int hour, int minute, int second);
+
+}
+
+#endif
+