mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-26 17:46:14 +01:00
HAL write range
This commit is contained in:
parent
66e57b5ab2
commit
8e6fe6df21
|
@ -405,7 +405,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (params==2) { // <o [-]vpin count>
|
if (params==2) { // <o [-]vpin count>
|
||||||
for (auto pix=vpin;pix<vpin+p[1];pix++) IODevice::write(pix,setON);
|
IODevice::writeRange(vpin,setON,p[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
|
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
|
||||||
|
@ -416,7 +416,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
||||||
// strange parameter mangling... see IO_NeoPixel.h NeoPixel::_writeAnalogue
|
// strange parameter mangling... see IO_NeoPixel.h NeoPixel::_writeAnalogue
|
||||||
int colour_RG=(p[1]<<8) | p[2];
|
int colour_RG=(p[1]<<8) | p[2];
|
||||||
uint16_t colour_B=p[3];
|
uint16_t colour_B=p[3];
|
||||||
for (auto pix=vpin;pix<vpin+count;pix++) IODevice::writeAnalogue(pix,colour_RG,setON,colour_B);
|
IODevice::writeAnalogueRange(vpin,colour_RG,setON,colour_B,count);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
IODevice.cpp
38
IODevice.cpp
|
@ -251,6 +251,26 @@ void IODevice::write(VPIN vpin, int value) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write value to count virtual pin(s).
|
||||||
|
// these may be within one driver or separated over several drivers
|
||||||
|
void IODevice::writeRange(VPIN vpin, int value, int count) {
|
||||||
|
|
||||||
|
while(count) {
|
||||||
|
auto dev = findDevice(vpin);
|
||||||
|
if (dev) {
|
||||||
|
auto vpinBefore=vpin;
|
||||||
|
// write to driver, driver will return next vpin it cant handle
|
||||||
|
vpin=dev->_writeRange(vpin, value,count);
|
||||||
|
count-= vpin-vpinBefore; // decrement by number of vpins changed
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// skip a vpin if no device handler
|
||||||
|
vpin++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write analogue value to virtual pin(s). If multiple devices are allocated
|
// Write analogue value to virtual pin(s). If multiple devices are allocated
|
||||||
// the same pin then only the first one found will be used.
|
// the same pin then only the first one found will be used.
|
||||||
//
|
//
|
||||||
|
@ -270,6 +290,24 @@ void IODevice::writeAnalogue(VPIN vpin, int value, uint8_t param1, uint16_t para
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
void IODevice::writeAnalogueRange(VPIN vpin, int value, uint8_t param1, uint16_t param2,int count) {
|
||||||
|
while(count) {
|
||||||
|
auto dev = findDevice(vpin);
|
||||||
|
if (dev) {
|
||||||
|
auto vpinBefore=vpin;
|
||||||
|
// write to driver, driver will return next vpin it cant handle
|
||||||
|
vpin=dev->_writeAnalogueRange(vpin, value, param1, param2,count);
|
||||||
|
count-= vpin-vpinBefore; // decrement by number of vpins changed
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// skip a vpin if no device handler
|
||||||
|
vpin++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// isBusy, when called for a device pin is always a digital output or analogue output,
|
// isBusy, when called for a device pin is always a digital output or analogue output,
|
||||||
// returns input feedback state of the pin, i.e. whether the pin is busy performing
|
// returns input feedback state of the pin, i.e. whether the pin is busy performing
|
||||||
// an animation or fade over a period of time.
|
// an animation or fade over a period of time.
|
||||||
|
|
20
IODevice.h
20
IODevice.h
|
@ -128,9 +128,11 @@ public:
|
||||||
|
|
||||||
// write invokes the IODevice instance's _write method.
|
// write invokes the IODevice instance's _write method.
|
||||||
static void write(VPIN vpin, int value);
|
static void write(VPIN vpin, int value);
|
||||||
|
static void writeRange(VPIN vpin, int value,int count);
|
||||||
|
|
||||||
// write invokes the IODevice instance's _writeAnalogue method (not applicable for digital outputs)
|
// write invokes the IODevice instance's _writeAnalogue method (not applicable for digital outputs)
|
||||||
static void writeAnalogue(VPIN vpin, int value, uint8_t profile=0, uint16_t duration=0);
|
static void writeAnalogue(VPIN vpin, int value, uint8_t profile=0, uint16_t duration=0);
|
||||||
|
static void writeAnalogueRange(VPIN vpin, int value, uint8_t profile, uint16_t duration, int count);
|
||||||
|
|
||||||
// isBusy returns true if the device is currently in an animation of some sort, e.g. is changing
|
// isBusy returns true if the device is currently in an animation of some sort, e.g. is changing
|
||||||
// the output over a period of time.
|
// the output over a period of time.
|
||||||
|
@ -177,11 +179,29 @@ public:
|
||||||
virtual void _write(VPIN vpin, int value) {
|
virtual void _write(VPIN vpin, int value) {
|
||||||
(void)vpin; (void)value;
|
(void)vpin; (void)value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Method to write new state (optionally implemented within device class)
|
||||||
|
// This will, by default just write to one vpin and return whet to do next.
|
||||||
|
// the real power comes where a single driver can update many vpins in one call.
|
||||||
|
virtual VPIN _writeRange(VPIN vpin, int value, int count) {
|
||||||
|
(void)count;
|
||||||
|
_write(vpin,value);
|
||||||
|
return vpin+1; // try next vpin
|
||||||
|
};
|
||||||
|
|
||||||
// Method to write an 'analogue' value (optionally implemented within device class)
|
// Method to write an 'analogue' value (optionally implemented within device class)
|
||||||
virtual void _writeAnalogue(VPIN vpin, int value, uint8_t param1=0, uint16_t param2=0) {
|
virtual void _writeAnalogue(VPIN vpin, int value, uint8_t param1=0, uint16_t param2=0) {
|
||||||
(void)vpin; (void)value; (void) param1; (void)param2;
|
(void)vpin; (void)value; (void) param1; (void)param2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Method to write an 'analogue' value to a VPIN range (optionally implemented within device class)
|
||||||
|
// This will, by default just write to one vpin and return whet to do next.
|
||||||
|
// the real power comes where a single driver can update many vpins in one call.
|
||||||
|
virtual VPIN _writeAnalogueRange(VPIN vpin, int value, uint8_t param1, uint16_t param2, int count) {
|
||||||
|
(void) count;
|
||||||
|
_writeAnalogue(vpin, value, param1, param2);
|
||||||
|
return vpin+1;
|
||||||
|
};
|
||||||
|
|
||||||
// Method to read digital pin state (optionally implemented within device class)
|
// Method to read digital pin state (optionally implemented within device class)
|
||||||
virtual int _read(VPIN vpin) {
|
virtual int _read(VPIN vpin) {
|
||||||
|
|
|
@ -233,7 +233,17 @@ private:
|
||||||
}
|
}
|
||||||
transmit(pixel);
|
transmit(pixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VPIN _writeRange(VPIN vpin,int value, int count) {
|
||||||
|
// using write range cuts out the constant vpin to driver lookup so
|
||||||
|
// we can update multiple pixels much faster.
|
||||||
|
VPIN nextVpin=vpin + (count>_nPins ? _nPins : count);
|
||||||
|
if (_deviceState != DEVSTATE_FAILED) while(vpin<nextVpin) {
|
||||||
|
_write(vpin,value);
|
||||||
|
vpin++;
|
||||||
|
}
|
||||||
|
return nextVpin; // next pin we cant
|
||||||
|
}
|
||||||
// Write analogue value.
|
// Write analogue value.
|
||||||
// The convoluted parameter mashing here is to allow passing the RGB and on/off
|
// The convoluted parameter mashing here is to allow passing the RGB and on/off
|
||||||
// information through the generic HAL _writeAnalog interface which was originally
|
// information through the generic HAL _writeAnalog interface which was originally
|
||||||
|
@ -248,7 +258,16 @@ private:
|
||||||
pixelBuffer[pixel]=newColour;
|
pixelBuffer[pixel]=newColour;
|
||||||
transmit(pixel);
|
transmit(pixel);
|
||||||
}
|
}
|
||||||
|
VPIN _writeAnalogueRange(VPIN vpin, int colour_RG, uint8_t onoff, uint16_t colour_B, int count) override {
|
||||||
|
// using write range cuts out the constant vpin to driver lookup so
|
||||||
|
VPIN nextVpin=vpin + (count>_nPins ? _nPins : count);
|
||||||
|
if (_deviceState != DEVSTATE_FAILED) while(vpin<nextVpin) {
|
||||||
|
_writeAnalogue(vpin,colour_RG, onoff,colour_B);
|
||||||
|
vpin++;
|
||||||
|
}
|
||||||
|
return nextVpin; // next pin we cant
|
||||||
|
}
|
||||||
|
|
||||||
// Display device information and status.
|
// Display device information and status.
|
||||||
void _display() override {
|
void _display() override {
|
||||||
DIAG(F("NeoPixel I2C:%s Vpins %u-%u %S"),
|
DIAG(F("NeoPixel I2C:%s Vpins %u-%u %S"),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user