From a4a856eb312b11c8ed1dcfcb5e8274ab86dfec75 Mon Sep 17 00:00:00 2001
From: hamza <hamza.tmm@tuta.com>
Date: Sun, 7 Jul 2024 18:52:54 +0300
Subject: [PATCH] V1.4

---
 Core/Inc/ADBMS_Abstraction.h |   4 +-
 Core/Inc/ADBMS_CMD_MAKROS.h  |   0
 Core/Inc/ADBMS_LL_Driver.h   |   4 +-
 Core/Inc/AMS_HighLevel.h     |  17 +---
 Core/Inc/PWM_control.h       |   7 ++
 Core/Inc/can.h               |   7 ++
 Core/Inc/state_machine.h     |  13 +--
 Core/Src/ADBMS_Abstraction.c |  16 ++--
 Core/Src/ADBMS_LL_Driver.c   |  82 +++++++-----------
 Core/Src/AMS_HighLevel.c     | 159 ++++-------------------------------
 Core/Src/PWM_control.c       |   7 ++
 Core/Src/can.c               |   7 +-
 Core/Src/main.c              |   4 +-
 Core/Src/state_machine.c     |  59 ++++++-------
 14 files changed, 126 insertions(+), 260 deletions(-)
 mode change 100644 => 100755 Core/Inc/ADBMS_Abstraction.h
 mode change 100644 => 100755 Core/Inc/ADBMS_CMD_MAKROS.h
 mode change 100644 => 100755 Core/Inc/ADBMS_LL_Driver.h
 mode change 100644 => 100755 Core/Inc/AMS_HighLevel.h
 mode change 100644 => 100755 Core/Src/ADBMS_Abstraction.c
 mode change 100644 => 100755 Core/Src/ADBMS_LL_Driver.c
 mode change 100644 => 100755 Core/Src/AMS_HighLevel.c

diff --git a/Core/Inc/ADBMS_Abstraction.h b/Core/Inc/ADBMS_Abstraction.h
old mode 100644
new mode 100755
index f095482..c9aacc6
--- a/Core/Inc/ADBMS_Abstraction.h
+++ b/Core/Inc/ADBMS_Abstraction.h
@@ -46,8 +46,8 @@ struct ADBMS6830_Internal_Status {
 };
 
 typedef struct {
-  float cellVoltages[MAXIMUM_CELL_VOLTAGES];
-  float auxVoltages[MAXIMUM_AUX_VOLTAGES];
+  int16_t cellVoltages[MAXIMUM_CELL_VOLTAGES];
+  int16_t auxVoltages[MAXIMUM_AUX_VOLTAGES];
 
   struct ADBMS6830_Internal_Status status;
   uint16 internalDieTemp;
diff --git a/Core/Inc/ADBMS_CMD_MAKROS.h b/Core/Inc/ADBMS_CMD_MAKROS.h
old mode 100644
new mode 100755
diff --git a/Core/Inc/ADBMS_LL_Driver.h b/Core/Inc/ADBMS_LL_Driver.h
old mode 100644
new mode 100755
index b4bc1f2..f5262e1
--- a/Core/Inc/ADBMS_LL_Driver.h
+++ b/Core/Inc/ADBMS_LL_Driver.h
@@ -27,8 +27,8 @@ uint8 calculateDataPEC(uint8* data, uint8 datalen);
 uint16 updateDataPEC(uint16 currentPEC, uint8 din);
 uint8 checkDataPEC(uint8* data, uint8 datalen);
 
-uint8 writeCMD(uint16 command, uint8* args, uint8 arglen);
-uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen);
+[[gnu::access(read_only, 2, 3)]] uint8 writeCMD(uint16 command, const uint8* args, uint8 arglen);
+[[gnu::access(write_only, 2, 3)]] uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen);
 uint8 pollCMD(uint16 command);
 
 void mcuAdbmsCSLow();
diff --git a/Core/Inc/AMS_HighLevel.h b/Core/Inc/AMS_HighLevel.h
old mode 100644
new mode 100755
index 5ac241a..33a768a
--- a/Core/Inc/AMS_HighLevel.h
+++ b/Core/Inc/AMS_HighLevel.h
@@ -12,11 +12,8 @@
 #include "ADBMS_CMD_MAKROS.h"
 #include "ADBMS_LL_Driver.h"
 #include "can.h"
