Jean Mercier
/
jmBridge
2 bit Bridge Driver
Diff: jmBridge.c
- Revision:
- 0:bfa30f27fe9d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jmBridge.c Sat Feb 19 01:30:54 2011 +0000 @@ -0,0 +1,256 @@ +/************************************************************************* + * @file jmBridge.c + * @version 1.0 + * @date Feb 18, 2011 + */ + +#include "jmBridge.h" +#include "jmRingBuffer.h" +#include "LPC17xx.h" +#include "main.h" +#include "jmCommands.h" +#include "jmMessages.h" +#include "stdio.h" + +#define ActiveLevelLow +#include "ActiveLevel.h" + +#ifndef nonStop + #define nonStop 65535 // for continuous mode operation +#endif + +#define bdNotInit 0 +#define bdRunningCW 1 +#define bdRunningCCW 2 +#define bdStopped 3 + +// Module Data Structure +struct StructBridge sBridge[bridgeQty]; // static creation + +/** Module Data Structure Initialization + * @brief All State Machines non initialized + * @param[in] none + * @returns none + */ +void BridgeInit(void){ + int i; + for(i=0;i<bridgeQty;i++){ + sBridge[i].active = bdNotInit; + } +} + +/** Bridge DC control (1 or up to 4) + * @brief bridgeDC Command Line Interface. + * Format: command name (arg info)min..max values + * bridgeDC (Bridge IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255 + * @param[in] Extracted from command line (Bridge IDs ORed)1..15 (tOn Value)0..255 (tOff Value)0..255 + * @returns Message: bridgeDC ids tOn tOff + */ +void cli_BridgeDC(void){ + unsigned int id, i, tOn,tOff; + if(ExtractUInteger(pLine,&id,1,15)){ //extract id + if(ExtractUInteger(pLine,&tOn,0,255)){ //extract tOn + if(ExtractUInteger(pLine,&tOff,0,255)){ //extract tOff + for(i=0;i<bridgeQty;i++){ // check each motor + if(id & 1<<i){ // motor included ? + if(sBridge[i].active){ // motor initialized ? + sBridge[i].tOn=(uint8_t)tOn; + sBridge[i].tOff=(uint8_t)tOff; + + if(tOn==0){ // 0% ? + sBridge[i].cycles=0; + // Inactive output according to active level selection + Inactive(sBridge[i].driveBitValue,sBridge[i].drivePort->FIOPIN); + } + + if(tOff==0){ // 100% ? + // Active output according to active level selection + Active(sBridge[i].driveBitValue,sBridge[i].drivePort->FIOPIN); + } + + if(tOn!=0 && tOff!=0){ // PWM ? + // change motor tOn and tOff values + sBridge[i].cycles=nonStop; + } + // report to gui + rGPPBD(i); + } + } + } + } + } + + if(Feedback)printf("BridgeDC ID %d tOn %d tOff %d\n",id,tOn, tOff); + return; + } + if(Help)printf("bridgeDC (Bridge IDs ORed)1..15 (tOn Value)1..255 (tOff Value)1..255\n"); + // Ignore pending command line + NextCommand(nl,pLine); +} + + +/*********************************************************************** + * @brief Module State Machine. + * Enable different bridges control concurrently. + * @param none + * @returns Message at end of cycles: GPPBD id pinA pinB tOn tOff status + */ +void BridgeSM(void){ + int i; + for(i=0;i<bridgeQty;i++){ // for each SM define by pins + // SM active ? + if(!sBridge[i].active) continue; + + if(sBridge[i].cycles!=0){ // Cycles to DO ? + switch(sBridge[i].state){ + + // pulse is low + case 0: if(sBridge[i].eggTimer==0){ // time to change ? + // Active output according to active level selection + Active(sBridge[i].driveBitValue,sBridge[i].drivePort->FIOPIN); + sBridge[i].eggTimer=sBridge[i].tOn; // load timer with tOn + sBridge[i].state=1; // next state + } + break; + + // pulse is High + case 1: if(sBridge[i].eggTimer==0){ // time to change ? + // Inactive output according to active level selection + Inactive(sBridge[i].driveBitValue,sBridge[i].drivePort->FIOPIN); + sBridge[i].eggTimer=sBridge[i].tOff; // load timer with tOff + if(sBridge[i].cycles != nonStop){ // continuous mode ? + if(--sBridge[i].cycles == 0) // decrease qty if not continuous mode + rGPPBD(i); // Message: GPPBD id pinA pinB tOn tOff status + } + sBridge[i].state=0; // state 0 + } + break; + }//switch + }//if + }//for +}//BridgeSM + + +/** @brief Bridge Command Line Interface + * Command Line Interface to control Bridge on mbed pins DIP5 to 30. + * Format: command name (arg info)min..max values + * 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] + * @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] + * @returns Message: GPPBD id pinA pinB tOn tOff status + */ +void cli_Bridge(void){ + unsigned int id,pinA,pinB, dir, tOn,tOff,cycles; + + if(ExtractUInteger(pLine,&id,0,bridgeQty-1)){ // extract motor id + if(ExtractUInteger(pLine,&pinA,0,432)){ // extract pinA pin + if(ExtractUInteger(pLine,&pinB,0,432)){ // extract pinB pin + if(ExtractUInteger(pLine,&dir,0,1)){ // extract direction + if(ExtractUInteger(pLine,&tOn,0,255)){ // extract tOn + if(ExtractUInteger(pLine,&tOff,0,255)){ // extract tOff + // extract cycles and test for nonStop mode + if(!ExtractUInteger(pLine,&cycles,1,nonStop))cycles = nonStop; + + sBridge[id].active = 1; + sBridge[id].direction = dir; + sBridge[id].tOn = (uint8_t)tOn; + sBridge[id].tOff = (uint8_t)tOff; + sBridge[id].cycles = (uint16_t)cycles; + sBridge[id].state = 0; + sBridge[id].eggTimer = 0; + sBridge[id].pinA = pinA; + sBridge[id].pinB = pinB; + + // the bridge driver that uses this software needs to switch + // dir and drive pins when you reverse direction + if(dir) + { // direction on pinA and drive on pinB + sBridge[id].dirBitValue = 1<<(pinA%100); + sBridge[id].dirPort = jmGPIO[pinA/100]; + sBridge[id].driveBitValue = 1<<(pinB%100);; + sBridge[id].drivePort = jmGPIO[pinB/100]; + } + else + { // direction on pinB and drive on pinA + sBridge[id].dirBitValue = 1<<(pinB%100); + sBridge[id].dirPort = jmGPIO[pinB/100]; + sBridge[id].driveBitValue = 1<<(pinA%100);; + sBridge[id].drivePort = jmGPIO[pinA/100]; + } + + // PinA, PinB directions to outputs + sBridge[id].dirPort->FIODIR |= sBridge[id].dirBitValue; + sBridge[id].drivePort->FIODIR |= sBridge[id].driveBitValue; + + + // Assert direction pin + Inactive(sBridge[id].dirBitValue,sBridge[id].dirPort->FIOPIN); + + // 100% + if(tOff==0){ + Active(sBridge[id].driveBitValue,sBridge[id].drivePort->FIOPIN); + // SM off + sBridge[id].cycles = 0; + } + + // 0% + if(tOn==0){ + Inactive(sBridge[id].driveBitValue,sBridge[id].drivePort->FIOPIN); + // SM off + sBridge[id].cycles = 0; + } + + rGPPBD(id); // Message: GPPBD id pinA pinB tOn tOff status + + if(Feedback)printf("Bridge %d pinA %d pinB %d Dir %d tOn %d tOff %d Cycles %d\n",id, + pinA, pinB, dir,tOn,tOff,cycles); + return; + } + } + } + } + } + // Ignore pending command line + NextCommand(nl,pLine); + return; + } + + 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); + // Ignore pending command line + NextCommand(nl,pLine); +} + +/** Module Get Module Process Properties Command Line Interface + * @brief Command Line Interface to Get Module Public Process Properties + * @param[in] id Extracted from command line + * @returns Message: GPPBD id pinA pinB tOn tOff status + */ +void cli_GPPBD(void) +{ unsigned int id; + if(ExtractUInteger(pLine,&id,0,bridgeQty-1)){ // extract id + rGPPBD(id); // Message: GPPBD id pinA pinB tOn tOff status + return; + } + + if(Help)printf("GPPST (Bridge id)0..%d\n",bridgeQty-1); + // Ignore pending command line + NextCommand(nl,pLine); +} + +/** Public Properties Message + * @brief Send Process Properties to update GUI + * @param[in] id Process identification + * @returns Message: GPPBD id pinA pinB tOn tOff status + */ +void rGPPBD(unsigned int id ){ + int status; + if( sBridge[id].active ) + { if(sBridge[id].cycles == 0)status = bdStopped; + else + { + if( sBridge[id].direction) status = bdRunningCW; + else status = bdRunningCCW; + } + } + else status = bdNotInit; + printf("GPPBD %d %d %d %d %d %d\n",id,sBridge[id].pinA,sBridge[id].pinB,sBridge[id].tOn,sBridge[id].tOff,status); +}