From 662faed1fec523be5d4c77400e2c1f1fbf7912b5 Mon Sep 17 00:00:00 2001
From: hamza <hamza.tmm@tuta.com>
Date: Wed, 10 Jul 2024 09:59:34 +0300
Subject: [PATCH] V1.10

---
 CHANGELOG.txt            |  6 +++++-
 Core/Inc/PWM_control.h   | 13 +++++++++----
 Core/Src/AMS_HighLevel.c |  3 ++-
 Core/Src/PWM_control.c   | 27 +++++++--------------------
 Core/Src/state_machine.c | 40 ++++++++++++++++++++++++++++++++++------
 5 files changed, 57 insertions(+), 32 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 2c3f8ad..6ad2f30 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -58,4 +58,8 @@ V1.8
 V1.9
 - switched ~CSB and ~WC to high speed GPIO
 - cleaned up the includes in most files
-- wrote some code for the eeprom
\ No newline at end of file
+- wrote some code for the eeprom
+
+V1.10
+- PWM_control now has some macros and the method PWM_powerground_softcontrol()
+- added void sm_powerground_manager() to state_machine.c
diff --git a/Core/Inc/PWM_control.h b/Core/Inc/PWM_control.h
index 2856930..e4fdd0e 100644
--- a/Core/Inc/PWM_control.h
+++ b/Core/Inc/PWM_control.h
@@ -9,10 +9,7 @@
 #define INC_PWM_CONTROL_H
 
 #include "stm32f3xx_hal.h"
-#include "ADBMS_LL_Driver.h"
 #include "state_machine.h"
-#include <stdint.h>
-#include "main.h"
 
 /*  The PWM period (1/FPWM) is defined by the following parameters: 
 ARR value, the Prescaler value, and the internal clock itself which drives the timer module FCLK.
@@ -28,13 +25,21 @@ DUTY CYCLE = 1/20 -> 0%, DUTY CYCLE = 2/20 -> 100%
 CCR * DUTY_CYCLE
 CCR: 1/20 -> 500, 2/20 -> 1000
 */
+// UNUSED
 #define POWERGROUND_FREQ            50
+#define POWERGROUND_PRESCALER       7
+#define POWERGROUND_ARR             39999
+#define POWERGROUND_MIN_DUTY_CYCLE  0.05
+#define POWERGROUND_MAX_DUTY_CYCLE  0.1
 
 //#define BATTERY_COOLING_FREQ        20000
 
+extern uint8_t current_powerground_status;
+extern uint8_t target_powerground_status;
+
 void PWM_control_init(TIM_HandleTypeDef* pg, TIM_HandleTypeDef* bat_cool, TIM_HandleTypeDef* esc_cool);
+void PWM_powerground_softcontrol();
 void PWM_powerground_control(uint8_t percent);
 void PWM_battery_cooling_control(uint8_t percent);
-void PWM_set_throttle();
 
 #endif /* INC_CHANNEL_CONTROL_H */
diff --git a/Core/Src/AMS_HighLevel.c b/Core/Src/AMS_HighLevel.c
index 039a346..75ce0a0 100755
--- a/Core/Src/AMS_HighLevel.c
+++ b/Core/Src/AMS_HighLevel.c
@@ -23,7 +23,8 @@ uint8_t packetChecksumFails = 0;
 uint8_t deviceSleeps = 0;
 #define MAX_DEVICE_SLEEP 3 //TODO: change to correct value
 #define MAX_CELL_VOLTAGE 4100 //change to 4200
-#define MIN_CELL_VOLTAGE 3100 //change to 3100
+#define MIN_CELL_VOLTAGE 3100 //change to 3000
+
 amsState currentAMSState = AMSDEACTIVE;
 amsState lastAMSState = AMSDEACTIVE;
 
diff --git a/Core/Src/PWM_control.c b/Core/Src/PWM_control.c
index 2165c7e..d0be4df 100644
--- a/Core/Src/PWM_control.c
+++ b/Core/Src/PWM_control.c
@@ -6,9 +6,6 @@
  */
  
 #include "PWM_control.h"
-#include "state_machine.h"
-#include "stm32f3xx_hal.h"
-#include <stdint.h>
 
 //uint32_t powerground1_CCR, powerground2_CCR, battery_cooling_CCR;
 
