Jean Mercier
/
jmAll
Command all jmCLIG modules from serial port
jmMotor.c@0:9112e09912db, 2011-02-12 (annotated)
- Committer:
- jm
- Date:
- Sat Feb 12 16:50:25 2011 +0000
- Revision:
- 0:9112e09912db
jmAll Command Line Interface Module
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jm | 0:9112e09912db | 1 | /************************************************************************* |
jm | 0:9112e09912db | 2 | * @file jmMotor.c |
jm | 0:9112e09912db | 3 | * @version 1.0 |
jm | 0:9112e09912db | 4 | * @date Feb 12, 2011 |
jm | 0:9112e09912db | 5 | */ |
jm | 0:9112e09912db | 6 | |
jm | 0:9112e09912db | 7 | #include "jmMotor.h" |
jm | 0:9112e09912db | 8 | #include "LPC17xx.h" |
jm | 0:9112e09912db | 9 | #include "main.h" |
jm | 0:9112e09912db | 10 | #include "jmCommands.h" |
jm | 0:9112e09912db | 11 | #include "jmMessages.h" |
jm | 0:9112e09912db | 12 | #include "jmRingBuffer.h" |
jm | 0:9112e09912db | 13 | #include "stdio.h" |
jm | 0:9112e09912db | 14 | |
jm | 0:9112e09912db | 15 | #ifndef nonStop |
jm | 0:9112e09912db | 16 | #define nonStop 65535 // for continuous mode operation |
jm | 0:9112e09912db | 17 | #endif |
jm | 0:9112e09912db | 18 | |
jm | 0:9112e09912db | 19 | #define mtNotInit 0 |
jm | 0:9112e09912db | 20 | #define mtRunningCW 1 |
jm | 0:9112e09912db | 21 | #define mtRunningCCW 2 |
jm | 0:9112e09912db | 22 | #define mtStopped 3 |
jm | 0:9112e09912db | 23 | |
jm | 0:9112e09912db | 24 | // Module Data Structure |
jm | 0:9112e09912db | 25 | struct StructMotor sMotor[motorQty]; // static creation |
jm | 0:9112e09912db | 26 | |
jm | 0:9112e09912db | 27 | /** Module Data Structure Initialization |
jm | 0:9112e09912db | 28 | * @brief All State Machines non initialized |
jm | 0:9112e09912db | 29 | * @param[in] none |
jm | 0:9112e09912db | 30 | * @returns none |
jm | 0:9112e09912db | 31 | */ |
jm | 0:9112e09912db | 32 | void MotorInit(void){ |
jm | 0:9112e09912db | 33 | int i; |
jm | 0:9112e09912db | 34 | for(i=0;i<motorQty;i++){ |
jm | 0:9112e09912db | 35 | sMotor[i].active = mtNotInit; |
jm | 0:9112e09912db | 36 | } |
jm | 0:9112e09912db | 37 | } |
jm | 0:9112e09912db | 38 | |
jm | 0:9112e09912db | 39 | /** Speed control for motors (1 or up to 4) |
jm | 0:9112e09912db | 40 | * @brief motorSpeed Command Line Interface. |
jm | 0:9112e09912db | 41 | * Format: command name (arg info)min..max values |
jm | 0:9112e09912db | 42 | * motorSpeed (Motor IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255 |
jm | 0:9112e09912db | 43 | * @param[in] Extracted from command line (Motor IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255 |
jm | 0:9112e09912db | 44 | * @returns Message: motorSpeed ids tOn tOff |
jm | 0:9112e09912db | 45 | */ |
jm | 0:9112e09912db | 46 | void cli_MotorSpeed(void){ |
jm | 0:9112e09912db | 47 | unsigned int id, i, tOn,tOff; |
jm | 0:9112e09912db | 48 | if(ExtractUInteger(pLine,&id,1,15)){ //extract id |
jm | 0:9112e09912db | 49 | if(ExtractUInteger(pLine,&tOn,0,255)){ //extract tOn |
jm | 0:9112e09912db | 50 | if(ExtractUInteger(pLine,&tOff,0,255)){ //extract tOff |
jm | 0:9112e09912db | 51 | for(i=0;i<motorQty;i++){ // check each motor |
jm | 0:9112e09912db | 52 | if(id & 1<<i){ // motor included ? |
jm | 0:9112e09912db | 53 | if(sMotor[i].active){ // motor initialized ? |
jm | 0:9112e09912db | 54 | sMotor[i].tOn=(uint8_t)tOn; |
jm | 0:9112e09912db | 55 | sMotor[i].tOff=(uint8_t)tOff; |
jm | 0:9112e09912db | 56 | |
jm | 0:9112e09912db | 57 | |
jm | 0:9112e09912db | 58 | if(tOn==0){ // 0% ? |
jm | 0:9112e09912db | 59 | sMotor[i].cycles=0; |
jm | 0:9112e09912db | 60 | sMotor[i].drivePort->FIOPIN &= ~sMotor[i].driveBitValue; // output pin low |
jm | 0:9112e09912db | 61 | } |
jm | 0:9112e09912db | 62 | |
jm | 0:9112e09912db | 63 | if(tOff==0){ // 100% ? |
jm | 0:9112e09912db | 64 | sMotor[i].drivePort->FIOPIN |= sMotor[i].driveBitValue; // output pin high |
jm | 0:9112e09912db | 65 | } |
jm | 0:9112e09912db | 66 | |
jm | 0:9112e09912db | 67 | if(tOn!=0 && tOff!=0){ // PWM ? |
jm | 0:9112e09912db | 68 | // change motor tOn and tOff values |
jm | 0:9112e09912db | 69 | sMotor[i].cycles=nonStop; |
jm | 0:9112e09912db | 70 | } |
jm | 0:9112e09912db | 71 | // report to gui |
jm | 0:9112e09912db | 72 | rGPPMT(i); |
jm | 0:9112e09912db | 73 | } |
jm | 0:9112e09912db | 74 | } |
jm | 0:9112e09912db | 75 | } |
jm | 0:9112e09912db | 76 | } |
jm | 0:9112e09912db | 77 | } |
jm | 0:9112e09912db | 78 | |
jm | 0:9112e09912db | 79 | if(Feedback)printf("MotorSpeed ID %d tOn %d tOff %d\n",id,tOn, tOff); |
jm | 0:9112e09912db | 80 | return; |
jm | 0:9112e09912db | 81 | } |
jm | 0:9112e09912db | 82 | if(Help)printf("motorSpeed (Motor IDs ORed)1..15 (tOn Value)1..255 (tOff Value)1..255\n"); |
jm | 0:9112e09912db | 83 | // Ignore pending command line |
jm | 0:9112e09912db | 84 | NextCommand(nl,pLine); |
jm | 0:9112e09912db | 85 | } |
jm | 0:9112e09912db | 86 | |
jm | 0:9112e09912db | 87 | |
jm | 0:9112e09912db | 88 | /*********************************************************************** |
jm | 0:9112e09912db | 89 | * @brief Module State Machine. |
jm | 0:9112e09912db | 90 | * Enable different motor control concurrently. |
jm | 0:9112e09912db | 91 | * @param none |
jm | 0:9112e09912db | 92 | * @returns Message at end of cycles: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 93 | */ |
jm | 0:9112e09912db | 94 | void MotorSM(void){ |
jm | 0:9112e09912db | 95 | int i; |
jm | 0:9112e09912db | 96 | for(i=0;i<motorQty;i++){ // for each SM define by pins |
jm | 0:9112e09912db | 97 | // SM active ? |
jm | 0:9112e09912db | 98 | if(!sMotor[i].active) continue; |
jm | 0:9112e09912db | 99 | |
jm | 0:9112e09912db | 100 | if(sMotor[i].cycles!=0){ // Cycles to DO ? |
jm | 0:9112e09912db | 101 | switch(sMotor[i].state){ |
jm | 0:9112e09912db | 102 | |
jm | 0:9112e09912db | 103 | // pulse is low |
jm | 0:9112e09912db | 104 | case 0: if(sMotor[i].eggTimer==0){ // time to change ? |
jm | 0:9112e09912db | 105 | sMotor[i].drivePort->FIOPIN |= sMotor[i].driveBitValue; // set pin High |
jm | 0:9112e09912db | 106 | sMotor[i].eggTimer=sMotor[i].tOn; // load timer with tOn |
jm | 0:9112e09912db | 107 | sMotor[i].state=1; // next state |
jm | 0:9112e09912db | 108 | } |
jm | 0:9112e09912db | 109 | break; |
jm | 0:9112e09912db | 110 | |
jm | 0:9112e09912db | 111 | // pulse is High |
jm | 0:9112e09912db | 112 | case 1: if(sMotor[i].eggTimer==0){ // time to change ? |
jm | 0:9112e09912db | 113 | sMotor[i].drivePort->FIOPIN &= ~sMotor[i].driveBitValue; // reset pin low |
jm | 0:9112e09912db | 114 | sMotor[i].eggTimer=sMotor[i].tOff; // load timer with tOff |
jm | 0:9112e09912db | 115 | if(sMotor[i].cycles != nonStop){ // continuous mode ? |
jm | 0:9112e09912db | 116 | if(--sMotor[i].cycles == 0) // decrease qty if not continuous mode |
jm | 0:9112e09912db | 117 | rGPPMT(i); // Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 118 | } |
jm | 0:9112e09912db | 119 | sMotor[i].state=0; // state 0 |
jm | 0:9112e09912db | 120 | } |
jm | 0:9112e09912db | 121 | break; |
jm | 0:9112e09912db | 122 | }//switch |
jm | 0:9112e09912db | 123 | }//if |
jm | 0:9112e09912db | 124 | }//for |
jm | 0:9112e09912db | 125 | }//MotorSM |
jm | 0:9112e09912db | 126 | |
jm | 0:9112e09912db | 127 | |
jm | 0:9112e09912db | 128 | /** @brief motor Command Line Interface |
jm | 0:9112e09912db | 129 | * Command Line Interface to control Motor on mbed pins DIP5 to 30. |
jm | 0:9112e09912db | 130 | * Format: command name (arg info)min..max values |
jm | 0:9112e09912db | 131 | * Command Line Format: motor (Motor ID)0..3 (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535] |
jm | 0:9112e09912db | 132 | * @param[in] Extracted from command line ((Motor ID)0..3 (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)1..255 (tOff)1..255 (Cycles)[1..65535] |
jm | 0:9112e09912db | 133 | * @returns Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 134 | */ |
jm | 0:9112e09912db | 135 | void cli_Motor(void){ |
jm | 0:9112e09912db | 136 | unsigned int id,dirPin,drivePin, dir, tOn,tOff,cycles; |
jm | 0:9112e09912db | 137 | |
jm | 0:9112e09912db | 138 | if(ExtractUInteger(pLine,&id,0,motorQty-1)){ // extract motor id |
jm | 0:9112e09912db | 139 | if(ExtractUInteger(pLine,&dirPin,0,432)){ // extract direction pin |
jm | 0:9112e09912db | 140 | if(ExtractUInteger(pLine,&drivePin,0,432)){ // extract drive pin |
jm | 0:9112e09912db | 141 | if(ExtractUInteger(pLine,&dir,0,1)){ // extract direction |
jm | 0:9112e09912db | 142 | if(ExtractUInteger(pLine,&tOn,0,255)){ // extract tOn |
jm | 0:9112e09912db | 143 | if(ExtractUInteger(pLine,&tOff,0,255)){ // extract tOff |
jm | 0:9112e09912db | 144 | // extract cycles and test for nonStop mode |
jm | 0:9112e09912db | 145 | if(!ExtractUInteger(pLine,&cycles,1,nonStop))cycles = nonStop; |
jm | 0:9112e09912db | 146 | |
jm | 0:9112e09912db | 147 | sMotor[id].dirBitValue = 1<<(dirPin%100); |
jm | 0:9112e09912db | 148 | sMotor[id].driveBitValue = 1<<(drivePin%100);; |
jm | 0:9112e09912db | 149 | sMotor[id].drivePort = jmGPIO[drivePin/100]; |
jm | 0:9112e09912db | 150 | sMotor[id].dirPort = jmGPIO[dirPin/100]; |
jm | 0:9112e09912db | 151 | sMotor[id].active = 1; |
jm | 0:9112e09912db | 152 | |
jm | 0:9112e09912db | 153 | // Port.Pin set to outputs |
jm | 0:9112e09912db | 154 | sMotor[id].dirPort->FIODIR |= sMotor[id].dirBitValue; |
jm | 0:9112e09912db | 155 | sMotor[id].drivePort->FIODIR |= sMotor[id].driveBitValue; |
jm | 0:9112e09912db | 156 | |
jm | 0:9112e09912db | 157 | sMotor[id].direction = dir; |
jm | 0:9112e09912db | 158 | sMotor[id].tOn = (uint8_t)tOn; |
jm | 0:9112e09912db | 159 | sMotor[id].tOff = (uint8_t)tOff; |
jm | 0:9112e09912db | 160 | sMotor[id].cycles = (uint16_t)cycles; |
jm | 0:9112e09912db | 161 | sMotor[id].state = 0; |
jm | 0:9112e09912db | 162 | sMotor[id].eggTimer = 0; |
jm | 0:9112e09912db | 163 | sMotor[id].dirPin = dirPin; |
jm | 0:9112e09912db | 164 | sMotor[id].drivePin = drivePin; |
jm | 0:9112e09912db | 165 | |
jm | 0:9112e09912db | 166 | // set output direction bit according to given direction |
jm | 0:9112e09912db | 167 | if(dir) sMotor[id].dirPort->FIOPIN |= sMotor[id].dirBitValue; |
jm | 0:9112e09912db | 168 | else sMotor[id].dirPort->FIOPIN &= ~sMotor[id].dirBitValue; |
jm | 0:9112e09912db | 169 | |
jm | 0:9112e09912db | 170 | // 100% |
jm | 0:9112e09912db | 171 | if(tOff==0){ |
jm | 0:9112e09912db | 172 | sMotor[id].drivePort->FIOPIN |= sMotor[id].driveBitValue; |
jm | 0:9112e09912db | 173 | // SM off |
jm | 0:9112e09912db | 174 | sMotor[id].cycles = 0; |
jm | 0:9112e09912db | 175 | } |
jm | 0:9112e09912db | 176 | |
jm | 0:9112e09912db | 177 | // 0% |
jm | 0:9112e09912db | 178 | if(tOn==0){ |
jm | 0:9112e09912db | 179 | sMotor[id].drivePort->FIOPIN &= ~sMotor[id].driveBitValue; |
jm | 0:9112e09912db | 180 | // SM off |
jm | 0:9112e09912db | 181 | sMotor[id].cycles = 0; |
jm | 0:9112e09912db | 182 | } |
jm | 0:9112e09912db | 183 | |
jm | 0:9112e09912db | 184 | rGPPMT(id); // Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 185 | |
jm | 0:9112e09912db | 186 | if(Feedback)printf("Motor %d DirPin %d DrivePin %d Dir %d tOn %d tOff %d Cycles %d\n",id, |
jm | 0:9112e09912db | 187 | dirPin, drivePin, dir,tOn,tOff,cycles); |
jm | 0:9112e09912db | 188 | return; |
jm | 0:9112e09912db | 189 | } |
jm | 0:9112e09912db | 190 | } |
jm | 0:9112e09912db | 191 | } |
jm | 0:9112e09912db | 192 | } |
jm | 0:9112e09912db | 193 | } |
jm | 0:9112e09912db | 194 | // Ignore pending command line |
jm | 0:9112e09912db | 195 | NextCommand(nl,pLine); |
jm | 0:9112e09912db | 196 | return; |
jm | 0:9112e09912db | 197 | } |
jm | 0:9112e09912db | 198 | |
jm | 0:9112e09912db | 199 | if(Help)printf("motor (Motor ID)0..%d (Direction Pin)0..432 (Drive Pin)0..432 (Direction)0..1 (tOn)0..255 (tOff)0..255 (Cycles)[1..65535]\n",motorQty-1); |
jm | 0:9112e09912db | 200 | // Ignore pending command line |
jm | 0:9112e09912db | 201 | NextCommand(nl,pLine); |
jm | 0:9112e09912db | 202 | } |
jm | 0:9112e09912db | 203 | |
jm | 0:9112e09912db | 204 | /** Module Get Module Process Properties Command Line Interface |
jm | 0:9112e09912db | 205 | * @brief Command Line Interface to Get Module Public Process Properties |
jm | 0:9112e09912db | 206 | * @param[in] id Extracted from command line |
jm | 0:9112e09912db | 207 | * @returns Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 208 | */ |
jm | 0:9112e09912db | 209 | void cli_GPPMT(void) |
jm | 0:9112e09912db | 210 | { unsigned int id; |
jm | 0:9112e09912db | 211 | if(ExtractUInteger(pLine,&id,0,motorQty-1)){ // extract id |
jm | 0:9112e09912db | 212 | rGPPMT(id); // Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 213 | return; |
jm | 0:9112e09912db | 214 | } |
jm | 0:9112e09912db | 215 | |
jm | 0:9112e09912db | 216 | if(Help)printf("GPPST (Motor id)0..%d\n",motorQty-1); |
jm | 0:9112e09912db | 217 | // Ignore pending command line |
jm | 0:9112e09912db | 218 | NextCommand(nl,pLine); |
jm | 0:9112e09912db | 219 | } |
jm | 0:9112e09912db | 220 | |
jm | 0:9112e09912db | 221 | /** Public Properties Message |
jm | 0:9112e09912db | 222 | * @brief Send Process Properties to update GUI |
jm | 0:9112e09912db | 223 | * @param[in] id Process identification |
jm | 0:9112e09912db | 224 | * @returns Message: GPPMT id dirPin drivePinB tOn tOff status |
jm | 0:9112e09912db | 225 | */ |
jm | 0:9112e09912db | 226 | void rGPPMT(unsigned int id ){ |
jm | 0:9112e09912db | 227 | int status; |
jm | 0:9112e09912db | 228 | if( sMotor[id].active ) |
jm | 0:9112e09912db | 229 | { if(sMotor[id].cycles == 0)status = mtStopped; |
jm | 0:9112e09912db | 230 | else |
jm | 0:9112e09912db | 231 | { |
jm | 0:9112e09912db | 232 | if( sMotor[id].direction) status = mtRunningCW; |
jm | 0:9112e09912db | 233 | else status = mtRunningCCW; |
jm | 0:9112e09912db | 234 | } |
jm | 0:9112e09912db | 235 | } |
jm | 0:9112e09912db | 236 | else status = mtNotInit; |
jm | 0:9112e09912db | 237 | printf("GPPMT %d %d %d %d %d %d\n",id,sMotor[id].dirPin,sMotor[id].drivePin,sMotor[id].tOn,sMotor[id].tOff,status); |
jm | 0:9112e09912db | 238 | } |