Control up to 4 steppers from serial port

Dependencies:   mbed

Committer:
jm
Date:
Sat Feb 12 16:42:08 2011 +0000
Revision:
0:0785901b085e
jmStepper Command Line Interface Module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jm 0:0785901b085e 1 /*************************************************************************
jm 0:0785901b085e 2 * @file jmStepper.c
jm 0:0785901b085e 3 * @brief Command Line Interface Stepper Module
jm 0:0785901b085e 4 *
jm 0:0785901b085e 5 * @version 1.0
jm 0:0785901b085e 6 * @date Feb 12, 2011
jm 0:0785901b085e 7 */
jm 0:0785901b085e 8
jm 0:0785901b085e 9 #include "jmMessages.h"
jm 0:0785901b085e 10 #include "jmStepper.h"
jm 0:0785901b085e 11 #include "LPC17xx.h"
jm 0:0785901b085e 12 #include "main.h"
jm 0:0785901b085e 13 #include "jmCommands.h"
jm 0:0785901b085e 14 #include "jmMessages.h"
jm 0:0785901b085e 15 #include "jmRingBuffer.h"
jm 0:0785901b085e 16 #include "stdio.h"
jm 0:0785901b085e 17
jm 0:0785901b085e 18 #ifndef nonStop
jm 0:0785901b085e 19 #define nonStop 65535
jm 0:0785901b085e 20 #endif
jm 0:0785901b085e 21
jm 0:0785901b085e 22 #define stNotInit 0
jm 0:0785901b085e 23 #define stRunningCW 1
jm 0:0785901b085e 24 #define stRunningCCW 2
jm 0:0785901b085e 25 #define stStopped 3
jm 0:0785901b085e 26
jm 0:0785901b085e 27 // static structures creation
jm 0:0785901b085e 28 struct StructStepper sStepper[stepperQty];
jm 0:0785901b085e 29
jm 0:0785901b085e 30 /** Module Data Structure Initialization
jm 0:0785901b085e 31 * @brief All State Machines put to sleep.
jm 0:0785901b085e 32 * @param[in] none
jm 0:0785901b085e 33 * @returns none
jm 0:0785901b085e 34 */
jm 0:0785901b085e 35 void StepperInit(void){
jm 0:0785901b085e 36 int i;
jm 0:0785901b085e 37 for(i=0;i<stepperQty;i++){
jm 0:0785901b085e 38 sStepper[i].active = stNotInit;
jm 0:0785901b085e 39 }
jm 0:0785901b085e 40 }
jm 0:0785901b085e 41
jm 0:0785901b085e 42 /** @brief Step Function
jm 0:0785901b085e 43 * Change Coil drives according to stepper number and direction.
jm 0:0785901b085e 44 * For 2 bit hardware controllers (full steps, full torque)
jm 0:0785901b085e 45 * @param[in] number (stepper number)0..3
jm 0:0785901b085e 46 * @param[in] CW (direction)0..1
jm 0:0785901b085e 47 * @returns none
jm 0:0785901b085e 48 */
jm 0:0785901b085e 49 void Step(int number, uint8_t CW){
jm 0:0785901b085e 50 uint8_t seq = sStepper[number].seq;
jm 0:0785901b085e 51 if(CW){
jm 0:0785901b085e 52 if(seq)sStepper[number].portCoilA->FIOPIN ^=sStepper[number].CoilA_bitValue;
jm 0:0785901b085e 53 else sStepper[number].portCoilB->FIOPIN ^=sStepper[number].CoilB_bitValue;
jm 0:0785901b085e 54 }
jm 0:0785901b085e 55 else {
jm 0:0785901b085e 56 if(seq)sStepper[number].portCoilB->FIOPIN ^=sStepper[number].CoilB_bitValue;
jm 0:0785901b085e 57 else sStepper[number].portCoilA->FIOPIN ^=sStepper[number].CoilA_bitValue;
jm 0:0785901b085e 58 }
jm 0:0785901b085e 59 sStepper[number].seq = !seq;
jm 0:0785901b085e 60 }
jm 0:0785901b085e 61
jm 0:0785901b085e 62
jm 0:0785901b085e 63 /**
jm 0:0785901b085e 64 * @brief stepperStop Command Line Interface.
jm 0:0785901b085e 65 * Format: command name (arg info)min..max values
jm 0:0785901b085e 66 * @param[in] number Extracted from command line (stepper ORed ids)1..15
jm 0:0785901b085e 67 * @returns none
jm 0:0785901b085e 68 */
jm 0:0785901b085e 69 void cli_StepperStop(void){
jm 0:0785901b085e 70 unsigned int value, i;
jm 0:0785901b085e 71 if(ExtractUInteger(pLine,&value,1,15)){
jm 0:0785901b085e 72 for(i=0;i<stepperQty;i++){
jm 0:0785901b085e 73 if(value & 1<<i)sStepper[i].nSteps=0;
jm 0:0785901b085e 74 rGPPST(i); // GPPST id pinA pinB delay status
jm 0:0785901b085e 75 }
jm 0:0785901b085e 76
jm 0:0785901b085e 77 if(Feedback)printf("StepperStop %d\n",value);
jm 0:0785901b085e 78 return;
jm 0:0785901b085e 79 }
jm 0:0785901b085e 80 if(Help)printf("stepperStop (Value)1..15\n");
jm 0:0785901b085e 81 // Ignore pending command line
jm 0:0785901b085e 82 NextCommand(nl,pLine);
jm 0:0785901b085e 83 }
jm 0:0785901b085e 84
jm 0:0785901b085e 85 /** Speed control for step motors (1 or up to 4)
jm 0:0785901b085e 86 * @brief stepSpeed Command Line Interface.
jm 0:0785901b085e 87 * Format: command name (arg info)min..max values
jm 0:0785901b085e 88 * @param[in] Extracted from command line (stepper ORed ids)1..15
jm 0:0785901b085e 89 * @returns Message: stepSpeed ids value
jm 0:0785901b085e 90 */
jm 0:0785901b085e 91 void cli_StepSpeed(void){
jm 0:0785901b085e 92 unsigned int id, i, delay;
jm 0:0785901b085e 93 if(ExtractUInteger(pLine,&id,1,15)){
jm 0:0785901b085e 94 if(ExtractUInteger(pLine,&delay,1,255)){
jm 0:0785901b085e 95 for(i=0;i<stepperQty;i++){
jm 0:0785901b085e 96 // change delay for one stepper
jm 0:0785901b085e 97 if(id & 1<<i)sStepper[i].delay=(uint8_t)delay;
jm 0:0785901b085e 98 // report to gui
jm 0:0785901b085e 99 printf("stepSpeed %d %d\n",id,delay);
jm 0:0785901b085e 100 }
jm 0:0785901b085e 101 }
jm 0:0785901b085e 102
jm 0:0785901b085e 103 if(Feedback)printf("StepperSpeed ID %d Delay %d\n",id,delay);
jm 0:0785901b085e 104 return;
jm 0:0785901b085e 105 }
jm 0:0785901b085e 106 if(Help)printf("stepSpeed (Stepper IDs ORed)1..15 (Delay Value)1..255\n");
jm 0:0785901b085e 107 // Ignore pending command line
jm 0:0785901b085e 108 NextCommand(nl,pLine);
jm 0:0785901b085e 109 }
jm 0:0785901b085e 110
jm 0:0785901b085e 111 /** @brief Module State Machine.
jm 0:0785901b085e 112 * @param[in] none
jm 0:0785901b085e 113 * @returns On Ending steps, Send Message: GPPST id pinA pinB delay status
jm 0:0785901b085e 114 */
jm 0:0785901b085e 115 void StepperSM(void){
jm 0:0785901b085e 116 int i;
jm 0:0785901b085e 117
jm 0:0785901b085e 118 for(i=0;i<stepperQty;i++){ // for each stepper
jm 0:0785901b085e 119 if(sStepper[i].active){ // SM initialized ?
jm 0:0785901b085e 120 if(sStepper[i].nSteps!=0){ // step to do ?
jm 0:0785901b085e 121 if(sStepper[i].eggTimer==0){ // time to step ?
jm 0:0785901b085e 122 Step(i,sStepper[i].cw); // step
jm 0:0785901b085e 123 sStepper[i].eggTimer=sStepper[i].delay; // set delay timer for next step
jm 0:0785901b085e 124 if(sStepper[i].nSteps<nonStop){ // continuous mode ?
jm 0:0785901b085e 125 if(--sStepper[i].nSteps == 0) // decrease step qty if not continuous mode
jm 0:0785901b085e 126 rGPPST(i); // Message GPPST id pinA pinB delay status
jm 0:0785901b085e 127 }
jm 0:0785901b085e 128 }
jm 0:0785901b085e 129 }
jm 0:0785901b085e 130 }
jm 0:0785901b085e 131 }
jm 0:0785901b085e 132 }
jm 0:0785901b085e 133
jm 0:0785901b085e 134
jm 0:0785901b085e 135 /** @brief stepper Command Line Interface.
jm 0:0785901b085e 136 * This function controls the stepper
jm 0:0785901b085e 137 * Command Line Format: stepper (value)0..3 (direction)0..1 (PinA)0..432 (PinB)0..432 (delay)1..255 (steps)1..65535
jm 0:0785901b085e 138 * @param[in] Extracted from command line (value)0..3 (PinA)0..432 (PinB)0..432 (direction)0..1 (delay)1..255 (steps)1..65535
jm 0:0785901b085e 139 * @returns Message: GPPST id pinA pinB delay status
jm 0:0785901b085e 140 */
jm 0:0785901b085e 141 void cli_Stepper(void){
jm 0:0785901b085e 142 unsigned int id,cw, delay, steps, pinA, pinB, port, bitValue;
jm 0:0785901b085e 143
jm 0:0785901b085e 144 if(ExtractUInteger(pLine,&id,0,stepperQty-1)){ // extract stepper id
jm 0:0785901b085e 145 if(ExtractUInteger(pLine,&pinA,0,432)){ // extract pinA
jm 0:0785901b085e 146 if(ExtractUInteger(pLine,&pinB,0,432)){ // extract pinB
jm 0:0785901b085e 147 if(ExtractUInteger(pLine,&cw,0,1)){ // extract direction
jm 0:0785901b085e 148 if(ExtractUInteger(pLine,&delay,1,255)){ // extract step delay
jm 0:0785901b085e 149 if(!ExtractUInteger(pLine,&steps,1,65535)){ // check for optionnal steps arg
jm 0:0785901b085e 150 steps = nonStop; // default to nonStop
jm 0:0785901b085e 151 }
jm 0:0785901b085e 152
jm 0:0785901b085e 153 // Get ports, bit and bit values
jm 0:0785901b085e 154 sStepper[id].pinA=(uint8_t)pinA;
jm 0:0785901b085e 155 sStepper[id].pinB=(uint8_t)pinB;
jm 0:0785901b085e 156 port = pinA/100;
jm 0:0785901b085e 157 bitValue = 1<<(pinA%100);
jm 0:0785901b085e 158 sStepper[id].portCoilA = jmGPIO[port]; // Coil A port
jm 0:0785901b085e 159 sStepper[id].CoilA_bitValue = bitValue; // Coil A bit
jm 0:0785901b085e 160
jm 0:0785901b085e 161 port = pinB/100;
jm 0:0785901b085e 162 bitValue = 1<<(pinB%100);
jm 0:0785901b085e 163 sStepper[id].portCoilB = jmGPIO[port]; // Coil B port
jm 0:0785901b085e 164 sStepper[id].CoilB_bitValue = bitValue; // Coil B bit
jm 0:0785901b085e 165
jm 0:0785901b085e 166 sStepper[id].active = 1; // initialized true
jm 0:0785901b085e 167
jm 0:0785901b085e 168 // Port.Pin set to outputs
jm 0:0785901b085e 169 sStepper[id].portCoilA->FIODIR |= sStepper[id].CoilA_bitValue;
jm 0:0785901b085e 170 sStepper[id].portCoilB->FIODIR |= sStepper[id].CoilB_bitValue;
jm 0:0785901b085e 171
jm 0:0785901b085e 172 sStepper[id].cw =cw;
jm 0:0785901b085e 173 sStepper[id].delay = (uint8_t)delay;
jm 0:0785901b085e 174 sStepper[id].nSteps = (uint16_t)steps;
jm 0:0785901b085e 175
jm 0:0785901b085e 176 // chip report to GUI
jm 0:0785901b085e 177 rGPPST(id); //Message: GPPST id pinA pinB delay status
jm 0:0785901b085e 178
jm 0:0785901b085e 179 if(Feedback)printf("Stepper:%d PinA:%d PinB:%d CW:%d Delay:%d Steps:%d\n",id,pinA,pinB,cw,delay,steps);
jm 0:0785901b085e 180 return;
jm 0:0785901b085e 181 }// delay
jm 0:0785901b085e 182 }// direction
jm 0:0785901b085e 183 }// pinB
jm 0:0785901b085e 184 }// pinA
jm 0:0785901b085e 185 }// stepper number
jm 0:0785901b085e 186 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");
jm 0:0785901b085e 187 // Ignore pending command line
jm 0:0785901b085e 188 NextCommand(nl,pLine);
jm 0:0785901b085e 189 }
jm 0:0785901b085e 190
jm 0:0785901b085e 191 /** Module Get Module Process Properties Command Line Interface
jm 0:0785901b085e 192 * @brief Command Line Interface to Get Module Public Process Properties
jm 0:0785901b085e 193 * @param[in] id Extracted from command line id Process identification
jm 0:0785901b085e 194 * @returns Message: GPPST id pinA pinB delay status
jm 0:0785901b085e 195 */
jm 0:0785901b085e 196 void cli_GPPST(void)
jm 0:0785901b085e 197 { unsigned int id;
jm 0:0785901b085e 198 if(ExtractUInteger(pLine,&id,0,stepperQty-1)){ // extract id Number
jm 0:0785901b085e 199 rGPPST(id); // Message: GPPST id pinA pinB delay status
jm 0:0785901b085e 200 return;
jm 0:0785901b085e 201 }
jm 0:0785901b085e 202
jm 0:0785901b085e 203 if(Help)printf("GPPST (Stepper id)0..%d\n",stepperQty-1);
jm 0:0785901b085e 204 // Ignore pending command line
jm 0:0785901b085e 205 NextCommand(nl,pLine);
jm 0:0785901b085e 206 }
jm 0:0785901b085e 207
jm 0:0785901b085e 208 /** Public Properties Message
jm 0:0785901b085e 209 * @brief Send Process Properties to update GUI
jm 0:0785901b085e 210 * @param[in] id Process identification
jm 0:0785901b085e 211 * @returns Message: GPPST id pinA pinB ddelay status
jm 0:0785901b085e 212 */
jm 0:0785901b085e 213 void rGPPST(unsigned int id ){
jm 0:0785901b085e 214 int status;
jm 0:0785901b085e 215 if( sStepper[id].active )
jm 0:0785901b085e 216 { if(sStepper[id].nSteps == 0)status = stStopped;
jm 0:0785901b085e 217 else
jm 0:0785901b085e 218 {
jm 0:0785901b085e 219 if( sStepper[id].cw) status = stRunningCW;
jm 0:0785901b085e 220 else status = stRunningCCW;
jm 0:0785901b085e 221 }
jm 0:0785901b085e 222 }
jm 0:0785901b085e 223 else status = stNotInit;
jm 0:0785901b085e 224 printf("GPPST %d %d %d %d %d\n",id,sStepper[id].pinA,sStepper[id].pinB,sStepper[id].delay,status);
jm 0:0785901b085e 225 }