migrated lot of stuff from Chainoiler-Project

This commit is contained in:
Marcel Peterkau 2023-02-20 13:51:54 +01:00
parent 8884e995ca
commit ae29e23812
11 changed files with 546 additions and 301 deletions

View File

@ -12,6 +12,8 @@
#define HOST_NAME "AirsoftTimer_%08X"
#define SHUTDOWN_DELAY_MS 5000
#define GPIO_LORA_TX D3
#define GPIO_LORA_RX D4
#define GPIO_LORA_AUX D0

View File

@ -7,61 +7,63 @@ persistenceData_t PersistenceData;
const uint16_t eeVersion = 1; // inc
boolean eeAvailable = false;
const uint16_t persistencemarker_Adress = 0; // sizeof 4
const uint16_t startofConfig_Adress = 16;
const uint16_t startofPersistence_Adress = startofConfig_Adress + sizeof(ConfigData) + (sizeof(ConfigData) % 16);
const uint16_t startofConfigData = 16;
const uint16_t startofPersistence = 16 + sizeof(ConfigData) + (sizeof(ConfigData) % 16);
boolean checkEEPROMavailable();
void InitEEPROM()
{
ee.begin();
if (!checkEEPROMavailable())
{
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
return;
}
GetConfig_EEPROM();
if (ConfigData.EEPROM_Version != eeVersion)
{
FormatConfig_EEPROM();
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_EEPROM_VERSION_BAD, true);
return;
}
if (getPersistanceAddress() > ee.getDeviceSize())
{
FormatPersistence_EEPROM();
globals.systemStatus = sysStat_Error;
MaintainDTC(DTC_EEPROM_PDS_MARKER_INVALID, true);
return;
}
GetPersistence_EEPROM();
checkEEPROMavailable();
}
void EEPROM_Process()
{
switch (globals.requestEEAction)
{
case EE_CFG_SAVE:
StoreConfig_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Stored EEPROM CFG");
break;
case EE_CFG_LOAD:
GetConfig_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Loaded EEPROM CFG");
break;
case EE_CFG_FORMAT:
FormatConfig_EEPROM();
globals.requestEEAction = EE_IDLE;
globals.systemStatus = sysStat_Shutdown;
Serial.println("Formated EEPROM CFG");
break;
case EE_PDS_SAVE:
StorePersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Stored EEPROM PDS");
break;
case EE_PDS_LOAD:
GetPersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Loaded EEPROM PDS");
break;
case EE_PDS_FORMAT:
FormatPersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Formated EEPROM PDS");
break;
case EE_FORMAT_ALL:
FormatConfig_EEPROM();
FormatPersistence_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Formated EEPROM ALL");
break;
case EE_ALL_SAVE:
StorePersistence_EEPROM();
StoreConfig_EEPROM();
globals.requestEEAction = EE_IDLE;
Serial.println("Stored EEPROM ALL");
break;
case EE_IDLE:
default:
@ -76,7 +78,7 @@ void StoreConfig_EEPROM()
if (!checkEEPROMavailable())
return;
ee.updateBlock(startofConfig_Adress, (uint8_t *)&ConfigData, sizeof(ConfigData));
ee.updateBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
}
void GetConfig_EEPROM()
@ -84,34 +86,29 @@ void GetConfig_EEPROM()
if (!checkEEPROMavailable())
return;
ee.readBlock(startofConfig_Adress, (uint8_t *)&ConfigData, sizeof(ConfigData));
ee.readBlock(startofConfigData, (uint8_t *)&ConfigData, sizeof(ConfigData));
uint32_t checksum = ConfigData.checksum;
ConfigData.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&ConfigData, sizeof(ConfigData)) != checksum)
{
MaintainDTC(DTC_EEPROM_CFG_BAD, true);
FormatConfig_EEPROM();
MaintainDTC(DTC_EEPROM_CFG_BAD, DTC_CRITICAL, true);
}
ConfigData.checksum = checksum;
}
uint32_t getPersistanceAddress()
{
uint32_t eePersistenceMarker;
ee.readBlock(persistencemarker_Adress, (uint8_t *)&eePersistenceMarker, sizeof(eePersistenceMarker));
return eePersistenceMarker;
}
uint32_t ConfigSanityCheckResult = ConfigSanityCheck(false);
void updatePersistanceAddress(uint32_t adress)
{
ee.updateBlock(persistencemarker_Adress, (uint8_t *)&adress, sizeof(adress));
if (ConfigSanityCheckResult > 0)
{
MaintainDTC(DTC_EEPROM_CFG_SANITY, DTC_WARN, true, ConfigSanityCheckResult);
globals.requestEEAction = EE_CFG_SAVE;
}
}
void StorePersistence_EEPROM()
{
if (PersistenceData.writeCycleCounter >= EEPROM_ENDURANCE)
if (PersistenceData.writeCycleCounter >= 0xFFF0)
MovePersistencePage_EEPROM(false);
else
PersistenceData.writeCycleCounter++;
@ -122,7 +119,7 @@ void StorePersistence_EEPROM()
if (!checkEEPROMavailable())
return;
ee.updateBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
ee.updateBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
}
void GetPersistence_EEPROM()
@ -130,32 +127,42 @@ void GetPersistence_EEPROM()
if (!checkEEPROMavailable())
return;
ee.readBlock(getPersistanceAddress(), (uint8_t *)&PersistenceData, sizeof(PersistenceData));
uint32_t checksum = PersistenceData.checksum;
PersistenceData.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum)
ee.readBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
// if we got the StartAdress of Persistance and it's out of Range - we Reset it and store defaults
// otherwise we Read from eeprom and check if everything is correct
if (globals.eePersistanceAdress < startofPersistence || globals.eePersistanceAdress > ee.getDeviceSize())
{
MaintainDTC(DTC_EEPROM_PDS_BAD, true);
MovePersistencePage_EEPROM(true);
FormatPersistence_EEPROM();
MaintainDTC(DTC_EEPROM_PDSADRESS_BAD, DTC_CRITICAL, true);
}
else
{
ee.readBlock(globals.eePersistanceAdress, (uint8_t *)&PersistenceData, sizeof(PersistenceData));
uint32_t checksum = PersistenceData.checksum;
PersistenceData.checksum = 0;
if (Checksum_EEPROM((uint8_t *)&PersistenceData, sizeof(PersistenceData)) != checksum)
{
MaintainDTC(DTC_EEPROM_PDS_BAD, DTC_CRITICAL, true);
}
PersistenceData.checksum = checksum;
}
PersistenceData.checksum = checksum;
}
void FormatConfig_EEPROM()
{
configData_t defaults;
ConfigData = defaults;
Serial.println("Formatting Config-Partition");
ConfigData = ConfigData_defaults;
ConfigData.EEPROM_Version = eeVersion;
StoreConfig_EEPROM();
}
void FormatPersistence_EEPROM()
{
persistenceData_t defaults;
PersistenceData = defaults;
updatePersistanceAddress(startofPersistence_Adress);
Serial.println("Formatting Persistance-Partition");
memset(&PersistenceData, 0, sizeof(PersistenceData));
StorePersistence_EEPROM();
}
@ -164,31 +171,16 @@ void MovePersistencePage_EEPROM(boolean reset)
if (!checkEEPROMavailable())
return;
if (reset)
{
updatePersistanceAddress(startofPersistence_Adress);
}
else
{
uint32_t newPersistenceMarker = getPersistanceAddress() + sizeof(PersistenceData);
globals.eePersistanceAdress = +sizeof(PersistenceData);
PersistenceData.writeCycleCounter = 0;
// check if we reached the End of the EEPROM and Startover at the beginning
if ((newPersistenceMarker + sizeof(PersistenceData)) > ee.getDeviceSize())
{
MaintainDTC(DTC_EEPROM_WORNOUT, true);
return;
}
else
{
updatePersistanceAddress(newPersistenceMarker);
PersistenceData.writeCycleCounter = 0;
}
// check if we reached the End of the EEPROM and Startover at the beginning
if ((globals.eePersistanceAdress + sizeof(PersistenceData)) > ee.getDeviceSize() || reset)
{
globals.eePersistanceAdress = startofPersistence;
}
}
uint32_t GetEESize()
{
return ee.getDeviceSize();
ee.updateBlock(0, (uint8_t *)&globals.eePersistanceAdress, sizeof(globals.eePersistanceAdress));
}
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len)
@ -214,12 +206,6 @@ void dumpEEPROM(uint16_t memoryAddress, uint16_t length)
{
#define BLOCK_TO_LENGTH 16
if (length > ee.getDeviceSize())
length = ee.getDeviceSize();
if (memoryAddress + length > ee.getDeviceSize())
return;
if (!checkEEPROMavailable())
return;
@ -254,8 +240,24 @@ boolean checkEEPROMavailable()
{
if (!ee.isConnected())
{
MaintainDTC(DTC_NO_EEPROM_FOUND, true);
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, true);
globals.systemStatus = sysStat_Error;
return false;
}
MaintainDTC(DTC_NO_EEPROM_FOUND, DTC_CRITICAL, false);
return true;
}
uint32_t ConfigSanityCheck(bool autocorrect)
{
uint32_t setting_reset_bits = 0;
if ((ConfigData.batteryType != BATTERY_LIPO_2S) || (ConfigData.batteryType != BATTERY_LIPO_3S))
{
setting_reset_bits = setting_reset_bits | (1 << 0);
if (autocorrect)
ConfigData.batteryType = ConfigData_defaults.batteryType;
}
return setting_reset_bits;
}

