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