mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-01-30 14:13:07 +01:00
5.5.8 Cam parser cleanup
This commit is contained in:
parent
137008ceb3
commit
95d90aa337
@ -1,31 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* © 2023-2025, Barry Daniel
|
||||||
|
* © 2025 Chris Harlow
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of CommandStation-EX
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
//sensorCAM parser.cpp version 3.03 Sep 2024
|
//sensorCAM parser.cpp version 3.05 Jan 2025
|
||||||
|
#include "DCCEXParser.h"
|
||||||
#include "CamParser.h"
|
#include "CamParser.h"
|
||||||
#include "FSH.h"
|
#include "FSH.h"
|
||||||
#include "IO_EXSensorCAM.h"
|
|
||||||
|
|
||||||
#ifndef SENSORCAM_VPIN //define CAM vpin (700?) in config.h
|
|
||||||
#define SENSORCAM_VPIN 0
|
|
||||||
#endif
|
|
||||||
#define CAM_VPIN SENSORCAM_VPIN
|
|
||||||
#ifndef SENSORCAM2_VPIN
|
|
||||||
#define SENSORCAM2_VPIN CAM_VPIN
|
|
||||||
#endif
|
|
||||||
#ifndef SENSORCAM3_VPIN
|
|
||||||
#define SENSORCAM3_VPIN 0
|
|
||||||
#endif
|
|
||||||
const int CAMVPINS[] = {CAM_VPIN,SENSORCAM_VPIN,SENSORCAM2_VPIN,SENSORCAM3_VPIN};
|
|
||||||
const int16_t ver=30177;
|
const int16_t ver=30177;
|
||||||
const int16_t ve =2899;
|
const int16_t ve =2899;
|
||||||
|
|
||||||
VPIN EXSensorCAM::CAMBaseVpin = CAM_VPIN;
|
|
||||||
|
// The CAMVPINS array will be filled by IO_EXSensorCam HAL drivers calling
|
||||||
|
// the CamParser::addVpin() function.
|
||||||
|
// The CAMBaseVpin is the one to be used when commands are given without a vpin.
|
||||||
|
VPIN CamParser::CAMBaseVpin = 0; // no vpins yet known
|
||||||
|
VPIN CamParser::CAMVPINS[] = {0,0,0,0}; // no vpins yet known
|
||||||
|
int CamParser::vpcount=sizeof(CAMVPINS)/sizeof(CAMVPINS[0]);
|
||||||
|
|
||||||
|
void CamParser::parse(Print * stream, byte & opcode, byte & paramCount, int16_t p[]) {
|
||||||
|
if (opcode!='N') return; // this is not for us.
|
||||||
|
if (parseN(stream,paramCount,p)) opcode=0; // we have consumed this
|
||||||
|
// If we fail, the caller will <X> the <N command.
|
||||||
|
}
|
||||||
|
|
||||||
bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
|
bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
|
||||||
(void)stream; // probably unused parameter
|
(void)stream; // probably unused parameter
|
||||||
VPIN vpin=EXSensorCAM::CAMBaseVpin; //use current CAM selection
|
VPIN vpin=CAMBaseVpin; //use current CAM selection
|
||||||
|
|
||||||
if (paramCount==0) {
|
if (paramCount==0) {
|
||||||
DIAG(F("vpin:%d EXSensorCAMs defined at Vpins #1@ %d #2@ %d #3@ %d"),vpin,CAMVPINS[1],CAMVPINS[2],CAMVPINS[3]);
|
DIAG(F("Cam base vpin:%d"),CAMBaseVpin);
|
||||||
|
for (auto i=0;i<vpcount;i++){
|
||||||
|
if (CAMVPINS[i]==0) break;
|
||||||
|
DIAG(F("EXSensorCam #%d vpin %d"),i+1,CAMVPINS[i]);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
uint8_t camop=p[0]; // cam oprerator
|
uint8_t camop=p[0]; // cam oprerator
|
||||||
@ -33,33 +58,33 @@ bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
|
|||||||
int16_t param3=9999; // =0 could invoke parameter changes. & -1 gives later errors
|
int16_t param3=9999; // =0 could invoke parameter changes. & -1 gives later errors
|
||||||
|
|
||||||
if(camop=='C'){
|
if(camop=='C'){
|
||||||
if(p[1]>=100) EXSensorCAM::CAMBaseVpin=p[1];
|
if(p[1]>=100) CAMBaseVpin=p[1];
|
||||||
if(p[1]<4) EXSensorCAM::CAMBaseVpin=CAMVPINS[p[1]];
|
if(p[1]<vpcount) CAMBaseVpin=CAMVPINS[p[1]];
|
||||||
DIAG(F("CAM base Vpin: %c %d "),p[0],EXSensorCAM::CAMBaseVpin);
|
DIAG(F("CAM base Vpin: %c %d "),p[0],CAMBaseVpin);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (camop<100) { //switch CAM# if p[1] dictates
|
if (camop<100) { //switch CAM# if p[1] dictates
|
||||||
if(p[1]>=100 && p[1]<400) { //limits to CAM# 1 to 3 for now
|
if(p[1]>=100 && p[1]<(vpcount*100)) { //limits to CAM# 1 to 3 for now
|
||||||
vpin=CAMVPINS[p[1]/100];
|
vpin=CAMVPINS[p[1]/100];
|
||||||
EXSensorCAM::CAMBaseVpin=vpin;
|
CAMBaseVpin=vpin;
|
||||||
DIAG(F("switching to CAM %d baseVpin:%d"),p[1]/100,vpin);
|
DIAG(F("switching to CAM %d baseVpin:%d"),p[1]/100,vpin);
|
||||||
p[1]=p[1]%100; //strip off CAM #
|
p[1]=p[1]%100; //strip off CAM #
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (EXSensorCAM::CAMBaseVpin==0) return false; // no cam defined
|
if (CAMBaseVpin==0) return false; // no cam defined
|
||||||
|
|
||||||
|
|
||||||
// send UPPER case to sensorCAM to flag binary data from a DCCEX-CS parser
|
// send UPPER case to sensorCAM to flag binary data from a DCCEX-CS parser
|
||||||
switch(paramCount) {
|
switch(paramCount) {
|
||||||
case 1: //<N ver> produces '^'
|
case 1: //<N ver> produces '^'
|
||||||
if((p[0] == ve) || (p[0] == ver) || (p[0] == 'V')) camop='^';
|
if((camop == 'V') || (p[0] == ve) || (p[0] == ver) ) camop='^';
|
||||||
if (STRCHR_P((const char *)F("EFGMQRVW^"),camop) == nullptr) return false;
|
if (STRCHR_P((const char *)F("EFGMQRVW^"),camop) == nullptr) return false;
|
||||||
if (camop=='Q') param3=10; //<NQ> for activation state of all 10 banks of sensors
|
if (camop=='Q') param3=10; //<NQ> for activation state of all 10 banks of sensors
|
||||||
if (camop=='F') camop=']'; //<NF> for Reset/Finish webCAM.
|
if (camop=='F') camop=']'; //<NF> for Reset/Finish webCAM.
|
||||||
break; // F Coded as ']' else conflicts with <Nf %%>
|
break; // F Coded as ']' else conflicts with <Nf %%>
|
||||||
|
|
||||||
case 2: //<N camop p1>
|
case 2: //<N camop p1>
|
||||||
if (STRCHR_P((const char *)F("ABFILMNOPQRSTUV"),camop)==nullptr) return false;
|
if (STRCHR_P((const char *)F("ABFHILMNOPQRSTUV"),camop)==nullptr) return false;
|
||||||
param1=p[1];
|
param1=p[1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -93,3 +118,22 @@ bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
|
|||||||
IODevice::writeAnalogue(vpin,param1,camop,param3);
|
IODevice::writeAnalogue(vpin,param1,camop,param3);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CamParser::addVpin(VPIN pin) {
|
||||||
|
// called by IO_EXSensorCam starting up a camera on a vpin
|
||||||
|
byte slot=255;
|
||||||
|
for (auto i=0;i<vpcount && slot==255;i++) {
|
||||||
|
if (CAMVPINS[i]==0) {
|
||||||
|
slot=i;
|
||||||
|
CAMVPINS[slot]=pin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (slot==255) {
|
||||||
|
DIAG(F("No more than %d cameras supported"),vpcount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (slot==0) CAMBaseVpin=pin;
|
||||||
|
DIAG(F("CamParser Registered cam #%dvpin %d"),slot+1,pin);
|
||||||
|
// tell the DCCEXParser that we wish to filter commands
|
||||||
|
DCCEXParser::setCamParserFilter(&parse);
|
||||||
|
}
|
28
CamParser.h
28
CamParser.h
@ -1,3 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* © 2023-2025, Barry Daniel
|
||||||
|
* © 2025 Chris Harlow
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of CommandStation-EX
|
||||||
|
*
|
||||||
|
* 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 CamParser_H
|
#ifndef CamParser_H
|
||||||
#define CamParser_H
|
#define CamParser_H
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
@ -5,7 +27,13 @@
|
|||||||
|
|
||||||
class CamParser {
|
class CamParser {
|
||||||
public:
|
public:
|
||||||
|
static void parse(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
|
||||||
|
static void addVpin(VPIN pin);
|
||||||
|
private:
|
||||||
static bool parseN(Print * stream, byte paramCount, int16_t p[]);
|
static bool parseN(Print * stream, byte paramCount, int16_t p[]);
|
||||||
|
static VPIN CAMBaseVpin;
|
||||||
|
static VPIN CAMVPINS[];
|
||||||
|
static int vpcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -238,6 +238,7 @@ int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], byte *cmd,
|
|||||||
extern __attribute__((weak)) void myFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
|
extern __attribute__((weak)) void myFilter(Print * stream, byte & opcode, byte & paramCount, int16_t p[]);
|
||||||
FILTER_CALLBACK DCCEXParser::filterCallback = myFilter;
|
FILTER_CALLBACK DCCEXParser::filterCallback = myFilter;
|
||||||
FILTER_CALLBACK DCCEXParser::filterRMFTCallback = 0;
|
FILTER_CALLBACK DCCEXParser::filterRMFTCallback = 0;
|
||||||
|
FILTER_CALLBACK DCCEXParser::filterCamParserCallback = 0;
|
||||||
AT_COMMAND_CALLBACK DCCEXParser::atCommandCallback = 0;
|
AT_COMMAND_CALLBACK DCCEXParser::atCommandCallback = 0;
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
@ -249,6 +250,10 @@ void DCCEXParser::setRMFTFilter(FILTER_CALLBACK filter)
|
|||||||
{
|
{
|
||||||
filterRMFTCallback = filter;
|
filterRMFTCallback = filter;
|
||||||
}
|
}
|
||||||
|
void DCCEXParser::setCamParserFilter(FILTER_CALLBACK filter)
|
||||||
|
{
|
||||||
|
filterCamParserCallback = filter;
|
||||||
|
}
|
||||||
void DCCEXParser::setAtCommandCallback(AT_COMMAND_CALLBACK callback)
|
void DCCEXParser::setAtCommandCallback(AT_COMMAND_CALLBACK callback)
|
||||||
{
|
{
|
||||||
atCommandCallback = callback;
|
atCommandCallback = callback;
|
||||||
@ -304,6 +309,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
|||||||
filterCallback(stream, opcode, params, p);
|
filterCallback(stream, opcode, params, p);
|
||||||
if (filterRMFTCallback && opcode!='\0')
|
if (filterRMFTCallback && opcode!='\0')
|
||||||
filterRMFTCallback(stream, opcode, params, p);
|
filterRMFTCallback(stream, opcode, params, p);
|
||||||
|
if (filterCamParserCallback && opcode!='\0')
|
||||||
|
filterCamParserCallback(stream, opcode, params, p);
|
||||||
|
|
||||||
// Functions return from this switch if complete, break from switch implies error <X> to send
|
// Functions return from this switch if complete, break from switch implies error <X> to send
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
@ -898,15 +905,11 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
|
|||||||
if (parseI(stream, params, p))
|
if (parseI(stream, params, p))
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#ifndef IO_NO_HAL
|
|
||||||
case 'N': // <N commands for SensorCam
|
|
||||||
if (CamParser::parseN(stream,params,p)) return;
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case '/': // implemented in EXRAIL parser
|
case '/': // implemented in EXRAIL parser
|
||||||
case 'L': // LCC interface implemented in EXRAIL parser
|
case 'L': // LCC interface implemented in EXRAIL parser
|
||||||
break; // Will <X> if not intercepted by EXRAIL
|
case 'N': // interface implemented in CamParser
|
||||||
|
break; // Will <X> if not intercepted by filters
|
||||||
|
|
||||||
#ifndef DISABLE_VDPY
|
#ifndef DISABLE_VDPY
|
||||||
case '@': // JMRI saying "give me virtual LCD msgs"
|
case '@': // JMRI saying "give me virtual LCD msgs"
|
||||||
|
@ -37,6 +37,7 @@ struct DCCEXParser
|
|||||||
static void parseOne(Print * stream, byte * command, RingStream * ringStream);
|
static void parseOne(Print * stream, byte * command, RingStream * ringStream);
|
||||||
static void setFilter(FILTER_CALLBACK filter);
|
static void setFilter(FILTER_CALLBACK filter);
|
||||||
static void setRMFTFilter(FILTER_CALLBACK filter);
|
static void setRMFTFilter(FILTER_CALLBACK filter);
|
||||||
|
static void setCamParserFilter(FILTER_CALLBACK filter);
|
||||||
static void setAtCommandCallback(AT_COMMAND_CALLBACK filter);
|
static void setAtCommandCallback(AT_COMMAND_CALLBACK filter);
|
||||||
static const int MAX_COMMAND_PARAMS=10; // Must not exceed this
|
static const int MAX_COMMAND_PARAMS=10; // Must not exceed this
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ struct DCCEXParser
|
|||||||
static void callback_Vbyte(int16_t result);
|
static void callback_Vbyte(int16_t result);
|
||||||
static FILTER_CALLBACK filterCallback;
|
static FILTER_CALLBACK filterCallback;
|
||||||
static FILTER_CALLBACK filterRMFTCallback;
|
static FILTER_CALLBACK filterRMFTCallback;
|
||||||
|
static FILTER_CALLBACK filterCamParserCallback;
|
||||||
static AT_COMMAND_CALLBACK atCommandCallback;
|
static AT_COMMAND_CALLBACK atCommandCallback;
|
||||||
static bool funcmap(int16_t cab, byte value, byte fstart, byte fstop);
|
static bool funcmap(int16_t cab, byte value, byte fstart, byte fstop);
|
||||||
static void sendFlashList(Print * stream,const int16_t flashList[]);
|
static void sendFlashList(Print * stream,const int16_t flashList[]);
|
||||||
|
@ -16,7 +16,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#define driverVer 305
|
#define driverVer 306
|
||||||
|
// v306 Pass vpin to regeister it in CamParser.
|
||||||
|
// Move base vpin to camparser.
|
||||||
|
// No more need for config.h settings.
|
||||||
// v305 less debug & alpha ordered switch
|
// v305 less debug & alpha ordered switch
|
||||||
// v304 static oldb0; t(##[,%%];
|
// v304 static oldb0; t(##[,%%];
|
||||||
// v303 zipped with CS 5.2.76 and uploaded to repo (with debug)
|
// v303 zipped with CS 5.2.76 and uploaded to repo (with debug)
|
||||||
@ -35,23 +38,18 @@
|
|||||||
* This device driver will configure the device on startup, along with CamParser.cpp
|
* This device driver will configure the device on startup, along with CamParser.cpp
|
||||||
* interacting with the sensorCAM device for all input/output duties.
|
* interacting with the sensorCAM device for all input/output duties.
|
||||||
*
|
*
|
||||||
* #include "CamParser.h" in DCCEXParser.cpp
|
* To create EX-SensorCAM devices,
|
||||||
* #include "IO_EXSensorCAM.h" in IODevice.h
|
* use HAL(EXSensorCAM, baseVpin, numpins, i2c_address) in myAutomation.h
|
||||||
* To create EX-SensorCAM devices, define them in myHal.cpp: with
|
* e.g.
|
||||||
* EXSensorCAM::create(baseVpin,num_vpins,i2c_address) or
|
* HAL(EXSensorCAM,700, 80, 0x11)
|
||||||
* alternatively use HAL(EXSensorCAM baseVpin numpins i2c_address) in myAutomation.h
|
|
||||||
* also #define SENSORCAM_VPIN baseVpin in config.h
|
|
||||||
*
|
*
|
||||||
* void halSetup() {
|
* or (deprecated) define them in myHal.cpp: with
|
||||||
* // EXSensorCAM::create(vpin, num_vpins, i2c_address);
|
* EXSensorCAM::create(baseVpin,num_vpins,i2c_address);
|
||||||
* EXSensorCAM::create(700, 80, 0x11);
|
|
||||||
* }
|
|
||||||
*
|
*
|
||||||
* I2C packet size of 32 bytes (in the Wire library).
|
|
||||||
*/
|
*/
|
||||||
# define DIGITALREFRESH 20000UL // min uSec delay between digital reads of digitalInputStates
|
|
||||||
#ifndef IO_EX_EXSENSORCAM_H
|
#ifndef IO_EX_EXSENSORCAM_H
|
||||||
#define IO_EX_EXSENSORCAM_H
|
#define IO_EX_EXSENSORCAM_H
|
||||||
|
#define DIGITALREFRESH 20000UL // min uSec delay between digital reads of digitalInputStates
|
||||||
#define SEND StringFormatter::send
|
#define SEND StringFormatter::send
|
||||||
#include "IODevice.h"
|
#include "IODevice.h"
|
||||||
#include "I2CManager.h"
|
#include "I2CManager.h"
|
||||||
@ -70,7 +68,7 @@ class EXSensorCAM : public IODevice {
|
|||||||
new EXSensorCAM(vpin, nPins, i2cAddress);
|
new EXSensorCAM(vpin, nPins, i2cAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VPIN CAMBaseVpin;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -81,6 +79,7 @@ class EXSensorCAM : public IODevice {
|
|||||||
_nPins = nPins;
|
_nPins = nPins;
|
||||||
_I2CAddress = i2cAddress;
|
_I2CAddress = i2cAddress;
|
||||||
addDevice(this);
|
addDevice(this);
|
||||||
|
CamParser::addVpin(firstVpin);
|
||||||
}
|
}
|
||||||
//*************************
|
//*************************
|
||||||
void _begin() {
|
void _begin() {
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
#include "StringFormatter.h"
|
#include "StringFormatter.h"
|
||||||
|
|
||||||
#define VERSION "5.5.7"
|
#define VERSION "5.5.8"
|
||||||
|
// 5.5.8 - EXSensorCam clean up to match other filters and
|
||||||
|
// - avoid need for config.h settings
|
||||||
// 5.5.7 - ESP32 bugfix packet buffer race (as 5.4.1)
|
// 5.5.7 - ESP32 bugfix packet buffer race (as 5.4.1)
|
||||||
// 5.5.6 - Fix ESP32 build bug caused by include reference loop
|
// 5.5.6 - Fix ESP32 build bug caused by include reference loop
|
||||||
// 5.5.5 - Railcom implementation with IO_I2CRailcom driver
|
// 5.5.5 - Railcom implementation with IO_I2CRailcom driver
|
||||||
|
Loading…
Reference in New Issue
Block a user