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

Compare commits

...

2 Commits

Author SHA1 Message Date
Barry Daniel
99df0a39d7
Add files via upload 2024-09-06 13:18:06 +10:00
Barry Daniel
3620a87869
Add files via upload 2024-09-06 12:45:31 +10:00
4 changed files with 61 additions and 47 deletions

View File

@ -53,12 +53,13 @@ bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
// 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 (strchr_P((const char *)F("EFGMRVW^"),camop) == nullptr) return false; if (STRCHR_P((const char *)F("EFGMQRVW^"),camop) == nullptr) return false;
if (camop=='F') camop=']'; //<NF> for Reset/Finish webCAM. if (camop=='F') camop=']'; //<NF> for Reset/Finish webCAM.
if (camop=='Q') param3=10; //<NQ> for activation state of all 10 banks of sensors
break; // Coded as ']' else conflicts with <Nf %%> break; // Coded as ']' else conflicts with <Nf %%>
case 2: //<N camop p1> case 2: //<N camop p1>
if (strchr_P((const char *)F("ABFILMNOPRSTUV^"),camop)==nullptr) return false; if (STRCHR_P((const char *)F("ABFILMNOPQRSTUV^"),camop)==nullptr) return false;
param1=p[1]; param1=p[1];
break; break;
@ -69,7 +70,7 @@ bool CamParser::parseN(Print * stream, byte paramCount, int16_t p[]) {
if (p[2]>316 || p[2]<0) return false; //column if (p[2]>316 || p[2]<0) return false; //column
camop=0x80; // special 'a' case for IO_SensorCAM camop=0x80; // special 'a' case for IO_SensorCAM
vpin = p[0]; vpin = p[0];
}else if (strchr_P((const char *)F("IJMNT"),camop) == nullptr) return false; }else if (STRCHR_P((const char *)F("IJMNT"),camop) == nullptr) return false;
param1 = p[1]; param1 = p[1];
param3 = p[2]; param3 = p[2];
break; break;

2
FSH.h
View File

@ -52,6 +52,7 @@ typedef __FlashStringHelper FSH;
#define STRNCPY_P strncpy_P #define STRNCPY_P strncpy_P
#define STRNCMP_P strncmp_P #define STRNCMP_P strncmp_P
#define STRLEN_P strlen_P #define STRLEN_P strlen_P
#define STRCHR_P strchr_P
#if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) #if defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560)
// AVR_MEGA memory deliberately placed at end of link may need _far functions // AVR_MEGA memory deliberately placed at end of link may need _far functions
@ -92,5 +93,6 @@ typedef char FSH;
#define STRNCPY_P strncpy #define STRNCPY_P strncpy
#define STRNCMP_P strncmp #define STRNCMP_P strncmp
#define STRLEN_P strlen #define STRLEN_P strlen
#define STRCHR_P strchr
#endif #endif
#endif #endif

View File

