Control up to 4 steppers axis with limit switch logic from serial port

Dependencies:   mbed

jmStepper.c

Committer:
jm
Date:
2011-02-12
Revision:
0:3e676fcd9c71

File content as of revision 0:3e676fcd9c71:

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