-#include "TMP1075.h"
-#include "can-halal.h"
-#include "errors.h"
-#include "stm32f3xx_hal.h"
-#include <stdint.h>
+
+#include <stdbool.h>
 
 typedef enum {
   AMSDEACTIVE,
@@ -31,11 +28,7 @@ typedef enum {
 extern amsState currentAMSState;
 extern Cell_Module module;
 extern uint32_t balancedCells;
-extern uint8_t BalancingActive;
-extern uint8_t stateofcharge;
-
-extern uint8_t amserrorcode;
-extern uint8_t amswarningcode;
+extern bool BalancingActive;
 
 extern uint8_t numberofCells;
 extern uint8_t numberofAux;
@@ -50,8 +43,4 @@ uint8_t AMS_Error_Loop();
 uint8_t AMS_Charging_Loop();
 uint8_t AMS_Discharging_Loop();
 
-uint8_t writeWarningLog(uint8_t warningCode);
-uint8_t writeErrorLog(uint8_t errorCode);
-uint8_t integrateCurrent();
-
 #endif /* INC_AMS_HIGHLEVEL_H_ */
diff --git a/Core/Inc/PWM_control.h b/Core/Inc/PWM_control.h
index 0525b98..a6356eb 100644
--- a/Core/Inc/PWM_control.h
+++ b/Core/Inc/PWM_control.h
@@ -1,3 +1,10 @@
+/*
+ *  PWM_control.h
+ *
+ *  Created on: 07.07.2024
+ *      Author: Hamza
+ */
+ 
 #ifndef INC_PWM_CONTROL_H
 #define INC_PWM_CONTROL_H
 
diff --git a/Core/Inc/can.h b/Core/Inc/can.h
index ee48dec..73b7fe6 100644
--- a/Core/Inc/can.h
+++ b/Core/Inc/can.h
@@ -1,3 +1,10 @@
+/*
+ *  can.h
+ *
+ *  Created on: 07.07.2024
+ *      Author: Hamza
+ */
+
 #ifndef INC_CAN_H
 #define INC_CAN_H
 
diff --git a/Core/Inc/state_machine.h b/Core/Inc/state_machine.h
index d9d610b..c05d67c 100644
--- a/Core/Inc/state_machine.h
+++ b/Core/Inc/state_machine.h
@@ -1,3 +1,10 @@
+/*
+ *  state_machine.h
+ *
+ *  Created on: 07.07.2024
+ *      Author: Hamza
+ */
+
 #ifndef INC_STATE_MACHINE_H
 #define INC_STATE_MACHINE_H
 
@@ -8,17 +15,12 @@
 #include "errors.h"
 #include "PWM_control.h"
 #include "TMP1075.h"
-#include <math.h>
 
-// Minimum vehicle side voltage to exit precharge
-#define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV
 // Time to wait after reaching 95% of battery voltage before exiting precharge
 // Set this to 1000 in scruti to demonstrate the voltage on the multimeter
 #define PRECHARGE_DURATION 3000 // ms
 // Time to wait for discharge
 #define DISCHARGE_DURATION 3000 // ms
-// Time to wait after there is no more error condition before exiting TS_ERROR
-#define NO_ERROR_TIME 1000 // ms
 // Time to wait for charger voltage before going to TS_ERROR
 #define MAX_CHARGING_CHECK_DURATION 2000 // ms
 // Time to wait between closing relays
@@ -91,5 +93,6 @@ void sm_handle_ams_in(const uint8 *data);
 void sm_check_errors();
 void sm_set_error(ErrorKind error_kind, bool is_errored);
 void sm_test_cycle_states();
+void sm_error_source();
 
 #endif /* "INC_STATE_MACHINE_H" */
\ No newline at end of file
diff --git a/Core/Src/ADBMS_Abstraction.c b/Core/Src/ADBMS_Abstraction.c
old mode 100644
new mode 100755
index 15b357f..cdc90db
--- a/Core/Src/ADBMS_Abstraction.c
+++ b/Core/Src/ADBMS_Abstraction.c
@@ -28,7 +28,7 @@ uint8 amsReset() {
   amsStopBalancing();
   amsConfigOverUnderVoltage(DEFAULT_OV, DEFAULT_UV);
 
-  uint8 buffer[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  const uint8 buffer[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
   CHECK_RETURN(writeCMD(CLRFLAG, buffer, 6)); //clear flags,
   CHECK_RETURN(writeCMD(CLOVUV, buffer, 6));  //OVUV flags
@@ -131,8 +131,8 @@ uint8 amsAuxAndStatusMeasurement(Cell_Module* module) {
 uint8 amsConfigBalancing(uint32 channels, uint8 dutyCycle) {
   uint8 buffer_a[PWM_GROUP_A_SIZE] = {};
   uint8 buffer_b[PWM_GROUP_B_SIZE] = {};
-  CHECK_RETURN(readCMD(RDPWMA, buffer_a, CFG_GROUP_A_SIZE));
-  CHECK_RETURN(readCMD(RDPWMB, buffer_b, CFG_GROUP_B_SIZE));
+  CHECK_RETURN(readCMD(RDPWMA, buffer_a, PWM_GROUP_A_SIZE));
+  CHECK_RETURN(readCMD(RDPWMB, buffer_b, PWM_GROUP_B_SIZE));
 
   if (dutyCycle > 0x0F) { // there are only 4 bits for duty cycle
     return 1;
@@ -150,8 +150,8 @@ uint8 amsConfigBalancing(uint32 channels, uint8 dutyCycle) {
     }
   }
 
-  CHECK_RETURN(writeCMD(WRPWMA, buffer_a, CFG_GROUP_A_SIZE));
-  CHECK_RETURN(writeCMD(WRPWMB, buffer_b, CFG_GROUP_B_SIZE));
+  CHECK_RETURN(writeCMD(WRPWMA, buffer_a, PWM_GROUP_A_SIZE));
+  CHECK_RETURN(writeCMD(WRPWMB, buffer_b, PWM_GROUP_B_SIZE));
 
   return 0;
 }
@@ -203,13 +203,11 @@ uint8 amsCheckUnderOverVoltage(Cell_Module* module) {
 }
 
 uint8 amsClearAux() {
-  uint8 buffer[6];
-  return writeCMD(CLRAUX, buffer, 0);
+  return writeCMD(CLRAUX, NULL, 0);
 }
 
 uint8 amsClearCells() {
-  uint8 buffer[6];
-  return writeCMD(CLRCELL, buffer, 0);
+  return writeCMD(CLRCELL, NULL, 0);
 }
 
 uint8 amsReadCellVoltages(Cell_Module* module) {
diff --git a/Core/Src/ADBMS_LL_Driver.c b/Core/Src/ADBMS_LL_Driver.c
old mode 100644
new mode 100755
index f852233..e57dc0a
--- a/Core/Src/ADBMS_LL_Driver.c
+++ b/Core/Src/ADBMS_LL_Driver.c
@@ -6,11 +6,11 @@
  */
 
 #include "ADBMS_LL_Driver.h"
-#include <stdbool.h>
 
 #define INITIAL_COMMAND_PEC        0x0010
 #define INITIAL_DATA_PEC           0x0010 
 #define ADBMS_SPI_TIMEOUT          100 // Timeout in ms
+#warning ask about the timeout value
 
 SPI_HandleTypeDef* adbmsspi;
 
@@ -31,7 +31,7 @@ uint8 calculateCommandPEC(uint8_t* data, uint8_t datalen) {
   if (datalen >= 3) {
     for (int i = 0; i < (datalen - 2); i++) {
       for (int n = 0; n < 8; n++) {
-        uint8 din = data[i] << (n);
+          const uint8 din = data[i] << (n);
         currentpec = updateCommandPEC(currentpec, din);
       }
     }
@@ -53,13 +53,13 @@ uint8 checkCommandPEC(uint8* data, uint8 datalen) {
 
   for (int i = 0; i < (datalen - 2); i++) {
     for (int n = 0; n < 8; n++) {
-      uint8 din = data[i] << (n);
+        const uint8 din = data[i] << (n);
       currentpec = updateCommandPEC(currentpec, din);
     }
   }
 
-  uint8 pechigh = (currentpec >> 7) & 0xFF;
-  uint8 peclow = (currentpec << 1) & 0xFF;
+  const uint8 pechigh = (currentpec >> 7) & 0xFF;
+  const uint8 peclow = (currentpec << 1) & 0xFF;
 
   if ((pechigh == data[datalen - 2]) && (peclow == data[datalen - 1])) {
     return 0;
@@ -70,13 +70,13 @@ uint8 checkCommandPEC(uint8* data, uint8 datalen) {
 
 uint16 updateCommandPEC(uint16 currentPEC, uint8 din) {
   din = (din >> 7) & 0x01;
-  uint8 in0 = din ^ ((currentPEC >> 14) & 0x01);
-  uint8 in3 = in0 ^ ((currentPEC >> 2) & 0x01);
-  uint8 in4 = in0 ^ ((currentPEC >> 3) & 0x01);
-  uint8 in7 = in0 ^ ((currentPEC >> 6) & 0x01);
-  uint8 in8 = in0 ^ ((currentPEC >> 7) & 0x01);
-  uint8 in10 = in0 ^ ((currentPEC >> 9) & 0x01);
-  uint8 in14 = in0 ^ ((currentPEC >> 13) & 0x01);
+  const uint8 in0 = din ^ ((currentPEC >> 14) & 0x01);
+  const uint8 in3 = in0 ^ ((currentPEC >> 2) & 0x01);
+  const uint8 in4 = in0 ^ ((currentPEC >> 3) & 0x01);
+  const uint8 in7 = in0 ^ ((currentPEC >> 6) & 0x01);
+  const uint8 in8 = in0 ^ ((currentPEC >> 7) & 0x01);
+  const uint8 in10 = in0 ^ ((currentPEC >> 9) & 0x01);
+  const uint8 in14 = in0 ^ ((currentPEC >> 13) & 0x01);
 
   uint16 newPEC = 0;
 
@@ -103,9 +103,9 @@ uint16 updateCommandPEC(uint16 currentPEC, uint8 din) {
 //CRC-10
 //x^10 + x^7 + x^3 + x^2 + x + 1
 
-uint16_t pec10_calc(bool rx_cmd, int len, uint8_t* data) {
-  uint16_t remainder = 16; /* PEC_SEED;   0000010000 */
-  uint16_t polynom = 0x8F; /* x10 + x7 + x3 + x2 + x + 1 <- the CRC15 polynomial
+uint16_t pec10_calc(bool rx_cmd, int len, const uint8_t* data) {
+  uint16_t remainder = 16;       /* PEC_SEED;   0000010000 */
+  const uint16_t polynom = 0x8F; /* x10 + x7 + x3 + x2 + x + 1 <- the CRC15 polynomial
                               100 1000 1111   48F */
 
   /* Perform modulo-2 division, a byte at a time. */
@@ -149,16 +149,13 @@ crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], uint16_t VF_nBytes);
 uint8 calculateDataPEC(uint8_t* data, uint8_t datalen) {
 
   if (datalen >= 3) {
-    
 
-    crc currentpec = pec10_calc(true, datalen - 2, data) & 0x3FF; // mask to 10 bits
+      const crc currentpec = pec10_calc(true, datalen - 2, data) & 0x3FF; // mask to 10 bits
 
     // memory layout is [[zeroes], PEC[9:8]], [PEC[7:0]]
     data[datalen - 2] = (currentpec >> 8) & 0xFF;
     data[datalen - 1] = currentpec & 0xFF;
 
-    volatile uint8 result = pec10_calc(true, datalen, data);
-
     return 0;
   } else {
     return 1;
@@ -170,7 +167,7 @@ uint8 checkDataPEC(uint8* data, uint8 len) {
     return 255;
   }
 
-  crc currentpec = F_CRC_CalculaCheckSum(data, len);
+  const crc currentpec = F_CRC_CalculaCheckSum(data, len);
 
   return (currentpec == 0) ? 0 : 1;
 }
@@ -212,10 +209,10 @@ crc F_CRC_CalculaCheckSum(uint8_t const AF_Datos[], uint16_t VF_nBytes) {
 
 uint16 updateDataPEC(uint16 currentPEC, uint8 din) {
   din = (din >> 7) & 0x01;
-  uint8 in0 = din ^ ((currentPEC >> 9) & 0x01);
-  uint8 in2 = in0 ^ ((currentPEC >> 1) & 0x01);
-  uint8 in3 = in0 ^ ((currentPEC >> 2) & 0x01);
-  uint8 in7 = in0 ^ ((currentPEC >> 6) & 0x01);
+  const uint8 in0 = din ^ ((currentPEC >> 9) & 0x01);
+  const uint8 in2 = in0 ^ ((currentPEC >> 1) & 0x01);
+  const uint8 in3 = in0 ^ ((currentPEC >> 2) & 0x01);
+  const uint8 in7 = in0 ^ ((currentPEC >> 6) & 0x01);
 
   uint16 newPEC = 0;
 
@@ -232,7 +229,7 @@ uint16 updateDataPEC(uint16 currentPEC, uint8 din) {
   return newPEC;
 }
 
-uint8 writeCMD(uint16 command, uint8* args, uint8 arglen) {
+uint8 writeCMD(uint16 command, const uint8 * args, uint8 arglen) {
   uint8 ret;
   if (arglen > 0) {
     uint8 buffer[6 + arglen]; //command + PEC (2 bytes) + data + DPEC (2 bytes)
@@ -266,23 +263,9 @@ uint8 writeCMD(uint16 command, uint8* args, uint8 arglen) {
   return ret;
 }
 
-#define ITER_COUNT 50
-static uint8_t count = 0;
-static bool isOn = false;
-
-uint8 readCMD(uint16 command, uint8* buffer, uint8 buflen) {
-  if (count == ITER_COUNT) {
-    HAL_GPIO_WritePin(STATUS_LED_B_GPIO_Port, STATUS_LED_B_Pin, isOn ? GPIO_PIN_SET : GPIO_PIN_RESET);
-
-    count = 0;
-    isOn = !isOn;
-  } else {
-    count++;
-  }
-
-
-  uint8 txbuffer[6 + buflen] = {};
-  uint8 rxbuffer[6 + buflen] = {};
+uint8 readCMD(uint16 command, uint8 * buffer, uint8 buflen) {
+  uint8 txbuffer[6 + buflen];
+  uint8 rxbuffer[6 + buflen];
 
   txbuffer[0] = (command >> 8) & 0xFF;
   txbuffer[1] = (command)&0xFF;
@@ -335,25 +318,22 @@ void mcuAdbmsCSHigh() {
 }
 
 uint8 mcuSPITransmit(uint8* buffer, uint8 buffersize) {
-  HAL_StatusTypeDef status;
-  uint8 rxbuf[buffersize];
-  status = HAL_SPI_TransmitReceive(adbmsspi, buffer, rxbuf, buffersize,
-                                   ADBMS_SPI_TIMEOUT);
+    uint8 rxbuf[buffersize];
+    const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(adbmsspi, buffer, rxbuf, buffersize,
+                                                             ADBMS_SPI_TIMEOUT);
   __HAL_SPI_CLEAR_OVRFLAG(adbmsspi);
   return status;
 }
 
 uint8 mcuSPIReceive(uint8* buffer, uint8 buffersize) {
-  HAL_StatusTypeDef status;
-  status = HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
+    const HAL_StatusTypeDef status = HAL_SPI_Receive(adbmsspi, buffer, buffersize, ADBMS_SPI_TIMEOUT);
   return status;
 }
 
 uint8 mcuSPITransmitReceive(uint8* rxbuffer, uint8* txbuffer,
                             uint8 buffersize) {
-  HAL_StatusTypeDef status;
-  status = HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize,
-                                   ADBMS_SPI_TIMEOUT);
+    const HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(adbmsspi, txbuffer, rxbuffer, buffersize,
+                                                             ADBMS_SPI_TIMEOUT);
   return status;
 }
 
diff --git a/Core/Src/AMS_HighLevel.c b/Core/Src/AMS_HighLevel.c
old mode 100644
new mode 100755
index 1c326c5..ec1a2aa
--- a/Core/Src/AMS_HighLevel.c
+++ b/Core/Src/AMS_HighLevel.c
@@ -6,29 +6,21 @@
  */
 
 #include "AMS_HighLevel.h"
-
+#include "ADBMS_Abstraction.h"
+#include "ADBMS_LL_Driver.h"
+#include "TMP1075.h"
+#include "can-halal.h"
+#include "errors.h"
+#include "stm32f3xx_hal.h"
 
 Cell_Module module = {};
 uint32_t balancedCells = 0;
-uint8_t BalancingActive = 0;
-uint8_t stateofcharge = 100;
-int64_t currentintegrator = 0;
-uint32_t lastticks = 0;
-uint32_t currenttick = 0;
-uint8_t eepromconfigured = 0;
-
-uint8_t internalbalancingalgo = 1;
-uint16_t startbalancingthreshold = 41000;
-uint16_t stopbalancingthreshold = 30000;
-uint16_t balancingvoltagedelta = 10;
+bool balancingActive = false;
 
 uint16_t amsuv = 0;
 uint16_t amsov = 0;
 
-uint8_t amserrorcode = 0;
-uint8_t amswarningcode = 0;
-
-uint8_t numberofCells = 16;
+uint8_t numberofCells = 13;
 uint8_t numberofAux = 0;
 
 uint8_t packetChecksumFails = 0;
@@ -48,18 +40,9 @@ struct pollingTimes {
 struct pollingTimes pollingTimes = {0, 0};
 
 void AMS_Init(SPI_HandleTypeDef* hspi) {
-  if (eepromconfigured == 1) {
-    /*amsov = eepromcellovervoltage>>4;
-    amsuv = (eepromcellundervoltage-1)>>4;
-    numberofCells = eepromnumofcells;
-    numberofAux = eepromnumofaux;
-    initAMS(hspi, eepromnumofcells, eepromnumofaux);*/
-    amsConfigOverUnderVoltage(amsov, amsuv);
-  } else {
-    initAMS(hspi, numberofCells, numberofAux);
-    amsov = DEFAULT_OV;
-    amsuv = DEFAULT_UV;
-  }
+  initAMS(hspi, numberofCells, numberofAux);
+  amsov = DEFAULT_OV;
+  amsuv = DEFAULT_UV;
 
   pollingTimes = (struct pollingTimes) {HAL_GetTick(), HAL_GetTick()};
 
@@ -83,10 +66,8 @@ void AMS_Loop() {
     case AMSDISCHARGING:
       break;
     case AMSWARNING:
-      writeWarningLog(0x01);
       break;
     case AMSERROR:
-      writeErrorLog(amserrorcode);
       break;
     }
     lastAMSState = currentAMSState;
@@ -117,8 +98,8 @@ void AMS_Loop() {
 
 uint8_t AMS_Idle_Loop() {
   if (!amsWakeUp()) {
-    //error_data.data_kind = SEK_INTERNAL_BMS_TIMEOUT;
-    //set_error_source(ERROR_SOURCE_INTERNAL);
+    error_data.data_kind = SEK_INTERNAL_BMS_TIMEOUT; //we don't receive data for the wakeup command
+    set_error_source(ERROR_SOURCE_INTERNAL);         //so we can't tell if we timed out
   }
   
   packetChecksumFails += amsAuxAndStatusMeasurement(&module);
@@ -147,15 +128,12 @@ uint8_t AMS_Idle_Loop() {
 
   packetChecksumFails += amsCellMeasurement(&module);
   packetChecksumFails += amsCheckUnderOverVoltage(&module);
-  packetChecksumFails += integrateCurrent();
 
   if (packetChecksumFails > MAX_PACKET_CHECKSUM_FAILS) {
     error_data.data_kind = SEK_INTERNAL_BMS_CHECKSUM_FAIL;
     set_error_source(ERROR_SOURCE_INTERNAL);
   }
   
-  tmp1075_measure();
-
   int any_voltage_error = 0;
   for (size_t i = 0; i < numberofCells; i++) {
     if (module.cellVoltages[i] < 2500) {
@@ -190,27 +168,16 @@ uint8_t AMS_Idle_Loop() {
   }
 
   mcuDelay(10);
-  return 0;
-}
 
-uint8_t AMS_Warning_Loop() {
-
-  amsWakeUp();
-  amsConfigOverUnderVoltage(amsov, amsuv);
-  amsClearAux();
-  amsCellMeasurement(&module);
-  amsAuxAndStatusMeasurement(&module);
-  amsCheckUnderOverVoltage(&module);
-
-  if (!(module.overVoltage | module.underVoltage)) {
-    currentAMSState = AMSIDLE;
-    // amsClearWarning();
+  if ((module.overVoltage | module.underVoltage)) {
+    
   }
-  amsStopBalancing();
 
   return 0;
 }
 
+uint8_t AMS_Warning_Loop() { return 0; }
+
 uint8_t AMS_Error_Loop() { return 0; }
 
 uint8_t AMS_Charging_Loop() { return 0; }
@@ -218,96 +185,6 @@ uint8_t AMS_Charging_Loop() { return 0; }
 uint8_t AMS_Discharging_Loop() { return 0; }
 
 uint8_t AMS_Balancing_Loop() {
-  uint8_t balancingdone = 1;
-  if ((eepromconfigured == 1) && (internalbalancingalgo == 1) &&
-      (module.internalDieTemp <
-       28000 /*Thermal Protection 93°C*/)) // If the EEPROM is configured and
-                                           // the internal Balancing Algorithm
-                                           // should be used
-  {
-    uint16_t highestcellvoltage = module.cellVoltages[0];
-    uint16_t lowestcellvoltage = module.cellVoltages[0];
-    uint8_t highestcell = 0;
-    uint8_t lowestcell = 0;
-
-    for (uint8_t n = 0; n < numberofCells; n++) {
-      if (module.cellVoltages[n] > highestcellvoltage) {
-        highestcellvoltage = module.cellVoltages[n];
-        highestcell = n;
-      }
-      if (module.cellVoltages[n] < lowestcellvoltage) {
-        lowestcellvoltage = module.cellVoltages[n];
-        lowestcell = n;
-      }
-    }
-
-    if (currentAMSState ==
-        AMSCHARGING) // Balancing is only Active if the BMS is in Charging Mode
-    {
-
-      uint32_t channelstobalance = 0;
-
-      if (highestcellvoltage > startbalancingthreshold) {
-        for (uint8_t n = 0; n < numberofCells; n++) {
-          if (module.cellVoltages[n] > stopbalancingthreshold) {
-            uint16_t dv = module.cellVoltages[n] - lowestcellvoltage;
-            if (dv > (balancingvoltagedelta * 1000)) {
-              balancingdone = 0;
-              channelstobalance |= 1 << n;
-            }
-          }
-        }
-      }
-
-      amsConfigBalancing(channelstobalance, 0x0F);
-      amsStartBalancing(100);
-    }
-
-    else if (currentAMSState == AMSIDLEBALANCING) {
-
-      uint32_t channelstobalance = 0;
-
-      if (lowestcellvoltage <
-          stopbalancingthreshold) // If under Voltage of one Cell is reached
-      {
-        amsStopBalancing();
-        balancingdone = 1;
-      } else // otherwise continue with regular Balancing Algorithm
-      {
-        for (uint8_t n = 0; n < numberofCells; n++) {
-          uint16_t dv = module.cellVoltages[n] - lowestcellvoltage;
-          if (dv > balancingvoltagedelta) {
-            balancingdone = 0;
-            channelstobalance |= 1 << n;
-          }
-        }
-
-        amsConfigBalancing(channelstobalance, 0x0F);
-        amsStartBalancing(100);
-      }
-    }
-  } else {
-    amsStopBalancing();
-    balancingdone = 1;
-  }
-  return balancingdone;
-}
-
-uint8_t writeWarningLog(uint8_t warningCode) {
-  // eepromWriteWarningLog(warningCode);
-  return 0;
-}
-uint8_t writeErrorLog(uint8_t errorCode) {
-  // eepromWriteErrorLog(errorCode);
-  return 0;
-}
-
-uint8_t integrateCurrent() {
-  lastticks = currenttick;
-  currenttick = HAL_GetTick();
-  if (currenttick < lastticks) {
-    currentintegrator += (module.auxVoltages[0] - module.auxVoltages[2]) *
-                         (currenttick - lastticks);
-  }
+  //TODO: implement
   return 0;
 }
diff --git a/Core/Src/PWM_control.c b/Core/Src/PWM_control.c
index 3a1666f..014293b 100644
--- a/Core/Src/PWM_control.c
+++ b/Core/Src/PWM_control.c
@@ -1,3 +1,10 @@
+/*
+ *  PWM_control.h
+ *
+ *  Created on: 07.07.2024
+ *      Author: Hamza
+ */
+ 
 #include "PWM_control.h"
 #include "state_machine.h"
 #include "stm32f3xx_hal.h"
diff --git a/Core/Src/can.c b/Core/Src/can.c
index 9eb50d4..ee87a05 100644
--- a/Core/Src/can.c
+++ b/Core/Src/can.c
@@ -1,6 +1,7 @@
 /*
- *          can.c
- *  Created on: Mai 23, 2024
+ *  can.h
+ *
+ *  Created on: 07.07.2024
  *      Author: Hamza
  */
 
@@ -71,7 +72,7 @@ void can_handle_send_status() {
   data[5] = ((CURRENT_MEASUREMENT >> 8));
   data[6] = ((CURRENT_MEASUREMENT & 0x00F0) | (highest_temp >> 12));
   data[7] = ((highest_temp) >> 4);
-  
+  //data[7] = state.error_source;
   ftcan_transmit(CAN_ID_OUT, data, sizeof(data));
   /*
   int8_t id_lowest_temp = -1;
diff --git a/Core/Src/main.c b/Core/Src/main.c
index a36326c..ea3898e 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -134,7 +134,9 @@ int main(void)
   AMS_Init(&hspi1);
   can_init(&hcan);
   PWM_control_init(&htim3, &htim2, &htim15);
-  HAL_Delay(10);
+  //AMS_Loop();
+  //int ttrgrtd = 2000 + HAL_GetTick();
+  //while (ttrgrtd > HAL_GetTick());
   /* USER CODE END 2 */
 
   /* Infinite loop */
diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c
index cce0139..a4fb82f 100644
--- a/Core/Src/state_machine.c
+++ b/Core/Src/state_machine.c
@@ -1,3 +1,10 @@
+/*
+ *  state_machine.h
+ *
+ *  Created on: 07.07.2024
+ *      Author: Hamza
+ */
+ 
 #include "state_machine.h"
 #include "AMS_HighLevel.h"
 #include "PWM_control.h"
@@ -23,8 +30,8 @@ uint8_t powerground_calibration_stage;
 static uint32_t timestamp;
 
 void sm_init(){
-  state.current_state = STATE_ERROR;
-  state.target_state = STATE_ERROR;
+  state.current_state = STATE_INACTIVE;
+  state.target_state = STATE_INACTIVE;
   state.error_source = 0;
   precharge_timer = discharge_timer = powerground_calibration_timer = 0;
 }
@@ -329,39 +336,14 @@ bool sm_is_errored(){
 */
 
 #warning TODO: add error checking for everything here
-void sm_check_errors(){
-  switch (error_data.data_kind) {
-    case SEK_OVERTEMP:
-    case SEK_UNDERTEMP:
-    case SEK_TOO_FEW_TEMPS:
-      state.error_type.temperature_error = 1;
-      break;
-    case SEK_OVERVOLT:
-    case SEK_UNDERVOLT:
-    case SEK_OPENWIRE:
-      state.error_type.voltage_error = 1;
-      break;
-    case SEK_EEPROM_ERR:
-      //state.error_type.eeprom_error = 1;
-      break;
-    case SEK_INTERNAL_BMS_TIMEOUT:
-      state.error_type.bms_timeout = 1;
-      break;
-    case SEK_INTERNAL_BMS_CHECKSUM_FAIL:
-    case SEK_INTERNAL_BMS_OVERTEMP:
-    case SEK_INTERNAL_BMS_FAULT:
-      state.error_type.bms_fault = 1;
-      break;
-  }
-  
-  state.error_type.temperature_error = (error_data.data_kind == SEK_OVERTEMP || error_data.data_kind == SEK_UNDERTEMP ||error_data.data_kind == SEK_TOO_FEW_TEMPS) ? 1 : 0;
-  state.error_type.voltage_error = (error_data.data_kind == SEK_OVERVOLT || error_data.data_kind == SEK_UNDERVOLT ||error_data.data_kind == SEK_OPENWIRE) ? 1 : 0;
+void sm_check_errors(){  
+  state.error_type.temperature_error = (error_data.data_kind == SEK_OVERTEMP || error_data.data_kind == SEK_UNDERTEMP || error_data.data_kind == SEK_TOO_FEW_TEMPS) ? 1 : 0;
+  state.error_type.voltage_error = (error_data.data_kind == SEK_OVERVOLT || error_data.data_kind == SEK_UNDERVOLT || error_data.data_kind == SEK_OPENWIRE || RELAY_BAT_SIDE_VOLTAGE < 30000) ? 1 : 0;
   state.error_type.bms_timeout = (error_data.data_kind == SEK_INTERNAL_BMS_TIMEOUT) ? 1 : 0;
-  state.error_type.bms_fault = (error_data.data_kind == SEK_INTERNAL_BMS_CHECKSUM_FAIL || error_data.data_kind == SEK_INTERNAL_BMS_FAULT || error_data.data_kind == SEK_INTERNAL_BMS_OVERTEMP) ? 1 : 0;
+  state.error_type.bms_fault = (error_data.data_kind == SEK_INTERNAL_BMS_CHECKSUM_FAIL || error_data.data_kind == SEK_INTERNAL_BMS_FAULT /*|| error_data.data_kind == SEK_INTERNAL_BMS_OVERTEMP*/) ? 1 : 0;
   //SEK_EEPROM_ERR: state.error_type.eeprom_error = 1;
   state.error_type.current_error = (powerground_status > 10 && CURRENT_MEASUREMENT < 1000) ? 1 : 0;
   state.error_type.current_sensor_missing = (!CURRENT_MEASUREMENT_ON) ? 1 : 0;
-  state.error_type.voltage_error = (RELAY_BAT_SIDE_VOLTAGE < 30000) ? 1 : 0;
   state.error_type.voltage_missing = (RELAY_BAT_SIDE_VOLTAGE < 1000) ? 1 : 0;
   
 
@@ -376,7 +358,7 @@ void sm_check_errors(){
     if (state.current_state == STATE_ERROR)
       state.target_state = STATE_INACTIVE;
   }
-  
+  sm_error_source();
 }  
 
 int16_t sm_return_cell_temperature(int id){ return tmp1075_temps[id]; }
@@ -422,3 +404,16 @@ void sm_test_cycle_states(){
 
   state.target_state = state.current_state;
 }
+
+void sm_error_source(){
+  state.error_source = 0;
+  state.error_source |= (state.error_type.bms_timeout << 0);
+  state.error_source |= (state.error_type.bms_fault << 1);
+  state.error_source |= (state.error_type.temperature_error << 2);
+  state.error_source |= (state.error_type.current_error << 3);
+  
+  state.error_source |= (state.error_type.current_sensor_missing << 4);
+  state.error_source |= (state.error_type.voltage_error << 5);
+  state.error_source |= (state.error_type.voltage_missing << 6);
+  state.error_source |= (state.error_type.state_transition_fail << 7);
+}
\ No newline at end of file