Andy Lustig / Mbed 2 deprecated stateScript_v2_karpova

Dependencies:   SMARTWAV mbed

Fork of stateScript_v2 by Mattias Karlsson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers behave.h Source File

behave.h

00001 //#include "mbed.h"
00002 #include <stdint.h>
00003 #include <string.h>
00004 #include <string>
00005 #include <vector>
00006 #include <list>
00007 #include <deque>
00008 #include <queue>
00009 #include "hardwareInterface.h"
00010 
00011 
00012 #define MBEDHARDWARE  //here is where we define which platform we are compiling for
00013 //#define FPGAHARDWARE
00014 
00015 #define MAXVARNAMESIZE 30 //The maximum number of characters of a variable name
00016 
00017 
00018 
00019 
00020 
00021 #ifdef MBEDHARDWARE
00022     #include "mbedInterface.h"
00023 #endif
00024 #ifdef FPGAHARDWARE
00025     #include "fpgaInterface.h"
00026 #endif
00027 
00028 /*
00029 #define NUMEVENTS 50
00030 #define NUMCONDITIONS 150
00031 #define NUMINTCOMPARE 150
00032 #define NUMACTIONS 150
00033 #define NUMPORTMESSAGES 150
00034 #define NUMINTOPERATIONS 150
00035 #define NUMDISPLAYACTIONS 30
00036 #define NUMTRIGGERACTIONS 30
00037 #define NUMFUNCTIONS 50
00038 #define INPUTCHARBUFFERSIZE 3072
00039 */
00040 
00041 #define ARITHMATIC_CONDITION    0
00042 #define OR_CONDITION    1
00043 #define AND_CONDITION    2
00044 
00045 extern "C" void mbed_reset();//reset mbed through software
00046 
00047 
00048 
00049 using namespace std;
00050 
00051 class event; //we foreward declare this because of class interdependencies
00052 
00053 //used in the digital port class to organize digital change events
00054 /*
00055 struct changeEvent {
00056     uint32_t timeStamp;
00057     bool triggered;
00058 };*/
00059 
00060 
00061 //The digitalPort object directly controls and keeps data about the port. Each port has
00062 //one digital out and one digital in.
00063 class digitalPort {
00064 public:
00065     digitalPort();
00066     //digitalPort(sDigitalOut* DOP, sDigitalIn* DIP);
00067     void init(sDigitalOut* DOP, sDigitalIn* DIP);
00068     void setDigitalOut(int outVal);
00069     //int  getDigitalOut();
00070     int  getDigitalIn();
00071     int getLastChangeState();
00072     uint32_t getTimeSinceLastChange();
00073     uint32_t lastChangeTime;
00074     uint32_t lastOutChangeTime;
00075 
00076     void setTriggerUpEvent(event* eventInput); //attahces a routine to an upward change
00077     void setTriggerDownEvent(event* eventInput); //attahces a routine to a downward change
00078     //void addStateChange(int newState, uint32_t timeStamp);
00079 
00080     bool update(); //called from the main loop
00081 
00082     int inState;
00083     int outState;
00084 
00085     bool outStateChanged;
00086 
00087     event* triggerUpEventPtr;
00088     event* triggerDownEventPtr;
00089 
00090 private:
00091 
00092     sDigitalOut* outPin;
00093     sDigitalIn*  inPin;
00094     int lastInState;
00095     uint32_t lastChangeInterval;
00096 
00097     //changeEvent lastUpEvent;
00098     //changeEvent lastDownEvent;
00099 };
00100 
00101 
00102 //an intVariable contains an integer value and the name of that variable within the script
00103 class intVariable {
00104 
00105 public:
00106     intVariable();
00107     intVariable(std::string& tagInput, int initialValue);
00108     void set(std::string& tagInput, int initialValue);
00109     int value;
00110     //string tag;
00111     char tag[MAXVARNAMESIZE+1];
00112     bool isUsed;
00113 
00114 };
00115 
00116 
00117 //ACTION SECTION-- an 'action' is a command in the script. It can be a single command,
00118 //or a block containing a set of actions
00119 //------------------------------------------------------------------------------------
00120 
00121 //display actions are used to output text messages via the serial port.  The user can display
00122 //either a static text string or the value of a single variable.
00123 class displayAction {
00124 
00125 public:
00126     displayAction();
00127     void set(int* variable, string varNameInput);
00128     void set(string text);
00129     bool isUsed;
00130     void execute();
00131     void release();
00132 
00133 private:
00134     int* dVariable;
00135     string dText;
00136 
00137 };
00138 
00139 class triggerFunctionAction {
00140 
00141 public:
00142     triggerFunctionAction();
00143     triggerFunctionAction(int functionNum);
00144     void set(int functionNum);
00145     bool isUsed;
00146     void execute();
00147     void release();
00148 private:
00149     int functionNum;
00150 
00151 
00152 };
00153 
00154 //intOpertaion is an action that does addition or subtraction of integers and returns/stores the result
00155 //these operation are very limited so far (only + or - allowed, and only one operation per object,
00156 //for example a = b + b works but a = b + c + d does not. The output value can also be set to a random number.
00157 class intOperation {
00158 
00159 public:
00160     intOperation();
00161 
00162     /*
00163      intOperation(int randParam, const char* cmpString, int cmpValInput);
00164      intOperation(int randParam, const char* cmpString, int* cmpIntVarInput);
00165      intOperation(int* intVarInput, const char* cmpString, int cmpValInput);
00166      intOperation(int* intVarInput, const char* cmpString, int* cmpIntVarInput);
00167      intOperation(int* intVarInput, intOperation* operationInput);
00168      */
00169 
00170     ~intOperation();
00171 
00172     //Supported operations with rand:
00173     //a = rand(x)
00174     //a = rand(x) + 3
00175     //a = rand(x) + b
00176     void setRandOp(int randParam, const char* cmpString, int cmpValInput, bool flipped);
00177     void setRandOp(int randParam, const char* cmpString, int* cmpIntVarInput, bool flipped);
00178 
00179     //Supported regular operations
00180     //a = 5
00181     //a = b
00182     //a = b + 6
00183     //a = b + c
00184     void set(int* intVarInput, const char* cmpString, int cmpValInput);
00185     void set(int* intVarInput, const char* cmpString, int* cmpIntVarInput);
00186     void set(int* intVarInput, intOperation* operationInput);
00187 
00188 
00189     //Supported operations with clock()
00190     //a = clock()
00191     //a = clock() + 5
00192     //a = clock() + b
00193     void setClockOp(int* intVarInput);
00194     void setClockOp(const char* cmpString, int cmpValInput, bool flip);
00195     void setClockOp(const char* cmpString, int* cmpIntVarInput, bool flip);
00196 
00197     void release();
00198     bool isUsed;
00199     int execute();
00200 
00201 private:
00202     int randHigh;
00203     int* cmpVal;
00204     int* intVal;
00205     intOperation* opPtr;
00206     bool cmpValGlobal;
00207     bool isClockAssign; //if the current clock value is part of the operation
00208     bool inputsFlipped;
00209     int (intOperation::*executePtr)();
00210     int addAndStore();
00211     int subtractAndStore();
00212     int add();
00213     int subtract();
00214     int equals();
00215 
00216 };
00217 
00218 //portMessage is an action to change a digital port.  So far, You can only change the digital out (0 or 1)
00219 class portMessage {
00220 public:
00221 
00222     portMessage();
00223     //portMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State
00224     //void setMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State
00225     //portMessage(int* portIn, int whichToSet, int value); //whichToSet:
00226     void setMessage(int* portIn, int whichToSet, int value, digitalPort* portVector); //whichToSet:
00227 
00228     void execute();
00229     void release();
00230     bool isUsed;
00231 
00232 private:
00233     int whichToSet; //hard coded port number
00234     int* port; //alternative variable port number
00235     int value;
00236 
00237     digitalPort* portVector;
00238 
00239 };
00240 
00241 //holder class for all possible actions. This include general system commands.
00242 class action {
00243 public:
00244 
00245     action();
00246     ~action();
00247     action(intOperation* opInput);
00248     action(portMessage* messageInput);
00249     action(event* eventInput);
00250     //action(event* eventInput, uint32_t delay);
00251     action(displayAction* displayInput);
00252     action(sSound* soundInput);
00253     action(triggerFunctionAction* triggerFuncInput);
00254     action(int8_t sysCommandInput); //for general system commands
00255 
00256     void set(intOperation* opInput);
00257     void set(portMessage* messageInput);
00258     void set(event* eventInput);
00259     //void set(event* eventInput, uint32_t delay);
00260 
00261     void set(displayAction* displayInput);
00262     void set(sSound* soundInput);
00263     void set(triggerFunctionAction* triggerFuncInput);
00264     void set(int8_t sysCommandInput);
00265     void execute();
00266     void execute(uint32_t blockExecTime);
00267     void release();
00268     bool isUsed;
00269 
00270 private:
00271     intOperation* op;
00272     portMessage* message;
00273     event* eventToCreate;
00274     displayAction* displayActionPtr;
00275     sSound* sound;
00276     triggerFunctionAction* triggerFunc;
00277     //uint32_t eventDelay;
00278     int8_t sysCommand;
00279     char actionType;
00280 
00281 };
00282 //-----------------------------------------------------
00283 
00284 //CONDITION SECTION-- a 'condition' is used in the beginning of a block (if-else blocks or while blocks)
00285 //If the condition is true, the block is exectuted during a callback
00286 //------------------------------------------------------------------------------------
00287 
00288 
00289 //intCompare is a condition class that compares the state value of a port or
00290 //an integer variable to another integer variable or operation output
00291 class intCompare {
00292 
00293 public:
00294     intCompare();
00295     intCompare(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse);
00296     intCompare(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse);
00297     intCompare(int* intVarInput, const char* cmpString, int cmpValInput);
00298     intCompare(int* intVarInput, const char* cmpString, int* cmpIntVarInput);
00299     intCompare(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput);
00300     intCompare(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse);
00301 
00302     void set(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse);
00303     void set(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse);
00304     void set(int* intVarInput, const char* cmpString, int cmpValInput);
00305     void set(int* intVarInput, const char* cmpString, int* cmpIntVarInput);
00306     void set(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput);
00307     void set(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse);
00308 
00309     void release();
00310 
00311     ~intCompare();
00312     bool isTrue();
00313     bool isUsed;
00314 
00315 private:
00316     digitalPort* port;
00317     int* portValPtr;
00318     int* cmpVal;
00319     int* intVal;
00320     intOperation* intOp;
00321     void setPointer(const char* cmpString);
00322     void setPointer_operation(const char* cmpString);
00323     bool (intCompare::*isTruePtr)();
00324     bool cmpValGlobal;
00325     bool greaterThan();
00326     bool greaterOrEqual();
00327     bool lessThan();
00328     bool lessOrEqual();
00329     bool equal();
00330     bool notEqual();
00331     bool greaterThan_op();
00332     bool greaterOrEqual_op();
00333     bool lessThan_op();
00334     bool lessOrEqual_op();
00335     bool equal_op();
00336     bool notEqual_op();
00337 };
00338 
00339 
00340 //holder class for all possible conditions (so far only intCompare)
00341 class condition {
00342 public:
00343 
00344     condition();
00345     condition(intCompare* compareInput);
00346     condition(condition* condition1, char condType, condition* condition2);
00347     ~condition();
00348     void set(intCompare* compareInput);
00349     void set(condition* condition1, char condType, condition* condition2);
00350     bool isTrue();
00351     bool isUsed;
00352     void release(); //called when the event is no longer being used;
00353 private:
00354 
00355     //char conditionType; //1 for intCompare
00356     intCompare* intCmp;
00357     condition*  conditionPtrs[2];
00358     char        conditionType;
00359 
00360 
00361 };
00362 //--------------------------------------------
00363 
00364 
00365 //queueItem connects a pre-defined event with an exectution time.
00366 //They are placed in the eventQueue
00367 struct queueItem {
00368     uint32_t timeToExecute;
00369     event* eventPtr;
00370 };
00371 
00372 
00373 //Organizes events in a temporal queue.  check() is called from the main loop.
00374 //If the execution time of the event has passed, then the event is exectuted.
00375 class eventQueue {
00376 public:
00377     eventQueue();
00378     void addEventToQueue(event* eventInput, uint32_t delay);
00379     void eraseQueue(); //clear all future events
00380     void check(void);
00381 
00382 private:
00383     std::vector<queueItem> events;
00384     int queueSize;
00385 
00386 };
00387 
00388 //An 'event' is a block of 'actions' that can be gated with a boolean 'condition' set. All
00389 //conditions in the set must be true for the block of actions to be executed. Right now,
00390 //there is no OR logic (||), only AND (&&).
00391 //The entire event is placed on the event queue to be executed at a given delay.
00392 //At that future time, the condition is checked and if true, the block of actions
00393 //is exectuted. Note: an 'action' can be another event (or even the parent event), allowing
00394 //nested 'if' and 'while' statements.
00395 class event {
00396 public:
00397 
00398     event();
00399     event(eventQueue* queueInput);
00400     ~event();
00401     void setTimeLag(uint32_t timeLagInput); //the event will be exectuted at this time from now
00402     void setTimeLag(int* timeLagInput); //the event will be exectuted at this time from now
00403     void setWhileLoopPeriod(uint32_t period);
00404     void setWhileLoopPeriod(int* period);
00405     void addCondition(condition* conditionInput); //contains a set of conditions to check and a truth table
00406     bool isConditionTrue(void); //checks if the condition is true
00407     void addAction(action* actionInput); //called during script parsing, when the block is being defined
00408     void addToQueue(void); //places the event on the event queue with default time lag.  When the time
00409     //lag has expired, the the block is executed
00410     void addToQueue(uint32_t delay);
00411     void execute(void); //Execute without checking the condition. Called only from the event queue
00412     void setNextElseEvent(event* eventInput); //allows for else event block
00413     uint32_t timeLag; //default time from now when the event will be executed (this is ignored once placed in event queue)
00414     int* timeLagVar; //exectution time lab defined by a variable
00415     eventQueue* queuePtr;
00416     void release(); //called when the event is no longer being used;
00417 
00418     char blockType;  //0 callback
00419     //1 if ... do block (with conditions)
00420     //2 do block (no conditions)
00421     //3 else if ... do block
00422     //4 else do (no conditions)
00423     //5 while ... do every ... block
00424     //6 else while ... do every ... block
00425     //7 then if ... do block
00426     //8 then do (no conditions)
00427 
00428     uint32_t whileLoopPeriod; //if non-zero, the block is a while loop (executed at regular intervals)
00429     int* whileLoopPeriodVar;
00430     event* nextElseEventPtr;
00431     bool isUsed;
00432     bool timeLagIsConstant;
00433     bool whileLoopPeriodIsConstant;
00434     bool hasWhileLoop;
00435 
00436 private:
00437     int numConditions;
00438     int numActions;
00439     condition* conditionToCheck;
00440     action* actionArray[20];
00441 
00442     //if statement (can be left empty, which is interpreted as 'true')
00443     //std::vector<condition*> conditionArray;
00444     //std::deque<action*> actionArray;
00445 
00446 };
00447 
00448 //each functionItem help a poiter to an action, and the name of the function.  Not currently in use.
00449 class functionItem {
00450 public:
00451     functionItem(action* actionInput, string tagInput);
00452     ~functionItem();
00453     string tag;
00454     action* actionPtr;
00455 };
00456 
00457 class blockBuffer {
00458 
00459 public:
00460     blockBuffer();
00461     bool addLine(char* input, int numChars);
00462     string getNextLine();
00463     int16_t linesAvailable();
00464     bool empty();
00465     void resetBuffer();
00466 
00467 private:
00468 #ifdef MBEDHARDWARE
00469     //On the MBED, we need to put this on a different memory bank
00470     __attribute((section("AHBSRAM1"),aligned)) char charBuffer[INPUTCHARBUFFERSIZE];
00471 #else
00472     char charBuffer[INPUTCHARBUFFERSIZE];
00473 #endif
00474     int16_t bufferWritePos;
00475     int16_t bufferReadPos;
00476     int16_t _linesAvailable;
00477 
00478 };
00479 
00480 //Parser for the incoming text.  The parser is called when a line terminates with a semicolon (;).
00481 //Only the final line in a callback block should have a semicolon.
00482 class scriptStream {
00483 public:
00484     scriptStream(digitalPort* portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem* system);
00485     void parseBlock();
00486     void addLineToCurrentBlock(char* lineInput); // if the line did not end with a semicolon, add it to the current block
00487     int* findIntVariable(string nameInput); //used to retrieve the pointer to the designated variable if it exists
00488     int* findIntVariable(const char* nameInput); //used to retrieve the pointer to the designated variable if it exists
00489     int* findIntVariable(const char* nameInput, int start, int end); //used to retrieve the pointer to the designated variable if it exists
00490 
00491     bool createIntVariable(string nameInput); // creates a new interger variable
00492     action* evaluateAssignmentForAction(string expression); //parses a numerical assignment or operation (a = b - c)
00493     action* evaluateAssignmentForAction(const char* expression); //parses a numerical assignment or operation (a = b - c)
00494 
00495     bool evaluateConditions(string& expression, event* currentEvent); //parses a condition statement (a == b && c > d)
00496     //condition* parseConditions(string& expression); //parses a condition statement (a == b && c > d)
00497     //std::size_t findFirstOrOutsideParenth(string& expression);
00498     //std::size_t findFirstAndOutsideParenth(string& expression);
00499     //bool isOutsideParenth(string& expression,std::size_t foundItem);
00500 
00501     condition* parseConditions(const char* expression,int start, int end); //parses a condition statement (a == b && c > d)
00502     int findFirstOrOutsideParenth(const char* expression, int start, int end);
00503     int findFirstAndOutsideParenth(const char* expression, int start, int end);
00504     bool isOutsideParenth(const char* expression,int foundItem, int start, int end);
00505     bool isNum(const char* expression, int start, int end);
00506     bool areStringsSame(const char* str1, const char* str2, int start, int end);
00507 
00508     int getRandomParam(string expression);
00509     int getRandomParam(const char* expression,int start,int end);
00510 
00511 
00512     int findStringLoc(const char* refString,const char* findString,int start, int end);
00513 
00514 
00515 
00516 private:
00517 
00518     int currentTriggerPort;
00519     int currentTriggerDir;
00520     int currentPort;
00521     int currentFunction;
00522 
00523     string tmpLine;
00524     vector<string> tokens;
00525 
00526     bool lineError;
00527     int blockDepth;
00528     bool ifBlockInit;
00529     bool whileBlockInit;
00530     bool elseFlag;
00531     bool thenFlag;
00532     bool expectingDoStatement;
00533     int currentDelay;
00534     event* tmpEvent;
00535     string tmpString;
00536 
00537     vector<intVariable*> globalVariables;
00538     vector<event*> tmpEventPtrArray;
00539     //event* functionEventArray[NUMFUNCTIONS];
00540     //bool   functionSpotTaken[NUMFUNCTIONS];
00541 
00542     //vector<functionItem*> functionArray; //any blocks declared outsite callback blocks are stored here
00543     //list<string> currentBlock;
00544     blockBuffer currentBlock;
00545     digitalPort* portVector;
00546     sSystem* system;
00547 
00548 
00549 
00550     int numPorts;
00551     eventQueue* queuePtr;
00552 
00553 };
00554 
00555 
00556 class mainLoop
00557 
00558 {
00559 public:
00560     mainLoop();
00561     void init();
00562     void exec();
00563 private:
00564     void eraseBuffer();
00565     uint32_t currentDIOstate[2];
00566     bool digitalInChanged;
00567     bool digitalOutChanged;
00568     scriptStream *parser;
00569     sSystem *hardware; //hardware interface
00570     sSerialPort *pc; //communication to computer
00571     char buffer[256];
00572     digitalPort ports[NUMPORTS];
00573 
00574 
00575 
00576 };