mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-01-28 21:23:06 +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 "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 <X> the <N command.
|
||||
}
|
||||
|
||||
bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
|
||||
(void)stream; // probably unused parameter
|
||||
VPIN vpin=EXSensorCAM::CAMBaseVpin; //use current CAM selection
|
||||
VPIN vpin=CAMBaseVpin; //use current CAM selection
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
|
||||
if(camop=='C'){
|
||||
if(p[1]>=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]<vpcount) CAMBaseVpin=CAMVPINS[p[1]];
|
||||
DIAG(F("CAM base Vpin: %c %d "),p[0],CAMBaseVpin);
|
||||
return true;
|
||||
}
|
||||
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];
|
||||
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: //<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 (camop=='Q') param3=10; //<NQ> for activation state of all 10 banks of sensors
|
||||
if (camop=='F') camop=']'; //<NF> for Reset/Finish webCAM.
|
||||
break; // F Coded as ']' else conflicts with <Nf %%>
|
||||
|
||||
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];
|
||||
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<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);
|
||||
}
|
30
CamParser.h
30
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
|
||||
#define CamParser_H
|
||||
#include <Arduino.h>
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 <X> 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': // <N commands for SensorCam
|
||||
if (CamParser::parseN(stream,params,p)) return;
|
||||
break;
|
||||
#endif
|
||||
case '/': // 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
|
||||
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 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[]);
|
||||
|
@ -16,7 +16,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* 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
|
||||
// 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() {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user