View File

@ -7,6 +7,7 @@
#include "globals.h"
#include "dtc.h"
#include "common.h"
#define EEPROM_SIZE_BYTES I2C_DEVICESIZE_24LC01
#define EEPROM_ENDURANCE 1000000
@ -49,6 +50,10 @@ typedef struct
uint32_t checksum = 0;
} configData_t;
const configData_t ConfigData_defaults = {
0, BATTERY_LIPO_3S, 0
};
void InitEEPROM();
void EEPROM_Process();
void StoreConfig_EEPROM();
@ -60,9 +65,7 @@ void FormatPersistence_EEPROM();
uint32_t Checksum_EEPROM(uint8_t const *data, size_t len);
void dumpEEPROM(uint16_t memoryAddress, uint16_t length);
void MovePersistencePage_EEPROM(boolean reset);
uint32_t getPersistanceAddress();
void updatePersistanceAddress(uint32_t adress);
uint32_t GetEESize();
uint32_t ConfigSanityCheck(bool autocorrect = false);
extern configData_t ConfigData;
extern persistenceData_t PersistenceData;

View File

@ -2,7 +2,7 @@
DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
void MaintainDTC(DTCNums_t DTC_no, boolean active)
void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, uint32_t DebugValue)
{
for (int i = 0; i < MAX_DTC_STORAGE; i++)
{
@ -10,13 +10,15 @@ void MaintainDTC(DTCNums_t DTC_no, boolean active)
{
if (active && DTCStorage[i].active != DTC_ACTIVE)
{
Serial.printf("DTC gone active: %d", DTC_no);
Serial.printf("DTC gone active: %d, DebugVal: %d\n", DTC_no, DebugValue);
DTCStorage[i].timestamp = millis();
DTCStorage[i].active = DTC_ACTIVE;
DTCStorage[i].severity = DTC_severity;
DTCStorage[i].debugVal = DebugValue;
}
if (!active && DTCStorage[i].active == DTC_ACTIVE)
{
Serial.printf("DTC gone previous: %d", DTC_no);
Serial.printf("DTC gone previous: %d\n", DTC_no);
DTCStorage[i].active = DTC_PREVIOUS;
}
return;
@ -31,10 +33,11 @@ void MaintainDTC(DTCNums_t DTC_no, boolean active)
{
if (DTCStorage[i].Number == DTC_LAST_DTC)
{
Serial.printf("new DTC registered: %d", DTC_no);
Serial.printf("new DTC registered: %d, DebugVal: %d\n", DTC_no, DebugValue);
DTCStorage[i].Number = DTC_no;
DTCStorage[i].timestamp = millis();
DTCStorage[i].active = DTC_ACTIVE;
DTCStorage[i].debugVal = DebugValue;
return;
}
}
@ -81,5 +84,25 @@ DTCNums_t getlastDTC(boolean only_active)
}
}
return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC;
}
DTCNums_t getlastDTC_Severity(boolean only_active, DTCSeverity_t severity)
{
int8_t pointer = -1;
uint32_t lasttimestamp = 0;
for (int i = 0; i < MAX_DTC_STORAGE; i++)
{
if (DTCStorage[i].Number > 0 && DTCStorage[i].timestamp > lasttimestamp)
{
if ((only_active == false || DTCStorage[i].active == DTC_ACTIVE) && DTCStorage[i].severity == severity)
{
pointer = i;
lasttimestamp = DTCStorage[i].timestamp;
}
}
}
return pointer >= 0 ? DTCStorage[pointer].Number : DTC_LAST_DTC;
}