@ -17,8 +17,8 @@
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. * along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/ */
#define driverVer 301 #define driverVer 303
// v301 improved 'f' and 'p' code and driver version calc. Correct bsNo calc. for 'a' // v301 improved 'f','p'&'q' code and driver version calc. Correct bsNo calc. for 'a'
// v300 stripped & revised without expander functionality. Needs sensorCAM.h v300 AND CamParser.cpp // v300 stripped & revised without expander functionality. Needs sensorCAM.h v300 AND CamParser.cpp
// v222 uses '@'for EXIORDD read. handles <NB $> and <NN $ ##> // v222 uses '@'for EXIORDD read. handles <NB $> and <NN $ ##>
// v216 includes 'j' command and uses CamParser rather than myFilter.h Incompatible with v203 senorCAM // v216 includes 'j' command and uses CamParser rather than myFilter.h Incompatible with v203 senorCAM
@ -49,8 +49,7 @@
# define DIGITALREFRESH 20000UL // min uSec delay between digital reads of digitalInputStates # 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 SEND StringFormatter::send
#define Sp Serial.print
#include "IODevice.h" #include "IODevice.h"
#include "I2CManager.h" #include "I2CManager.h"
@ -83,7 +82,7 @@ class EXSensorCAM : public IODevice {
addDevice(this); addDevice(this);
} }
//************************* //*************************
uint8_t oldb0;
void _begin() { void _begin() {
uint8_t status; uint8_t status;
// Initialise EX-SensorCAM device // Initialise EX-SensorCAM device
@ -148,9 +147,9 @@ void _loop(unsigned long currentMicros) override {
if ((_CAMresponseBuff[0] & 0x60) >= 0x60) { //Buff[0] seems to have ascii cmd header (bit6 high) (o06) if ((_CAMresponseBuff[0] & 0x60) >= 0x60) { //Buff[0] seems to have ascii cmd header (bit6 high) (o06)
int error = processIncomingPkt( _CAMresponseBuff, _CAMresponseBuff[0]); // '~' 'i' 'm' 'n' 't' etc int error = processIncomingPkt( _CAMresponseBuff, _CAMresponseBuff[0]); // '~' 'i' 'm' 'n' 't' etc
if (error>0) DIAG(F("CAM packet header(0x%x) not recognised"),_CAMresponseBuff[0]); if (error>0) DIAG(F("CAM packet header(0x%x) not recognised"),_CAMresponseBuff[0]);
}else{ // Header not valid - typically replaced by bank 0 data! To avoid any bad response set S06 to 0 }else{ // Header not valid - typically replaced by bank 0 data! To avoid any bad responses set S06 to 0
// versions of sensorCAM.h after v300 should return header of '@'(0x40) (not 0xE6) followed by // Versions of sensorCAM.h after v300 should return header for '@' of '`'(0x60) (not 0xE6)
// digitalInputStates sensor state array // followed by digitalInputStates sensor state array
} }
}else reportError(status, false); // report i2c eror but don't go offline. }else reportError(status, false); // report i2c eror but don't go offline.
_readState = RDS_IDLE; _readState = RDS_IDLE;
@ -202,7 +201,7 @@ void _write(VPIN vpin, int value) override {
} }
//************************* //*************************
// i2cAddr of ESP32 CAM // i2cAddr of ESP32 CAM
// rBuff buffer for return packet // rBuf buffer for return packet
// inbytes number of bytes to request from CAM // inbytes number of bytes to request from CAM
// outBuff holds outbytes to be sent to CAM // outBuff holds outbytes to be sent to CAM
int ioESP32(uint8_t i2cAddr,uint8_t *rBuf,int inbytes,uint8_t *outBuff,int outbytes) { int ioESP32(uint8_t i2cAddr,uint8_t *rBuf,int inbytes,uint8_t *outBuff,int outbytes) {
@ -226,12 +225,14 @@ int ioESP32(uint8_t i2cAddr,uint8_t *rBuf,int inbytes,uint8_t *outBuff,int outby
int processIncomingPkt(uint8_t *rBuf,uint8_t sensorCmd) { int processIncomingPkt(uint8_t *rBuf,uint8_t sensorCmd) {
int k; int k;
int b; int b;
char str[] = "11111111";
// if (sensorCmd <= '~') DIAG(F("processIncomingPkt %c %d %d %d"),rBuf[0],rBuf[1],rBuf[2],rBuf[3]); // if (sensorCmd <= '~') DIAG(F("processIncomingPkt %c %d %d %d"),rBuf[0],rBuf[1],rBuf[2],rBuf[3]);
switch (sensorCmd){ switch (sensorCmd){
case '`': //response to request for digitalInputStates[] table '@'=>'`' case '`': //response to request for digitalInputStates[] table '@'=>'`'
memcpy(_digitalInputStates, rBuf+1, digitalBytesNeeded); memcpy(_digitalInputStates, rBuf+1, digitalBytesNeeded);
break; if ( _digitalInputStates[0]!=oldb0) { oldb0=_digitalInputStates[0]; //debug
for (k=0;k<5;k++) {Serial.print(" ");Serial.print(_digitalInputStates[k],HEX);}
}break;
case EXIORDY: //some commands give back acknowledgement only case EXIORDY: //some commands give back acknowledgement only
break; break;
@ -262,45 +263,48 @@ int processIncomingPkt(uint8_t *rBuf,uint8_t sensorCmd) {
,rBuf[4],rBuf[2],rBuf[3],rBuf[5]); ,rBuf[4],rBuf[2],rBuf[3],rBuf[5]);
break; break;
case 'q':
for (int i =0; i<8; i++) str[i] = ((rBuf[2] << i) & 0x80 ? '1' : '0');
DIAG(F("(q $) Query bank %c ENABLED sensors(S%c7-%c0): %s "), rBuf[1], rBuf[1], rBuf[1], str);
break;
case 'f': case 'f':
DIAG(F("(f %%%%) frame header 'f' for 0%o - showing Quarter sample (1 row) only"), rBuf[1]); DIAG(F("(f %%%%) frame header 'f' for bsNo %d/%d - showing Quarter sample (1 row) only"), rBuf[1]/8,rBuf[1]%8);
/*if(rBuf[2]==0)*/ { Sp("<n bsNo "); Sp(rBuf[1]/8);Sp("/");Sp(rBuf[1]%8);Sp("\n"); } SEND(&USB_SERIAL,F("<n row: %d Ref bytes: "),rBuf[2]);
Sp("<n row:"); Sp(rBuf[2]);Sp(" Ref bytes" ); for(k=3;k<15;k++)
for(k=3;k<15;k++) { Sp(" "); Sp(rBuf[k]>>4,HEX); Sp(rBuf[k]&15,HEX); if(k%3==2)Sp(" "); } SEND(&USB_SERIAL,F("%x%x%s"), rBuf[k]>>4, rBuf[k]&15, k%3==2 ? " " : " ");
Sp(" latest grab ->"); Serial.print(" latest grab: ");
for(k=16;k<28;k++){ Sp(" "); Sp(rBuf[k]>>4,HEX); Sp(rBuf[k]&15,HEX); if(k%3==0)Sp(" "); } for(k=16;k<28;k++)
Sp(" n>\n"); SEND(&USB_SERIAL,F("%x%x%s"), rBuf[k]>>4, rBuf[k]&15, (k%3==0) ? " " : " ");
Serial.print(" n>\n");
break; break;
case 'p': case 'p':
b=rBuf[1]-2; b=rBuf[1]-2;
if(b<4) { Sp("<n (p%%) Bank empty n>\n"); break; } if(b<4) { Serial.print("<n (p%%) Bank empty n>\n"); break; }
Sp("<n (p%%) Bank:"); Sp((0x7F&rBuf[2])/8); Sp(" "); SEND(&USB_SERIAL,F("<n (p%%) Bank: %d "),(0x7F&rBuf[2])/8);
for (int j=2; j<b; j+=3) { for (int j=2; j<b; j+=3)
if(0x7F&rBuf[j] < 8) Sp(" S[0"); else Sp(" S["); SEND(&USB_SERIAL,F(" S[%d%d]: r=%d x=%d"),0x7F&rBuf[j]/8,0x7F&rBuf[j]%8,rBuf[j+1],rBuf[j+2]+2*(rBuf[j]&0x80));
Sp(0x7F&rBuf[j],OCT);Sp("]: r=");Sp(rBuf[j+1]);Sp(" x=");Sp(rBuf[j+2] + 2*(rBuf[j] & 0x80)); Serial.print(" n>\n");
}
Sp(" n>\n");
break; break;
case 't': //threshold etc. from t## //bad pkt if 't' FF's case 't': //threshold etc. from t## //bad pkt if 't' FF's
if(rBuf[1]==0xFF) {Serial.println("<n bad CAM 't' packet: 74 FF n>");_savedCmd[2] +=1; return 0;} if(rBuf[1]==0xFF) {Serial.println("<n bad CAM 't' packet: 74 FF n>");_savedCmd[2] +=1; return 0;}
Sp("<n (t[##[,%%]]) Threshold:");Sp(rBuf[1]);Sp(" sensor S00:");Sp("-");k=rBuf[2]&0x7F;if(k>99)k=99;Sp(k); SEND(&USB_SERIAL,F("<n (t[##[,%%]]) Threshold:%d sensor S00:-%d"),rBuf[1],min(rBuf[2]&0x7F,99));
if(rBuf[2]>127) Sp("##* "); if(rBuf[2]>127) Serial.print("##* ");
else{ else{
if(rBuf[2]>rBuf[1]) Sp("-?* "); if(rBuf[2]>rBuf[1]) Serial.print("-?* ");
else Sp("--* "); else Serial.print("--* ");
} }
for(int i=3;i<31;i+=2){ for(int i=3;i<31;i+=2){
uint8_t valu=rBuf[i]; //get bsn uint8_t valu=rBuf[i]; //get bsn
if(valu==80) break; //80 = end flag if(valu==80) break; //80 = end flag
else{ else{
if((valu&0x7F)<8) Sp("0"); Sp(valu&0x7F,OCT);Sp(':'); SEND(&USB_SERIAL,F("%d%d:"), (valu&0x7F)/8,(valu&0x7F)%8);
if(valu>=128) Sp("?-"); if(valu>=128) Serial.print("?-");
else {if(rBuf[i+1]>=128) Sp("oo");else Sp("--");} else {if(rBuf[i+1]>=128) Serial.print("oo");else Serial.print("--");}
valu=rBuf[i+1]; k=valu&0x7F; valu=rBuf[i+1];
if(k>99) k=99; Sp(k); SEND(&USB_SERIAL,F("%d%s"),min(valu&0x7F,99),(valu<128) ? "--* ":"##* ");
if(valu<128) Sp("--* "); else Sp("##* ");
} }
} }
Serial.print(" >\n"); Serial.print(" >\n");
@ -324,7 +328,7 @@ void _writeAnalogue(VPIN vpin, int param1, uint8_t camop, uint16_t param3) overr
camop=param1; //put row (0-236) in expected place camop=param1; //put row (0-236) in expected place
param1=param3; //put column in expected place param1=param3; //put column in expected place
outputBuffer[0] = 'A'; outputBuffer[0] = 'A';
pin = (pin/8)*10 + pin%8; //restore bsNo. pin = (pin/8)*10 + pin%8; //restore bsNo. as integer
} }
if (_deviceState == DEVSTATE_FAILED) return; if (_deviceState == DEVSTATE_FAILED) return;
@ -335,13 +339,20 @@ void _writeAnalogue(VPIN vpin, int param1, uint8_t camop, uint16_t param3) overr
outputBuffer[5] = param3 & 0xFF; outputBuffer[5] = param3 & 0xFF;
outputBuffer[6] = param3 >> 8; outputBuffer[6] = param3 >> 8;
int count=param1+1;
if(camop=='Q'){
if(param3<=10) {count=param3; camop='B';}
//if(param1<10) outputBuffer[2] = param1*10;
}
if(camop=='B'){ //then 'b'(b%) cmd - can totally deal with that here. (but can't do b%,# (brightSF)) if(camop=='B'){ //then 'b'(b%) cmd - can totally deal with that here. (but can't do b%,# (brightSF))
if(param1>97) return; if(param1>97) return;
if(param1>9) param1 = param1/10; //accept a bsNo if(param1>9) param1 = param1/10; //accept a bsNo
uint8_t b=_digitalInputStates[param1]; for(param1;param1<count;param1++) {
char str[] = "11111111"; uint8_t b=_digitalInputStates[param1];
for (int i=0;i<8;i++) if(((b<<i)&0x80) == 0) str[i]='0'; char str[] = "11111111";
DIAG(F("(b $) Bank: %d occupancy status byte: 0x%x%x (sensors S%d7->0) %s"), param1,b>>4,b&15,param1,str ); for (int i=0;i<8;i++) if(((b<<i)&0x80) == 0) str[i]='0';
DIAG(F("(b $) Bank: %d activated byte: 0x%x%x (sensors S%d7->%d0) %s"), param1,b>>4,b&15,param1,param1,str );
}
return; return;
} }
if (outputBuffer[4]=='T') { //then 't' cmd if (outputBuffer[4]=='T') { //then 't' cmd

View File

@ -36,7 +36,7 @@
void halSetup() { void halSetup() {
//I2CManager.setClock(100000); I2CManager.setClock(100000);
//======================================================================= //=======================================================================
// The following directives define auxiliary display devices. // The following directives define auxiliary display devices.