diff --git a/ECU/Application/Inc/Pinging.h b/ECU/Application/Inc/Pinging.h new file mode 100644 index 00000000..97e7ca16 --- /dev/null +++ b/ECU/Application/Inc/Pinging.h @@ -0,0 +1,13 @@ +#include + +#ifndef PINGING_H +#define PINGING_H + +#define PINGTIMEOUT_TIME 250U // time in ms before a ping is considered timed out +#define PINGTIMEOUT_VALUE (UINT8_MAX - 1) // return time value representing a timed out ping + +void pingAll(void); // ping all IDs specified, to be run every PINGTIMEOUT_TIME milliseconds +uint32_t getRTT(uint8_t id); // get latest RTT by ID +void respondToPing(uint8_t srcID, uint32_t timestamp); // "callback" + +#endif diff --git a/ECU/Application/Src/CANdler.c b/ECU/Application/Src/CANdler.c index cd12c47e..f00fa29e 100644 --- a/ECU/Application/Src/CANdler.c +++ b/ECU/Application/Src/CANdler.c @@ -6,6 +6,7 @@ #include "GR_OLD_MSG_ID.h" #include "GR_OLD_NODE_ID.h" #include "Logomatic.h" +#include "Pinging.h" #include "StateData.h" #include "bitManipulations.h" @@ -48,7 +49,7 @@ void ECU_CAN_MessageHandler(ECU_StateData *state_data, GR_OLD_BUS_ID bus_id, GR_ ReportBadMessageLength(bus_id, msg_id, sender_id); break; } - // TODO See Issue #143 + respondToPing(sender_id, ((GR_OLD_PING_MSG *)data)->timestamp); break; case MSG_BCU_STATUS_1: diff --git a/ECU/Application/Src/Pinging.c b/ECU/Application/Src/Pinging.c new file mode 100644 index 00000000..858c41df --- /dev/null +++ b/ECU/Application/Src/Pinging.c @@ -0,0 +1,58 @@ +#include "Pinging.h" + +#include "CANutils.h" +#include "GR_OLD_MSG_DAT.h" +#include "GR_OLD_MSG_ID.h" +#include "GR_OLD_NODE_ID.h" +#include "StateUtils.h" + +// add new pingable devices here, arrays are updated automagically +#define PING_LIST(X) \ + X(GR_BCU, 0) \ + X(GR_DASH_PANEL, 1) \ + X(GR_CCU, 2) + +const uint8_t IDsToBePinged[] = { +#define AS_ID(id, idx) id, + PING_LIST(AS_ID)}; + +const uint8_t PingsToBeIDed[] = { +#define AS_LOOKUP(id, idx) [id] = idx, + PING_LIST(AS_LOOKUP)}; + +#define NUMBER_OF_PING_DEVICES (sizeof(IDsToBePinged) / sizeof(IDsToBePinged[0])) + +static volatile uint32_t sentTimestamps[NUMBER_OF_PING_DEVICES]; +static volatile uint32_t receivedTimestamps[NUMBER_OF_PING_DEVICES]; +static uint8_t RTTs[NUMBER_OF_PING_DEVICES]; + +void pingAll(void) +{ + for (uint8_t i = 0; i < NUMBER_OF_PING_DEVICES; i++) { + uint32_t timestamp = MillisecondsSinceBoot(); + + if (receivedTimestamps[i] >= sentTimestamps[i]) { + // no timeout + RTTs[i] = receivedTimestamps[i] - sentTimestamps[i]; + } else { + // timeout + RTTs[i] = PINGTIMEOUT_VALUE; + } + + sentTimestamps[i] = timestamp; + ECU_CAN_Send(GR_OLD_BUS_PRIMARY, IDsToBePinged[i], MSG_PING, &(GR_OLD_PING_MSG){timestamp}, sizeof(GR_OLD_PING_MSG)); + } +} + +uint32_t getRTT(uint8_t ID) +{ + return RTTs[PingsToBeIDed[ID]]; +} + +void respondToPing(uint8_t srcID, uint32_t timestamp) +{ + uint8_t index = PingsToBeIDed[srcID]; + if (timestamp == sentTimestamps[index]) { + receivedTimestamps[index] = MillisecondsSinceBoot(); + } +} diff --git a/ECU/CMakeLists.txt b/ECU/CMakeLists.txt index 26953c93..41327e2a 100644 --- a/ECU/CMakeLists.txt +++ b/ECU/CMakeLists.txt @@ -77,6 +77,7 @@ target_sources( Application/Src/StateTicks.c Application/Src/StateUtils.c Application/Src/CANutils.c + Application/Src/Pinging.c Application/Src/Lights.c ) diff --git a/ECU/Core/Src/main.c b/ECU/Core/Src/main.c index 3457c251..3ea450de 100644 --- a/ECU/Core/Src/main.c +++ b/ECU/Core/Src/main.c @@ -35,6 +35,7 @@ #include "CANutils.h" #include "Lights.h" #include "Logomatic.h" +#include "Pinging.h" #include "StateTicks.h" #include "StateUtils.h" #include "adc.h" @@ -431,15 +432,34 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + static uint32_t nextPing; + if (MillisecondsSinceBoot() >= nextPing) { + pingAll(); + + if (nextPing != 0) { + if (getRTT(GR_BCU) == PINGTIMEOUT_VALUE) { + LOGOMATIC("ERROR: BCU is not responding to pings!\n"); + } + if (getRTT(GR_DASH_PANEL) == PINGTIMEOUT_VALUE) { + LOGOMATIC("ERROR: Dash Panel is not responding to pings!\n"); + } + if (getRTT(GR_CCU) != PINGTIMEOUT_VALUE) { + // halt if CCU is connected + return 1; + } + } + nextPing = MillisecondsSinceBoot() + PINGTIMEOUT_TIME; + } + read_digital(); // TODO: determine alpha ADC_UpdateAnalogValues_EMA(ADC_buffers, NUM_SIGNALS, 0.3, ADC_outputs); SendECUStateDataOverCAN(&stateLump); + write_adc_values_to_state_data(); ECU_State_Tick(); lightControl(&stateLump); LOGOMATIC("Main Loop Tick Complete. I use Arch btw\n"); - LL_mDelay(250); // FIXME Reduce or remove de } /* USER CODE END 3 */ }