Andy Lustig
/
stateScript_v2
fork of StateScript
Fork of stateScript_v2 by
Diff: behave.cpp
- Revision:
- 7:5fe7329751d4
- Parent:
- 6:6a6761a47951
- Child:
- 8:872b843a3053
--- a/behave.cpp Fri Jun 10 21:22:34 2016 +0000 +++ b/behave.cpp Tue Feb 07 18:45:25 2017 +0000 @@ -105,14 +105,32 @@ DIO_DCR = DIO_DCR_IE; // enable DIO edge interrupts #endif - for (int i = 0; i < NUMPORTS; i++) { - //Set up the ports. Each has two pointers to the harware implementations - //of a digital out and digital in. - ports[i].init(hardware->getDigitalOutPtr(i),hardware->getDigitalInPtr(i)); + //Set up the ports. + int totalPorts = 0; + for (int i = 0; i < NUMDIGINPORTS; i++) { + digInPorts[i].init(hardware->getDigitalInPtr(i)); + ports[totalPorts] = &digInPorts[i]; + totalPorts++; + } + for (int i = 0; i < NUMDIGOUTPORTS; i++) { + digOutPorts[i].init(hardware->getDigitalOutPtr(i)); + ports[totalPorts] = &digOutPorts[i]; + totalPorts++; } - - - parser = new scriptStream(ports, NUMPORTS, &mainQueue, hardware); + for (int i = 0; i < NUMANINPORTS; i++) { + anInPorts[i].init(hardware->getAnalogInPtr(i)); + ports[totalPorts] = &anInPorts[i]; + totalPorts++; + } + for (int i = 0; i < NUMANOUTPORTS; i++) { + anOutPorts[i].init(hardware->getAnalogOutPtr(i)); + ports[totalPorts] = &anOutPorts[i]; + totalPorts++; + } + + + //int totalPorts = NUMDIGINPORTS+NUMDIGOUTPORTS+NUMANINPORTS+NUMANOUTPORTS; + parser = new scriptStream(ports, totalPorts, &mainQueue, hardware); } @@ -169,9 +187,9 @@ #endif //Get the initial state of all input pins - for (int i = 0; i < NUMPORTS; i++) { - - if (ports[i].getDigitalIn() == 1) { + for (int i = 0; i < NUMDIGINPORTS; i++) { + + if (digInPorts[i].read() == 1) { currentDIOstate[0] |= (1 << i); } else { currentDIOstate[0] &= ~(1 << i); @@ -214,12 +232,52 @@ } } + //Check all the analog ports to see if anything has changed. In the update routine, the port's + //script callbacks are called if the port crossed threshold. + for (int i = 0; i < NUMANINPORTS; i++) { + anInPorts[i].update(); + } + for (int i = 0; i < NUMANOUTPORTS; i++) { + anOutPorts[i].update(); + } + //Check all the digital ports to see if anything has changed. In the update routine, the port's //script callbacks are called if the port was triggered digitalInChanged = false; digitalOutChanged = false; changeTime = timeKeeper; + for (int i = 0; i < NUMDIGINPORTS; i++) { + + if (digInPorts[i].update()) { + + digitalInChanged = true; + changeTime = max(changeTime,digInPorts[i].lastChangeTime); + + //The input state of all the ports in condensed into one number (each bit contains the info) + if (digInPorts[i].getLastChangeState() == 1) { + currentDIOstate[0] |= (1 << i); + } else { + currentDIOstate[0] &= ~(1 << i); + } + } + } + for (int i = 0; i < NUMDIGOUTPORTS; i++) { + + if (digOutPorts[i].update()) { + + digitalOutChanged = true; + changeTime = max(changeTime,digOutPorts[i].lastChangeTime); + + //The input state of all the ports in condensed into one number (each bit contains the info) + if (digOutPorts[i].getLastChangeState() == 1) { + currentDIOstate[1] |= (1 << i); + } else { + currentDIOstate[1] &= ~(1 << i); + } + } + } + /* for (int i = 0; i < NUMPORTS; i++) { if (ports[i].update()) { @@ -252,28 +310,18 @@ } ports[i].outStateChanged = false; } - } - - //If anything changed, we write the new values to the serial port (this can be turned off + }*/ + + //If anything changed in the DIOs, we write the new values to the serial port (this can be turned off //with broadCastStateChanges) if ( (digitalInChanged||digitalOutChanged) && broadCastStateChanges) { textDisplay << changeTime << " " << currentDIOstate[0] << " " << currentDIOstate[1] << "\r\n"; - - /* - timeConvert << changeTime; //broadcast the earliest timestamp when a change occured - //stateConvert << currentDIOstate[0] << " " << currentDIOstate[1]; - stateConvert << currentDIOstate[0] << " " << currentDIOstate[1] << " "; - - textDisplay.send(timeConvert.str() + " " + stateConvert.str() + "\r\n"); - timeConvert.clear(); - timeConvert.seekp(0); - stateConvert.clear(); - stateConvert.seekp(0); - */ digitalInChanged = false; digitalOutChanged = false; } + + //We use a buffer to send text via the serial port. For every loop //in the main loop, we send one character if there is enything to send. //This way, outputting text to serial does not hold up other time-sensitive @@ -295,8 +343,10 @@ //check for shortcut triggers numTriggersToProcess = hardware->getPendingFunctionTriggers(shortcutTriggers); for (int i = 0; i < numTriggersToProcess; i++) { - textDisplay << "Trigger function " << shortcutTriggers[i]+1 << "\r\n"; - if ((shortcutTriggers[i] < NUMTRIGGERACTIONS) && functionSpotTaken[shortcutTriggers[i]] && functionEventArray[i]->isUsed) { + textDisplay << "Trigger function " << shortcutTriggers[i]+1 << " taken: " << (uint16_t)functionSpotTaken[shortcutTriggers[i]] << " isused: " << (uint16_t)functionEventArray[shortcutTriggers[i]]->isUsed<< "\r\n"; + + if ((shortcutTriggers[i] < NUMTRIGGERACTIONS) && functionSpotTaken[shortcutTriggers[i]] && functionEventArray[shortcutTriggers[i]]->isUsed) { + textDisplay << "Executing trigger function.\r\n"; //textDisplay << "Executing function array index " << shortcutTriggers[i] << "\r\n"; functionEventArray[shortcutTriggers[i]]->execute(); } @@ -376,8 +426,267 @@ pos = str.find_first_of(delimiters, lastPos); } } - - +//----------------------------------------- +AbstractPort::AbstractPort(): + triggerUpEventPtr(NULL), + triggerDownEventPtr(NULL), + state(0), + portDir(none), + thresh(0), + lastChangeTime(0), + hasTriggerFunction(false), + reportUpdates(false) { + +} + + + +void AbstractPort::write(int outVal) { + //Default do nothing +} + +void AbstractPort::setThresh(int threshVal) { + thresh = threshVal; +} + + +void AbstractPort::setTriggerUpEvent(event *eventInput) { + + if (triggerUpEventPtr != NULL) { + triggerUpEventPtr->release(); + } + triggerUpEventPtr = eventInput; + hasTriggerFunction = true; +} + +void AbstractPort::setTriggerDownEvent(event *eventInput) { + + if (triggerDownEventPtr != NULL) { + triggerDownEventPtr->release(); + } + triggerDownEventPtr = eventInput; + hasTriggerFunction = true; +} + +void AbstractPort::clearTriggerEvents() { + + if (triggerUpEventPtr != NULL) { + triggerUpEventPtr->release(); + triggerUpEventPtr = NULL; + } + if (triggerDownEventPtr != NULL) { + triggerDownEventPtr->release(); + triggerDownEventPtr = NULL; + } + hasTriggerFunction = false; +} + +void AbstractPort::setReportUpdates(bool report) { + reportUpdates = report; +} + +int AbstractPort::getLastChangeState() { + return lastInState; +} +uint32_t AbstractPort::getTimeSinceLastChange() { + return lastChangeInterval; +} + +bool AbstractPort::checkForChange() { + //Default behavior checks if the signal has crossed threshold using sofware + //detect change in the software main loop + //we read the pin state to see if it is different than the + //remembered state. This is important in order to report both edges of a + //fast up-down event. + + state = read(); + bool changed = ((lastInState < thresh && state >= thresh) || (lastInState >= thresh && state < thresh)); + + if (changed) { + if (state >= thresh) { + + lastChangeInterval = timeKeeper - lastChangeTime; + lastChangeTime = timeKeeper; + + if (triggerUpEventPtr != NULL && triggerUpEventPtr->isUsed) {triggerUpEventPtr->execute();} + } else if (state < thresh) { + + lastChangeInterval = timeKeeper - lastChangeTime; + lastChangeTime = timeKeeper; + + + if (triggerDownEventPtr != NULL && triggerDownEventPtr->isUsed){triggerDownEventPtr->execute();} + } + + lastInState = state; + + } +} + +bool AbstractPort::update() { + + + bool changed = false; + + if ((reportUpdates || hasTriggerFunction)&&(timeKeeper - lastChangeTime) > 1) { //prevents flutter triggers when button is pressed + changed = checkForChange(); + } else if (portDir == in) { + state = read(); + } + + return changed; +} + + + +//----------------------------------------- +AnalogPort::AnalogPort(): + outPin(NULL), + inPin(NULL) { + + portType = analog; + +} + +void AnalogPort::init(sAnalogIn *IP) { + + portDir = in; + inPin = IP; + +} + +void AnalogPort::init(sAnalogOut *OP){ + portDir = out; + outPin = OP; +} + +void AnalogPort::write(int outVal) { + if (portDir == out) { + outPin->write(outVal); + if (state != outVal) { + outStateChanged = true; + lastOutChangeTime = timeKeeper; + } + //state = outVal; + state = outPin->read(); + } +} + +int AnalogPort::read() { + if (portDir == out) { + return outPin->read(); + } else if (portDir == in) { + return inPin->read(); + } +} + +void AnalogPort::setThresh(int threshVal) { + thresh = threshVal; + //TODO: set thresh for hardware object too +} + + +//----------------------------------------- +DigitalPort::DigitalPort(): + outPin(NULL), + inPin(NULL) { + + portType = digital; + thresh = 1; + +} + +void DigitalPort::init(sDigitalIn *IP) { + + portDir = in; + inPin = IP; + +} + +void DigitalPort::init(sDigitalOut *OP){ + portDir = out; + outPin = OP; +} + +void DigitalPort::write(int outVal) { + if (portDir == out) { + if (outVal == -1) { + outVal = 1-state; + } + outPin->write(outVal); + if (state != outVal) { + outStateChanged = true; + lastOutChangeTime = timeKeeper; + } + state = outVal; + } +} + +int DigitalPort::read() { + if (portDir == out) { + return outPin->read(); + } else if (portDir == in) { + return inPin->read(); + } +} + +bool DigitalPort::checkForChange() { + + //Use hardware to detect state change times + bool changed = false; + + inPin->setUpdate(true); //Once we get the state of the pin, we buffer any pin changes until we are done checking + + //Every ms, we first check if a hardware trigger occured + //in the opposite direction of the last remembered state + if (lastInState == 0) { + changed = inPin->lastUpEvent.triggered; + if (changed) state = 1; + } else if (lastInState == 1) { + changed = inPin->lastDownEvent.triggered; + if (changed) state = 0; + } + + //if not, then we read the pin state to see if it is different than the + //remembered state. This is important in order to report both edges of a + //fast up-down event. + if (!changed) { + state = read(); + changed = (lastInState != state); + + } + + + //changed = (inPin->lastUpEvent.triggered || inPin->lastDownEvent.triggered); + if (changed) { + if (state == 1) { + + lastChangeInterval = inPin->lastUpEvent.timeStamp - lastChangeTime; + lastChangeTime = inPin->lastUpEvent.timeStamp; + + if (triggerUpEventPtr != NULL && triggerUpEventPtr->isUsed) {triggerUpEventPtr->execute();} + } else if (state == 0) { + + lastChangeInterval = inPin->lastDownEvent.timeStamp - lastChangeTime; + lastChangeTime = inPin->lastDownEvent.timeStamp; + + if (triggerDownEventPtr != NULL && triggerDownEventPtr->isUsed){triggerDownEventPtr->execute();} + } + + lastInState = state; + inPin->lastUpEvent.triggered = false; + inPin->lastDownEvent.triggered = false; + + inPin->setUpdate(false); //This also checks if there were any buffered changes that occured + } + + inPin->setUpdate(false); //This also checks if there were any buffered changes that occured + + return changed; +} + + +//------------------------------------------ digitalPort::digitalPort(): outPin(NULL), inPin(NULL), @@ -455,7 +764,7 @@ bool execDown = false; if ((timeKeeper - lastChangeTime) > 1) { //prevents flutter triggers when button is pressed - //changed = (lastInState != inState); + inPin->setUpdate(true); //Once we get the state of the pin, we buffer any pin changes until we are done checking //Every ms, we first check if a hardware trigger occured @@ -474,6 +783,7 @@ if (!changed) { inState = getDigitalIn(); changed = (lastInState != inState); + } @@ -548,13 +858,13 @@ inPin->lastUpEvent.triggered = false; inPin->lastDownEvent.triggered = false; - //inPin->setUpdate(false); //This also checks if there were any buffered changes that occured - + inPin->setUpdate(false); //This also checks if there were any buffered changes that occured + } inPin->setUpdate(false); //This also checks if there were any buffered changes that occured - + } @@ -664,7 +974,7 @@ isUsed = false; } -intCompare::intCompare(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse): +intCompare::intCompare(AbstractPort* portInput, const char* cmpString, int cmpValInput, int whichToUse): port(portInput) { cmpVal = new int(cmpValInput); cmpValGlobal = false; @@ -673,13 +983,13 @@ setPointer(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } -intCompare::intCompare(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse): +intCompare::intCompare(AbstractPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse): port(portInput), cmpVal(cmpIntVarInput) { cmpValGlobal = true; @@ -688,9 +998,9 @@ setPointer(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } @@ -727,7 +1037,7 @@ setPointer_operation(cmpString); } -intCompare::intCompare(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse): +intCompare::intCompare(AbstractPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse): port(portInput) { cmpVal = NULL; intVal = NULL; @@ -736,15 +1046,15 @@ setPointer_operation(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } -void intCompare::set(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse) { +void intCompare::set(AbstractPort* portInput, const char* cmpString, int cmpValInput, int whichToUse) { port = portInput; cmpVal = new int(cmpValInput); cmpValGlobal = false; @@ -753,13 +1063,13 @@ setPointer(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } -void intCompare::set(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse) { +void intCompare::set(AbstractPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse) { port = portInput; cmpVal = cmpIntVarInput; cmpValGlobal = true; @@ -768,9 +1078,9 @@ setPointer(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } @@ -807,7 +1117,7 @@ isUsed = true; } -void intCompare::set(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse) { +void intCompare::set(AbstractPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse) { port = portInput; cmpVal = NULL; intVal = NULL; @@ -816,9 +1126,9 @@ setPointer_operation(cmpString); isUsed = true; if (whichToUse == 1) { - portValPtr = &port->inState; + portValPtr = &port->state; } else { - portValPtr = &port->outState; + portValPtr = &port->state; } } @@ -1428,47 +1738,25 @@ isUsed = false; } -/* - portMessage::portMessage(digitalPort* portIn, int whichToSetIn, int valueIn): - whichToSet(whichToSetIn), - value(valueIn), - port(portIn) { - isUsed = true; - } - - void portMessage::setMessage(digitalPort* portIn, int whichToSetIn, int valueIn) { - whichToSet = whichToSetIn; - value = valueIn; - port = portIn; - isUsed = true; - }*/ - -/* -portMessage::portMessage(int* portIn, int whichToSetIn, int valueIn): -whichToSet(whichToSetIn), -value(valueIn), -port(portIn) { - isUsed = true; -}*/ - -void portMessage::setMessage(int* portIn, int whichToSetIn, int valueIn, digitalPort* portVectorIn) { +void portMessage::setMessage(int* portIn, int whichToSetIn, int valueIn, AbstractPort** portVectorIn, int portVectorLength) { whichToSet = whichToSetIn; value = valueIn; port = portIn; portVector = portVectorIn; isUsed = true; + vectorLength = portVectorLength; } void portMessage::execute() { if (port != NULL) { - if ((*port > 0) && (*port <= NUMPORTS)) { - portVector[*port-1].setDigitalOut(value); + if ((*port > 0) && (*port <= vectorLength)) { + portVector[*port-1]->write(value); } else { textDisplay << "Error: port index assigned by variable does not exist.\r\n"; } } else { - portVector[whichToSet-1].setDigitalOut(value); + portVector[whichToSet-1]->write(value); } } @@ -2170,12 +2458,45 @@ } -scriptStream::scriptStream(digitalPort* portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem *system): +scriptStream::scriptStream(AbstractPort** portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem *system): portVector(portVectorInput), numPorts(numPortsInput), queuePtr(queueInput), system(system) { + numAnInPorts = 0; + numDigInPorts = 0; + numAnOutPorts = 0; + numDigOutPorts = 0; + + for (int i=0;i<numPortsInput;i++) { + if ((portVectorInput[i]->portType == AbstractPort::analog)&&(portVectorInput[i]->portDir == AbstractPort::in)) { + if(numAnInPorts < NUMANINPORTS) { + anInPortVector[numAnInPorts] = portVectorInput[i]; + anInLookup[numAnInPorts] = i; + numAnInPorts++; + } + } else if ((portVectorInput[i]->portType == AbstractPort::analog)&&(portVectorInput[i]->portDir == AbstractPort::out)) { + if(numAnOutPorts < NUMANOUTPORTS) { + anOutPortVector[numAnOutPorts] = portVectorInput[i]; + anOutLookup[numAnOutPorts] = i; + numAnOutPorts++; + } + } else if ((portVectorInput[i]->portType == AbstractPort::digital)&&(portVectorInput[i]->portDir == AbstractPort::in)) { + if(numDigInPorts < NUMDIGINPORTS) { + digInPortVector[numDigInPorts] = portVectorInput[i]; + digInLookup[numDigInPorts] = i; + numDigInPorts++; + } + } else if ((portVectorInput[i]->portType == AbstractPort::digital)&&(portVectorInput[i]->portDir == AbstractPort::out)) { + if(numDigOutPorts < NUMDIGOUTPORTS) { + digOutPortVector[numDigOutPorts] = portVectorInput[i]; + digOutLookup[numDigOutPorts] = i; + numDigOutPorts++; + } + } + } + currentPort = -1; currentTriggerPort = -1; currentTriggerDir = 1; @@ -2666,11 +2987,11 @@ if (!lineError) { int funcNum = atoi(tmpLine.substr(pos1,pos2-pos1).data()); if ((funcNum > 0) && (funcNum < NUMFUNCTIONS+1)) { - if (functionSpotTaken[funcNum-1] && functionEventArray[funcNum]->isUsed) { + if (functionSpotTaken[funcNum-1] && functionEventArray[funcNum-1]->isUsed) { } else { - textDisplay << "Error: function number does not exist\r\n"; + textDisplay << "Error: function number does not exist\r\n"; lineError = true; } } else { @@ -2856,7 +3177,7 @@ } else if (tokens[i+1].compare("off") == 0) { stream = false; } else { - textDisplay << "Error: 'updates' useage: 'updates on' or 'updates off'\r\n"; + textDisplay << "Error: 'updates' usage: 'updates on' or 'updates off'\r\n"; lineError = true; } } @@ -2868,7 +3189,7 @@ if (tempPort > 0) { specifiedPort = tempPort-1; } else { - textDisplay << "Error: 'updates' useage: 'updates on [port]' or 'updates off [port]'\r\n"; + textDisplay << "Error: 'updates' usage: 'updates on [port]' or 'updates off [port]'\r\n"; lineError = true; } i++; @@ -2878,21 +3199,25 @@ if (stream) { //applies to all; broadCastStateChanges = true; - if (specifiedPort > -1) { - system->setPortUpdatesOn(specifiedPort); + if ((specifiedPort > -1) && (specifiedPort < NUMDIGINPORTS)) { + //system->setPortUpdatesOn(specifiedPort); + digInPortVector[specifiedPort]->setReportUpdates(true); } else { - for (int i=0;i<NUMPORTS;i++) { - system->setPortUpdatesOn(i); + for (int i=0;i<NUMDIGINPORTS;i++) { + //system->setPortUpdatesOn(i); + digInPortVector[i]->setReportUpdates(true); } } } else { - if (specifiedPort > -1) { - system->setPortUpdatesOff(specifiedPort); + if ((specifiedPort > -1) && (specifiedPort < NUMDIGINPORTS)) { + //system->setPortUpdatesOff(specifiedPort); + digInPortVector[specifiedPort]->setReportUpdates(false); } else { //applies to all //broadCastStateChanges = false; - for (int i=0;i<NUMPORTS;i++) { - system->setPortUpdatesOff(i); + for (int i=0;i<NUMDIGINPORTS;i++) { + //system->setPortUpdatesOff(i); + digInPortVector[i]->setReportUpdates(false); } } @@ -3020,7 +3345,7 @@ if (!ifBlockInit && !whileBlockInit) { - if ((currentTriggerPort > 0) || (currentFunction > -1)) { //check to make sure we are inside a trigger block + if ((currentTriggerPort > -1) || (currentFunction > -1)) { //check to make sure we are inside a trigger block } else { @@ -3276,10 +3601,12 @@ int pos2 = tokens[i+1].find_first_of("]",pos1); currentTriggerPort = atoi(tokens[i+1].substr(pos1,pos2-pos1).data()); - if (currentTriggerPort <= 0) { + if (currentTriggerPort <= 0 || currentTriggerPort > NUMDIGINPORTS) { currentTriggerPort = -1; - textDisplay << "Error: Not a valid port number\r\n"; + textDisplay << "Error: Not a valid port number.\r\n"; lineError = true; + } else { + currentTriggerPort = digInLookup[currentTriggerPort-1]; } } else { textDisplay << "Error: Not a valid callback input\r\n"; @@ -3322,10 +3649,10 @@ tmpEventPtrArray.push_back(tmpEvent); if (currentTriggerDir == 1) { - portVector[currentTriggerPort-1].setTriggerUpEvent(tmpEventPtrArray.back()); + portVector[currentTriggerPort]->setTriggerUpEvent(tmpEventPtrArray.back()); } else { - portVector[currentTriggerPort-1].setTriggerDownEvent(tmpEventPtrArray.back()); + portVector[currentTriggerPort]->setTriggerDownEvent(tmpEventPtrArray.back()); } } @@ -3444,7 +3771,7 @@ } textDisplay.debug("While statement\r\n"); - if ((currentTriggerPort > 0) || (currentFunction > -1)) { //check to make sure we are inside a trigger block + if ((currentTriggerPort > -1) || (currentFunction > -1)) { //check to make sure we are inside a trigger block } else { @@ -3701,13 +4028,15 @@ textDisplay.debug(nameInput.data()); int* outPtr = NULL; bool foundIt = false; + + //First check if the variable is the state of a port if (nameInput.find("portout") != std::string::npos) { int pos1 = nameInput.find("portout[")+8; int pos2 = nameInput.find_first_of("]",pos1); int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); int portVal = 0; - if ((portnum > 0) && (portnum <= numPorts)) { - outPtr = &portVector[portnum-1].outState; + if ((portnum > 0) && (portnum <= numDigOutPorts)) { + outPtr = &digOutPortVector[portnum-1]->state; foundIt = true; } } else if (nameInput.find("portin") != std::string::npos) { @@ -3715,12 +4044,31 @@ int pos2 = nameInput.find_first_of("]",pos1); int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); int portVal = 0; - if ((portnum > 0) && (portnum <= numPorts)) { - outPtr = &portVector[portnum-1].inState; + if ((portnum > 0) && (portnum <= numDigInPorts)) { + outPtr = &digInPortVector[portnum-1]->state; + foundIt = true; + } + } else if (nameInput.find("analogout") != std::string::npos) { + int pos1 = nameInput.find("analogout[")+10; + int pos2 = nameInput.find_first_of("]",pos1); + int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); + int portVal = 0; + if ((portnum > 0) && (portnum <= numAnOutPorts)) { + outPtr = &anOutPortVector[portnum-1]->state; + foundIt = true; + } + } else if (nameInput.find("analogin") != std::string::npos) { + int pos1 = nameInput.find("analogin[")+9; + int pos2 = nameInput.find_first_of("]",pos1); + int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); + int portVal = 0; + if ((portnum > 0) && (portnum <= numAnInPorts)) { + outPtr = &anInPortVector[portnum-1]->state; foundIt = true; } } + //Then check if it is a defined int variable if (!foundIt) { std::vector<intVariable*>::size_type sz = globalVariables.size(); int start = 0; @@ -3753,6 +4101,7 @@ int* outPtr = NULL; bool foundIt = false; + //First check if the variable is the current state of a port if (findStringLoc(nameInput,"portout[",start,end) != -1) { int pos1 = findStringLoc(nameInput,"portout[",start,end)+8; int pos2 = findStringLoc(nameInput, "]",pos1,end); @@ -3763,8 +4112,8 @@ //int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); long int portnum = strtol(nameInput+pos1,NULL,10); - if ((portnum > 0) && (portnum <= numPorts)) { - outPtr = &portVector[(int)portnum-1].outState; + if ((portnum > 0) && (portnum <= numDigOutPorts)) { + outPtr = &digOutPortVector[(int)portnum-1]->state; foundIt = true; } } else if (findStringLoc(nameInput,"portin[",start,end) != -1) { @@ -3776,8 +4125,35 @@ } long int portnum = strtol(nameInput+pos1,NULL,10); - if ((portnum > 0) && (portnum <= numPorts)) { - outPtr = &portVector[(int)portnum-1].inState; + if ((portnum > 0) && (portnum <= numDigInPorts)) { + outPtr = &digOutPortVector[(int)portnum-1]->state; + foundIt = true; + } + } else if (findStringLoc(nameInput,"analogout[",start,end) != -1) { + int pos1 = findStringLoc(nameInput,"analogout[",start,end)+10; + int pos2 = findStringLoc(nameInput, "]",pos1,end); + if ((pos1 == -1)||(pos2 == -1)) { + //syntax error + return NULL; + } + + //int portnum = atoi(nameInput.substr(pos1,pos2-pos1).data()); + long int portnum = strtol(nameInput+pos1,NULL,10); + if ((portnum > 0) && (portnum <= numAnOutPorts)) { + outPtr = &anOutPortVector[(int)portnum-1]->state; + foundIt = true; + } + } else if (findStringLoc(nameInput,"analogin[",start,end) != -1) { + int pos1 = findStringLoc(nameInput,"portin[",start,end)+9; + int pos2 = findStringLoc(nameInput, "]",pos1,end); + if ((pos1 == -1)||(pos2 == -1)) { + //syntax error + return NULL; + } + long int portnum = strtol(nameInput+pos1,NULL,10); + + if ((portnum > 0) && (portnum <= numAnInPorts)) { + outPtr = &anOutPortVector[(int)portnum-1]->state; foundIt = true; } } @@ -3860,7 +4236,7 @@ } int* tmpVar = findIntVariable(expression, pos1,pos2); //returns pointer to the variable, if given int portVal = 0; - if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numPorts))) { + if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numDigOutPorts))) { if (isNum(expression,afterEqualLoc,lastCharLoc)) { //a simple numeric assign portVal = atoi(expression+afterEqualLoc); if ((portVal == 0) || (portVal == 1)) { @@ -3873,9 +4249,9 @@ } else { //tmpMessage->setMessage(portVector[portnum],1,portVal); if (tmpVar == NULL) { //a constant port number was given - tmpMessage->setMessage(NULL,portnum,portVal,portVector); + tmpMessage->setMessage(NULL,portnum,portVal,digOutPortVector,numDigOutPorts); } else { - tmpMessage->setMessage(tmpVar,0,portVal,portVector); + tmpMessage->setMessage(tmpVar,0,portVal,digOutPortVector,numDigOutPorts); } } @@ -3898,9 +4274,9 @@ } else { //tmpMessage->setMessage(portVector[portnum],1,-1); if (tmpVar == NULL) { //a constant port number was given - tmpMessage->setMessage(NULL,portnum,-1,portVector); + tmpMessage->setMessage(NULL,portnum,-1,digOutPortVector,numDigOutPorts); } else { - tmpMessage->setMessage(tmpVar,0,-1,portVector); + tmpMessage->setMessage(tmpVar,0,-1,digOutPortVector,numDigOutPorts); } } tmpAction->set(tmpMessage); @@ -3911,7 +4287,62 @@ return NULL; } } else { - textDisplay << "Port number not found (must be between 1 and " << numPorts << " or an existing variable)\r\n"; + textDisplay << "Port number not found (must be between 1 and " << numDigOutPorts << " or an existing variable)\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else if (findStringLoc(expression,"analogout[",0,beforeEqualLoc) != -1) { //set the output of an analog port + textDisplay.debug("Portout assignment\r\n"); + int pos1 = findStringLoc(expression,"analogout[",0,beforeEqualLoc)+10; + int pos2 = findStringLoc(expression,"]",pos1,beforeEqualLoc)-1; + if (pos2 < pos1) { + textDisplay << "Error: expected a ] character\r\n"; + return NULL; + } + + int portnum = -1; + if (isNum(expression,pos1,pos2)) { + portnum = atoi(expression+pos1); + } + int* tmpVar = findIntVariable(expression, pos1,pos2); //returns pointer to the variable, if given + int portVal = 0; + if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numAnOutPorts))) { + if (isNum(expression,afterEqualLoc,lastCharLoc)) { //a simple numeric assign + portVal = atoi(expression+afterEqualLoc); + if ((portVal >= 0) || (portVal <= 3700)) { + //portMessage* tmpMessage = new portMessage(portVector[portnum],1,portVal); + portMessage* tmpMessage = findFirstUnUsed(portMessageBlock, NUMPORTMESSAGES); + if (tmpMessage == NULL) { + textDisplay << "Error: no memory slots available.\r\n"; + tmpAction->release(); + return NULL; + } else { + //tmpMessage->setMessage(portVector[portnum],1,portVal); + if (tmpVar == NULL) { //a constant port number was given + tmpMessage->setMessage(NULL,portnum,portVal,anOutPortVector,numAnOutPorts); + } else { + tmpMessage->setMessage(tmpVar,0,portVal,anOutPortVector,numAnOutPorts); + } + } + + + tmpAction->set(tmpMessage); + + } else { + textDisplay << "Error: analogouts can only be directly assigned a value between 0 and 3700 mV\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else { + textDisplay << "Error: analogouts can only be directly assigned a value between 0 and 3700 mV\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else { + textDisplay << "Port number not found (must be between 1 and " << numAnOutPorts << " or an existing variable)\r\n"; //delete tmpAction; tmpAction->release(); return NULL; @@ -3921,6 +4352,11 @@ //delete tmpAction; tmpAction->release(); return NULL; + } else if (findStringLoc(expression,"analogin",0,stringInd)!=-1) { + textDisplay << "Error: analog ins can not be set\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; } else if (tmpVar != NULL) { intOperation* tmpOp; intOperation* tmpOp2; @@ -4400,7 +4836,7 @@ int portnum = atoi(beforeEqual.substr(pos1,pos2-pos1).data()); int* tmpVar = findIntVariable(beforeEqual.substr(pos1,pos2-pos1)); //returns pointer to the variable, if given int portVal = 0; - if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numPorts))) { + if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numDigOutPorts))) { if (isNumber(afterEqual)) { //a simple numeric assign portVal = atoi(afterEqual.data()); if ((portVal == 0) || (portVal == 1)) { @@ -4413,9 +4849,9 @@ } else { //tmpMessage->setMessage(portVector[portnum],1,portVal); if (tmpVar == NULL) { //a constant port number was given - tmpMessage->setMessage(NULL,portnum,portVal,portVector); + tmpMessage->setMessage(NULL,portnum,portVal,digOutPortVector,numDigOutPorts); } else { - tmpMessage->setMessage(tmpVar,0,portVal,portVector); + tmpMessage->setMessage(tmpVar,0,portVal,digOutPortVector,numDigOutPorts); } } @@ -4438,9 +4874,9 @@ } else { //tmpMessage->setMessage(portVector[portnum],1,-1); if (tmpVar == NULL) { //a constant port number was given - tmpMessage->setMessage(NULL,portnum,-1,portVector); + tmpMessage->setMessage(NULL,portnum,-1,digOutPortVector,numDigOutPorts); } else { - tmpMessage->setMessage(tmpVar,0,-1,portVector); + tmpMessage->setMessage(tmpVar,0,-1,digOutPortVector,numDigOutPorts); } } tmpAction->set(tmpMessage); @@ -4451,7 +4887,54 @@ return NULL; } } else { - textDisplay << "Port number not found (must be between 1 and " << numPorts << " or an existing variable)\r\n"; + textDisplay << "Port number not found (must be between 1 and " << numDigOutPorts << " or an existing variable)\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else if (beforeEqual.find("analogout[") != std::string::npos) { //set the output of a digital port + textDisplay.debug("Portout assignment\r\n"); + int pos1 = beforeEqual.find("analogout[")+10; + int pos2 = beforeEqual.find_first_of("]",pos1); + int portnum = atoi(beforeEqual.substr(pos1,pos2-pos1).data()); + int* tmpVar = findIntVariable(beforeEqual.substr(pos1,pos2-pos1)); //returns pointer to the variable, if given + int portVal = 0; + if ((tmpVar != NULL)||((portnum > 0) && (portnum <= numAnOutPorts))) { + if (isNumber(afterEqual)) { //a simple numeric assign + portVal = atoi(afterEqual.data()); + if ((portVal >= 0) || (portVal <= 3700)) { + //portMessage* tmpMessage = new portMessage(portVector[portnum],1,portVal); + portMessage* tmpMessage = findFirstUnUsed(portMessageBlock, NUMPORTMESSAGES); + if (tmpMessage == NULL) { + textDisplay << "Error: no memory slots available.\r\n"; + tmpAction->release(); + return NULL; + } else { + //tmpMessage->setMessage(portVector[portnum],1,portVal); + if (tmpVar == NULL) { //a constant port number was given + tmpMessage->setMessage(NULL,portnum,portVal,anOutPortVector,numAnOutPorts); + } else { + tmpMessage->setMessage(tmpVar,0,portVal,anOutPortVector,numAnOutPorts); + } + } + + + tmpAction->set(tmpMessage); + + } else { + textDisplay << "Error: analogouts can only be directly assigned a value between 0 and 3700 mV \r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else { + textDisplay << "Error: analogouts can only be directly assigned a value between 0 and 3700 mV\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; + } + } else { + textDisplay << "Port number not found (must be between 1 and " << numAnOutPorts << " or an existing variable)\r\n"; //delete tmpAction; tmpAction->release(); return NULL; @@ -4461,6 +4944,11 @@ //delete tmpAction; tmpAction->release(); return NULL; + } else if (beforeEqual.find("analogin") != std::string::npos) { + textDisplay << "Error: analog ins can not be set\r\n"; + //delete tmpAction; + tmpAction->release(); + return NULL; } else if (tmpVar != NULL) { intOperation* tmpOp; intOperation* tmpOp2; @@ -5522,18 +6010,18 @@ //clear callbacks, functions, and queue if (clearMode & BLOCKMEMORYTYPES) { - for (int pNum = 0; pNum < NUMPORTS; pNum++) { + for (int pNum = 0; pNum < NUMDIGINPORTS+NUMDIGOUTPORTS+NUMANINPORTS+NUMANOUTPORTS; pNum++) { //delete portVector[pNum]->triggerUpEventPtr; - if (portVector[pNum].triggerUpEventPtr != NULL) { - portVector[pNum].triggerUpEventPtr->release(); + if (portVector[pNum]->triggerUpEventPtr != NULL) { + portVector[pNum]->triggerUpEventPtr->release(); } - portVector[pNum].triggerUpEventPtr = NULL; + portVector[pNum]->triggerUpEventPtr = NULL; //delete portVector[pNum]->triggerDownEventPtr; - if (portVector[pNum].triggerDownEventPtr != NULL) { - portVector[pNum].triggerDownEventPtr->release(); + if (portVector[pNum]->triggerDownEventPtr != NULL) { + portVector[pNum]->triggerDownEventPtr->release(); } - portVector[pNum].triggerDownEventPtr = NULL; + portVector[pNum]->triggerDownEventPtr = NULL; } for (int i = 0; i < NUMFUNCTIONS; i++) { @@ -5577,10 +6065,12 @@ if (clearMode & ENVSETTINGSMEMORYTYPES) { //set all environment settings to default values - broadCastStateChanges = true; - for (int i=0;i<NUMPORTS;i++) { - system->setPortUpdatesOn(i); + broadCastStateChanges = false; + for (int i=0;i<NUMDIGINPORTS;i++) { + //system->setPortUpdatesOff(i); + digInPortVector[i]->setReportUpdates(false); } + system->reset(); }