Generate up to 8 different digital waeforms from serial port

Dependencies:   mbed

jmPulse.c

Committer:
jm
Date:
2011-02-12
Revision:
0:374d47623fab

File content as of revision 0:374d47623fab:

/**
 * @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);

    }
}