Command all jmCLIG modules from serial port

Files at this revision

API Documentation at this revision

Comitter:
jm
Date:
Sat Feb 12 16:50:25 2011 +0000
Commit message:
jmAll Command Line Interface Module

Changed in this revision

jmCommands.c Show annotated file Show diff for this revision Revisions of this file
jmCommands.h Show annotated file Show diff for this revision Revisions of this file
jmInterpreter.c Show annotated file Show diff for this revision Revisions of this file
jmInterpreter.h Show annotated file Show diff for this revision Revisions of this file
jmLPC17xx_gpio.c Show annotated file Show diff for this revision Revisions of this file
jmLPC17xx_gpio.h Show annotated file Show diff for this revision Revisions of this file
jmMessages.c Show annotated file Show diff for this revision Revisions of this file
jmMessages.h Show annotated file Show diff for this revision Revisions of this file
jmMotor.c Show annotated file Show diff for this revision Revisions of this file
jmMotor.h Show annotated file Show diff for this revision Revisions of this file
jmPulse.c Show annotated file Show diff for this revision Revisions of this file
jmPulse.h Show annotated file Show diff for this revision Revisions of this file
jmRingBuffer.c Show annotated file Show diff for this revision Revisions of this file
jmRingBuffer.h Show annotated file Show diff for this revision Revisions of this file
jmStepper.c Show annotated file Show diff for this revision Revisions of this file
jmStepper.h Show annotated file Show diff for this revision Revisions of this file
jmStepperAxis.c Show annotated file Show diff for this revision Revisions of this file
jmStepperAxis.h Show annotated file Show diff for this revision Revisions of this file
jmSwitch.c Show annotated file Show diff for this revision Revisions of this file
jmSwitch.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmCommands.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,153 @@
+/** @file  jmCommands.c
+ *  Auto Generated by jmCLIG
+ *  Saturday, February 12, 2011  11:21 AM
+ *  @version  2011.01.05
+ */
+
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "jmLPC17xx_gpio.h"
+#include "jmMotor.h"
+#include "jmPulse.h"
+#include "jmStepper.h"
+#include "jmStepperAxis.h"
+#include "jmSwitch.h"
+
+const char jmCLIG[] = {"\njmCLIG Version  2011.01.05 \nInstance Saturday, February 12, 2011  11:21 AM\n"};
+
+// Command Name Table
+const char cmdNames[]=
+   {
+      'i','p','o','r','t',0,
+      'i','p','o','r','t','s',0,
+      'G','P','P','G','0',0,
+      'g','p','i','o','B','i','t','s',0,
+      'g','p','i','o','B','i','t',0,
+      'b','i','t','R','e','a','d',0,
+      'l','i','s','t',0,
+      'v','e','r',0,
+      'h','e','l','p',0,
+      'f','e','e','d','b','a','c','k',0,
+      'e','c','h','o',0,
+      'm','o','t','o','r',0,
+      'G','P','P','M','T',0,
+      'm','o','t','o','r','S','p','e','e','d',0,
+      'p','u','l','s','e',0,
+      'p','u','l','s','e','I','n','i','t',0,
+      'p','u','l','s','e','S','t','o','p',0,
+      'G','P','P','P','0',0,
+      's','t','e','p','p','e','r',0,
+      's','t','e','p','p','e','r','S','t','o','p',0,
+      'G','P','P','S','T',0,
+      's','t','e','p','S','p','e','e','d',0,
+      's','t','e','p','p','e','r','A','x','i','s',0,
+      'G','P','P','S','T','A',0,
+      's','w','R','e','a','d',0,
+      's','w','I','n','i','t',0,
+      'G','P','P','S','0',0,
+      'i','n','i','t',0,
+      0
+   };
+
+//  Section Definitions
+#define iport 0
+#define iports 1
+#define GPPG0 2
+#define gpioBits 3
+#define gpioBit 4
+#define bitRead 5
+#define list 6
+#define ver 7
+#define help 8
+#define feedback 9
+#define echo 10
+#define motor 11
+#define GPPMT 12
+#define motorSpeed 13
+#define pulse 14
+#define pulseInit 15
+#define pulseStop 16
+#define GPPP0 17
+#define stepper 18
+#define stepperStop 19
+#define GPPST 20
+#define stepSpeed 21
+#define stepperAxis 22
+#define GPPSTA 23
+#define swRead 24
+#define swInit 25
+#define GPPS0 26
+#define init 27
+
+
+/***********************************************************************
+ * @brief	Command steering
+ * Command Associated with Command Number is Executed
+ * @param[in]	cmdNum Command Number
+ * @return		none
+ **********************************************************************/
+void Action(int cmdNum){
+   switch(cmdNum){
+     case iport   : cli_PortInfo();
+             break;
+     case iports   : PortsInfo();
+             break;
+     case GPPG0   : cli_GPPG0();
+             break;
+     case gpioBits   : cli_gpioBits();
+             break;
+     case gpioBit   : cli_gpioBit();
+             break;
+     case bitRead   : cli_BitRead();
+             break;
+     case list   : cli_list();
+             break;
+     case ver   : cli_version();
+             break;
+     case help   : cli_help();
+             break;
+     case feedback   : cli_feedback();
+             break;
+     case echo   : cli_echo();
+             break;
+     case motor   : cli_Motor();
+             break;
+     case GPPMT   : cli_GPPMT();
+             break;
+     case motorSpeed   : cli_MotorSpeed();
+             break;
+     case pulse   : cli_Pulse();
+             break;
+     case pulseInit   : PulseInit();
+             break;
+     case pulseStop   : cli_PulseStop();
+             break;
+     case GPPP0   : cli_GPPP0();
+             break;
+     case stepper   : cli_Stepper();
+             break;
+     case stepperStop   : cli_StepperStop();
+             break;
+     case GPPST   : cli_GPPST();
+             break;
+     case stepSpeed   : cli_StepSpeed();
+             break;
+     case stepperAxis   : cli_StepperAxis();
+             break;
+     case GPPSTA   : cli_GPPSTA();
+             break;
+     case swRead   : cli_SwitchRead();
+             break;
+     case swInit   : cli_SwitchInit();
+             break;
+     case GPPS0   : cli_GPPS0();
+             break;
+     case init   : Inits();
+             break;
+     default : UnknownCommand();
+               NextCommand(nl,pLine);
+   }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmCommands.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,18 @@
+/** @file  jmCommands.h
+*  Auto Generated by jmCLIG
+*  @version  Saturday, February 12, 2011  11:21 AM
+*/
+
+#ifndef jmCommandsdef
+   #define jmCommandsdef 1
+
+   #define nbCommands 28
+
+   // Strings
+   extern const char jmCLIG[77];
+   extern const char cmdNames[208];
+
+#endif
+
+// Prototypes
+void Action(int);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmInterpreter.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,46 @@
+/*************************************************************************
+ * @file     jmInterpreter.c
+ * @brief    Command Line Interpreter
+ *                  
+ * @date    December 27,2010 
+*/
+
+#include "jmInterpreter.h"
+#include "jmRingBuffer.h"
+#include "jmCommands.h"
+
+/** @brief Interpret a command line.
+ * Interpreter uses Command Line Buffer to fecth command name
+ * and redirects execution to associated function.
+ * @param none
+ * @returns none
+ */
+void Interpret(void){ 
+  unsigned int i,k;
+  unsigned char Command, found;
+  char Word[WordMaxSize];
+  Command =0;
+  found = 0;
+  
+  if(NotEmpty(pLine)){
+     ExtractWord(pLine,Word);              // Command name extraction 
+     for(i=0, k=0;i<sizeof(cmdNames);i++){ // lookup in names array
+         if(cmdNames[i]!=Word[k]){         // if different
+            while(cmdNames[i]!=0)i++;      // next entry in names array
+            Command++;                     // update command index
+            k=0;
+         }
+         else{
+           if(Word[k]==0){             
+              found=1; 
+            } 
+           else k++;
+         } //else
+    
+         if(found)break; 
+     }  //for
+   }
+  
+  // Command execution
+  Action(Command);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmInterpreter.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,9 @@
+/*************************************************************************
+ * @file     jmInterpreter.h
+ * @brief    Command Line Interpreter
+ *                  
+ * @date    December 27,2010 
+*/
+
+// Prototypes
+void Interpret(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmLPC17xx_gpio.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,279 @@
+/*************************************************************************
+ * @file    jmLPC17xx_gpio.c
+ * @brief    Command Line Interface Module for LPC_GPIO
+ *                  
+ * @version    1.1
+ * @date    Jan 24, 2011
+ */
+
+#include "jmLPC17xx_gpio.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+
+#define DIR 0
+#define PIN 1
+#define MASK 2
+#define CLR 3
+#define SET 4
+
+#define Clear 0
+#define Set 1
+#define Toggle 2
+
+/***********************************************************************
+ * @brief        Send port registers content
+ * @param[in]    portNum    (Port Number value)0..4
+ * @return        none
+ **********************************************************************/
+void PortInfo(unsigned int portNum){
+   if(portNum <5){
+      printf("Port %1d\n",portNum);
+      printf("FIODIR   \t0x%08X\n",jmGPIO[portNum]->FIODIR);
+      printf("FIOMASK  \t0x%08X\n",jmGPIO[portNum]->FIOMASK);
+      printf("FIOPIN   \t0x%08X\n",jmGPIO[portNum]->FIOPIN);
+      printf("FIOSET   \t0x%08X\n",jmGPIO[portNum]->FIOSET);
+      printf("FIOCLR   \t0x%08X\n",jmGPIO[portNum]->FIOCLR);
+      printf("\n");
+   }
+}
+
+/***********************************************************************
+ * @brief        Send all ports registers content
+ * @param[in]    none
+ * @return        none
+ **********************************************************************/
+void PortsInfo(void){
+   unsigned int portNum;
+   for(portNum=0;portNum<5;portNum++) PortInfo(portNum);
+}
+
+/***********************************************************************
+ * @brief    iport Command Line Interface.
+ * Send port register content
+ * Command Line Format: iport (portNumber)0..4 
+ * @example iport 1     Will printout Port1 registers content
+ * @param[in]    Extracted from command line ring buffer (PortNumber)0..4
+ * @return        none
+ **********************************************************************/
+void cli_PortInfo(void){
+   unsigned int portNum;
+
+   if(ExtractUInteger(pLine,&portNum,0,4))
+      PortInfo(portNum);
+   else{
+      if(Help)printf("iport (portNumber)0..4\n");
+      // Ignore pending command line
+      NextCommand(nl,pLine);
+   }
+}
+
+
+/***********************************************************************
+ * @brief        Command line interface to read and send Port.Bit per bit position
+ * Command Line Format: bitRead  (Port Number)0..4 (Bit position)0..31
+ * ex: bitRead  1 18  read and send P1.18 input pin value
+ * pin must be previously set to input in GPIODIR and associated GPIOMASK bit= 0
+ * @param[in]    Extracted from command line (Port Number)0..4 (Bit position)0..31
+ * @return        none
+ **********************************************************************/
+void cli_BitRead(void){
+  unsigned int portNumber, bitPosition, bitValue;
+   // Extract pin number from Command Line
+   if(ExtractUInteger(pLine,&portNumber,0,4)){
+      // Extract bit position from Command Line
+      if(ExtractUInteger(pLine,&bitPosition,0,31)){
+         // Extract state from Command Line
+         bitValue = 1<<bitPosition;
+         if(jmGPIO[portNumber]->FIOPIN & bitValue)bitValue =1;
+         printf("P%d.%d %d\n",portNumber,bitPosition,bitValue);
+          return;
+      }
+   } 
+   if(Help)printf("bitRead (Port Number)0..4 (Bit position)0..31\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** Read GPIO Registers 
+ * @brief        Command Line Interface to Read and Send GPIO register value
+ * @param[in]    Extracted from command line GPPG0 (Port)0..4 (Register DIR/PIN/MASK)0..2
+ * @returns    Message: GPPG0 (Port)0..4 (Register DIR/PIN/MASK)0..2 (value)0..0xFFFFFFFF 
+ */
+void cli_GPPG0(void){
+   uint32_t value=0;
+   unsigned int port, reg;
+   if(ExtractUInteger(pLine,&port,0,4)){    // extract port id
+         if(ExtractUInteger(pLine,&reg,0,4)){  // extract register id
+         switch(reg){
+             case DIR: value = jmGPIO[port]->FIODIR; break;
+            case PIN: value = jmGPIO[port]->FIOPIN; break;
+            case MASK: value = jmGPIO[port]->FIOMASK; break;
+            case CLR: value = jmGPIO[port]->FIOCLR; break;
+            case SET: value = jmGPIO[port]->FIOSET; break;
+        }
+        printf("GPPG0 %d %d 0x%08X\n",port,reg,value);
+          return;
+      }
+    }
+  if(Help)printf("GPPG0 (Port)0..4 (Register DIR/PIN/MASK/CLR/SET)0..4\n");  
+  // Ignore pending command line
+  NextCommand(nl,pLine);
+}
+
+/***********************************************************************
+ * @brief        Command line interface to access GPIO register bits
+ * Use with care. Designed to be used with gui which locks non MBED DIP pins
+ * Command Line Format:   gpioBits (Port id)0..4 (Register DIR/PIN/MASK/CLR/SET)0..4 (value)0..0xFFFFFFFF (clear/set/toggle)0..2\n
+ * @param[in]    Extracted from command line   (Port)0..4 (Register DIR/PIN/MASK)0..2 (value)0..0xFFFFFFFF 
+ * @return        Message: GPPG0 (Port)0..4 (Register DIR/PIN/MASK)0..2 (value)0..0xFFFFFFFF 
+ **********************************************************************/
+void cli_gpioBits(void){
+  unsigned int port, reg, value, action;
+   // Extract port id from Command Line
+   if(ExtractUInteger(pLine,&port,0,4)){
+      // Extract register id from Command Line
+      if(ExtractUInteger(pLine,&reg,0,4)){
+          // Extract value from Command Line
+          if(ExtractUInteger(pLine,&value,0,0xFFFFFFFF)){
+             // Extract state from Command Line
+             if(ExtractUInteger(pLine,&action,0,2)){
+                switch(reg){
+                   case DIR:
+                       switch(action){
+                           case Clear: jmGPIO[port]->FIODIR &= ~value;
+                              break;
+                           case Set: jmGPIO[port]->FIODIR |= value;
+                              break;
+                           case Toggle: jmGPIO[port]->FIODIR ^= value;
+                              break;
+                        }
+                        break;
+                   case PIN:
+                       switch(action){
+                           case Clear: jmGPIO[port]->FIOPIN &= ~value;
+                              break;
+                           case Set: jmGPIO[port]->FIOPIN |= value;
+                              break;
+                           case Toggle: jmGPIO[port]->FIOPIN ^= value;
+                              break;
+                        }
+                        break;
+                   case MASK:
+                       switch(action){
+                           case Clear: jmGPIO[port]->FIOMASK &= ~value;
+                              break;
+                           case Set: jmGPIO[port]->FIOMASK |= value;
+                              break;
+                           case Toggle: jmGPIO[port]->FIOMASK ^= value;
+                              break;
+                        }
+                        break;
+                   case CLR:
+                       switch(action){
+                           case Clear: jmGPIO[port]->FIOCLR &= ~value;
+                              break;
+                           case Set: jmGPIO[port]->FIOCLR |= value;
+                              break;
+                           case Toggle: jmGPIO[port]->FIOCLR ^= value;
+                              break;
+                        }
+                        break;
+                   case SET:
+                       switch(action){
+                           case Clear: jmGPIO[port]->FIOSET &= ~value;
+                              break;
+                           case Set: jmGPIO[port]->FIOSET |= value;
+                              break;
+                           case Toggle: jmGPIO[port]->FIOSET ^= value;
+                              break;
+                        }
+                        break;
+
+                }
+                // gui feedback  
+                switch(reg)
+                {    
+                    case DIR: printf("GPPG0 %d %d 0x%08X\n",port,reg,jmGPIO[port]->FIODIR);
+                        break;
+                    case PIN: printf("GPPG0 %d %d 0x%08X\n",port,reg,jmGPIO[port]->FIOPIN);
+                        break;
+                    case MASK: printf("GPPG0 %d %d 0x%08X\n",port,reg,jmGPIO[port]->FIOMASK);
+                        break;
+                    case CLR: printf("GPPG0 %d %d 0x%08X\n",port,reg,jmGPIO[port]->FIOCLR);
+                        break;
+                    case SET: printf("GPPG0 %d %d 0x%08X\n",port,reg,jmGPIO[port]->FIOSET);
+                        break;
+                }
+                if(Feedback)printf("GPIO %d %d 0x%08X %d\n",port,reg,value,action);
+                return;
+             }
+         }
+      }
+   } 
+   if(Help)printf("gpioBits (Port id)0..4 (Register DIR/PIN/MASK/CLR/SET)0..4 (value)0..0xFFFFFFFF (clear/set/toggle)0..2\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** @brief   Reset/Set/Toggle an output pin
+ * Also sets pin as outputs.
+ * @param[in]    pin      pin id (value)0..432
+ * @param[in]    action  0..2 Clear/Set/Toggle
+ * @returns     Return Message: GPPB0 pin state
+ */
+void gpio(unsigned int pin, unsigned int action){
+   // Get port and bit for that pin
+   uint32_t bitValue;
+   uint8_t port;
+
+   // Get port, bit and bit value
+   port = pin/100;
+   bitValue = 1<<(pin%100);
+   
+   // set mbed pin direction as output
+   jmGPIO[port]->FIODIR |= bitValue;
+   // make sure FIOMASK bit is enable
+   jmGPIO[port]->FIOMASK &= ~bitValue;
+
+   switch(action)
+   {
+    case Clear:     jmGPIO[port]->FIOPIN &= ~bitValue; // reset pin low 
+                break;
+    case Set:    jmGPIO[port]->FIOPIN |= bitValue;  // set pin High
+                break;
+    case Toggle:jmGPIO[port]->FIOPIN ^= bitValue; // toggle pin 
+                break;
+   }
+   if( (jmGPIO[port]->FIOPIN & bitValue) == 0)bitValue = 0;
+   else bitValue = 1;
+
+   // Report bit modification
+   printf("GPPB0 %d %d\n",pin, bitValue);
+}
+
+/** @brief   Command line to Reset/Set/Toggle an output pin
+ * Also sets pin as outputs.  Not all pins are available
+ * Use with care. Designed to be used with gui which locks non MBED DIP pins
+ * Command Line Format:   gpioBit (Pin id)0..432 (action clear/set/toggle)0..2
+ * @param[in]    From command line: (Pin id)0..432 (action clear/set/toggle)0..2
+ * @returns     Return Message: GPPB0 pin state
+ */
+void cli_gpioBit(void){
+  unsigned int pin, action;
+   // Extract pin number from Command Line
+   if(ExtractUInteger(pLine,&pin,0,432)){
+      // Extract action from Command Line
+      if(ExtractUInteger(pLine,&action,0,2)){
+         gpio(pin,action);
+         return;
+      }
+   } 
+   if(Help)printf("Use with care ! gpioBit (pin Number)0..432 (action Clear/Set/Toggle)0..2\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmLPC17xx_gpio.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,38 @@
+/***********************************************************************//**
+ * @file	jmLPC17xx_gpio.h
+ * @brief	LPC17xx GPIO Command Line Interface 
+ * 				 
+ * @version	1.0
+ * @date	Feb 2, 2011
+ */
+
+// Section Port Information
+void PortInfo(unsigned int portNumber);
+void PortsInfo(void);
+void cli_PortInfo(void);
+
+// Section Port All Bits Access
+void cli_GPPG0(void);
+void cli_gpioBits(void);
+void cli_gpioBit(void);
+void gpio(unsigned int pin, unsigned int action);
+
+// Section Port Bitd
+void cli_BitRead(void);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmLPC17xx_gpio.h"
+*/
+
+// CLIG-CMD
+/*
+iport cli_PortInfo();
+iports PortsInfo();
+GPPG0 cli_GPPG0();
+gpioBits cli_gpioBits();
+gpioBit cli_gpioBit();
+bitRead cli_BitRead();
+*/
+//-------------------------- END CLIG PLUGS --------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmMessages.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,125 @@
+/*************************************************************************
+ * @file     jmMessages.c
+ * @brief    Control System Messages
+ *                  
+ * @date    December 27,2010 
+*/
+
+#include "jmCommands.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+#include "jmMessages.h"
+#include "stdint.h"
+
+uint8_t Help;
+uint8_t Feedback;
+uint8_t Echo;
+
+
+/** @brief Enable only help messages
+ * @param none
+ * @returns none
+ */
+void InitMessages(void){
+   Help = 1;
+   Echo = 0;
+   Feedback = 0;
+}
+ 
+/** @brief Send all command names in a project
+ * @param none
+ * @returns none
+ */
+void cli_list(void){
+   int i,j;
+   printf("Commands:\n");
+   printf(".......................\n");
+   // for each command 
+   for(i=0,j=0; i<nbCommands; i++,j++){
+      // print name
+      while(cmdNames[j]) printf("%c",cmdNames[j++]); 
+      printf("\n"); 
+   }
+   printf("........................\n");
+}
+
+/** @brief Send Message Unknown Command from interpreter
+ * @param none
+ * @returns none
+ */
+void UnknownCommand(void){
+   printf("\n?\n");
+}
+
+/** @brief Send Build Version Message
+ * @param none
+ * @returns none
+ */
+void cli_version(void){
+    printf(jmCLIG);
+}
+
+/** @brief Help Command Line Control.
+ * Enable/disable help messages
+ * When enabled, Typing name only prints Command Format
+ * @param none
+ * @returns none 
+ */
+void cli_help(void){
+    unsigned int  value;
+   if(ExtractUInteger(pLine,&value,0,1)){
+      if(value == 1)  printf("Help Enabled ! type command name to print its format\n");
+       else printf("Help Disabled !\n");
+        
+        Help = (uint8_t) value;                // save status
+        return;
+   } 
+   // Error on input, show format
+   if(Help)printf("help  (value)0..1\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** @brief Feedback Command Line Control. 
+ * Enable/disable feedback messages
+ * When enabled, feedback from user input commands are returned
+ * @param none
+ * @returns none 
+ */
+void cli_feedback(void){
+    unsigned int  value;
+   if(ExtractUInteger(pLine,&value,0,1)){
+      if(value == 1)  printf("Feedback Enabled !\n");
+       else    printf("Feedback Disabled !\n");
+       
+        Feedback = (uint8_t)value;        // save status
+        return;
+   } 
+
+   // Error on input, show format
+   if(Help)printf("feedback  (value)0..1\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** @brief Echo Command Line Control.
+ * Enable/disable communication echoes
+ * When enabled, user inputs are echoed back
+ * @param none
+ * @returns none 
+ */
+void cli_echo(void){
+    unsigned int  value;
+   if(ExtractUInteger(pLine,&value,0,1)){
+      if(value == 1)  printf("Echo Enabled !\n");
+       else    printf("Echo Disabled !\n");
+        
+        Echo = (uint8_t)value;         // save status
+       return;
+   } 
+
+   // Error on input, show format
+   if(Help)printf("echo  (value)0..1\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmMessages.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,35 @@
+/*************************************************************************
+ * @file     jmMessages.h
+ * @brief    Control System Messages
+ *                  
+ * @date    December 27,2010 
+*/
+
+#include "stdint.h"
+
+// variables to enable/disable messages
+extern   uint8_t Help;
+extern   uint8_t Feedback;
+extern   uint8_t Echo;
+
+// Prototypes
+void InitMessages(void);
+void cli_list(void);
+void cli_version(void);
+void UnknownCommand(void);
+void cli_help(void);
+void cli_feedback(void);
+void cli_echo(void);
+
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-CMD
+/*
+list cli_list();
+ver cli_version();
+help cli_help();
+feedback cli_feedback();
+echo cli_echo();
+*/
+
+//------------------------ END CLIG PLUGS -----------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmMotor.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,238 @@
+/*************************************************************************
+ * @file    jmMotor.c                 
+ * @version 1.0
+ * @date    Feb 12, 2011
+ */
+
+#include "jmMotor.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+#ifndef nonStop
+  #define nonStop 65535  // for continuous mode operation
+#endif
+
+#define mtNotInit 0
+#define mtRunningCW 1
+#define mtRunningCCW 2
+#define mtStopped 3
+
+// Module Data Structure
+struct StructMotor sMotor[motorQty]; // static creation
+
+/** Module Data Structure Initialization
+ * @brief   All State Machines non initialized
+ * @param[in]    none
+ * @returns none
+ */
+void MotorInit(void){
+   int i;
+   for(i=0;i<motorQty;i++){
+     sMotor[i].active = mtNotInit;
+   }
+}
+
+/** Speed control for motors (1 or up to 4)
+ * @brief motorSpeed Command Line Interface.
+ * Format: command name (arg info)min..max values 
+ * motorSpeed (Motor IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255
+ * @param[in] Extracted from command line (Motor IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255 
+ * @returns Message: motorSpeed ids tOn tOff
+ */
+void cli_MotorSpeed(void){
+   unsigned int id, i, tOn,tOff;
+   if(ExtractUInteger(pLine,&id,1,15)){          //extract id
+      if(ExtractUInteger(pLine,&tOn,0,255)){      //extract tOn
+         if(ExtractUInteger(pLine,&tOff,0,255)){ //extract tOff
+              for(i=0;i<motorQty;i++){              // check each motor
+                  if(id & 1<<i){                 // motor included ?     
+                      if(sMotor[i].active){         // motor initialized ?
+                           sMotor[i].tOn=(uint8_t)tOn;
+                           sMotor[i].tOff=(uint8_t)tOff;
+
+                         
+                         if(tOn==0){             // 0% ?
+                             sMotor[i].cycles=0;            
+                            sMotor[i].drivePort->FIOPIN &= ~sMotor[i].driveBitValue;    // output pin low 
+                          }
+    
+                          if(tOff==0){              // 100% ?            
+                            sMotor[i].drivePort->FIOPIN |= sMotor[i].driveBitValue;    // output pin high
+                          }
+    
+                          if(tOn!=0 && tOff!=0){   // PWM ?
+                             // change motor tOn and tOff values
+                             sMotor[i].cycles=nonStop;
+                          }
+                          // report to gui
+                          rGPPMT(i);
+                      }    
+                  }             
+              }
+          }
+      }
+
+      if(Feedback)printf("MotorSpeed ID %d tOn %d tOff %d\n",id,tOn, tOff);
+      return;
+   }
+   if(Help)printf("motorSpeed (Motor IDs ORed)1..15 (tOn Value)1..255 (tOff Value)1..255\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+
+/***********************************************************************
+ * @brief    Module State Machine.  
+ * Enable different motor control concurrently.
+ * @param none
+ * @returns Message at end of cycles: GPPMT id dirPin drivePinB tOn tOff status
+ */ 
+void MotorSM(void){
+  int i;
+   for(i=0;i<motorQty;i++){ // for each SM define by pins
+     // SM active ?
+     if(!sMotor[i].active) continue;
+   
+     if(sMotor[i].cycles!=0){  // Cycles to DO ?
+       switch(sMotor[i].state){       
+
+         // pulse is low
+         case  0: if(sMotor[i].eggTimer==0){             // time to change ?     
+                     sMotor[i].drivePort->FIOPIN |= sMotor[i].driveBitValue;  // set pin High         
+                     sMotor[i].eggTimer=sMotor[i].tOn;   // load timer with tOn   
+                     sMotor[i].state=1;                  // next state 
+                  }
+                  break;
+
+         // pulse is High
+         case  1: if(sMotor[i].eggTimer==0){                    // time to change ?
+                     sMotor[i].drivePort->FIOPIN &= ~sMotor[i].driveBitValue;    // reset pin low      
+                     sMotor[i].eggTimer=sMotor[i].tOff;  // load timer with tOff  
+                     if(sMotor[i].cycles != nonStop){    // continuous mode ?
+                        if(--sMotor[i].cycles == 0)      // decrease qty if not continuous mode
+                           rGPPMT(i);   // Message: GPPMT id dirPin drivePinB tOn tOff status
+                     }
+                     sMotor[i].state=0;                  // state 0
+                  }
+                  break;
+         }//switch
+       }//if
+  }//for
+}//MotorSM
+
+
+/** @brief motor Command Line Interface
+ * Command Line Interface to control Motor on mbed pins DIP5 to 30.
+ * Format: command name (arg info)min..max values 
+ * Command Line Format: motor (Motor ID)0..3 (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535]
+ * @param[in]    Extracted from command line ((Motor ID)0..3 (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)1..255 (tOff)1..255 (Cycles)[1..65535]
+ * @returns    Message: GPPMT id dirPin drivePinB tOn tOff status
+ */
+void cli_Motor(void){
+   unsigned int id,dirPin,drivePin, dir, tOn,tOff,cycles;
+
+   if(ExtractUInteger(pLine,&id,0,motorQty-1)){         // extract motor id
+      if(ExtractUInteger(pLine,&dirPin,0,432)){            // extract direction    pin
+         if(ExtractUInteger(pLine,&drivePin,0,432)){       // extract drive pin
+            if(ExtractUInteger(pLine,&dir,0,1)){            // extract direction
+                if(ExtractUInteger(pLine,&tOn,0,255)){       // extract tOn
+                   if(ExtractUInteger(pLine,&tOff,0,255)){   // extract tOff
+                       // extract cycles and test for nonStop mode
+                       if(!ExtractUInteger(pLine,&cycles,1,nonStop))cycles = nonStop;
+    
+                       sMotor[id].dirBitValue = 1<<(dirPin%100);
+                       sMotor[id].driveBitValue = 1<<(drivePin%100);;
+                       sMotor[id].drivePort = jmGPIO[drivePin/100];
+                       sMotor[id].dirPort = jmGPIO[dirPin/100];
+                       sMotor[id].active = 1;
+            
+                       // Port.Pin set to outputs
+                       sMotor[id].dirPort->FIODIR |= sMotor[id].dirBitValue;
+                       sMotor[id].drivePort->FIODIR |= sMotor[id].driveBitValue;
+        
+                       sMotor[id].direction = dir;
+                       sMotor[id].tOn = (uint8_t)tOn;
+                       sMotor[id].tOff = (uint8_t)tOff;
+                       sMotor[id].cycles = (uint16_t)cycles;
+                       sMotor[id].state = 0;
+                       sMotor[id].eggTimer = 0;
+                       sMotor[id].dirPin = dirPin;
+                       sMotor[id].drivePin = drivePin;
+    
+                      // set output direction bit according to given direction
+                      if(dir) sMotor[id].dirPort->FIOPIN |=    sMotor[id].dirBitValue;
+                      else sMotor[id].dirPort->FIOPIN &=    ~sMotor[id].dirBitValue;
+    
+                      // 100%
+                      if(tOff==0){
+                         sMotor[id].drivePort->FIOPIN |= sMotor[id].driveBitValue;
+                         // SM off
+                         sMotor[id].cycles = 0;
+                      }
+    
+                      // 0%
+                      if(tOn==0){
+                         sMotor[id].drivePort->FIOPIN &= ~sMotor[id].driveBitValue;
+                         // SM off
+                         sMotor[id].cycles = 0;
+                      }
+                      
+                      rGPPMT(id);   // Message: GPPMT id dirPin drivePinB tOn tOff status
+        
+                      if(Feedback)printf("Motor %d DirPin %d DrivePin %d Dir %d tOn %d tOff %d Cycles %d\n",id,
+                                         dirPin, drivePin, dir,tOn,tOff,cycles); 
+                       return;
+                }
+             }
+          }
+       }
+       }
+    // Ignore pending command line
+       NextCommand(nl,pLine);
+    return;
+   }
+
+   if(Help)printf("motor (Motor ID)0..%d (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535]\n",motorQty-1);  
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** Module Get Module Process Properties Command Line Interface
+ * @brief        Command Line Interface to Get Module Public Process Properties
+ * @param[in]    id Extracted from command line
+ * @returns    Message: GPPMT id dirPin drivePinB tOn tOff status
+ */
+void cli_GPPMT(void)
+{    unsigned int id;
+   if(ExtractUInteger(pLine,&id,0,motorQty-1)){  // extract id
+       rGPPMT(id);   // Message: GPPMT id dirPin drivePinB tOn tOff status
+       return;
+    }
+
+    if(Help)printf("GPPST (Motor id)0..%d\n",motorQty-1);  
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** Public Properties Message
+ * @brief    Send Process Properties to update GUI
+ * @param[in] id Process identification
+ * @returns   Message: GPPMT id dirPin drivePinB tOn tOff status
+ */
+void rGPPMT(unsigned int id ){
+    int status;
+    if( sMotor[id].active )
+    {   if(sMotor[id].cycles == 0)status = mtStopped;
+        else 
+        {
+         if( sMotor[id].direction) status = mtRunningCW;
+         else status = mtRunningCCW;
+        }
+    }
+    else  status = mtNotInit;                     
+    printf("GPPMT %d %d %d %d %d %d\n",id,sMotor[id].dirPin,sMotor[id].drivePin,sMotor[id].tOn,sMotor[id].tOff,status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmMotor.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,85 @@
+/*************************************************************************
+ * @file    jmMotor.h
+ * @brief   Control motor drive, direction and repetition on mbed DIP5 to 30.
+ *          Up to 4 motors can be controlled at the same time.
+ *             
+ * @version 1.0
+ * @date    Feb 12, 2011
+ */
+
+/*
+   * Module Command Line Interface 
+     Format: command name (arg info)min..max values [optional argument]
+   
+     motor (Motor ID)0..3 (Direction Pin)0..432 (Drive Pin)0..432 (Rotation cw/ccw)0..1 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535]
+
+   * Module Events
+         On terminating cycles, send Message: GPPMT id dirPin drivePinB tOn tOff status
+
+   *  Module Feedback and Help messages may be enabled/disabled by Command Lines.
+         feedback (enable/disable)0..1
+         help (enable/disable)0..1
+*/
+
+#ifndef Motordef
+  #define Motordef 1
+
+  #define motorQty 4 // max number of motor
+  
+  #include "LPC17xx.h"
+
+  // Module Data Structure
+  extern struct StructMotor{
+     uint8_t active; 
+     uint8_t direction; 
+     uint8_t tOff;       
+     uint8_t tOn;
+     uint8_t state;
+     uint16_t dirPin;
+     uint16_t drivePin;
+     uint16_t eggTimer;
+     uint16_t cycles;
+     uint32_t dirBitValue;
+     LPC_GPIO_TypeDef * dirPort;
+     uint32_t driveBitValue;
+     LPC_GPIO_TypeDef * drivePort;
+  }sMotor[motorQty]; 
+#endif
+
+// Module Prototypes
+void cli_Motor(void);
+void MotorInit(void);
+void MotorSM(void);
+void cli_MotorSpeed(void);
+void cli_GPPMT(void);
+void rGPPMT(unsigned int id);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmMotor.h"
+*/
+
+// CLIG-CMD
+/*
+motor cli_Motor();
+GPPMT cli_GPPMT();
+motorSpeed cli_MotorSpeed();
+*/
+
+// CLIG-INIT
+/*
+   MotorInit();
+*/
+
+// CLIG-TIMER
+/*
+   // Module jmMotor
+   for(i=0;i<motorQty;i++)if(sMotor[i].eggTimer>0)sMotor[i].eggTimer--;
+*/
+
+// CLIG-SM
+/*
+     MotorSM();
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmPulse.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,247 @@
+/**
+ * @file	jmPulse.c				 
+ * @version	1.0
+ * @date	Feb 12, 2011
+ */
+
+#include "jmPulse.h"
+#include "jmRingBuffer.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+#ifndef nonStop
+  #define nonStop 65535  // for continuous mode operation
+#endif
+
+// output defenitions
+#define Low 0
+#define High 1
+#define StatusOffset 3
+
+// State definitions
+#define puNotInit	0
+#define puStopped 2
+#define Pulse 1
+
+struct StructPulse sPulse[pulseQty]; // static creation
+
+/** Module Data Structure Initialization
+ * @brief   All State Machines put to sleep.
+ * @param[in]	none
+ * @returns none
+ */
+void PulseInit(void){
+   int i;
+   for(i=0;i<pulseQty;i++){
+     sPulse[i].state = puNotInit;
+   }
+}
+
+/** 
+ * @brief   Stop one or all pulse Machines
+ * @param[in] Extracted from command line (Pulse Number)0..7 255 for all
+ * @returns   Return Message: GPPP0 id pin tOn tOff status
+ */
+void cli_PulseStop(void){
+   unsigned int id,i;
+
+   if(ExtractUInteger(pLine,&id,0,255)){    // extract pulseNumber
+ 	  // put id pulse machine to sleep 
+	  if(id < pulseQty){
+		  sPulse[id].cycles = 0;
+		  sPulse[id].state = puStopped;
+		  rGPPP0(id);
+		  return;
+	  }
+
+	  if(id == 255){
+		  // stop all controllers
+		  for(i=0;i<pulseQty;i++){
+	          sPulse[i].cycles = 0;
+			  sPulse[i].state = puStopped;
+	      }
+	  }
+
+	  cli_GPPP0();	// Return 8 Messages: GPPP0 id pin tOn tOff status
+	  return;
+    }
+  if(Help)printf("pulseStop (Pulse number)0..%d \n",pulseQty-1);  
+  // Ignore pending command line
+  NextCommand(nl,pLine);
+}
+
+
+/** Module Pulse Command Line Interface
+ * @brief		Command Line Interface to control PWM/Pulse on output pins.
+ * @param[in]	Extracted from command line (Pulse Controller Number)0..7 (Pin id)0..432 (tOn)0..255 (tOff)0..255) (cycles)1..65535
+ * @returns    none
+ */
+void cli_Pulse(void){
+   unsigned int pulseNum, pinNumber,tOn,tOff,cycles;
+   if(ExtractUInteger(pLine,&pulseNum,0,pulseQty-1)){    // extract pulseNumber
+      if(ExtractUInteger(pLine,&pinNumber,0,432)){       // extract pin id
+         if(ExtractUInteger(pLine,&tOn,0,255)){          // extract tOn
+            if(ExtractUInteger(pLine,&tOff,0,255)){      // extract tOff
+               // extract cycles and test for nonStop mode
+               if(!ExtractUInteger(pLine,&cycles,1,65535))cycles = nonStop;
+
+			   SetPulseParam(pulseNum, pinNumber, tOn, tOff, cycles);
+	           if(Feedback)printf("pulse %d Pin%d tOn:%d  tOff:%d  Cycles:%d\n",pulseNum,pinNumber,tOn,tOff,cycles); 
+               return;
+           }
+        }
+      }
+    }
+  if(Help)printf("pulse (Pulse number)0..%d (Pin id)0..432 (tOn)0..255 (tOff)0..255 (Cycles)[1..0xFFFF]\n",pulseQty-1);  
+  // Ignore pending command line
+  NextCommand(nl,pLine);
+}
+
+/** Module Parameter Setting Function
+ * @brief   Enables PWM/pulse State Machine,
+ * Also sets mbed pin as outputs.
+ * @param[in]	num      pulse controller number (value)0..7  
+ * @param[in]	pin      pin id (value)0..432
+ * @param[in]	tOn      on time interval in ticks (tOn)0..255
+ * @param[in]	tOff     off time interval in ticks (tOff)0..255
+ * @param[in]	cycles   repetition number of tOn-tOff cycles
+ * @param[in]	state    set state: inactive, pulse, high, low
+ * @returns     Return Message: GPPP0 id pin state
+ */
+void SetPulseParam(uint8_t num, uint16_t pin, uint8_t tOn, uint8_t tOff, uint16_t cycles){
+   // Get port and bit for that pin
+   uint32_t bitValue;
+   uint8_t port;
+
+   // Get port, bit and bit value
+   port = pin/100;
+   bitValue = 1<<(pin%100);
+
+   sPulse[num].port = jmGPIO[port];
+   sPulse[num].pin = (uint8_t)pin;
+   sPulse[num].bitValue = bitValue;
+   
+   // set mbed pin direction as output
+   jmGPIO[port]->FIODIR |= bitValue;
+   // make sure FIOMASK bit is enable
+   jmGPIO[port]->FIOMASK &= ~bitValue;
+
+   
+   // Low State
+   if(tOn == 0 && tOff != 0)
+   {
+		jmGPIO[port]->FIOPIN &= ~bitValue; // reset pin low 
+		sPulse[num].output = Low;
+		sPulse[num].state = puStopped;
+   }
+   // High State 
+   if(tOn != 0 && tOff == 0)	 
+   {
+		jmGPIO[port]->FIOPIN |= bitValue;  // set pin High
+		sPulse[num].output = High;
+		sPulse[num].state = puStopped;
+   }
+   // Toggle output
+   if(tOn == 0 && tOff == 0) 
+   {
+	   jmGPIO[port]->FIOPIN ^= bitValue; // toggle pin 
+	   // Toggle state
+	   if(sPulse[num].output == High)sPulse[num].output = Low;
+	   else sPulse[num].output = High;
+	   sPulse[num].state = puStopped;
+   }
+   // Start Pulse controller
+   if(tOn != 0 && tOff != 0 && cycles !=0){	         
+       sPulse[num].state = Pulse;	
+	   sPulse[num].tOn = (uint8_t)tOn;
+	   sPulse[num].tOff = (uint8_t)tOff;
+	   sPulse[num].cycles = (uint16_t)cycles;
+	   sPulse[num].eggTimer = 0;
+   }
+      // Stop Pulse controller
+   if(tOn != 0 && tOff != 0 && cycles ==0){	         
+	   sPulse[num].cycles = 0;
+       sPulse[num].state = puStopped;
+   }
+
+   // Report process modification
+   rGPPP0(num);	//Return Message: GPPP0 id pin tOn tOff status
+}
+
+/***********************************************************************
+ * @brief	Module State Machine.  
+ * Enable different pwm/pulse rates concurrently.
+ * @param none
+ * @returns    When cycles Done, Return Message: GPPP0 id pin tOn tOff status
+ */ 
+void PulseSM(void){
+  int i;
+   for(i=0;i<pulseQty;i++){ // for each SM define by pins
+	 
+	 if(sPulse[i].state == puStopped) continue; //controller running ?
+	     
+	 if(sPulse[i].cycles!=0){  // Cycles to DO ?
+	   switch(sPulse[i].output){       
+
+		 // output is low
+		 case  Low: if(sPulse[i].eggTimer==0){                      // time to change ?     
+					 sPulse[i].port->FIOPIN |= sPulse[i].bitValue;  // set pin High         
+					 sPulse[i].eggTimer=sPulse[i].tOn;              // load timer with tOn   
+					 sPulse[i].output=High;                         // udpate structure
+				  }
+				  break;
+
+		 // output is High
+		 case  High: if(sPulse[i].eggTimer==0){					       // time to change ?
+					 sPulse[i].port->FIOPIN &= ~sPulse[i].bitValue;    // reset pin low  
+					 sPulse[i].output=Low;                             // update structure    
+					 sPulse[i].eggTimer=sPulse[i].tOff;                // load timer with tOff  
+					 if(sPulse[i].cycles != nonStop){                  // continuous mode ?
+						if(--sPulse[i].cycles == 0){      // decrease qty if not continuous mode
+							sPulse[i].state = puStopped;					// stop controller
+							// report end of cycles
+                            rGPPP0(i); //Message: GPPP0 id pin tOn tOff status
+						}
+					 }
+				  }
+				  break;
+		 }//switch
+	 }//if cycles
+  }//for
+}//PulseSM
+
+/** Module Get Module Process Properties Command Line Interface
+ * @brief		Command Line Interface to Get Module Public Process Properties
+ * @param[in]	Extracted from command line GPPP0 id
+ * @returns    Message: GPPP0 id pin tOn tOff status
+ */
+void cli_GPPP0(void)
+{	unsigned int id;
+   if(ExtractUInteger(pLine,&id,0,7)){    // extract pulse id Number
+       rGPPP0(id); //Message: GPPP0 id pin tOn tOff status
+	   return;
+	}
+
+    if(Help)printf("GPPP0 (Pulse id)0..%d\n",pulseQty-1);  
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** Public Properties Message
+ * @brief	Send Process Properties to update GUI
+ * @param[in] id Process identification
+ * @returns   Message: GPPP0 id pin tOn tOff status
+ */
+void rGPPP0(unsigned int id ){
+    int status;
+	if(id < pulseQty){
+	   if( sPulse[id].state == puStopped)status = sPulse[id].output +StatusOffset;
+	   else  status = sPulse[id].state;
+	   printf("GPPP0 %d %d %d %d %d\n",id,sPulse[id].pin,sPulse[id].tOn,sPulse[id].tOff,status);
+
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmPulse.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,92 @@
+/*************************************************************************
+ * @file	jmPulse.h
+ * @brief	Control pulse duration and repetition on digital mbed pins
+ *          Up to 8 pins can be controlled at the same time.
+ *          Single pulse or PWM like waveforms can be generated.
+ *             
+ * @version	1.1
+ * @date	Feb 12, 2011
+ */
+
+/*
+   * Module Command Line Interface 
+     Format: command name (arg info)min..max values [optional argument]
+     
+     pulse (pulse number)0..3 (pin number)0..432 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535]
+      Ex: pulse 0 118 5 10 20     Pulse Port1 Bit 18 High for 5 tick units, then Low for 10 ticks and repeat 20 times,
+                                 then Return Message: GPPP0 id pin tOn tOff status
+
+      Ex: pulse 0 118 1 0	Set output Port1 Bit 18 High
+      Ex: pulse 0 118 0 1	Reset output Port1 Bit 18 Low
+	  Ex: pulse 0 118 0 0	Toggle Port1 Bit 18 state
+
+   * Module Events
+         On terminating pulse cycles, Return Message: GPPP0 id pin tOn tOff status
+
+   *  Module Feedback and Help messages may be enabled/disabled by Command Lines.
+         feedback (enable/disable)0..1
+         help (enable/disable)0..1
+*/
+
+#ifndef Pulsedef
+  #define Pulsedef 1
+
+  #define pulseQty 8 // number of pins for pulse
+
+  #include "LPC17xx.h"
+
+  // Module Data Structure
+  extern struct StructPulse{
+     uint16_t pin;
+	 uint8_t tOff;       
+     uint8_t tOn;
+	 uint8_t output;
+     uint8_t state;
+     uint16_t eggTimer;
+     uint16_t cycles;
+     uint32_t bitValue;
+	 LPC_GPIO_TypeDef * port;
+  }sPulse[pulseQty];
+
+
+#endif
+
+// Module Prototypes
+void PulseInit(void);
+void cli_Pulse(void);
+void PulseSM(void);
+void SetPulseParam(uint8_t pulseNum, uint16_t pin, uint8_t tOn, uint8_t tOff, uint16_t cycles);
+void cli_GPPP0(void);
+void rGPPP0(unsigned int id);
+void cli_PulseStop(void);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmPulse.h"
+*/
+
+// CLIG-CMD
+/*
+pulse cli_Pulse();
+pulseInit PulseInit();
+pulseStop cli_PulseStop();
+GPPP0 cli_GPPP0();
+*/
+
+// CLIG-INIT
+/*
+   PulseInit();
+*/
+
+// CLIG-TIMER
+/*
+   // Module jmPulse
+   for(i=0;i<pulseQty;i++)if(sPulse[i].eggTimer>0)sPulse[i].eggTimer--;
+*/
+
+// CLIG-SM
+/*
+     PulseSM();
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmRingBuffer.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,215 @@
+/*************************************************************************
+ * @file     jmRingBuffer.c
+ * @brief    Command Line Rx Ring Buffer
+ *                  
+ * @date    Feb 12, 2011 
+*/
+
+
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+// static creation of Command Line Buffer
+struct RingBuffer  Line, *pLine; 
+
+/** @brief Command line ring buffer initialization.
+ * @param none
+ * @returns none 
+ */
+void InitCommandLineRingBuffer(void){
+ pLine = &Line;
+ FlushRingBuffer(pLine);
+}
+
+/** @brief Move ring head pointer foward.
+ * @param *p pointer to ring buffer
+ * @returns none 
+ */
+void NextHead(struct RingBuffer *p)              
+{    p->head++;            
+    if(p->head >= DimRingBuffer) 
+       p->head=0;          
+}
+
+/** @brief Move ring tail pointer foward.
+ * @param pointer to ring buffer
+ * @returns none 
+ */
+void NextTail(struct RingBuffer *p)              
+{    p->tail++;              
+    if(p->tail >= DimRingBuffer)   
+       p->tail=0;            
+}
+      
+/** @brief Check if buffer full.
+ * @param *p pointer to ring buffer
+ * @returns true if full, false otherwise 
+ */ 
+bool Full(struct RingBuffer *p)
+{  if(p->qty >= DimRingBuffer)         
+       return true;
+   else
+      return false;
+}
+  
+/** @brief Insert a char in buffer.
+ * @param c unsigned char to be inserted
+ * @param *p pointer to ring buffer
+ * @returns none 
+ */
+void Insert(unsigned char c, struct RingBuffer *p)
+{  if(Full(p))              
+      NextHead(p);            
+   else
+      p->qty++;                  
+ 
+   p->Buffer[p->tail]=c;          
+   NextTail(p);                   
+}
+
+/** @brief Check if ring buffer not empty.
+ * @param *p pointer to ring buffer
+ * @returns true if full, false otherwise
+ */ 
+bool NotEmpty(struct RingBuffer *p)
+{  if(p->qty == 0)                
+      return false ;                          
+   else 
+      return true;                          
+}
+
+/** @brief Extract a char from ring buffer.
+ * @param *p pointer to ring buffer
+ * @returns unsigned char
+ */
+unsigned char Extract(struct RingBuffer *p)      
+{  unsigned char c;
+   c = p->Buffer[p->head];     
+   if(NotEmpty(p))            
+   {  NextHead(p);            
+      p->qty--;                
+   }
+   return c;
+}
+
+/** @brief Flush ring buffer.
+ * @param *p pointer to ring buffer
+ * @returns none
+ */
+void FlushRingBuffer(struct RingBuffer *p)    
+{  int i;
+   p->head = 0;
+   p->tail = 0;
+   p->qty = 0;
+   for(i=0;i<DimRingBuffer;i++)p->Buffer[i]=0;
+}
+
+/** @brief Delete last char from ring buffer.
+ * @param *p pointer to ring buffer
+ * @returns none
+ */
+void DelChar(struct RingBuffer *p)
+{ if(p->qty != 0){
+     if(p->tail==0)p->tail=DimRingBuffer;
+     else p->tail--;  
+     p->qty--;    
+   }
+}
+
+/** @brief Remove a command line from ring buffer. 
+ * @param c end command identifier unsigned char
+ * @param *p pointer to ring buffer
+ * @returns none
+ */
+void NextCommand(unsigned char c, struct RingBuffer *p){
+   // remove all char till end identifier is found
+   while(NotEmpty(p) && p->Buffer[p->head] != c)
+   {  NextHead(p);            
+      p->qty--;                 
+   }
+
+   // remove end identifier
+   if(NotEmpty(p)&& p->Buffer[p->head] == c)               
+   {  NextHead(p);             
+      p->qty--;                 
+   }
+}
+
+/** @brief View ring buffer content.
+ * Print ring buffer content
+ * @param *p pointer to ring buffer
+ * @returns none
+ */
+void ViewRingBuffer(struct RingBuffer *p){
+   int i,j;
+
+   printf("\nRingBuffer Qty: %d \nContent: ",p->qty);
+
+   for(j=0,i=p->head;j<p->qty;j++){
+      printf("%c",p->Buffer[i]); 
+      if(i++>DimRingBuffer)i=0; 
+   }
+   printf("\n");
+}
+
+/** @brief Extract a word from ring buffer.
+ * The extracted word is put in the array pointed by word
+ * @param p pointer to a ring buffer 
+ * @param word pointer to array of char
+ * @returns true if a word is extracted otherwise returns false
+ */ 
+bool ExtractWord(struct RingBuffer *p, char * word){   
+   unsigned char c;
+   int i,j;
+   j=0;
+
+   if(NotEmpty(p)){
+        for(i=0;i<WordMaxSize-1;i++){
+          // extract a char from Rx ring buffer
+          c=Extract(p);
+    
+          // remove leading blanks
+          if(c==' ' && j==0)continue;
+    
+          // end of word or end of command line
+          if(c==' ' || c==nl)break;
+    
+          // build the Word
+          word[j++]=c;
+       }
+       // 0 string termination
+       word[j]=0;
+       if(j>0)return true;
+    }
+    return false;
+}
+
+/** @brief Extract an unsigned int from ring buffer.
+ * Convert a word from buffer into an integer between min and max values
+ * Value converted should be between min and max values.
+ * Value should be decimal or hexadecimal (beginning by 0x or 0X)
+ * @param p pointer to ring buffer
+ * @param result pointer to unsigned int
+ * @param min minimum limit
+ * @param max maximum limit
+ * @returns true if value is converted beetween limits, including limits.
+ */
+bool ExtractUInteger(struct RingBuffer *p, unsigned int *result, unsigned int min, unsigned int max){
+   unsigned int i ;
+   char word[WordMaxSize-1];
+
+   if(ExtractWord(p,word)){       // Extract string value
+      if(word[0]=='0' && (word[1]=='x' || word[1]=='X')) {
+         sscanf(word,"%x",&i);  // convert hexadecimal input
+      }
+      else
+         sscanf(word,"%d",&i);  // convert decimal input
+
+      if(i>=min && i<=max){
+         *result = i;
+         return true;
+      }
+   }
+   *result = 0;
+   return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmRingBuffer.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,36 @@
+/*************************************************************************
+ * @file     jmRingBuffer.h
+ * @brief    Command Line Rx Ring Buffer
+ *                  
+ * @date  Feb12, 2011
+*/
+
+#ifndef jmRingBufferDef
+ #define jmRingBufferDef 1 
+ 
+ #define nl 10 // new line
+ #define WordMaxSize 21
+ #define DimRingBuffer  41    
+     
+
+ // Ring Buffer data structure
+ extern  struct RingBuffer                 
+  {  unsigned char  Buffer[DimRingBuffer];      
+     unsigned char  head;               
+     unsigned char  tail;                 
+     unsigned char  qty;   
+  }Line, *pLine;
+#endif
+
+// Prototypes
+bool Full(struct RingBuffer *p);
+void Insert(unsigned char c, struct RingBuffer *p);
+bool NotEmpty(struct RingBuffer *p);
+unsigned char Extract(struct RingBuffer *p);      
+void FlushRingBuffer(struct RingBuffer *p); 
+void DelChar(struct RingBuffer *p);
+void InitCommandLineRingBuffer(void);
+void NextCommand(unsigned char c, struct RingBuffer *p);
+void ViewRingBuffer(struct RingBuffer *p);
+bool ExtractWord(struct RingBuffer *p, char *param);
+bool ExtractUInteger(struct RingBuffer *p, unsigned int *result, unsigned int min, unsigned int max);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmStepper.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,225 @@
+/*************************************************************************
+ * @file	jmStepper.c
+ * @brief	Command Line Interface Stepper Module
+ * 				 
+ * @version	1.0
+ * @date	Feb 12, 2011
+ */
+
+#include "jmMessages.h"
+#include "jmStepper.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+#ifndef nonStop
+   #define nonStop 65535
+#endif
+
+#define stNotInit 0
+#define stRunningCW 1
+#define stRunningCCW 2
+#define stStopped 3
+
+// static structures creation
+struct StructStepper sStepper[stepperQty];
+
+/** Module Data Structure Initialization
+ * @brief   All State Machines put to sleep.
+ * @param[in]	none
+ * @returns none
+ */
+void StepperInit(void){
+   int i;
+   for(i=0;i<stepperQty;i++){
+     sStepper[i].active = stNotInit;
+   }
+}
+
+/**  @brief Step Function
+ * Change Coil drives according to stepper number and direction.
+ * For 2 bit hardware controllers (full steps, full torque)
+ * @param[in]	number     (stepper number)0..3  
+ * @param[in]	CW         (direction)0..1
+ * @returns none
+ */
+void Step(int number, uint8_t CW){
+  uint8_t seq = sStepper[number].seq;
+   if(CW){
+      if(seq)sStepper[number].portCoilA->FIOPIN ^=sStepper[number].CoilA_bitValue;
+      else sStepper[number].portCoilB->FIOPIN ^=sStepper[number].CoilB_bitValue;
+   }
+   else {
+      if(seq)sStepper[number].portCoilB->FIOPIN ^=sStepper[number].CoilB_bitValue;
+      else sStepper[number].portCoilA->FIOPIN ^=sStepper[number].CoilA_bitValue;
+   }
+   sStepper[number].seq = !seq;
+}
+
+
+/**  
+ * @brief stepperStop Command Line Interface.
+ * Format: command name (arg info)min..max values 
+ * @param[in]	number   Extracted from command line (stepper ORed ids)1..15  
+ * @returns none
+ */
+void cli_StepperStop(void){
+   unsigned int value, i;
+   if(ExtractUInteger(pLine,&value,1,15)){ 
+      for(i=0;i<stepperQty;i++){
+         if(value & 1<<i)sStepper[i].nSteps=0;
+		 rGPPST(i);  // GPPST id pinA pinB delay status
+      }
+
+      if(Feedback)printf("StepperStop %d\n",value);
+      return;
+   }
+   if(Help)printf("stepperStop (Value)1..15\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/** Speed control for step motors (1 or up to 4)
+ * @brief stepSpeed Command Line Interface.
+ * Format: command name (arg info)min..max values 
+ * @param[in] Extracted from command line (stepper ORed ids)1..15  
+ * @returns Message: stepSpeed ids value
+ */
+void cli_StepSpeed(void){
+   unsigned int id, i, delay;
+   if(ExtractUInteger(pLine,&id,1,15)){ 
+      if(ExtractUInteger(pLine,&delay,1,255)){ 
+	      for(i=0;i<stepperQty;i++){
+	         // change delay for one stepper
+			 if(id & 1<<i)sStepper[i].delay=(uint8_t)delay;
+			 // report to gui
+			 printf("stepSpeed %d %d\n",id,delay);
+	      }
+	  }
+
+      if(Feedback)printf("StepperSpeed ID %d Delay %d\n",id,delay);
+      return;
+   }
+   if(Help)printf("stepSpeed (Stepper IDs ORed)1..15 (Delay Value)1..255\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/**  @brief Module State Machine.
+ * @param[in]	none 
+ * @returns    On Ending steps, Send Message: GPPST id pinA pinB delay status
+ */
+void StepperSM(void){
+   int i;
+
+   for(i=0;i<stepperQty;i++){                      // for each stepper
+      if(sStepper[i].active){                      // SM initialized ?  
+         if(sStepper[i].nSteps!=0){                // step to do ?
+            if(sStepper[i].eggTimer==0){           // time to step ?
+               Step(i,sStepper[i].cw);             // step
+               sStepper[i].eggTimer=sStepper[i].delay;  // set delay timer for next step
+               if(sStepper[i].nSteps<nonStop){     // continuous mode ?
+                  if(--sStepper[i].nSteps == 0)    // decrease step qty if not continuous mode
+                     rGPPST(i);   // Message GPPST id pinA pinB delay status
+               }
+            }     
+         }
+      }
+   }
+}
+
+
+/**  @brief stepper Command Line Interface.
+ * This function controls the stepper 
+ * Command Line Format: stepper (value)0..3 (direction)0..1 (PinA)0..432 (PinB)0..432 (delay)1..255 (steps)1..65535  
+ * @param[in]	Extracted from command line (value)0..3 (PinA)0..432 (PinB)0..432 (direction)0..1 (delay)1..255 (steps)1..65535 
+ * @returns    Message: GPPST id pinA pinB delay status
+ */
+void cli_Stepper(void){
+unsigned int id,cw, delay, steps, pinA, pinB, port, bitValue;
+
+   if(ExtractUInteger(pLine,&id,0,stepperQty-1)){       // extract stepper id
+   	 if(ExtractUInteger(pLine,&pinA,0,432)){			// extract pinA
+	 	 if(ExtractUInteger(pLine,&pinB,0,432)){		// extract pinB
+		      if(ExtractUInteger(pLine,&cw,0,1)){               // extract direction
+		         if(ExtractUInteger(pLine,&delay,1,255)){       // extract step delay
+		            if(!ExtractUInteger(pLine,&steps,1,65535)){ // check for optionnal steps arg
+		               steps = nonStop;  // default to nonStop
+		            }
+			     				  
+				  // Get ports, bit and bit values
+				  sStepper[id].pinA=(uint8_t)pinA;
+				  sStepper[id].pinB=(uint8_t)pinB;
+			      port = pinA/100;
+			      bitValue = 1<<(pinA%100);
+				  sStepper[id].portCoilA = jmGPIO[port];    // Coil A port
+	              sStepper[id].CoilA_bitValue = bitValue; // Coil A bit
+	
+				  port = pinB/100;
+			      bitValue = 1<<(pinB%100);
+				  sStepper[id].portCoilB = jmGPIO[port];    // Coil B port
+	              sStepper[id].CoilB_bitValue = bitValue; // Coil B bit
+	
+	              sStepper[id].active = 1;            // initialized true
+	
+	              // Port.Pin set to outputs
+	              sStepper[id].portCoilA->FIODIR |= sStepper[id].CoilA_bitValue;
+	              sStepper[id].portCoilB->FIODIR |= sStepper[id].CoilB_bitValue;
+					
+		          sStepper[id].cw =cw;           
+		          sStepper[id].delay = (uint8_t)delay;
+		          sStepper[id].nSteps = (uint16_t)steps;
+		            
+				  // chip report to GUI
+				  rGPPST(id); //Message: GPPST id pinA pinB delay status
+
+				  if(Feedback)printf("Stepper:%d PinA:%d PinB:%d CW:%d Delay:%d Steps:%d\n",id,pinA,pinB,cw,delay,steps);              
+		          return;
+		        }// delay
+		      }// direction
+			}// pinB
+		}// pinA
+    }// stepper number
+    if(Help)printf("stepper (Stepper id)0..3 (PinA)0..432 (PinB)0..432 (Direction cw/ccw)0..1 (Delay)1..255 [(Steps)1..65535]\n"); 
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** Module Get Module Process Properties Command Line Interface
+ * @brief		Command Line Interface to Get Module Public Process Properties
+ * @param[in]	id Extracted from command line id Process identification
+ * @returns    Message: GPPST id pinA pinB delay status
+ */
+void cli_GPPST(void)
+{	unsigned int id;
+   if(ExtractUInteger(pLine,&id,0,stepperQty-1)){  // extract id Number
+       rGPPST(id);   // Message: GPPST id pinA pinB delay status
+	   return;
+	}
+
+    if(Help)printf("GPPST (Stepper id)0..%d\n",stepperQty-1);  
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** Public Properties Message
+ * @brief	Send Process Properties to update GUI
+ * @param[in] id Process identification
+ * @returns   Message: GPPST id pinA pinB ddelay status
+ */
+void rGPPST(unsigned int id ){
+    int status;
+	if( sStepper[id].active )
+	{   if(sStepper[id].nSteps == 0)status = stStopped;
+	    else 
+		{
+		 if( sStepper[id].cw) status = stRunningCW;
+		 else status = stRunningCCW;
+		}
+	}
+	else  status = stNotInit;					 
+	printf("GPPST %d %d %d %d %d\n",id,sStepper[id].pinA,sStepper[id].pinB,sStepper[id].delay,status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmStepper.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,99 @@
+/*************************************************************************
+ * @file	jmStepper.h
+ * @brief	Stepper Control Interface
+ *          You can use 4,5,6 and 8 wire steppers.
+ *          Each output pin must have two drivers. 
+ * 			One driver must be the inverted output pin.
+ *          The other driver is the non inverted output pin.
+ *          This way the steppers operate in full step, full torque mode.
+ *             .
+ * @version	1.0
+ * @date	Feb 12, 2010
+ */
+
+/*
+   * Module Command Line Interface 
+     Format: command name (arg info)min..max values [optional argument]
+      stepper (Stepper number)0..3 (Pin CoilA)0..432 (Pin CoilB)0..432 (Direction)0..1 (Delay)1..255 [(Steps)1..65535] 
+      stepperStop (steppers value)1..15
+
+      Example for stepper on pins Port1.31 Port1.30	  DIP20 DIP19
+	  stepper 0 131 130 1 1     shortest delays between steps (fastest speed) continuous mode
+      stepper 0 131 130 0 1 1   one step in reverse direction 
+      stepper 0 131 130 1 10 5  5 steps in foward direction with 10 unit ticks between steps
+
+   * Module Events
+      GPPST (stepper id)0..3   
+         On Ending steps, Send Message: GPPST id pinA pinB delay status
+
+   *  Module Feedback and Help messages may be enabled/disabled by Command Lines.
+		 feedback (enable/disable)0..1
+         help (enable/disable)0..1
+
+*/
+
+#ifndef jmStepperdef
+  #define jmStepperdef 1
+
+  #define stepperQty 4 // 4 steppers max 
+
+  #include "LPC17xx.h"
+
+  // Module Data Structure
+  extern struct StructStepper{
+   uint8_t cw;  
+   uint8_t active; 
+   uint8_t seq;   
+   uint8_t delay;            
+   uint8_t eggTimer;  
+   uint16_t nSteps;
+   uint16_t pinA;
+   uint16_t pinB;
+   uint32_t CoilA_bitValue;
+   uint32_t CoilB_bitValue;
+   LPC_GPIO_TypeDef *portCoilA;
+   LPC_GPIO_TypeDef *portCoilB;
+ }sStepper[stepperQty];
+
+#endif
+
+// Module Prototypes
+void StepperInit(void);
+void StepperSM(void);
+void cli_Stepper(void);
+void Step(int number, bool CW);
+void cli_StepperStop(void);
+void cli_GPPST(void);
+void rGPPST(unsigned int id);
+void cli_StepSpeed(void);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmStepper.h"
+*/
+
+// CLIG-INIT
+/*
+   StepperInit();
+*/
+
+// CLIG-TIMER
+/*
+   // Module jmStepper
+   for(i=0;i<stepperQty;i++)if(sStepper[i].eggTimer>0)sStepper[i].eggTimer--;
+*/
+
+// CLIG-CMD
+/*
+stepper cli_Stepper();
+stepperStop cli_StepperStop();
+GPPST cli_GPPST();
+stepSpeed cli_StepSpeed();
+*/
+
+// CLIG-SM
+/*
+     StepperSM();
+*/
+//-------------------------- END CLIG PLUGS --------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmStepperAxis.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,173 @@
+/*************************************************************************
+ * @file	jmStepperAxis.c
+ * @brief	Command Line Interface StepperAxis Module
+ * 				 
+ * @version	1.0
+ * @date	Feb 12, 2011
+ */
+
+#include "jmMessages.h"
+#include "jmStepperAxis.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+#include "jmSwitch.h"
+#include "jmStepper.h"
+
+#ifndef nonStop
+   #define nonStop 65535
+#endif
+
+#define NotInit 0
+#define Initialized 1
+#define CW 1
+#define CCW 0
+#define Open 1
+#define Close 0
+#define bothLimitSwitchActivated 4
+#define LimitCWReached 3
+#define LimitCCWReached 2
+#define LogicOK 1
+#define true 1
+#define false 0
+
+// static structures creation
+struct StructStepperAxis sStepperAxis[stepperAxisQty];
+
+/** Module Data Structure Initialization
+ * @brief   All State Machines put to sleep.
+ * @param[in]	none
+ * @returns none
+ */
+void StepperAxisInit(void){
+   int i;
+   for(i=0;i<stepperAxisQty;i++){
+     sStepperAxis[i].active = false;
+   }
+}
+
+/**  @brief stepperAxis Command Line Interface.
+ * Set up a stepper axis from one stepper and two limit switch modules
+ * Command Line Format:  stepperAxis id stepperID limitCWid limitCCWid
+ * @param[in]	Extracted from command line  id stepperID limitCWid limitCCWid
+ * @returns    Message:  GPPSTA id stepperID limitCWid limitCCWid status
+ */
+void cli_StepperAxis(void){
+unsigned int id, stepperID, limitCWid, limitCCWid;
+
+   if(ExtractUInteger(pLine,&id,0,stepperAxisQty-1)){               // extract stepper axis id
+   	 if(ExtractUInteger(pLine,&stepperID,0,stepperQty-1)){			// extract stepper id
+	 	 if(ExtractUInteger(pLine,&limitCWid,0,switchQty-1)){		// extract Limit Switch CW id
+		      if(ExtractUInteger(pLine,&limitCCWid,0,switchQty-1)){ // extract Limit Switch CCW id
+
+				  sStepperAxis[id].active=true;
+				  sStepperAxis[id].stepperID=stepperID;
+				  sStepperAxis[id].limitCW=limitCWid;
+				  sStepperAxis[id].limitCCW=limitCCWid;
+
+				  // chip report to GUI
+				  rGPPSTA(id); 
+				  if(Feedback)printf("StepperAxis %d StepperID %d limitCCWid %d limitCWid %d\n",id,stepperID,limitCCWid,limitCWid);              
+		          return;
+			   }// CCW
+			}// CW
+		}// stepper
+    }// axis
+    if(Help)printf("stepperAxis (Stepper id)0..3 (limit switch CCW id)0..7 (limit switch CW id)0..7\n"); 
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** @brief   
+ * @param[in] none
+ * @returns 
+ */
+void StepperAxisSM(void)
+{
+   int i;
+   for(i=0;i<stepperAxisQty;i++)
+   {
+     if(sStepperAxis[i].active==true)
+	 {
+		 uint8_t oldStatus = sStepperAxis[i].status;	 
+		 
+		 // Limits Reached
+		 // two limits switches activated ? 
+		 if(sSwitch[sStepperAxis[i].limitCW].state == Close && sSwitch[sStepperAxis[i].limitCCW].state==Close){
+		 	sStepper[sStepperAxis[i].stepperID].nSteps=0;         // stop stepper
+			sStepperAxis[i].status = bothLimitSwitchActivated;
+			if(oldStatus !=  bothLimitSwitchActivated)rGPPSTA(i); // report change 			   
+			continue;  
+	     }
+		 // Limit Switch CW activated and step direction CW
+		 if(sSwitch[sStepperAxis[i].limitCW].state == Close && sStepper[sStepperAxis[i].stepperID].cw ==CW){
+			sStepper[sStepperAxis[i].stepperID].nSteps=0; // stop stepper
+			sStepperAxis[i].status = LimitCWReached;  
+			if(oldStatus !=  LimitCWReached)rGPPSTA(i); // report change  			     
+			continue;
+		 }
+
+		 // Limit Switch CCW activated and step direction CCW
+		 if(sSwitch[sStepperAxis[i].limitCCW].state == Close && sStepper[sStepperAxis[i].stepperID].cw ==CCW){
+			sStepper[sStepperAxis[i].stepperID].nSteps=0; // stop stepper
+			sStepperAxis[i].status = LimitCCWReached;    
+			if(oldStatus !=  LimitCCWReached)rGPPSTA(i); // report change 			 
+			continue;
+		 }	
+		 
+		 // safe operating area
+		 // no limit switch activated
+		 if(sSwitch[sStepperAxis[i].limitCW].state == Open && sSwitch[sStepperAxis[i].limitCCW].state == Open){
+			sStepperAxis[i].status = LogicOK;  
+			if(oldStatus !=  LogicOK)rGPPSTA(i); // report change   
+			continue;
+		 }
+
+		 // Limit Switch CW activated and step direction CCW
+		 if(sSwitch[sStepperAxis[i].limitCW].state == Close && sStepper[sStepperAxis[i].stepperID].cw ==CCW){
+			sStepperAxis[i].status = LogicOK;   
+			if(oldStatus !=  LogicOK)rGPPSTA(i); // report change     
+			continue;
+		 }
+
+		 // Limit Switch CCW activated and step direction CW
+		 if(sSwitch[sStepperAxis[i].limitCCW].state == Close && sStepper[sStepperAxis[i].stepperID].cw ==CW){
+			sStepperAxis[i].status = LogicOK; 
+			if(oldStatus !=  LogicOK)rGPPSTA(i); // report change  
+			continue;
+		 }	 
+	 }
+   }
+}
+
+/** Module Get Module Process Properties Command Line Interface
+ * @brief		Command Line Interface to Get Module Public Process Properties
+ * @param[in]	id Extracted from command line id Process identification
+ * @returns    none
+ */
+void cli_GPPSTA(void)
+{	unsigned int id;
+   if(ExtractUInteger(pLine,&id,0,stepperAxisQty-1)){  // extract id 
+       rGPPSTA(id);   
+	   return;
+	}
+
+    if(Help)printf("GPPSTA (StepperAxis id)0..%d\n",stepperAxisQty-1);  
+    // Ignore pending command line
+    NextCommand(nl,pLine);
+}
+
+/** Public Properties Message
+ * @brief	Send Process Properties to update GUI
+ * @param[in] id Process identification
+ * @returns   Message: GPPSTA id stepperID limitCWid limitCCWid status
+ */
+void rGPPSTA(unsigned int id ){		 
+	int status;
+	if(sStepperAxis[id].active==false)status=0;
+	else status = sStepperAxis[id].status;
+	printf("GPPSTA %d %d %d %d %d\n",id,sStepperAxis[id].stepperID,sStepperAxis[id].limitCCW,sStepperAxis[id].limitCW ,status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmStepperAxis.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,74 @@
+/*************************************************************************
+ * @file	jmStepperAxis.h
+ * @brief	
+ *             .
+ * @version	1.0
+ * @date	Feb 12, 2011
+ */
+
+/*
+   * Module Command Line Interface 
+     Format: command name (arg info)min..max values [optional argument]
+
+
+   * Module Events
+
+   *  Module Feedback and Help messages may be enabled/disabled by Command Lines.
+		 feedback (enable/disable)0..1
+         help (enable/disable)0..1
+
+*/
+
+#ifndef jmStepperAxisdef
+  #define jmStepperAxisdef 1
+
+  #define stepperAxisQty 4 // 4 steppers max 
+
+  #include "LPC17xx.h"
+
+  // Module Data Structure
+  extern struct StructStepperAxis{
+   uint8_t active;    
+   uint8_t limitCW;  
+   uint8_t limitCCW; 
+   uint8_t stepperID; 
+   uint8_t status;  
+ }sStepperAxis[stepperAxisQty];
+
+#endif
+
+// Module Prototypes
+void StepperAxisInit(void);
+void StepperAxisSM(void);
+void cli_StepperAxis(void);
+void rGPPSTA(unsigned int id );
+void cli_GPPSTA(void);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmStepperAxis.h"
+*/
+
+// CLIG-INIT
+/*
+   StepperAxisInit();
+*/
+
+// CLIG-NEEDS
+/*
+jmStepper
+jmSwitch
+*/
+
+// CLIG-CMD
+/*
+stepperAxis cli_StepperAxis();
+GPPSTA cli_GPPSTA();
+*/
+
+// CLIG-SM
+/*
+     StepperAxisSM();
+*/
+//-------------------------- END CLIG PLUGS --------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmSwitch.c	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,152 @@
+/*************************************************************************
+ * @file	jmSwitch.c
+ * @brief	Switch Debounce Module
+ * 				 
+ * @version	1.0
+ * @date	Feb 12, 2011
+*/
+
+#include "jmRingBuffer.h"
+#include "jmMessages.h"
+#include "jmSwitch.h"
+#include "LPC17xx.h"
+#include "main.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "jmRingBuffer.h"
+#include "stdio.h"
+
+#define swClose 0
+#define swOpen 1
+#define swNotInit 2
+
+
+// Static structure creation
+struct StructSwitch sSwitch[switchQty];
+
+/***********************************************************************
+ * @brief		Limit Switch Module Reset
+ * @param[in]	none
+ * @return		none
+ **********************************************************************/
+void SwitchModuleReset(void){
+	int i;
+	for(i=0;i<switchQty;i++){
+		sSwitch[i].state=swNotInit;
+	}
+}
+
+/***********************************************************************
+ * @brief	Initialize an input Switch process
+ * Format: command name (arg info)min..max values 
+ * Command Line Format: swInit (Switch id)0..7 (Pin number)0..432 (Debounce)1..255
+ * @param[in]	Extracted from command line (Switch id)0..7 (Pin number)0..432 (Debounce)1..255
+ * @return		Send Message GPPS0 id pin debounce state
+ **********************************************************************/
+void cli_SwitchInit(void){
+ //get switch id, DIP number, debounce time and update structure
+   unsigned int swNum, pin, debounce, state, port,bitValue;
+   if(ExtractUInteger(pLine,&swNum,0,7)){
+      if(ExtractUInteger(pLine,&pin,0,432)){
+         if(ExtractUInteger(pLine,&debounce,1,255)){
+		    // Get port, bit and bit value
+		    port = pin/100;
+		    bitValue = 1<<(pin%100);
+		
+            sSwitch[swNum].pin = (uint8_t)pin;
+            sSwitch[swNum].port = jmGPIO[port];
+            sSwitch[swNum].bitValue = bitValue;
+            sSwitch[swNum].debounce = (uint8_t)debounce;
+			// read Switch present state
+			state = sSwitch[swNum].port->FIOPIN &= sSwitch[swNum].bitValue;
+			if(state>0)sSwitch[swNum].state = swOpen;
+			else sSwitch[swNum].state = swClose;
+			rGPPS0(swNum);	// Message GPPS0 id pin debounce state
+            if(Feedback)printf("SW %d Pin %d Debounce %d Value %d\n",swNum,pin,debounce,state);
+
+            return;
+         }
+      }
+   }
+   if(Help)printf("swInit (Switch id)0..7 (Pin number)0..432 (Debounce)1..255\n");
+   
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}
+
+/***********************************************************************
+ * @brief		Switch Edge Detection
+ * @param[in]	none
+ * @return		Send Message GPPS0 id pin debounce state
+ **********************************************************************/
+void SwitchEdgeDetect(void){
+   unsigned int presentState,i;
+   
+   for(i=0;i<switchQty;i++){           // for each switch SM           
+      if(sSwitch[i].state < swNotInit){  // Switch initialized ?
+         if(sSwitch[i].eggTimer==0){   // debouncing ?                  
+		      
+            presentState = sSwitch[i].port->FIOPIN &= sSwitch[i].bitValue;
+            
+            if(presentState > 0)presentState = swOpen;	  // present switch state
+			else 	presentState = swClose;
+            
+            if(sSwitch[i].state > presentState ){           // High to Low edge ?
+		         sSwitch[i].eggTimer = sSwitch[i].debounce; // load debounce time
+		        // memorize presentState
+		        sSwitch[i].state = presentState;
+				rGPPS0(i);						            // GPPS0 message
+		    }
+            else{   		 
+              if(presentState > sSwitch[i].state ){          // Low to High edge ?
+		           sSwitch[i].eggTimer = sSwitch[i].debounce;// load debounce time
+		            // memorize presentState
+		            sSwitch[i].state = presentState;
+					rGPPS0(i);						         // GPPS0 message
+		      }
+            }            
+	      }
+      }
+   }               
+}
+
+/***********************************************************************
+ * @brief   Command line interface to read Limit Switch Status
+ * Format: command name (arg info)min..max values 
+ * Command Line Format: swRead (Switch id number)0..7
+ * @param[in]	Extracted from command line (switch id number)0..7
+ * @return		Message GPPS0 id pin debounce state
+ **********************************************************************/
+void cli_SwitchRead(void){
+   unsigned int swNumber;
+   if(ExtractUInteger(pLine,&swNumber,0,7)){   
+	  // One Message GPPS0 id pin debounce state
+      rGPPS0(swNumber);	 		
+      return;
+   } 
+   if(Help)printf("swRead (Switch id number)0..7\n");
+   // Ignore pending command line
+   NextCommand(nl,pLine);
+}  
+
+/** Get Module Process Properties Command Line Interface
+ * @brief	  Command Line Interface to Get All Public Process Properties
+ * @param[in] none
+ * @returns   8 Messages: GPPS0 id pin debounce state
+ */
+void cli_GPPS0(void){
+	int i;
+	for(i=0;i<switchQty;i++){	
+		rGPPS0(i); // Message GPPS0 id pin debounce state
+	}  
+}
+
+/** Public Properties Message
+ * @brief	Send Process Properties to update GUI
+ * @param[in] id Process identification
+ * @returns   Message GPPS0 id pin debounce state
+ */
+void rGPPS0(unsigned int id )
+{
+    printf("GPPS0 %d %d %d %d\n",id,sSwitch[id].pin,sSwitch[id].debounce,sSwitch[id].state); 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmSwitch.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,77 @@
+/*************************************************************************
+ * @file	jmSwitch.h
+ * @brief	Command Line Interface Module for reading switches
+ * 			Up to 8 switches can be defined on any digital mbed Pin.
+ *          Provide debounce and edge detection
+ * @version	1.0
+ * @date	Feb 2, 2011
+
+   Command Line Interface 
+   Format: command name (arg info)min..max values [optional argument]
+      swRead (Switch id)0..3  Return Message: GPPS0 id pin debounce state
+      swInit (Switch id)0..7 (Pin number)0..432 (debounce interval)1..255
+	          Initialize a Limit Switch Process and return Message: GPPS0 id pin debounce state
+	  GPPS0	 Return 8 Message: GPPS0 id pin debounce state
+
+   Module Events
+        On closing of switch, Return Message: GPPS0 id pin debounce state
+        On Opening of switch, Return Message: GPPS0 id pin debounce state
+*/
+
+#ifndef jmSwitchDef
+   #define jmSwitchDef 1
+   #include "stdint.h"
+   #include "LPC17xx.h"
+
+   #define switchQty 8 // max switch qty
+
+    // Module Data Structure
+	 extern   struct StructSwitch{ 
+	       uint16_t pin;
+	       uint8_t debounce;   
+		   uint8_t state; 
+	       uint8_t eggTimer;  
+	       uint32_t bitValue;
+	       LPC_GPIO_TypeDef *port;
+	    }sSwitch[switchQty]; 
+#endif
+
+// Module Prototypes
+void SwitchEdgeDetect(void);
+void cli_SwitchInit(void);
+void cli_SwitchRead(void);
+void cli_GPPS0();
+void rGPPS0(unsigned int id);
+void SwitchModuleReset(void);
+
+//-------------------------- CLIG PLUGS --------------------
+// CLIG-INCLUDE
+/*
+#include "jmSwitch.h"
+
+*/
+
+// CLIG-INIT
+/*
+   SwitchModuleReset();   
+*/
+
+// CLIG-TIMER
+/*
+   // Module jmSwitch
+   for(i=0;i<switchQty;i++)if(sSwitch[i].eggTimer>0)sSwitch[i].eggTimer--;
+*/
+
+// CLIG-CMD
+/*
+swRead cli_SwitchRead();
+swInit cli_SwitchInit();
+GPPS0 cli_GPPS0();
+*/
+
+// CLIG-SM
+/*
+     SwitchEdgeDetect();
+*/
+
+//-------------------------- END CLIG PLUGS --------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,96 @@
+/*************************************************************************
+ * @file         main.cpp
+ *                  
+ * @version      1.0
+ * @date         Feb 12, 2011
+*/
+
+#include "mbed.h"
+
+// Basic includes
+#include "jmInterpreter.h"
+#include "jmRingBuffer.h"
+#include "jmCommands.h"
+#include "jmMessages.h"
+#include "LPC17xx.h"
+
+
+LPC_GPIO_TypeDef *jmGPIO[5] ={LPC_GPIO0,LPC_GPIO1,LPC_GPIO2,LPC_GPIO3,LPC_GPIO4};
+
+// CLIG-INCLUDE
+#include "jmLPC17xx_gpio.h"
+#include "jmMotor.h"
+#include "jmPulse.h"
+#include "jmStepper.h"
+#include "jmStepperAxis.h"
+#include "jmSwitch.h"
+
+
+// Initializations
+void Inits(){
+   InitCommandLineRingBuffer();
+   InitMessages();
+   cli_version();
+
+   // CLIG-INIT
+   MotorInit();
+   PulseInit();
+   StepperInit();
+   StepperAxisInit();
+   SwitchModuleReset();   
+
+}
+
+// EggTimer tickers for modules
+void eggTimers(){
+   int i;
+   // CLIG-TIMER
+   // Module jmMotor
+   for(i=0;i<motorQty;i++)if(sMotor[i].eggTimer>0)sMotor[i].eggTimer--;
+   // Module jmPulse
+   for(i=0;i<pulseQty;i++)if(sPulse[i].eggTimer>0)sPulse[i].eggTimer--;
+   // Module jmStepper
+   for(i=0;i<stepperQty;i++)if(sStepper[i].eggTimer>0)sStepper[i].eggTimer--;
+   // Module jmSwitch
+   for(i=0;i<switchQty;i++)if(sSwitch[i].eggTimer>0)sSwitch[i].eggTimer--;
+
+}
+
+int main() {
+   unsigned char c;
+   Serial pc(USBTX, USBRX);          // communication medium
+   pc.baud(115200);                  // 115200 bauds, 8bits, 1 stop, no control flow
+   Ticker tick;                      // enable system ticks
+   tick.attach_us(&eggTimers,1000);  // enable and select granularity for egg timers
+   Inits();                          // initialization
+
+   while(true){
+     if( pc.readable()){             // something to read ?
+        c= pc.getc();                // read one char   
+
+        if(Echo) printf("%c",c);     // echo it ?
+
+        switch(c){                   // process it
+
+          case  8 : DelChar(pLine);  // remove last one
+                    break;
+          case 10 : Insert(c,pLine); // end of line
+                         Interpret();// process line 
+                    break;
+          default : Insert(c,pLine); // insert char in command line buffer
+        }
+     } // if
+
+     // CLIG-SM
+     MotorSM();
+     PulseSM();
+     StepperSM();
+     StepperAxisSM();
+     SwitchEdgeDetect();
+
+
+   }// while
+}// main
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,18 @@
+/*************************************************************************
+ * @file       main.h
+ * @version    1.0
+ * @date       Feb 12, 2011
+ */
+
+#include "LPC17xx.h"
+
+// registers
+extern LPC_GPIO_TypeDef *jmGPIO[5];
+
+// Prototypes
+void Inits(void);
+
+// CLIG-CMD
+/*
+init Inits();
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Feb 12 16:50:25 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912