Provides an API software interface to TIMER2 to control upto four stepper motors.

Dependents:   Steppermotor

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Mon May 02 10:02:18 2011 +0000
Child:
1:1030a91cbf4c
Commit message:

Changed in this revision

inc/IOmacros.h Show annotated file Show diff for this revision Revisions of this file
inc/SimpleStepperMbed.h Show annotated file Show diff for this revision Revisions of this file
inc/SimpleStepperOutput.h Show annotated file Show diff for this revision Revisions of this file
inc/SimpleSteppers.h Show annotated file Show diff for this revision Revisions of this file
inc/example1.h Show annotated file Show diff for this revision Revisions of this file
src/SimpleStepperInst.cpp Show annotated file Show diff for this revision Revisions of this file
src/SimpleSteppers.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/IOmacros.h	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,426 @@
+/****************************************************************************
+ * Product: LIB17 Open Source Library
+ *
+ *                    Steller Technologies Limited
+ *                    ----------------------------
+ *
+ * Copyright (C) 2002-2011 Steller Technologies Limited. All rights reserved.
+ *
+ * This software may be distributed and modified under the terms of the GNU
+ * General Public License version 2 (GPL) as published by the Free Software
+ * Foundation and appearing in the file GPL.TXT included in the packaging of
+ * this file. Please note that GPL Section 2[b] requires that all works based
+ * on this software must also be made publicly available under the terms of
+ * the GPL ("Copyleft").
+ *
+ * Alternatively, this software may be distributed and modified under the
+ * terms of Steller Technologies Limited commercial licenses, which expressly
+ * supersede the GPL and are specifically designed for licensees interested in
+ * retaining the proprietary status of their code.
+ *
+ ***************************************************************************/
+
+#ifndef AJK_LIB17_IOMACROS_H
+#define AJK_LIB17_IOMACROS_H
+
+#ifndef __LPC17xx_H__
+#include "LPC17xx.h"
+#endif
+
+#define PIN_PULLUP      0UL
+#define PIN_REPEAT      1UL
+#define PIN_NONE        2UL
+#define PIN_PULLDOWN    3UL
+
+/* p5 is P0.9 */
+#define p5_SEL_MASK     ~(3UL << 18)
+#define p5_SET_MASK     (1UL << 9)
+#define p5_CLR_MASK     ~(p5_SET_MASK)
+#define p5_AS_OUTPUT    LPC_PINCON->PINSEL0&=p5_SEL_MASK;LPC_GPIO0->FIODIR|=p5_SET_MASK
+#define p5_AS_INPUT     LPC_GPIO0->FIOMASK &= p5_CLR_MASK; 
+#define p5_SET          LPC_GPIO0->FIOSET = p5_SET_MASK
+#define p5_CLR          LPC_GPIO0->FIOCLR = p5_SET_MASK
+#define p5_IS_SET       (bool)(LPC_GPIO0->FIOPIN & p5_SET_MASK)
+#define p5_IS_CLR       !(p5_IS_SET)
+#define p5_MODE(x)      LPC_PINCON->PINMODE0&=p5_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<18)
+
+/* p6 is P0.8 */
+#define p6_SEL_MASK     ~(3UL << 16)
+#define p6_SET_MASK     (1UL <<  8)
+#define p6_CLR_MASK     ~(p6_SET_MASK)
+#define p6_AS_OUTPUT    LPC_PINCON->PINSEL0&=p6_SEL_MASK;LPC_GPIO0->FIODIR|=p6_SET_MASK
+#define p6_AS_INPUT     LPC_GPIO0->FIOMASK &= p6_CLR_MASK; 
+#define p6_SET          LPC_GPIO0->FIOSET = p6_SET_MASK
+#define p6_CLR          LPC_GPIO0->FIOCLR = p6_SET_MASK
+#define p6_IS_SET       (bool)(LPC_GPIO0->FIOPIN & p6_SET_MASK)
+#define p6_IS_CLR       !(p6_IS_SET)
+#define p6_MODE(x)      LPC_PINCON->PINMODE0&=p6_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<16)    
+
+/* p7 is P0.7 */
+#define p7_SEL_MASK     ~(3UL << 14)
+#define p7_SET_MASK     (1UL <<  7)
+#define p7_CLR_MASK     ~(p7_SET_MASK)
+#define p7_AS_OUTPUT    LPC_PINCON->PINSEL0&=p7_SEL_MASK;LPC_GPIO0->FIODIR|=p7_SET_MASK
+#define p7_AS_INPUT     LPC_GPIO0->FIOMASK &= p7_CLR_MASK; 
+#define p7_SET          LPC_GPIO0->FIOSET = p7_SET_MASK
+#define p7_CLR          LPC_GPIO0->FIOCLR = p7_SET_MASK
+#define p7_IS_SET       (bool)(LPC_GPIO0->FIOPIN & p7_SET_MASK)
+#define p7_IS_CLR       !(p7_IS_SET)
+#define p7_MODE(x)      LPC_PINCON->PINMODE0&=p7_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<14)    
+
+/* p8 is P0.6 */
+#define p8_SEL_MASK     ~(3UL << 12)
+#define p8_SET_MASK     (1UL <<  6)
+#define p8_AS_OUTPUT    LPC_PINCON->PINSEL0&=p8_SEL_MASK;LPC_GPIO0->FIODIR|=p8_SET_MASK
+#define p8_AS_INPUT     LPC_GPIO0->FIOMASK &= p8_CLR_MASK; 
+#define p8_SET          LPC_GPIO0->FIOSET = p8_SET_MASK
+#define p8_CLR          LPC_GPIO0->FIOCLR = p8_SET_MASK
+#define p8_IS_SET       (bool)(LPC_GPIO0->FIOPIN & p8_SET_MASK)
+#define p8_IS_CLR       !(p8_IS_SET)
+#define p8_MODE(x)      LPC_PINCON->PINMODE0&=p8_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<12)    
+
+/* p9 is P0.0 */
+#define p9_SEL_MASK     ~(3UL <<  0)
+#define p9_SET_MASK     (1UL <<  0)
+#define p9_CLR_MASK     ~(p9_SET_MASK)
+#define p9_AS_OUTPUT    LPC_PINCON->PINSEL0&=p9_SEL_MASK;LPC_GPIO0->FIODIR|=p9_SET_MASK
+#define p9_AS_INPUT     LPC_GPIO0->FIOMASK &= p9_CLR_MASK; 
+#define p9_SET          LPC_GPIO0->FIOSET = p9_SET_MASK
+#define p9_CLR          LPC_GPIO0->FIOCLR = p9_SET_MASK
+#define p9_IS_SET       (bool)(LPC_GPIO0->FIOPIN & p9_SET_MASK)
+#define p9_IS_CLR       !(p9_IS_SET)
+#define p9_MODE(x)      LPC_PINCON->PINMODE0&=p9_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<0)    
+
+/* p10 is P0.1 */
+#define p10_SEL_MASK    ~(3UL <<  2)
+#define p10_SET_MASK    (1UL <<  1)
+#define p10_CLR_MASK    ~(p10_SET_MASK)
+#define p10_AS_OUTPUT   LPC_PINCON->PINSEL0&=p10_SEL_MASK;LPC_GPIO0->FIODIR|=p10_SET_MASK
+#define p10_AS_INPUT    LPC_GPIO0->FIOMASK &= p10_CLR_MASK; 
+#define p10_SET         LPC_GPIO0->FIOSET = p10_SET_MASK
+#define p10_CLR         LPC_GPIO0->FIOCLR = p10_SET_MASK
+#define p10_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p10_SET_MASK)
+#define p10_IS_CLR      !(p10_IS_SET)
+#define p10_MODE(x)     LPC_PINCON->PINMODE0&=p10_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<2)
+
+/* p11 is P0.18 */
+#define p11_SEL_MASK    ~(3UL << 4)
+#define p11_SET_MASK    (1UL <<  18)
+#define p11_CLR_MASK    ~(p11_SET_MASK)
+#define p11_AS_OUTPUT   LPC_PINCON->PINSEL1&=p11_SEL_MASK;LPC_GPIO0->FIODIR|=p11_SET_MASK
+#define p11_AS_INPUT    LPC_GPIO0->FIOMASK &= p11_CLR_MASK; 
+#define p11_SET         LPC_GPIO0->FIOSET = p11_SET_MASK
+#define p11_CLR         LPC_GPIO0->FIOCLR = p11_SET_MASK
+#define p11_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p11_SET_MASK)
+#define p11_IS_CLR      !(p11_IS_SET)
+#define p11_MODE(x)     LPC_PINCON->PINMODE1&=p11_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<4)
+
+/* p12 is P0.17 */
+#define p12_SEL_MASK    ~(3UL << 2)
+#define p12_SET_MASK    (1UL << 17)
+#define p12_CLR_MASK    ~(p12_SET_MASK)
+#define p12_AS_OUTPUT   LPC_PINCON->PINSEL1&=p12_SEL_MASK;LPC_GPIO0->FIODIR|=p12_SET_MASK
+#define p12_AS_INPUT    LPC_GPIO0->FIOMASK &= p12_CLR_MASK; 
+#define p12_SET         LPC_GPIO0->FIOSET = p12_SET_MASK
+#define p12_CLR         LPC_GPIO0->FIOCLR = p12_SET_MASK
+#define p12_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p12_SET_MASK)
+#define p12_IS_CLR      !(p12_IS_SET)
+#define p12_MODE(x)     LPC_PINCON->PINMODE1&=p12_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<2)
+
+/* p13 is P0.15 */
+#define p13_SEL_MASK    ~(3UL << 30)
+#define p13_SET_MASK    (1UL << 15)
+#define p13_CLR_MASK    ~(p13_SET_MASK)
+#define p13_AS_OUTPUT   LPC_PINCON->PINSEL0&=p13_SEL_MASK;LPC_GPIO0->FIODIR|=p13_SET_MASK
+#define p13_AS_INPUT    LPC_GPIO0->FIOMASK &= p13_CLR_MASK; 
+#define p13_SET         LPC_GPIO0->FIOSET = p13_SET_MASK
+#define p13_CLR         LPC_GPIO0->FIOCLR = p13_SET_MASK
+#define p13_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p13_SET_MASK)
+#define p13_IS_CLR      !(p13_IS_SET)
+#define p13_MODE(x)     LPC_PINCON->PINMODE0&=p13_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<30)
+
+/* p14 is P0.16 */
+#define p14_SEL_MASK    ~(3UL << 0)
+#define p14_SET_MASK    (1UL << 16)
+#define p14_CLR_MASK    ~(p14_SET_MASK)
+#define p14_AS_OUTPUT   LPC_PINCON->PINSEL1&=p14_SEL_MASK;LPC_GPIO0->FIODIR|=p14_SET_MASK
+#define p14_AS_INPUT    LPC_GPIO0->FIOMASK &= p14_CLR_MASK; 
+#define p14_SET         LPC_GPIO0->FIOSET = p14_SET_MASK
+#define p14_CLR         LPC_GPIO0->FIOCLR = p14_SET_MASK
+#define p14_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p14_SET_MASK)
+#define p14_IS_CLR      !(p14_IS_SET)
+#define p14_MODE(x)     LPC_PINCON->PINMODE1&=p14_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<0)
+
+/* p15 is P0.23 */
+#define p15_SEL_MASK    ~(3UL << 14)
+#define p15_SET_MASK    (1UL << 23)
+#define p15_CLR_MASK    ~(p15_SET_MASK)
+#define p15_AS_OUTPUT   LPC_PINCON->PINSEL1&=p15_SEL_MASK;LPC_GPIO0->FIODIR|=p15_SET_MASK
+#define p15_AS_INPUT    LPC_GPIO0->FIOMASK &= p15_CLR_MASK; 
+#define p15_SET         LPC_GPIO0->FIOSET = p15_SET_MASK
+#define p15_CLR         LPC_GPIO0->FIOCLR = p15_SET_MASK
+#define p15_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p15_SET_MASK)
+#define p15_IS_CLR      !(p15_IS_SET)
+#define p15_MODE(x)     LPC_PINCON->PINMODE1&=p15_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<14)
+
+/* p16 is P0.24 */
+#define p16_SEL_MASK    ~(3UL << 16)
+#define p16_SET_MASK    (1UL <<  24)
+#define p16_CLR_MASK    ~(p16_SET_MASK)
+#define p16_AS_OUTPUT   LPC_PINCON->PINSEL1&=p16_SEL_MASK;LPC_GPIO0->FIODIR|=p16_SET_MASK
+#define p16_AS_INPUT    LPC_GPIO0->FIOMASK &= p16_CLR_MASK; 
+#define p16_SET         LPC_GPIO0->FIOSET = p16_SET_MASK
+#define p16_CLR         LPC_GPIO0->FIOCLR = p16_SET_MASK
+#define p16_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p16_SET_MASK)
+#define p16_IS_CLR      !(p16_IS_SET)
+#define p16_MODE(x)     LPC_PINCON->PINMODE1&=p16_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<16)
+
+/* p17 is P0.25 */
+#define p17_SEL_MASK    ~(3UL <<  18)
+#define p17_SET_MASK    (1UL <<  25)
+#define p17_CLR_MASK    ~(p17_SET_MASK)
+#define p17_AS_OUTPUT   LPC_PINCON->PINSEL1&=p17_SEL_MASK;LPC_GPIO0->FIODIR|=p17_SET_MASK
+#define p17_AS_INPUT    LPC_GPIO0->FIOMASK &= p17_CLR_MASK; 
+#define p17_SET         LPC_GPIO0->FIOSET = p17_SET_MASK
+#define p17_CLR         LPC_GPIO0->FIOCLR = p17_SET_MASK
+#define p17_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p17_SET_MASK)
+#define p17_IS_CLR      !(p17_IS_SET)
+#define p17_MODE(x)     LPC_PINCON->PINMODE1&=p17_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<18)
+
+/* p18 is P0.26 */
+#define p18_SEL_MASK    ~(3UL << 20)
+#define p18_SET_MASK    (1UL << 26)
+#define p18_CLR_MASK    ~(p18_SET_MASK)
+#define p18_AS_OUTPUT   LPC_PINCON->PINSEL1&=p18_SEL_MASK;LPC_GPIO0->FIODIR|=p18_SET_MASK
+#define p18_AS_INPUT    LPC_GPIO0->FIOMASK &= p18_CLR_MASK; 
+#define p18_SET         LPC_GPIO0->FIOSET = p18_SET_MASK
+#define p18_CLR         LPC_GPIO0->FIOCLR = p18_SET_MASK
+#define p18_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p18_SET_MASK)
+#define p18_IS_CLR      !(p18_IS_SET)
+#define p18_MODE(x)     LPC_PINCON->PINMODE1&=p18_SEL_MASK;LPC_PINCON->PINMODE1|=((x&0x3)<<20)
+
+/* p19 is P1.30 */
+#define p19_SEL_MASK    ~(3UL << 28)
+#define p19_SET_MASK    (1UL << 30)
+#define p19_AS_OUTPUT   LPC_PINCON->PINSEL3&=p19_SEL_MASK;LPC_GPIO1->FIODIR|=p19_SET_MASK
+#define p19_AS_INPUT    LPC_GPIO1->FIOMASK &= p19_CLR_MASK; 
+#define p19_SET         LPC_GPIO1->FIOSET = p19_SET_MASK
+#define p19_CLR         LPC_GPIO1->FIOCLR = p19_SET_MASK
+#define p19_IS_SET      (bool)(LPC_GPIO1->FIOPIN & p19_SET_MASK)
+#define p19_IS_CLR      !(p19_IS_SET)
+#define p19_MODE(x)     LPC_PINCON->PINMODE3&=p19_SEL_MASK;LPC_PINCON->PINMODE3|=((x&0x3)<<28)
+
+/* p20 is P1.31 */
+#define p20_SEL_MASK    ~(3UL << 30)
+#define p20_SET_MASK    (1UL << 31)
+#define p20_CLR_MASK    ~(p20_SET_MASK)
+#define p20_AS_OUTPUT   LPC_PINCON->PINSEL3&=p20_SEL_MASK;LPC_GPIO1->FIODIR|=p20_SET_MASK
+#define p20_AS_INPUT    LPC_GPIO1->FIOMASK &= p20_CLR_MASK; 
+#define p20_SET         LPC_GPIO1->FIOSET = p20_SET_MASK
+#define p20_CLR         LPC_GPIO1->FIOCLR = p20_SET_MASK
+#define p20_IS_SET      (bool)(LPC_GPIO1->FIOPIN & p20_SET_MASK)
+#define p20_IS_CLR      !(p20_IS_SET)
+#define p20_MODE(x)     LPC_PINCON->PINMODE3&=p20_SEL_MASK;LPC_PINCON->PINMODE3|=((x&0x3)<<30)
+#define p20_TOGGLE      p20_IS_SET?p20_CLR:p20_SET
+
+/* p21 is P2.5 */
+#define p21_SEL_MASK    ~(3UL << 10)
+#define p21_SET_MASK    (1UL << 5)
+#define p21_CLR_MASK    ~(p21_SET_MASK)
+#define p21_AS_OUTPUT   LPC_PINCON->PINSEL4&=p21_SEL_MASK;LPC_GPIO2->FIODIR|=p21_SET_MASK
+#define p21_AS_INPUT    LPC_GPIO2->FIOMASK &= p21_CLR_MASK; 
+#define p21_SET         LPC_GPIO2->FIOSET = p21_SET_MASK
+#define p21_CLR         LPC_GPIO2->FIOCLR = p21_SET_MASK
+#define p21_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p21_SET_MASK)
+#define p21_IS_CLR      !(p21_IS_SET)
+#define p21_TOGGLE      p21_IS_SET?p21_CLR:p21_SET
+#define p21_MODE(x)     LPC_PINCON->PINMODE4&=p21_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<10)
+
+/* p22 is P2.4 */
+#define p22_SEL_MASK    ~(3UL << 8)
+#define p22_SET_MASK    (1UL << 4)
+#define p22_CLR_MASK    ~(p22_SET_MASK)
+#define p22_AS_OUTPUT   LPC_PINCON->PINSEL4&=p22_SEL_MASK;LPC_GPIO2->FIODIR|=p22_SET_MASK
+#define p22_AS_INPUT    LPC_GPIO2->FIOMASK &= p22_CLR_MASK; 
+#define p22_SET         LPC_GPIO2->FIOSET = p22_SET_MASK
+#define p22_CLR         LPC_GPIO2->FIOCLR = p22_SET_MASK
+#define p22_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p22_SET_MASK)
+#define p22_IS_CLR      !(p22_IS_SET)
+#define p22_TOGGLE      p22_IS_SET?p22_CLR:p22_SET
+#define p22_MODE(x)     LPC_PINCON->PINMODE4&=p22_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<8)
+
+/* p23 is P2.3 */
+#define p23_SEL_MASK    ~(3UL << 6)
+#define p23_SET_MASK    (1UL << 3)
+#define p23_CLR_MASK    ~(p23_SET_MASK)
+#define p23_AS_OUTPUT   LPC_PINCON->PINSEL4&=p23_SEL_MASK;LPC_GPIO2->FIODIR|=p23_SET_MASK
+#define p23_AS_INPUT    LPC_GPIO2->FIOMASK &= p23_CLR_MASK; 
+#define p23_SET         LPC_GPIO2->FIOSET = p23_SET_MASK
+#define p23_CLR         LPC_GPIO2->FIOCLR = p23_SET_MASK
+#define p23_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p23_SET_MASK)
+#define p23_IS_CLR      !(p23_IS_SET)
+#define p23_TOGGLE      p23_IS_SET?p23_CLR:p23_SET
+#define p23_MODE(x)     LPC_PINCON->PINMODE4&=p23_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<6)
+
+/* p24 is P2.2 */
+#define p24_SEL_MASK    ~(3UL << 4)
+#define p24_SET_MASK    (1UL << 2)
+#define p24_CLR_MASK    ~(p24_SET_MASK)
+#define p24_AS_OUTPUT   LPC_PINCON->PINSEL4&=p24_SEL_MASK;LPC_GPIO2->FIODIR|=p24_SET_MASK
+#define p24_AS_INPUT    LPC_GPIO2->FIOMASK &= p24_CLR_MASK; 
+#define p24_SET         LPC_GPIO2->FIOSET = p24_SET_MASK
+#define p24_CLR         LPC_GPIO2->FIOCLR = p24_SET_MASK
+#define p24_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p24_SET_MASK)
+#define p24_IS_CLR      !(p24_IS_SET)
+#define p24_TOGGLE      p24_IS_SET?p24_CLR:p24_SET
+#define p24_MODE(x)     LPC_PINCON->PINMODE4&=p24_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<4)
+
+/* p25 is P2.1 */
+#define p25_SEL_MASK    ~(3UL << 2)
+#define p25_SET_MASK    (1UL << 1)
+#define p25_CLR_MASK    ~(p25_SET_MASK)
+#define p25_AS_OUTPUT   LPC_PINCON->PINSEL4&=p25_SEL_MASK;LPC_GPIO2->FIODIR|=p25_SET_MASK
+#define p25_AS_INPUT    LPC_GPIO2->FIOMASK &= p25_CLR_MASK; 
+#define p25_SET         LPC_GPIO2->FIOSET = p25_SET_MASK
+#define p25_CLR         LPC_GPIO2->FIOCLR = p25_SET_MASK
+#define p25_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p25_SET_MASK)
+#define p25_IS_CLR      !(p25_IS_SET)
+#define p25_MODE(x)     LPC_PINCON->PINMODE4&=p25_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<2)
+
+/* p26 is P2.0 */
+#define p26_SEL_MASK    ~(3UL << 0)
+#define p26_SET_MASK    (1UL << 0)
+#define p26_CLR_MASK    ~(p26_SET_MASK)
+#define p26_AS_OUTPUT   LPC_PINCON->PINSEL4&=p26_SEL_MASK;LPC_GPIO2->FIODIR|=p26_SET_MASK
+#define p26_AS_INPUT    LPC_GPIO2->FIOMASK &= p26_CLR_MASK; 
+#define p26_SET         LPC_GPIO2->FIOSET = p26_SET_MASK
+#define p26_CLR         LPC_GPIO2->FIOCLR = p26_SET_MASK
+#define p26_IS_SET      (bool)(LPC_GPIO2->FIOPIN & p26_SET_MASK)
+#define p26_IS_CLR      !(p26_IS_SET)
+#define p26_MODE(x)     LPC_PINCON->PINMODE4&=p26_SEL_MASK;LPC_PINCON->PINMODE4|=((x&0x3)<<0)
+
+/* p27 is P0.11 */
+#define p27_SEL_MASK    ~(3UL << 22)
+#define p27_SET_MASK    (1UL << 11)
+#define p27_CLR_MASK    ~(p27_SET_MASK)
+#define p27_AS_OUTPUT   LPC_PINCON->PINSEL0&=p27_SEL_MASK;LPC_GPIO0->FIODIR|=p27_SET_MASK
+#define p27_AS_INPUT    LPC_GPIO0->FIOMASK &= p27_CLR_MASK; 
+#define p27_SET         LPC_GPIO0->FIOSET = p27_SET_MASK
+#define p27_CLR         LPC_GPIO0->FIOCLR = p27_SET_MASK
+#define p27_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p27_SET_MASK)
+#define p27_IS_CLR      !(p27_IS_SET)
+#define p27_MODE(x)     LPC_PINCON->PINMODE0&=p27_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<22)
+
+/* p28 is P0.10 */
+#define p28_SEL_MASK    ~(3UL << 20)
+#define p28_SET_MASK    (1UL <<  10)
+#define p28_CLR_MASK    ~(p28_SET_MASK)
+#define p28_AS_OUTPUT   LPC_PINCON->PINSEL0&=p28_SEL_MASK;LPC_GPIO0->FIODIR|=p28_SET_MASK
+#define p28_AS_INPUT    LPC_GPIO0->FIOMASK &= p28_CLR_MASK; 
+#define p28_SET         LPC_GPIO0->FIOSET = p28_SET_MASK
+#define p28_CLR         LPC_GPIO0->FIOCLR = p28_SET_MASK
+#define p28_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p28_SET_MASK)
+#define p28_IS_CLR      !(p28_IS_SET)
+#define p28_MODE(x)     LPC_PINCON->PINMODE0&=p28_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<20)
+
+/* p29 is P0.5 */
+#define p29_SEL_MASK    ~(3UL << 10)
+#define p29_SET_MASK    (1UL << 5)
+#define p29_CLR_MASK    ~(p29_SET_MASK)
+#define p29_AS_OUTPUT   LPC_PINCON->PINSEL0&=p29_SEL_MASK;LPC_GPIO0->FIODIR|=p29_SET_MASK
+#define p29_AS_INPUT    LPC_GPIO0->FIOMASK &= p29_CLR_MASK; 
+#define p29_SET         LPC_GPIO0->FIOSET = p29_SET_MASK
+#define p29_CLR         LPC_GPIO0->FIOCLR = p29_SET_MASK
+#define p29_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p29_SET_MASK)
+#define p29_IS_CLR      !(p29_IS_SET)
+#define p29_TOGGLE      p29_IS_SET?p29_CLR:p29_SET
+#define p29_MODE(x)     LPC_PINCON->PINMODE0&=p29_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<10)
+
+/* p30 is P0.4 */
+#define p30_SEL_MASK    ~(3UL << 8)
+#define p30_SET_MASK    (1UL << 4)
+#define p30_CLR_MASK    ~(p30_SET_MASK)
+#define p30_AS_OUTPUT   LPC_PINCON->PINSEL0&=p30_SEL_MASK;LPC_GPIO0->FIODIR|=p30_SET_MASK
+#define p30_AS_INPUT    LPC_GPIO0->FIOMASK &= p30_CLR_MASK; 
+#define p30_SET         LPC_GPIO0->FIOSET = p30_SET_MASK
+#define p30_CLR         LPC_GPIO0->FIOCLR = p30_SET_MASK
+#define p30_IS_SET      (bool)(LPC_GPIO0->FIOPIN & p30_SET_MASK)
+#define p30_IS_CLR      !(p30_IS_SET)
+#define p30_MODE(x)     LPC_PINCON->PINMODE0&=p30_SEL_MASK;LPC_PINCON->PINMODE0|=((x&0x3)<<8)
+
+/* The following definitions are for the four Mbed LEDs.
+    LED1 = P1.18
+    LED2 = P1.20
+    LED3 = P1.21
+    LED4 = P1.23 */
+
+#define P1_18_SEL_MASK  ~(3UL << 4)
+#define P1_18_SET_MASK  (1UL << 18)
+#define P1_18_CLR_MASK  ~(P1_18_SET_MASK)
+#define P1_18_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_18_SEL_MASK;LPC_GPIO1->FIODIR|=P1_18_SET_MASK
+#define P1_18_AS_INPUT  LPC_GPIO1->FIOMASK &= P1_18_CLR_MASK; 
+#define P1_18_SET       LPC_GPIO1->FIOSET = P1_18_SET_MASK
+#define P1_18_CLR       LPC_GPIO1->FIOCLR = P1_18_SET_MASK
+#define P1_18_IS_SET    (bool)(LPC_GPIO1->FIOPIN & P1_18_SET_MASK)
+#define P1_18_IS_CLR    !(P1_18_IS_SET)
+#define LED1_USE        P1_18_AS_OUTPUT;P1_18_AS_INPUT
+#define LED1_ON         P1_18_SET
+#define LED1_OFF        P1_18_CLR
+#define LED1_IS_ON      P1_18_IS_SET
+#define LED1_TOGGLE     P1_18_IS_SET?LED1_OFF:LED1_ON
+
+#define P1_20_SEL_MASK  ~(3UL << 8)
+#define P1_20_SET_MASK  (1UL << 20)
+#define P1_20_CLR_MASK  ~(P1_20_SET_MASK)
+#define P1_20_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_20_SEL_MASK;LPC_GPIO1->FIODIR|=P1_20_SET_MASK
+#define P1_20_AS_INPUT  LPC_GPIO1->FIOMASK &= P1_20_CLR_MASK; 
+#define P1_20_SET       LPC_GPIO1->FIOSET = P1_20_SET_MASK
+#define P1_20_CLR       LPC_GPIO1->FIOCLR = P1_20_SET_MASK
+#define P1_20_IS_SET    (bool)(LPC_GPIO1->FIOPIN & P1_20_SET_MASK)
+#define P1_20_IS_CLR    !(P1_20_IS_SET)    
+#define LED2_USE        P1_20_AS_OUTPUT;P1_20_AS_INPUT
+#define LED2_ON         P1_20_SET
+#define LED2_OFF        P1_20_CLR
+#define LED2_IS_ON      P1_20_IS_SET
+#define LED2_TOGGLE     P1_20_IS_SET?LED2_OFF:LED2_ON
+
+#define P1_21_SEL_MASK  ~(3UL << 10)
+#define P1_21_SET_MASK  (1UL << 21)
+#define P1_21_CLR_MASK  ~(P1_21_SET_MASK)
+#define P1_21_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_21_SEL_MASK;LPC_GPIO1->FIODIR|=P1_21_SET_MASK
+#define P1_21_AS_INPUT  LPC_GPIO1->FIOMASK &= P1_21_CLR_MASK; 
+#define P1_21_SET       LPC_GPIO1->FIOSET = P1_21_SET_MASK
+#define P1_21_CLR       LPC_GPIO1->FIOCLR = P1_21_SET_MASK
+#define P1_21_IS_SET    (bool)(LPC_GPIO1->FIOPIN & P1_21_SET_MASK)
+#define P1_21_IS_CLR    !(P1_21_IS_SET)
+#define LED3_USE        P1_21_AS_OUTPUT;P1_21_AS_INPUT
+#define LED3_ON         P1_21_SET
+#define LED3_OFF        P1_21_CLR
+#define LED3_IS_ON      P1_21_IS_SET
+#define LED3_TOGGLE     P1_21_IS_SET?LED3_OFF:LED3_ON
+
+#define P1_23_SEL_MASK  ~(3UL << 14)
+#define P1_23_SET_MASK  (1UL << 23)
+#define P1_23_CLR_MASK  ~(P1_23_SET_MASK)
+#define P1_23_AS_OUTPUT LPC_PINCON->PINSEL3&=P1_23_SEL_MASK;LPC_GPIO1->FIODIR|=P1_23_SET_MASK
+#define P1_23_AS_INPUT  LPC_GPIO1->FIOMASK &= P1_23_CLR_MASK; 
+#define P1_23_SET       LPC_GPIO1->FIOSET = P1_23_SET_MASK
+#define P1_23_CLR       LPC_GPIO1->FIOCLR = P1_23_SET_MASK
+#define P1_23_IS_SET    (bool)(LPC_GPIO1->FIOPIN & P1_23_SET_MASK)
+#define P1_23_IS_CLR    !(P1_23_IS_SET)    
+#define LED4_USE        P1_23_AS_OUTPUT;P1_23_AS_INPUT
+#define LED4_ON         P1_23_SET
+#define LED4_OFF        P1_23_CLR
+#define LED4_IS_ON      P1_23_IS_SET
+#define LED4_TOGGLE     P1_23_IS_SET?LED4_OFF:LED4_ON
+
+#ifndef UB
+#define UB(x) LPC_UART0->RBR=x
+#endif
+
+#ifndef UBB
+#define UBB(x) { while((LPC_UART0->LSR&(1UL << 5)) == 0); LPC_UART0->RBR=x; }
+#endif
+
+#endif /* AJK_LIB17_IOMACROS_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/SimpleStepperMbed.h	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,85 @@
+/*
+    Copyright (c) 2011 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#ifndef AJK_SIMPLESTEPPERMBED_H
+#define AJK_SIMPLESTEPPERMBED_H
+
+#ifndef MBED_PINNAMES_H
+#define MBED_PINNAMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    P0_0 = LPC_GPIO0_BASE, P0_1, P0_2, P0_3, P0_4, P0_5, P0_6, P0_7
+            , P0_8, P0_9, P0_10, P0_11, P0_12, P0_13, P0_14, P0_15
+            , P0_16, P0_17, P0_18, P0_19, P0_20, P0_21, P0_22, P0_23
+            , P0_24, P0_25, P0_26, P0_27, P0_28, P0_29, P0_30, P0_31
+            , P1_0, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7
+            , P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15
+            , P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23
+            , P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31
+            , P2_0, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7
+            , P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15
+            , P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23
+            , P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31
+            , P3_0, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7
+            , P3_8, P3_9, P3_10, P3_11, P3_12, P3_13, P3_14, P3_15
+            , P3_16, P3_17, P3_18, P3_19, P3_20, P3_21, P3_22, P3_23
+            , P3_24, P3_25, P3_26, P3_27, P3_28, P3_29, P3_30, P3_31
+            , P4_0, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7
+            , P4_8, P4_9, P4_10, P4_11, P4_12, P4_13, P4_14, P4_15
+            , P4_16, P4_17, P4_18, P4_19, P4_20, P4_21, P4_22, P4_23
+            , P4_24, P4_25, P4_26, P4_27, P4_28, P4_29, P4_30, P4_31
+
+            // Mbed DIP Pin Names
+            , p5 = P0_9, p6 = P0_8, p7 = P0_7, p8 = P0_6, p9 = P0_0, p10 = P0_1
+            , p11 = P0_18, p12 = P0_17, p13 = P0_15, p14 = P0_16, p15 = P0_23
+            , p16 = P0_24, p17 = P0_25, p18 = P0_26, p19 = P1_30, p20 = P1_31
+            , p21 = P2_5, p22 = P2_4, p23 = P2_3, p24 = P2_2, p25 = P2_1
+            , p26 = P2_0, p27 = P0_11, p28 = P0_10, p29 = P0_5, p30 = P0_4
+
+            // Other Mbed Pin Names
+            , LED1 = P1_18, LED2 = P1_20, LED3 = P1_21, LED4 = P1_23
+            , USBTX = P0_2, USBRX = P0_3
+
+            // Not connected
+            , NC = (int)0xFFFFFFFF
+
+} PinName;
+
+typedef enum {
+    PullUp = 0
+    , Repeater = 1
+    , PullNone = 2
+    , PullDown = 3
+    , OpenDrain = 4
+} PinMode;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBED_PINNAMES_H */
+
+#endif /* AJK_SIMPLESTEPPERMBED_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/SimpleStepperOutput.h	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,339 @@
+/****************************************************************************
+ * Product: LIB17 Open Source Library
+ *
+ *                    Steller Technologies Limited
+ *                    ----------------------------
+ *
+ * Copyright (C) 2002-2011 Steller Technologies Limited. All rights reserved.
+ *
+ * This software may be distributed and modified under the terms of the GNU
+ * General Public License version 2 (GPL) as published by the Free Software
+ * Foundation and appearing in the file GPL.TXT included in the packaging of
+ * this file. Please note that GPL Section 2[b] requires that all works based
+ * on this software must also be made publicly available under the terms of
+ * the GPL ("Copyleft").
+ *
+ * Alternatively, this software may be distributed and modified under the
+ * terms of Steller Technologies Limited commercial licenses, which expressly
+ * supersede the GPL and are specifically designed for licensees interested in
+ * retaining the proprietary status of their code.
+ *
+ * $Id:$
+ *
+ ***************************************************************************/
+
+/**
+ * @defgroup SimpleStepperOutput SimpleStepperOutput functions
+ */
+
+#ifndef AJK_SIMPLESTEPPEROUTPUT_H
+#define AJK_SIMPLESTEPPEROUTPUT_H
+
+#ifndef __ARMCC_VERSION
+#include "SimpleStepperMbed.h"
+#else
+#include "mbed.h"
+#endif
+
+
+namespace AjK {
+
+/** SimpleStepperOutput - Adds pin output objects.
+ *
+ * The Mbed library supplies the DigitalIn and DigitalOut objects to allow you
+ * to specify ins and outs.
+ *
+ * SimpleStepperOutput allows library objects to implement pins without the requirement
+ * to link against the Mbed library. This increase portability when using
+ * alternate compilers (such as the Code Red GCC C++ compiler for LPCXpresso).
+ *
+ * @ingroup SimpleStepperOutput
+ */
+class SimpleStepperOutput {
+public:
+    enum Direction {
+          Out = 0
+        , In
+    };
+
+protected:
+    PinName pin;
+    uint32_t mask;
+    uint32_t fiodir;
+    uint32_t fiomask;
+    uint32_t fiopin;
+    uint32_t fioset;
+    uint32_t fioclr;
+
+    inline void setpin(PinName p)  { pin     = p; }
+    inline void setmask(PinName p) { mask    = (uint32_t)(1UL << ((uint32_t)p & 0x1F)); }
+    inline void setDir(PinName p)  { fiodir  = (uint32_t)(p & ~0x1F) + 0x00; }
+    inline void setMask(PinName p) { fiomask = (uint32_t)(p & ~0x1F) + 0x10; }
+    inline void setPin(PinName p)  { fiopin  = (uint32_t)(p & ~0x1F) + 0x14; }
+    inline void setSet(PinName p)  { fioset  = (uint32_t)(p & ~0x1F) + 0x18; }
+    inline void setClr(PinName p)  { fioclr  = (uint32_t)(p & ~0x1F) + 0x1C; }
+
+    inline void pinUp() { *((volatile uint32_t *)fioset) = mask; }
+    inline void pinDn() { *((volatile uint32_t *)fioclr) = mask; }
+    inline uint32_t pinIs() { return *((volatile uint32_t *)(fiopin)) & mask; }
+
+public:
+
+    /** Constructor
+     * @ingroup SimpleStepperOutput
+     */
+    SimpleStepperOutput(PinName p, Direction d = Out, PinMode m = PullDown) { init(p, d, m); };
+
+    /** write
+     *
+     * Writes a value to the pin.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @param i Zero makes the pin 0v, non-zero makes the pin 1.
+     */
+    void write(int i)     { if (i!=0) { pinUp(); } else { pinDn(); } }
+
+    /** read
+     *
+     * Reads the value on the pin.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    int  read(void)       { return pinIs() ? 1 : 0; };
+
+    /** output
+     *
+     * Setup the pin to be an output.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @ingroup API
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    void output(void)    { *((volatile uint32_t *)fiodir) |=  mask; }
+
+    /** input
+     *
+     * Setup the pin to be an input.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    void input(void)    { *((volatile uint32_t *)fiodir) &= ~mask; }
+
+    /** getPin
+     *
+     * Get the PinName this object is operating on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    PinName getPin(void) { return pin; }
+
+    /** getDirection
+     *
+     * Get the operational direction this pin is setup for.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    int getDirection(void) { return *((volatile uint32_t *)fiomask) & mask ? 1 : 0; }
+
+    /**  operator int()
+     *
+     * Reads the value on the pin.
+     *
+     * @see read
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return int 0v returns zero, otherwise returns 1.
+     */
+    operator int() { return read(); }
+
+    /** operator=
+     *
+     * Writes a value to the pin.
+     *
+     * @see write
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     */
+    SimpleStepperOutput& operator= (int value)  { write(value); return *this; }
+
+    /** operator=
+     *
+     * Writes a value to the pin.
+     *
+     * @see write
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     */
+    SimpleStepperOutput& operator= (SimpleStepperOutput& rhs) { write(rhs.read()); return *this; }
+
+    /** getMask
+     *
+     * Get the mask value for this pin.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The mask value used by this pin.
+     */
+    uint32_t getMask(void)    { return mask;    }
+
+    /** getFiodir
+     *
+     * Get the FIODIR register for the port the pin is on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The register value.
+     */
+    uint32_t getFiodir(void)  { return fiodir;  }
+
+    /** getFiomask
+     *
+     * Get the FIOMASK register for the port the pin is on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The register value.
+     */
+    uint32_t getFiomask(void) { return fiomask; }
+
+    /** getFiopin
+     *
+     * Get the FIOPIN register for the port the pin is on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The register value.
+     */
+    uint32_t getFiopin(void)  { return fiopin;  }
+
+    /** getFioset
+     *
+     * Get the FIOSET register for the port the pin is on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The register value.
+     */
+    uint32_t getFioset(void)  { return fioset;  }
+
+    /** getFioclr
+     *
+     * Get the FIOCLR register for the port the pin is on.
+     *
+     * @see http://cornflakes.wikidot.com/lib17:core:lib17-dio
+     * @ingroup SimpleStepperOutput
+     * @return uint32_t The register value.
+     */
+    uint32_t getFioclr(void)  { return fioclr;  }
+
+
+protected:
+    void init(PinName p, Direction d, PinMode m)
+    {
+        // We rely on the fact that by default the LPC1768
+        // sets all pins to be GPIO. The user will change
+        // that if they need to. So we don't bother trying
+        // to setup PINSELx
+
+        // psel(); // Not used, see above.
+
+        setpin(p);
+        setmask(p);
+        setDir(p);
+        setMask(p);
+        setPin(p);
+        setSet(p);
+        setClr(p);
+
+        if (d == Out) output();
+        else mode( m );
+    }
+
+protected:
+    void psel(void)
+    {
+        uint32_t ppsel, pumask;
+
+        if (pin >= P0_0 && pin <= P0_15)         ppsel = (uint32_t)(&LPC_PINCON->PINSEL0);
+        else if (pin >= P0_16 && pin <= P0_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL1);
+        else if (pin >= P1_0 && pin <= P1_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL2);
+        else if (pin >= P1_16 && pin <= P1_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL3);
+        else if (pin >= P2_0 && pin <= P2_15)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL4);
+        else if (pin >= P3_16 && pin <= P3_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL7);
+        else if (pin >= P4_16 && pin <= P4_31)     ppsel = (uint32_t)(&LPC_PINCON->PINSEL9);
+        else return;
+
+        pumask = ~(3UL << ((pin & 0x1F)>>1));
+        *((volatile uint32_t *)ppsel) &= pumask;
+    }
+
+public:
+    void mode(PinMode m)
+    {
+        uint32_t ppmod, pumask;
+
+        if (m == OpenDrain) {
+            openDrain(1);
+        }
+        else {
+            if (pin >= P0_0 && pin <= P0_15) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE0);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
+            }
+            else if (pin >= P0_16 && pin <= P0_31) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE1);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
+            }
+            else if (pin >= P1_0 && pin <= P1_15) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE2);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
+            }
+            else if (pin >= P1_16 && pin <= P1_31) {
+                 ppmod = (uint32_t)(&LPC_PINCON->PINMODE3);
+                 pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
+            }
+            else if (pin >= P2_0 && pin <= P2_15) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE4);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-0)*2) );
+            }
+            else if (pin >= P3_16 && pin <= P3_31) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE7);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
+            }
+            else if (pin >= P4_16 && pin <= P4_31) {
+                ppmod = (uint32_t)(&LPC_PINCON->PINMODE9);
+                pumask = ((m & 0x3) << ( ((pin & 0x1F)-16)*2) );
+            }
+            else return;
+
+            *((volatile uint32_t *)ppmod) |= pumask;
+        }
+    }
+
+public:
+    void openDrain(int i = 1)
+    {
+        if (pin >= P0_0 && pin <= P0_31)           { if (i) LPC_PINCON->PINMODE_OD0 |= mask; else LPC_PINCON->PINMODE_OD0 &= ~mask; }
+        else if (pin >= P1_0 && pin <= P1_31)      { if (i) LPC_PINCON->PINMODE_OD1 |= mask; else LPC_PINCON->PINMODE_OD1 &= ~mask; }
+        else if (pin >= P2_0 && pin <= P2_31)      { if (i) LPC_PINCON->PINMODE_OD2 |= mask; else LPC_PINCON->PINMODE_OD2 &= ~mask; }
+        else if (pin >= P3_16 && pin <= P3_31)     { if (i) LPC_PINCON->PINMODE_OD3 |= mask; else LPC_PINCON->PINMODE_OD3 &= ~mask; }
+        else if (pin >= P4_16 && pin <= P4_31)     { if (i) LPC_PINCON->PINMODE_OD4 |= mask; else LPC_PINCON->PINMODE_OD4 &= ~mask; }
+    }
+
+};
+
+}; /* namespace AjK ends. */
+
+using namespace AjK;
+
+#endif /* AJK_SIMPLESTEPPEROUTPUT_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/SimpleSteppers.h	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,262 @@
+/*
+    Copyright (c) 2011 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#ifndef AJK_SIMPLESTEPPERS_H
+#define AJK_SIMPLESTEPPERS_H
+
+#define SIMPLESTEPPER_F 100000
+#include "LPC17xx.h"
+#include "core_cm3.h"
+#include <stdint.h>
+
+#ifndef __ARMCC_VERSION
+#include "SimpleStepperMbed.h"
+#else
+#include "mbed.h"
+#endif
+
+#include "SimpleStepperOutput.h"
+
+namespace AjK {
+
+// Forward reference the main controller.
+class SimpleStepperController;
+
+/** SimpleStepper
+ *
+ * SimpleStepper is a class designed to handle the pulse and direction
+ * signals for a stepper motor. A simple API is exposed to allow the
+ * setting of the pulse width and the number of pulses per second.
+ *
+ * Note, SimpleStepper uses the SimpleStepperController class to manage
+ * the TIMER2. SimpleStepperController and SimpleStepper take total
+ * control of the LPC17xx's TIMER2. Your application or other library that
+ * your application uses, should use TIMER2.
+ *
+ * @include example1.h
+ */
+class SimpleStepper {
+
+public:
+    enum MAT           { MAT2_0, MAT2_1, MAT2_2, MAT2_3 };
+    enum MATCH_OP      { NothingOnMatch, ClrOnMatch, SetOnMatch, ToggleOnMatch };
+    enum PULSE_STATE   { PulseIdle, PulseAssert, PulseDeassert };
+    enum STEPPER_STATE { Stopped, ConstantSpeed };
+        
+protected:    
+    SimpleStepperController *_simpleStepperController;    
+    SimpleStepperOutput *_direction;
+    
+    PinName     _pulse;
+    MAT         _pulseMAT;
+    uint32_t    _operShift;
+    uint32_t    _pMR;
+    uint32_t    _match_shift;
+    uint32_t    _EMmask;
+    uint32_t    _EMCshift;
+    int         _pulseLen;
+    int         _pulseSense;
+    int         _directionSense;
+    int         _commandSpeed;
+    int64_t     _pulseCounter;
+    int64_t     _pulseWrapPos;
+    int64_t     _pulseWrapNeg;    
+    uint32_t    _currentMatch;
+    
+    bool        _maintainPositionData;
+    
+    PULSE_STATE _pulseState;
+    
+    STEPPER_STATE _stepperState;
+
+    void init(void);
+    
+    void isr(uint32_t);
+    
+    void next_step(void);
+    
+public:
+    friend class SimpleStepperController;
+    
+    /** Constructor
+     * 
+     * PinName pulse can be p5, p6, p7 or p8
+     * SimpleStepperOutput *direction is a pointer to an output.
+     *
+     * @param PinName The output for the pulse output.
+     * @param SimpleStepperOutput *direction The output pin for direction control
+     */
+    SimpleStepper(PinName pulse, SimpleStepperOutput *direction = 0);
+    
+    /** Constructor
+     * 
+     * PinName pulse can be p5, p6, p7 or p8
+     * SimpleStepperOutput *direction is a pointer to an output.
+     *
+     * @param SimpleStepperController *con A pointer to a base controller.
+     * @param PinName The output for the pulse output.
+     * @param SimpleStepperOutput *direction The output pin for direction control
+     */
+    SimpleStepper(SimpleStepperController *con, PinName pulse, SimpleStepperOutput *direction);
+   
+    /** setPulseSense
+     *
+     * Set's the logic value that pulse asserted assumes. Default is 1.
+     *
+     * 1 means pulse goes from 0 to 1 and remains 1 for pulseLen time then goes to 0.
+     * 0 means pulse goes from 1 to 0 and remains 0 for pulseLen time then goes to 1.
+     *
+     * @param int What is the logic sense for the pulse output.
+     */
+    void setPulseSense(int i = 1) { _pulseSense = i; }
+    
+    /** setDirectionSense
+     *
+     * Set's the logic value that direction forward assumes. Default is 1.
+     *
+     * 1 means that the direction output is 1 for forward and 0 for reverse.
+     * 0 means that the direction output is 0 for forward and 1 for reverse.
+     *
+     * Additionally, for position:-
+     * 1 means forward pulses are counted upwards, reverse means counted downwards.
+     * 0 means forward pulses are counted downwards, reverse means counted upwards.
+     *
+     * @param int What is the logic sense for the direction output.
+     */
+    void setDirectionSense(int i = 1) { _directionSense = i; }
+    
+    /** setPulseLen
+     *
+     * Used to set the pulse length. Default pulse length is 50us.
+     * If no arg supplied returns the current pulse length.
+     * <b>Note,</b> the length is specified as 10us increments.
+     * The default is 5 which is 50us
+     * @param int pulse length
+     * @return int the value of the pulse length.
+     */
+    int setPulseLen(int i = 0) { if (i) _pulseLen = i; return _pulseLen; }
+    
+    /** setSpeed
+     * 
+     * Set the motor speed in pulses per second. Zero stops all motor pulses.
+     * 
+     * With the default pulseLen of 50us (5 timer "ticks") the maximum speed
+     * that can be set is 10000 pulses per second (pps) which will produce a square
+     * wave with 50% duty cycle. Pushing it beyond will give a square wave a duty 
+     * cycle shifts so that the off time between pulses becomes shorter than the on 
+     * pulse length.
+     *
+     * The pulseLen can be adjusted using setPulseLen() down even more to eek out 
+     * some extra bandwidth. However, you really should be checking both the datasheet
+     * for your stepper motor amplifier and stepper motor. Running a stepper motor at
+     * such high speed may have electrical and mechanical issues.
+     *
+     * The arg raw is used when you want to "sync" channels. Suppose for example you
+     * have the following code to set the speed to two front wheels:-
+     * @code
+     *      stepper0.setSpeed(100);
+     *      stepper1.setSpeed(100);
+     * @endcode
+     *
+     * The problem here is they will be a few "clock ticks" out from each other as the
+     * TIMER2 TC increments between the two calls. If you wanted to make two motors sync
+     * together you can pass in the raw value of TIMER2 TC to make both functions calculate
+     * the same stepp values and so sync together:-
+     * @code
+     *      uint32_t i = LPC_TIM2->TC; // Capture TC.
+     *      stepper0.setSpeed(100, i);
+     *      stepper1.setSpeed(100, i);
+     * @endcode     
+     *
+     * The above code forces setSpeed() to calculate both axis in sync with respect to 
+     * a common TC value.
+     *
+     * @param int steps_per_second Number of pulses per second required.     
+     */
+    void setSpeed(int steps_per_second = 0, uint32_t raw = 0); 
+    
+    /** setSpeed
+     * 
+     * Set the motor speed in pulses per second. Zero stops all motor pulses.
+     * @param double steps_per_second Number of pulses per second required.     
+     */
+    void setSpeed(double steps_per_second = 0, uint32_t raw = 0); 
+    
+    /** setInterval
+     * 
+     * Set the motor speed pulse interval. Zero stops all motor pulses.
+     * @param int interval 
+     */
+    void setInterval(int i = 0, uint32_t raw = 0); 
+    
+    /** getPosition
+     * 
+     * Get the current position (the pulse counter).
+     *
+     * @return int64_t The current position as maintained by the interrupts.
+     */
+    int64_t getPosition(void) { return _pulseCounter; }
+
+    /** setWrapPos
+     *     
+     * Set the value that we should wrap the pulse position counter.
+     * Zero (default) means no wrap occurs.
+     *
+     * @param int64_t The value to wrap to NEG at.
+     */
+    void setWrapPos(int64_t i = 0) { _pulseWrapPos = i; }
+    
+    /** setWrapNeg
+     *     
+     * Set the value that we should wrap the pulse position counter.
+     * Zero (default) means no wrap occurs.
+     *
+     * @param int64_t The value to wrap to POS at.
+     */
+    void setWrapNeg(int64_t i = 0) { _pulseWrapNeg = i; }
+    
+    /** setMaintainPositionData
+     *
+     * Setting this false removes the maintainence of positional data.
+     * This allows the interrupt service routine to not perform these
+     * steps (if not required) thus making the ISR run slightly fatser.
+     * You might want to do this if positional data isn't required.
+     */
+    void setMaintainPositionData(bool b) { _maintainPositionData = b; }
+    
+};
+
+class SimpleStepperController {
+protected:
+    SimpleStepper   *_stepper[4];
+
+public:
+    friend class SimpleStepper;
+    
+    SimpleStepperController();    
+    ~SimpleStepperController();    
+    void isr(void);
+};
+
+}; // namespace AjK ends
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/example1.h	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,47 @@
+
+#include "mbed.h"
+#include "SimpleSteppers.h"
+
+SimpleStepperOutput led1(LED1);
+
+// SimpleStepperOutput is basically the same as
+// Mbed's DigitalOut class. However, it's more
+// portable to other platforms without having
+// to also port the entire Mbed library.
+SimpleStepperOutput sdir0(p17);
+SimpleStepperOutput sdir1(p18);
+SimpleStepperOutput sdir2(p19);
+SimpleStepperOutput sdir3(p20);
+
+// Create four steppers.
+// Stepper0 has the pulse output on p8 and dir on p17
+SimpleStepper stepper0(p8, &sdir0);
+// Stepper0 has the pulse output on p7 and dir on p18
+SimpleStepper stepper1(p7, &sdir1);
+// Stepper0 has the pulse output on p7 and dir on p19
+SimpleStepper stepper2(p6, &sdir2);
+// Stepper0 has the pulse output on p7 and dir on p20
+SimpleStepper stepper3(p5, &sdir3);
+
+int main() {
+    pc.baud(115200);
+    
+    // We do not need to maintain the stepper position
+    // for this simple example. This reduces the amount
+    // of work the ISR has to do.
+    stepper0.setMaintainPositionData(false);
+    stepper1.setMaintainPositionData(false);
+    stepper2.setMaintainPositionData(false);
+    stepper3.setMaintainPositionData(false);
+    
+    // Set all steppers to top speed of 5000 pulses/second.
+    stepper0.setSpeed(5000);
+    stepper1.setSpeed(5000);
+    stepper2.setSpeed(5000);
+    stepper3.setSpeed(5000);
+
+    while(1) {
+        led1 = !led1;
+        wait(0.2);        
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SimpleStepperInst.cpp	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,41 @@
+/*
+    Copyright (c) 2010 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#include "SimpleSteppers.h"
+#include "IOmacros.h"
+
+#ifdef __ARMCC_VERSION
+#define __SS_IRQ  __irq
+#else 
+#define __SS_IRQ
+#endif
+
+namespace AjK {
+
+SimpleStepperController __simpleStepperController;
+
+extern "C" void TIMER2_IRQHandler(void) __SS_IRQ {
+    __simpleStepperController.isr();
+    LPC_TIM2->IR = 0x3F;  // Clear all possible TIMER2 interrupts.   
+}
+
+}; // namespace AjK ends.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SimpleSteppers.cpp	Mon May 02 10:02:18 2011 +0000
@@ -0,0 +1,360 @@
+/*
+    Copyright (c) 2010 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+#include <math.h>
+#include "SimpleSteppers.h"
+#include "IOmacros.h"
+
+#define _PMR    *((uint32_t *)_pMR)
+
+namespace AjK {
+
+extern SimpleStepperController __simpleStepperController;
+
+void TIMER2_IRQHandler(void);
+
+SimpleStepper::SimpleStepper(PinName pulse, SimpleStepperOutput *direction)
+{
+    _simpleStepperController = &__simpleStepperController;
+    _pulse     = pulse;
+    _direction = direction;
+    init();
+}
+
+SimpleStepper::SimpleStepper(SimpleStepperController *con, PinName pulse, SimpleStepperOutput *direction)
+{
+    _simpleStepperController = con;
+    _pulse     = pulse;
+    _direction = direction;
+    init();
+}
+
+void
+SimpleStepper::init(void)
+{
+    _pulseCounter = 0;
+    _pulseWrapPos = 0;
+    _pulseWrapNeg = 0;
+    
+    _maintainPositionData = true; 
+    
+    setPulseSense(1);
+    setDirectionSense(1);
+    
+    switch (_pulse) {
+        case P0_6: // Mbed p8
+            _pulseMAT = MAT2_0;
+            _operShift = 4;
+            _pMR = 0x40090018; // T2MR0
+            _match_shift = 0;
+            _EMmask = 1;
+            _EMCshift = 4;
+            _simpleStepperController->_stepper[0] = this;
+            if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+            LPC_PINCON->PINSEL0 |= (3UL << 12);
+            break;
+        case P0_7: // Mbed p7
+            _pulseMAT = MAT2_1;
+            _operShift = 6;
+            _pMR = 0x4009001C; // T2MR1
+            _match_shift = 3;
+            _EMmask = 2;
+            _EMCshift = 6;
+            _simpleStepperController->_stepper[1] = this;
+            if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+            LPC_PINCON->PINSEL0 |= (3UL << 14);
+            break;        
+        case P0_8: // Mbed p6
+            _pulseMAT = MAT2_2;
+            _operShift = 8;
+            _pMR = 0x40090020; // T2MR2
+            _match_shift = 6;
+            _EMmask = 4;
+            _EMCshift = 8;
+            _simpleStepperController->_stepper[2] = this;
+            if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+            LPC_PINCON->PINSEL0 |= (3UL << 16);
+            break;        
+        case P0_9: // Mbed p5
+            _pulseMAT = MAT2_3;
+            _operShift = 10;
+            _pMR = 0x40090024; // T2MR3
+            _match_shift = 9;
+            _EMmask = 8;
+            _EMCshift = 10;
+            _simpleStepperController->_stepper[3] = this;
+            if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+            LPC_PINCON->PINSEL0 |= (3UL << 18);
+            break;
+        default:
+            while(1); /* ToDo, proper error reporting. */
+    } 
+    
+    
+    // The default pulse length. 5 * (1/SIMPLESTEPPER_F) = 100us.
+    _pulseLen = 5;
+    
+    // Initial state machine conditions.
+    _pulseState = PulseIdle;    
+    _stepperState = Stopped;       
+}
+
+void
+SimpleStepper::setInterval(int interval, uint32_t raw)
+{    
+    
+    if (interval == 0) { setSpeed((int)0); }
+    else {
+        int n = interval;
+        if (n < 0) n *= -1;
+        if (_direction) {
+            if (_directionSense) {
+                if (interval >= 0.0) _direction->write(1);
+                if (interval <  0.0) _direction->write(0);
+            }
+            else {
+                if (interval >= 0.0) _direction->write(0);
+                if (interval <  0.0) _direction->write(1);        
+            }
+        }        
+        _commandSpeed = n - _pulseLen; 
+        _pulseState = PulseAssert;
+        _stepperState = ConstantSpeed;
+        if (raw) {
+            _PMR = raw + _commandSpeed;
+        }
+        else {
+            _PMR = LPC_TIM2->TC + _commandSpeed;
+        }                
+        if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
+        LPC_TIM2->MCR &= ~(7UL << _match_shift);
+        LPC_TIM2->MCR |=  (1UL << _match_shift);
+    }
+}
+
+void
+SimpleStepper::setSpeed(double steps_per_second, uint32_t raw)
+{    
+    int i = 0;
+    
+    if (steps_per_second == 0.0) { setSpeed(i); }
+    else {
+        double fractpart, intpart;
+        fractpart = modf (steps_per_second , &intpart);
+        if (fractpart >= 0.50) intpart++;
+        double n = intpart;
+        if (n < 0.0) n *= -1.0;
+        if (_direction) {
+            if (_directionSense) {
+                if (steps_per_second >= 0.0) _direction->write(1);
+                if (steps_per_second <  0.0) _direction->write(0);
+            }
+            else {
+                if (steps_per_second >= 0.0) _direction->write(0);
+                if (steps_per_second <  0.0) _direction->write(1);        
+            }
+        }        
+        _commandSpeed = (int)(((double)SIMPLESTEPPER_F / n)) - _pulseLen; 
+        _pulseState = PulseAssert;
+        _stepperState = ConstantSpeed;
+        if (raw) {
+            _PMR = raw + _commandSpeed;
+        }
+        else {
+            _PMR = LPC_TIM2->TC + _commandSpeed;
+        }                
+        if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
+        LPC_TIM2->MCR &= ~(7UL << _match_shift);
+        LPC_TIM2->MCR |=  (1UL << _match_shift);
+    }
+}
+
+void
+SimpleStepper::setSpeed(int steps_per_second, uint32_t raw)
+{
+    if (steps_per_second == 0) {
+        LPC_TIM2->EMR |=  (NothingOnMatch << _EMCshift);
+        LPC_TIM2->MCR &= ~(7UL << _match_shift);
+        if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+        _stepperState = Stopped;
+        _pulseState = PulseIdle;
+        _commandSpeed = 0;
+    }
+    else {
+        int n = steps_per_second;
+        if (n < 0) n *= -1;
+        if (_direction) {
+            if (_directionSense) {
+                if (steps_per_second >= 0) _direction->write(1);
+                if (steps_per_second <  0) _direction->write(0);
+            }
+            else {
+                if (steps_per_second >= 0) _direction->write(0);
+                if (steps_per_second <  0) _direction->write(1);        
+            }
+        }        
+        _commandSpeed = (SIMPLESTEPPER_F / n) - _pulseLen;        
+        _pulseState = PulseAssert;
+        _stepperState = ConstantSpeed;        
+        if (raw) {
+            _PMR = raw + _commandSpeed;
+        }
+        else {
+            _PMR = LPC_TIM2->TC + _commandSpeed;
+        }
+        if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
+        LPC_TIM2->MCR &= ~(7UL << _match_shift);
+        LPC_TIM2->MCR |=  (1UL << _match_shift);
+    }
+}
+
+void 
+SimpleStepper::next_step(void) 
+{    
+    _PMR += _commandSpeed;
+        
+    switch(_pulseSense) {
+        case 1:
+            LPC_TIM2->EMR &= ~(3UL << _EMCshift); 
+            LPC_TIM2->EMR |=  (SetOnMatch << _EMCshift); 
+            break;
+        case 0:
+            LPC_TIM2->EMR &= ~(3UL << _EMCshift); 
+            LPC_TIM2->EMR |=  (ClrOnMatch << _EMCshift); 
+            break;
+    }
+    
+    // Next IRQ will automatically assert the pulse.
+    _pulseState = PulseAssert;
+}
+
+void 
+SimpleStepper::isr(uint32_t ir) 
+{
+    // Test to see if this interrupt is for us.
+    if (ir & _EMmask) { 
+    
+        if (_stepperState == Stopped) {
+            if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+            return;
+        }
+       
+        switch(_pulseState) {
+            case PulseIdle:
+                if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask;
+                _currentMatch = _PMR; // Store the current match value for profile().
+                next_step();
+                break;
+                
+            case PulseAssert: // Pulse has just been asserted on MAT2_x. 
+                _PMR += _pulseLen; // We now program for the deassert IRQ to occur at the required time.            
+                LPC_TIM2->EMR &= ~(ToggleOnMatch << _EMCshift); // At next IRQ we want to switch the pulse off...
+                LPC_TIM2->EMR |=  (ToggleOnMatch << _EMCshift); // ... we do this by toggling it.
+                _pulseState = PulseDeassert; // Set state for next interrupt.
+                
+                if (_maintainPositionData) {
+                    if (_directionSense) {
+                        if (_commandSpeed > 0) {
+                            _pulseCounter++;
+                            if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
+                                _pulseCounter = _pulseWrapNeg + 1;
+                            }
+                        }                        
+                        if (_commandSpeed < 0) {
+                            _pulseCounter--;
+                            if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
+                                _pulseCounter = _pulseWrapPos - 1;
+                            }
+                        }
+                    }
+                    else {
+                        if (_commandSpeed > 0) {
+                            _pulseCounter--;
+                            if (_pulseWrapNeg && _pulseCounter <= _pulseWrapNeg) {
+                                _pulseCounter = _pulseWrapPos - 1;
+                            }
+                        }                        
+                        if (_commandSpeed < 0) {
+                            _pulseCounter++;
+                            if (_pulseWrapPos && _pulseCounter >= _pulseWrapPos) {
+                                _pulseCounter = _pulseWrapNeg + 1;
+                            }
+                        }
+                    }
+                }
+                break;
+                
+            case PulseDeassert: // Pulse has just been deasserted on MAT2_x.
+                LPC_TIM2->EMR &= ~(NothingOnMatch << _EMCshift); // No further action...
+                LPC_TIM2->EMR |=  (NothingOnMatch << _EMCshift); // ... just in case.
+                _pulseState = PulseIdle; // Set state for next interrupt (profile() may change this).
+                _currentMatch = _PMR; // Store the current match value for profile().
+                next_step();
+                break;
+        }    
+    }
+}
+
+// **************************************************
+// * Controller class SimpleStepperController code. *
+// **************************************************
+
+SimpleStepperController::SimpleStepperController()
+{
+    for (int i = 0; i < 4; i++) _stepper[i] = 0;
+    
+    uint32_t pr = (uint32_t)(SystemCoreClock / 8 / SIMPLESTEPPER_F);
+    
+    LPC_SC->PCONP    |= (1UL << 22); // TIM2 On
+    LPC_SC->PCLKSEL1 |= (3UL << 12); // CCLK/8 = 12MHz
+    LPC_TIM2->PR      = pr - 1;      // TC clocks at SIMPLESTEPPER_F hz.
+    LPC_TIM2->MR0     = 0;
+    LPC_TIM2->MR1     = 0;
+    LPC_TIM2->MR2     = 0;
+    LPC_TIM2->MR3     = 0;
+    LPC_TIM2->MCR     = 0;          
+    
+    // Enable interrupts
+    NVIC_EnableIRQ(TIMER2_IRQn);  
+    
+    // Start timer operations.
+    LPC_TIM2->TCR = 2; // reset 
+    LPC_TIM2->TCR = 1; // enable
+}
+
+SimpleStepperController::~SimpleStepperController()
+{
+    NVIC_DisableIRQ(TIMER2_IRQn);    
+    LPC_SC->PCONP &= ~(1UL << 22); // TIM2 Off.
+}
+
+void
+SimpleStepperController::isr(void)
+{
+    uint32_t ir = LPC_TIM2->IR & 0xF;
+    if (_stepper[0] && ir & 1) _stepper[0]->isr(ir);
+    if (_stepper[1] && ir & 2) _stepper[1]->isr(ir);
+    if (_stepper[2] && ir & 4) _stepper[2]->isr(ir);
+    if (_stepper[3] && ir & 8) _stepper[3]->isr(ir);
+}
+
+}; // namespace AjK ends.