1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-27 01:56:14 +01:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Asbelos
8e6fe6df21 HAL write range 2024-09-12 08:35:26 +01:00
Asbelos
66e57b5ab2 Killblink on neopixel set. 2024-09-08 09:26:37 +01:00
Asbelos
360c426675 Merge branch 'devel' into devel-pauls-i2c-devices 2024-09-07 16:45:29 +01:00
Harald Barth
b026417efb EXTRAIL: Propagate a failed loco addr read to EXRAIL so it can be used as IFLOCO(-1) 2024-09-06 09:28:40 +02:00
Harald Barth
7ffbd9d0e8 Use port variable 2024-09-05 13:01:54 +02:00
Harald Barth
6fa5511670 version 2024-09-04 09:13:52 +02:00
Harald Barth
c07ac38ab1 EXRAIL: Catch CV read errors in the callback 2024-09-04 09:11:51 +02:00
8 changed files with 101 additions and 17 deletions

View File

@ -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;
} }
} }

View File

@ -478,10 +478,15 @@ bool RMFT2::skipIfBlock() {
/* static */ void RMFT2::readLocoCallback(int16_t cv) { /* static */ void RMFT2::readLocoCallback(int16_t cv) {
if (cv <= 0) {
DIAG(F("CV read error"));
progtrackLocoId = -1;
return;
}
if (cv & LONG_ADDR_MARKER) { // maker bit indicates long addr if (cv & LONG_ADDR_MARKER) { // maker bit indicates long addr
progtrackLocoId = cv ^ LONG_ADDR_MARKER; // remove marker bit to get real long addr progtrackLocoId = cv ^ LONG_ADDR_MARKER; // remove marker bit to get real long addr
if (progtrackLocoId <= HIGHEST_SHORT_ADDR ) { // out of range for long addr if (progtrackLocoId <= HIGHEST_SHORT_ADDR ) { // out of range for long addr
DIAG(F("Long addr %d <= %d unsupported\n"), progtrackLocoId, HIGHEST_SHORT_ADDR); DIAG(F("Long addr %d <= %d unsupported"), progtrackLocoId, HIGHEST_SHORT_ADDR);
progtrackLocoId = -1; progtrackLocoId = -1;
} }
} else { } else {
@ -921,11 +926,10 @@ void RMFT2::loop2() {
delayMe(100); delayMe(100);
return; // still waiting for callback return; // still waiting for callback
} }
if (progtrackLocoId<0) {
kill(F("No Loco Found"),progtrackLocoId);
return; // still waiting for callback
}
// At failed read will result in loco == -1
// which is intended so it can be checked
// from within EXRAIL
loco=progtrackLocoId; loco=progtrackLocoId;
speedo=0; speedo=0;
forward=true; forward=true;
@ -998,17 +1002,19 @@ void RMFT2::loop2() {
} }
break; break;
#ifndef IO_NO_HAL
case OPCODE_NEOPIXEL: case OPCODE_NEOPIXEL:
// OPCODE_NEOPIXEL,V([-]vpin),OPCODE_PAD,V(colour_RG),OPCODE_PAD,V(colour_B),OPCODE_PAD,V(count) // OPCODE_NEOPIXEL,V([-]vpin),OPCODE_PAD,V(colour_RG),OPCODE_PAD,V(colour_B),OPCODE_PAD,V(count)
{ {
VPIN vpin=operand>0?operand:-operand; VPIN vpin=operand>0?operand:-operand;
auto count=getOperand(3); auto count=getOperand(3);
for (auto pix=vpin;pix<vpin+count;pix++) for (auto pix=vpin;pix<vpin+count;pix++) {
killBlinkOnVpin(pix);
IODevice::writeAnalogue(pix,getOperand(1),operand>0,getOperand(2)); IODevice::writeAnalogue(pix,getOperand(1),operand>0,getOperand(2));
} }
}
break; break;
#ifndef IO_NO_HAL
case OPCODE_WAITFORTT: // OPCODE_WAITFOR,V(turntable_id) case OPCODE_WAITFORTT: // OPCODE_WAITFOR,V(turntable_id)
if (Turntable::ttMoving(operand)) { if (Turntable::ttMoving(operand)) {
delayMe(100); delayMe(100);

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-202408291145Z" #define GITHUB_SHA "devel-202409040713Z"

View File

@ -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.

View File

@ -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.
@ -178,11 +180,29 @@ public:
(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) {
(void)vpin; (void)vpin;

View File

@ -234,6 +234,16 @@ 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,6 +258,15 @@ 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 {

View File

@ -265,7 +265,7 @@ bool WifiESP::setup(const char *SSid,
if(!MDNS.begin(hostname)) { if(!MDNS.begin(hostname)) {
DIAG(F("Wifi setup failed to start mDNS")); DIAG(F("Wifi setup failed to start mDNS"));
} }
if(!MDNS.addService("withrottle", "tcp", 2560)) { if(!MDNS.addService("withrottle", "tcp", port)) {
DIAG(F("Wifi setup failed to add withrottle service to mDNS")); DIAG(F("Wifi setup failed to add withrottle service to mDNS"));
} }

View File

@ -3,8 +3,9 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.2.75i2c" #define VERSION "5.2.76i2c"
// 5.2.75i2c - Add various I2C drivers, including TCA8418 and Adafruit NeoPixel Driver initially // 5.2.76i2c - Add various I2C drivers, including TCA8418 and Adafruit NeoPixel Driver initially
// 5.2.76 - Bugfix: EXRAIL: Catch CV read errors in the callback
// 5.2.75 - Bugfix: Serial lines 4 to 6 OK // 5.2.75 - Bugfix: Serial lines 4 to 6 OK
// 5.2.74 - Bugfix: ESP32 turn on the joined prog (as main) again after a prog operation // 5.2.74 - Bugfix: ESP32 turn on the joined prog (as main) again after a prog operation
// 5.2.73 - Bugfix: STM32 further fixes to shadowPORT entries in TrackManager.cpp for PORTG and PORTH // 5.2.73 - Bugfix: STM32 further fixes to shadowPORT entries in TrackManager.cpp for PORTG and PORTH