2 bit Bridge Driver

Committer:
jm
Date:
Sat Feb 19 01:30:54 2011 +0000
Revision:
0:bfa30f27fe9d
jmBridge Module

Who changed what in which revision?

UserRevisionLine numberNew 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 }