mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-06-07 16:55:23 +02:00
5.5.25 IO_Bitmap
This commit is contained in:
parent
fefc4c6035
commit
54f8aaf116
35
EXRAIL2.cpp
35
EXRAIL2.cpp
@ -263,6 +263,8 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
|||||||
case OPCODE_ATLT:
|
case OPCODE_ATLT:
|
||||||
case OPCODE_IFGTE:
|
case OPCODE_IFGTE:
|
||||||
case OPCODE_IFLT:
|
case OPCODE_IFLT:
|
||||||
|
case OPCODE_IFBITMAP_ALL:
|
||||||
|
case OPCODE_IFBITMAP_ANY:
|
||||||
case OPCODE_DRIVE: {
|
case OPCODE_DRIVE: {
|
||||||
DIAG(F("EXRAIL analog input VPIN %u"),(VPIN)operand);
|
DIAG(F("EXRAIL analog input VPIN %u"),(VPIN)operand);
|
||||||
IODevice::configureAnalogIn((VPIN)operand);
|
IODevice::configureAnalogIn((VPIN)operand);
|
||||||
@ -273,6 +275,10 @@ LookList* RMFT2::LookListLoader(OPCODE op1, OPCODE op2, OPCODE op3) {
|
|||||||
if (compileFeatures & FEATURE_SENSOR)
|
if (compileFeatures & FEATURE_SENSOR)
|
||||||
new EXRAILSensor(operand,progCounter+3,true );
|
new EXRAILSensor(operand,progCounter+3,true );
|
||||||
break;
|
break;
|
||||||
|
case OPCODE_ONBITMAP:
|
||||||
|
if (compileFeatures & FEATURE_SENSOR)
|
||||||
|
new EXRAILSensor(operand,progCounter+3,true, true );
|
||||||
|
break;
|
||||||
case OPCODE_ONBUTTON:
|
case OPCODE_ONBUTTON:
|
||||||
if (compileFeatures & FEATURE_SENSOR)
|
if (compileFeatures & FEATURE_SENSOR)
|
||||||
new EXRAILSensor(operand,progCounter+3,false );
|
new EXRAILSensor(operand,progCounter+3,false );
|
||||||
@ -763,6 +769,14 @@ void RMFT2::loop2() {
|
|||||||
skipIf=IODevice::readAnalogue(operand)>=(int)(getOperand(1));
|
skipIf=IODevice::readAnalogue(operand)>=(int)(getOperand(1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPCODE_IFBITMAP_ALL: // do next operand if sensor & mask == mask
|
||||||
|
skipIf=(IODevice::readAnalogue(operand) & getOperand(1)) != getOperand(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPCODE_IFBITMAP_ANY: // do next operand if sensor & mask !=0
|
||||||
|
skipIf=(IODevice::readAnalogue(operand) & getOperand(1)) == 0;
|
||||||
|
break;
|
||||||
|
|
||||||
case OPCODE_IFLOCO: // do if the loco is the active one
|
case OPCODE_IFLOCO: // do if the loco is the active one
|
||||||
skipIf=loco!=(uint16_t)operand; // bad luck if someone enters negative loco numbers into EXRAIL
|
skipIf=loco!=(uint16_t)operand; // bad luck if someone enters negative loco numbers into EXRAIL
|
||||||
break;
|
break;
|
||||||
@ -1095,6 +1109,26 @@ void RMFT2::loop2() {
|
|||||||
//if (diag) DIAG(F("EXRAIL begin(%d)"),operand);
|
//if (diag) DIAG(F("EXRAIL begin(%d)"),operand);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPCODE_BITMAP_INC:
|
||||||
|
IODevice::writeAnalogue(operand,IODevice::readAnalogue(operand)+1);
|
||||||
|
break;
|
||||||
|
case OPCODE_BITMAP_DEC:
|
||||||
|
{ int newval=IODevice::readAnalogue(operand)-1;
|
||||||
|
if (newval<0) newval=0;
|
||||||
|
IODevice::writeAnalogue(operand,newval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OPCODE_BITMAP_AND:
|
||||||
|
IODevice::writeAnalogue(operand,IODevice::readAnalogue(operand) & getOperand(1));
|
||||||
|
break;
|
||||||
|
case OPCODE_BITMAP_OR:
|
||||||
|
IODevice::writeAnalogue(operand,IODevice::readAnalogue(operand) | getOperand(1));
|
||||||
|
break;
|
||||||
|
case OPCODE_BITMAP_XOR:
|
||||||
|
IODevice::writeAnalogue(operand,IODevice::readAnalogue(operand) ^ getOperand(1));
|
||||||
|
break;
|
||||||
|
|
||||||
case OPCODE_AUTOSTART: // Handled only during begin process
|
case OPCODE_AUTOSTART: // Handled only during begin process
|
||||||
case OPCODE_PAD: // Just a padding for previous opcode needing >1 operand byte.
|
case OPCODE_PAD: // Just a padding for previous opcode needing >1 operand byte.
|
||||||
case OPCODE_TURNOUT: // Turnout definition ignored at runtime
|
case OPCODE_TURNOUT: // Turnout definition ignored at runtime
|
||||||
@ -1114,6 +1148,7 @@ void RMFT2::loop2() {
|
|||||||
case OPCODE_ONTIME:
|
case OPCODE_ONTIME:
|
||||||
case OPCODE_ONBUTTON:
|
case OPCODE_ONBUTTON:
|
||||||
case OPCODE_ONSENSOR:
|
case OPCODE_ONSENSOR:
|
||||||
|
case OPCODE_ONBITMAP:
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
case OPCODE_DCCTURNTABLE: // Turntable definition ignored at runtime
|
case OPCODE_DCCTURNTABLE: // Turntable definition ignored at runtime
|
||||||
case OPCODE_EXTTTURNTABLE: // Turntable definition ignored at runtime
|
case OPCODE_EXTTTURNTABLE: // Turntable definition ignored at runtime
|
||||||
|
@ -78,11 +78,12 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT,
|
|||||||
OPCODE_ROUTE_DISABLED,
|
OPCODE_ROUTE_DISABLED,
|
||||||
OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH,
|
OPCODE_STASH,OPCODE_CLEAR_STASH,OPCODE_CLEAR_ALL_STASH,OPCODE_PICKUP_STASH,
|
||||||
OPCODE_CLEAR_ANY_STASH,
|
OPCODE_CLEAR_ANY_STASH,
|
||||||
OPCODE_ONBUTTON,OPCODE_ONSENSOR,
|
OPCODE_ONBUTTON,OPCODE_ONSENSOR,OPCODE_ONVP_SENSOR,
|
||||||
OPCODE_NEOPIXEL,
|
OPCODE_NEOPIXEL,
|
||||||
OPCODE_ONBLOCKENTER,OPCODE_ONBLOCKEXIT,
|
OPCODE_ONBLOCKENTER,OPCODE_ONBLOCKEXIT,
|
||||||
OPCODE_ESTOPALL,OPCODE_XPOM,
|
OPCODE_ESTOPALL,OPCODE_XPOM,
|
||||||
// OPcodes below this point are skip-nesting IF operations
|
OPCODE_BITMAP_AND,OPCODE_BITMAP_OR,OPCODE_BITMAP_XOR,OPCODE_BITMAP_INC,OPCODE_BITMAP_DEC,OPCODE_ONBITMAP,
|
||||||
|
// OPcodes below this point are skip-nesting IF operations
|
||||||
// placed here so that they may be skipped as a group
|
// placed here so that they may be skipped as a group
|
||||||
// see skipIfBlock()
|
// see skipIfBlock()
|
||||||
IF_TYPE_OPCODES, // do not move this...
|
IF_TYPE_OPCODES, // do not move this...
|
||||||
@ -96,6 +97,7 @@ enum OPCODE : byte {OPCODE_THROW,OPCODE_CLOSE,OPCODE_TOGGLE_TURNOUT,
|
|||||||
OPCODE_IFLOCO,
|
OPCODE_IFLOCO,
|
||||||
OPCODE_IFTTPOSITION,
|
OPCODE_IFTTPOSITION,
|
||||||
OPCODE_IFSTASH,
|
OPCODE_IFSTASH,
|
||||||
|
OPCODE_IFBITMAP_ALL,OPCODE_IFBITMAP_ANY,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure thrunge_lcd is put last as there may be more than one display,
|
// Ensure thrunge_lcd is put last as there may be more than one display,
|
||||||
|
@ -94,6 +94,8 @@
|
|||||||
#undef IFTIMEOUT
|
#undef IFTIMEOUT
|
||||||
#undef IFTTPOSITION
|
#undef IFTTPOSITION
|
||||||
#undef IFRE
|
#undef IFRE
|
||||||
|
#undef IFBITMAP_ALL
|
||||||
|
#undef IFBITMAP_ANY
|
||||||
#undef INVERT_DIRECTION
|
#undef INVERT_DIRECTION
|
||||||
#undef JMRI_SENSOR
|
#undef JMRI_SENSOR
|
||||||
#undef JOIN
|
#undef JOIN
|
||||||
@ -133,6 +135,7 @@
|
|||||||
#undef ONBUTTON
|
#undef ONBUTTON
|
||||||
#undef ONSENSOR
|
#undef ONSENSOR
|
||||||
#undef ONTHROW
|
#undef ONTHROW
|
||||||
|
#undef ONBITMAP
|
||||||
#undef ONCHANGE
|
#undef ONCHANGE
|
||||||
#undef PARSE
|
#undef PARSE
|
||||||
#undef PAUSE
|
#undef PAUSE
|
||||||
@ -195,6 +198,11 @@
|
|||||||
#undef VIRTUAL_TURNOUT
|
#undef VIRTUAL_TURNOUT
|
||||||
#undef WAITFOR
|
#undef WAITFOR
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
|
#undef BITMAP_AND
|
||||||
|
#undef BITMAP_OR
|
||||||
|
#undef BITMAP_XOR
|
||||||
|
#undef BITMAP_INC
|
||||||
|
#undef BITMAP_DEC
|
||||||
#undef WAITFORTT
|
#undef WAITFORTT
|
||||||
#endif
|
#endif
|
||||||
#undef WITHROTTLE
|
#undef WITHROTTLE
|
||||||
@ -651,6 +659,22 @@
|
|||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
#define IFRE(vpin,value)
|
#define IFRE(vpin,value)
|
||||||
|
/**
|
||||||
|
* @def IFBITMAP_ALL(vpin,mask)
|
||||||
|
* @briaf Checks if (vpin pseudo-analog value & mask) == mask.
|
||||||
|
* @see IF
|
||||||
|
* @param vpin
|
||||||
|
* @param mask Binary mask applied to vpin value
|
||||||
|
*/
|
||||||
|
#define IFBITMAP_ALL(vpin,mask)
|
||||||
|
/**
|
||||||
|
* @def IFBITMAP_ANY(vpin,mask)
|
||||||
|
* @briaf Checks if vpin pseudo-analog value & mask is non zero
|
||||||
|
* @see IF
|
||||||
|
* @param vpin
|
||||||
|
* @param mask Binary mask applied to vpin value
|
||||||
|
*/
|
||||||
|
#define IFBITMAP_ANY(vpin,mask)
|
||||||
/**
|
/**
|
||||||
* @def INVERT_DIRECTION
|
* @def INVERT_DIRECTION
|
||||||
* @brief Marks current task so that FWD and REV commands are inverted.
|
* @brief Marks current task so that FWD and REV commands are inverted.
|
||||||
@ -899,6 +923,12 @@
|
|||||||
* @param vpin
|
* @param vpin
|
||||||
*/
|
*/
|
||||||
#define ONSENSOR(vpin)
|
#define ONSENSOR(vpin)
|
||||||
|
/**
|
||||||
|
* @def ONBITMAP(vpin)
|
||||||
|
* @brief Start task here when bitmap sensor changes state (debounced)
|
||||||
|
* @param vpin
|
||||||
|
*/
|
||||||
|
#define ONBITMAP(vpin)
|
||||||
/**
|
/**
|
||||||
* @def ONBUTTON(vpin)
|
* @def ONBUTTON(vpin)
|
||||||
* @brief Start task here when sensor changes HIGH to LOW.
|
* @brief Start task here when sensor changes HIGH to LOW.
|
||||||
@ -1322,9 +1352,42 @@
|
|||||||
* @param description... quoted text or HIDDEN
|
* @param description... quoted text or HIDDEN
|
||||||
*/
|
*/
|
||||||
#define VIRTUAL_TURNOUT(id,description...)
|
#define VIRTUAL_TURNOUT(id,description...)
|
||||||
|
/**
|
||||||
|
* @def BITMAP_AND(vpin1,mask)
|
||||||
|
* @brief Performs a bitwise AND operation on the given vpin analog value and mask.
|
||||||
|
* @param vpin1
|
||||||
|
* @param mask Binary mask to be ANDed with vpin1 value
|
||||||
|
*/
|
||||||
|
#define BITMAP_AND(vpin1,mask)
|
||||||
|
/**
|
||||||
|
* @def BITMAP_INC(vpin)
|
||||||
|
* @brief Increments poesudo analog value by 1
|
||||||
|
* @param vpin
|
||||||
|
*/
|
||||||
|
#define BITMAP_INC(vpin)
|
||||||
|
/**
|
||||||
|
* @def BITMAP_DEC(vpin)
|
||||||
|
* @brief Decrements poesudo analog value by 1 (to zero)
|
||||||
|
* @param vpin
|
||||||
|
*/
|
||||||
|
#define BITMAP_DEC(vpin)
|
||||||
|
/**
|
||||||
|
* @def BITMAP_OR(vpin1,mask)
|
||||||
|
* @brief Performs a bitwise OR operation on the given vpin analog value and mask.
|
||||||
|
* @param vpin1
|
||||||
|
* @param mask Binary mask to be ORed with vpin1 value
|
||||||
|
*/
|
||||||
|
#define BITMAP_OR(vpin1,mask)
|
||||||
|
/**
|
||||||
|
* @def BITMAP_XOR(vpin1,mask)
|
||||||
|
* @brief Performs a bitwise XOR operation on the given vpin analog value and mask.
|
||||||
|
* @param vpin1
|
||||||
|
* @param mask Binary mask to be XORed with vpin1 value
|
||||||
|
*/
|
||||||
|
#define BITMAP_XOR(vpin1,mask)
|
||||||
/**
|
/**
|
||||||
* @def WAITFOR(vpin)
|
* @def WAITFOR(vpin)
|
||||||
* @brief WAits for completion of servo movement
|
* @brief Waits for completion of servo movement
|
||||||
* @param vpin
|
* @param vpin
|
||||||
*/
|
*/
|
||||||
#define WAITFOR(pin)
|
#define WAITFOR(pin)
|
||||||
|
@ -160,6 +160,8 @@ bool exrailHalSetup() {
|
|||||||
#define ONBUTTON(vpin) | FEATURE_SENSOR
|
#define ONBUTTON(vpin) | FEATURE_SENSOR
|
||||||
#undef ONSENSOR
|
#undef ONSENSOR
|
||||||
#define ONSENSOR(vpin) | FEATURE_SENSOR
|
#define ONSENSOR(vpin) | FEATURE_SENSOR
|
||||||
|
#undef ONBITMAP
|
||||||
|
#define ONBITMAP(vpin) | FEATURE_SENSOR
|
||||||
#undef ONBLOCKENTER
|
#undef ONBLOCKENTER
|
||||||
#define ONBLOCKENTER(blockid) | FEATURE_BLOCK
|
#define ONBLOCKENTER(blockid) | FEATURE_BLOCK
|
||||||
#undef ONBLOCKEXIT
|
#undef ONBLOCKEXIT
|
||||||
@ -481,6 +483,8 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
|
|||||||
#define IFTTPOSITION(id,position) OPCODE_IFTTPOSITION,V(id),OPCODE_PAD,V(position),
|
#define IFTTPOSITION(id,position) OPCODE_IFTTPOSITION,V(id),OPCODE_PAD,V(position),
|
||||||
#endif
|
#endif
|
||||||
#define IFRE(sensor_id,value) OPCODE_IFRE,V(sensor_id),OPCODE_PAD,V(value),
|
#define IFRE(sensor_id,value) OPCODE_IFRE,V(sensor_id),OPCODE_PAD,V(value),
|
||||||
|
#define IFBITMAP_ALL(vpin,mask) OPCODE_IFBITMAP_ALL,V(vpin),OPCODE_PAD,V(mask),
|
||||||
|
#define IFBITMAP_ANY(vpin,mask) OPCODE_IFBITMAP_ANY,V(vpin),OPCODE_PAD,V(mask),
|
||||||
#define INVERT_DIRECTION OPCODE_INVERT_DIRECTION,0,0,
|
#define INVERT_DIRECTION OPCODE_INVERT_DIRECTION,0,0,
|
||||||
#define JMRI_SENSOR(vpin,count...)
|
#define JMRI_SENSOR(vpin,count...)
|
||||||
#define JOIN OPCODE_JOIN,0,0,
|
#define JOIN OPCODE_JOIN,0,0,
|
||||||
@ -533,6 +537,7 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
|
|||||||
#define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id),
|
#define ONTHROW(turnout_id) OPCODE_ONTHROW,V(turnout_id),
|
||||||
#define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id),
|
#define ONCHANGE(sensor_id) OPCODE_ONCHANGE,V(sensor_id),
|
||||||
#define ONSENSOR(sensor_id) OPCODE_ONSENSOR,V(sensor_id),
|
#define ONSENSOR(sensor_id) OPCODE_ONSENSOR,V(sensor_id),
|
||||||
|
#define ONBITMAP(sensor_id) OPCODE_ONBITMAP,V(sensor_id),
|
||||||
#define ONBUTTON(sensor_id) OPCODE_ONBUTTON,V(sensor_id),
|
#define ONBUTTON(sensor_id) OPCODE_ONBUTTON,V(sensor_id),
|
||||||
#define PAUSE OPCODE_PAUSE,0,0,
|
#define PAUSE OPCODE_PAUSE,0,0,
|
||||||
#define PICKUP_STASH(id) OPCODE_PICKUP_STASH,V(id),
|
#define PICKUP_STASH(id) OPCODE_PICKUP_STASH,V(id),
|
||||||
@ -595,6 +600,11 @@ int RMFT2::onLCCLookup[RMFT2::countLCCLookup];
|
|||||||
#define UNLATCH(sensor_id) OPCODE_UNLATCH,V(sensor_id),
|
#define UNLATCH(sensor_id) OPCODE_UNLATCH,V(sensor_id),
|
||||||
#define VIRTUAL_SIGNAL(id)
|
#define VIRTUAL_SIGNAL(id)
|
||||||
#define VIRTUAL_TURNOUT(id,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(0),
|
#define VIRTUAL_TURNOUT(id,description...) OPCODE_PINTURNOUT,V(id),OPCODE_PAD,V(0),
|
||||||
|
#define BITMAP_AND(vpin,mask) OPCODE_BITMAP_AND,V(vpin),OPCODE_PAD,V(mask),
|
||||||
|
#define BITMAP_INC(vpin) OPCODE_BITMAP_INC,V(vpin),
|
||||||
|
#define BITMAP_DEC(vpin) OPCODE_BITMAP_DEC,V(vpin),
|
||||||
|
#define BITMAP_OR(vpin,mask) OPCODE_BITMAP_OR,V(vpin),OPCODE_PAD,V(mask),
|
||||||
|
#define BITMAP_XOR(vpin,mask) OPCODE_BITMAP_XOR,V(vpin),OPCODE_PAD,V(mask),
|
||||||
#define WITHROTTLE(msg) PRINT(msg)
|
#define WITHROTTLE(msg) PRINT(msg)
|
||||||
#define WAITFOR(pin) OPCODE_WAITFOR,V(pin),
|
#define WAITFOR(pin) OPCODE_WAITFOR,V(pin),
|
||||||
#ifndef IO_NO_HAL
|
#ifndef IO_NO_HAL
|
||||||
|
@ -59,7 +59,7 @@ void EXRAILSensor::checkAll() {
|
|||||||
|
|
||||||
bool EXRAILSensor::check() {
|
bool EXRAILSensor::check() {
|
||||||
// check for debounced change in this sensor
|
// check for debounced change in this sensor
|
||||||
inputState = RMFT2::readSensor(pin);
|
inputState = useAnalog?IODevice::readAnalogue(pin):RMFT2::readSensor(pin);
|
||||||
|
|
||||||
// Check if changed since last time, and process changes.
|
// Check if changed since last time, and process changes.
|
||||||
if (inputState == active) {// no change
|
if (inputState == active) {// no change
|
||||||
@ -83,18 +83,18 @@ bool EXRAILSensor::check() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXRAILSensor::EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange) {
|
EXRAILSensor::EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange, bool _useAnalog) {
|
||||||
// Add to the start of the list
|
|
||||||
//DIAG(F("ONthing vpin=%d at %d"), _pin, _progCounter);
|
|
||||||
nextSensor = firstSensor;
|
nextSensor = firstSensor;
|
||||||
firstSensor = this;
|
firstSensor = this;
|
||||||
|
|
||||||
pin=_pin;
|
pin=_pin;
|
||||||
progCounter=_progCounter;
|
progCounter=_progCounter;
|
||||||
onChange=_onChange;
|
onChange=_onChange;
|
||||||
|
useAnalog=_useAnalog;
|
||||||
|
|
||||||
IODevice::configureInput(pin, true);
|
IODevice::configureInput(pin, true);
|
||||||
active = IODevice::read(pin);
|
active = useAnalog?IODevice::readAnalogue(pin): IODevice::read(pin);
|
||||||
inputState = active;
|
inputState = active;
|
||||||
latchDelay = minReadCount;
|
latchDelay = minReadCount;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@ class EXRAILSensor {
|
|||||||
public:
|
public:
|
||||||
static void checkAll();
|
static void checkAll();
|
||||||
|
|
||||||
EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange);
|
EXRAILSensor(VPIN _pin, int _progCounter, bool _onChange, bool _useAnalog=false);
|
||||||
|
|
||||||
bool check();
|
bool check();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -42,9 +43,10 @@ class EXRAILSensor {
|
|||||||
EXRAILSensor* nextSensor;
|
EXRAILSensor* nextSensor;
|
||||||
VPIN pin;
|
VPIN pin;
|
||||||
int progCounter;
|
int progCounter;
|
||||||
bool active;
|
uint16_t active;
|
||||||
bool inputState;
|
uint16_t inputState;
|
||||||
bool onChange;
|
bool onChange;
|
||||||
|
bool useAnalog;
|
||||||
byte latchDelay;
|
byte latchDelay;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,19 +20,31 @@
|
|||||||
This is the list of HAL drivers automatically included by IODevice.h
|
This is the list of HAL drivers automatically included by IODevice.h
|
||||||
It has been moved here to be easier to maintain than editing IODevice.h
|
It has been moved here to be easier to maintain than editing IODevice.h
|
||||||
*/
|
*/
|
||||||
|
#include "IO_AnalogueInputs.h"
|
||||||
|
#include "IO_DFPlayer.h"
|
||||||
|
#include "IO_DS1307.h"
|
||||||
|
#include "IO_duinoNodes.h"
|
||||||
|
#include "IO_EncoderThrottle.h"
|
||||||
|
#include "IO_EXFastclock.h"
|
||||||
|
#include "IO_EXIOExpander.h"
|
||||||
|
#include "IO_EXSensorCAM.h"
|
||||||
|
#include "IO_HALDisplay.h"
|
||||||
|
#include "IO_HCSR04.h"
|
||||||
|
#include "IO_I2CDFPlayer.h"
|
||||||
|
#include "IO_I2CRailcom.h"
|
||||||
#include "IO_MCP23008.h"
|
#include "IO_MCP23008.h"
|
||||||
#include "IO_MCP23017.h"
|
#include "IO_MCP23017.h"
|
||||||
|
#include "IO_NeoPixel.h"
|
||||||
|
#include "IO_PCA9555.h"
|
||||||
|
#include "IO_PCA9685pwm.h"
|
||||||
#include "IO_PCF8574.h"
|
#include "IO_PCF8574.h"
|
||||||
#include "IO_PCF8575.h"
|
#include "IO_PCF8575.h"
|
||||||
#include "IO_PCA9555.h"
|
#include "IO_RotaryEncoder.h"
|
||||||
#include "IO_duinoNodes.h"
|
#include "IO_Servo.h"
|
||||||
#include "IO_EXIOExpander.h"
|
|
||||||
#include "IO_trainbrains.h"
|
|
||||||
#include "IO_EncoderThrottle.h"
|
|
||||||
#include "IO_TCA8418.h"
|
#include "IO_TCA8418.h"
|
||||||
#include "IO_NeoPixel.h"
|
|
||||||
#include "IO_TM1638.h"
|
#include "IO_TM1638.h"
|
||||||
#include "IO_EXSensorCAM.h"
|
#include "IO_TouchKeypad.h"
|
||||||
#include "IO_DS1307.h"
|
#include "IO_trainbrains.h"
|
||||||
#include "IO_I2CRailcom.h"
|
#include "IO_Bitmap.h"
|
||||||
|
#include "IO_VL53L0X.h"
|
||||||
|
|
||||||
|
89
IO_Bitmap.h
Normal file
89
IO_Bitmap.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* © 2025, Chris Harlow. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of DCC-EX API
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* It is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef IO_Bitmap_h
|
||||||
|
#define IO_Bitmap_h
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "defines.h"
|
||||||
|
#include "IODevice.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bitmap provides a set of virtual pins with no hardware.
|
||||||
|
Bitmap pins are able to be output and input and may be set and tested
|
||||||
|
as digital or analogue values.
|
||||||
|
When writing a digital value, the analogue value is set to 0 or 1.
|
||||||
|
When reading a digital value, the return is LOW for value 0 or HIGH for any other value
|
||||||
|
or analogue.
|
||||||
|
|
||||||
|
Bitmap pins may be used for any purpose, this is easier to manage than LATCH in EXRAIL
|
||||||
|
as they can be explicitely set and tested without interfering with underlying hardware.
|
||||||
|
Bitmap pins may be set, reset and tested in the same way as any other pin.
|
||||||
|
They are not persistent across reboots, but are retained in the current session.
|
||||||
|
Bitmap pins may also be monitored by JMRI_SENSOR() and <S> as for any other pin.
|
||||||
|
|
||||||
|
*/
|
||||||
|
class Bitmap : public IODevice {
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void create(VPIN firstVpin, int nPins) {
|
||||||
|
if (IODevice::checkNoOverlap(firstVpin,nPins))
|
||||||
|
new Bitmap( firstVpin, nPins);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap(VPIN firstVpin, int nPins) : IODevice(firstVpin, nPins) {
|
||||||
|
_pinValues=(int16_t *) calloc(nPins,sizeof(int16_t));
|
||||||
|
// Connect to HAL so my _write, _read and _loop will be called as required.
|
||||||
|
IODevice::addDevice(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by HAL to start handling this device
|
||||||
|
void _begin() override {
|
||||||
|
_deviceState = DEVSTATE_NORMAL;
|
||||||
|
_display();
|
||||||
|
}
|
||||||
|
|
||||||
|
int _read(VPIN vpin) override {
|
||||||
|
int pin=vpin - _firstVpin;
|
||||||
|
return _pinValues[pin]?1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _write(VPIN vpin, int value) override {
|
||||||
|
int pin = vpin - _firstVpin;
|
||||||
|
_pinValues[pin]=value!=0; // this is digital write
|
||||||
|
}
|
||||||
|
|
||||||
|
int _readAnalogue(VPIN vpin) override {
|
||||||
|
int pin=vpin - _firstVpin;
|
||||||
|
return _pinValues[pin]; // this is analog read
|
||||||
|
}
|
||||||
|
|
||||||
|
void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) override {
|
||||||
|
int pin=vpin - _firstVpin;
|
||||||
|
_pinValues[pin]=value; // this is analog write
|
||||||
|
}
|
||||||
|
|
||||||
|
void _display() override {
|
||||||
|
DIAG(F("Bitmap Configured on Vpins:%u-%u"),
|
||||||
|
(int)_firstVpin,
|
||||||
|
(int)_firstVpin+_nPins-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int16_t* _pinValues;
|
||||||
|
};
|
||||||
|
#endif
|
58
Release_Notes/IO_Bitmap.md
Normal file
58
Release_Notes/IO_Bitmap.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
Virtual Bitmap device pins.
|
||||||
|
|
||||||
|
a Bitmap device pin is a software representation of a virtual hardware device that has the ability to store a 16bit value.
|
||||||
|
|
||||||
|
This this is easier to manage than LATCH in EXRAIL as they can be explicitely set and tested without interfering with underlying hardware or breaching the 255 limit.
|
||||||
|
|
||||||
|
Virtual pins may be set, reset and tested in the same way as any other pin. Unlike sensors and leds, these device pins are both INPUT and OUTPUT These can be used in many ways:
|
||||||
|
|
||||||
|
As a simple digital flag to assist in inter-thread communication.
|
||||||
|
A flag or value that can be set from commands and tested in EXRAIL.(e.g. to stop a sequence)
|
||||||
|
As a counter for looping or occupancy counts such as trains passing over a multi track road crossing.
|
||||||
|
As a collection of 16 digital bits that can be set, reset, toggled, masked and tested.
|
||||||
|
|
||||||
|
Existing <> and exrail commands for vpins work on these pins.
|
||||||
|
|
||||||
|
Virtual pin creation:
|
||||||
|
HAL(Bitmap,firstpin,npins)
|
||||||
|
creates 1 or more virtual pins in software. (RAM requirement approximately 2 bytes per pin)
|
||||||
|
e.g. HAL(Bitmap,1000,20) creates pins 1000..1019
|
||||||
|
|
||||||
|
Simple use as flags:
|
||||||
|
This uses the traditional digital pin commands
|
||||||
|
SET(1013) RESET(1013) sets value 1 or 0
|
||||||
|
SET(1000,20) RESET(1000,20) sets/resets a range of pins
|
||||||
|
IF(1000) tests if pin value!=0
|
||||||
|
|
||||||
|
Commands can set 1/0 values using <z 1010> <z -1010> as for any digital output.
|
||||||
|
BLINK can be used to set them on/off on a time pattern.
|
||||||
|
|
||||||
|
In addition, Exrail sensor comands work as if these pins were sensors
|
||||||
|
ONBUTTON(1013) triggers when value changes from 0 to something.
|
||||||
|
ONSENSOR(1013) triggers when value changes to or from 0.
|
||||||
|
<S 1013 1013 1> and JMRI_SENSOR(1013) report <Q/q responses when changing to or from 0.
|
||||||
|
|
||||||
|
Use as analog values:
|
||||||
|
Analog values may be set into the virtual pins and tested using the existing analog value commands and exrail macros.
|
||||||
|
<z vpin value> <D ANIN vpin> etc.
|
||||||
|
|
||||||
|
Use as counters:
|
||||||
|
For loop counting, counters can be incremented by BITMAP_INC(1013) and decremented by BITMAP_DEC(1013) and tested with IF/IFNOT/IFGTE etc.
|
||||||
|
Counters be used to automate a multi track crossing where each train entering increments the counter and decrements it on clearing the crossing. Crossing gate automation can be started when the value changes from 0, and be stopped when the counter returns to 0. Detecting the first increment from 0 to 1 can be done with ONBUTTON(1013) and the automation can use IF(1013) or IFNOT(1013) to detect when it needs to reopen the road gates.
|
||||||
|
|
||||||
|
Use as binary flag groups:
|
||||||
|
Virtual pins (and others that respond to an analog read in order to provide bitmapped digital data, such as SensorCam) can be set and tested with new special EXRAIL commands
|
||||||
|
|
||||||
|
IFBITMAP_ALL(vpin,mask) Bitwise ANDs the the vpin value with the mask value and is true if ALL the 1 bits in the mask are also 1 bits in the value.
|
||||||
|
e.g. IFBITMAP_ALL(1013,0x0f) would be true if ALL the last 4 bits of the value are 1s.
|
||||||
|
|
||||||
|
IFBITMAP_ANY(1013,0x0f) would be true if ANY of the last 4 bits are 1s.
|
||||||
|
|
||||||
|
|
||||||
|
Modifying bitmap values:
|
||||||
|
BITMAP_AND(vpin,mask) performs a bitwise AND operation.
|
||||||
|
BITMAP_OR(vpin,mask) performa a bitwise OR operation
|
||||||
|
BITMAP_XOR(vpin,mask) performs a bitwise EXCLUSIVE OR (which is basically a toggle)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "5.5.24"
|
#define VERSION "5.5.25"
|
||||||
|
// 5.2.25 - IO_Bitmap and assicated Exrail macros
|
||||||
// 5.5.24 - SensorCAM in I2C scan and automatically setClock
|
// 5.5.24 - SensorCAM in I2C scan and automatically setClock
|
||||||
// 5.5.23 - Reminder loop Idle packet optimization
|
// 5.5.23 - Reminder loop Idle packet optimization
|
||||||
// 5.5.22 - (5.4.9) Handle non-compliant decoders returning 255 for cv 20 and confusing <R> with bad consist addresses.
|
// 5.5.22 - (5.4.9) Handle non-compliant decoders returning 255 for cv 20 and confusing <R> with bad consist addresses.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user