diff --git a/IO_EXIOExpander.h b/IO_EXIOExpander.h index 289f282..a782942 100644 --- a/IO_EXIOExpander.h +++ b/IO_EXIOExpander.h @@ -70,12 +70,6 @@ private: _firstVpin = firstVpin; _nPins = nPins; _i2cAddress = i2cAddress; - // To save RAM, space for servo configuration is not allocated unless a pin is used. - // Initialise the pointers to NULL. - // _servoData = (ServoData**) calloc(_nPins, sizeof(ServoData*)); - // for (int i=0; i<_nPins; i++) { - // _servoData[i] = NULL; - // } addDevice(this); } @@ -166,14 +160,6 @@ private: I2CManager.read(_i2cAddress, _digitalInputStates, _digitalPinBytes, _command1Buffer, 1); _command1Buffer[0] = EXIORDAN; I2CManager.read(_i2cAddress, _analogueInputStates, _analoguePinBytes, _command1Buffer, 1); - // if ((currentMicros - _lastRefresh) / 1000UL > refreshInterval) { - // _lastRefresh = currentMicros; - // for (int pin=0; pin<_nPins; pin++) { - // if (_servoData[pin] != NULL) { - // updatePosition(pin); - // } - // } - // } } // Obtain the correct analogue input value @@ -194,42 +180,21 @@ private: int _read(VPIN vpin) override { if (_deviceState == DEVSTATE_FAILED) return 0; int pin = vpin - _firstVpin; - // if (_servoData[pin] == NULL) { - uint8_t pinByte = pin / 8; - bool value = bitRead(_digitalInputStates[pinByte], pin - pinByte * 8); - return value; - // } else { - // struct ServoData *s = _servoData[pin]; - // if (s == NULL) { - // return false; // No structure means no animation! - // } else { - // return (s->stepNumber < s->numSteps); - // } - // } + uint8_t pinByte = pin / 8; + bool value = bitRead(_digitalInputStates[pinByte], pin - pinByte * 8); + return value; } void _write(VPIN vpin, int value) override { if (_deviceState == DEVSTATE_FAILED) return; int pin = vpin - _firstVpin; - // if (_servoData[pin] == NULL) { - _digitalOutBuffer[0] = EXIOWRD; - _digitalOutBuffer[1] = pin; - _digitalOutBuffer[2] = value; - I2CManager.read(_i2cAddress, _command1Buffer, 1, _digitalOutBuffer, 3); - if (_command1Buffer[0] != EXIORDY) { - DIAG(F("Vpin %d cannot be used as a digital output pin"), (int)vpin); - } - // } else { - // if (value) value = 1; - // struct ServoData *s = _servoData[pin]; - // if (s != NULL) { - // // Use configured parameters - // this->_writeAnalogue(vpin, value ? s->activePosition : s->inactivePosition, s->profile, s->duration); - // } else { - // /* simulate digital pin on PWM */ - // this->_writeAnalogue(vpin, value ? 4095 : 0, Instant | NoPowerOff, 0); - // } - // } + _digitalOutBuffer[0] = EXIOWRD; + _digitalOutBuffer[1] = pin; + _digitalOutBuffer[2] = value; + I2CManager.read(_i2cAddress, _command1Buffer, 1, _digitalOutBuffer, 3); + if (_command1Buffer[0] != EXIORDY) { + DIAG(F("Vpin %d cannot be used as a digital output pin"), (int)vpin); + } } void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) override { @@ -252,88 +217,6 @@ private: } } -/* - void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) override { - if (_deviceState == DEVSTATE_FAILED) return; - int pin = vpin - _firstVpin; -#ifdef DIAG_IO - DIAG(F("Servo: WriteAnalogue Vpin:%d Value:%d Profile:%d Duration:%d %S"), - vpin, value, profile, duration, _deviceState == DEVSTATE_FAILED?F("DEVSTATE_FAILED"):F("")); -#endif - if (_deviceState == DEVSTATE_FAILED) return; - if (value > 4095) value = 4095; - else if (value < 0) value = 0; - - struct ServoData *s = _servoData[pin]; - if (s == NULL) { - // Servo pin not configured, so configure now using defaults - s = _servoData[pin] = (struct ServoData *) calloc(sizeof(struct ServoData), 1); - if (s == NULL) return; // Check for memory allocation failure - s->activePosition = 4095; - s->inactivePosition = 0; - s->currentPosition = value; - s->profile = Instant | NoPowerOff; // Use instant profile (but not this time) - } - - // Animated profile. Initiate the appropriate action. - s->currentProfile = profile; - uint8_t profileValue = profile & ~NoPowerOff; // Mask off 'don't-power-off' bit. - s->numSteps = profileValue==Fast ? 10 : // 0.5 seconds - profileValue==Medium ? 20 : // 1.0 seconds - profileValue==Slow ? 40 : // 2.0 seconds - profileValue==Bounce ? sizeof(_bounceProfile)-1 : // ~ 1.5 seconds - duration * 2 + 1; // Convert from deciseconds (100ms) to refresh cycles (50ms) - s->stepNumber = 0; - s->toPosition = value; - s->fromPosition = s->currentPosition; - } -*/ - -/* - void updatePosition(uint8_t pin) { - struct ServoData *s = _servoData[pin]; - if (s == NULL) return; // No pin configuration/state data - - if (s->numSteps == 0) return; // No animation in progress - - if (s->stepNumber == 0 && s->fromPosition == s->toPosition) { - // Go straight to end of sequence, output final position. - s->stepNumber = s->numSteps-1; - } - - if (s->stepNumber < s->numSteps) { - // Animation in progress, reposition servo - s->stepNumber++; - if ((s->currentProfile & ~NoPowerOff) == Bounce) { - // Retrieve step positions from array in flash - uint8_t profileValue = GETFLASH(&_bounceProfile[s->stepNumber]); - s->currentPosition = map(profileValue, 0, 100, s->fromPosition, s->toPosition); - } else { - // All other profiles - calculate step by linear interpolation between from and to positions. - s->currentPosition = map(s->stepNumber, 0, s->numSteps, s->fromPosition, s->toPosition); - } - // Send servo command - this->writePWM(pin, s->currentPosition); - } else if (s->stepNumber < s->numSteps + _catchupSteps) { - // We've finished animation, wait a little to allow servo to catch up - s->stepNumber++; - } else if (s->stepNumber == s->numSteps + _catchupSteps - && s->currentPosition != 0) { - s->numSteps = 0; // Done now. - } - } -*/ - -/* - void writePWM(int pin, uint16_t value) { - _command4Buffer[0] = EXIOWRAN; - _command4Buffer[1] = pin; - _command4Buffer[2] = value & 0xFF; - _command4Buffer[3] = value >> 8; - I2CManager.write(_i2cAddress, _command4Buffer, 4); - } -*/ - void _display() override { DIAG(F("EX-IOExpander I2C:x%x v%d.%d.%d Vpins %d-%d %S"), _i2cAddress, _majorVer, _minorVer, _patchVer, @@ -360,36 +243,6 @@ private: byte _servoBuffer[7]; uint8_t* _analoguePinMap; -/* - // Servo specific - struct ServoData { - uint16_t activePosition : 12; // Config parameter - uint16_t inactivePosition : 12; // Config parameter - uint16_t currentPosition : 12; - uint16_t fromPosition : 12; - uint16_t toPosition : 12; - uint8_t profile; // Config parameter - uint16_t stepNumber; // Index of current step (starting from 0) - uint16_t numSteps; // Number of steps in animation, or 0 if none in progress. - uint8_t currentProfile; // profile being used for current animation. - uint16_t duration; // time (tenths of a second) for animation to complete. - }; // 14 bytes per element, i.e. per pin in use - - ServoData** _servoData; - - static const uint8_t _catchupSteps = 5; // number of steps to wait before switching servo off - - const unsigned int refreshInterval = 50; // refresh every 50ms - unsigned long _lastRefresh = 0; - - // Profile for a bouncing signal or turnout - // The profile below is in the range 0-100% and should be combined with the desired limits - // of the servo set by _activePosition and _inactivePosition. The profile is symmetrical here, - // i.e. the bounce is the same on the down action as on the up action. First entry isn't used. - const byte FLASH _bounceProfile[30] = - {0,2,3,7,13,33,50,83,100,83,75,70,65,60,60,65,74,84,100,83,75,70,70,72,75,80,87,92,97,100}; -*/ - // EX-IOExpander protocol flags enum { EXIOINIT = 0xE0, // Flag to initialise setup procedure