Generate up to 8 different digital waeforms from serial port

Dependencies:   mbed

Revision:
0:374d47623fab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmPulse.c	Sat Feb 12 16:41:07 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);
+
+    }
+}