From a5c43777be0202cb25f4f36cc0b4184436b40ae3 Mon Sep 17 00:00:00 2001 From: nrs1g15 <nrs1g15@soton.ac.uk> Date: Fri, 26 Jul 2019 16:16:01 +0100 Subject: [PATCH] Moved unused firmwares to legacy folder --- .../sufst-can-sd-xbee/sufst-can-sd-xbee.ino | 1638 +++++++++++++++++ .../.idea/codeStyles/Project.xml | 76 + .../.idea/codeStyles/codeStyleConfig.xml | 5 + .../sufst-openlogger/.idea/misc.xml | 6 + .../sufst-openlogger/.idea/modules.xml | 8 + .../.idea/sufst-openlogger.iml | 8 + .../sufst-openlogger/.idea/vcs.xml | 7 + .../sufst-openlogger/.idea/workspace.xml | 329 ++++ Legacy-firmware/sufst-openlogger/buffer.cpp | 135 ++ Legacy-firmware/sufst-openlogger/buffer.h | 42 + .../sufst-openlogger/openLogger.cpp | 433 +++++ Legacy-firmware/sufst-openlogger/openLogger.h | 53 + .../sufst-openlogger/sufst-openlogger.ino | 21 + .../.idea/codeStyles/Project.xml | 60 + .../.idea/codeStyles/codeStyleConfig.xml | 5 + .../.idea/misc.xml | 6 + .../.idea/modules.xml | 8 + .../.idea/sufst-openlogger_controller.iml | 8 + .../sufst-openlogger_controller/.idea/vcs.xml | 6 + .../.idea/workspace.xml | 410 +++++ .../sufst-openlogger_controller/buffer.cpp | 142 ++ .../sufst-openlogger_controller/buffer.h | 48 + .../sufst-openlogger_controller/can.cpp | 321 ++++ .../sufst-openlogger_controller/can.h | 69 + .../sufst-openlogger_controller/ecuCan.cpp | 280 +++ .../sufst-openlogger_controller/ecuCan.h | 38 + .../ecuOpenloggerTags.h | 19 + .../openLoggerController.cpp | 296 +++ .../openLoggerController.h | 49 + .../sufst-openlogger_controller.ino | 64 + 30 files changed, 4590 insertions(+) create mode 100644 Legacy-firmware/sufst-can-sd-xbee/sufst-can-sd-xbee.ino create mode 100644 Legacy-firmware/sufst-openlogger/.idea/codeStyles/Project.xml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/codeStyles/codeStyleConfig.xml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/misc.xml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/modules.xml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/sufst-openlogger.iml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/vcs.xml create mode 100644 Legacy-firmware/sufst-openlogger/.idea/workspace.xml create mode 100644 Legacy-firmware/sufst-openlogger/buffer.cpp create mode 100644 Legacy-firmware/sufst-openlogger/buffer.h create mode 100644 Legacy-firmware/sufst-openlogger/openLogger.cpp create mode 100644 Legacy-firmware/sufst-openlogger/openLogger.h create mode 100644 Legacy-firmware/sufst-openlogger/sufst-openlogger.ino create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/Project.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/codeStyleConfig.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/misc.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/modules.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/sufst-openlogger_controller.iml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/vcs.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/.idea/workspace.xml create mode 100644 Legacy-firmware/sufst-openlogger_controller/buffer.cpp create mode 100644 Legacy-firmware/sufst-openlogger_controller/buffer.h create mode 100644 Legacy-firmware/sufst-openlogger_controller/can.cpp create mode 100644 Legacy-firmware/sufst-openlogger_controller/can.h create mode 100644 Legacy-firmware/sufst-openlogger_controller/ecuCan.cpp create mode 100644 Legacy-firmware/sufst-openlogger_controller/ecuCan.h create mode 100644 Legacy-firmware/sufst-openlogger_controller/ecuOpenloggerTags.h create mode 100644 Legacy-firmware/sufst-openlogger_controller/openLoggerController.cpp create mode 100644 Legacy-firmware/sufst-openlogger_controller/openLoggerController.h create mode 100644 Legacy-firmware/sufst-openlogger_controller/sufst-openlogger_controller.ino diff --git a/Legacy-firmware/sufst-can-sd-xbee/sufst-can-sd-xbee.ino b/Legacy-firmware/sufst-can-sd-xbee/sufst-can-sd-xbee.ino new file mode 100644 index 0000000..0d9a240 --- /dev/null +++ b/Legacy-firmware/sufst-can-sd-xbee/sufst-can-sd-xbee.ino @@ -0,0 +1,1638 @@ +// Watchdog +#include <avr/wdt.h> + +/* TABLE OF CONTENTS */ +/* 1. START OF MODULES CONFIG */ +/* 2. START OF DEBUG */ +/* 3. COMPILER NOTICES */ +/* 4. SHAFT SPEED */ +/* 5. SD */ +/* 6. XBee */ +/* 7. CAN */ +/* 8. FUNCTION PROTOTYPES */ +/* 9. FUNCTION POINTERS */ +/* 10. SHAFT FUNCTIONS */ +/* 11. ECU FUNCTIONS */ +/* 12. CAN FUNCTIONS */ +/* 13. TIMER FUNCTIONS */ +/* 14. SD FUNCTIONS */ +/* 15. XBee FUNCTIONS */ +/* 16. ARDUINO FUNCTIONS (SETUP AND LOOP) */ + + +/***************** START OF MODULES CONFIG *********************/ +#define SD_ENABLED 1 + +// TODO: ADD XBEE BUFFERS +#define XBEE_ENABLED 0 + +#define SHAFT_SPEED_SENSOR_ENABLED 0 + +#define EMULATE_ECU 0 + +#define ECU_ATTACHED_ENABLED 1 + +#define RPM_LEDS_ENABLED 0 + +/***************** START OF DEBUG *********************/ +#define DEBUG_CAN_RX 0 +#define DEBUG_CAN_RX_MINIMAL 0 + +#define DEBUG_CAN_TX 0 +#define DEBUG_CAN_TX_MINIMAL 0 +#define DEBUG_CAN_TX_REQS 0 + +#define DEBUG_ECU_CAN 0 +#define DEBUG_ECU_CAN_MINIMAL 0 + +#define DEBUG_SD 0 +#define DEBUG_SD_MINIMAL 1 +#define SD_SERIAL_PRINT_BLOCK_WRITES 1 + +#define DEBUG_SHAFT_SPEED 0 +/***************** END OF DEBUG ********************/ + +/***************** START OF COMPLIER NOTICES *********************/ +#if EMULATE_ECU +#pragma message "Emulate ECU Enabled" +#endif //EMULATE_ECU + +#if ECU_ATTACHED_ENABLED +#pragma message "ECU Attached Enabled" +#endif //ECU_ATTACHED_ENABLED + +#if DEBUG_CAN_RX +#pragma message "Can Rx Debug Enabled" +#endif //DEBUG_CAN_RX + +#if DEBUG_CAN_RX_MINIMAL +#pragma message "Can Rx Minimal Debug Enabled" +#endif //DEBUG_CAN_RX_MINIMAL + +#if DEBUG_CAN_TX +#pragma message "Can Tx Debug Enabled" +#endif //DEBUG_CAN_TX + +#if DEBUG_CAN_TX_MINIMAL +#pragma message "Can Tx Minimal Debug Enabled" +#endif //DEBUG_CAN_TX_MINIMAL + +#if DEBUG_CAN_TX_REQS +#pragma message "Can Tx Requests Debug Enabled" +#endif //DEBUG_CAN_TX_REQS + +#if DEBUG_ECU_CAN +#pragma message "ECU Debug Enabled" +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL +#pragma message "ECU Minimal Debug Enabled" +#endif //DEBUG_ECU_CAN_MINIMAL + +#if DEBUG_SD +#pragma message "SD Debug Enabled" +#endif //DEBUG_SD + +#if DEBUG_SD_MINIMAL +#pragma message "SD Minimal Debug Enabled" +#endif //DEBUG_SD_MINIMAL + +#if SD_ENABLED +#pragma message "SD Enabled" +#endif //SD_ENABLED + +#if XBEE_ENABLED +#pragma message "Xbee Enabled" +#endif //XBEE_ENABLED + +#if SHAFT_SPEED_SENSOR_ENABLED +#pragma message "Shaft Speed Sensor Enabled" +#endif // SHAFT_SPEED_SENSOR_ENABLED + +#if DEBUG_SHAFT_SPEED +#pragma message "Shaft Speed Debug Enabled" +#endif //DEBUG_SHAFT_SPEED + +#if SD_SERIAL_PRINT_BLOCK_WRITES +#pragma message "SD Serial Printing Block Writes Info Enabled" +#endif //SD_SERIAL_PRINT_BLOCK_WRITES + +#if RPM_LEDS_ENABLED +#pragma message "RPM LEDs Enabled" +#endif //RPM_LEDS_ENABLED +/***************** END OF COMPLIER NOTICES *********************/ + +/***************** START OF SHAFT SPEED *********************/ +#if SHAFT_SPEED_SENSOR_ENABLED + +#define SHAFT_SPEED_SENSOR_PIN A15 + +#define SHAFT_HARDWARE_TIMER_NR 5 + +#define SHAFT_SPEED_THRESHOLD_VALUE 2 + +#define SHAFT_CALC_FREQUENCY_RATE_FREQ 10000 + +volatile float shaftLastCalcFrequency = 0.0; + +#endif //SHAFT_SPEED_SENSOR_ENABLED +/***************** END OF SHAFT SPEED *********************/ + +/***************** START OF RPM LEDS **********************/ +#if RPM_LEDS_ENABLED +#define RPM1_PIN 0 +#define RPM2_PIN 1 +#define RPM3_PIN 2 +#define RPM4_PIN 3 +#define RPM5_PIN 4 +#define UPSHIT_PIN 5 //CHANGED XBEE CTS AND RTS PIN care + +#define RED1_THRESHOLD 6000 // below this, time to downshit +#define RED2_THRESHOLD 8000 +#define GREEN1_THRESHOLD 10000 +#define GREEN2_THRESHOLD 11000 +#define GREEN3_THRESHOLD 12000 +#define UPSHIT_THRESHOLD 13000 //above this, time to upshit + + +uint16_t g_RPM = 0; + +#endif // RPM_LEDS_ENABLED +/***************** END OF RPM LEDS **********************/ +/***************** START OF SD *********************/ +#if SD_ENABLED + +#define SD_WRITE_BUFFER_LEN 3 + +#define SD_WRITE_FREQUENCY 10 +#define SD_HARDWARE_TIMER_NR 4 + +#define SD_CS_PIN 8 + +#include <SdFat.h> + +typedef struct { + uint16_t blockHead; + // Writing 512 bytes per write gives fastest performance due to + // least overheads. + uint8_t block[512]; +} sdBlockTemplate; + +static sdBlockTemplate sdWriteBuffer[SD_WRITE_BUFFER_LEN]; + +uint16_t sdWriteBufferHead = 0; +uint16_t sdWriteBufferTail = 0; + +SdFat sd; +SdFile file; + +uint8_t sdCardStatus = 0; + +#if ECU_ATTACHED_ENABLED + +#define ECU_SD_START_BYTE 0x8C +#define ECU_SD_END_BYTE 0xA7 + +#endif //ECU_ATTACHED_ENABLED + +#endif // SD_ENABLED + +/***************** END OF SD *********************/ + +/***************** START OF XBEE *********************/ +#if XBEE_ENABLED + +#define XBEE_USE_OWN_TX_BUFFER 1 + +#define XBEE_CTS_PIN 6 +#define XBEE_RTS_PIN 7 + +#define XBEE_CAN_NO_REC_PERIOD_BEFORE_TRANSMIT_MS 2 + +#include "XBee.h" + +XBee xbee; + +XBeeAddress64 xbeeAddress64(0x0013A200, 0x410AC922); +Tx64Request xbeeTx64Request(xbeeAddress64, 0, 0); + +#endif // XBEE_ENABLED + +/***************** END OF XBEE *********************/ + +/***************** START OF CAN *********************/ +// CAN_INT_PIN MUST BE 2 +#define CAN_INT_PIN 2 +#define CAN_CS_PIN 10 + +#define CAN_RX_BUFFER_LEN 128 +#define CAN_TX_BUFFER_LEN 64 + +#define CAN_RESET_DEVICE_ON_TIMEOUT 0 +#define CAN_NO_MSG_TIMEOUT_RESET_MS 10000 + +#define CAN_TX_RETRY_LIMIT 5 + + +#include <mcp_can.h> +#include <mcp_can_dfs.h> + +typedef struct { + union { + uint16_t id; + // if id is 0x2001 then idByte[0] is 0x01 and idByte[1] is 0x20 + // due to the endianness of the system + uint8_t idByte[2]; + }; + uint8_t len; + + union { + uint8_t data[8]; + uint16_t data16[4]; + uint32_t data32[2]; + float dataFl[2]; + }; + +} CanMsgTemplate; + +// Can Rx Buffer +static CanMsgTemplate canRxBuffer[CAN_RX_BUFFER_LEN]; +volatile uint8_t canRxBufferHead = 0; +volatile uint8_t canRxBufferTail = 0; + +// Can Tx Buffer +static CanMsgTemplate canTxBuffer[CAN_TX_BUFFER_LEN]; +volatile uint8_t canTxBufferHead = 0; +volatile uint8_t canTxBufferTail = 0; + +// Can instance +MCP_CAN can; + +// Keep track of the last time we received a can msg +volatile unsigned long lastCanMsgRecTimeMs = 0; +unsigned long currMs = 0; + +/***************** END OF CAN *********************/ + +/***************** START OF FUNCTION PROTOS *********************/ +// ECU +#if ECU_ATTACHED_ENABLED + +static uint8_t ecuCanMsg0x2000(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2001(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2002(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2003(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2004(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2005(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2006(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2007(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2008(CanMsgTemplate *canMsg); + +static uint8_t ecuCanMsg0x2009(CanMsgTemplate *canMsg); + +#if SD_ENABLED + +uint8_t ecuAddToSdWriteRequest(CanMsgTemplate *canMsg); + +#endif // SD_ENABLED + +#endif // ECU_ATTACHED_ENABLED + +// CAN +uint8_t canSaveMsg(); + +void canAddTxRequest(uint16_t id, void *data, uint8_t lenBytes); + +void canBeginExtInterrupt(); + +uint8_t canParseRxMsg(CanMsgTemplate *canMsg); + +uint8_t canProcessRx(); + +uint8_t canProcessTx(); + +void canNoActivityResetDevice(); + +// TIMERS +#if SD_ENABLED || EMULATE_ECU || SHAFT_SPEED_SENSOR_ENABLED + +void timerBegin(uint16_t freq); + +static uint8_t timerSetupTimer3Using256Prescal(uint16_t freq); + +static uint8_t timerSetupTimer4Using256Prescal(uint16_t freq); + +static uint8_t timerSetupTimer5Using256Prescal(uint16_t freq); + +#endif // SD_ENABLED || EMULATE_ECU + +// SD +#if SD_ENABLED + +uint8_t sdBegin(); + +uint8_t sdWriteBufferBlocks(); + +uint8_t sdAddToWriteBlocks(void *pPayload, uint8_t payloadLen); + +uint8_t sdProcessWrite(); + +#endif // SD_ENABLED + +// XBEE +#if XBEE_ENABLED +uint8_t canTransmitRxToXbee() +#endif //XBEE_ENABLED + +/***************** END OF FUNCTION PROTOS *********************/ + + +/***************** START OF FUNCTIONS PTRS *********************/ +// CAN +#define CAN_ECU_MSG_0x2000_FUNC ecuCanMsg0x2000 +#define CAN_ECU_MSG_0x2001_FUNC ecuCanMsg0x2001 +#define CAN_ECU_MSG_0x2002_FUNC ecuCanMsg0x2002 +#define CAN_ECU_MSG_0x2003_FUNC ecuCanMsg0x2003 +#define CAN_ECU_MSG_0x2004_FUNC ecuCanMsg0x2004 +#define CAN_ECU_MSG_0x2005_FUNC ecuCanMsg0x2005 +#define CAN_ECU_MSG_0x2006_FUNC ecuCanMsg0x2006 +#define CAN_ECU_MSG_0x2007_FUNC ecuCanMsg0x2007 +#define CAN_ECU_MSG_0x2008_FUNC ecuCanMsg0x2008 +#define CAN_ECU_MSG_0x2009_FUNC ecuCanMsg0x2009 + +#define CAN_ECU_NUMBER_CAN_IDS 10 + +// ECU can messages function pointers for calling the corresponding function when that msg is seen. +// Used in function canParseRxMsg. +uint8_t +(*ecuCanFuncPtrs[CAN_ECU_NUMBER_CAN_IDS])(CanMsgTemplate *) = {CAN_ECU_MSG_0x2000_FUNC, CAN_ECU_MSG_0x2001_FUNC, + CAN_ECU_MSG_0x2002_FUNC, + CAN_ECU_MSG_0x2003_FUNC, + CAN_ECU_MSG_0x2004_FUNC, CAN_ECU_MSG_0x2005_FUNC, + CAN_ECU_MSG_0x2006_FUNC, + CAN_ECU_MSG_0x2007_FUNC, CAN_ECU_MSG_0x2008_FUNC, + CAN_ECU_MSG_0x2009_FUNC}; + + +// TIMERS +#if SD_ENABLED || EMULATE_ECU || SHAFT_SPEED_SENSOR_ENABLED + +#define HARDWARE_TIMER_0_BEGIN_FUNC NULL +#define HARDWARE_TIMER_1_BEGIN_FUNC NULL +#define HARDWARE_TIMER_2_BEGIN_FUNC NULL +#define HARDWARE_TIMER_3_BEGIN_FUNC timerSetupTimer3Using256Prescal +#define HARDWARE_TIMER_4_BEGIN_FUNC timerSetupTimer4Using256Prescal +#define HARDWARE_TIMER_5_BEGIN_FUNC timerSetupTimer5Using256Prescal + +// Array of pointers for calling the corresponding hardware timer setup function from the selected +// hardtimer number passed to timerBegin +uint8_t (*timerBeginFuncPtrs[6])(uint16_t) += { +HARDWARE_TIMER_0_BEGIN_FUNC, HARDWARE_TIMER_1_BEGIN_FUNC, HARDWARE_TIMER_2_BEGIN_FUNC, +HARDWARE_TIMER_3_BEGIN_FUNC, HARDWARE_TIMER_4_BEGIN_FUNC, HARDWARE_TIMER_5_BEGIN_FUNC}; + +#endif // SD_ENABLED || EMULATE_ECU || SHAFT_SPEED_SENSOR_ENABLED +/***************** END OF FUNCTIONS PTRS *********************/ + +/***************** START OF SHAFT FUNCTIONS *********************/ +#if SHAFT_SPEED_SENSOR_ENABLED + +static void shaftCheckThreshold() { + volatile uint16_t shaftVal = analogRead(SHAFT_SPEED_SENSOR_PIN); + + //Serial.print("SH "); + //Serial.println(shaftVal); + + volatile uint8_t shaftThresholdPassed = (shaftVal > SHAFT_SPEED_THRESHOLD_VALUE) ? 1 : 0; + + volatile static uint8_t shaftLastSeenThreshold = 0; + + volatile static unsigned long shaftLastPulseDetectedMs = 0; + + volatile static float shaftPrevCalcFrequencies[4] = {0, 0, 0, 0}; + + if (shaftThresholdPassed) { + if (!shaftLastSeenThreshold) { + unsigned long currMs = millis(); + + memcpy(shaftPrevCalcFrequencies, &(shaftPrevCalcFrequencies[1]), 4); + memcpy(&(shaftPrevCalcFrequencies[1]), &(shaftPrevCalcFrequencies[2]), 4); + memcpy(&(shaftPrevCalcFrequencies[2]), &(shaftPrevCalcFrequencies[3]), 4); + + shaftPrevCalcFrequencies[3] = 1000.0 / (currMs - shaftLastPulseDetectedMs); + + //Serial.print("FREQ "); + Serial.println(shaftPrevCalcFrequencies[3]); + + shaftLastCalcFrequency = + (shaftPrevCalcFrequencies[0] + shaftPrevCalcFrequencies[1] + shaftPrevCalcFrequencies[2] + + shaftPrevCalcFrequencies[3]) / 4; + +#if DEBUG_SHAFT_SPEED + //Serial.print("SHAFT : FREQ CALC "); + //Serial.println(shaftLastCalcFrequency); +#endif // DEBUG_SHAFT_SPEED + + shaftLastPulseDetectedMs = currMs; + shaftLastSeenThreshold = 1; + } + } else { + if (shaftLastSeenThreshold) { + shaftLastSeenThreshold = 0; + } + } +} + +#endif // SHAFT_SPEED_SENSOR_ENABLED + +/***************** END OF SHAFT FUNCTIONS *********************/ + +/***************** START OF ECU FUNCTIONS *********************/ +#if SD_ENABLED + +uint8_t ecuAddToSdWriteRequest(CanMsgTemplate *canMsg) { + + uint8_t ecuSdStartByte = ECU_SD_START_BYTE; + + uint8_t ecuSdEndByte = ECU_SD_END_BYTE; + + if (sdCardStatus) { + uint8_t retVal = sdAddToWriteBlocks(&ecuSdStartByte, 1); + retVal = sdAddToWriteBlocks(&(canMsg->idByte[0]), 1); + retVal = sdAddToWriteBlocks(&(canMsg->data), 8); + } + + return 1; +} + +#endif // SD_ENABLED + +static uint8_t ecuCanMsg0x2000(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2000 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2000"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t rpm = canMsg->data16[0]; +#if RPM_LEDS_ENABLED + g_RPM = rpm; +#endif + + uint16_t tpsPerc = canMsg->data16[1]; + uint16_t waterTempC = canMsg->data16[2]; + uint16_t airTempC = canMsg->data16[3]; + + Serial.println(tpsPerc); + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2001(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2001 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2001"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t mainifoldPresKpa = canMsg->data16[0]; + uint16_t lambdax1000 = canMsg->data16[1]; + uint16_t speedKphx10 = canMsg->data16[2]; + uint16_t oilPressKpa = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2002(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2002 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2002"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t fuelPressKpa = canMsg->data16[0]; + uint16_t oilTempC = canMsg->data16[1]; + uint16_t batteryVx10 = canMsg->data16[2]; + uint16_t fuelComsumLpHrx10 = canMsg->data16[3]; + + + // Serial.println((float)(batteryVx10 / 10.0)); + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2003(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2003 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2003"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t currentGear = canMsg->data16[0]; + uint16_t advanceDegx10 = canMsg->data16[1]; + uint16_t injectionTimeMsx100 = canMsg->data16[2]; + uint16_t fuelComsumLp100kMx10 = canMsg->data16[3]; + + Serial.println(currentGear); + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2004(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2004 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2004"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t ana1mV = canMsg->data16[0]; + uint16_t ana2mV = canMsg->data16[1]; + uint16_t ana3mV = canMsg->data16[2]; + uint16_t camAdvanceDegx10 = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2005(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2005 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2005"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t camTargDegx10 = canMsg->data16[0]; + uint16_t camPwmPercx10 = canMsg->data16[1]; + uint16_t crankErrorsNr = canMsg->data16[2]; + uint16_t camErrorsNr = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2006(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2006 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2006"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t cam2AdvDegx10 = canMsg->data16[0]; + uint16_t cam2TargDegx10 = canMsg->data16[1]; + uint16_t cam2PwmPercx10 = canMsg->data16[2]; + uint16_t external5VmV = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + + return 1; +} + +static uint8_t ecuCanMsg0x2007(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2007 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2007"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t injDutyCyclePerc = canMsg->data16[0]; + uint16_t lambdaPidTargPercx10 = canMsg->data16[1]; + uint16_t lambdaPidAdjPercx10 = canMsg->data16[2]; + uint16_t ecuSwitchesBitField = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2008(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2008 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2008"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t rdSpeedKphx10 = canMsg->data16[0]; + uint16_t rUdSpeedKphx10 = canMsg->data16[1]; + uint16_t ldSpeedKphx10 = canMsg->data16[2]; + uint16_t lUdSpeedKphx10 = canMsg->data16[3]; + +#if SD_ENABLED + ecuAddToSdWriteRequest(canMsg); +#endif // SD_ENABLED + + return 1; +} + +static uint8_t ecuCanMsg0x2009(CanMsgTemplate *canMsg) { +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2009 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2008"); +#endif //DEBUG_ECU_CAN_MINIMAL + + //uint16_t rightLambdax1000 = canMsg->data16[0]; + + return 1; +} + +/***************** END OF ECU FUNCTIONS *********************/ + +/***************** START OF CAN FUNCTIONS *********************/ + +uint8_t canSaveMsg() { + if (digitalRead(CAN_INT_PIN)) { + return 0; + } + + union { + uint8_t id[4]; + uint32_t id32; + } uid; + + if (can.checkReceive() != CAN_MSGAVAIL) { + return 0; + } + + CanMsgTemplate *currCanRxBufferSlot = &(canRxBuffer[canRxBufferHead]); + + if (can.readMsgBuf(&(currCanRxBufferSlot->len), currCanRxBufferSlot->data) != CAN_OK) { + return 0; + } + + uid.id32 = can.getCanId(); + + currCanRxBufferSlot->id = (uid.id[1] << 8) | uid.id[0]; + + canRxBufferHead = (canRxBufferHead + 1) % CAN_RX_BUFFER_LEN; + +#if DEBUG_CAN_RX + Serial.print("CAN SV RX: "); + + Serial.print(currCanRxBufferSlot->id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(currCanRxBufferSlot->data[i]); + Serial.print(", "); + } + Serial.println(currCanRxBufferSlot->data[7]); +#endif // DEBUG_CAN_RX + +#if DEBUG_CAN_RX + Serial.print("CAN SV RX: HEAD AT "); + Serial.println(canRxBufferHead); +#endif // DEBUG_CAN_RX + + if (canRxBufferHead == canRxBufferTail) { + canRxBufferTail = (canRxBufferTail + 1) % CAN_RX_BUFFER_LEN; + +#if DEBUG_CAN_RX || DEBUG_CAN_RX_MINIMAL + Serial.println("CAN SV RX: BUFFER FULL"); +#endif // DEBUG_CAN_RX + +#if DEBUG_CAN_RX + Serial.print("CAN SV RX: TAIL AT "); + Serial.println(canRxBufferTail); +#endif // DEBUG_CAN_RX + } + + return 1; +} + +void canAddTxRequest(uint16_t id, void *data, uint8_t lenBytes) { + data = (uint8_t *) data; + + CanMsgTemplate *currCanTxBufferSlot = &(canTxBuffer[canTxBufferHead]); + + if (NULL == data) { + return; + } + + noInterrupts(); + currCanTxBufferSlot->id = id; + + currCanTxBufferSlot->len = lenBytes; + + memcpy(currCanTxBufferSlot->data, data, lenBytes); + + interrupts(); + +#if DEBUG_CAN_TX_REQS + Serial.print("CAN TX ADD: "); + Serial.print(currCanTxBufferSlot->id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(currCanTxBufferSlot->data[i], HEX); + Serial.print(", "); + } + Serial.println(currCanTxBufferSlot->data[7], HEX); +#endif // DEBUG_CAN_TX_REQS + + noInterrupts(); + canTxBufferHead = (canTxBufferHead + 1) % CAN_TX_BUFFER_LEN; + interrupts(); + + noInterrupts(); + if (canTxBufferHead == canTxBufferTail) { + canTxBufferTail = (canTxBufferTail + 1) % CAN_TX_BUFFER_LEN; + +#if DEBUG_CAN_TX || DEBUG_CAN_TX_MINIMAL + Serial.println("CAN TX BUFFER FULL"); +#endif // DEBUG_CAN_TX + } + interrupts(); + +} + +// External interrupt currently only designed to work with atmega 2560 +#if !defined(__AVR_ATmega2560__) +#error "PLATFORM NOT SUPPORTED CURRENTLY" +#endif // !defined(atmega2560) + +#if CAN_INT_PIN != 2 +#error "CAN_INT_PIN CHANGED FROM 2" +#endif //CAN_INT_PIN != 2 + +void canBeginExtInterrupt() { + noInterrupts(); + + // On the mega 2560 pin 2 is external interrupt 4 + EIMSK &= ~(1 << INT4); + + EICRB &= ~(1 << ISC41); + //EICRB &= ~(1 << ISC40); + + EIMSK |= (1 << INT4); + + interrupts(); +} + +ISR(INT4_vect) { + + noInterrupts(); + + lastCanMsgRecTimeMs = millis(); + + canSaveMsg(); + + interrupts(); +} + +uint8_t canParseRxMsg(CanMsgTemplate *canMsg) { + if ((canMsg->id >= 0x2000) && (canMsg->id <= 0x200A)) { + // canMsg->idByte[0] holds the 0x01 in 0x2001 received can msg + // We use the sub byte of the can ecu msg to determine the corresonding function + // This removes the need for a long if statement giving significant performance boosts + return (*ecuCanFuncPtrs[canMsg->idByte[0]])(canMsg); + } + + + return 0; +} + +uint8_t canProcessRx() { + uint8_t retVal = 0; + + noInterrupts(); + canSaveMsg(); + + CanMsgTemplate *currCanRxBufferSlot = &(canRxBuffer[canRxBufferTail]); + interrupts(); + + noInterrupts(); + while (canRxBufferTail != canRxBufferHead) { + +#if DEBUG_CAN_RX + Serial.print("CAN RX: "); + + Serial.print(currCanRxBufferSlot->id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(currCanRxBufferSlot->data[i]); + Serial.print(", "); + } + Serial.println(currCanRxBufferSlot->data[7]); +#endif // DEBUG_CAN_RX + +#if DEBUG_CAN_RX_MINIMAL + Serial.print("CAN PRO RX : "); + Serial.println(currCanRxBufferSlot->id, HEX); +#endif // DEBUG_CAN_RX_MINIMAL + + retVal = canParseRxMsg(currCanRxBufferSlot); + + canRxBufferTail = (canRxBufferTail + 1) % CAN_RX_BUFFER_LEN; + +#if DEBUG_CAN_RX || DEBUG_CAN_RX_MINIMAL + Serial.print("CAN PRO RX: TAIL AT "); + Serial.println(canRxBufferTail); +#endif // DEBUG_CAN_RX || DEBUG_CAN_RX_MINIMAL + + currCanRxBufferSlot = &(canRxBuffer[canRxBufferTail]); + + // This may seem dumb but this allows any pending interrupts to be serviced safely + // just before we start another loop. Otherwise if we stay in this loop too long without + // servicing any interrupts we might miss one. + interrupts(); + noInterrupts(); + } + interrupts(); + + return retVal; +} + +uint8_t canProcessTx() { + + noInterrupts(); + CanMsgTemplate *currCanTxBufferSlot = &(canTxBuffer[canTxBufferTail]); + + uint8_t retVal = 0; + + while (canTxBufferTail != canTxBufferHead) { + +#if DEBUG_CAN_TX + Serial.print("CAN TX: "); + Serial.print(currCanTxBufferSlot->id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < (currCanTxBufferSlot->len - 1); i++) { + Serial.print(currCanTxBufferSlot->data[i]); + Serial.print(", "); + } + Serial.println(currCanTxBufferSlot->data[currCanTxBufferSlot->len - 1]); +#endif // DEBUG_CAN_TX + +#if DEBUG_CAN_TX_MINIMAL + Serial.print("CAN TX : "); + Serial.println(currCanTxBufferSlot->id, HEX); +#endif // DEBUG_CAN_TX_MINIMAL + + uint8_t canTxWasSuccessful = 0; + + for (uint8_t i = 0; i < CAN_TX_RETRY_LIMIT; i++) { + if (can.sendMsgBuf(currCanTxBufferSlot->id, 1, currCanTxBufferSlot->len, + currCanTxBufferSlot->data, true) == CAN_OK) { + + canTxBufferTail = (canTxBufferTail + 1) % CAN_TX_BUFFER_LEN; + + currCanTxBufferSlot = &(canTxBuffer[canTxBufferTail]); + + canTxWasSuccessful = 1; + + retVal = 1; + + break; + } else { + + retVal = 0; + } + } + + if (!canTxWasSuccessful) { + +#if DEBUG_CAN_TX || DEBUG_CAN_TX_MINIMAL + Serial.println("CAN TX: TX FAILED"); +#endif // DEBUG_CAN_TX || DEBUG_CAN_TX_MINIMAL + + canTxBufferTail = (canTxBufferTail + 1) % CAN_TX_BUFFER_LEN; + + currCanTxBufferSlot = &(canTxBuffer[canTxBufferTail]); + } + + // This may seem dumb but this allows any pending interrupts to be serviced safely + // just before we start another loop. Otherwise if we stay in this loop too long without + // servicing any interrupts we might miss one. + interrupts(); + noInterrupts(); + } + + interrupts(); + + return retVal; +} + +void canNoActivityResetDevice() { + Serial.println("CAN ERROR : RESETTING DEVICE"); + Serial.flush(); + +#if SD_ENABLED + + uint8_t payload[10] = {0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00}; + + sdAddToWriteBlocks(payload, 10); + + sdWriteBufferBlocks(); + +#endif //SD_ENABLED + + // Enabled watchdog timer to reset device as we will not pat it + wdt_enable(WDTO_15MS); + + while (true); + +} + +/***************** END OF CAN FUNCTIONS *********************/ + +/***************** START OF TIMER FUNCTIONS *********************/ +#if SD_ENABLED || EMULATE_ECU || SHAFT_SPEED_SENSOR_ENABLED + +// Hardware timers currently only designed to work with atmega 2560 +#if !defined(__AVR_ATmega2560__) +#error "PLATFORM NOT SUPPORTED CURRENTLY" +#endif // !defined(atmega2560) + +/* + * FOR REFERENCE: + * + * The defines here such as TCCR3A are defined in AVR backend files + * Hence, they are not defined anywhere + * + */ + +static uint8_t timerSetupTimer3Using256Prescal(uint16_t freq) { + if ((freq < 1) || (freq > 62500)) { + return 0; + } + noInterrupts(); + + TCCR3A = 0; + TCCR3B = 0; + TCNT3 = 0; + + // F_CPU is passed to the compilier by arduino so we do not defined it ourselves + // but we can access it + OCR3A = (uint16_t)(F_CPU / (256 * freq)); + + // 256 Prescaler + TCCR3B |= (1 << WGM32); + TCCR3B |= (1 << CS32); + + // Enable timer + TIMSK3 |= (1 << OCIE3A); + + interrupts(); + + return 1; +} + +static uint8_t timerSetupTimer4Using256Prescal(uint16_t freq) { + if ((freq < 1) || (freq > 62500)) { + return 0; + } + + noInterrupts(); + + TCCR4A = 0; + TCCR4B = 0; + TCNT4 = 0; + + // F_CPU is passed to the compilier by arduino so we do not defined it ourselves + // but we can access it + OCR4A = (uint16_t)(F_CPU / (256 * freq)); + + // 256 Prescaler + TCCR4B |= (1 << WGM42); + TCCR4B |= (1 << CS42); + + // Enable timer + TIMSK4 |= (1 << OCIE4A); + + interrupts(); + + return 1; +} + +static uint8_t timerSetupTimer5Using256Prescal(uint16_t freq) { + if ((freq < 1) || (freq > 62500)) { + return 0; + } + + noInterrupts(); + + TCCR5A = 0; + TCCR5B = 0; + TCNT5 = 0; + + // F_CPU is passed to the compilier by arduino so we do not defined it ourselves + // but we can access it + OCR5A = (uint16_t)(F_CPU / (256 * freq)); + + // 256 Prescaler + TCCR5B |= (1 << WGM52); + TCCR5B |= (1 << CS52); + + // Enable timer + TIMSK5 |= (1 << OCIE5A); + + interrupts(); + + return 1; +} + +uint8_t timerBegin(uint16_t freq, uint8_t hwTimerNr) { + return (*timerBeginFuncPtrs[hwTimerNr])(freq); +} + +ISR(TIMER3_COMPA_vect) { +#if EMULATE_ECU + uint16_t data[4] = { 0xFFBB, 0xAA88, 0x7799, 0xCCFF }; + + canAddTxRequest(0x2000, data, 8); + canAddTxRequest(0x2001, data, 8); + canAddTxRequest(0x2002, data, 8); + canAddTxRequest(0x2003, data, 8); + canAddTxRequest(0x2004, data, 8); + canAddTxRequest(0x2005, data, 8); + canAddTxRequest(0x2006, data, 8); + +#endif //EMULATE_ECU +} + +ISR(TIMER4_COMPA_vect) { +#if RPM_LEDS_ENABLED + if (rpmBlueFlashFlag){ + rpmBlueFlashFlag = ~rpmBlueFlashFlag; + } + +#endif // RPM_LEDS_ENABLED +} + +ISR(TIMER5_COMPA_vect) { +#if SHAFT_SPEED_SENSOR_ENABLED + + shaftCheckThreshold(); + +#endif // SHAFT_SPEED_SENSOR_ENABLED +} + +#endif // SD_ENABLED || EMULATE_ECU || SHAFT_SPEED_SENSOR_ENABLED +/***************** END OF TIMER FUNCTIONS *********************/ + +/***************** START OF SD FUNCTIONS *********************/ +#if SD_ENABLED + +uint8_t sdBegin() { + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: STARTING SD SERIAL"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + noInterrupts(); + + if (!sd.begin(SD_CS_PIN, SD_SCK_MHZ(10))) { + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); + + sd.card()->spiStop(); + interrupts(); + return 0; + } + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: STARTED SD SERIAL"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + if (sd.exists("DATA.BIN")) { + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: FILE EXISTS - REMOVING"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + if (!sd.remove("DATA.BIN")) { + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); + + sd.card()->spiStop(); + interrupts(); + return 0; + } + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: REMOVED FILE"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + } + + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: OPENING FILE"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + if (!file.open("DATA.BIN", O_WRITE | O_CREAT)) { + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); + + sd.card()->spiStop(); + interrupts(); + return 0; + } + + sd.card()->spiStop(); + interrupts(); + + Serial.println("SD: OPEN FOR WRITES"); + Serial.println("SD: !!IMPORTANT NOTICE!!"); + Serial.println("SD: SEND 's' TO STOP WRITES"); + Serial.println("SD: REMOVING SD WITHOUT STOPPING WRITES WILL CORRUPT DATA LOG FILE!"); + + sdCardStatus = 1; + + return 1; +} + +uint8_t sdProcessWrite() { + + if (Serial.available()) { + + char sdReceivedByte = Serial.read(); + + if (sdReceivedByte == 's') { + + if (!sdCardStatus) { + + Serial.println("SD: WRITES ALREADY STOPPED"); + return 0; + } + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: SHUTTING DOWN"); + Serial.flush(); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + noInterrupts(); + sd.card()->spiStart(); + sd.card()->writeStop(); + + if (!file.close()) { + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); + sd.card()->spiStop(); + interrupts(); + + Serial.println("SD: FAILED TO STOP WRITES"); + Serial.println("SD: TRY 's' AGAIN"); + return 0; + } + + sd.card()->spiStop(); + + sdCardStatus = 0; + + interrupts(); + + Serial.println("SD: WRITES STOPPED"); + + } else if (sdReceivedByte == 'g') { + + if (sdCardStatus) { + Serial.println("SD: ALREADY WRITING"); + return 0; + } + + while (!sdBegin()) { + Serial.println("SD: BEGIN FAIL"); + delay(100); + } + + sdCardStatus = 1; + } + } else { + + if (!sdCardStatus) { + return 0; + } + + noInterrupts(); + if ((millis() - lastCanMsgRecTimeMs) > 2) { + interrupts(); + + if (sdWriteBufferTail != sdWriteBufferHead) { + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.println("SD: WRITING BLOCK"); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + sdWriteBufferBlocks(); + } + } + interrupts(); + } + + return 1; +} + +uint8_t sdAddToWriteBlocks(void *pPayload, uint8_t payloadLen) { + +#if DEBUG_SD || DEBUG_SD_MINIMAL + Serial.print("SD: REQ "); + Serial.println(payloadLen); + + Serial.print("SD: BLOCK NR "); + Serial.println(sdWriteBufferHead); + Serial.flush(); +#endif //DEBUG_SD || DEBUG_SD_MINIMAL + + sdBlockTemplate *sdCurrBlock = &(sdWriteBuffer[sdWriteBufferHead]); + + uint16_t sdBytesLeftInCurrBlock = 512 - sdCurrBlock->blockHead; + +#if DEBUG_SD + Serial.print("SD: CURRENT BLOCK HEAD "); + Serial.println(sdCurrBlock->blockHead); + + Serial.print("SD: BYTES LEFT IN BLOCK "); + Serial.println(sdBytesLeftInCurrBlock); + Serial.flush(); +#endif //DEBUG_SD + + if ((payloadLen + sdCurrBlock->blockHead) <= 512) { + memcpy(&(sdCurrBlock->block[sdCurrBlock->blockHead]), pPayload, payloadLen); + + sdCurrBlock->blockHead = sdCurrBlock->blockHead + payloadLen; + +#if DEBUG_SD + Serial.print("SD: WROTE TO CURR BLOCK "); + Serial.println(payloadLen); + Serial.flush(); +#endif //DEBUG_SD + } else { +#if DEBUG_SD + Serial.print("SD: WR THIS AND NEXT BLOCK "); + Serial.println(payloadLen); + Serial.flush(); +#endif //DEBUG_SD + + uint16_t sdBytesToAddThisBlock = sdBytesLeftInCurrBlock; + uint16_t sdBytesToAddNextBlock = payloadLen - sdBytesToAddThisBlock; + +#if DEBUG_SD + Serial.print("SD: WR THIS "); + Serial.println(sdBytesLeftInCurrBlock); + Serial.print("SD: WR NEXT "); + Serial.println(sdBytesToAddNextBlock); + + Serial.flush(); +#endif //DEBUG_SD + + memcpy(&(sdCurrBlock->block[sdCurrBlock->blockHead]), pPayload, sdBytesToAddThisBlock); + + sdWriteBufferHead = (sdWriteBufferHead + 1) % SD_WRITE_BUFFER_LEN; + + sdCurrBlock = &(sdWriteBuffer[sdWriteBufferHead]); + + memcpy(&(sdCurrBlock->block), (uint8_t * )((pPayload + sdBytesToAddThisBlock) - 1), sdBytesToAddNextBlock); + + sdCurrBlock->blockHead = sdBytesToAddNextBlock; + +#if DEBUG_SD + Serial.print("SD: WROTE TO CURR BLOCK "); + Serial.println(sdBytesToAddThisBlock); + + Serial.print("SD: WROTE TO NEXT BLOCK "); + Serial.println(sdBytesToAddNextBlock); + Serial.flush(); +#endif //DEBUG_SD + + } + + return 1; +} + +uint8_t sdWriteBufferBlocks() { + + sdBlockTemplate *sdCurrBlock = &(sdWriteBuffer[sdWriteBufferTail]); + + static uint8_t sdBlocksBeforeSync = 0; + + static uint32_t sdTotalBlocksWrittenToCard = 0; + + noInterrupts(); + sd.card()->spiStart(); + + if (!(file.write(sdCurrBlock->block, 512))) { + return 0; + } + + sd.card()->spiStop(); + noInterrupts(); + + if (sdBlocksBeforeSync >= 2) { + noInterrupts(); + sd.card()->spiStart(); + + file.flush(); + + sd.card()->spiStop(); + noInterrupts(); + + sdBlocksBeforeSync = 0; + } + +#if SD_SERIAL_PRINT_BLOCK_WRITES + Serial.print("SD: BL WR "); + Serial.println(sdTotalBlocksWrittenToCard); +#endif // SD_SERIAL_PRINT_BLOCK_WRITES + + sdBlocksBeforeSync++; + + sdCurrBlock->blockHead = 0; + + sdTotalBlocksWrittenToCard++; + + sdWriteBufferTail = (sdWriteBufferTail + 1) % SD_WRITE_BUFFER_LEN; + + + return 1; +} + +#endif // SD_ENABLED +/***************** END OF SD/EMULATE ECU FUNCTIONS *********************/ + +/***************** START OF XBEE FUNCTIONS *********************/ +#if XBEE_ENABLED + +uint8_t canTransmitRxToXbee() +{ + if (digitalRead(XBEE_CTS_PIN)) { + return 0; + } + + noInterrupts(); + + while (canRxBufferTail != canRxBufferHead) { + + xbeeTx64Request.setPayload(canRxBuffer[canRxBufferTail].data); + xbeeTx64Request.setPayloadLength(canRxBuffer[canRxBufferTail].len); + + xbee.send(xbeeTx64Request); + + canRxBufferTail = (canRxBufferTail + 1) % CAN_RX_BUFFER_LEN; + + if (digitalRead(XBEE_CTS_PIN)) { + interrupts(); + return 0; + } + + // This may seem dumb but this allows any pending interrupts to be serviced safely + // just before we start another loop. Otherwise if we stay in this loop too long without + // servicing any interrupts we might miss one. + interrupts(); + noInterrupts(); + + } + + interrupts(); + + return 1; +} + +#endif //XBEE_ENABLED +/***************** END OF XBEE FUNCTIONS *********************/ +/***************** START OF RPM LED FUNCTIONS *********************/ + +/***************** END OF RPM LED FUNCTIONS *********************/ +#if RPM_LEDS_ENABLED + +void rpmBegin() { + pinMode(RPM1_PIN, OUTPUT); + pinMode(RPM2_PIN, OUTPUT); + pinMode(RPM3_PIN, OUTPUT); + pinMode(RPM4_PIN, OUTPUT); + pinMode(RPM5_PIN, OUTPUT); + timerBegin(4, 4); +} + +void rpmProcessLEDS() { + //Use g_RPM to set LED INDICATORS + //for testing change rpm to tps for testing :) + if (g_RPM > RED1_THRESHOLD) //RED ONE + { + //TURN ON + digitalWrite(RPM1_PIN, 1); + //TURN OFF + digitalWrite(RPM2_PIN, 0); + digitalWrite(RPM3_PIN, 0); + digitalWrite(RPM4_PIN, 0); + digitalWrite(RPM5_PIN, 0); + + + } else if (g_RPM > RED2_THRESHOLD) { //RED TWO + //TURN ON + digitalWrite(RPM1_PIN, 1); + digitalWrite(RPM2_PIN, 1); + //TURN OFF + digitalWrite(RPM3_PIN, 0); + digitalWrite(RPM4_PIN, 0); + digitalWrite(RPM5_PIN, 0); + digitalWrite(UPSHIT_PIN, 0); + } else if (g_RPM > GREEN1_THRESHOLD) { + //TURN ON + digitalWrite(RPM1_PIN, 1); + digitalWrite(RPM2_PIN, 1); + digitalWrite(RPM3_PIN, 1); + //TURN OFF + digitalWrite(RPM4_PIN, 0); + digitalWrite(RPM5_PIN, 0); + digitalWrite(UPSHIT_PIN, 0); + } else if (g_RPM > GREEN2_THRESHOLD) { + //TURN ON + digitalWrite(RPM1_PIN, 1); + digitalWrite(RPM2_PIN, 1); + digitalWrite(RPM3_PIN, 1); + digitalWrite(RPM4_PIN, 1); + //TURN OFF + digitalWrite(RPM5_PIN, 0); + digitalWrite(UPSHIT_PIN, 0); + + } else if (g_RPM > GREEN3_THRESHOLD) { + digitalWrite(RPM1_PIN, 1); + digitalWrite(RPM2_PIN, 1); + digitalWrite(RPM3_PIN, 1); + digitalWrite(RPM4_PIN, 1); + digitalWrite(RPM5_PIN, 1); + digitalWrite(UPSHIT_PIN, 0); + + + } else if (g_RPM > UPSHIT_THRESHOLD) { + if (rpmBlueFlashFlag) { + digitalWrite(UPSHIT_PIN, 1); + } else + digitalWrite(UPSHIT_PIN, 0); + digitalWrite(RPM1_PIN, 0); + digitalWrite(RPM2_PIN, 0); + digitalWrite(RPM3_PIN, 0); + digitalWrite(RPM4_PIN, 0); + digitalWrite(RPM5_PIN, 0); + } +} + +#endif // RPM_LEDS_ENABLED + +/***************** START OF ARDUINO FUNCTIONS *********************/ +void setup() { + Serial.begin(230400); + + Serial.println("~~~~ BEGIN PROGRAM ~~~~"); + + pinMode(CAN_INT_PIN, INPUT_PULLUP); + + can.init_CS(CAN_CS_PIN); + + while (can.begin(CAN_1000KBPS) != CAN_OK) { + Serial.println("CAN : INIT FAIL"); + delay(100); + } + +//#if SD_ENABLED +// while (!sdBegin()) { +// Serial.println("SD: BEGIN FAIL"); +// delay(100); +// } +//#endif //SD_ENABLED + +#if SD_ENABLED + Serial.println("SD: SEND 'g' TO START WRITES"); +#endif //SD_ENABLED + +#if EMULATE_ECU + timerBegin(50, 3); +#endif //EMULATE_CAN + +#if SHAFT_SPEED_SENSOR_ENABLED + timerBegin(1000, SHAFT_HARDWARE_TIMER_NR); +#endif // SHAFT_SPEED_SENSOR_ENABLED + +#if XBEE_ENABLED + xbee.setSerial(Serial); + + pinMode(XBEE_CTS_PIN, INPUT); + + pinMode(XBEE_RTS_PIN, OUTPUT); + + digitalWrite(XBEE_RTS_PIN, LOW); +#endif //XBEE_ENABLED + + canBeginExtInterrupt(); + + // Initial read to get current ms + lastCanMsgRecTimeMs = millis(); + + wdt_enable(WDTO_1S); +} + +void loop() { + // put your main code here, to run repeatedly: + + canProcessRx(); + canProcessTx(); + +#if SD_ENABLED + sdProcessWrite(); +#endif // SD_ENABLED + + wdt_reset(); + +} diff --git a/Legacy-firmware/sufst-openlogger/.idea/codeStyles/Project.xml b/Legacy-firmware/sufst-openlogger/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..a7d5539 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/codeStyles/Project.xml @@ -0,0 +1,76 @@ +<component name="ProjectCodeStyleConfiguration"> + <code_scheme name="Project" version="173"> + <Objective-C> + <option name="INDENT_NAMESPACE_MEMBERS" value="0" /> + <option name="INDENT_C_STRUCT_MEMBERS" value="2" /> + <option name="INDENT_CLASS_MEMBERS" value="2" /> + <option name="INDENT_VISIBILITY_KEYWORDS" value="1" /> + <option name="INDENT_INSIDE_CODE_BLOCK" value="2" /> + <option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" /> + <option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" /> + <option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_PARAMETERS_WRAP" value="5" /> + <option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" /> + <option name="CLASS_CONSTRUCTOR_INIT_LIST_WRAP" value="5" /> + <option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" /> + <option name="HEADER_GUARD_STYLE_PATTERN" value="${PROJECT_NAME}_${PROJECT_REL_PATH}_${FILE_NAME}_${EXT}_" /> + <option name="NAMESPACES_NAMING_CONVENTION"> + <value prefix="" style="SNAKE_CASE" suffix="" /> + </option> + <option name="CLASSES_AND_STRUCTS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="ENUMS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="ENUMERATORS_NAMING_CONVENTION"> + <value prefix="" style="SCREAMING_SNAKE_CASE" suffix="" /> + </option> + <option name="TYPEDEFS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="UNIONS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="METHODS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="FIELDS_NAMING_CONVENTION"> + <value prefix="" style="SNAKE_CASE" suffix="_" /> + </option> + <option name="GLOBAL_FUNCTIONS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="GLOBAL_VARIABLES_NAMING_CONVENTION"> + <value prefix="" style="SNAKE_CASE" suffix="" /> + </option> + <option name="PARAMETERS_NAMING_CONVENTION"> + <value prefix="" style="SNAKE_CASE" suffix="" /> + </option> + <option name="LOCAL_VARIABLES_NAMING_CONVENTION"> + <value prefix="" style="SNAKE_CASE" suffix="" /> + </option> + </Objective-C> + <codeStyleSettings language="ObjectiveC"> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> + <option name="BLANK_LINES_BEFORE_IMPORTS" value="0" /> + <option name="BLANK_LINES_AFTER_IMPORTS" value="0" /> + <option name="BLANK_LINES_AROUND_CLASS" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" /> + <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" /> + <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> + <option name="FOR_STATEMENT_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="4" /> + </indentOptions> + </codeStyleSettings> + </code_scheme> +</component> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/codeStyles/codeStyleConfig.xml b/Legacy-firmware/sufst-openlogger/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> + </state> +</component> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/misc.xml b/Legacy-firmware/sufst-openlogger/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="JavaScriptSettings"> + <option name="languageLevel" value="ES6" /> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/modules.xml b/Legacy-firmware/sufst-openlogger/.idea/modules.xml new file mode 100644 index 0000000..72d5b8a --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/sufst-openlogger.iml" filepath="$PROJECT_DIR$/.idea/sufst-openlogger.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/sufst-openlogger.iml b/Legacy-firmware/sufst-openlogger/.idea/sufst-openlogger.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/sufst-openlogger.iml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="CPP_MODULE" version="4"> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/vcs.xml b/Legacy-firmware/sufst-openlogger/.idea/vcs.xml new file mode 100644 index 0000000..64713b8 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/vcs.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$/../.." vcs="Git" /> + <mapping directory="$PROJECT_DIR$/.." vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/.idea/workspace.xml b/Legacy-firmware/sufst-openlogger/.idea/workspace.xml new file mode 100644 index 0000000..103382c --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/.idea/workspace.xml @@ -0,0 +1,329 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true"> + <generated /> + </component> + <component name="CMakeSettings"> + <configurations> + <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" /> + </configurations> + </component> + <component name="ChangeListManager"> + <list default="true" id="81322c4e-6adb-4223-9d00-22249012da89" name="Default Changelist" comment=""> + <change afterPath="$PROJECT_DIR$/../../sufst-controller/daq.cpp" afterDir="false" /> + <change afterPath="$PROJECT_DIR$/../../sufst-controller/daq.h" afterDir="false" /> + <change afterPath="$PROJECT_DIR$/../../sufst-controller/sd.cpp" afterDir="false" /> + <change afterPath="$PROJECT_DIR$/../../sufst-controller/sd.h" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-can-sd-xbee/sufst-can-sd-xbee.ino" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-controller/dashController.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../../sufst-controller/dashController.cpp" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-controller/ecuCan.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../../sufst-controller/ecuCan.cpp" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-controller/ecuOpenloggerTags.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-controller/openLoggerController.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-controller/openLoggerController.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/codeStyles/Project.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/codeStyles/codeStyleConfig.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/misc.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/modules.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/sufst-openlogger.iml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/vcs.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/.idea/workspace.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/buffer.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/buffer.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/openLogger.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/openLogger.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger/sufst-openlogger.ino" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/codeStyles/Project.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/codeStyles/codeStyleConfig.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/misc.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/modules.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/sufst-openlogger_controller.iml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/vcs.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/.idea/workspace.xml" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/buffer.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/buffer.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/can.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/can.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/ecuCan.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/ecuCan.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/ecuOpenloggerTags.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/openLoggerController.cpp" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/openLoggerController.h" beforeDir="false" /> + <change beforePath="$PROJECT_DIR$/../../sufst-openlogger_controller/sufst-openlogger_controller.ino" beforeDir="false" /> + </list> + <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> + <option name="SHOW_DIALOG" value="false" /> + <option name="HIGHLIGHT_CONFLICTS" value="true" /> + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> + <option name="LAST_RESOLUTION" value="IGNORE" /> + </component> + <component name="ClangdSettings"> + <option name="formatViaClangd" value="false" /> + </component> + <component name="FavoritesManager"> + <favorites_list name="sufst-openlogger" /> + </component> + <component name="FileEditorManager"> + <leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/sufst-openlogger.ino"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="238"> + <caret line="14" column="6" lean-forward="true" selection-start-line="14" selection-start-column="6" selection-end-line="14" selection-end-column="6" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/buffer.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="647"> + <caret line="128" selection-start-line="128" selection-end-line="128" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="true"> + <entry file="file://$PROJECT_DIR$/openLogger.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="1170"> + <caret line="432" column="1" selection-start-line="432" selection-start-column="1" selection-end-line="432" selection-end-column="1" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/openLogger.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="442"> + <caret line="26" selection-start-line="26" selection-end-line="26" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/buffer.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="527"> + <caret line="31" column="5" selection-start-line="31" selection-start-column="5" selection-end-line="31" selection-end-column="5" /> + </state> + </provider> + </entry> + </file> + </leaf> + </component> + <component name="FindInProjectRecents"> + <findStrings> + <find>Read</find> + <find>Write</find> + <find>UartCir</find> + <find>1</find> + <find>Fast</find> + <find>sdUartByte</find> + <find>cirBuffer</find> + <find>SerialE</find> + <find>Begin</find> + <find>openloggerWriteBufferBlocks</find> + <find>cir</find> + <find>fast</find> + <find>start</find> + <find>begin</find> + <find>close</find> + <find>SERIAL</find> + <find>OPENLOGGER_INFO_WRITES_STARTED</find> + <find>OPENLOGGER_UART_STOP_BYTE</find> + <find>openloggerInformMaster</find> + <find>Serial</find> + <find>sdRx</find> + <find>uartTxBufferUsedCapacity</find> + <find>openloggerBeginSd</find> + <find>wdt</find> + <find>[</find> + <find>bein</find> + <find>unitSizeBytes</find> + <find>sdB</find> + <find>sdBufferUsedBytes</find> + <find>write</find> + </findStrings> + <replaceStrings> + <replace>DEBUG_OPENLOGGER</replace> + <replace>rxUartByte</replace> + <replace>uartStopByte</replace> + <replace>sdRxBufferUsedCapacity</replace> + <replace>unitSize</replace> + </replaceStrings> + </component> + <component name="Git.Settings"> + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." /> + </component> + <component name="IdeDocumentHistory"> + <option name="CHANGED_PATHS"> + <list> + <option value="$PROJECT_DIR$/circularBuffer.h" /> + <option value="$PROJECT_DIR$/circularBuffer.cpp" /> + <option value="$PROJECT_DIR$/sufst-openlogger.ino" /> + <option value="$PROJECT_DIR$/buffer.h" /> + <option value="$PROJECT_DIR$/openLogger.h" /> + <option value="$PROJECT_DIR$/buffer.cpp" /> + <option value="$PROJECT_DIR$/openLogger.cpp" /> + </list> + </option> + </component> + <component name="OCFindUsagesOptions" text="true" ivars="false" properties="true" derivedClasses="false" /> + <component name="ProjectFrameBounds"> + <option name="x" value="-8" /> + <option name="width" value="977" /> + <option name="height" value="1038" /> + </component> + <component name="ProjectLevelVcsManager" settingsEditedManually="true" /> + <component name="ProjectView"> + <navigator proportions="" version="1"> + <foldersAlwaysOnTop value="true" /> + </navigator> + <panes> + <pane id="Scope" /> + <pane id="ProjectPane"> + <subPane> + <expand> + <path> + <item name="sufst-openlogger" type="b2602c69:ProjectViewProjectNode" /> + <item name="sufst-openlogger" type="462c0819:PsiDirectoryNode" /> + </path> + </expand> + <select /> + </subPane> + </pane> + </panes> + </component> + <component name="PropertiesComponent"> + <property name="ASKED_SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> + <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> + <property name="WebServerToolWindowFactoryState" value="false" /> + <property name="last_opened_file_path" value="$PROJECT_DIR$/../sufst-openlogger_controller" /> + <property name="node.js.detected.package.eslint" value="true" /> + <property name="node.js.detected.package.tslint" value="true" /> + <property name="node.js.path.for.package.eslint" value="project" /> + <property name="node.js.path.for.package.tslint" value="project" /> + <property name="node.js.selected.package.eslint" value="(autodetect)" /> + <property name="node.js.selected.package.tslint" value="(autodetect)" /> + <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" /> + <property name="nodejs_npm_path_reset_for_default_project" value="true" /> + <property name="nodejs_package_manager_path" value="npm" /> + <property name="run.code.analysis.last.selected.profile" value="pProject Default" /> + <property name="settings.editor.selected.configurable" value="project.propVCSSupport.Mappings" /> + </component> + <component name="RunDashboard"> + <option name="ruleStates"> + <list> + <RuleState> + <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> + </RuleState> + <RuleState> + <option name="name" value="StatusDashboardGroupingRule" /> + </RuleState> + </list> + </option> + </component> + <component name="SvnConfiguration"> + <configuration /> + </component> + <component name="TaskManager"> + <task active="true" id="Default" summary="Default task"> + <changelist id="81322c4e-6adb-4223-9d00-22249012da89" name="Default Changelist" comment="" /> + <created>1563140776084</created> + <option name="number" value="Default" /> + <option name="presentableId" value="Default" /> + <updated>1563140776084</updated> + <workItem from="1563140777259" duration="246000" /> + <workItem from="1563216461708" duration="10620000" /> + <workItem from="1563385421018" duration="9848000" /> + <workItem from="1563401015844" duration="2752000" /> + <workItem from="1563476541945" duration="26985000" /> + <workItem from="1564136510712" duration="2720000" /> + </task> + <servers /> + </component> + <component name="TimeTrackingManager"> + <option name="totallyTimeSpent" value="80706000" /> + </component> + <component name="ToolWindowManager"> + <frame x="-6" y="0" width="781" height="830" extended-state="0" /> + <editor active="true" /> + <layout> + <window_info content_ui="combo" id="Project" order="0" sideWeight="0.49426934" weight="0.40638003" /> + <window_info id="Structure" order="1" sideWeight="0.5057307" side_tool="true" weight="0.40638003" /> + <window_info id="Favorites" order="2" side_tool="true" weight="0.32916266" /> + <window_info anchor="bottom" id="Message" order="0" /> + <window_info anchor="bottom" id="Find" order="1" /> + <window_info anchor="bottom" id="Run" order="2" /> + <window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> + <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> + <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> + <window_info anchor="bottom" id="TODO" order="6" /> + <window_info anchor="bottom" id="Database Changes" order="7" /> + <window_info anchor="bottom" id="Version Control" order="8" /> + <window_info anchor="bottom" id="Terminal" order="9" /> + <window_info anchor="bottom" id="Event Log" order="10" side_tool="true" /> + <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" /> + <window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> + <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> + <window_info anchor="right" id="Database" order="3" /> + </layout> + </component> + <component name="TypeScriptGeneratedFilesManager"> + <option name="version" value="1" /> + </component> + <component name="editorHistoryManager"> + <entry file="file://$PROJECT_DIR$/circularBuffer.cpp" /> + <entry file="file://$PROJECT_DIR$/circularBuffer.h" /> + <entry file="file://$PROJECT_DIR$/buffer.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="647"> + <caret line="128" selection-start-line="128" selection-end-line="128" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/buffer.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="527"> + <caret line="31" column="5" selection-start-line="31" selection-start-column="5" selection-end-line="31" selection-end-column="5" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/sufst-openlogger.ino"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="238"> + <caret line="14" column="6" lean-forward="true" selection-start-line="14" selection-start-column="6" selection-end-line="14" selection-end-column="6" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/openLogger.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="442"> + <caret line="26" selection-start-line="26" selection-end-line="26" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/openLogger.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="1170"> + <caret line="432" column="1" selection-start-line="432" selection-start-column="1" selection-end-line="432" selection-end-column="1" /> + </state> + </provider> + </entry> + </component> + <component name="masterDetails"> + <states> + <state key="ScopeChooserConfigurable.UI"> + <settings> + <splitter-proportions> + <option name="proportions"> + <list> + <option value="0.2" /> + </list> + </option> + </splitter-proportions> + </settings> + </state> + </states> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/buffer.cpp b/Legacy-firmware/sufst-openlogger/buffer.cpp new file mode 100644 index 0000000..ad56e02 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/buffer.cpp @@ -0,0 +1,135 @@ +// +// Created by Sil on 7/19/2019. +// + +#include "buffer.h" + +uint8_t cirBufferBegin(cirBuffer_handle cirBuff, void *data, uint16_t len, uint8_t unitSize) +{ + + if (cirBuff == NULL) { + return 0; + } + + if (data == NULL) { + return 0; + } + + cirBuff->head = 0; + cirBuff->tail = 0; + cirBuff->capacity = len; + cirBuff->full = 0; + cirBuff->data = (uint8_t *) data; + cirBuff->unitSize = unitSize; + + return 1; +} + +uint16_t cirBufferAvailable(cirBuffer_handle cirBuff) +{ + if (!cirBuff->full) { + if (cirBuff->head >= cirBuff->tail) { + return (cirBuff->head - cirBuff->tail); + } + else { + return (cirBuff->capacity + cirBuff->head - cirBuff->tail); + } + } + else { + return cirBuff->capacity; + } +} + +uint16_t cirBufferAvailableForWrite(cirBuffer_handle cirBuff) +{ + return cirBuff->capacity - cirBufferAvailable(cirBuff); +} + +void cirBufferWrite(cirBuffer_handle cirBuff, void *unit) +{ + + + memcpy(&(cirBuff->data[cirBuff->head * cirBuff->unitSize]), unit, cirBuff->unitSize); + + ++cirBuff->head &= (cirBuff->capacity - 1); + + if (cirBuff->head == cirBuff->tail) { + cirBuff->full = 1; + + ++cirBuff->tail &= (cirBuff->capacity - 1); + } +} + +void cirBufferWriteBytes(cirBuffer_handle cirBuff, void *src, uint16_t len) +{ + uint16_t head = cirBuff->head; + uint16_t andOperator = cirBuff->capacity - 1; + + uint16_t remainingBytes = cirBufferAvailableForWrite(cirBuff); + + if ((remainingBytes + len) >= cirBuff->capacity) { + cirBuff->full = 1; + } + + for (uint16_t i = 0; i < len; i++) { + cirBuff->data[head] = ((uint8_t *) src)[i]; + + ++head &= andOperator; + } + + if (cirBuff->full) { + cirBuff->tail = (cirBuff->tail + (len - (cirBuff->capacity - remainingBytes))) & (cirBuff->capacity - 1); + + } + + cirBuff->head = head; + cirBuff->full = 0; +} + +uint8_t *cirBufferExternalWrite(cirBuffer_handle cirBuff) +{ + uint8_t *head = &(cirBuff->data[cirBuff->head]); + + ++cirBuff->head &= cirBuff->capacity - 1; + + if (cirBuff->head == cirBuff->tail) { + cirBuff->full = 1; + + ++cirBuff->tail &= (cirBuff->capacity - 1); + } + + return head; +} + +void cirBufferRead(cirBuffer_handle cirBuff, void *loc) +{ + + memcpy(loc, &(cirBuff->data[cirBuff->tail * cirBuff->unitSize]), cirBuff->unitSize); + + ++cirBuff->tail &= (cirBuff->capacity - 1); + + cirBuff->full = 0; + +} + +void cirBufferReadBytes(cirBuffer_handle cirBuff, void *loc, uint16_t len) +{ + uint16_t tail = cirBuff->tail; + uint16_t andOperator = cirBuff->capacity - 1; + + for (uint16_t i = 0; i < len; i++) { + ((uint8_t *) loc)[i] = cirBuff->data[tail]; + + ++tail &= andOperator; + } + + cirBuff->tail = tail; + cirBuff->full = 0; +} + +void cirBufferReset(cirBuffer_handle cirBuff) +{ + cirBuff->head = 0; + cirBuff->tail = 0; + cirBuff->full = 0; +} diff --git a/Legacy-firmware/sufst-openlogger/buffer.h b/Legacy-firmware/sufst-openlogger/buffer.h new file mode 100644 index 0000000..f05bf2b --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/buffer.h @@ -0,0 +1,42 @@ +// +// Created by Sil on 7/19/2019. +// + +#ifndef BUFFER_H +#define BUFFER_H + +#include "Arduino.h" + +typedef struct CirBuffer +{ + uint16_t head; + uint16_t tail; + uint8_t full; + uint8_t *data; + uint16_t capacity; + uint8_t unitSize; +}; + +typedef CirBuffer *cirBuffer_handle; + +/* + * THE LEN OF THE BUFFER MUST BE A POWER OF 2 + */ + +uint8_t cirBufferBegin(cirBuffer_handle cirBuff, void *data, uint16_t len, uint8_t unitSize); + +uint16_t cirBufferAvailable(cirBuffer_handle cirBuff); + +uint16_t cirBufferAvailableForWrite(cirBuffer_handle cirBuff); + +void cirBufferWrite(cirBuffer_handle cirBuff, void *unit); + +uint8_t *cirBufferExternalWrite(cirBuffer_handle cirBuff); + +void cirBufferRead(cirBuffer_handle cirBuff, void *loc); + +void cirBufferReadBytes(cirBuffer_handle cirBuff, void *loc, uint16_t len); + +void cirBufferReset(cirBuffer_handle cirBuff); + +#endif //BUFFER_H diff --git a/Legacy-firmware/sufst-openlogger/openLogger.cpp b/Legacy-firmware/sufst-openlogger/openLogger.cpp new file mode 100644 index 0000000..a687d6c --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/openLogger.cpp @@ -0,0 +1,433 @@ +// +// Created by Sil on 14/07/2019. +// + +#include "openLogger.h" + +#include <avr/wdt.h> +#include <avr/interrupt.h> +#include "buffer.h" + +#include <SdFat.h> + +SdFat sd; + +SdFile file; + +#if DEBUG_OPENLOGGER +enum +{ + uartStartByte = 's', + uartStopByte = 'f' +}; + +enum +{ + uartTypeData = 'd', + uartTypeCommand = 'c', + uartTypeInfo = 'i' +}; + +enum +{ + uartCommandStartWrites = 'v', + uartCommandStopWrites = 'b' +}; + +enum +{ + uartInfoAlreadyRunning = '1', + uartInfoAlreadyIdle = '2', + uartInfoWritesStarted = '3', + uartInfoWritesStartError = '4', + uartInfoStopped = '5', + uartInfoStopError = '6', + uartInfoWriteError = '7', + uartInfoWritesNotStarted = '8' +}; +#else +enum +{ + uartStartByte = 's', + uartStopByte = 'f' +}; + +enum +{ + uartTypeData = 0, + uartTypeCommand, + uartTypeInfo +}; + +enum +{ + uartCommandStartWrites = 0, + uartCommandStopWrites +}; + +enum +{ + uartInfoAlreadyRunning = 0, + uartInfoAlreadyIdle, + uartInfoWritesStarted, + uartInfoWritesStartError, + uartInfoStopped, + uartInfoStopError, + uartInfoWriteError, + uartInfoWritesNotStarted +}; +#endif // DEBUG_OPENLOGGER + +typedef enum +{ + idle = 0, + starting, + running, + stopping +} OpenloggerState; + +typedef enum +{ + checkingForStart = 0, + checkingForType, + checkingForLength, + receivingData, + checkingForCommand +} UartRxState; + +uint8_t openloggerBeginSd(); + +void uartCheckingForStartByte(); + +void uartCheckingForType(); + +void uartCheckingForLength(); + +void uartReceivingData(); + +void uartCheckingForCommand(); + +void openloggerIdle(); + +void openloggerStarting(); + +void openloggerRunning(); + +void openloggerStopping(); + +void openloggerInformMaster(uint8_t info); + +void watchdogBegin500ms(); + +OpenloggerState openloggerState = idle; + +UartRxState uartRxState = checkingForStart; + +uint8_t sdBuffer[OPENLOGGER_WRITE_BUFFER_LEN]; + +CirBuffer sdCirBuffer; + +void (*openloggerState_ptrs[4])(void) = {openloggerIdle, openloggerStarting, openloggerRunning, openloggerStopping}; + +void +(*uartRxState_ptrs[5])(void) = {uartCheckingForStartByte, uartCheckingForType, uartCheckingForLength, uartReceivingData, + uartCheckingForCommand}; + +volatile uint8_t uartExpectedDataLength = 0; + +uint8_t openloggerLastSeenCommand = 0; + +bool ledStatus = false; + +void serialEvent() +{ + + wdt_reset(); + + uartRxState_ptrs[uartRxState](); +} + +ISR(WDT_vect) { + uartRxState = checkingForStart; +} + +void uartCheckingForStartByte() +{ + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING START "); + Serial.println((char) Serial.peek()); +#endif // DEBUG_OPENLOGGER + + if (Serial.read() == uartStartByte) { + uartRxState = checkingForType; + } +} + +void uartCheckingForType() +{ +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING FOR TYPE "); + Serial.println((char) Serial.peek()); +#endif // DEBUG_OPENLOGGER + + if (Serial.peek() <= uartTypeInfo) { + uartRxState = (Serial.read() == uartTypeData) ? checkingForLength : checkingForCommand; + } +} + +void uartCheckingForLength() +{ + if (openloggerState != running) { +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: NOT running"); +#endif // DEBUG_OPENLOGGER + + openloggerInformMaster(uartInfoWritesNotStarted); + + uartRxState = checkingForStart; + + return; + } + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING LENGTH "); + Serial.println((char) Serial.peek()); +#endif // DEBUG_OPENLOGGER + + if (Serial.peek() <= OPENLOGGER_WRITE_BUFFER_LEN) { + uartExpectedDataLength = Serial.read(); + + uartRxState = receivingData; + } + else { + uartRxState = checkingForStart; + } +} + +void uartReceivingData() +{ + for (; uartExpectedDataLength > 0; uartExpectedDataLength--) { + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: LEFT "); + Serial.println(uartExpectedDataLength); +#endif // DEBUG_OPENLOGGER + + Serial.readBytes(cirBufferExternalWrite(&sdCirBuffer), 1); + } + + uartRxState = checkingForStart; +} + +void uartCheckingForCommand() +{ +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING COMMAND "); + Serial.println((char) Serial.peek()); +#endif // DEBUG_OPENLOGGER + + openloggerState = (Serial.read() == uartCommandStartWrites) ? starting : stopping; + + uartRxState = checkingForStart; +} + +void openloggerIdle() +{ + +} + +void openloggerStarting() +{ +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: starting WRITES"); +#endif // DEBUG_OPENLOGGER + + if (openloggerBeginSd()) { + + if (!ledStatus) { + digitalWrite(5, HIGH); + + ledStatus = true; + } + + openloggerInformMaster(uartInfoWritesStarted); + + openloggerState = running; + } + else { + openloggerInformMaster(uartInfoWritesStartError); + + openloggerState = idle; + } +} + +void openloggerRunning() +{ + static uint8_t sdPayload[OPENLOGGER_BYTES_PER_BLOCK_WRITE]; + + if (cirBufferAvailable(&sdCirBuffer) >= OPENLOGGER_BYTES_PER_BLOCK_WRITE) { + +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: WRITING BLOCK"); +#endif // DEBUG_OPENLOGGER + + static uint8_t sdBlocksWritten = 0; + + cirBufferReadBytes(&sdCirBuffer, sdPayload, OPENLOGGER_BYTES_PER_BLOCK_WRITE); + + if (!file.write(sdPayload, OPENLOGGER_BYTES_PER_BLOCK_WRITE)) { + + openloggerInformMaster(uartInfoWriteError); + + openloggerState = stopping; + } + + sdBlocksWritten++; + + if (sdBlocksWritten >= OPENLOGGER_BLOCKS_BEFORE_FLUSH) { + file.flush(); + + sdBlocksWritten = 0; + } + } +} + +void openloggerStopping() +{ +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: stopping "); +#endif // DEBUG_OPENLOGGER + + if (file.close()) { + + openloggerInformMaster(uartInfoStopped); + } + else { + + openloggerInformMaster(uartInfoStopError); + } + + openloggerState = idle; + + if (ledStatus) { + digitalWrite(5, LOW); + + ledStatus = false; + } + +} + +void openloggerProcess() +{ + openloggerState_ptrs[openloggerState](); +} + +uint8_t openloggerBegin() +{ + + Serial.begin(OPENLOGGER_SERIAL_BUAD_RATE); + +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: BEGIN"); + + Serial.setTimeout((uint32_t)(-1)); +#endif // DEBUG_OPENLOGGER + +#if !DEBUG_OPENLOGGER + watchdogBegin500ms(); +#endif // !DEBUG_OPENLOGGER + + pinMode(5, OUTPUT); + + digitalWrite(5, LOW); + + cirBufferBegin(&sdCirBuffer, sdBuffer, OPENLOGGER_WRITE_BUFFER_LEN, sizeof(uint8_t)); + + return 1; +} + +void openloggerInformMaster(uint8_t info) +{ + Serial.write(uartStartByte); + Serial.write(uartTypeInfo); + Serial.write(info); + Serial.write(uartStopByte); +} + +void watchdogBegin500ms() +{ + cli(); + + WDTCSR = (1 << WDCE) | (1 << WDE); + WDTCSR = 0; + + WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP0); + + sei(); +} + +uint8_t openloggerBeginSd() +{ + +#if DEBUG_OPENLOGGER + Serial.println("SD: starting SD SERIAL"); +#endif //DEBUG_OPENLOGGER + + noInterrupts(); + + if (!sd.begin(OPENLOGGER_CS_PIN, SD_SCK_MHZ(10))) { + +#if DEBUG_OPENLOGGER + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); +#endif // DEBUG_OPENLOGGER + + interrupts(); + return 0; + } + +#if DEBUG_OPENLOGGER + Serial.println("SD: STARTED SD SERIAL"); +#endif //DEBUG_OPENLOGGER + + if (sd.exists("DATA.BIN")) { + +#if DEBUG_OPENLOGGER + Serial.println("SD: FILE EXISTS - REMOVING"); +#endif //DEBUG_OPENLOGGER + + if (!sd.remove("DATA.BIN")) { + +#if DEBUG_OPENLOGGER + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); +#endif // DEBUG_OPENLOGGER + + interrupts(); + return 0; + } + +#if DEBUG_OPENLOGGER + Serial.println("SD: REMOVED FILE"); +#endif //DEBUG_OPENLOGGER + } + +#if DEBUG_OPENLOGGER + Serial.println("SD: OPENING FILE"); +#endif //DEBUG_OPENLOGGER + + if (!file.open("DATA.BIN", O_WRITE | O_CREAT)) { +#if DEBUG_OPENLOGGER + Serial.print("SD: ERROR "); + Serial.println(sd.card()->errorCode(), HEX); +#endif // DEBUG_OPENLOGGER + + interrupts(); + return 0; + } + + interrupts(); + + return 1; +} \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger/openLogger.h b/Legacy-firmware/sufst-openlogger/openLogger.h new file mode 100644 index 0000000..281500a --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/openLogger.h @@ -0,0 +1,53 @@ +// +// Created by Sil on 14/07/2019. +// + +#ifndef SUFST_OPENLOGGER_INO_SDCARD_H +#define SUFST_OPENLOGGER_INO_SDCARD_H + +#include "Arduino.h" + +#define DEBUG_OPENLOGGER 0 + +#if DEBUG_OPENLOGGER + +#define OPENLOGGER_SERIAL_BUAD_RATE 115200 + +#else + +#define OPENLOGGER_SERIAL_BUAD_RATE 115200 + +#endif // DEBUG_OPENLOGGER + +#define OPENLOGGER_BYTES_PER_BLOCK_WRITE 128 +#define OPENLOGGER_WRITE_BUFFER_LEN OPENLOGGER_BYTES_PER_BLOCK_WRITE * 4 +#define OPENLOGGER_BLOCKS_BEFORE_FLUSH 4 + +#define OPENLOGGER_CS_PIN 10 + +/* + * + * There are three types of transactions: save this data, do this command or heres some info. + * + * STRUCTURE OF A VALID SD CARD UART SAVE THIS DATA TRANSACTION + * + * START BYTE | DATA TYPE | LENGTH BYTE | DATA BYTES | STOP BYTE + * + * STRUCTURE OF A VALID COMMAND TRANSACTION + * + * START BYTE | COMMAND TYPE | COMMAND BYTE | STOP BYTE + * + * STUCTURE OF VALID INFO TRANSACTION + * + * START BYTE | INFO TYPE | INFO BYTE | STOP BYTE + * + * If no rx has been received for more than 500ms the rx state is reset to checking for start byte + * This ensures the open logger does not get stuck in the middle of a transaction if the master stops sending data + * + */ + +void openloggerProcess(); + +uint8_t openloggerBegin(); + +#endif //SUFST_OPENLOGGER_INO_SDCARD_H diff --git a/Legacy-firmware/sufst-openlogger/sufst-openlogger.ino b/Legacy-firmware/sufst-openlogger/sufst-openlogger.ino new file mode 100644 index 0000000..2cf83c8 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger/sufst-openlogger.ino @@ -0,0 +1,21 @@ + +#include "openLogger.h" + +void setup() +{ + // put your setup code here, to run once: + + openloggerBegin(); + +} + +void loop() +{ + + /* + * ALL PROCESSES *MUST* BE NON BLOCKING + */ + + openloggerProcess(); + +} diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/Project.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..1be0d30 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/Project.xml @@ -0,0 +1,60 @@ +<component name="ProjectCodeStyleConfiguration"> + <code_scheme name="Project" version="173"> + <Objective-C> + <option name="INDENT_NAMESPACE_MEMBERS" value="0" /> + <option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" /> + <option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" /> + <option name="NAMESPACE_BRACE_PLACEMENT" value="2" /> + <option name="FUNCTION_BRACE_PLACEMENT" value="2" /> + <option name="BLOCK_BRACE_PLACEMENT" value="2" /> + <option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_PARAMETERS_WRAP" value="5" /> + <option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" /> + <option name="CLASS_CONSTRUCTOR_INIT_LIST_WRAP" value="5" /> + <option name="CLASS_CONSTRUCTOR_INIT_LIST_NEW_LINE_BEFORE_COLON" value="1" /> + <option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" /> + <option name="SPACE_BEFORE_SUPERCLASS_COLON" value="false" /> + <option name="HEADER_GUARD_STYLE_PATTERN" value="${FILE_NAME}_${EXT}" /> + <option name="NAMESPACES_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="CLASSES_AND_STRUCTS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="ENUMS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="TYPEDEFS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + <option name="UNIONS_NAMING_CONVENTION"> + <value prefix="" style="PASCAL_CASE" suffix="" /> + </option> + </Objective-C> + <codeStyleSettings language="ObjectiveC"> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> + <option name="BLANK_LINES_BEFORE_IMPORTS" value="0" /> + <option name="BLANK_LINES_AFTER_IMPORTS" value="0" /> + <option name="BLANK_LINES_AROUND_CLASS" value="0" /> + <option name="BLANK_LINES_AROUND_FIELD" value="1" /> + <option name="BLANK_LINES_AROUND_METHOD" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" /> + <option name="CLASS_BRACE_STYLE" value="2" /> + <option name="ELSE_ON_NEW_LINE" value="true" /> + <option name="WHILE_ON_NEW_LINE" value="true" /> + <option name="CATCH_ON_NEW_LINE" value="true" /> + <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" /> + <option name="METHOD_CALL_CHAIN_WRAP" value="1" /> + <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> + <option name="FOR_STATEMENT_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <indentOptions> + <option name="CONTINUATION_INDENT_SIZE" value="4" /> + </indentOptions> + </codeStyleSettings> + </code_scheme> +</component> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/codeStyleConfig.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </state> +</component> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/misc.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="JavaScriptSettings"> + <option name="languageLevel" value="ES6" /> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/modules.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/modules.xml new file mode 100644 index 0000000..24eddf4 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/sufst-openlogger_controller.iml" filepath="$PROJECT_DIR$/.idea/sufst-openlogger_controller.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/sufst-openlogger_controller.iml b/Legacy-firmware/sufst-openlogger_controller/.idea/sufst-openlogger_controller.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/sufst-openlogger_controller.iml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="CPP_MODULE" version="4"> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/vcs.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$/.." vcs="Git" /> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/.idea/workspace.xml b/Legacy-firmware/sufst-openlogger_controller/.idea/workspace.xml new file mode 100644 index 0000000..09347fb --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/.idea/workspace.xml @@ -0,0 +1,410 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CMakeRunConfigurationManager" shouldGenerate="true" shouldDeleteObsolete="true"> + <generated /> + </component> + <component name="CMakeSettings"> + <configurations> + <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" /> + </configurations> + </component> + <component name="ChangeListManager"> + <list default="true" id="e173ebdc-c119-4235-9653-364cc21b27a5" name="Default Changelist" comment=""> + <change afterPath="$PROJECT_DIR$/dashController.cpp" afterDir="false" /> + <change afterPath="$PROJECT_DIR$/dashController.h" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/../sufst-openlogger/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/../sufst-openlogger/.idea/workspace.xml" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/can.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/can.cpp" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/ecuCan.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/ecuCan.cpp" afterDir="false" /> + <change beforePath="$PROJECT_DIR$/sufst-openlogger_controller.ino" beforeDir="false" afterPath="$PROJECT_DIR$/sufst-openlogger_controller.ino" afterDir="false" /> + </list> + <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> + <option name="SHOW_DIALOG" value="false" /> + <option name="HIGHLIGHT_CONFLICTS" value="true" /> + <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> + <option name="LAST_RESOLUTION" value="IGNORE" /> + </component> + <component name="ClangdSettings"> + <option name="formatViaClangd" value="false" /> + </component> + <component name="DatabaseView"> + <option name="SHOW_INTERMEDIATE" value="true" /> + <option name="GROUP_DATA_SOURCES" value="true" /> + <option name="GROUP_SCHEMA" value="true" /> + <option name="GROUP_CONTENTS" value="false" /> + <option name="SORT_POSITIONED" value="false" /> + <option name="SHOW_EMPTY_GROUPS" value="false" /> + <option name="AUTO_SCROLL_FROM_SOURCE" value="false" /> + <option name="HIDDEN_KINDS"> + <set /> + </option> + <expand /> + <select /> + </component> + <component name="FavoritesManager"> + <favorites_list name="sufst-openlogger_controller" /> + </component> + <component name="FileEditorManager"> + <leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/sufst-openlogger_controller.ino"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="391"> + <caret line="29" lean-forward="true" selection-start-line="29" selection-end-line="29" /> + <folding> + <element signature="e#57#90#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/openLoggerController.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="576"> + <caret line="175" column="87" selection-start-line="175" selection-start-column="87" selection-end-line="175" selection-end-column="87" /> + <folding> + <element signature="e#40#73#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/openLoggerController.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="187"> + <caret line="11" column="37" selection-start-line="11" selection-start-column="37" selection-end-line="11" selection-end-column="37" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/can.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="844"> + <caret line="52" column="8" selection-start-line="52" selection-start-column="8" selection-end-line="52" selection-end-column="8" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/can.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="170"> + <caret line="73" column="11" lean-forward="true" selection-start-line="73" selection-start-column="11" selection-end-line="73" selection-end-column="11" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="true"> + <entry file="file://$PROJECT_DIR$/ecuCan.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="102"> + <caret line="6" column="30" selection-start-line="6" selection-start-column="30" selection-end-line="6" selection-end-column="30" /> + <folding> + <element signature="e#39#58#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/dashController.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="476"> + <caret line="28" selection-start-line="28" selection-end-line="28" selection-end-column="28" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/dashController.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="153"> + <caret line="9" column="18" selection-start-line="9" selection-start-column="5" selection-end-line="9" selection-end-column="18" /> + </state> + </provider> + </entry> + </file> + <file pinned="false" current-in-tab="false"> + <entry file="file://$PROJECT_DIR$/ecuOpenloggerTags.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="34"> + <caret line="2" column="2" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="2" /> + </state> + </provider> + </entry> + </file> + </leaf> + </component> + <component name="FindInProjectRecents"> + <findStrings> + <find>cir</find> + <find>open</find> + <find>openloggerStopped</find> + <find>CHECKING_FOR_START</find> + <find>OPENLOGGER_TYPE_INFO</find> + <find>OPENLOGGER_UART_TX_BUFFER_LEN</find> + <find>OPEN</find> + <find>uartStopbyte</find> + <find>openloggerRxCheckingForInfo</find> + <find>head</find> + <find>uartCurrentlyTransmitting</find> + <find>Serial1</find> + <find>*(</find> + <find>buffer</find> + <find>peek</find> + <find>openloggerTxDataCirBuffer</find> + <find>writes</find> + <find>uartTxDataAmount</find> + <find>cirBufferAvailable</find> + <find>availableForWrite</find> + <find>available</find> + <find>tail</find> + <find>Serial</find> + <find>OPENLOGGER_TX_BUFFER_LEN</find> + <find>startTag</find> + <find>&</find> + <find>tx</find> + <find>&=</find> + <find>openloggerProcess</find> + <find>cirBuffer</find> + </findStrings> + <replaceStrings> + <replace>Serial1</replace> + <replace>uartTypeInfo</replace> + <replace>uartStopByte</replace> + <replace>Serial</replace> + </replaceStrings> + </component> + <component name="Git.Settings"> + <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." /> + </component> + <component name="IdeDocumentHistory"> + <option name="CHANGED_PATHS"> + <list> + <option value="$PROJECT_DIR$/circularBuffer.cpp" /> + <option value="$PROJECT_DIR$/circularBuffer.h" /> + <option value="$PROJECT_DIR$/buffer.h" /> + <option value="$PROJECT_DIR$/ecuCan.h" /> + <option value="$PROJECT_DIR$/can.h" /> + <option value="$PROJECT_DIR$/ecuOpenloggerTags.h" /> + <option value="$PROJECT_DIR$/buffer.cpp" /> + <option value="$PROJECT_DIR$/openLoggerController.h" /> + <option value="$PROJECT_DIR$/openLoggerController.cpp" /> + <option value="$PROJECT_DIR$/sufst-openlogger_controller.ino" /> + <option value="$PROJECT_DIR$/can.cpp" /> + <option value="$PROJECT_DIR$/dashController.cpp" /> + <option value="$PROJECT_DIR$/dashController.h" /> + <option value="$PROJECT_DIR$/ecuCan.cpp" /> + </list> + </option> + </component> + <component name="OCFindUsagesOptions" text="true" ivars="false" properties="true" derivedClasses="false" /> + <component name="ProjectFrameBounds" extendedState="6"> + <option name="x" value="501" /> + <option name="width" value="1428" /> + <option name="height" value="1038" /> + </component> + <component name="ProjectLevelVcsManager" settingsEditedManually="true"> + <ConfirmationsSetting value="2" id="Add" /> + </component> + <component name="ProjectView"> + <navigator proportions="" version="1"> + <foldersAlwaysOnTop value="true" /> + </navigator> + <panes> + <pane id="ProjectPane"> + <subPane> + <expand> + <path> + <item name="sufst-openlogger_controller" type="b2602c69:ProjectViewProjectNode" /> + <item name="sufst-openlogger_controller" type="462c0819:PsiDirectoryNode" /> + </path> + </expand> + <select /> + </subPane> + </pane> + <pane id="Scope" /> + </panes> + </component> + <component name="PropertiesComponent"> + <property name="ASKED_SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> + <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> + <property name="WebServerToolWindowFactoryState" value="false" /> + <property name="last_opened_file_path" value="$PROJECT_DIR$" /> + <property name="node.js.detected.package.eslint" value="true" /> + <property name="node.js.detected.package.tslint" value="true" /> + <property name="node.js.path.for.package.eslint" value="project" /> + <property name="node.js.path.for.package.tslint" value="project" /> + <property name="node.js.selected.package.eslint" value="(autodetect)" /> + <property name="node.js.selected.package.tslint" value="(autodetect)" /> + <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" /> + <property name="nodejs_npm_path_reset_for_default_project" value="true" /> + <property name="settings.editor.selected.configurable" value="preferences.sourceCode.C/C++" /> + </component> + <component name="RunDashboard"> + <option name="ruleStates"> + <list> + <RuleState> + <option name="name" value="ConfigurationTypeDashboardGroupingRule" /> + </RuleState> + <RuleState> + <option name="name" value="StatusDashboardGroupingRule" /> + </RuleState> + </list> + </option> + </component> + <component name="SvnConfiguration"> + <configuration /> + </component> + <component name="TaskManager"> + <task active="true" id="Default" summary="Default task"> + <changelist id="e173ebdc-c119-4235-9653-364cc21b27a5" name="Default Changelist" comment="" /> + <created>1563403781995</created> + <option name="number" value="Default" /> + <option name="presentableId" value="Default" /> + <updated>1563403781995</updated> + <workItem from="1563403785876" duration="5878000" /> + <workItem from="1563472777392" duration="25184000" /> + <workItem from="1563556486428" duration="2811000" /> + <workItem from="1563582896736" duration="1316000" /> + <workItem from="1563820826788" duration="5069000" /> + </task> + <servers /> + </component> + <component name="TimeTrackingManager"> + <option name="totallyTimeSpent" value="106065000" /> + </component> + <component name="ToolWindowManager"> + <frame x="-7" y="-7" width="1550" height="838" extended-state="6" /> + <editor active="true" /> + <layout> + <window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.49291784" visible="true" weight="0.16375838" /> + <window_info id="Structure" order="1" sideWeight="0.50708216" side_tool="true" visible="true" weight="0.16375838" /> + <window_info id="Favorites" order="2" side_tool="true" weight="0.3298872" /> + <window_info anchor="bottom" id="Message" order="0" /> + <window_info anchor="bottom" id="Find" order="1" /> + <window_info anchor="bottom" id="Run" order="2" /> + <window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> + <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> + <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> + <window_info anchor="bottom" id="TODO" order="6" /> + <window_info anchor="bottom" id="Version Control" order="7" weight="0.3295129" /> + <window_info anchor="bottom" id="Database Changes" order="8" /> + <window_info anchor="bottom" id="Terminal" order="9" /> + <window_info anchor="bottom" id="Event Log" order="10" side_tool="true" /> + <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" /> + <window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> + <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> + <window_info anchor="right" id="Database" order="3" weight="0.3295129" /> + </layout> + </component> + <component name="TypeScriptGeneratedFilesManager"> + <option name="version" value="1" /> + </component> + <component name="editorHistoryManager"> + <entry file="file://$PROJECT_DIR$/../sufst-openlogger/openLogger.cpp"> + <provider selected="true" editor-type-id="text-editor" /> + </entry> + <entry file="file://$PROJECT_DIR$/../sufst-openlogger/openLogger.h"> + <provider selected="true" editor-type-id="text-editor" /> + </entry> + <entry file="file://$PROJECT_DIR$/circularBuffer.cpp" /> + <entry file="file://$PROJECT_DIR$/circularBuffer.h" /> + <entry file="file://$PROJECT_DIR$/ecuCan.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="357"> + <caret line="21" selection-start-line="21" selection-end-line="21" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/openLoggerController.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="187"> + <caret line="11" column="37" selection-start-line="11" selection-start-column="37" selection-end-line="11" selection-end-column="37" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/buffer.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="255"> + <caret line="15" column="22" selection-start-line="15" selection-start-column="22" selection-end-line="15" selection-end-column="22" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/buffer.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="799"> + <caret line="47" column="1" selection-start-line="47" selection-start-column="1" selection-end-line="47" selection-end-column="1" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/can.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="844"> + <caret line="52" column="8" selection-start-line="52" selection-start-column="8" selection-end-line="52" selection-end-column="8" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/openLoggerController.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="576"> + <caret line="175" column="87" selection-start-line="175" selection-start-column="87" selection-end-line="175" selection-end-column="87" /> + <folding> + <element signature="e#40#73#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/ecuOpenloggerTags.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="34"> + <caret line="2" column="2" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="2" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/can.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="170"> + <caret line="73" column="11" lean-forward="true" selection-start-line="73" selection-start-column="11" selection-end-line="73" selection-end-column="11" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/sufst-openlogger_controller.ino"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="391"> + <caret line="29" lean-forward="true" selection-start-line="29" selection-end-line="29" /> + <folding> + <element signature="e#57#90#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/dashController.h"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="153"> + <caret line="9" column="18" selection-start-line="9" selection-start-column="5" selection-end-line="9" selection-end-column="18" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/dashController.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="476"> + <caret line="28" selection-start-line="28" selection-end-line="28" selection-end-column="28" /> + </state> + </provider> + </entry> + <entry file="file://$PROJECT_DIR$/ecuCan.cpp"> + <provider selected="true" editor-type-id="text-editor"> + <state relative-caret-position="102"> + <caret line="6" column="30" selection-start-line="6" selection-start-column="30" selection-end-line="6" selection-end-column="30" /> + <folding> + <element signature="e#39#58#0" expanded="true" /> + </folding> + </state> + </provider> + </entry> + </component> +</project> \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/buffer.cpp b/Legacy-firmware/sufst-openlogger_controller/buffer.cpp new file mode 100644 index 0000000..b9f3742 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/buffer.cpp @@ -0,0 +1,142 @@ +// +// Created by Sil on 7/19/2019. +// + +#include "buffer.h" + +uint8_t cirBufferBegin(cirBuffer_handle cirBuff, void *data, uint16_t len, uint8_t unitSize) +{ + + if (cirBuff == NULL) { + return 0; + } + + if (data == NULL) { + return 0; + } + + cirBuff->head = 0; + cirBuff->tail = 0; + cirBuff->capacity = len; + cirBuff->full = 0; + cirBuff->data = (uint8_t *) data; + cirBuff->unitSize = unitSize; + + return 1; +} + +uint16_t cirBufferAvailable(cirBuffer_handle cirBuff) +{ + uint16_t availableForWrite = 0; + + if (!cirBuff->full) { + if (cirBuff->head >= cirBuff->tail) { + availableForWrite = cirBuff->head - cirBuff->tail; + } + else { + availableForWrite = cirBuff->capacity - cirBuff->tail + cirBuff->head; + } + } + else { + availableForWrite = cirBuff->capacity; + } + + return availableForWrite; +} + +uint16_t cirBufferAvailableForWrite(cirBuffer_handle cirBuff) +{ + return cirBuff->capacity - cirBufferAvailable(cirBuff); +} + +void cirBufferWrite(cirBuffer_handle cirBuff, void *unit) +{ + memcpy(&(cirBuff->data[cirBuff->head * cirBuff->unitSize]), unit, cirBuff->unitSize); + + ++cirBuff->head &= (cirBuff->capacity - 1); + + if (cirBuff->head == cirBuff->tail) { + cirBuff->full = 1; + + ++cirBuff->tail &= (cirBuff->capacity - 1); + } +} + +void cirBufferWriteBytes(cirBuffer_handle cirBuff, void *src, uint16_t len) +{ + + uint16_t usedBytes = cirBufferAvailable(cirBuff); + + if ((usedBytes + len) > cirBuff->capacity) { + cirBuff->full = 1; + } + + for (uint16_t i = 0; i < len; i++) { + cirBuff->data[cirBuff->head] = ((uint8_t *) src)[i]; + + ++cirBuff->head &= cirBuff->capacity - 1; + } + + if (cirBuff->full) { + cirBuff->tail = (cirBuff->tail + (len - (cirBuff->capacity - usedBytes))) & (cirBuff->capacity - 1); + } +} + +void *cirBufferExternalWrite(cirBuffer_handle cirBuff) +{ + uint8_t *head = &(cirBuff->data[cirBuff->head]); + + ++cirBuff->head &= cirBuff->capacity - 1; + + if (cirBuff->head == cirBuff->tail) { + cirBuff->full = 1; + + ++cirBuff->tail &= (cirBuff->capacity - 1); + } + + return head; +} + +void *cirBufferExternalRead(cirBuffer_handle cirBuff) +{ + uint8_t *tail = &(cirBuff->data[cirBuff->tail]); + + ++cirBuff->tail &= (cirBuff->capacity - 1); + + return (void *) tail; +} + +void cirBufferRead(cirBuffer_handle cirBuff, void *loc) +{ + + memcpy(loc, &(cirBuff->data[cirBuff->tail * cirBuff->unitSize]), cirBuff->unitSize); + + ++cirBuff->tail &= (cirBuff->capacity - 1); + + cirBuff->full = 0; + +} + +void *cirBufferPeek(cirBuffer_handle cirBuff) +{ + return (void *) (cirBuff->data[cirBuff->tail]); +} + +void cirBufferReadBytes(cirBuffer_handle cirBuff, void *loc, uint16_t len) +{ + cirBuff->full = 0; + + for (uint16_t i = 0; i < len; i++) { + ((uint8_t *) loc)[i] = cirBuff->data[cirBuff->tail]; + + ++cirBuff->tail &= cirBuff->capacity - 1; + } + +} + +void cirBufferReset(cirBuffer_handle cirBuff) +{ + cirBuff->head = 0; + cirBuff->tail = 0; + cirBuff->full = 0; +} \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/buffer.h b/Legacy-firmware/sufst-openlogger_controller/buffer.h new file mode 100644 index 0000000..d8f886d --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/buffer.h @@ -0,0 +1,48 @@ +// +// Created by Sil on 7/19/2019. +// + +#ifndef BUFFER_H +#define BUFFER_H + +#include "Arduino.h" + +typedef struct CirBuffer +{ + uint16_t head; + uint16_t tail; + uint8_t full; + uint8_t *data; + uint16_t capacity; + uint8_t unitSize; +}; + +typedef CirBuffer *cirBuffer_handle; + +/* + * THE LEN OF THE BUFFER MUST BE A POWER OF 2 + */ + +uint8_t cirBufferBegin(cirBuffer_handle cirBuff, void *data, uint16_t len, uint8_t unitSize); + +uint16_t cirBufferAvailable(cirBuffer_handle cirBuff); + +uint16_t cirBufferAvailableForWrite(cirBuffer_handle cirBuff); + +void cirBufferWrite(cirBuffer_handle cirBuff, void *unit); + +void cirBufferWriteBytes(cirBuffer_handle cirBuff, void *src, uint16_t len); + +void *cirBufferExternalWrite(cirBuffer_handle cirBuff); + +void cirBufferRead(cirBuffer_handle cirBuff, void *loc); + +void cirBufferReadBytes(cirBuffer_handle cirBuff, void *loc, uint16_t len); + +void *cirBufferExternalRead(cirBuffer_handle cirBuff); + +void *cirBufferPeek(cirBuffer_handle cirBuff); + +void cirBufferReset(cirBuffer_handle cirBuff); + +#endif //BUFFER_H \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/can.cpp b/Legacy-firmware/sufst-openlogger_controller/can.cpp new file mode 100644 index 0000000..4cc3e65 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/can.cpp @@ -0,0 +1,321 @@ +// +// Created by Sil on 15/07/2019. +// + +#include "can.h" +// Watchdog +#include <avr/wdt.h> +#include "buffer.h" +#include <mcp_can.h> +#include <mcp_can_dfs.h> + +#include "ecuCan.h" + +// Can instance +MCP_CAN can; + +volatile unsigned long lastCanMsgRecTimeMs = 0; + +static CanMsgTemplate canRxBuffer[CAN_RX_BUFFER_LEN]; + +volatile CirBuffer canRxCirBuffer; + +static CanMsgTemplate canTxBuffer[CAN_TX_BUFFER_LEN]; + +volatile CirBuffer canTxCirBuffer; + +extern void ecuCanMsg0x2000(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2001(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2002(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2003(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2004(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2005(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2006(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2007(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2008(CanMsgTemplate *canMsg); + +extern void ecuCanMsg0x2009(CanMsgTemplate *canMsg); + +// ECU can messages function pointers for calling the corresponding function when that msg is seen. +// Used in function canParseRxMsg. +void +(*ecuCanFuncPtrs[10])(CanMsgTemplate *) = {ecuCanMsg0x2000, ecuCanMsg0x2001, + ecuCanMsg0x2002, + ecuCanMsg0x2003, + ecuCanMsg0x2004, ecuCanMsg0x2005, + ecuCanMsg0x2006, + ecuCanMsg0x2007, ecuCanMsg0x2008, + ecuCanMsg0x2009}; + +uint8_t canBegin() +{ + if (!cirBufferBegin(&canRxCirBuffer, canRxBuffer, CAN_RX_BUFFER_LEN, sizeof(CanMsgTemplate))) { + return 0; + } + + if (!cirBufferBegin(&canTxCirBuffer, canTxBuffer, CAN_TX_BUFFER_LEN, sizeof(CanMsgTemplate))) { + return 0; + } + + pinMode(CAN_INT_PIN, INPUT_PULLUP); + + // Initialize the Arduino CAN class with slave select pin. + can.init_CS(CAN_CS_PIN); + + // Initialize the CAN bus with speed 1000kbps + if (can.begin(CAN_1000KBPS) == CAN_FAILINIT) { + return 0; + } + + + return 1; +} + +uint8_t canSaveMsg() +{ + if (digitalRead(CAN_INT_PIN)) { + return 0; + } + + union + { + uint8_t id[4]; + uint32_t id32; + } uid; + + if (can.checkReceive() != CAN_MSGAVAIL) { + return 0; + } + + CanMsgTemplate canReceivedMsg; + + if (can.readMsgBuf(&(canReceivedMsg.len), canReceivedMsg.data) != CAN_OK) { + return 0; + } + + uid.id32 = can.getCanId(); + + canReceivedMsg.timestamp = millis(); + + canReceivedMsg.id = (uid.id[1] << 8) | uid.id[0]; + + cirBufferWrite(&canRxCirBuffer, &canReceivedMsg); + +#if DEBUG_CAN_RX + Serial.print("CAN SV RX: "); + + Serial.print(canReceivedMsg.id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(canReceivedMsg.data[i]); + Serial.print(", "); + } + Serial.println(canReceivedMsg.data[7]); +#endif // DEBUG_CAN_RX; + + return 1; +} + +void canAddTxRequest(CanMsgTemplate *canMsg) +{ + if (NULL == canMsg) { + return; + } + +#if DEBUG_CAN_TX_REQS + Serial.print("CAN TX ADD: "); + Serial.print(canMsg.id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(canMsg.data[i], HEX); + Serial.print(", "); + } + Serial.println(canMsg.data[7], HEX); +#endif // DEBUG_CAN_TX_REQS + + cirBufferWrite(&canTxCirBuffer, canMsg); +} + +// External interrupt currently only designed to work with atmega 2560 +#if !defined(__AVR_ATmega2560__) +#error "PLATFORM NOT SUPPORTED CURRENTLY" +#endif // !defined(atmega2560) + +#if CAN_INT_PIN != 2 +#error "CAN_INT_PIN CHANGED FROM 2" +#endif //CAN_INT_PIN != 2 + +void canBeginExtInterrupt() +{ + noInterrupts(); + + // On the mega 2560 pin 2 is external interrupt 4 + EIMSK &= ~(1 << INT4); + + EICRB &= ~(1 << ISC41); + //EICRB &= ~(1 << ISC40); + + EIMSK |= (1 << INT4); + + interrupts(); +} + +ISR(INT4_vect) { + + noInterrupts(); + + lastCanMsgRecTimeMs = millis(); + + canSaveMsg(); + + interrupts(); +} + +void canParseRxMsg(CanMsgTemplate *canMsg) +{ + if ((canMsg->id >= 0x2000) && (canMsg->id <= 0x200A)) { + // canMsg->idByte[0] holds the 0x01 in 0x2001 received can msg + // We use the sub byte of the can ecu msg to determine the corresonding function + // This removes the need for a long if statement giving significant performance boosts + (*ecuCanFuncPtrs[canMsg->idByte[0]])(canMsg); + } +} + +void canProcessRx() +{ + uint8_t retVal = 0; + + noInterrupts(); + canSaveMsg(); + interrupts(); + + noInterrupts(); + while (cirBufferAvailable(&canRxCirBuffer) > 0) { + + CanMsgTemplate canMsg; + + cirBufferRead(&canRxCirBuffer, &canMsg); + +#if DEBUG_CAN_RX + Serial.print("CAN RX: "); + + Serial.print(canMsg.id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < 7; i++) { + Serial.print(canMsg.data[i]); + Serial.print(", "); + } + Serial.println(canMsg.data[7]); +#endif // DEBUG_CAN_RX + +#if DEBUG_CAN_RX_MINIMAL + Serial.print("CAN RX : "); + Serial.println(canMsg.id, HEX); +#endif // DEBUG_CAN_RX_MINIMAL + + canParseRxMsg(&canMsg); + + // This may seem dumb but this allows any pending interrupts to be serviced safely + // just before we start another loop. Otherwise if we stay in this loop too long without + // servicing any interrupts we might miss one. + interrupts(); + noInterrupts(); + } + interrupts(); +} + +uint8_t canProcessTx() +{ + + uint8_t retVal = 1; + + noInterrupts(); + while (cirBufferAvailable(&canTxCirBuffer) > 0) { + + CanMsgTemplate canMsg; + + cirBufferRead(&canTxCirBuffer, &canMsg); + +#if DEBUG_CAN_TX + Serial.print("CAN TX: "); + Serial.print(canMsg.id, HEX); + Serial.print(" : "); + for(uint8_t i = 0; i < (canMsg.len - 1); i++) { + Serial.print(canMsg.data[i]); + Serial.print(", "); + } + Serial.println(canMsg.data[canMsg.len - 1]); +#endif // DEBUG_CAN_TX + +#if DEBUG_CAN_TX_MINIMAL + Serial.print("CAN TX : "); + Serial.println(canMsg.id, HEX); +#endif // DEBUG_CAN_TX_MINIMAL + + uint8_t canTxWasSuccessful = 0; + + for (uint8_t i = 0; i < CAN_TX_RETRY_LIMIT; i++) { + if (can.sendMsgBuf(canMsg.id, 1, canMsg.len, + canMsg.data, true) == CAN_OK) { + + canTxWasSuccessful = 1; + + retVal = 1; + + break; + } + else { + retVal = 0; + } + + } + + if (!canTxWasSuccessful) { + +#if DEBUG_CAN_TX || DEBUG_CAN_TX_MINIMAL + Serial.println("CAN TX: TX FAILED"); +#endif // DEBUG_CAN_TX || DEBUG_CAN_TX_MINIMAL + + } + + // This may seem dumb but this allows any pending interrupts to be serviced safely + // just before we start another loop. Otherwise if we stay in this loop too long without + // servicing any interrupts we might miss one. + interrupts(); + noInterrupts(); + } + + interrupts(); + + return retVal; +} + +void canNoActivityResetDevice() +{ + Serial.println("CAN ERROR : RESETTING DEVICE"); + Serial.flush(); + +#if SD_ENABLED + + uint8_t payload[10] = {0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00}; + + sdAddToWriteBlocks(payload, 10); + + sdWriteBufferBlocks(); + +#endif //SD_ENABLED + + // Enabled watchdog timer to reset device as we will not pat it + wdt_enable(WDTO_15MS); + + while (true); + +} \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/can.h b/Legacy-firmware/sufst-openlogger_controller/can.h new file mode 100644 index 0000000..4fc862a --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/can.h @@ -0,0 +1,69 @@ +// +// Created by Sil on 15/07/2019. +// + +#ifndef SUFST_OPENLOGGER_CONTROLLER_CAN_H +#define SUFST_OPENLOGGER_CONTROLLER_CAN_H + +#include "Arduino.h" + +// CAN_INT_PIN MUST BE 2 +#define CAN_INT_PIN 2 +#define CAN_CS_PIN 10 + +#define CAN_RX_BUFFER_LEN 32 +#define CAN_TX_BUFFER_LEN 32 + +#define CAN_RESET_DEVICE_ON_TIMEOUT 0 +#define CAN_NO_MSG_TIMEOUT_RESET_MS 10000 + +#define CAN_TX_RETRY_LIMIT 5 + +#define DEBUG_CAN_RX 0 +#define DEBUG_CAN_RX_MINIMAL 0 + +#define DEBUG_CAN_TX 0 +#define DEBUG_CAN_TX_MINIMAL 0 +#define DEBUG_CAN_TX_REQS 0 + +typedef struct CanMsgTemplate +{ + uint32_t timestamp; + + union + { + uint16_t id; + // if id is 0x2001 then idByte[0] is 0x01 and idByte[1] is 0x20 + // due to the endianness of the system + uint8_t idByte[2]; + }; + + uint8_t len; + + union + { + uint8_t data[8]; + uint16_t data16[4]; + uint32_t data32[2]; + float dataFl[2]; + }; + +}; + +uint8_t canBegin(); + +uint8_t canSaveMsg(); + +uint8_t canAddTxRequest(uint16_t id, void *data, uint8_t lenBytes); + +void canBeginExtInterrupt(); + +void canParseRxMsg(CanMsgTemplate *canMsg); + +void canProcessRx(); + +uint8_t canProcessTx(); + +void canNoActivityResetDevice(); + +#endif //SUFST_OPENLOGGER_CONTROLLER_CAN_H diff --git a/Legacy-firmware/sufst-openlogger_controller/ecuCan.cpp b/Legacy-firmware/sufst-openlogger_controller/ecuCan.cpp new file mode 100644 index 0000000..e7f5d9f --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/ecuCan.cpp @@ -0,0 +1,280 @@ +// +// Created by Sil on 7/21/2019. +// + +#include "ecuCan.h" +#include "openLoggerController.h" +#include "ecuOpenloggerTags.h" + +struct EcuDataOpenlogger +{ + uint8_t startTag; + uint32_t timestamp; + uint16_t data; + uint8_t endTag; +}; + +void ecuOpenloggerWrite(EcuDataOpenlogger *ecuDataOpenlogger); + +void ecuOpenloggerSave(CanMsgTemplate *canMsgTemplate, uint8_t index); + +void ecuOpenloggerWrite(EcuDataOpenlogger &ecuDataOpenlogger) +{ + static uint8_t openloggerPayload[8]; + + memcpy(openloggerPayload, &(ecuDataOpenlogger.startTag), 1); + + memcpy(&(openloggerPayload[1]), &(ecuDataOpenlogger.timestamp), 4); + + memcpy(&(openloggerPayload[5]), &(ecuDataOpenlogger.data), 2); + + memcpy(&(openloggerPayload[7]), &(ecuDataOpenlogger.endTag), 1); + + openloggerWrite(openloggerPayload, 8); +} + +void ecuOpenloggerSave(CanMsgTemplate *canMsg, uint8_t index) +{ + static EcuDataOpenlogger ecuDataOpenlogger; + + uint8_t ecuId = canMsg->idByte[0]; + + uint8_t ecuParamterTag = ecuMsgParameterToOpenloggerTag[ecuId][index]; + + ecuDataOpenlogger.startTag = ecuParamterTag; + + ecuDataOpenlogger.timestamp = canMsg->timestamp; + + ecuDataOpenlogger.data = canMsg->data16[index]; + + ecuDataOpenlogger.endTag = ecuParamterTag; + + ecuOpenloggerWrite(ecuDataOpenlogger); +} + +void ecuCanMsg0x2000(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2000 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2000"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t rpm = canMsg->data16[0]; + uint16_t tpsPerc = canMsg->data16[1]; + uint16_t waterTempC = canMsg->data16[2]; + uint16_t airTempC = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 0); + ecuOpenloggerSave(canMsg, 1); + ecuOpenloggerSave(canMsg, 2); +} + +void ecuCanMsg0x2001(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2001 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2001"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t mainifoldPresKpa = canMsg->data16[0]; + uint16_t lambdax1000 = canMsg->data16[1]; + uint16_t speedKphx10 = canMsg->data16[2]; + uint16_t oilPressKpa = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 1); +} + +void ecuCanMsg0x2002(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2002 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2002"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t fuelPressKpa = canMsg->data16[0]; + uint16_t oilTempC = canMsg->data16[1]; + uint16_t batteryVx10 = canMsg->data16[2]; + uint16_t fuelComsumLpHrx10 = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 2); + + // Serial.println((float)(batteryVx10 / 10.0)); +} + +void ecuCanMsg0x2003(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2003 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2003"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t currentGear = canMsg->data16[0]; + uint16_t advanceDegx10 = canMsg->data16[1]; + uint16_t injectionTimeMsx100 = canMsg->data16[2]; + uint16_t fuelComsumLp100kMx10 = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 1); +} + +void ecuCanMsg0x2004(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2004 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2004"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t ana1mV = canMsg->data16[0]; + uint16_t ana2mV = canMsg->data16[1]; + uint16_t ana3mV = canMsg->data16[2]; + uint16_t camAdvanceDegx10 = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 3); +} + +void ecuCanMsg0x2005(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2005 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2005"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t camTargDegx10 = canMsg->data16[0]; + uint16_t camPwmPercx10 = canMsg->data16[1]; + uint16_t crankErrorsNr = canMsg->data16[2]; + uint16_t camErrorsNr = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 0); +} + +void ecuCanMsg0x2006(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2006 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2006"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t cam2AdvDegx10 = canMsg->data16[0]; + uint16_t cam2TargDegx10 = canMsg->data16[1]; + uint16_t cam2PwmPercx10 = canMsg->data16[2]; + uint16_t external5VmV = canMsg->data16[3]; +} + +void ecuCanMsg0x2007(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2007 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2007"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t injDutyCyclePerc = canMsg->data16[0]; + uint16_t lambdaPidTargPercx10 = canMsg->data16[1]; + uint16_t lambdaPidAdjPercx10 = canMsg->data16[2]; + uint16_t ecuSwitchesBitField = canMsg->data16[3]; + + ecuOpenloggerSave(canMsg, 0); + ecuOpenloggerSave(canMsg, 1); + ecuOpenloggerSave(canMsg, 2); +} + +void ecuCanMsg0x2008(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2008 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2008"); +#endif //DEBUG_ECU_CAN_MINIMAL + + uint16_t rdSpeedKphx10 = canMsg->data16[0]; + uint16_t rUdSpeedKphx10 = canMsg->data16[1]; + uint16_t ldSpeedKphx10 = canMsg->data16[2]; + uint16_t lUdSpeedKphx10 = canMsg->data16[3]; +} + +void ecuCanMsg0x2009(CanMsgTemplate *canMsg) +{ +#if DEBUG_ECU_CAN + Serial.print("ECU : 0x2009 : "); + for (uint8_t i = 0; i < 3; i++) { + Serial.print(canMsg->data16[i], HEX); + Serial.print(" , "); + } + Serial.println(canMsg->data16[3], HEX); +#endif //DEBUG_ECU_CAN + +#if DEBUG_ECU_CAN_MINIMAL + Serial.println("ECU : 0x2008"); +#endif //DEBUG_ECU_CAN_MINIMAL + + // uint16_t rightLambdax1000 = canMsg->data16[0]; +} \ No newline at end of file diff --git a/Legacy-firmware/sufst-openlogger_controller/ecuCan.h b/Legacy-firmware/sufst-openlogger_controller/ecuCan.h new file mode 100644 index 0000000..3e0f985 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/ecuCan.h @@ -0,0 +1,38 @@ +// +// Created by Sil on 7/21/2019. +// + +#ifndef ECUCAN_H +#define ECUCAN_H + +#include "Arduino.h" +#include "can.h" + +/* + * These are called from can.cpp when their corresponding can msg id is seen. + * So functions name *must* ecuCanMsg0x200N. + * + */ + +void ecuCanMsg0x2000(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2001(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2002(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2003(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2004(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2005(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2006(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2007(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2008(CanMsgTemplate *canMsg); + +void ecuCanMsg0x2009(CanMsgTemplate *canMsg); + + +#endif //ECUCAN_H diff --git a/Legacy-firmware/sufst-openlogger_controller/ecuOpenloggerTags.h b/Legacy-firmware/sufst-openlogger_controller/ecuOpenloggerTags.h new file mode 100644 index 0000000..c0bc6d3 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/ecuOpenloggerTags.h @@ -0,0 +1,19 @@ +// +// Created by Sil on 7/21/2019. +// + +#ifndef ECUOPENLOGGERTAGS_H +#define ECUOPENLOGGERTAGS_H + +uint8_t ecuMsgParameterToOpenloggerTag[8][4] = { + {1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12}, + {13, 14, 15, 16}, + {17, 18, 19, 20}, + {21, 22, 23, 24}, + {25, 26, 27, 28}, + {29, 30, 31, 32} +}; + +#endif //ECUOPENLOGGERTAGS_H diff --git a/Legacy-firmware/sufst-openlogger_controller/openLoggerController.cpp b/Legacy-firmware/sufst-openlogger_controller/openLoggerController.cpp new file mode 100644 index 0000000..d530acb --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/openLoggerController.cpp @@ -0,0 +1,296 @@ +// +// Created by Sil on 14/07/2019. +// + +#include "openLoggerController.h" +#include "buffer.h" + +enum +{ + uartStartByte = 's', + uartStopByte = 'f' +}; + +enum +{ + uartTypeData = 0, + uartTypeCommand, + uartTypeInfo +}; + +enum +{ + uartCommandStartWrites = 0, + uartCommandStopWrites +}; + +enum +{ + uartInfoAlreadyRunning = 0, + uartInfoAlreadyIdle, + uartInfoWritesStarted, + uartInfoWritesStartError, + uartInfoStopped, + uartInfoStopError, + uartInfoWriteError, + uartInfoWritesNotStarted +}; + +typedef enum +{ + idle = 0, + running, + failedToStart, + failedToStop, + failToWrite +} OpenloggerState; + +typedef enum +{ + checkingForStart = 0, + checkingForType, + checkingForInfo +} OpenloggerUartRxState; + +static uint8_t openloggerTxDataBuffer[OPENLOGGER_TX_BUFFER_LEN]; + +static CirBuffer openloggerTxDataCirBuffer; + +static uint8_t openloggerTxCommandBuffer[OPENLOGGER_TX_COMMAND_BUFFER_LEN]; + +static CirBuffer openloggerTxCommandCirBuffer; + +OpenloggerState openloggerState = idle; + +OpenloggerUartRxState openloggerUartRxState = checkingForStart; + +static bool uartCurrentlyTransmitting = false; + +void openloggerIdle(); + +void openloggerRunning(); + +void openloggerFailedToStart(); + +void openloggerFailedToStop(); + +void openloggerFailedToWrite(); + +void openloggerRxCheckingForStart(); + +void openloggerRxCheckingForType(); + +void openloggerRxCheckingForInfo(); + +/* + * openloggerState_ptrs correspond to INFO packets, so e.g if OPENLOGGER_INFO_WRITES_STARTED (0x02) is seen then + * [2] is called which is openloggerRunning. + */ + +OpenloggerState rxInfoTypeToStateLookup[8] = {running, idle, running, failedToStart, idle, failedToStop, + failToWrite, idle}; + +void (*openloggerState_ptrs[8])(void) = {openloggerIdle, openloggerRunning, + openloggerFailedToStart, openloggerFailedToStop, + openloggerFailedToWrite}; + +void (*openloggerUartRxState_ptrs[3])(void) = {openloggerRxCheckingForStart, openloggerRxCheckingForType, + openloggerRxCheckingForInfo}; + +void serialEvent1() +{ + openloggerUartRxState_ptrs[openloggerUartRxState](); +} + +void openloggerRxCheckingForStart() +{ + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING START "); + Serial.println(Serial1.peek()); +#endif // DEBUG_OPENLOGGER + + if (Serial1.read() == uartStartByte) { + openloggerUartRxState = checkingForType; + } +} + +void openloggerRxCheckingForType() +{ +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING FOR TYPE "); + Serial.println(Serial1.peek()); +#endif // DEBUG_OPENLOGGER + + if (Serial1.read() == uartTypeInfo) { + openloggerUartRxState = checkingForInfo; + } + else { + openloggerUartRxState = checkingForStart; + } +} + +void openloggerRxCheckingForInfo() +{ +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: CHECKING FOR INFO "); + Serial.println(Serial1.peek()); +#endif // DEBUG_OPENLOGGER + /* + * The value received from the openlogger dictates what state we are in. + */ + openloggerState = rxInfoTypeToStateLookup[Serial1.read()]; + + openloggerUartRxState = checkingForStart; + +} + +void openloggerIdle() +{ + +} + +void openloggerRunning() +{ + /* + * The uart Tx buffer has a capacity of 64 bytes, if we try to write more than this then Serial.write becomes + * blocking, so we want to avoid this at all costs. + * + */ + + static uint8_t uartTxPayload[64]; + + static uint16_t uartAmountToTransmit = 0; + + static uint32_t uartLastTransmissionMs = millis(); + + uint32_t uartCurrentMs = millis(); + + uint16_t uartTxDataAmount = cirBufferAvailable(&openloggerTxDataCirBuffer); + + if (uartTxDataAmount > 0) { + + if ((uartCurrentMs - uartLastTransmissionMs) >= 5) { + if (Serial1.availableForWrite() >= 35) { + + uint8_t uartTxBytes = (uartTxDataAmount >= 32) ? 32 : uartTxDataAmount; + + Serial1.write(uartStartByte); + Serial1.write(uartTypeData); + Serial1.write(uartTxBytes); + + cirBufferReadBytes(&openloggerTxDataCirBuffer, uartTxPayload, uartTxBytes); + + Serial1.write(uartTxPayload, uartTxBytes); + + uartLastTransmissionMs = millis(); + } + } + } +} + +void openloggerFailedToStart() +{ +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: FAILED TO START"); +#endif // DEBUG_OPENLOGGER + + openloggerState = idle; +} + +void openloggerFailedToStop() +{ +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: FAILED TO STOP"); +#endif // DEBUG_OPENLOGGER + + openloggerState = idle; +} + +void openloggerFailedToWrite() +{ +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: FAILED TO WRITE"); +#endif // DEBUG_OPENLOGGER + + openloggerState = idle; +} + +void openloggerBegin(uint32_t serialBaud) +{ + + Serial1.begin(serialBaud); + + cirBufferBegin(&openloggerTxDataCirBuffer, + openloggerTxDataBuffer, + OPENLOGGER_TX_BUFFER_LEN, + sizeof(uint8_t)); + + cirBufferBegin(&openloggerTxCommandCirBuffer, + openloggerTxCommandBuffer, + OPENLOGGER_TX_COMMAND_BUFFER_LEN, + sizeof(uint8_t)); + +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: BEGIN FINISHED"); +#endif // DEBUG_OPENLOGGER +} + +void openloggerBeginWrites() +{ + openloggerWriteCommand(uartCommandStartWrites); + +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: OPLOG STARTING WRITES"); +#endif // DEBUG_OPENLOGGER +} + +void openloggerStopWrites() +{ + openloggerWriteCommand(uartCommandStopWrites); + +#if DEBUG_OPENLOGGER + Serial.println("OPLOG: OPLOG STOPPING WRITES"); +#endif // DEBUG_OPENLOGGER +} + +void openloggerProcess() +{ + if (!uartCurrentlyTransmitting) { + if (cirBufferAvailable(&openloggerTxCommandCirBuffer) > 0) { + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: COMMAND "); + Serial.println(*((uint8_t *)cirBufferPeek(&openloggerTxCommandCirBuffer)), HEX); +#endif // DEBUG_OPENLOGGER + + Serial1.write(uartStartByte); + Serial1.write(uartTypeCommand); + Serial1.write(*((uint8_t *) cirBufferExternalRead(&openloggerTxCommandCirBuffer))); + Serial1.flush(); + } + } + + openloggerState_ptrs[openloggerState](); +} + +void openloggerWrite(void *pPayload, uint8_t payloadLen) +{ + + if (openloggerState == running) { + cirBufferWriteBytes(&openloggerTxDataCirBuffer, pPayload, payloadLen); + } +} + +void openloggerWriteCommand(uint8_t command) +{ + +#if DEBUG_OPENLOGGER + Serial.print("OPLOG: APPENDING COMMAND "); + Serial.println(command, HEX); + Serial.flush(); +#endif // DEBUG_OPENLOGGER + + cirBufferWrite(&openloggerTxCommandCirBuffer, &command); + +} diff --git a/Legacy-firmware/sufst-openlogger_controller/openLoggerController.h b/Legacy-firmware/sufst-openlogger_controller/openLoggerController.h new file mode 100644 index 0000000..fd48ca6 --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/openLoggerController.h @@ -0,0 +1,49 @@ +// +// Created by Sil on 14/07/2019. +// + +#ifndef SUFST_OPENLOGGER_INO_SDCARDMASTER_H +#define SUFST_OPENLOGGER_INO_SDCARDMASTER_H + +#include "Arduino.h" + +#define DEBUG_OPENLOGGER 0 + +#define OPENLOGGER_TX_BUFFER_LEN 1024 +#define OPENLOGGER_TX_COMMAND_BUFFER_LEN 8 + +/* + * The serial port is hard coded to serial1 so ensure openlogger is connected to serial1. + * + * There are three types of transactions: save this data, do this command or heres some info. + * + * STRUCTURE OF A VALID SD CARD UART SAVE THIS DATA TRANSACTION + * + * START BYTE | DATA TYPE | LENGTH BYTE | DATA BYTES | STOP BYTE + * + * STRUCTURE OF A VALID COMMAND TRANSACTION + * + * START BYTE | COMMAND TYPE | COMMAND BYTE | STOP BYTE + * + * STUCTURE OF VALID INFO TRANSACTION + * + * START BYTE | INFO TYPE | INFO BYTE | STOP BYTE + * + * If no rx has been received for more than 500ms the rx state is reset to checking for start byte + * This ensures the open logger does not get stuck in the middle of a transaction if the master stops sending data + * + */ +void openloggerBegin(uint32_t serialBaud); + +void openloggerBeginWrites(); + +void openloggerStopWrites(); + +void openloggerProcess(); + +void openloggerWrite(void *pPayload, uint8_t payloadLen); + +void openloggerWriteCommand(uint8_t command); + + +#endif //SUFST_OPENLOGGER_INO_SDCARDMASTER_H diff --git a/Legacy-firmware/sufst-openlogger_controller/sufst-openlogger_controller.ino b/Legacy-firmware/sufst-openlogger_controller/sufst-openlogger_controller.ino new file mode 100644 index 0000000..4a2d09a --- /dev/null +++ b/Legacy-firmware/sufst-openlogger_controller/sufst-openlogger_controller.ino @@ -0,0 +1,64 @@ +#define DEBUG_ECU_CAN 0 +#define DEBUG_ECU_CAN_MINIMAL 0 + +#include "openLoggerController.h" +#include "ecuCan.h" +#include "can.h" + +// Watchdog +#include <avr/wdt.h> + +#define OPENLOGGER_SERIAL_BUAD_RATE 115200 + +uint8_t arduinoProcessSerial(); + +void setup() +{ + // put your setup code here, to run once: + + + // Serial port for host pc communications + Serial.begin(115200); + + Serial.println("BEGIN"); + + // Openlogger runs on uart port TX1 RX1 (Serial1) + openloggerBegin(OPENLOGGER_SERIAL_BUAD_RATE); + + canBegin(); +} + +void loop() +{ + // put your main code here, to run repeatedly: + + /* + * ALL PROCESSES *MUST* BE NON BLOCKING + */ + wdt_reset(); + + openloggerProcess(); + arduinoProcessSerial(); + canProcessRx(); + canProcessTx(); +} + +uint8_t arduinoProcessSerial() +{ + if (Serial.available()) { + + uint8_t serialByte = Serial.read(); + + switch (serialByte) { + case 'g':openloggerBeginWrites(); + + break; + + case 's':openloggerStopWrites(); + + break; + } + } + + return 1; +} -- GitLab