mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 03:39:49 +03:00
CAN: config retrieving from master
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#
|
||||
-DWIFI_ENABLE
|
||||
-DDMX_DISABLE
|
||||
# - exeption in DMX.update/begin
|
||||
@@ -12,7 +13,7 @@
|
||||
-DARDUINO_OTA_MDNS_DISABLE
|
||||
-DMDNS_ENABLE
|
||||
#- ArduinoMDNS didnt working
|
||||
|
||||
-D CANDRV
|
||||
-DMCP23017
|
||||
-DMODBUS_TX_PIN=13
|
||||
#-DARTNET_ENABLE - udp rx errors ((
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <candriver.h>
|
||||
#include <Arduino.h>
|
||||
#include <main.h>
|
||||
#include <utils.h>
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
#include <STM32_CAN.h>
|
||||
@@ -20,6 +21,9 @@ STM32_CAN STMCan( CAN1, ALT, RX_SIZE_64, TX_SIZE_16 );
|
||||
#include <config.h>
|
||||
//#include <systemconfigdata.h>
|
||||
extern systemConfig sysConf;
|
||||
extern canStream CANConfStream;
|
||||
extern aJsonObject * root;
|
||||
extern volatile int8_t configLocked;
|
||||
|
||||
|
||||
void printFrame(datagram_t * frame, uint8_t len ) {
|
||||
@@ -91,22 +95,47 @@ bool canDriver::lookupMAC()
|
||||
return res;
|
||||
}
|
||||
|
||||
bool canDriver::requestFrame(uint8_t devId, payloadType _payloadType )
|
||||
{
|
||||
canid_t id;
|
||||
datagram_t packet;
|
||||
bool res;
|
||||
|
||||
|
||||
id.reserve=0;
|
||||
id.status=0;
|
||||
id.payloadType=_payloadType;
|
||||
id.deviceId=devId;
|
||||
id.itemId=0; //CRC?
|
||||
packet.metric1 =0;
|
||||
//memcpy(packet.mac,sysConf.mac,6);
|
||||
|
||||
debugSerial<<("Request frame ")<<_payloadType<<F(" for id ")<<devId<<endl;
|
||||
res=write (id.id,&packet,1);
|
||||
if (res) state=canState::FrameRequested;
|
||||
else state=canState::Error;
|
||||
responseTimer=millisNZ();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool canDriver::sendRemoteID(macAddress mac)
|
||||
{
|
||||
canid_t id;
|
||||
//datagram_t packet;
|
||||
bool res=false;
|
||||
id.deviceId=getIdByMac(mac); //Retrieved controllerID
|
||||
if (!id.deviceId) return false;
|
||||
|
||||
id.reserve=0;
|
||||
id.status=1; //response
|
||||
id.payloadType=payloadType::lookupMAC;
|
||||
id.deviceId=100; //Retrieved controllerID
|
||||
id.itemId=200; //CRC of remote config
|
||||
|
||||
id.itemId=200; //CRC16 of remote config
|
||||
//packet.data[0]=1;
|
||||
|
||||
debugSerial<<("Send remote ID")<<endl;
|
||||
res = write (id.id);//,&packet,8);
|
||||
if (res) state=canState::HaveId;
|
||||
if (res) state=canState::Idle;
|
||||
else state=canState::Error;
|
||||
// responseTimer=millisNZ(); ????????
|
||||
return res;
|
||||
@@ -137,21 +166,24 @@ bool canDriver::begin()
|
||||
#endif
|
||||
|
||||
debugSerial<<"CAN initialized"<<endl;
|
||||
controllerId = getMyId();
|
||||
ready=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void canDriver::Poll()
|
||||
{
|
||||
// return ;
|
||||
if (!ready) return;
|
||||
int canDriver::readFrame()
|
||||
{
|
||||
if (!ready) return -1;
|
||||
//STM32
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
if (STMCan.read(CAN_RX_msg))
|
||||
{
|
||||
processPacket( CAN_RX_msg.id, (datagram_t*) CAN_RX_msg.buf,CAN_RX_msg.len);
|
||||
if (CAN_RX_msg.len>8) CAN_RX_msg.len=8;
|
||||
memcpy(RXpacket.data, CAN_RX_msg.buf,CAN_RX_msg.len);
|
||||
RXlen = CAN_RX_msg.len;
|
||||
RXid.id = CAN_RX_msg.id;
|
||||
return RXlen;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
@@ -182,21 +214,22 @@ void canDriver::Poll()
|
||||
//debugSerialPort.println(packetSize);
|
||||
debugSerialPort.println(CAN.packetDlc());
|
||||
|
||||
datagram_t packet;
|
||||
// only print packet data for non-RTR packets
|
||||
int i=0;
|
||||
while (CAN.available()) {
|
||||
packet.data[i++]=CAN.read();
|
||||
//debugSerialPort.print((char)CAN.read());
|
||||
if (i>=8) break;
|
||||
}
|
||||
debugSerialPort.println();
|
||||
|
||||
processPacket( CAN.packetId(), &packet,i);
|
||||
// only print packet data for non-RTR packets
|
||||
RXlen=0;
|
||||
while (CAN.available()) {
|
||||
RXpacket.data[RXlen++]=CAN.read();
|
||||
if (RXlen>=8) break;
|
||||
}
|
||||
RXid.id = CAN.packetId();
|
||||
|
||||
debugSerialPort.println();
|
||||
return RXlen;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//DUE
|
||||
#if defined(__SAM3X8E__)
|
||||
CAN_FRAME incoming;
|
||||
@@ -207,12 +240,20 @@ void canDriver::Poll()
|
||||
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void canDriver::Poll()
|
||||
{
|
||||
|
||||
if (readFrame()>=0) processPacket( RXid, &RXpacket, RXlen);
|
||||
//State machine
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case canState::MACLookup:
|
||||
// case canState::FrameRequested:
|
||||
|
||||
if (isTimeOver(responseTimer,millis(),1000UL))
|
||||
{
|
||||
responseTimer=millisNZ();
|
||||
@@ -226,55 +267,189 @@ switch (state)
|
||||
lookupMAC();
|
||||
break;
|
||||
|
||||
// case canState::HaveId:
|
||||
case canState::ReadConfig:
|
||||
{
|
||||
//Blocking read config
|
||||
if (configLocked) return; // only in safe moments
|
||||
configLocked++;
|
||||
|
||||
infoSerial<<F("Requesting Config from CAN")<<endl;
|
||||
|
||||
CANConfStream.open(controllerId,payloadType::configFrame,'r');
|
||||
|
||||
if (CANConfStream.peek() == '{') {
|
||||
debugSerial<<F("JSON detected")<<endl;
|
||||
aJsonStream as = aJsonStream(&CANConfStream);
|
||||
cleanConf(false);
|
||||
root = aJson.parse(&as);
|
||||
CANConfStream.close();
|
||||
if (!root) {
|
||||
errorSerial<<F("load failed")<<endl;
|
||||
sysConf.setETAG("");
|
||||
// sysConfStream.close();
|
||||
configLocked--;
|
||||
state = canState::Error;
|
||||
return;
|
||||
}
|
||||
infoSerial<<F("Loaded from CAN")<<endl;
|
||||
configLocked--;
|
||||
applyConfig();
|
||||
sysConf.loadETAG();
|
||||
state = canState::Idle;
|
||||
return ;
|
||||
}
|
||||
CANConfStream.close();
|
||||
infoSerial<<F("Config not loaded")<<endl;
|
||||
state = canState::Error;
|
||||
configLocked--;
|
||||
}
|
||||
break;
|
||||
|
||||
// case canState::Idle:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool canDriver::processPacket(uint32_t rawid, datagram_t *packet, uint8_t len, bool rtr)
|
||||
bool canDriver::processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr)
|
||||
{
|
||||
canid_t id;
|
||||
id.id = rawid;
|
||||
|
||||
debugSerial.print("CAN Received ");
|
||||
debugSerialPort.print(len);
|
||||
debugSerialPort.print(" bytes id 0x");
|
||||
debugSerialPort.println(id.id,HEX);
|
||||
|
||||
printFrame(packet,len);
|
||||
if (len) printFrame(packet,len);
|
||||
if (id.status)
|
||||
//Responces
|
||||
switch (state)
|
||||
{
|
||||
case canState::MACLookup:
|
||||
if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
|
||||
if ((id.payloadType == payloadType::lookupMAC))
|
||||
{
|
||||
debugSerial<<"Got Controller CAN addr: "<<id.deviceId<<endl;
|
||||
controllerId=id.deviceId;
|
||||
state = canState::ReadConfig;
|
||||
}
|
||||
return true;
|
||||
case canState::HaveId:
|
||||
|
||||
case canState::FrameRequested:
|
||||
if ((id.payloadType == payloadType::configFrame) && (id.deviceId == controllerId))
|
||||
{
|
||||
errorSerial<<F("Config received when not expected")<<endl;
|
||||
}
|
||||
|
||||
break;
|
||||
case canState::Idle:
|
||||
|
||||
break;
|
||||
|
||||
case canState::Error:
|
||||
return false;
|
||||
}
|
||||
else //Requests
|
||||
|
||||
|
||||
{
|
||||
|
||||
if (id.payloadType == payloadType::lookupMAC)
|
||||
if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
|
||||
{
|
||||
return sendRemoteID(packet->mac);
|
||||
//debugSerial<<"ID requested"<<endl;
|
||||
}
|
||||
else if (id.payloadType == payloadType::configFrame)
|
||||
{
|
||||
debugSerial<<F("Requested conf for dev#")<<id.deviceId<<endl;
|
||||
aJsonObject * remoteConfObj = findConfbyID(id.deviceId);
|
||||
if (remoteConfObj)
|
||||
{
|
||||
infoSerial<<F("Sending conf for dev#")<<id.deviceId<<endl;
|
||||
CANConfStream.open(id.deviceId,payloadType::configFrame,'w');
|
||||
aJsonStream outStream = aJsonStream(&CANConfStream);
|
||||
aJson.print(remoteConfObj, &outStream);
|
||||
CANConfStream.close();
|
||||
}
|
||||
|
||||
return 1;
|
||||
//debugSerial<<"ID requested"<<endl;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t canDriver::getMyId()
|
||||
{
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
|
||||
aJsonObject * addrObj = aJson.getObjectItem(canObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int)) return addrObj->valueint;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
aJsonObject * canDriver::findConfbyID(uint8_t devId)
|
||||
{
|
||||
if (!root) return NULL;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return NULL;
|
||||
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(canObj, "conf");
|
||||
|
||||
if (!remoteConfObj) return NULL;
|
||||
remoteConfObj=remoteConfObj->child;
|
||||
while (remoteConfObj)
|
||||
{
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (remoteCanObj)
|
||||
{
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "addr");
|
||||
if (addrObj && (addrObj->type == aJson_Int) && (addrObj->valueint == devId)) return remoteConfObj;
|
||||
}
|
||||
remoteConfObj=remoteConfObj->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
uint8_t canDriver::getIdByMac(macAddress mac)
|
||||
{
|
||||
char macStr[19];
|
||||
uint8_t strptr = 0;
|
||||
|
||||
if (!root) return 0;
|
||||
aJsonObject * canObj = aJson.getObjectItem(root, "can");
|
||||
if (!canObj) return 0;
|
||||
aJsonObject * confObj = aJson.getObjectItem(canObj, "conf");
|
||||
if (!confObj) return 0;
|
||||
|
||||
memset(macStr,0,sizeof(macStr));
|
||||
for (byte i = 0; i < 6; i++)
|
||||
{
|
||||
if (mac[i]<16) macStr[strptr++]='0';
|
||||
|
||||
SetBytes(&mac[i],1,&macStr[strptr]);
|
||||
strptr+=2;
|
||||
|
||||
if (i < 5) macStr[strptr++]=':';
|
||||
}
|
||||
debugSerial<<F("Searching devId for ")<<macStr<<endl;
|
||||
aJsonObject * remoteConfObj = aJson.getObjectItem(confObj, macStr);
|
||||
|
||||
if (!remoteConfObj) return 0;
|
||||
|
||||
aJsonObject * remoteCanObj = aJson.getObjectItem(remoteConfObj, "can");
|
||||
if (!remoteCanObj) return 0;
|
||||
|
||||
aJsonObject * addrObj = aJson.getObjectItem(remoteCanObj, "addr");
|
||||
if (!addrObj) return 0;
|
||||
if (addrObj && (addrObj->type == aJson_Int))
|
||||
{
|
||||
debugSerial<<F("find dev#")<< addrObj->valueint << endl;
|
||||
return addrObj->valueint;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
|
||||
{ //return 0;
|
||||
@@ -289,7 +464,7 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
|
||||
CAN_TX_msg.id = msg_id;
|
||||
CAN_TX_msg.flags.extended = 1; // To enable extended ID
|
||||
CAN_TX_msg.len=size;
|
||||
if (res=STMCan.write(CAN_TX_msg)) debugSerial<<("CAN Wrote ")<<size<<" bytes"<<endl;
|
||||
if (res=STMCan.write(CAN_TX_msg)) debugSerial<<("CAN Wrote ")<<size<<" bytes, id "<<_HEX(msg_id)<<endl;
|
||||
else debugSerial.println("CAN Write error");
|
||||
return res;
|
||||
#endif
|
||||
@@ -299,7 +474,7 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
|
||||
CAN.beginExtendedPacket(msg_id,size);
|
||||
CAN.write(buf->data,size);
|
||||
//for(uint8_t i=0;i<size; i++) CAN.write(buf[i]);
|
||||
if (res=CAN.endPacket()) debugSerial.println("CAN Wrote");
|
||||
if (res=CAN.endPacket()) debugSerial<< ("CAN Wrote ")<<size << " bytes, id "<<_HEX(msg_id)<<endl;
|
||||
else debugSerial.println("CAN Write error");
|
||||
return res;
|
||||
#endif
|
||||
@@ -319,4 +494,192 @@ bool canDriver::write(uint32_t msg_id, datagram_t * buf, uint8_t size)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool canDriver::sendStatus(char * itemName, itemCmd cmd)
|
||||
{
|
||||
|
||||
}
|
||||
bool canDriver::sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////// Steream //////////////////////////
|
||||
|
||||
|
||||
int canStream::send(uint8_t len)
|
||||
{
|
||||
canid_t id;
|
||||
datagram_t packet;
|
||||
bool res;
|
||||
if (!driver) return 0;
|
||||
id.reserve=0;
|
||||
id.status=1;
|
||||
id.payloadType=pType;
|
||||
id.deviceId=devId;
|
||||
id.itemId=0; // chunk?
|
||||
|
||||
res=driver->write (id.id, &writeBuffer, len);
|
||||
writePos=0;
|
||||
if (res)
|
||||
{
|
||||
//Await check?
|
||||
return 1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int canStream::checkState()
|
||||
{
|
||||
bool res = false;
|
||||
if (!driver) return -1;
|
||||
switch (state)
|
||||
{
|
||||
case canState::StreamOpenedRead:
|
||||
readPos = 0;
|
||||
res= driver->requestFrame(devId,pType); //Requesting frame;
|
||||
if (res)
|
||||
state = canState::FrameRequested;
|
||||
else
|
||||
{
|
||||
state = canState::Error;
|
||||
return -1;
|
||||
}
|
||||
//continue
|
||||
|
||||
case canState::FrameRequested:
|
||||
{
|
||||
uint32_t timer = millis();
|
||||
int c;
|
||||
|
||||
do {
|
||||
debugSerial.print(".");
|
||||
yield();
|
||||
|
||||
if (c=driver->readFrame()>0 && (driver->RXid.deviceId == devId) && (driver ->RXid.payloadType == pType))
|
||||
{
|
||||
state = canState::FrameReceived;
|
||||
debugSerial<<F("Payload received ")<< c << "|" <<driver->RXlen<< " "<<driver->RXpacket.payload<<endl;;
|
||||
return driver->RXlen;
|
||||
}
|
||||
|
||||
} while((!isTimeOver(timer,millis(),1000UL)) );
|
||||
|
||||
debugSerial<<F("RX data awaiting timeout")<<endl;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case canState::FrameReceived:
|
||||
return driver->RXlen;
|
||||
break;
|
||||
|
||||
case canState::waitingConfirm:
|
||||
if (driver->readFrame()>=0)
|
||||
{
|
||||
if (
|
||||
(driver->RXid.deviceId == devId) &&
|
||||
(driver->RXid.payloadType == pType) &&
|
||||
(driver->RXid.status == 0)
|
||||
)
|
||||
state = canState::StreamOpenedWrite;
|
||||
return 0;
|
||||
}
|
||||
return driver->RXlen;
|
||||
break;
|
||||
|
||||
case canState::Idle:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Stream methods
|
||||
int canStream::available()
|
||||
{
|
||||
if (!driver) return -1;
|
||||
int avail = checkState();
|
||||
return avail;
|
||||
};
|
||||
|
||||
int canStream::read()
|
||||
{
|
||||
if (!driver) return -1;
|
||||
int avail = checkState();
|
||||
int ch;
|
||||
if (avail>=0)
|
||||
{
|
||||
ch = driver->RXpacket.data[readPos++];
|
||||
if (readPos>=8) state = canState::StreamOpenedRead;
|
||||
return ch;
|
||||
}
|
||||
else return -1;
|
||||
};
|
||||
|
||||
int canStream::peek()
|
||||
{
|
||||
if (!driver) return -1;
|
||||
int avail = checkState();
|
||||
int ch;
|
||||
if (avail>=0)
|
||||
{
|
||||
ch = driver->RXpacket.data[readPos];
|
||||
return ch;
|
||||
}
|
||||
else return -1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
size_t canStream::write(uint8_t c)
|
||||
{
|
||||
//if ((state != canState::StreamOpenedWrite) || (state != canState::waitingConfirm)) return -1;
|
||||
|
||||
uint32_t timer = millis();
|
||||
do
|
||||
{
|
||||
checkState();
|
||||
yield();
|
||||
//debugSerial.print("*");
|
||||
if (isTimeOver(timer,millis(),1000UL))
|
||||
{
|
||||
state = canState::Error;
|
||||
errorSerial<<F("CAN write timeout")<<endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
while (!availableForWrite() );
|
||||
|
||||
writeBuffer.data[writePos++]=c;
|
||||
if (writePos>=8)
|
||||
{
|
||||
bool res = send(8);
|
||||
if (res) state = canState::waitingConfirm;
|
||||
else state = canState::Error;
|
||||
return res;
|
||||
}
|
||||
return 1; };
|
||||
|
||||
void canStream::flush()
|
||||
{
|
||||
send(writePos);
|
||||
};
|
||||
|
||||
|
||||
int canStream::availableForWrite()
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case canState::waitingConfirm: return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#endif
|
||||
|
||||
#include <itemCmd.h>
|
||||
|
||||
#include <Stream.h>
|
||||
#include <aJSON.h>
|
||||
#include <streamlog.h>
|
||||
//#include <config.h> NO!
|
||||
|
||||
typedef uint8_t macAddress[6];
|
||||
@@ -28,7 +32,7 @@ typedef union
|
||||
} canid_t;
|
||||
|
||||
enum payloadType
|
||||
{
|
||||
{ unknown=0,
|
||||
itemCommand=1,
|
||||
lookupMAC=2,
|
||||
configFrame=3,
|
||||
@@ -66,6 +70,7 @@ enum commandType
|
||||
|
||||
typedef union {
|
||||
uint8_t data[8];
|
||||
char payload[8];
|
||||
struct {
|
||||
itemCmdStore cmd;
|
||||
itemArgStore param;
|
||||
@@ -87,13 +92,17 @@ typedef union {
|
||||
|
||||
enum canState
|
||||
{
|
||||
Unknown=0,
|
||||
MACLookup=2,
|
||||
HaveId=3,
|
||||
ConfigFrameRequested=4,
|
||||
ConfigFrameReceived=5,
|
||||
ConfigLoaded=6,
|
||||
Error=7
|
||||
Unknown,
|
||||
MACLookup,
|
||||
Idle,
|
||||
StreamOpenedWrite,
|
||||
StreamOpenedRead,
|
||||
FrameRequested,
|
||||
FrameReceived,
|
||||
ReadConfig,
|
||||
ConfigLoaded,
|
||||
waitingConfirm,
|
||||
Error
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -101,25 +110,101 @@ class canDriver
|
||||
{
|
||||
public:
|
||||
canDriver(){ready=false; controllerId=0; responseTimer=0; state=canState::Unknown;};
|
||||
uint8_t getMyId();
|
||||
bool sendStatus(char * itemName, itemCmd cmd);
|
||||
bool sendCommand(uint8_t devID, uint16_t itemID, itemCmd cmd);
|
||||
bool upTime(uint32_t ut);
|
||||
bool salt(uint32_t salt);
|
||||
bool lookupMAC();
|
||||
bool requestFrame(uint8_t devId, payloadType _payloadType );
|
||||
int readFrame();
|
||||
bool sendRemoteID(macAddress mac);
|
||||
bool begin();
|
||||
void Poll();
|
||||
bool processPacket(uint32_t rawid, datagram_t *packet, uint8_t len, bool rtr=false);
|
||||
bool processPacket(canid_t id, datagram_t *packet, uint8_t len, bool rtr=false);
|
||||
bool write(uint32_t msg_id, datagram_t * buf = NULL, uint8_t size=0);
|
||||
private:
|
||||
uint8_t getControllerID(){return controllerId;};
|
||||
uint8_t getIdByMac(macAddress mac);
|
||||
|
||||
datagram_t RXpacket;
|
||||
canid_t RXid;
|
||||
uint8_t RXlen;
|
||||
|
||||
private:
|
||||
aJsonObject * findConfbyID(uint8_t devId);
|
||||
|
||||
#if defined(ARDUINO_ARCH_STM32)
|
||||
CAN_message_t CAN_RX_msg;
|
||||
CAN_message_t CAN_TX_msg;
|
||||
#endif
|
||||
bool ready;
|
||||
|
||||
|
||||
|
||||
uint8_t controllerId;
|
||||
canState state;
|
||||
uint32_t responseTimer;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern aJsonObject * topics;
|
||||
|
||||
class canStream : public Stream
|
||||
{
|
||||
public:
|
||||
canStream(canDriver * _driver) : readPos(0),writePos(0),devId(0), pType(payloadType::unknown),state(canState::Unknown){driver=_driver; }
|
||||
int open(uint8_t controllerID, payloadType _pType, char _mode)
|
||||
{
|
||||
if (mode) close();
|
||||
devId=controllerID;
|
||||
pType = _pType;
|
||||
mode = _mode;
|
||||
if (mode == 'w') state=canState::StreamOpenedWrite;
|
||||
else state=canState::StreamOpenedRead;
|
||||
return 1;
|
||||
};
|
||||
int close ()
|
||||
{
|
||||
if ((mode == 'w') && writePos) flush();
|
||||
mode = '\0';
|
||||
state=canState::Unknown;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Stream methods
|
||||
virtual int available();
|
||||
virtual int read();
|
||||
virtual int peek();
|
||||
|
||||
virtual void flush();
|
||||
// Print methods
|
||||
virtual size_t write(uint8_t c) ;
|
||||
virtual int availableForWrite();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
int send(uint8_t len);
|
||||
int checkState();
|
||||
canDriver * driver;
|
||||
unsigned int readPos;
|
||||
unsigned int writePos;
|
||||
|
||||
datagram_t writeBuffer;
|
||||
|
||||
uint8_t devId;
|
||||
char mode;
|
||||
payloadType pType;
|
||||
canState state;
|
||||
//bool writeBlocked;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //
|
||||
@@ -70,6 +70,7 @@ systemConfig sysConf(&sysConfStream);
|
||||
|
||||
#ifdef CANDRV
|
||||
canDriver LHCAN;
|
||||
canStream CANConfStream(&LHCAN);
|
||||
#endif
|
||||
|
||||
extern long timer0_overflow_count;
|
||||
@@ -1572,6 +1573,44 @@ int loadConfigFromEEPROM()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int loadConfigFromCAN()
|
||||
{
|
||||
if (configLocked) return 0;
|
||||
configLocked++;
|
||||
|
||||
infoSerial<<F("Loading Config from CAN")<<endl;
|
||||
|
||||
CANConfStream.open(LHCAN.getControllerID(),payloadType::configFrame,'r');
|
||||
|
||||
|
||||
if (CANConfStream.peek() == '{') {
|
||||
debugSerial<<F("JSON detected")<<endl;
|
||||
aJsonStream as = aJsonStream(&CANConfStream);
|
||||
cleanConf(false);
|
||||
root = aJson.parse(&as);
|
||||
CANConfStream.close();
|
||||
if (!root) {
|
||||
errorSerial<<F("load failed")<<endl;
|
||||
sysConf.setETAG("");
|
||||
// sysConfStream.close();
|
||||
configLocked--;
|
||||
return 0;
|
||||
}
|
||||
infoSerial<<F("Loaded from CAN")<<endl;
|
||||
configLocked--;
|
||||
applyConfig();
|
||||
sysConf.loadETAG();
|
||||
|
||||
return 1;
|
||||
}
|
||||
CANConfStream.close();
|
||||
infoSerial<<F("No stored config")<<endl;
|
||||
configLocked--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int cmdFunctionSave(int arg_cnt, char **args)
|
||||
{
|
||||
if (arg_cnt>1)
|
||||
|
||||
@@ -332,6 +332,7 @@ bool disabledDisconnected(const aJsonObject *thermoExtensionArray, int thermoLat
|
||||
|
||||
void resetHard();
|
||||
|
||||
bool cleanConf(bool wait);
|
||||
|
||||
void printCurentLanConfig();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user