View File

@ -10,9 +10,11 @@ typedef enum DTCNums_e
DTC_NO_EEPROM_FOUND,
DTC_EEPROM_CFG_BAD,
DTC_EEPROM_PDS_BAD,
DTC_EEPROM_PDSADRESS_BAD,
DTC_EEPROM_VERSION_BAD,
DTC_EEPROM_WORNOUT, // this will happen if the EEPROM-cells are all overwritten 1 million times!
DTC_EEPROM_PDS_MARKER_INVALID, // This happens if the Marker of the PersistanceData was pointing to an EE-Adress bigger than the used EEPROM-IC
DTC_FLASHFS_ERROR,
DTC_FLASHFS_VERSION_ERROR,
DTC_EEPROM_CFG_SANITY,
DTC_LAST_DTC
} DTCNums_t;
@ -23,17 +25,27 @@ typedef enum DTCActive_e
DTC_NONE
} DTCActive_t;
typedef enum DTCSeverity_e
{
DTC_INFO,
DTC_WARN,
DTC_CRITICAL
} DTCSeverity_t;
typedef struct DTCEntry_s
{
DTCNums_t Number;
uint32_t timestamp;
DTCActive_t active;
DTCSeverity_t severity;
uint32_t debugVal;
} DTCEntry_t;
void MaintainDTC(DTCNums_t DTC_no, boolean active);
void MaintainDTC(DTCNums_t DTC_no, DTCSeverity_t DTC_severity, boolean active, uint32_t DebugValue = 0);
void ClearDTC(DTCNums_t DTC_no);
void ClearAllDTC();
DTCNums_t getlastDTC(boolean only_active);
DTCNums_t getlastDTC_Severity(boolean only_active, DTCSeverity_t severity);
extern DTCEntry_s DTCStorage[MAX_DTC_STORAGE];
#endif

View File

