Skip to content

Commit

Permalink
HAL write range
Browse files Browse the repository at this point in the history
  • Loading branch information
Asbelos committed Sep 12, 2024
1 parent 66e57b5 commit 8e6fe6d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
4 changes: 2 additions & 2 deletions DCCEXParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
return;
}
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;
}
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
Expand All @@ -416,7 +416,7 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
// strange parameter mangling... see IO_NeoPixel.h NeoPixel::_writeAnalogue
int colour_RG=(p[1]<<8) | p[2];
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;
}
}
Expand Down
38 changes: 38 additions & 0 deletions IODevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,26 @@ void IODevice::write(VPIN vpin, int value) {
#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
// the same pin then only the first one found will be used.
//
Expand All @@ -270,6 +290,24 @@ void IODevice::writeAnalogue(VPIN vpin, int value, uint8_t param1, uint16_t para
#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,
// returns input feedback state of the pin, i.e. whether the pin is busy performing
// an animation or fade over a period of time.
Expand Down
20 changes: 20 additions & 0 deletions IODevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ class IODevice {

// write invokes the IODevice instance's _write method.
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)
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
// the output over a period of time.
Expand Down Expand Up @@ -177,11 +179,29 @@ class IODevice {
virtual void _write(VPIN vpin, int 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)
virtual void _writeAnalogue(VPIN vpin, int value, uint8_t param1=0, uint16_t param2=0) {
(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)
virtual int _read(VPIN vpin) {
Expand Down
23 changes: 21 additions & 2 deletions IO_NeoPixel.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,17 @@ class NeoPixel : public IODevice {
}
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.
// The convoluted parameter mashing here is to allow passing the RGB and on/off
// information through the generic HAL _writeAnalog interface which was originally
Expand All @@ -248,7 +258,16 @@ class NeoPixel : public IODevice {
pixelBuffer[pixel]=newColour;
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.
void _display() override {
DIAG(F("NeoPixel I2C:%s Vpins %u-%u %S"),
Expand Down

0 comments on commit 8e6fe6d

Please sign in to comment.