
Microcontroller firmware that uses a simple, yet powerful scripting language to control the timing of input and output events with high temporal resolution. Written by Mattias Karlsson
Revision 7:5fe7329751d4, committed 2017-02-07
- Comitter:
- mkarlsso
- Date:
- Tue Feb 07 18:45:25 2017 +0000
- Parent:
- 6:6a6761a47951
- Child:
- 8:872b843a3053
- Commit message:
- Fixed flip command for digital outputs
Changed in this revision
--- 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(); }
--- a/behave.h Fri Jun 10 21:22:34 2016 +0000 +++ b/behave.h Tue Feb 07 18:45:25 2017 +0000 @@ -56,6 +56,89 @@ bool triggered; };*/ +class AbstractPort { + +public: + AbstractPort(); + + enum Direction{in,out,none}; + enum DataType{digital, analog}; + + Direction portDir; + DataType portType; + + virtual void write(int outVal); + virtual int read() = 0; //Must be defined in inheriting class + virtual void setThresh(int threshVal); + + uint32_t lastChangeTime; + uint32_t lastOutChangeTime; + + bool update(); //called from the main loop + void setTriggerUpEvent(event* eventInput); //attahces a routine to an upward change + void setTriggerDownEvent(event* eventInput); //attahces a routine to a downward change + void clearTriggerEvents(); + void setReportUpdates(bool report); + int getLastChangeState(); + uint32_t getTimeSinceLastChange(); + + int state; + bool outStateChanged; + + event* triggerUpEventPtr; + event* triggerDownEventPtr; + +protected: + virtual bool checkForChange(); + bool hasTriggerFunction; + bool reportUpdates; + + int lastInState; + int thresh; + uint32_t lastChangeInterval; + +private: + +}; + +class AnalogPort: public AbstractPort { +public: + AnalogPort(); + + void init(sAnalogIn* IP); + void init(sAnalogOut* OP); + + void set(int outVal); + int read(); + void setThresh(int threshVal); + void write(int outVal); + +private: + sAnalogOut* outPin; + sAnalogIn* inPin; + +}; + +class DigitalPort: public AbstractPort { +public: + DigitalPort(); + + void init(sDigitalIn* IP); + void init(sDigitalOut* OP); + + void set(int outVal); + int read(); + void write(int outVal); + +protected: + bool checkForChange(); + +private: + sDigitalOut* outPin; + sDigitalIn* inPin; + +}; + //The digitalPort object directly controls and keeps data about the port. Each port has //one digital out and one digital in. @@ -98,6 +181,8 @@ }; + + //an intVariable contains an integer value and the name of that variable within the script class intVariable { @@ -214,7 +299,7 @@ }; -//portMessage is an action to change a digital port. So far, You can only change the digital out (0 or 1) +//portMessage is an action to change a port state. class portMessage { public: @@ -222,7 +307,7 @@ //portMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State //void setMessage(digitalPort* portIn, int whichToSet, int value); //whichToSet: 1 DigitalOut; 2 State //portMessage(int* portIn, int whichToSet, int value); //whichToSet: - void setMessage(int* portIn, int whichToSet, int value, digitalPort* portVector); //whichToSet: + void setMessage(int* portIn, int whichToSet, int value, AbstractPort** portVector, int portVectorLength); //whichToSet: void execute(); void release(); @@ -232,8 +317,9 @@ int whichToSet; //hard coded port number int* port; //alternative variable port number int value; + int vectorLength; - digitalPort* portVector; + AbstractPort** portVector; }; @@ -291,19 +377,19 @@ public: intCompare(); - intCompare(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); - intCompare(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); + intCompare(AbstractPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); + intCompare(AbstractPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); intCompare(int* intVarInput, const char* cmpString, int cmpValInput); intCompare(int* intVarInput, const char* cmpString, int* cmpIntVarInput); intCompare(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput); - intCompare(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); + intCompare(AbstractPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); - void set(digitalPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); - void set(digitalPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); + void set(AbstractPort* portInput, const char* cmpString, int cmpValInput, int whichToUse); + void set(AbstractPort* portInput, const char* cmpString, int* cmpIntVarInput, int whichToUse); void set(int* intVarInput, const char* cmpString, int cmpValInput); void set(int* intVarInput, const char* cmpString, int* cmpIntVarInput); void set(int* intVarInput, const char* cmpString, intOperation* cmpIntOpInput); - void set(digitalPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); + void set(AbstractPort* portInput, const char* cmpString, intOperation* cmpIntOpInput, int whichToUse); void release(); @@ -312,7 +398,7 @@ bool isUsed; private: - digitalPort* port; + AbstractPort* port; int* portValPtr; int* cmpVal; int* intVal; @@ -480,7 +566,7 @@ //Only the final line in a callback block should have a semicolon. class scriptStream { public: - scriptStream(digitalPort* portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem* system); + scriptStream(AbstractPort** portVectorInput, int numPortsInput, eventQueue* queueInput, sSystem* system); void parseBlock(); //Parses everything since the last semicolon was found void addLineToCurrentBlock(char* lineInput); // if the line did not end with a semicolon, add it to the current block @@ -531,12 +617,27 @@ //vector<functionItem*> functionArray; //any blocks declared outsite callback blocks are stored here //list<string> currentBlock; blockBuffer currentBlock; - digitalPort* portVector; sSystem* system; + AbstractPort** portVector; + int numPorts; + AbstractPort* digInPortVector[NUMDIGINPORTS]; + uint8_t digInLookup[NUMDIGINPORTS]; + int numDigInPorts; - int numPorts; + AbstractPort* digOutPortVector[NUMDIGOUTPORTS]; + uint8_t digOutLookup[NUMDIGOUTPORTS]; + int numDigOutPorts; + + AbstractPort* anInPortVector[NUMANINPORTS]; + uint8_t anInLookup[NUMANINPORTS]; + int numAnInPorts; + + AbstractPort* anOutPortVector[NUMANOUTPORTS]; + uint8_t anOutLookup[NUMANOUTPORTS]; + int numAnOutPorts; + eventQueue* queuePtr; }; @@ -558,8 +659,13 @@ sSystem *hardware; //hardware interface sSerialPort *pc; //communication to computer char buffer[256]; - digitalPort ports[NUMPORTS]; + //digitalPort ports[NUMPORTS]; + DigitalPort digInPorts[NUMDIGINPORTS]; + DigitalPort digOutPorts[NUMDIGOUTPORTS]; + AnalogPort anInPorts[NUMANINPORTS]; + AnalogPort anOutPorts[NUMANOUTPORTS]; + AbstractPort* ports[NUMDIGINPORTS+NUMDIGOUTPORTS+NUMANINPORTS+NUMANOUTPORTS]; };
--- a/hardwareInterface.cpp Fri Jun 10 21:22:34 2016 +0000 +++ b/hardwareInterface.cpp Tue Feb 07 18:45:25 2017 +0000 @@ -33,7 +33,7 @@ sSystem::sSystem() { for (int i=0;i<32;i++) { - ignorePortUpdates[i] = false; + ignorePortUpdates[i] = true; //by default, all digital port changes are not automatically reported. } } @@ -65,6 +65,10 @@ } +void sSystem::reset() { + +} + void sSystem::resumeInterrupts() { } @@ -80,6 +84,16 @@ uint32_t sSystem::getDigitalInputChangeFlags() { } +//----------------------------------------------------- +sAnalogOut::sAnalogOut() { + +} + +//------------------------------------------------------ +sAnalogIn::sAnalogIn() { + +} + //------------------------------------------------------ sDigitalOut::sDigitalOut() { @@ -112,10 +126,10 @@ //If we are currently checking this input, then we buffer the trigger and deal with it after if (newState == 0){ bufferedDownEvent.timeStamp = timeStamp; - //bufferedDownEvent.triggered = true; + bufferedDownEvent.triggered = true; } else if (newState == 1) { bufferedUpEvent.timeStamp = timeStamp; - //bufferedUpEvent.triggered = true; + bufferedUpEvent.triggered = true; } } /*
--- a/hardwareInterface.h Fri Jun 10 21:22:34 2016 +0000 +++ b/hardwareInterface.h Tue Feb 07 18:45:25 2017 +0000 @@ -33,6 +33,34 @@ }; +class sAnalogIn +{ +public: + sAnalogIn(); + + virtual void init(int pin) = 0; + virtual int read() = 0; + + +protected: + + +}; + +class sAnalogOut +{ +public: + sAnalogOut(); + + virtual void init(int pin) = 0; + virtual void write(int value) = 0; + virtual int read() = 0; +protected: + +}; + + + class sDigitalIn { public: @@ -101,12 +129,15 @@ virtual void setSlaveClock() = 0; virtual sDigitalOut* getDigitalOutPtr(int portNum) = 0; virtual sDigitalIn* getDigitalInPtr(int portNum) = 0; + virtual sAnalogOut* getAnalogOutPtr(int portNum) = 0; + virtual sAnalogIn* getAnalogInPtr(int portNum) = 0; virtual sSound* createNewSoundAction() = 0; virtual void externalClockReset() = 0; //needs to reset harware timer before calling immediateClockReset(); virtual void incrementClock() = 0; virtual void mainLoopToDo(); virtual void pauseInterrupts(); virtual void resumeInterrupts(); + virtual void reset(); virtual int getPendingFunctionTriggers(uint16_t *bufferPtr); //Returns the number of pending shortcut triggers virtual uint32_t getDigitalOutputChangeFlags(); virtual uint32_t getDigitalInputChangeFlags();
--- a/mbedInterface/mbedInterface.cpp Fri Jun 10 21:22:34 2016 +0000 +++ b/mbedInterface/mbedInterface.cpp Tue Feb 07 18:45:25 2017 +0000 @@ -134,10 +134,17 @@ //--------------------------------------------------------------------- //translate pin numbers to hardware pins -PinName outPins[NUMOUTPORTS] = {p11,p13,p15,p18,p21,p23,p25,p29,p20,p6}; //Old board output pins -//PinName outPins[NUMPORTS] = {p18,p15,p13,p11,p29,p25,p23,p21,p20}; //New board output pins -PinName inPins[NUMINPORTS] = {p12,p14,p16,p17,p22,p24,p26,p30,p7}; +//PinName dOutPins[NUMDIGOUTPORTS] = {p11,p13,p15,p18,p21,p23,p25,p29,p20,p6}; //Old board output pins +//PinName dOutPins[NUMDIGOUTPORTS] = {p18,p15,p13,p11,p29,p25,p23,p21,p20}; //New board output pins +//PinName dInPins[NUMDIGINPORTS] = {p12,p14,p16,p17,p22,p24,p26,p30,p7}; +//PinName aInPins[NUMANINPORTS] = {}; +//PinName aOutPins[NUMANOUTPORTS] = {}; + +PinName dOutPins[NUMDIGOUTPORTS] = {p7,p15,p13,p11,p29,p25,p23,p21}; //With analog pins +PinName dInPins[NUMDIGINPORTS] = {p12,p14,p16,p17,p22,p24,p26,p30}; +PinName aInPins[NUMANINPORTS] = {p20}; +PinName aOutPins[NUMANOUTPORTS] = {p18}; //The sound output uses a SmartWav device and their simple serial library @@ -196,10 +203,19 @@ //------------------------------- - for (int i=0; i < NUMPORTS; i++) { + for (int i=0; i < NUMDIGINPORTS; i++) { dIn[i].init(i); + } + for (int i=0; i < NUMDIGOUTPORTS; i++) { dOut[i].init(i); } + for (int i=0; i < NUMANINPORTS; i++) { + aIn[i].init(i); + } + for (int i=0; i < NUMANOUTPORTS; i++) { + aOut[i].init(i); + } + sWav.reset(); @@ -263,7 +279,7 @@ } sDigitalOut* MBEDSystem::getDigitalOutPtr(int portNum){ - if (portNum < NUMPORTS) { + if (portNum < NUMDIGOUTPORTS) { return &dOut[portNum]; } else { return NULL; @@ -271,13 +287,29 @@ } sDigitalIn* MBEDSystem::getDigitalInPtr(int portNum) { - if (portNum < NUMPORTS) { + if (portNum < NUMDIGINPORTS) { return &dIn[portNum]; } else { return NULL; } } +sAnalogOut* MBEDSystem::getAnalogOutPtr(int portNum){ + if (portNum < NUMANOUTPORTS) { + return &aOut[portNum]; + } else { + return NULL; + } +} + +sAnalogIn* MBEDSystem::getAnalogInPtr(int portNum) { + if (portNum < NUMANINPORTS) { + return &aIn[portNum]; + } else { + return NULL; + } +} + sSound* MBEDSystem::createNewSoundAction() { MBEDSound *tmpSound = new MBEDSound(); return tmpSound; @@ -374,13 +406,70 @@ } //----------------------------------------------------- +MBEDAnalogOut::MBEDAnalogOut() { + +} + +void MBEDAnalogOut::init(int pin) { + if (pin < NUMANOUTPORTS) { + outpin = new AnalogOut(aOutPins[pin]); + pinExists = true; + } +} + +int MBEDAnalogOut::read() { + + if (pinExists) { + return outpin->read()*3300.0; //read value is a fload between 0 and 1.0 (max voltage). Convert to mV integer value. + + } else { + return 0; + } + +} + +void MBEDAnalogOut::write(int value) { + + if (pinExists) { + + outpin->write((float)value / 3300.0);//should be a float input (percentage). We convert from integer mV value. + } + + +} +//-------------------------------------------------------- + +MBEDAnalogIn::MBEDAnalogIn() { + +} + +void MBEDAnalogIn::init(int pin) { + + if (pin < NUMANINPORTS) { + inpin = new AnalogIn(aInPins[pin]); + pinExists = true; + } + +} + +int MBEDAnalogIn::read() { + + if (pinExists) { + return inpin->read()*3300; //read value is a fload between 0 and 1.0 (max voltage). Convert to mV integer value. + } else { + return 0; + } +} + + +//----------------------------------------------------- MBEDDigitalOut::MBEDDigitalOut() { pinExists = false; } void MBEDDigitalOut::init(int pin) { - if (pin < NUMOUTPORTS) { - outpin = new DigitalOut(outPins[pin]); + if (pin < NUMDIGOUTPORTS) { + outpin = new DigitalOut(dOutPins[pin]); pinExists = true; } } @@ -407,9 +496,9 @@ void MBEDDigitalIn::init(int pin) { - if (pin < NUMINPORTS) { - inpin = new DigitalIn(inPins[pin]); - inpin_interrupt = new InterruptIn(inPins[pin]); + if (pin < NUMDIGINPORTS) { + inpin = new DigitalIn(dInPins[pin]); + inpin_interrupt = new InterruptIn(dInPins[pin]); inpin->mode(PullDown); //Set up callbacks for the port interrupts inpin_interrupt->rise(this, &MBEDDigitalIn::interrupt_up_callback);
--- a/mbedInterface/mbedInterface.h Fri Jun 10 21:22:34 2016 +0000 +++ b/mbedInterface/mbedInterface.h Tue Feb 07 18:45:25 2017 +0000 @@ -15,9 +15,11 @@ //#define MBED_RF -#define NUMPORTS 10 //the number of ports available on this hardware -#define NUMINPORTS 9 -#define NUMOUTPORTS 10 +//#define NUMPORTS 10 //the number of ports available on this hardware +#define NUMDIGINPORTS 8 +#define NUMDIGOUTPORTS 8 +#define NUMANINPORTS 1 +#define NUMANOUTPORTS 1 #define NUMEVENTS 50 #define NUMCONDITIONS 150 @@ -52,7 +54,40 @@ };*/ +class MBEDAnalogOut : public sAnalogOut +{ +public: + MBEDAnalogOut(); + void init(int pin); + void write(int value); + int read(); + +private: + //define the hardware output pin + uint8_t pinNumber; + AnalogOut *outpin; + bool pinExists; + +}; + +class MBEDAnalogIn : public sAnalogIn +{ +public: + MBEDAnalogIn(); + + void init(int pin); + int read(); + +protected: + +private: + uint8_t pinNumber; + AnalogIn *inpin; + bool pinExists; + + +}; class MBEDDigitalOut : public sDigitalOut { @@ -126,6 +161,8 @@ void setSlaveClock(); sDigitalOut* getDigitalOutPtr(int portNum); sDigitalIn* getDigitalInPtr(int portNum); + sAnalogOut* getAnalogOutPtr(int portNum); + sAnalogIn* getAnalogInPtr(int portNum); sSound* createNewSoundAction(); void pauseInterrupts(); void resumeInterrupts(); @@ -140,8 +177,10 @@ InterruptIn clockExternalIncrement; private: - MBEDDigitalIn dIn[NUMPORTS]; - MBEDDigitalOut dOut[NUMPORTS]; + MBEDDigitalIn dIn[NUMDIGINPORTS]; + MBEDDigitalOut dOut[NUMDIGOUTPORTS]; + MBEDAnalogIn aIn[NUMANINPORTS]; + MBEDAnalogOut aOut[NUMANOUTPORTS]; }; #endif // MBEDINTERFACE_H