From 8750923e9be7d62321e06d852bb00849f6fea366 Mon Sep 17 00:00:00 2001
From: jazzpi <jasper@mezzo.de>
Date: Mon, 25 Jul 2022 18:48:26 +0200
Subject: [PATCH] Send error flags via CAN

---
 Core/Inc/CAN_Communication.h  |  5 ++--
 Core/Inc/SPI_Communication.h  |  6 ++---
 Core/Inc/main.h               | 11 ++++++++-
 Core/Src/CAN_Communication.c  | 15 +++++-------
 Core/Src/Check_Shunt_Limits.c |  7 +++---
 Core/Src/SPI_Communication.c  | 41 ++++++++++++++++---------------
 Core/Src/main.c               | 46 +++++++++++++++++++++++++++--------
 7 files changed, 82 insertions(+), 49 deletions(-)

diff --git a/Core/Inc/CAN_Communication.h b/Core/Inc/CAN_Communication.h
index 1030b8d..75aeeef 100644
--- a/Core/Inc/CAN_Communication.h
+++ b/Core/Inc/CAN_Communication.h
@@ -8,8 +8,6 @@
 #ifndef INC_CAN_COMMUNICATION_H_
 #define INC_CAN_COMMUNICATION_H_
 
-#include "SPI_Communication.h"
-
 #include "stm32g4xx_hal.h"
 #include "stm32g4xx_hal_fdcan.h"
 
@@ -79,7 +77,8 @@ uint8_t CAN_Receive(FDCAN_HandleTypeDef* hcan);
 uint8_t CAN_Transmit(FDCAN_HandleTypeDef* hcan, uint16_t frameid,
                      uint8_t* buffer, uint8_t datalen);
 void CAN_SendAbxStatus(FDCAN_HandleTypeDef* hcan);
-void CAN_SendAMSPanic(FDCAN_HandleTypeDef* hcan);
+typedef struct ErrorFlagHandlerStruct ErrorFlagHandler;
+void CAN_SendAMSPanic(FDCAN_HandleTypeDef* hcan, ErrorFlagHandler* errorflags);
 void CAN_SendLoggingFrame(FDCAN_HandleTypeDef* hcan);
 uint8_t CAN_convert_logval(uint16_t value, uint8_t type);
 
diff --git a/Core/Inc/SPI_Communication.h b/Core/Inc/SPI_Communication.h
index 51339d4..4d1815f 100644
--- a/Core/Inc/SPI_Communication.h
+++ b/Core/Inc/SPI_Communication.h
@@ -58,10 +58,10 @@ typedef struct {
 
 } TSHandler;
 
