From 95d90aa3375af82d260dd0351868dbcf4ce3151a Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 19 Jan 2025 13:00:34 +0000 Subject: [PATCH] 5.5.8 Cam parser cleanup --- CamParser.cpp | 92 +++++++++++++++++++++++++++++++++++------------- CamParser.h | 30 +++++++++++++++- DCCEXParser.cpp | 15 ++++---- DCCEXParser.h | 2 ++ IO_EXSensorCAM.h | 29 ++++++++------- version.h | 4 ++- 6 files changed, 125 insertions(+), 47 deletions(-) diff --git a/CamParser.cpp b/CamParser.cpp index 6ea26e5..a5b8227 100644 --- a/CamParser.cpp +++ b/CamParser.cpp @@ -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 . + */ -//sensorCAM parser.cpp version 3.03 Sep 2024 +//sensorCAM parser.cpp version 3.05 Jan 2025 +#include "DCCEXParser.h" #include "CamParser.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 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 the =100) EXSensorCAM::CAMBaseVpin=p[1]; - if(p[1]<4) EXSensorCAM::CAMBaseVpin=CAMVPINS[p[1]]; - DIAG(F("CAM base Vpin: %c %d "),p[0],EXSensorCAM::CAMBaseVpin); + if(p[1]>=100) CAMBaseVpin=p[1]; + 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]; - EXSensorCAM::CAMBaseVpin=vpin; + CAMBaseVpin=vpin; DIAG(F("switching to CAM %d baseVpin:%d"),p[1]/100,vpin); 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 switch(paramCount) { case 1: // 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 (camop=='Q') param3=10; // for activation state of all 10 banks of sensors if (camop=='F') camop=']'; // for Reset/Finish webCAM. break; // F Coded as ']' else conflicts with case 2: // - 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]; break; @@ -92,4 +117,23 @@ bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) { DIAG(F("CamParser: %d %c %d %d"),vpin,camop,param1,param3); IODevice::writeAnalogue(vpin,param1,camop,param3); 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. + */ + + #ifndef CamParser_H #define CamParser_H #include @@ -5,7 +27,13 @@ class CamParser { public: - static bool parseN(Print * stream, byte paramCount, int16_t p[]); + 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 VPIN CAMBaseVpin; + static VPIN CAMVPINS[]; + static int vpcount; }; diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 9a9a8a4..3174b5b 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -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[]); FILTER_CALLBACK DCCEXParser::filterCallback = myFilter; FILTER_CALLBACK DCCEXParser::filterRMFTCallback = 0; +FILTER_CALLBACK DCCEXParser::filterCamParserCallback = 0; AT_COMMAND_CALLBACK DCCEXParser::atCommandCallback = 0; // deprecated @@ -249,6 +250,10 @@ void DCCEXParser::setRMFTFilter(FILTER_CALLBACK filter) { filterRMFTCallback = filter; } +void DCCEXParser::setCamParserFilter(FILTER_CALLBACK filter) +{ + filterCamParserCallback = filter; +} void DCCEXParser::setAtCommandCallback(AT_COMMAND_CALLBACK callback) { atCommandCallback = callback; @@ -304,6 +309,8 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) filterCallback(stream, opcode, params, p); if (filterRMFTCallback && opcode!='\0') 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 to send switch (opcode) @@ -898,15 +905,11 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream) if (parseI(stream, params, p)) return; break; -#endif -#ifndef IO_NO_HAL - case 'N': // if not intercepted by EXRAIL + case 'N': // interface implemented in CamParser + break; // Will if not intercepted by filters #ifndef DISABLE_VDPY case '@': // JMRI saying "give me virtual LCD msgs" diff --git a/DCCEXParser.h b/DCCEXParser.h index 1ff8521..4c7553e 100644 --- a/DCCEXParser.h +++ b/DCCEXParser.h @@ -37,6 +37,7 @@ struct DCCEXParser static void parseOne(Print * stream, byte * command, RingStream * ringStream); static void setFilter(FILTER_CALLBACK filter); static void setRMFTFilter(FILTER_CALLBACK filter); + static void setCamParserFilter(FILTER_CALLBACK filter); static void setAtCommandCallback(AT_COMMAND_CALLBACK filter); 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 FILTER_CALLBACK filterCallback; static FILTER_CALLBACK filterRMFTCallback; + static FILTER_CALLBACK filterCamParserCallback; static AT_COMMAND_CALLBACK atCommandCallback; static bool funcmap(int16_t cab, byte value, byte fstart, byte fstop); static void sendFlashList(Print * stream,const int16_t flashList[]); diff --git a/IO_EXSensorCAM.h b/IO_EXSensorCAM.h index f91248d..a8156eb 100644 --- a/IO_EXSensorCAM.h +++ b/IO_EXSensorCAM.h @@ -16,7 +16,10 @@ * You should have received a copy of the GNU General Public License * along with CommandStation. If not, see . */ -#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 // v304 static oldb0; t(##[,%%]; // 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 * interacting with the sensorCAM device for all input/output duties. * - * #include "CamParser.h" in DCCEXParser.cpp - * #include "IO_EXSensorCAM.h" in IODevice.h - * To create EX-SensorCAM devices, define them in myHal.cpp: with - * EXSensorCAM::create(baseVpin,num_vpins,i2c_address) or - * alternatively use HAL(EXSensorCAM baseVpin numpins i2c_address) in myAutomation.h - * also #define SENSORCAM_VPIN baseVpin in config.h - * - * void halSetup() { - * // EXSensorCAM::create(vpin, num_vpins, i2c_address); - * EXSensorCAM::create(700, 80, 0x11); - * } + * To create EX-SensorCAM devices, + * use HAL(EXSensorCAM, baseVpin, numpins, i2c_address) in myAutomation.h + * e.g. + * HAL(EXSensorCAM,700, 80, 0x11) + * + * or (deprecated) define them in myHal.cpp: with + * EXSensorCAM::create(baseVpin,num_vpins,i2c_address); * - * 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 #define IO_EX_EXSENSORCAM_H +#define DIGITALREFRESH 20000UL // min uSec delay between digital reads of digitalInputStates #define SEND StringFormatter::send #include "IODevice.h" #include "I2CManager.h" @@ -70,7 +68,7 @@ class EXSensorCAM : public IODevice { new EXSensorCAM(vpin, nPins, i2cAddress); } - static VPIN CAMBaseVpin; + private: // Constructor @@ -81,6 +79,7 @@ class EXSensorCAM : public IODevice { _nPins = nPins; _I2CAddress = i2cAddress; addDevice(this); + CamParser::addVpin(firstVpin); } //************************* void _begin() { diff --git a/version.h b/version.h index 2ba389b..36c1338 100644 --- a/version.h +++ b/version.h @@ -3,7 +3,9 @@ #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.6 - Fix ESP32 build bug caused by include reference loop // 5.5.5 - Railcom implementation with IO_I2CRailcom driver