@ -16,18 +16,27 @@ typedef enum eEERequest
EE_IDLE,
EE_CFG_SAVE,
EE_CFG_LOAD,
EE_CFG_FORMAT,
EE_PDS_SAVE,
EE_PDS_LOAD
EE_PDS_LOAD,
EE_PDS_FORMAT,
EE_FORMAT_ALL,
EE_ALL_SAVE
} tEERequest;
typedef struct Globals_s
{
char DeviceName[33];
char DeviceName_ID[43];
char FlashVersion[10];
tSystem_Status systemStatus = sysStat_Startup;
tSystem_Status resumeStatus = sysStat_Startup;
char systemStatustxt[16] = "";
eEERequest requestEEAction = EE_IDLE;
float loadvoltage = 0;
uint16_t eePersistanceAdress;
bool hasDTC;
int loadvoltage_mV = 0;
int battery_level = 0;
} Globals_t;

161
Software/src/lora_net.cpp Normal file
View File

@ -0,0 +1,161 @@
#include "lora_net.h"
LoRa_E220 e220ttl(GPIO_LORA_TX, GPIO_LORA_RX, GPIO_LORA_AUX, 3, 4); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
void printParameters(struct Configuration configuration);
void printModuleInformation(struct ModuleInformation moduleInformation);
void InitLoRa(void (*MPinHelper)(int, int))
{
e220ttl.setMPins = MPinHelper;
e220ttl.begin();
ResponseStructContainer c;
c = e220ttl.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration *)c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
ResponseStructContainer cMi;
cMi = e220ttl.getModuleInformation();
// It's important get information pointer before all other operation
// ModuleInformation mi = *(ModuleInformation *)cMi.data;
Serial.println(cMi.status.getResponseDescription());
Serial.println(cMi.status.code);
// ----------------------- DEFAULT TRANSPARENT WITH RSSI -----------------------
configuration.ADDL = 0x02;
configuration.ADDH = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_200_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableLBT = LBT_ENABLED;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
c.close();
printParameters(configuration);
}
void LoRa_Process()
{
if (e220ttl.available() > 1)
{
ResponseContainer rc = e220ttl.receiveMessageRSSI();
// Is something goes wrong print error
if (rc.status.code != 1)
{
Serial.println(rc.status.getResponseDescription());
}
else
{
// Print the data received
Serial.println(rc.status.getResponseDescription());
Serial.println(rc.data);
Serial.print("RSSI: ");
Serial.println(rc.rssi, DEC);
}
}
}
void sendStatus_LoRa()
{
struct
{
MessageType_t type = "STATUS";
MessageStatus_t status;
} __attribute__((packed)) sendStatus;
sendStatus.status.nodeid = 0x0002;
sendStatus.status.millis = millis();
sendStatus.status.faction_active = 1;
sendStatus.status.faction_1_timer = 0xBBBBBBBB;
sendStatus.status.faction_2_timer = 0xCCCCCCCC;
sendStatus.status.faction_3_timer = 0xDDDDDDDD;
ResponseStatus rs = e220ttl.sendFixedMessage(0xFF, 0xFF, 23, (byte *)&sendStatus, sizeof(sendStatus));
Serial.println(rs.getResponseDescription());
}
void printParameters(struct Configuration configuration)
{
Serial.println("----------------------------------------");
Serial.print(F("HEAD : "));
Serial.print(configuration.COMMAND, HEX);
Serial.print(" ");
Serial.print(configuration.STARTING_ADDRESS, HEX);
Serial.print(" ");
Serial.println(configuration.LENGHT, HEX);
Serial.println(F(" "));
Serial.print(F("AddH : "));
Serial.println(configuration.ADDH, HEX);
Serial.print(F("AddL : "));
Serial.println(configuration.ADDL, HEX);
Serial.println(F(" "));
Serial.print(F("Chan : "));
Serial.print(configuration.CHAN, DEC);
Serial.print(" -> ");
Serial.println(configuration.getChannelDescription());
Serial.println(F(" "));
Serial.print(F("SpeedParityBit : "));
Serial.print(configuration.SPED.uartParity, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTParityDescription());
Serial.print(F("SpeedUARTDatte : "));
Serial.print(configuration.SPED.uartBaudRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTBaudRateDescription());
Serial.print(F("SpeedAirDataRate : "));
Serial.print(configuration.SPED.airDataRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getAirDataRateDescription());
Serial.println(F(" "));
Serial.print(F("OptionSubPacketSett: "));
Serial.print(configuration.OPTION.subPacketSetting, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getSubPacketSetting());
Serial.print(F("OptionTranPower : "));
Serial.print(configuration.OPTION.transmissionPower, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionRSSIAmbientNo: "));
Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
Serial.println(F(" "));
Serial.print(F("TransModeWORPeriod : "));
Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
Serial.print(F("TransModeEnableLBT : "));
Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
Serial.print(F("TransModeEnableRSSI: "));
Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
Serial.print(F("TransModeFixedTrans: "));
Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Serial.println("----------------------------------------");
}

21
Software/src/lora_net.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _LORA_NET_H_
#define _LORA_NET_H_
#include <Arduino.h>
#include <LoRa_E220.h>
// local includes
#include "lora_messages.h"
#include "defaults.h"
#include "config.h"
#include "globals.h"
#include "dtc.h"
#include "common.h"
#define FREQUENCY_868
void InitLoRa(void (*MPinHelper)(int, int));
void LoRa_Process();
void sendStatus_LoRa();
#endif

View File

@ -1,29 +1,23 @@
#define FREQUENCY_868
#include <Arduino.h>
#include <TM1637.h>
#include <Ticker.h>
#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ESPAsyncWebServer.h>
#include <LittleFS.h>
#include <PCF8574.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
#include <ArduinoJson.h>
#include <LoRa_E220.h>
// local includes
#include "lora_messages.h"
#include "defaults.h"
#include "webui.h"
#include "config.h"
#include "globals.h"
#include "dtc.h"
#include "common.h"
#include "lora_net.h"
#ifdef WIFI_CLIENT
#include <WiFiMulti.h>
@ -37,27 +31,19 @@ WiFiMulti wifiMulti;
PCF8574 i2c_io(I2C_IO_ADDRESS);
Adafruit_INA219 ina219;
LoRa_E220 e220ttl(GPIO_LORA_TX, GPIO_LORA_RX, GPIO_LORA_AUX, 3, 4); // Arduino RX <-- e220 TX, Arduino TX --> e220 RX AUX M0 M1
TM1637 disp_FAC_1(GPIO_7SEG_CLK, GPIO_7SEG_EN_FAC1);
TM1637 disp_FAC_2(GPIO_7SEG_CLK, GPIO_7SEG_EN_FAC2);
TM1637 disp_FAC_3(GPIO_7SEG_CLK, GPIO_7SEG_EN_FAC3);
#ifdef CAPTIVE
DNSServer dnsServer;
#endif
AsyncWebServer server(80);
void printParameters(struct Configuration configuration);
void printModuleInformation(struct ModuleInformation moduleInformation);
void displayInfo();
void SevenSeg_Output();
void toggleWiFiAP(boolean shutdown = false);
void SystemShutdown();
void SetBatteryType(batteryType_t type);
void ProcessKeyCombos(bool *btnState);
void OverrideDisplay(const uint8_t *message, uint32_t time);
uint32_t getESPChipID();
void initGlobals();
void setMPins_Helper(int pin, int status);
void tmrCallback_StatusSender();
Ticker tmrStatusSender(tmrCallback_StatusSender, 30000, 0, MILLIS);
@ -80,6 +66,13 @@ char DisplayOverrideValue[5] = {0};
Globals_t globals;
void initGlobals()
{
globals.requestEEAction = EE_IDLE;
globals.resumeStatus = sysStat_Normal;
globals.systemStatus = sysStat_Startup;
}
void setMPins_Helper(int pin, int status)
{
i2c_io.write(pin, status);
@ -88,19 +81,22 @@ void setMPins_Helper(int pin, int status)
void setup()
{
system_update_cpu_freq(SYS_CPU_80MHZ);
Serial.begin(115200);
Serial.print("\n\n\n");
#ifdef SERIAL_DEBUG
Serial.setDebugOutput(true);
#endif
strcpy(globals.DeviceName, DEVICE_NAME);
snprintf(globals.DeviceName_ID, 42, "%s_%08X", globals.DeviceName, ESP.getChipId());
WiFi.persistent(false);
WiFi.disconnect();
strcpy(globals.DeviceName, DEVICE_NAME);
snprintf(globals.DeviceName_ID, 42, "%s_%08X", globals.DeviceName, getESPChipID());
Serial.begin(115200);
Serial.setDebugOutput(false);
Serial.println("\n\nDark Emergency Timer - by Hiabuto Defense");
Serial.println(globals.DeviceName);
ClearAllDTC(); // Init DTC-Storage
InitEEPROM();
GetConfig_EEPROM();
GetPersistence_EEPROM();
if (i2c_io.begin())
{
@ -121,54 +117,9 @@ void setup()
Serial.print("INA219 not Initialized\n");
}
e220ttl.setMPins = &setMPins_Helper;
e220ttl.begin();
ResponseStructContainer c;
c = e220ttl.getConfiguration();
// It's important get configuration pointer before all other operation
Configuration configuration = *(Configuration *)c.data;
Serial.println(c.status.getResponseDescription());
Serial.println(c.status.code);
ResponseStructContainer cMi;
cMi = e220ttl.getModuleInformation();
// It's important get information pointer before all other operation
// ModuleInformation mi = *(ModuleInformation *)cMi.data;
Serial.println(cMi.status.getResponseDescription());
Serial.println(cMi.status.code);
// ----------------------- DEFAULT TRANSPARENT WITH RSSI -----------------------
configuration.ADDL = 0x02;
configuration.ADDH = 0x00;
configuration.CHAN = 23;
configuration.SPED.uartBaudRate = UART_BPS_9600;
configuration.SPED.airDataRate = AIR_DATA_RATE_010_24;
configuration.SPED.uartParity = MODE_00_8N1;
configuration.OPTION.subPacketSetting = SPS_200_00;
configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_ENABLED;
configuration.OPTION.transmissionPower = POWER_22;
configuration.TRANSMISSION_MODE.enableRSSI = RSSI_ENABLED;
configuration.TRANSMISSION_MODE.fixedTransmission = FT_FIXED_TRANSMISSION;
configuration.TRANSMISSION_MODE.enableLBT = LBT_ENABLED;
configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011;
// Set configuration changed and set to not hold the configuration
ResponseStatus rs = e220ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_LOSE);
Serial.println(rs.getResponseDescription());
Serial.println(rs.code);
c.close();
printParameters(configuration);
InitLoRa(&setMPins_Helper);
tmrStatusSender.start();
LittleFS.begin();
#ifdef WIFI_CLIENT
WiFi.mode(WIFI_STA);
WiFi.setHostname(globals.DeviceName_ID);
@ -177,14 +128,9 @@ void setup()
#else
WiFi.mode(WIFI_AP);
WiFi.begin(QUOTE(DEVICE_NAME), QUOTE(WIFI_AP_PASSWORD));
#if defined(ESP32)
WiFi.sleep(true);
#endif
WiFi.mode(WIFI_OFF);
#endif
InitEEPROM();
ArduinoOTA.setPort(8266);
ArduinoOTA.setHostname(globals.DeviceName_ID);
ArduinoOTA.setPassword(QUOTE(ADMIN_PASSWORD));
@ -236,6 +182,7 @@ void setup()
#endif
initWebUI();
initGlobals();
disp_FAC_1.init();
disp_FAC_1.setBrightness(5);
@ -247,30 +194,13 @@ void setup()
tmrEEPROMCyclicPDS.start();
tmrFactionTicker.start();
tmrInputGetter.start();
Serial.println("Setup Done");
}
void loop()
{
if (e220ttl.available() > 1)
{
ResponseContainer rc = e220ttl.receiveMessageRSSI();
// Is something goes wrong print error
if (rc.status.code != 1)
{
Serial.println(rc.status.getResponseDescription());
}
else
{
// Print the data received
Serial.println(rc.status.getResponseDescription());
Serial.println(rc.data);
Serial.print("RSSI: ");
Serial.println(rc.rssi, DEC);
}
}
tmrEEPROMCyclicPDS.update();
tmrFactionTicker.update();
tmrInputGetter.update();
@ -280,6 +210,7 @@ void loop()
ArduinoOTA.handle();
SevenSeg_Output();
EEPROM_Process();
LoRa_Process();
#ifdef CAPTIVE
dnsServer.processNextRequest();
@ -321,7 +252,7 @@ void SevenSeg_Output()
if (millis() % 3000 < 1500)
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4d", globals.battery_level);
else
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%4s", String(globals.loadvoltage, 1).c_str());
snprintf(sevenSegBuff, sizeof(sevenSegBuff), "%2d.%1d", (globals.loadvoltage_mV / 1000), ((globals.loadvoltage_mV % 1000) / 100));
disp_FAC_1.setBrightness(1);
disp_FAC_1.display(" BAT");
@ -423,90 +354,9 @@ void tmrCallback_InputGetter()
}
}
void printParameters(struct Configuration configuration)
{
Serial.println("----------------------------------------");
Serial.print(F("HEAD : "));
Serial.print(configuration.COMMAND, HEX);
Serial.print(" ");
Serial.print(configuration.STARTING_ADDRESS, HEX);
Serial.print(" ");
Serial.println(configuration.LENGHT, HEX);
Serial.println(F(" "));
Serial.print(F("AddH : "));
Serial.println(configuration.ADDH, HEX);
Serial.print(F("AddL : "));
Serial.println(configuration.ADDL, HEX);
Serial.println(F(" "));
Serial.print(F("Chan : "));
Serial.print(configuration.CHAN, DEC);
Serial.print(" -> ");
Serial.println(configuration.getChannelDescription());
Serial.println(F(" "));
Serial.print(F("SpeedParityBit : "));
Serial.print(configuration.SPED.uartParity, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTParityDescription());
Serial.print(F("SpeedUARTDatte : "));
Serial.print(configuration.SPED.uartBaudRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getUARTBaudRateDescription());
Serial.print(F("SpeedAirDataRate : "));
Serial.print(configuration.SPED.airDataRate, BIN);
Serial.print(" -> ");
Serial.println(configuration.SPED.getAirDataRateDescription());
Serial.println(F(" "));
Serial.print(F("OptionSubPacketSett: "));
Serial.print(configuration.OPTION.subPacketSetting, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getSubPacketSetting());
Serial.print(F("OptionTranPower : "));
Serial.print(configuration.OPTION.transmissionPower, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.print(F("OptionRSSIAmbientNo: "));
Serial.print(configuration.OPTION.RSSIAmbientNoise, BIN);
Serial.print(" -> ");
Serial.println(configuration.OPTION.getRSSIAmbientNoiseEnable());
Serial.println(F(" "));
Serial.print(F("TransModeWORPeriod : "));
Serial.print(configuration.TRANSMISSION_MODE.WORPeriod, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getWORPeriodByParamsDescription());
Serial.print(F("TransModeEnableLBT : "));
Serial.print(configuration.TRANSMISSION_MODE.enableLBT, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getLBTEnableByteDescription());
Serial.print(F("TransModeEnableRSSI: "));
Serial.print(configuration.TRANSMISSION_MODE.enableRSSI, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getRSSIEnableByteDescription());
Serial.print(F("TransModeFixedTrans: "));
Serial.print(configuration.TRANSMISSION_MODE.fixedTransmission, BIN);
Serial.print(" -> ");
Serial.println(configuration.TRANSMISSION_MODE.getFixedTransmissionDescription());
Serial.println("----------------------------------------");
}
void tmrCallback_StatusSender()
{
struct
{
MessageType_t type = "STATUS";
MessageStatus_t status;
} __attribute__((packed)) sendStatus;
sendStatus.status.nodeid = 0x0002;
sendStatus.status.millis = millis();
sendStatus.status.faction_active = 1;
sendStatus.status.faction_1_timer = 0xBBBBBBBB;
sendStatus.status.faction_2_timer = 0xCCCCCCCC;
sendStatus.status.faction_3_timer = 0xDDDDDDDD;
ResponseStatus rs = e220ttl.sendFixedMessage(0xFF, 0xFF, 23, (byte *)&sendStatus, sizeof(sendStatus));
Serial.println(rs.getResponseDescription());
sendStatus_LoRa();
}
void tmrCallback_PowerMonitor()
@ -528,15 +378,15 @@ void tmrCallback_PowerMonitor()
busvoltage = ina219.getBusVoltage_V();
// current_mA = ina219.getCurrent_mA();
// power_mW = ina219.getPower_mW();
globals.loadvoltage = busvoltage + (shuntvoltage / 1000);
globals.loadvoltage_mV = (busvoltage * 1000) + shuntvoltage;
switch (ConfigData.batteryType)
{
case BATTERY_LIPO_2S:
battery_level = map(globals.loadvoltage * 100, bat_min_2s, bat_max_2s, 0, 100);
battery_level = map(globals.loadvoltage_mV / 10, bat_min_2s, bat_max_2s, 0, 100);
globals.battery_level = battery_level < 0 ? 0 : battery_level;
break;
case BATTERY_LIPO_3S:
battery_level = map(globals.loadvoltage * 100, bat_min_3s, bat_max_3s, 0, 100);
battery_level = map(globals.loadvoltage_mV / 10, bat_min_3s, bat_max_3s, 0, 100);
globals.battery_level = battery_level < 0 ? 0 : battery_level;
break;
default:
@ -547,7 +397,7 @@ void tmrCallback_PowerMonitor()
// Serial.printf("Battery Level: %d %%\n", globals.battery_level);
// Serial.printf("Bus Voltage: %f V\n", busvoltage);
// Serial.printf("Shunt Voltage: %f mV\n", shuntvoltage);
// Serial.printf("Load Voltage: %f V\n", globals.loadvoltage);
// Serial.printf("Load Voltage: %d mV\n", globals.loadvoltage_mV;
// Serial.printf("Current: %f mA\n", current_mA);
// Serial.printf("Power: %f mW\n", power_mW);
}
@ -599,8 +449,19 @@ void toggleWiFiAP(boolean shutdown)
void SystemShutdown()
{
StoreConfig_EEPROM();
ESP.restart();
static uint32_t shutdown_delay = 0;
if (shutdown_delay == 0)
{
shutdown_delay = millis() + SHUTDOWN_DELAY_MS;
Serial.printf("Shutdown requested - Restarting in %d seconds\n", SHUTDOWN_DELAY_MS / 1000);
}
if (shutdown_delay < millis())
{
StoreConfig_EEPROM();
StorePersistence_EEPROM();
ESP.restart();
}
}
void SetBatteryType(batteryType_t type)
@ -619,20 +480,6 @@ void OverrideDisplay(const char *message, uint32_t time)
strcpy(DisplayOverrideValue, message);
}
uint32_t getESPChipID()
{
#if defined(ESP8266)
return ESP.getChipId();
#elif defined(ESP32)
uint32_t chipId;
for (int i = 0; i < 17; i = i + 8)
{
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
}
return chipId;
#endif
}
void ProcessKeyCombos(bool *btnState)
{
typedef enum

View File

@ -13,26 +13,52 @@ typedef enum
char StatusResponseMessage[64];
statusResponseMessage_Type_t StatusResponseMessage_Type = RESPMSG_INFO;
#ifdef CAPTIVE
DNSServer dnsServer;
#endif
AsyncWebServer server(80);
String processor(const String &var);
void WebserverPOST_Callback(AsyncWebServerRequest *request);
void WebserverNotFound_Callback(AsyncWebServerRequest *request);
void Webserver_Callback(AsyncWebServerRequest *request);
void WebserverCommands_Callback(String input);
void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final);
void WebServerEEJSON_Callback(AsyncWebServerRequest *request);
void GetFlashVersion(char *buff, size_t buff_size);
void initWebUI()
{
if (!LittleFS.begin())
{
Serial.println("An Error has occurred while mounting LittleFS");
MaintainDTC(DTC_FLASHFS_ERROR, DTC_CRITICAL, true);
return;
}
GetFlashVersion(globals.FlashVersion, sizeof(globals.FlashVersion));
if (strcmp(globals.FlashVersion, QUOTE(FLASH_FS_VERSION)))
{
MaintainDTC(DTC_FLASHFS_VERSION_ERROR, DTC_WARN, true);
}
MDNS.begin(globals.DeviceName);
MDNS.addService("telnet", "tcp", 23);
MDNS.addService("http", "tcp", 80);
webServer.serveStatic("/static/", LittleFS, "/static/").setCacheControl("max-age=360000");
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->redirect("/index.htm"); });
webServer.onNotFound(WebserverNotFound_Callback);
webServer.on("/index.htm", HTTP_GET, Webserver_Callback);
webServer.on("/index.htm", HTTP_POST, WebserverPOST_Callback);
webServer.on("/post.htm", HTTP_POST, WebserverPOST_Callback);
webServer.on("/eejson", HTTP_GET, WebServerEEJSON_Callback);
webServer.on(
"/doUpdate", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverFirmwareUpdate_Callback);
webServer.on(
"/eeRestore", HTTP_POST, [](AsyncWebServerRequest *request) {}, WebserverEERestore_Callback);
webServer.begin();
}
@ -72,7 +98,7 @@ String processor(const String &var)
return String(globals.DeviceName);
if (var == "BAT_VOLTAGE")
return String(globals.loadvoltage);
return String((float)globals.loadvoltage_mV / 1000.0);
if (var == "DTC_TABLE")
{
@ -161,7 +187,7 @@ String processor(const String &var)
}
if (var == "BATTERY_VOLTAGE")
{
return String(globals.loadvoltage);
return String((float)globals.loadvoltage_mV / 1000.0);
}
return String();
@ -222,4 +248,138 @@ void WebserverCommands_Callback(String input)
ConfigData.batteryType = BATTERY_LIPO_2S;
globals.requestEEAction = EE_CFG_SAVE;
}
}
void GetFlashVersion(char *buff, size_t buff_size)
{
File this_file = LittleFS.open("version", "r");
if (!this_file)
{ // failed to open the file, retrn empty result
buff[0] = '\0';
return;
}
if (this_file.available())
{
int bytes_read;
bytes_read = this_file.readBytesUntil('\r', buff, buff_size - 1);
buff[bytes_read] = '\0';
}
this_file.close();
}
void WebserverFirmwareUpdate_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final)
{
if (!index)
{
Serial.println("Update");
size_t content_len = request->contentLength();
int cmd = (filename.indexOf(".fs") > -1) ? U_FS : U_FLASH;
Update.runAsync(true);
if (!Update.begin(content_len, cmd))
{
Update.printError(Serial);
}
}
if (Update.write(data, len) != len)
{
Update.printError(Serial);
}
else
{
Serial.printf("Progress: %d%%\n", (Update.progress() * 100) / Update.size());
}
if (final)
{
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "Please wait while the device reboots");
response->addHeader("Refresh", "20");
response->addHeader("Location", "/");
request->send(response);
if (!Update.end(true))
{
Update.printError(Serial);
}
else
{
Serial.println("Update complete");
Serial.flush();
globals.systemStatus = sysStat_Shutdown;
}
}
}
void WebserverEERestore_Callback(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final)
{
bool ee_done = false;
bool validext = false;
if (!index)
{
Serial.println("EEPROM restore");
validext = (filename.indexOf(".ee.json") > -1);
}
if (validext)
{
Serial.println("Restoring EEPROM-Stuff");
}
if (final)
{
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "Please wait while the device reboots");
response->addHeader("Refresh", "20");
response->addHeader("Location", "/");
request->send(response);
if (ee_done)
{
Serial.println("Update complete");
Serial.flush();
globals.systemStatus = sysStat_Shutdown;
}
else
{
}
}
}
void WebServerEEJSON_Callback(AsyncWebServerRequest *request)
{
AsyncResponseStream *response = request->beginResponseStream("application/json");
DynamicJsonDocument json(1024);
JsonObject fwinfo = json.createNestedObject("info");
char buffer[16];
fwinfo["DeviceName"] = globals.DeviceName;
fwinfo["FW-Version"] = QUOTE(SW_VERSION);
fwinfo["FS-Version"] = globals.FlashVersion;
JsonObject config = json.createNestedObject("config");
config["EEPROM_Version"] = ConfigData.EEPROM_Version;
sprintf(buffer, "0x%08X", ConfigData.checksum);
config["checksum"] = buffer;
JsonObject eepart = json.createNestedObject("eepart");
sprintf(buffer, "0x%04X", globals.eePersistanceAdress);
eepart["PersistanceAddress"] = buffer;
JsonObject persis = json.createNestedObject("persis");
persis["writeCycleCounter"] = PersistenceData.writeCycleCounter;
sprintf(buffer, "0x%08X", PersistenceData.checksum);
persis["checksum"] = buffer;
serializeJsonPretty(json, *response);
response->addHeader("Content-disposition", "attachment; filename=backup.ee.json");
request->send(response);
}

View File

@ -6,10 +6,15 @@
#include <LittleFS.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Updater.h>
#include <ESP8266mDNS.h>
#include <AsyncJson.h>
#include <ArduinoJson.h>
#include "config.h"
#include "globals.h"
#include "dtc.h"
#include "defaults.h"
#include "common.h"
void initWebUI();