@@ -20,7 +17,9 @@ TIM_HandleTypeDef *powerground, *battery_cooling, *esc_cooling;
 */
 
 void PWM_control_init(TIM_HandleTypeDef* pg, TIM_HandleTypeDef* bat_cool, TIM_HandleTypeDef* esc_cool){
-  powerground_status = 0;
+  current_powerground_status = 0;
+  target_powerground_status = 0;
+
   //battery_cooling_status = 0;
   
   powerground = pg;
@@ -44,35 +43,23 @@ void PWM_control_init(TIM_HandleTypeDef* pg, TIM_HandleTypeDef* bat_cool, TIM_Ha
 }              
 
 /*
-  controls the duty cycle of the fans by setting the CCR of the channel percent/100 = x/ARR
+  controls the duty cycle of the fans by setting the CCR of the channel 
+  6+percent/100 = x/ARR
   DUTYCYCLE = 40000 * X/100
 */
 void PWM_powerground_control(uint8_t percent){
   if (percent > 100){ //something went wrong
     __HAL_TIM_SET_COMPARE(powerground, TIM_CHANNEL_3, 0);
     __HAL_TIM_SET_COMPARE(powerground, TIM_CHANNEL_4, 0);
-      powerground_status = 0;
+      current_powerground_status = target_powerground_status = 0;
     return;
   }
-  powerground_status = percent;
+  current_powerground_status = target_powerground_status = percent;
 
   int ccr = 2000 + (20 * percent);
   __HAL_TIM_SET_COMPARE(powerground, TIM_CHANNEL_3, ccr);
   __HAL_TIM_SET_COMPARE(powerground, TIM_CHANNEL_4, ccr);
 }
 
-void PWM_set_throttle(){
-  uint32_t timestamp = HAL_GetTick() + 5000;
-  while (timestamp > HAL_GetTick()) {}
-
-  PWM_powerground_control(100);
-  timestamp = HAL_GetTick() + 2000;
-  while (timestamp > HAL_GetTick()) {}
-
-  PWM_powerground_control(0);
-  timestamp = HAL_GetTick() + 1000;
-  while (timestamp > HAL_GetTick()) {}
-}
-
 void PWM_battery_cooling_control(uint8_t percent){}
 void PWM_esc_cooling(uint8_t percent){}
diff --git a/Core/Src/state_machine.c b/Core/Src/state_machine.c
index f7d3bc0..b36c840 100644
--- a/Core/Src/state_machine.c
+++ b/Core/Src/state_machine.c
@@ -5,7 +5,7 @@
  *      Author: Hamza
  */
  
-#include "state_machine.h"
+#include "PWM_control.h"
 
 // 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
@@ -26,14 +26,17 @@ int32_t CURRENT_MEASUREMENT;
 bool CURRENT_MEASUREMENT_ON;
 float base_offset = 0;
 
-uint8_t powerground_status;
 uint32_t precharge_timer;
 uint32_t discharge_timer;
 uint32_t CAN_timer;
 
+uint32_t powerground_softstart_timer;
 uint32_t powerground_calibration_timer;
 uint8_t powerground_calibration_stage;
 
+uint8_t current_powerground_status;
+uint8_t target_powerground_status;
+
 static uint32_t timestamp;
 
 void sm_init(){
@@ -49,6 +52,7 @@ void sm_update(){
   sm_check_errors();
   sm_precharge_discharge_manager();
   sm_calibrate_powerground();
+  sm_powerground_manager();
   //if (CAN_timer < HAL_GetTick())
   //  state.current_state = state.target_state = STATE_ERROR;
 
@@ -113,12 +117,12 @@ void sm_handle_ams_in(const uint8_t *data){
       break;
     case 0x02:
       if (state.current_state == STATE_READY || state.current_state == STATE_ACTIVE){
-        PWM_powerground_control(data[1]);
         state.target_state = STATE_ACTIVE;        // READY -> ACTIVE
       }
       break;
     case 0xF0:
       if (state.current_state == STATE_INACTIVE){
+        target_powerground_status = data[1];
         state.target_state = STATE_CHARGING_PRECHARGE;
       }
       break;
@@ -157,6 +161,24 @@ void sm_precharge_discharge_manager(){
 
 }
 
+void sm_powerground_manager(){
+  if (target_powerground_status > 100){ //something went wrong
+    PWM_powerground_control(255);
+    current_powerground_status = target_powerground_status= 0;
+    return;
+  }
+
+  if (powerground_softstart_timer < HAL_GetTick()){
+    if (current_powerground_status < target_powerground_status ){
+      PWM_powerground_control(current_powerground_status + 1);
+      powerground_softstart_timer = HAL_GetTick() + 10;
+    } else if (current_powerground_status > target_powerground_status) {
+      PWM_powerground_control(current_powerground_status - 1);
+      powerground_softstart_timer = HAL_GetTick() + 10;
+    }
+  }
+}
+
 void sm_calibrate_powerground(){
   if (powerground_calibration_stage != 4 && state.current_state == STATE_PRECHARGE){
     switch (powerground_calibration_stage) {
@@ -187,6 +209,13 @@ void sm_calibrate_powerground(){
   }
 }
 
+void sm_balancing(){
+  for (int i = 0; i < 13; i++) {
+    amsConfigBalancing((1 << i), 0xF);
+  }
+  amsStartBalancing(0);
+}
+
 #warning TODO: add error checking for everything here
 void sm_check_errors(){  
   state.error_type.temperature_error = (error_data.error_sources & (1 << 0) || error_data.error_sources & (1 << 1) || error_data.error_sources & (1 << 4)) ? 1 : 0;
@@ -298,8 +327,7 @@ State sm_update_charging(){
     case STATE_DISCHARGE:
       return STATE_DISCHARGE;
     default:
-      //amsConfigBalancing((1 << 7), 0xF);
-      //amsStartBalancing(0);e
+
       return STATE_CHARGING;
   }
 }
@@ -403,7 +431,7 @@ void sm_test_cycle_states(){
     case STATE_ACTIVE:
       state.current_state = STATE_DISCHARGE;
       timestamp = HAL_GetTick() + 10000;
-      PWM_powerground_control(1);
+      PWM_powerground_control(10);
       break;
     case STATE_DISCHARGE:
       state.current_state = STATE_INACTIVE;