-typedef struct {
+typedef struct ErrorFlagHandlerStruct {
 
   uint8_t errorcode;
-  uint8_t errorargs[8];
+  uint8_t errorargs[7];
   uint8_t AMS_ERROR_LED;
   uint8_t IMD_ERROR_LED;
   uint8_t IMD_ERROR;
@@ -76,7 +76,7 @@ typedef struct {
 
 extern SlaveHandler slaves[NUMBEROFSLAVES];
 extern uint16_t min_voltage, max_voltage, min_temp, max_temp;
-extern ErrorFlagHandler errorflags;
+extern ErrorFlagHandler spierrorflags;
 extern TSHandler ctrltsstate;
 
 extern uint8_t actualTSState;
diff --git a/Core/Inc/main.h b/Core/Inc/main.h
index e161bd2..ec11774 100644
--- a/Core/Inc/main.h
+++ b/Core/Inc/main.h
@@ -46,6 +46,14 @@ extern "C" {
 #define THRESH_OV 55050 /* 4.2V */
 #define THRESH_UT 0     /* 0C */
 #define THRESH_OT 880   /* 55C */
+
+#define AMS_ERRORCODE_TIMEOUT_SHUNT 6
+#define AMS_ERRORCODE_MASTER_THRESH 7
+
+#define AMS_ERRORFLAG_MASTER_THRESH_UT 0
+#define AMS_ERRORFLAG_MASTER_THRESH_OT 1
+#define AMS_ERRORFLAG_MASTER_THRESH_UV 2
+#define AMS_ERRORFLAG_MASTER_THRESH_OV 3
 /* USER CODE END EC */
 
 /* Exported macro ------------------------------------------------------------*/
@@ -59,7 +67,8 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim);
 void Error_Handler(void);
 
 /* USER CODE BEGIN EFP */
-
+void AMS_Error_Handler(uint8_t ErrorCode, uint32_t nErrorArgs,
+                       uint8_t* ErrorArgs);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
diff --git a/Core/Src/CAN_Communication.c b/Core/Src/CAN_Communication.c
index 9d359a7..cb1a4ed 100644
--- a/Core/Src/CAN_Communication.c
+++ b/Core/Src/CAN_Communication.c
@@ -7,10 +7,13 @@
 
 #include "CAN_Communication.h"
 
+#include "SPI_Communication.h"
 #include "SoC_Estimation.h"
 
 #include "stm32g4xx_hal_fdcan.h"
 
+#include <string.h>
+
 canFrame framebuffer[CANFRAMEBUFFERSIZE] = {0};
 uint8_t framebufferwritepointer;
 uint8_t framebufferreadpointer;
@@ -188,16 +191,10 @@ void CAN_SendAbxStatus(FDCAN_HandleTypeDef* hcan) {
   CAN_Transmit(hcan, AMS_STATUS_ID, buffer, 4);
 }
 
-void CAN_SendAMSPanic(FDCAN_HandleTypeDef* hcan) {
+void CAN_SendAMSPanic(FDCAN_HandleTypeDef* hcan, ErrorFlagHandler* errorflags) {
   uint8_t buffer[8];
-  buffer[0] = errorflags.errorcode;
-  buffer[1] = errorflags.errorargs[0];
-  buffer[2] = 0;
-  buffer[3] = 0;
-  buffer[4] = 0;
-  buffer[5] = 0;
-  buffer[6] = 0;
-  buffer[7] = 0;
+  buffer[0] = errorflags->errorcode;
+  memcpy(&buffer[1], errorflags->errorargs, 7);
   CAN_Transmit(hcan, AMS_PANIC_ID, buffer, 8);
 }
 
diff --git a/Core/Src/Check_Shunt_Limits.c b/Core/Src/Check_Shunt_Limits.c
index c5d9e06..30c13fc 100644
--- a/Core/Src/Check_Shunt_Limits.c
+++ b/Core/Src/Check_Shunt_Limits.c
@@ -8,10 +8,9 @@
 #include "Check_Shunt_Limits.h"
 
 void CheckShuntLimits() {
-  uint32_t tick = HAL_GetTick();
-  if (((shuntlastmessage + SHUNT_TIMEOUT) < HAL_GetTick()) &&
-      (HAL_GetTick() > 2000)) {
-    AMS_Error_Handler(0x06);
+  uint32_t now = HAL_GetTick();
+  if (((shuntlastmessage + SHUNT_TIMEOUT) < now) && (now > 2000)) {
+    AMS_Error_Handler(AMS_ERRORCODE_TIMEOUT_SHUNT, 0, NULL);
   }
   /*if(shuntcurrent > SHUNT_OVERCURRENT)
   {
diff --git a/Core/Src/SPI_Communication.c b/Core/Src/SPI_Communication.c
index 96ec962..9ab7c51 100644
--- a/Core/Src/SPI_Communication.c
+++ b/Core/Src/SPI_Communication.c
@@ -22,7 +22,7 @@ uint8_t spirxbuf[1024];
 
 SlaveHandler slaves[NUMBEROFSLAVES] = {0};
 uint16_t min_voltage = 0, max_voltage = 0, min_temp = 0, max_temp = 0;
-ErrorFlagHandler errorflags = {0};
+ErrorFlagHandler spierrorflags = {0};
 TSHandler ctrltsstate = {0};
 
 uint8_t spibusy = 0;
@@ -277,28 +277,31 @@ void InterSTMFrame(uint8_t targettsstate) {
 
   uint16_t errorflagbaseaddress = NUMBEROFSLAVES * 89 + 1;
 
-  errorflags.errorcode = spirxbuf[errorflagbaseaddress];
-  errorflags.errorargs[0] = spirxbuf[errorflagbaseaddress + 1];
-  errorflags.errorargs[1] = spirxbuf[errorflagbaseaddress + 2];
-  errorflags.errorargs[2] = spirxbuf[errorflagbaseaddress + 3];
-  errorflags.errorargs[3] = spirxbuf[errorflagbaseaddress + 4];
-  errorflags.errorargs[4] = spirxbuf[errorflagbaseaddress + 5];
-  errorflags.errorargs[5] = spirxbuf[errorflagbaseaddress + 6];
-  errorflags.errorargs[6] = spirxbuf[errorflagbaseaddress + 7];
-  errorflags.errorargs[7] = spirxbuf[errorflagbaseaddress + 8];
-  errorflags.AMS_ERROR_LED = (spirxbuf[errorflagbaseaddress + 9] >> 7) & 0x01;
-  errorflags.IMD_ERROR_LED = (spirxbuf[errorflagbaseaddress + 9] >> 6) & 0x01;
-  errorflags.IMD_ERROR = (spirxbuf[errorflagbaseaddress + 9] >> 5) & 0x01;
-  errorflags.HV_Inactive = (spirxbuf[errorflagbaseaddress + 9] >> 4) & 0x01;
-  errorflags.TS_no_voltage_error =
+  spierrorflags.errorcode = spirxbuf[errorflagbaseaddress];
+  spierrorflags.errorargs[0] = spirxbuf[errorflagbaseaddress + 1];
+  spierrorflags.errorargs[1] = spirxbuf[errorflagbaseaddress + 2];
+  spierrorflags.errorargs[2] = spirxbuf[errorflagbaseaddress + 3];
+  spierrorflags.errorargs[3] = spirxbuf[errorflagbaseaddress + 4];
+  spierrorflags.errorargs[4] = spirxbuf[errorflagbaseaddress + 5];
+  spierrorflags.errorargs[5] = spirxbuf[errorflagbaseaddress + 6];
+  spierrorflags.errorargs[6] = spirxbuf[errorflagbaseaddress + 7];
+  // TODO: We can only transmit 7 error flags, we can remove the 8th
+  // errorflags.errorargs[7] = spirxbuf[errorflagbaseaddress + 8];
+  spierrorflags.AMS_ERROR_LED =
+      (spirxbuf[errorflagbaseaddress + 9] >> 7) & 0x01;
+  spierrorflags.IMD_ERROR_LED =
+      (spirxbuf[errorflagbaseaddress + 9] >> 6) & 0x01;
+  spierrorflags.IMD_ERROR = (spirxbuf[errorflagbaseaddress + 9] >> 5) & 0x01;
+  spierrorflags.HV_Inactive = (spirxbuf[errorflagbaseaddress + 9] >> 4) & 0x01;
+  spierrorflags.TS_no_voltage_error =
       (spirxbuf[errorflagbaseaddress + 9] >> 3) & 0x01;
-  errorflags.negative_AIR_error =
+  spierrorflags.negative_AIR_error =
       (spirxbuf[errorflagbaseaddress + 9] >> 2) & 0x01;
-  errorflags.positive_AIR_or_PC_error =
+  spierrorflags.positive_AIR_or_PC_error =
       (spirxbuf[errorflagbaseaddress + 9] >> 1) & 0x01;
-  errorflags.positive_AIR_and_PC_open =
+  spierrorflags.positive_AIR_and_PC_open =
       spirxbuf[errorflagbaseaddress + 9] & 0x01;
-  errorflags.negative_AIR_open = spirxbuf[errorflagbaseaddress + 10] & 0x01;
+  spierrorflags.negative_AIR_open = spirxbuf[errorflagbaseaddress + 10] & 0x01;
 
   uint16_t tsstatebaseaddress = errorflagbaseaddress + 12;
   ctrltsstate.currentTSState = spirxbuf[tsstatebaseaddress + 0];
diff --git a/Core/Src/main.c b/Core/Src/main.c
index 928eb75..caffb9a 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -76,18 +76,35 @@ void setAMSError();
 
 /* Private user code ---------------------------------------------------------*/
 /* USER CODE BEGIN 0 */
-void AMS_Error_Handler(uint8_t ErrorCode);
 void Send_Can_Info_Frame(void);
 void softTSAL(void);
 
 void CheckCellLimits() {
-  if (HAL_GetTick() < 10000) {
+  if (HAL_GetTick() < 12000) {
     return;
   }
 
-  if (min_temp < THRESH_UT || max_temp > THRESH_OT || min_voltage < THRESH_UV ||
-      max_voltage > THRESH_OV) {
-    AMS_Error_Handler(0x10);
+  int8_t errorcode = -1;
+  if (min_temp < THRESH_UT) {
+    errorcode = AMS_ERRORFLAG_MASTER_THRESH_UT;
+  }
+  if (max_temp > THRESH_OT) {
+    errorcode = AMS_ERRORFLAG_MASTER_THRESH_OT;
+  }
+  if (min_voltage < THRESH_UV) {
+    errorcode = AMS_ERRORFLAG_MASTER_THRESH_UV;
+  }
+  if (max_voltage > THRESH_OV) {
+    errorcode = AMS_ERRORFLAG_MASTER_THRESH_OV;
+  }
+  if (errorcode != -1) {
+    AMS_Error_Handler(AMS_ERRORCODE_MASTER_THRESH, 1, (uint8_t*)&errorcode);
+  }
+}
+
+void CheckSPIError() {
+  if (spierrorflags.errorcode != 0) {
+    AMS_Error_Handler(spierrorflags.errorcode, 7, spierrorflags.errorargs);
   }
 }
 /* USER CODE END 0 */
@@ -159,6 +176,7 @@ int main(void) {
     CAN_SendAbxStatus(&hfdcan1);
     CheckShuntLimits();
     CheckCellLimits();
+    CheckSPIError();
     CAN_SendLoggingFrame(&hfdcan1);
     HAL_GPIO_TogglePin(Status_LED_GPIO_Port, Status_LED_Pin);
     Temp_Ctrl_Loop();
@@ -410,19 +428,27 @@ static void MX_GPIO_Init(void) {
 
 /* USER CODE BEGIN 4 */
 
-void AMS_Error_Handler(uint8_t ErrorCode) {
+void AMS_Error_Handler(uint8_t ErrorCode, uint32_t nErrorArgs,
+                       uint8_t* ErrorArgs) {
+  ErrorFlagHandler errorflags;
+  errorflags.errorcode = ErrorCode;
+  if (nErrorArgs > 7) {
+    nErrorArgs = 7;
+  }
+  memcpy(errorflags.errorargs, ErrorArgs, nErrorArgs);
+
   while (1) {
     setAMSError();
-    CAN_SendAMSPanic(&hfdcan1);
+    CAN_SendAMSPanic(&hfdcan1, &errorflags);
     CAN_Receive(&hfdcan1);
     InterSTMFrame(TSTargetState);
   }
 }
 
 void softTSAL() {
-  uint8_t tsoff_condition = errorflags.positive_AIR_and_PC_open &
-                            errorflags.negative_AIR_open &
-                            errorflags.HV_Inactive;
+  uint8_t tsoff_condition = spierrorflags.positive_AIR_and_PC_open &
+                            spierrorflags.negative_AIR_open &
+                            spierrorflags.HV_Inactive;
 
   if (tsoff_condition) {
     HAL_GPIO_WritePin(Soft_TSAL_GPIO_Port, Soft_TSAL_Pin,