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