Files
CuboBmsFirmware/firmware/Core/Src/main.c
2023-03-29 20:05:42 +03:00

2995 lines
88 KiB
C

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
#include "rtc.h"
#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "stdint.h"
#include "generalDefines.h"
#include "stm32f1xx_hal.h"
#include "modDelay.h"
#include "modFlash.h"
#include "modPowerElectronics.h"
#include "modConfig.h"
#include "modStateOfCharge.h"
#include "modUART.h"
#include "driverSWStorageManager.h"
#include "mainDataTypes.h"
#include "DPC_Timeout.h"
#include "GSM.h"
#include "time.h"
#include "can.h"
#include "SD_Card.h"
#define LoByte(param) ((uint8_t *)&param)[0]
#define HiByte(param) ((uint8_t *)&param)[1]
#define LoLoWord(param) ((uint16_t *)&param)[0]
#define LoHiWord(param) ((uint16_t *)&param)[1]
#define HiLoWord(param) ((uint16_t *)&param)[2]
#define HiHiWord(param) ((uint16_t *)&param)[3]
#define LoWord(param) ((uint32_t *)&param)[0]
#define HiWord(param) ((uint32_t *)&param)[1]
#define __DEEP_DISCHARGE_RATIO 0.8 //As a percent of undervoltage
#define __STATUS_POWER_ON 1
#define __STATUS_POWER_OFF 2
#define __STATUS_CHARGE_ON 3 //Pilot contact exist
#define __STATUS_CELL_UNDERVOLTAGE 4 //Cell below discharge level
#define __STATUS_OVERLOAD 5 //Load current too high
#define __STATUS_OVERHEATING 6 //Temp too high
#define __STATUS_CHARGING_OVERVOLTAGE 7 //Cell voltage above max level
#define __STATUS_CHARGING_DISCONNECT 8 //Pilot contact disconnect
#define __STATUS_HEATING_ON 9 //
#define __STATUS_HEATING_OFF 10 //
#define __STATUS_TAKE_BRUSH 11 //Brush is in the upper state
#define __STATUS_ERROR_1 12
#define __STATUS_ERROR_2 13
#define __GLSTATUS_SHUTDOWN 1
#define __GLSTATUS_IDLE 2
#define __GLSTATUS_WORKING 3
#define __GLSTATUS_CHARGING 4
#define __GLSTATUS_ERROR 5
#define __DEFAULT_BATTERY_RESISTANCE 0.0
#define __BACKUP_TIMEOUT 30000
#define __GRT_PERIOD 600000//3600000
#define __DELAY_FOR_SIM 30000
//#define __GRT_PERIOD 600000
#define _ON 1
#define _OFF 0
#define __BLINK_INIT 1000
#define __BLINK_GSM_AND_SD_OK 500
#define __BLINK_SD_OK_NO_GSM 250
#define __BLINK_GSM_OK_NO_SD 750
#define __BLINK_ERROR 100
#define __SD_BUFFER_MAX_VAL 8
#define __SS_BUFFER_MAX_VAL 8
#define __FILENAME_UPDATE_TIMEOUT 10000
size_t Heap;
modConfigGeneralConfigStructTypedef *generalConfig;
modStateOfChargeStructTypeDef *generalStateOfCharge;
modPowerElectronicsPackStateTypedef packState;
uint16_t LED_Blink_Delay;
uint64_t TIM_Clock;
uint64_t Led_Timer;
uint64_t HTTP_timer;
uint8_t service_sw;
__IO uint8_t USB_On_Flag;
uint8_t UART_Buffer[1024];
uint8_t UART_Flag;
uint8_t UART_Permission_to_send;
SD_CARD_Global_Struct SD_Global_Struct;
SIM800_Global_Struct SIM800_Struct;
uint8_t CMD_Switch;
SIM800_Op_Commands CMD_SET;
void SIM_Processing();
uint8_t SIM_Module_Init();
SIM800_Op_States SIM_Module_REQUEST(SIM800_Op_Commands* CMD);
__IO uint8_t SS_Ready2Send_Flag;
__IO uint8_t SD_Ready2Send_Flag;
Time_Struct Test_time;
Time_Struct Current_Time;
Time_Struct SW_OFF_time;
__IO uint32_t SS_status_ptr;
uint8_t Pilot_Status = 0;
uint8_t Maximum_Charge_Current_Status = 0;
uint8_t Maximum_Voltage_Status = 0;
uint8_t Maximum_Temp_Status = 0;
uint8_t Maximum_Load_Current_Status = 0;
uint8_t Minimum_Voltage_Status = 0;
uint8_t Deep_Discharge_Status = 0;
uint8_t Brush_Status = 0;
uint64_t Battery_Serial;
float cellVoltageLow_Minimum = 0;
float cellVoltageLow_Minimum_Hyst = 0;
float cellVoltageHigh_Maximum = 0;
float cellVoltageHigh_Maximum_Hyst = 0;
float maxChargeCurrent = 0;
float maxLoadCurrent = 0;
float maxTemperature = 0;
float maxTemperature_Hyst = 0;
typedef struct{
uint64_t Last_time_param_send;
uint64_t Last_time_status_send;
uint64_t Last_data_update_time;
uint64_t Last_data_backup_time;
uint8_t Status_History_Buffer[__SS_BUFFER_MAX_VAL+2];
Time_Struct Status_History_time[__SS_BUFFER_MAX_VAL+2];
uint8_t Status_flag[16];
uint8_t Active_State; //idle/working/charging/error
uint8_t Previous_Active_State;
uint8_t Load_Params_After_Reboot;
Battery_Data_Struct Actual_data;
Battery_Data_Struct Param_History_Buffer[__SS_BUFFER_MAX_VAL+2];
uint8_t Param_History_Buffer_Counter;
uint8_t Param_History_Buffer_Position;
uint8_t Param_History_Sending_Counter;
uint8_t Param_Flag[16];
uint16_t Battery_Level_At_Start;
float Battery_Voltage_At_Start;
float Max_Charge_Current;
float Max_Load_Current;
uint8_t Status_History_Buffer_Counter;
uint8_t Status_History_Buffer_Position;
uint8_t Status_History_Sending_Counter;
Time_Struct Started_at_time;
Time_Struct Ended_at_time;
Time_Struct Event_time;
float Remaining_SOC_at_Start;
Time_Struct Shutdown_time;
Time_Struct Shutdown_prev_state_start_time;
}SimStatus_Struct_Typedef;
SimStatus_Struct_Typedef SimStatus_Struct;
typedef struct{
uint64_t Last_SD_Update_Time;
uint64_t Last_time_param_send;
uint64_t Last_time_status_send;
uint8_t Status_History_Buffer[__SD_BUFFER_MAX_VAL+2];
Time_Struct Status_History_time[__SD_BUFFER_MAX_VAL+2];
uint8_t Status_flag[16];
uint8_t Status_History_Buffer_Counter;
uint8_t Status_History_Buffer_Position;
uint8_t Status_History_Sending_Counter;
uint8_t Param_History_Buffer_Counter;
uint8_t Param_History_Buffer_Position;
uint8_t Param_History_Sending_Counter;
Battery_Data_Struct Param_History_Buffer[__SD_BUFFER_MAX_VAL+2];
uint8_t Active_State; //idle/working/charging/error
uint8_t Previous_Active_State;
uint8_t Load_Params_After_Reboot;
float Remaining_SOC_at_Start;
Time_Struct Started_at_time;
Time_Struct Ended_at_time;
Time_Struct Event_time;
Time_Struct Shutdown_time;
Time_Struct Shutdown_prev_state_start_time;
}SD_CARD_Struct_Typedef;
SD_CARD_Struct_Typedef SD_CARD_Struct;
//SS_status(1);
//SS_status_ptr++;
__IO uint64_t _global_clock;
uint8_t load_switch_state = 0;
uint8_t charge_switch_state = 0;
float currentZero_config = 0;
//#define _ADC_ZERO 3033
#define _ADC_ZERO currentZero_config
uint16_t export_adc_average_res = 0;
float Brush_Minimum_SoC = 0;
uint8_t Brush_Default_State = 0;
uint8_t check_pilot_flag_history = 1;
uint8_t check_minimum_voltage_flag_history = 1;
uint8_t check_maximum_voltage_flag_history = 1;
uint8_t check_maximum_temp_flag_history = 1;
ADC_HandleTypeDef hadc2;
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
DAC_HandleTypeDef hdac;
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi3;
UART_HandleTypeDef huart2;
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim6;
uint8_t OVP_counter = 0;
uint16_t load_current = 0;
uint16_t charge_current = 0;
float float_current = 0;
uint64_t output_control_clock = 0;
bool need_shunt_charging_contractor = false;
uint64_t shunt_charging_contractor_clock = 0;
uint64_t can1_transmit_clock = 0;
uint64_t can2_transmit_clock = 0;
#define __MA_WIN_SIZE (500)
#define __MA_ARRAY_QTY 2
/* Private function prototypes -----------------------------------------------*/
void Total_DeInit();
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC2_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
static void MX_DAC_Init(void);
static void MX_SPI1_Init(void);
//static void MX_SPI3_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM6_Init(void);
static void MX_TIM2_Init(void);
uint8_t SS_status(uint8_t type, Time_Struct* Event_time);
void Status_Save(uint8_t Type);
void Status_Clear(uint8_t Type);
void Save_data_to_Backup();
void Restore_shutdown_data();
void updateLimitsFromMem();
void modem_init();
uint8_t SS_param(Battery_Data_Struct* Source_Data);
void Parameters_Save();
void Update_parameters_for_sim();
void Parameters_Send_to_Buf(uint8_t State);
void Set_Shutdown_Data();
uint8_t SD_status(uint8_t type, Time_Struct* Event_time);
void SD_Status_Clear(uint8_t Type);
uint8_t SD_param(Battery_Data_Struct* Source_Data);
void SD_Params_Send_to_Buf(uint8_t State);
uint8_t SD_Mount();
void SD_Event_and_Param_Processing();
void SD_Card_data_init();
void SD_Status_Save(uint8_t Type);
uint8_t SD_Umount();
void SD_Update_Filename(SD_CARD_Global_Struct* source );
uint32_t last_usb_call = 0;
//void SS_status_power_on() {
//// static uint8_t comp_flag;
//// static uint8_t time_flag;
//
//// if(time_flag == 0) {
//
//// time_flag = 1;
//// }
//
//// if(comp_flag == 0) {
//// if(SS_status(__STATUS_POWER_ON)) {
//// comp_flag = 1;
//// }
//// }
//}
void usbTIM(uint8_t OnOff) {
if(OnOff) {
USB_On_Flag = 1;
//HAL_TIM_Base_Start_IT(&htim6);
last_usb_call = HAL_GetTick();
} else {
USB_On_Flag = 0;
//HAL_TIM_Base_Stop_IT(&htim6);
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
// testsi++;
if (htim->Instance == TIM2)
{
TimeoutMng();
TIM_Clock++;
}
else if (htim->Instance == TIM6)
{
libPacketTimerFunc();
// HAL_TIM_Base_Stop_IT(&htim6);
// HAL_GPIO_TogglePin(HL3_GPIO_Port, HL3_Pin);
// if(USB_On_Flag){
// if(USB_On_Flag){
modUARTTask();
// }
// }
//TimeoutMng();
// HAL_TIM_Base_Start_IT(&htim6);
}
}
void charge_switch(uint8_t state) {
if(state){
HAL_GPIO_WritePin(Output_5_GPIO_Port, Output_5_Pin, 1);
} else {
HAL_GPIO_WritePin(Output_5_GPIO_Port, Output_5_Pin, 0);
}
}
float export_real_capacity;
void load_switch(uint8_t state) {
if(state){
HAL_GPIO_WritePin(Output_4_GPIO_Port, Output_4_Pin, 1);
} else {
HAL_GPIO_WritePin(Output_4_GPIO_Port, Output_4_Pin, 0);
}
}
/* USER CODE END 0 */
uint16_t MA_Filter(uint16_t input, uint8_t array)
{
uint16_t Result = 0;
static uint32_t ma_n[__MA_ARRAY_QTY];
static uint32_t ma_array[__MA_ARRAY_QTY][__MA_WIN_SIZE];
static uint32_t pre_out[__MA_ARRAY_QTY];
pre_out[array] = pre_out[array] + (input - ma_array[array][ma_n[array]] );
ma_array[array][ma_n[array]] = input;
ma_n[array] = (ma_n[array]+1)% __MA_WIN_SIZE;
Result = (uint32_t)pre_out[array] / __MA_WIN_SIZE;
return Result;
}
IWDG_HandleTypeDef handleIWDG;
void mainWatchDogReset(void) {
HAL_IWDG_Refresh(&handleIWDG);
}
void mainWatchDogInitAndStart(void) {
handleIWDG.Instance = IWDG;
handleIWDG.Init.Prescaler = IWDG_PRESCALER_64;
// handleIWDG.Init.Window = 4095;
handleIWDG.Init.Reload = 4095;
if (HAL_IWDG_Init(&handleIWDG) != HAL_OK) {
Error_Handler();
}
// HAL_IWDG_
// if(HAL_IWDG_Start(&handleIWDG) != HAL_OK) {
// Error_Handler();
// }
}
void Get_Shunt_Current() {
// static uint16_t adc;
// static uint16_t adc_average[100];
// static uint8_t adc_average_cnt = 0;
// static uint32_t adc_average_sum = 0;
static uint32_t adc_average_res = 0;
currentZero_config = generalConfig->shuntLCFactor;
HAL_ADC_Start(&hadc2);
adc_average_res = MA_Filter((HAL_ADC_GetValue(&hadc2)), 1);
export_adc_average_res = adc_average_res;
//export_adc_average_res = 3033;
if(adc_average_res >= _ADC_ZERO){
if((adc_average_res - _ADC_ZERO) > 10) { // load
//load_current = (adc_average_res - 3060) * 0.34;
float_current = (adc_average_res - _ADC_ZERO + generalConfig->floatCurrentK1) * generalConfig->floatCurrentK2;
float_current = -float_current;
} else {
load_current = 0;
charge_current = 0;
float_current = 0;
}
} else {
if ((_ADC_ZERO - adc_average_res) > 10) {
//charge_current = ;
float_current = (_ADC_ZERO - adc_average_res + generalConfig->floatCurrentK1) * generalConfig->floatCurrentK2;
} else {
load_current = 0;
charge_current = 0;
float_current = 0;
}
}
}
void USB_Check_Timeout() {
if((HAL_GetTick() - last_usb_call) > 10000) {
usbTIM(0);
}
}
uint8_t Check_Pilot(){ // 1 - charging // 0 - no charging
uint8_t res = 0;
if(HAL_GPIO_ReadPin(Input_3_GPIO_Port, Input_3_Pin)){
HAL_GPIO_WritePin(Charging_GPIO_Port, Charging_Pin, 0); // charging
res = 1;
return res;
} else {
HAL_GPIO_WritePin(Charging_GPIO_Port, Charging_Pin, 1); // no charging
res = 0;
OVP_counter = 0;
return res;
}
}
/*
*
modCommandsPrintf("NoOfCells : %u",generalConfig->noOfCellsSeries);
modCommandsPrintf("batteryCapacity : %.2fAh",generalConfig->batteryCapacity);
modCommandsPrintf("cellHardUnderVoltage : %.3fV",generalConfig->cellHardUnderVoltage);
modCommandsPrintf("cellHardOverVoltage : %.3fV",generalConfig->cellHardOverVoltage);
modCommandsPrintf("cellLCSoftUnderVoltage : %.3fV",generalConfig->cellLCSoftUnderVoltage);
modCommandsPrintf("cellSoftOverVoltage : %.3fV",generalConfig->cellSoftOverVoltage);
modCommandsPrintf("cellBalanceStart : %.3fV",generalConfig->cellBalanceStart);
*/
uint8_t Check_Maximum_Voltage(){ // 0 - voltage too high // 1 - voltage normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 2.2C maximum
//if(packState.cellVoltageHigh >= 3.65){
if(packState.cellVoltageHigh >= cellVoltageHigh_Maximum){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
OVP_counter++;
} else if ( (( (HAL_GetTick()) - timer_to_error) > 2000) ) {
res = 0;
}
//} else if (packState.cellVoltageHigh < 3.5) {
} else if (packState.cellVoltageHigh < cellVoltageHigh_Maximum_Hyst) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
if(OVP_counter < 3) {
res = 1;
}
}
}
return res;
}
uint8_t Check_Minimum_Voltage(){ // 0 - voltage too low // 1 - voltage normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 2.2C maximum
//if(packState.cellVoltageLow <= 2.5){
if(packState.cellVoltageLow <= cellVoltageLow_Minimum){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_error) > 2000) ) {
//check_minimum_voltage_flag_history = 0;
res = 0;
}
//} else if (packState.cellVoltageLow > 2.7) {
} else if (packState.cellVoltageLow > cellVoltageLow_Minimum_Hyst) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
res = 1;
}
}
return res;
}
uint8_t Check_Deep_Discharge(){ // 0 - voltage too low // 1 - voltage normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 2.2C maximum
//if(packState.cellVoltageLow <= 2.5){
if(packState.cellVoltageLow <= cellVoltageLow_Minimum * __DEEP_DISCHARGE_RATIO){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_error) > 2000) ) {
//check_minimum_voltage_flag_history = 0;
res = 0;
}
//} else if (packState.cellVoltageLow > 2.7) {
} else if (packState.cellVoltageLow > cellVoltageLow_Minimum_Hyst * __DEEP_DISCHARGE_RATIO) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
res = 1;
}
}
return res;
}
uint8_t Check_Maximum_Charge_Current(){ // 0 - current too high // 1 - normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 1C
//if(float_current >= 144){
if(float_current >= maxChargeCurrent){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_error) > 2000) ) {
res = 0;
}
//} else if (float_current < 144) {
} else if (float_current < maxChargeCurrent) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
res = 1;
}
}
return res;
}
uint8_t Check_Maximum_Load_Current(){ // // 0 - current too high // 1 - normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 2.2C maximum
//if(float_current <= -315){
if(float_current <= -maxLoadCurrent){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_error) > 2000) ) {
res = 0;
}
//} else if (float_current > -315) {
} else if (float_current > -maxLoadCurrent) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
res = 1;
}
}
return res;
}
uint8_t Check_Maximum_Temp() { // 0 - too hot // 1 - normal
static uint8_t res = 1;
static uint8_t error_counter = 0;
static uint8_t first_time_normal_flag = 0;
static uint8_t first_time_error_flag = 0;
static uint32_t timer_to_normal = 0;
static uint32_t timer_to_error = 0;
// 2.2C maximum
if(packState.tempBatteryHigh >= maxTemperature){
timer_to_normal = 0;
first_time_normal_flag = 0;
if(first_time_error_flag == 0) {
error_counter++;
first_time_error_flag = 1;
timer_to_error = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_error) > 5000) ) {
res = 0;
}
} else if (packState.tempBatteryHigh < maxTemperature_Hyst) {
timer_to_error = 0;
first_time_error_flag = 0;
if (first_time_normal_flag == 0) {
first_time_normal_flag = 1;
timer_to_normal = HAL_GetTick();
} else if ( (( (HAL_GetTick()) - timer_to_normal) > 5000) ) {
res = 1;
}
}
return res;
}
void Display_Control() {
uint32_t voltage_out = 0;
// 2700 - 100%
// x - soc
// soc = 100x/2700
// x = 2700soc/100
// voltage_out = packState.SoC * 100 / 2685;
//voltage_out = 100 * 100 / 2685;
//voltage_out = 100 * 4.95 / 100 * 2685 / 4.95;
// voltage_out = 2685 * packState.SoC / 100;
voltage_out = 2481 * packState.SoC / 100;
//voltage_out = 2481 * 6 / 100;
// voltage_out = 2400;
//voltage_out = 2685 * 100 / 100;
//voltage_out = 2685;
HAL_DAC_Start(&hdac,DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac,DAC_CHANNEL_1,DAC_ALIGN_12B_R,voltage_out);
}
void Do_Balance() {
if (packState.cellVoltageMisMatch > 0) {
}
}
void heart_beat(){
static uint32_t timer = 0;
if(( (HAL_GetTick()) - timer ) > LED_Blink_Delay) {
//HAL_GPIO_TogglePin(HL3_GPIO_Port, HL3_Pin);
HAL_GPIO_TogglePin(HL3_GPIO_Port, HL5_Pin);
// HAL_GPIO_TogglePin(HL3_GPIO_Port, HL1_Pin);
//HAL_GPIO_TogglePin(HL2_GPIO_Port, HL2_Pin);
timer = HAL_GetTick();
}
}
void Check_Status() {
Get_Shunt_Current();
Pilot_Status = Check_Pilot();
Maximum_Charge_Current_Status = Check_Maximum_Charge_Current();
Maximum_Voltage_Status = Check_Maximum_Voltage();
Maximum_Temp_Status = Check_Maximum_Temp();
Maximum_Load_Current_Status = Check_Maximum_Load_Current();
Minimum_Voltage_Status = Check_Minimum_Voltage();
Deep_Discharge_Status = Check_Deep_Discharge();
if (Pilot_Status && float_current<0){ //charge current should be positive
float_current = -float_current;
}
else if (!Pilot_Status && float_current>0){ //load current should be negative
float_current = -float_current;
}
if (float_current>0) {
charge_current = float_current;
load_current = 0;
}
else if (float_current<0) {
load_current = -float_current;
charge_current = 0;
}
}
void Check_Events_and_Parameters(){
if (TIM_Clock - SimStatus_Struct.Last_data_update_time>1000){
SimStatus_Struct.Last_data_update_time = TIM_Clock;
Update_parameters_for_sim();
}
if (TIM_Clock- SimStatus_Struct.Last_data_backup_time>__BACKUP_TIMEOUT){
Save_data_to_Backup();
SimStatus_Struct.Last_data_backup_time = TIM_Clock;
}
//Generating HTTP Events
if (Pilot_Status) {
Status_Save(__STATUS_CHARGE_ON);
SD_Status_Save(__STATUS_CHARGE_ON);
Status_Clear(__STATUS_CHARGING_DISCONNECT);
SD_Status_Clear(__STATUS_CHARGING_DISCONNECT);
}
else if (!Pilot_Status) {
Status_Save(__STATUS_CHARGING_DISCONNECT);
SD_Status_Save(__STATUS_CHARGING_DISCONNECT);
Status_Clear(__STATUS_CHARGE_ON);
SD_Status_Clear(__STATUS_CHARGE_ON);
}
if (Maximum_Load_Current_Status) {
Status_Clear(__STATUS_OVERLOAD);
SD_Status_Clear(__STATUS_OVERLOAD);
}
else if (!Maximum_Load_Current_Status) {
Status_Save(__STATUS_OVERLOAD);
SD_Status_Save(__STATUS_OVERLOAD);
}
if (Maximum_Voltage_Status) {
Status_Clear(__STATUS_CHARGING_OVERVOLTAGE);
SD_Status_Clear(__STATUS_CHARGING_OVERVOLTAGE);
}
else if (!Maximum_Voltage_Status) {
Status_Save(__STATUS_CHARGING_OVERVOLTAGE);
SD_Status_Save(__STATUS_CHARGING_OVERVOLTAGE);
}
if (Minimum_Voltage_Status) {
Status_Clear(__STATUS_CELL_UNDERVOLTAGE);
SD_Status_Clear(__STATUS_CELL_UNDERVOLTAGE);
}
else if (!Minimum_Voltage_Status) {
Status_Save(__STATUS_CELL_UNDERVOLTAGE);
SD_Status_Save(__STATUS_CELL_UNDERVOLTAGE);
}
if (Maximum_Temp_Status) {
Status_Clear(__STATUS_OVERHEATING);
SD_Status_Clear(__STATUS_OVERHEATING);
}
else if (!Maximum_Temp_Status) {
Status_Save(__STATUS_OVERHEATING);
SD_Status_Save(__STATUS_OVERHEATING);
}
if (Brush_Status) {
Status_Save(__STATUS_TAKE_BRUSH);
SD_Status_Save(__STATUS_TAKE_BRUSH);
}
else if (!Brush_Status) {
Status_Clear(__STATUS_TAKE_BRUSH);
SD_Status_Clear(__STATUS_TAKE_BRUSH);
}
//Generating HTTP Params
if (Pilot_Status){
SimStatus_Struct.Active_State = __GLSTATUS_CHARGING;
}
else if(!Pilot_Status && load_current>0){
SimStatus_Struct.Active_State = __GLSTATUS_WORKING;
}
else SimStatus_Struct.Active_State = __GLSTATUS_IDLE;
if(SimStatus_Struct.Active_State!=SimStatus_Struct.Previous_Active_State){
Parameters_Send_to_Buf(SimStatus_Struct.Previous_Active_State);
SD_Params_Send_to_Buf(SimStatus_Struct.Previous_Active_State);
Parameters_Save();
SimStatus_Struct.Last_time_param_send= TIM_Clock;
}
if (TIM_Clock-SimStatus_Struct.Last_time_param_send>600000){
SimStatus_Struct.Last_time_param_send= TIM_Clock;
Parameters_Send_to_Buf(SimStatus_Struct.Active_State);
SD_Params_Send_to_Buf(SimStatus_Struct.Active_State);
Parameters_Save();
}
if (SimStatus_Struct.Active_State==__GLSTATUS_CHARGING){
if (SimStatus_Struct.Max_Charge_Current < charge_current) SimStatus_Struct.Max_Charge_Current = charge_current;
SimStatus_Struct.Max_Load_Current = 0;
}
else if (SimStatus_Struct.Active_State==__GLSTATUS_WORKING || SimStatus_Struct.Active_State==__GLSTATUS_IDLE ){
if (SimStatus_Struct.Max_Load_Current < load_current) SimStatus_Struct.Max_Load_Current = load_current;
SimStatus_Struct.Max_Charge_Current = 0;
}
}
void updateLimitsFromMem(){
/*
uint8_t cellVoltageLow_Minimum = 0;
uint8_t cellVoltageLow_Minimum_Hyst = 0;
uint8_t cellVoltageHigh_Maximum = 0;
uint8_t cellVoltageHigh_Maximum_Hyst = 0;
uint8_t maxChargeCurrent = 0;
uint8_t maxLoadCurrent = 0;
*/
//modPowerElectronicsGeneralConfigHandle->cellBalanceStart
/*
cellHardUnderVoltage
cellHardOverVoltage
cellSoftOverVoltage
cellLCSoftUnderVoltage
maxAllowedCurrent
maxMismatchThreshold
modCommandsPrintf("NoOfCells : %u",generalConfig->noOfCellsSeries);
modCommandsPrintf("batteryCapacity : %.2fAh",generalConfig->batteryCapacity);
modCommandsPrintf("cellHardUnderVoltage : %.3fV",generalConfig->cellHardUnderVoltage);
modCommandsPrintf("cellHardOverVoltage : %.3fV",generalConfig->cellHardOverVoltage);
modCommandsPrintf("cellLCSoftUnderVoltage : %.3fV",generalConfig->cellLCSoftUnderVoltage);
modCommandsPrintf("cellSoftOverVoltage : %.3fV",generalConfig->cellSoftOverVoltage);
modCommandsPrintf("cellBalanceStart : %.3fV",generalConfig->cellBalanceStart);
*/
cellVoltageLow_Minimum = generalConfig->cellHardUnderVoltage;
cellVoltageLow_Minimum_Hyst = generalConfig->cellLCSoftUnderVoltage;
cellVoltageHigh_Maximum = generalConfig->cellHardOverVoltage;
cellVoltageHigh_Maximum_Hyst = generalConfig->cellSoftOverVoltage;
maxChargeCurrent = generalConfig->maxAllowedCurrent;
maxLoadCurrent = generalConfig->maxMismatchThreshold;
maxTemperature = generalConfig->allowedTempBattChargingMax;
maxTemperature_Hyst = generalConfig->allowedTempBattChargingMin;
}
//void Brush_Control() {
// //Output_2_Pin GPIO_PIN_2
// //Output_2_GPIO_Port GPIOE
//
// Brush_Minimum_SoC = generalConfig->minimalPrechargePercentage;
// Brush_Default_State = generalConfig->timeoutLCPreCharge;
//
// if(packState.SoC < Brush_Minimum_SoC) {
// HAL_GPIO_WritePin(Output_2_GPIO_Port, Output_2_Pin, !Brush_Default_State);
// Brush_Status = 1; //Brush is Up
// } else {
// HAL_GPIO_WritePin(Output_2_GPIO_Port, Output_2_Pin, Brush_Default_State);
// Brush_Status = 0; //Brush is down
// }
//}
void outputControl()
{
if ((TIM_Clock - output_control_clock) < 100)
{
return;
}
// 2 output handle
if (generalConfig->chargeBatteryOutputChecked)
{
GPIO_PinState chargeContactorState = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_5);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, chargeContactorState);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_0, GPIO_PIN_RESET);
}
// 3 output handle
if (!generalConfig->brushOrShuntMode) // brush mode
{
if (packState.SoC <= generalConfig->brushUsageSocThreshold)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, generalConfig->brushOrShuntOutputChecked ? GPIO_PIN_RESET : GPIO_PIN_SET);
else
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, generalConfig->brushOrShuntOutputChecked ? GPIO_PIN_SET : GPIO_PIN_RESET);
Brush_Status = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_1);
}
else // shunt mode
{
if (generalConfig->brushOrShuntOutputChecked)
{
GPIO_PinState loadContactorState = HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4);
if (loadContactorState == GPIO_PIN_SET && !need_shunt_charging_contractor)
{
need_shunt_charging_contractor = true;
shunt_charging_contractor_clock = TIM_Clock;
}
if (loadContactorState == GPIO_PIN_SET && need_shunt_charging_contractor &&
(TIM_Clock - shunt_charging_contractor_clock) >= generalConfig->shuntChargingContactorDelay * 1000)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
}
if (loadContactorState == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
need_shunt_charging_contractor = false;
}
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
need_shunt_charging_contractor = false;
}
}
// 4 output handle
if (generalConfig->coolingOutputChecked)
{
if (packState.tempBatteryHigh <= generalConfig->coolingStopThreshold)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
if (packState.tempBatteryHigh >= generalConfig->coolingStartThreshold)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
}
// 5 output handle
if (generalConfig->heatingOutputChecked)
{
if (packState.tempBatteryLow >= generalConfig->heatingStopThreshold)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
if (packState.tempBatteryLow <= generalConfig->heatingStartThreshold)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);
}
output_control_clock = TIM_Clock;
}
void transmitCan1Packet()
{
if ((TIM_Clock - can1_transmit_clock) < 1000)
{
return;
}
uint8_t data1[8] = {0x45};
CAN_Transmit(300, data1, 8, &hcan1);
can1_transmit_clock = TIM_Clock;
return;
CAN_TxHeaderTypeDef header;
header.IDE = CAN_ID_STD;
header.RTR = CAN_RTR_DATA;
header.StdId = 0x444;
header.DLC = 1;
uint8_t data[32] = {};
uint32_t mailbox = 0;
// sending SOC, SOH and number of cells
uint16_t id = 0x101;
memcpy(data, &id, sizeof(id));
memcpy(data + 2, &packState.SoC, sizeof(packState.SoC));
memcpy(data + 6, &packState.SoCCapacityAh, sizeof(packState.SoCCapacityAh));
memcpy(data + 10, &generalConfig->noOfCellsSeries, sizeof(generalConfig->noOfCellsSeries));
header.DLC = 11;
HAL_CAN_AddTxMessage(&hcan1, &header, data, &mailbox);
// sending charge current, discharge current // TODO
id = 0x102;
memcpy(data, &id, sizeof(id));
memcpy(data + 2, &packState.packCurrent, sizeof(packState.packCurrent));
memcpy(data + 6, &packState.loCurrentLoadCurrent, sizeof(packState.loCurrentLoadCurrent));
header.DLC = 10;
HAL_CAN_AddTxMessage(&hcan1, &header, data, &mailbox);
// sending BMS state, input state, output state // TODO
id = 0x103;
memcpy(data, &id, sizeof(id));
memcpy(data + 2, &packState.cellVoltageLow, sizeof(packState.cellVoltageLow));
memcpy(data + 6, &packState.cellVoltageAverage, sizeof(packState.cellVoltageAverage));
memcpy(data + 10, &packState.cellVoltageHigh, sizeof(packState.cellVoltageHigh));
header.DLC = 12;
HAL_CAN_AddTxMessage(&hcan1, &header, data, &mailbox);
// sending cell voltages
id = 0x200;
for (int cellPointer = 0; cellPointer < generalConfig->noOfCellsSeries * generalConfig->noOfParallelModules; ++cellPointer)
{
++id;
memcpy(data, &id, sizeof(id));
float voltage = 0;
if (packState.cellVoltagesIndividual[cellPointer].cellBleedActive)
voltage = packState.cellVoltagesIndividual[cellPointer].cellVoltage * -1000;
else
voltage = packState.cellVoltagesIndividual[cellPointer].cellVoltage * 1000;
memcpy(data + 2, &voltage, sizeof(voltage));
header.DLC = 6;
HAL_CAN_AddTxMessage(&hcan1, &header, data, &mailbox);
}
// sending temperatures
id = 0x300;
for (int sensorPointer = 0; sensorPointer < NoOfTempSensors; ++sensorPointer)
{
++id;
memcpy(data, &id, sizeof(id));
float temperature = packState.temperatures[sensorPointer];
memcpy(data + 2, &temperature, sizeof(temperature));
header.DLC = 6;
HAL_CAN_AddTxMessage(&hcan1, &header, data, &mailbox);
}
can1_transmit_clock = TIM_Clock;
}
int getIndexBySoc()
{
const float soc = packState.SoC;
if (soc == 0)
{
return 0;
}
else if (soc <= 10 && soc > 0)
{
return 1;
}
else if (soc <= 20 && soc > 10)
{
return 2;
}
else if (soc <= 30 && soc > 20)
{
return 3;
}
else if (soc <= 40 && soc > 30)
{
return 4;
}
else if (soc <= 50 && soc > 40)
{
return 5;
}
else if (soc <= 60 && soc > 50)
{
return 6;
}
else if (soc <= 70 && soc > 60)
{
return 7;
}
else if (soc <= 80 && soc > 70)
{
return 8;
}
else if (soc <= 95 && soc > 80)
{
return 9;
}
else if (soc <= 100 && soc > 95)
{
return 10;
}
return -1;
}
int getIndexByTemperature()
{
const float temp = packState.tempBatteryAverage;
if (temp > 0)
{
return 0;
}
else if (temp < 2 && temp >= 0)
{
return 1;
}
else if (temp < 7 && temp >= 2)
{
return 2;
}
else if (temp < 15 && temp >= 7)
{
return 3;
}
else if (temp < 20 && temp >= 15)
{
return 4;
}
else if (temp < 45 && temp >= 20)
{
return 5;
}
else if (temp < 50 && temp >= 45)
{
return 6;
}
else if (temp < 55 && temp >= 50)
{
return 7;
}
else if (temp >= 55)
{
return 8;
}
return -1;
}
void transmitCan2Packet()
{
if ((TIM_Clock - can2_transmit_clock) < 500)
{
return;
}
can2_transmit_clock = TIM_Clock;
uint8_t buffer[8] = {0};
// sending heartbeat command
const uint32_t rtr = 1;
memcpy(buffer, &rtr, sizeof(rtr));
CAN_Transmit(0x500, buffer, 8, &hcan2);
// sending common current and voltage command
memcpy(buffer, &packState.packCurrent, sizeof(packState.packCurrent));
memcpy(buffer + 4, &packState.packVoltage, sizeof(packState.packVoltage));
CAN_Transmit(0x501, buffer, 8, &hcan2);
// sending charge voltages (start, end) command
memcpy(buffer, &generalConfig->cellLCSoftUnderVoltage, sizeof(generalConfig->cellLCSoftUnderVoltage));
memcpy(buffer + 4, &generalConfig->cellSoftOverVoltage, sizeof(generalConfig->cellSoftOverVoltage));
CAN_Transmit(0x502, buffer, 8, &hcan2);
// sending fault voltages (under, over) command
memcpy(buffer, &generalConfig->cellHardUnderVoltage, sizeof(generalConfig->cellHardUnderVoltage));
memcpy(buffer + 4, &generalConfig->cellHardOverVoltage, sizeof(generalConfig->cellHardOverVoltage));
CAN_Transmit(0x503, buffer, 8, &hcan2);
// sending charge current command
const int socIndex = getIndexBySoc();
const int temperatureIndex = getIndexByTemperature();
float tableCurrent = 0;
float chargeEndingCurrent = 5; // TODO move to generalConfig
if (socIndex != -1 && temperatureIndex != -1)
{
float tableValue = generalConfig->externalChargeCurrentTable[temperatureIndex][socIndex];
float pureCurrent = generalConfig->externalChargeUnitTable[temperatureIndex][socIndex];
tableCurrent = pureCurrent ? tableValue : generalConfig->batteryCapacity * tableValue;
}
memcpy(buffer, &tableCurrent, sizeof(tableCurrent));
memcpy(buffer + 4, &chargeEndingCurrent, sizeof(chargeEndingCurrent));
CAN_Transmit(0x504, buffer, 8, &hcan2);
// sending charge permission, charge ending and charge/discharge state command
const bool chargeAllowed = packState.chargeAllowed;
const bool chargeEnding = packState.SoC > 95;
const bool chargeSwitchState = charge_switch_state;
uint32_t data = chargeAllowed;
data |= (chargeEnding << 1);
data |= (chargeSwitchState << 2);
memset(buffer, '\0', sizeof(buffer));
memcpy(buffer, &data, sizeof(data));
CAN_Transmit(0x505, buffer, 8, &hcan2);
}
void modem_init(){
SIM800_Var_Init(&SIM800_Struct);
HTTP_Data_Init(&SIM800_Struct);
DPC_TO_Init();
// HAL_Delay(2000);
HAL_UARTEx_ReceiveToIdle_IT(&huart2, (uint8_t*)UART_Buffer, 1023);
DPC_TO_Set(TO_LED,1000);
DPC_TO_Set(TO_UART,100);
DPC_TO_Set(TO_SIM_TIMEOUT, 60000);
HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_SET);
// SIM800_Struct.Default_Longitude = "-115.812477";
// SIM800_Struct.Default_Latitude = "37.236992";
SIM800_Struct.Default_Longitude = "5.257022";
SIM800_Struct.Default_Latitude = "50.527822";
SIM800_Struct.BATTERY_DATA.Serial = Battery_Serial;
SIM800_Struct.BATTERY_DATA.Battery_cond_ID = 5;
RTC_Get_Values(&SIM800_Struct.BATTERY_DATA.Event_time);
RTC_Get_Values(&SIM800_Struct.BATTERY_DATA.Started_At_Time);
RTC_Get_Values(&SIM800_Struct.BATTERY_DATA.Ended_At_Time);
SIM800_Struct.BATTERY_DATA.Status_Indication = 1;
SIM800_Struct.BATTERY_DATA.Energy_Sum = 280;
SIM800_Struct.BATTERY_DATA.Battery_Level_At_Start = 15;
SIM800_Struct.BATTERY_DATA.Battery_Level_At_End = 75;
SIM800_Struct.BATTERY_DATA.Battery_Voltage_At_Start = 23.6;
SIM800_Struct.BATTERY_DATA.Battery_Voltage_At_End = 27.5;
SIM800_Struct.BATTERY_DATA.Battery_Temperature_At_End = 22;
SIM800_Struct.BATTERY_DATA.Maximum_Load_Current = 150;
SIM800_Struct.BATTERY_DATA.Maximum_Charge_Current = 120;
SIM800_Struct.BATTERY_DATA.Internal_Resistance = 8.2111011;
SIM800_Struct.BATTERY_DATA.Moderated = 0;
Battery_Data_to_String_Converter(&SIM800_Struct);
//HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_RESET);
// SS_status(__STATUS_POWER_ON);
}
void SD_Card_data_init(){
SD_Card_Var_Init(&SD_Global_Struct);
memcpy(&SD_Global_Struct.BATTERY_DATA, &SIM800_Struct.BATTERY_DATA, sizeof(SIM800_Struct.BATTERY_DATA));
DPC_TO_Set(TO_SD_Filename, __FILENAME_UPDATE_TIMEOUT);
}
void SD_Status_Save(uint8_t Type){
if (SD_Global_Struct.SD_CARD_ChipDetect){
if (!SD_CARD_Struct.Status_flag[Type]){
if (TIM_Clock-SD_CARD_Struct.Last_time_status_send>1000 || Type==__STATUS_POWER_OFF || Type==__STATUS_POWER_ON){
SD_CARD_Struct.Status_flag[Type] = 1;
SD_CARD_Struct.Status_History_Buffer[SD_CARD_Struct.Status_History_Buffer_Position]=Type;
if (Type==2) memcpy(&SD_CARD_Struct.Status_History_time[SD_CARD_Struct.Status_History_Buffer_Position], &SD_CARD_Struct.Shutdown_time, sizeof(SD_CARD_Struct.Shutdown_time));
else RTC_Get_Values(&SD_CARD_Struct.Status_History_time[SD_CARD_Struct.Status_History_Buffer_Position]);
SD_CARD_Struct.Status_History_Buffer_Counter++;
SD_CARD_Struct.Status_History_Buffer_Position++;
SD_CARD_Struct.Last_time_status_send=TIM_Clock;
}
}
}
if (SD_CARD_Struct.Status_History_Buffer_Counter>9) SD_CARD_Struct.Status_History_Buffer_Counter=9;
if (SD_CARD_Struct.Status_History_Buffer_Position>9) SD_CARD_Struct.Status_History_Buffer_Position=9;
}
void Status_Save(uint8_t Type){
if (SS_Ready2Send_Flag){
if (!SimStatus_Struct.Status_flag[Type]){
if (TIM_Clock-SimStatus_Struct.Last_time_status_send>1000 || Type==__STATUS_POWER_OFF || Type==__STATUS_POWER_ON){
SimStatus_Struct.Status_flag[Type] = 1;
SimStatus_Struct.Status_History_Buffer[SimStatus_Struct.Status_History_Buffer_Position]=Type;
if (Type==2) memcpy(&SimStatus_Struct.Status_History_time[SimStatus_Struct.Status_History_Buffer_Position], &SimStatus_Struct.Shutdown_time, sizeof(SimStatus_Struct.Shutdown_time));
else RTC_Get_Values(&SimStatus_Struct.Status_History_time[SimStatus_Struct.Status_History_Buffer_Position]);
SimStatus_Struct.Status_History_Buffer_Counter++;
SimStatus_Struct.Status_History_Buffer_Position++;
SimStatus_Struct.Last_time_status_send=TIM_Clock;
}
}
}
if (SimStatus_Struct.Status_History_Buffer_Counter>__SS_BUFFER_MAX_VAL) SimStatus_Struct.Status_History_Buffer_Counter=__SS_BUFFER_MAX_VAL;
if (SimStatus_Struct.Status_History_Buffer_Position>__SS_BUFFER_MAX_VAL) SimStatus_Struct.Status_History_Buffer_Position=__SS_BUFFER_MAX_VAL;
}
void Status_Clear(uint8_t Type){
if (SimStatus_Struct.Status_flag[Type]){
SimStatus_Struct.Status_flag[Type]=0;
}
}
void SD_Status_Clear(uint8_t Type){
if (SD_CARD_Struct.Status_flag[Type]){
SD_CARD_Struct.Status_flag[Type]=0;
}
}
void SD_Event_and_Param_Processing(){
if (SD_CARD_Struct.Status_History_Buffer_Counter!=0){
if (SD_Global_Struct.Mount_Flag){
if (SD_status(SD_CARD_Struct.Status_History_Buffer[SD_CARD_Struct.Status_History_Sending_Counter], &SD_CARD_Struct.Status_History_time[SD_CARD_Struct.Status_History_Sending_Counter])){
SD_CARD_Struct.Status_History_Buffer_Counter--;
SD_CARD_Struct.Status_History_Sending_Counter++;
if (SD_CARD_Struct.Status_History_Sending_Counter>9) SD_CARD_Struct.Status_History_Sending_Counter=0;
if (SD_CARD_Struct.Status_History_Buffer_Counter==0){
SD_CARD_Struct.Status_History_Sending_Counter=0;
SD_CARD_Struct.Status_History_Buffer_Position=0;
}
}
}
else {
SD_Mount();
}
}
else if (SD_CARD_Struct.Param_History_Buffer_Counter!=0){
if (SD_Global_Struct.Mount_Flag){
if (SD_param(&SD_CARD_Struct.Param_History_Buffer[SD_CARD_Struct.Param_History_Sending_Counter])){
SD_CARD_Struct.Param_History_Buffer_Counter--;
SD_CARD_Struct.Param_History_Sending_Counter++;
if (SD_CARD_Struct.Param_History_Sending_Counter>5) SD_CARD_Struct.Param_History_Sending_Counter=0;
if(SD_CARD_Struct.Param_History_Buffer_Counter==0){
SD_CARD_Struct.Param_History_Sending_Counter=0;
SD_CARD_Struct.Param_History_Buffer_Position=0;
}
}
}
else {
SD_Mount();
}
}
else {
if (SD_Global_Struct.Mount_Flag){
SD_Global_Struct.Mount_Flag = !SD_Umount();
}
}
if (SD_CARD_Struct.Param_History_Buffer_Counter==0){
SD_CARD_Struct.Param_History_Sending_Counter=0;
SD_CARD_Struct.Param_History_Buffer_Position=0;
}
if (SD_CARD_Struct.Status_History_Buffer_Counter==0){
SD_CARD_Struct.Status_History_Sending_Counter=0;
SD_CARD_Struct.Status_History_Buffer_Position=0;
}
}
void SS_Event_and_Param_Processing(){
if (SimStatus_Struct.Status_History_Buffer_Counter!=0){
if (SS_status(SimStatus_Struct.Status_History_Buffer[SimStatus_Struct.Status_History_Sending_Counter], &SimStatus_Struct.Status_History_time[SimStatus_Struct.Status_History_Sending_Counter])){
SimStatus_Struct.Status_History_Buffer_Counter--;
SimStatus_Struct.Status_History_Sending_Counter++;
if (SimStatus_Struct.Status_History_Sending_Counter>9) SimStatus_Struct.Status_History_Sending_Counter=0;
if (SimStatus_Struct.Status_History_Buffer_Counter==0){
SimStatus_Struct.Status_History_Sending_Counter=0;
SimStatus_Struct.Status_History_Buffer_Position=0;
}
}
}
else if (SimStatus_Struct.Param_History_Buffer_Counter!=0){
if (SS_param(&SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Sending_Counter])){
SimStatus_Struct.Param_History_Buffer_Counter--;
SimStatus_Struct.Param_History_Sending_Counter++;
if (SimStatus_Struct.Param_History_Sending_Counter>5) SimStatus_Struct.Param_History_Sending_Counter=0;
if(SimStatus_Struct.Param_History_Buffer_Counter==0){
SimStatus_Struct.Param_History_Sending_Counter=0;
SimStatus_Struct.Param_History_Buffer_Position=0;
}
}
}
if (SimStatus_Struct.Param_History_Buffer_Counter==0){
SimStatus_Struct.Param_History_Sending_Counter=0;
SimStatus_Struct.Param_History_Buffer_Position=0;
}
if (SimStatus_Struct.Status_History_Buffer_Counter==0){
SimStatus_Struct.Status_History_Sending_Counter=0;
SimStatus_Struct.Status_History_Buffer_Position=0;
}
}
uint8_t SS_param(Battery_Data_Struct* Source_Data) {
uint8_t result = 0;
Battery_Data_Struct Service_Struct;
Service_Struct = *Source_Data;
//memcpy(&SIM800_Struct.BATTERY_DATA, Source_Data, sizeof(*Source_Data));
SIM800_Struct.BATTERY_DATA.Battery_Level_At_End = Source_Data->Battery_Level_At_End;
SIM800_Struct.BATTERY_DATA.Battery_Level_At_Start = Source_Data->Battery_Level_At_Start;
SIM800_Struct.BATTERY_DATA.Battery_Temperature_At_End = Source_Data->Battery_Temperature_At_End;
SIM800_Struct.BATTERY_DATA.Battery_Voltage_At_End = Source_Data->Battery_Voltage_At_End;
SIM800_Struct.BATTERY_DATA.Battery_Voltage_At_Start = Source_Data->Battery_Voltage_At_Start;
SIM800_Struct.BATTERY_DATA.Energy_Sum = Source_Data->Energy_Sum;
SIM800_Struct.BATTERY_DATA.Internal_Resistance = Source_Data->Internal_Resistance;
SIM800_Struct.BATTERY_DATA.Maximum_Charge_Current = Source_Data->Maximum_Charge_Current;
SIM800_Struct.BATTERY_DATA.Maximum_Load_Current = Source_Data->Maximum_Load_Current;
SIM800_Struct.BATTERY_DATA.Moderated = Source_Data->Moderated;
SIM800_Struct.BATTERY_DATA.Serial = Source_Data->Serial;
SIM800_Struct.BATTERY_DATA.Status_Indication = Source_Data->Status_Indication;
memcpy(&SIM800_Struct.BATTERY_DATA.Ended_At_Time, &Service_Struct.Ended_At_Time, sizeof(Service_Struct.Ended_At_Time));
memcpy(&SIM800_Struct.BATTERY_DATA.Started_At_Time, &Service_Struct.Started_At_Time, sizeof(Service_Struct.Started_At_Time));
//Battery_Data_to_String_Converter(&SIM800_Struct);
if(SIM800_Set_Command(&SIM800_Struct, HTTP_PARAMETERS_POST, 60000) == COMMAND_SET) {
result = 1;
}
return result;
}
uint8_t SD_status(uint8_t type, Time_Struct* Event_time){
uint8_t result = 0;
memcpy(&SD_Global_Struct.BATTERY_DATA.Event_time, Event_time, sizeof(*Event_time));
SD_Global_Struct.BATTERY_DATA.Battery_cond_ID = type;
Battery_Data_to_CSV_Converter(&SD_Global_Struct, &SD_Global_Struct.CSV_DATA);
if(SD_Set_Command(&SD_Global_Struct,SD_OP_WRITE_STATUS, 10000) == SD_COMMAND_SET) {
result = 1;
}
return result;
}
uint8_t SD_param(Battery_Data_Struct* Source_Data){
uint8_t result = 0;
Battery_Data_Struct Service_Struct;
Service_Struct = *Source_Data;
SD_Global_Struct.BATTERY_DATA.Battery_Level_At_End = Source_Data->Battery_Level_At_End;
SD_Global_Struct.BATTERY_DATA.Battery_Level_At_Start = Source_Data->Battery_Level_At_Start;
SD_Global_Struct.BATTERY_DATA.Battery_Temperature_At_End = Source_Data->Battery_Temperature_At_End;
SD_Global_Struct.BATTERY_DATA.Battery_Voltage_At_End = Source_Data->Battery_Voltage_At_End;
SD_Global_Struct.BATTERY_DATA.Battery_Voltage_At_Start = Source_Data->Battery_Voltage_At_Start;
SD_Global_Struct.BATTERY_DATA.Energy_Sum = Source_Data->Energy_Sum;
SD_Global_Struct.BATTERY_DATA.Internal_Resistance = Source_Data->Internal_Resistance;
SD_Global_Struct.BATTERY_DATA.Maximum_Charge_Current = Source_Data->Maximum_Charge_Current;
SD_Global_Struct.BATTERY_DATA.Maximum_Load_Current = Source_Data->Maximum_Load_Current;
SD_Global_Struct.BATTERY_DATA.Moderated = Source_Data->Moderated;
SD_Global_Struct.BATTERY_DATA.Serial = Source_Data->Serial;
SD_Global_Struct.BATTERY_DATA.Status_Indication = Source_Data->Status_Indication;
memcpy(&SD_Global_Struct.BATTERY_DATA.Ended_At_Time, &Service_Struct.Ended_At_Time, sizeof(Service_Struct.Ended_At_Time));
memcpy(&SD_Global_Struct.BATTERY_DATA.Started_At_Time, &Service_Struct.Started_At_Time, sizeof(Service_Struct.Started_At_Time));
Battery_Data_to_CSV_Converter(&SD_Global_Struct, &SD_Global_Struct.CSV_DATA);
if(SD_Set_Command(&SD_Global_Struct,SD_OP_WRITE_PARAM, 10000) == SD_COMMAND_SET) {
result = 1;
}
return result;
}
uint8_t SD_Mount(){
uint8_t result = 0;
if(SD_Set_Command(&SD_Global_Struct,SD_OP_MOUNT, 10000) == SD_COMMAND_SET) {
result = 1;
}
return result;
}
uint8_t SD_Umount(){
uint8_t result = 0;
if(SD_Set_Command(&SD_Global_Struct,SD_OP_UMOUNT, 10000) == SD_COMMAND_SET) {
result = 1;
}
return result;
}
uint8_t SS_status(uint8_t type, Time_Struct* Event_time) {
static uint32_t prev_ptr = 0;
uint8_t result = 0;
SIM800_Struct.BATTERY_DATA.Event_time.day = Event_time->day;
SIM800_Struct.BATTERY_DATA.Event_time.hour = Event_time->hour;
SIM800_Struct.BATTERY_DATA.Event_time.minute = Event_time->minute;
SIM800_Struct.BATTERY_DATA.Event_time.month = Event_time->month;
SIM800_Struct.BATTERY_DATA.Event_time.second = Event_time->second;
SIM800_Struct.BATTERY_DATA.Event_time.timezone = Event_time->timezone;
SIM800_Struct.BATTERY_DATA.Event_time.year = Event_time->year;
SIM800_Struct.BATTERY_DATA.Battery_cond_ID = type;
//Battery_Data_to_String_Converter(&SIM800_Struct);
if(SIM800_Set_Command(&SIM800_Struct, HTTP_EVENT_POST, 60000) == COMMAND_SET) {
prev_ptr++;
result = 1;
}
return result;
}
void Update_parameters_for_sim(){
// float Service;
RTC_Get_Values(&SimStatus_Struct.Actual_data.Ended_At_Time);
SimStatus_Struct.Actual_data.Battery_Level_At_End = (uint16_t) packState.SoC;
SimStatus_Struct.Actual_data.Battery_Voltage_At_End = packState.packVoltage;
SimStatus_Struct.Actual_data.Battery_Temperature_At_End = (uint16_t) packState.tempBatteryAverage;
//Service = abs(SimStatus_Struct.Remaining_SOC_at_Start - packState.SoCCapacityAh);
//SimStatus_Struct.Actual_data.Energy_Sum = (uint16_t) Service;
SimStatus_Struct.Actual_data.Energy_Sum = (uint16_t) packState.SoCCapacityAh;
SimStatus_Struct.Actual_data.Internal_Resistance = __DEFAULT_BATTERY_RESISTANCE;
SimStatus_Struct.Actual_data.Moderated = 0;
SimStatus_Struct.Actual_data.Maximum_Charge_Current = (uint16_t) SimStatus_Struct.Max_Charge_Current;
SimStatus_Struct.Actual_data.Maximum_Load_Current = (uint16_t) SimStatus_Struct.Max_Load_Current;
SimStatus_Struct.Actual_data.Battery_Level_At_Start = SimStatus_Struct.Battery_Level_At_Start;
SimStatus_Struct.Actual_data.Battery_Voltage_At_Start = SimStatus_Struct.Battery_Voltage_At_Start;
memcpy(&SimStatus_Struct.Actual_data.Started_At_Time, &SimStatus_Struct.Started_at_time, sizeof(SimStatus_Struct.Started_at_time));
}
void SD_Params_Send_to_Buf(uint8_t State){
//if (SD_Global_Struct.Mount_Flag){
if (packState.serial_number==0) SD_Global_Struct.BATTERY_DATA.Serial = Battery_Serial;
else SD_Global_Struct.BATTERY_DATA.Serial = packState.serial_number;
memcpy(&SD_CARD_Struct.Param_History_Buffer[SD_CARD_Struct.Param_History_Buffer_Position], &SimStatus_Struct.Actual_data, sizeof(SimStatus_Struct.Actual_data));
SD_CARD_Struct.Param_History_Buffer[SD_CARD_Struct.Param_History_Buffer_Position].Status_Indication=State;
if (SD_CARD_Struct.Param_History_Buffer_Counter <= __SD_BUFFER_MAX_VAL){
SD_CARD_Struct.Param_History_Buffer_Counter++;
SD_CARD_Struct.Param_History_Buffer_Position++;
}
if (SD_CARD_Struct.Param_History_Buffer_Counter>__SD_BUFFER_MAX_VAL) SD_CARD_Struct.Param_History_Buffer_Counter=__SD_BUFFER_MAX_VAL;
if (SD_CARD_Struct.Param_History_Buffer_Position>__SD_BUFFER_MAX_VAL) SD_CARD_Struct.Param_History_Buffer_Position=__SD_BUFFER_MAX_VAL;
//}
}
void Parameters_Send_to_Buf(uint8_t State){
//if (SS_Ready2Send_Flag){
if (packState.serial_number==0) SimStatus_Struct.Actual_data.Serial = Battery_Serial;
else SimStatus_Struct.Actual_data.Serial = packState.serial_number;
//if (!SimStatus_Struct.Param_Flag[State]){
// SimStatus_Struct.Param_Flag[State] = 1;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Status_Indication=State;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Battery_Level_At_Start = SimStatus_Struct.Battery_Level_At_Start;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Battery_Voltage_At_Start = SimStatus_Struct.Battery_Voltage_At_Start;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Started_At_Time = SimStatus_Struct.Started_at_time;
//
// RTC_Get_Values(&SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Ended_At_Time);
//
// if (packState.serial_number==0) SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Serial = __DEFAULT_BATTERY_SERIAL;
// else SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Serial = packState.serial_number;
//
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Battery_Level_At_End = (uint16_t) packState.SoC;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Battery_Voltage_At_End = packState.packVoltage;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Battery_Temperature_At_End = (uint16_t) packState.tempBatteryAverage;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Energy_Sum = (uint16_t) packState.SoCCapacityAh;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Internal_Resistance = __DEFAULT_BATTERY_RESISTANCE;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Moderated = 0;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Maximum_Charge_Current = (uint16_t) SimStatus_Struct.Max_Charge_Current;
// SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Maximum_Load_Current = (uint16_t) SimStatus_Struct.Max_Load_Current;
memcpy(&SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position], &SimStatus_Struct.Actual_data, sizeof(SimStatus_Struct.Actual_data));
SimStatus_Struct.Param_History_Buffer[SimStatus_Struct.Param_History_Buffer_Position].Status_Indication=State;
if (SimStatus_Struct.Param_History_Buffer_Counter <= __SS_BUFFER_MAX_VAL){
SimStatus_Struct.Param_History_Buffer_Counter++;
SimStatus_Struct.Param_History_Buffer_Position++;
}
if (SimStatus_Struct.Param_History_Buffer_Counter>__SS_BUFFER_MAX_VAL) SimStatus_Struct.Param_History_Buffer_Counter=__SS_BUFFER_MAX_VAL;
if (SimStatus_Struct.Param_History_Buffer_Position>__SS_BUFFER_MAX_VAL) SimStatus_Struct.Param_History_Buffer_Position=__SS_BUFFER_MAX_VAL;
//}
// SimStatus_Struct.Previous_Active_State = SimStatus_Struct.Active_State;
// RTC_Get_Values(&SimStatus_Struct.Started_at_time);
// SimStatus_Struct.Battery_Level_At_Start = (uint16_t) packState.SoC;
// SimStatus_Struct.Battery_Voltage_At_Start = packState.packVoltage;
// SimStatus_Struct.Remaining_SOC_at_Start = packState.SoCCapacityAh;
//}
}
void Parameters_Save(){
//if (SS_Ready2Send_Flag){
SimStatus_Struct.Previous_Active_State = SimStatus_Struct.Active_State;
RTC_Get_Values(&SimStatus_Struct.Started_at_time);
SimStatus_Struct.Battery_Level_At_Start = (uint16_t) packState.SoC;
SimStatus_Struct.Battery_Voltage_At_Start = packState.packVoltage;
SimStatus_Struct.Remaining_SOC_at_Start = packState.SoCCapacityAh;
//}
}
void Save_data_to_Backup(){
Time_Struct CurrentTime;
// Time_Struct Previous_time;
struct tm tm_CurrenttimeStruct = {0};
struct tm tm_PrevtimeStruct = {0};
time_t Unixtime1;
time_t Unixtime2;
uint64_t Unixtime_delta;
uint16_t Service_var;
// float Service_float;
RTC_Get_Values(&CurrentTime);
tm_CurrenttimeStruct.tm_year = CurrentTime.year+2000-1900;
tm_CurrenttimeStruct.tm_mon = CurrentTime.month-1;
tm_CurrenttimeStruct.tm_mday = CurrentTime.day;
tm_CurrenttimeStruct.tm_hour = CurrentTime.hour;
tm_CurrenttimeStruct.tm_min = CurrentTime.minute;
tm_CurrenttimeStruct.tm_sec = CurrentTime.second;
tm_PrevtimeStruct.tm_year = SimStatus_Struct.Started_at_time.year+2000-1900;
tm_PrevtimeStruct.tm_mon = SimStatus_Struct.Started_at_time.month-1;
tm_PrevtimeStruct.tm_mday = SimStatus_Struct.Started_at_time.day;
tm_PrevtimeStruct.tm_hour = SimStatus_Struct.Started_at_time.hour;
tm_PrevtimeStruct.tm_min = SimStatus_Struct.Started_at_time.minute;
tm_PrevtimeStruct.tm_sec = SimStatus_Struct.Started_at_time.second;
Unixtime1 = mktime(&tm_CurrenttimeStruct);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, LoLoWord(Unixtime1));
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, LoHiWord(Unixtime1));
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, HiLoWord(Unixtime1));
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, HiHiWord(Unixtime1));
Unixtime2 = mktime(&tm_PrevtimeStruct);
Unixtime_delta = (uint16_t) (Unixtime1 - Unixtime2);
if (Unixtime_delta>0xFFFFFFFF) Unixtime_delta=0;
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR9, LoLoWord(Unixtime_delta));
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR10, LoHiWord(Unixtime_delta));
//HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR11, HiLoWord(Unixtime2));
//HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR12, HiHiWord(Unixtime2));
//Prev State and Temp
Service_var = SimStatus_Struct.Active_State;
Service_var = Service_var<<8;
Service_var = Service_var + (uint8_t) packState.tempBatteryAverage;
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, Service_var);
//Battery SOC levels
Service_var = (uint8_t) packState.SoC;
Service_var = Service_var<<8;
Service_var = Service_var + (uint8_t) SimStatus_Struct.Battery_Level_At_Start;
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR6, Service_var);
//Battery Voltage levels
Service_var = (uint8_t) packState.packVoltage;
Service_var = Service_var<<8;
Service_var = Service_var + (uint8_t) SimStatus_Struct.Battery_Voltage_At_Start;
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR7, Service_var);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR8, SimStatus_Struct.Actual_data.Energy_Sum);
}
void Restore_shutdown_data(){
uint16_t HiHiPart;
uint16_t HiLoPart;
uint16_t LoLoPart;
uint16_t LoHiPart;
// uint32_t LoPart;
// uint32_t HiPart;
time_t Unixtime;
uint32_t Time_delta;
struct tm tm_timeStruct = {0};
//HAL_PWR_EnableBkUpAccess();
LoLoPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);
LoHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
HiLoPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3);
HiHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);
Unixtime = HiHiPart;
Unixtime = Unixtime<<16;
Unixtime = Unixtime + HiLoPart;
Unixtime = Unixtime<<16;
Unixtime = Unixtime + LoHiPart;
Unixtime = Unixtime<<16;
Unixtime = Unixtime + LoLoPart;
tm_timeStruct = *(localtime(&Unixtime));
if(Unixtime < 0x386D4380){
SimStatus_Struct.Shutdown_time.year = 0;
SimStatus_Struct.Shutdown_time.month = 1;
SimStatus_Struct.Shutdown_time.day = 1;
SimStatus_Struct.Shutdown_time.hour = 0;
SimStatus_Struct.Shutdown_time.minute = 0;
SimStatus_Struct.Shutdown_time.second = 0;
} else {
SimStatus_Struct.Shutdown_time.year = tm_timeStruct.tm_year+1900-2000;
SimStatus_Struct.Shutdown_time.month = tm_timeStruct.tm_mon+1;
SimStatus_Struct.Shutdown_time.day = tm_timeStruct.tm_mday;
SimStatus_Struct.Shutdown_time.hour = tm_timeStruct.tm_hour;
SimStatus_Struct.Shutdown_time.minute = tm_timeStruct.tm_min;
SimStatus_Struct.Shutdown_time.second = tm_timeStruct.tm_sec;
}
LoLoPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR9);
LoHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR10);
// HiLoPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR11);
// HiHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR12);
// Unixtime = HiHiPart;
// Unixtime = Unixtime<<16;
// Unixtime = Unixtime + HiLoPart;
// Unixtime = Unixtime<<16;
Time_delta = LoHiPart;
Time_delta = Time_delta<<16;
Time_delta = Time_delta + LoLoPart;
Unixtime = Unixtime - Time_delta;
tm_timeStruct = *(localtime(&Unixtime));
if(Unixtime < 0x386D4380){
SimStatus_Struct.Shutdown_prev_state_start_time.year = 0;
SimStatus_Struct.Shutdown_prev_state_start_time.month = 1;
SimStatus_Struct.Shutdown_prev_state_start_time.day = 1;
SimStatus_Struct.Shutdown_prev_state_start_time.hour = 0;
SimStatus_Struct.Shutdown_prev_state_start_time.minute = 0;
SimStatus_Struct.Shutdown_prev_state_start_time.second = 0;
} else {
SimStatus_Struct.Shutdown_prev_state_start_time.year = tm_timeStruct.tm_year+1900-2000;
SimStatus_Struct.Shutdown_prev_state_start_time.month = tm_timeStruct.tm_mon+1;
SimStatus_Struct.Shutdown_prev_state_start_time.day = tm_timeStruct.tm_mday;
SimStatus_Struct.Shutdown_prev_state_start_time.hour = tm_timeStruct.tm_hour;
SimStatus_Struct.Shutdown_prev_state_start_time.minute = tm_timeStruct.tm_min;
SimStatus_Struct.Shutdown_prev_state_start_time.second = tm_timeStruct.tm_sec;
}
HiHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5);
SimStatus_Struct.Active_State = HiByte(HiHiPart);
SimStatus_Struct.Actual_data.Battery_Temperature_At_End = LoByte(HiHiPart);
HiHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR6);
SimStatus_Struct.Actual_data.Battery_Level_At_End = HiByte(HiHiPart);
SimStatus_Struct.Actual_data.Battery_Level_At_Start = LoByte(HiHiPart);
HiHiPart = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR7);
SimStatus_Struct.Actual_data.Battery_Voltage_At_End = HiByte(HiHiPart);
SimStatus_Struct.Actual_data.Battery_Voltage_At_Start = LoByte(HiHiPart);
SimStatus_Struct.Actual_data.Energy_Sum = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR8);
memcpy(&SimStatus_Struct.Actual_data.Started_At_Time, &SimStatus_Struct.Shutdown_prev_state_start_time, sizeof(SimStatus_Struct.Shutdown_prev_state_start_time));
memcpy(&SimStatus_Struct.Actual_data.Ended_At_Time, &SimStatus_Struct.Shutdown_time, sizeof(SimStatus_Struct.Shutdown_time));
}
void Set_Shutdown_Data(){
memcpy(&SimStatus_Struct.Actual_data.Started_At_Time, &SimStatus_Struct.Actual_data.Ended_At_Time, sizeof(SimStatus_Struct.Actual_data.Ended_At_Time));
//memcpy(&SimStatus_Struct.Actual_data.Ended_At_Time, &Current_Time, sizeof(Current_Time));
RTC_Get_Values(&SimStatus_Struct.Actual_data.Ended_At_Time);
SimStatus_Struct.Actual_data.Energy_Sum = (uint16_t) packState.SoCCapacityAh;
SimStatus_Struct.Actual_data.Battery_Voltage_At_Start = SimStatus_Struct.Actual_data.Battery_Voltage_At_End;
SimStatus_Struct.Actual_data.Battery_Voltage_At_End = packState.packVoltage;
SimStatus_Struct.Actual_data.Battery_Level_At_Start = SimStatus_Struct.Actual_data.Battery_Level_At_End;
SimStatus_Struct.Actual_data.Battery_Level_At_End = (uint16_t) packState.SoC;
SimStatus_Struct.Actual_data.Battery_Temperature_At_End = (uint16_t) packState.tempBatteryAverage;
}
uint8_t SS_Sync_Time(){
static uint8_t comp_flag = 0;
static uint64_t last_ask = 0;
static uint8_t asked = 0;
if( asked == 0 ) {
if(SIM800_Set_Command(&SIM800_Struct, GET_TIME, 60000) == COMMAND_SET){
if(SIM800_Struct.Sim_Stages_List == READY_TO_OPERATE) {
SIM800_import_time_to_struct(&SIM800_Struct, &Current_Time);
RTC_Set_Values(&Current_Time);
asked = 1;
last_ask = HAL_GetTick();
comp_flag = 1;
if (Current_Time.year < 20){
comp_flag=0;
asked=0;
}
}
}
} else if( (asked == 1) && ((HAL_GetTick() - last_ask) >= 600000) ) {
asked = 0;
comp_flag = 0;
}
return comp_flag;
}
uint8_t SS_Sync_GPS(){
static uint8_t comp_flag = 0;
static uint64_t last_ask = 0;
static uint8_t asked = 0;
if( asked == 0 ) {
if(SIM800_Set_Command(&SIM800_Struct, GET_GPS_COORDINATES, 60000) == COMMAND_SET){
if(SIM800_Struct.Sim_Stages_List == READY_TO_OPERATE) {
asked = 1;
last_ask = HAL_GetTick();
comp_flag = 1;
}
}
} else if( (asked == 1) && ((HAL_GetTick() - last_ask) >= 600000) ) {
asked = 0;
comp_flag = 0;
}
return comp_flag;
}
//void SS_Pilot_Status_ON(){
// static uint8_t prev_pilot = 0;
// static uint8_t pilot_changed = 0;
// static uint8_t param_flag = 0;
//
// if (prev_pilot != Pilot_Status) {
// pilot_changed = 1;
// }
//
// if( (pilot_changed) && (param_flag == 0) ){
//// if( SS_status(__STATUS_CHARGE_ON) ){
//// pilot_changed = 0;
//// prev_pilot = Pilot_Status;
//// param_flag = 1;
//// }
// }
//
// if( (pilot_changed == 0) && (param_flag == 1) ){
// if( SS_param() ){
// // pilot_changed = 0;
// param_flag = 0;
// }
// }
//}
//void SS_Pilot_Status_OFF(){
// static uint8_t prev_pilot = 0;
// static uint8_t pilot_changed = 0;
// static uint8_t param_flag = 0;
//
// if (prev_pilot != Pilot_Status) {
// pilot_changed = 1;
// }
//
//
// if( (pilot_changed) && (param_flag == 0) ){
//// if( SS_status(__STATUS_CHARGING_DISCONNECT) ){
//// pilot_changed = 0;
//// prev_pilot = Pilot_Status;
//// param_flag=1;
//// }
// }
//
// if( (pilot_changed == 0) && (param_flag == 1) ){
// if( SS_param() ){
// // pilot_changed = 0;
// param_flag = 0;
// }
// }
//}
void Global_Reset_Timer(uint32_t time) {
if (TIM_Clock>=time){
NVIC_SystemReset();
}
}
#define __TO_TIME_ON 60000
#define __TO_TIME_OFF 300000
void Test_Output(uint32_t time_on, uint32_t time_off) {
static uint32_t last_switch_time = 0;
static uint8_t state = 0;
if( (state == 0) && ( (HAL_GetTick() - last_switch_time) > time_on) ) {
HAL_GPIO_WritePin(Output_3_GPIO_Port, Output_3_Pin, GPIO_PIN_SET);
state = 1;
last_switch_time = HAL_GetTick();
}
if( (state == 1) && ( (HAL_GetTick() - last_switch_time) > time_off) ) {
HAL_GPIO_WritePin(Output_3_GPIO_Port, Output_3_Pin, GPIO_PIN_RESET);
state = 0;
last_switch_time = HAL_GetTick();
}
}
//void SD_Card_Processing(){
//
// fres = f_mount(&FatFs, "", 1); //1=mount now
// if (fres != FR_OK) {
// while(1);
// }
//
// fres = f_getfree("", &free_clusters, &getFreeFs);
// if (fres != FR_OK) {
// HAL_GPIO_WritePin(HL5_GPIO_Port, HL4_Pin, GPIO_PIN_SET);
// }
//
// total_sectors = (getFreeFs->n_fatent - 2) * getFreeFs->csize;
// free_sectors = free_clusters * getFreeFs->csize;
//
//
// fres = f_open(&fil, "test.csv", FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS);
// if (fres == FR_OK){
// f_puts("STM32 SD Card I/O Example via SPI\n", &fil);
// }
//
// if(f_close(&fil) != FR_OK){
// HAL_GPIO_WritePin(HL5_GPIO_Port, HL4_Pin, GPIO_PIN_SET);
// }
//
// if(f_mount(NULL, "", 1) != FR_OK){
// HAL_GPIO_WritePin(HL5_GPIO_Port, HL4_Pin, GPIO_PIN_SET);
// }
//}
void UpdateGSMParamsFromConfig(){
SetParametersFromConfig(&SIM800_Struct,generalConfig);
}
void SD_Update_Filename(SD_CARD_Global_Struct* source ){
Time_Struct rtc_time;
uint32_t Raw;
char* csvtxt=".csv";
char* stringptr=&source->Raw_var[0];
//char* test1_ptr=&test1[0];
// istr=strstr(source->FileName,".csv");
// FN=atoi(istr-4);
// FN_month=(uint8_t)(FN/100);
// Raw=FN_month*100;
// FN_year=(uint8_t)(FN-Raw);
RTC_Get_Values(&rtc_time);
if (rtc_time.year<20){
rtc_time.year=01;
rtc_time.month=01;
}
// if ((FN_year==rtc_time.year) && (FN_month==rtc_time.month)){
// source->Filename_Check_Done=1;
// }
// else {
Raw = rtc_time.month;
Raw=Raw*100;
Raw=Raw+rtc_time.year;
itoa(Raw,stringptr,sizeof(Raw)+6);
//strcat(stringptr,"%s");
//strncpy(source->FileName,stringptr,sizeof(stringptr));
strcpy(source->FileName,stringptr);
strcat(source->FileName,csvtxt);
source->Filename_Check_Done=1;
// }
}
void Total_DeInit(){
MX_FATFS_DeInit();
HAL_TIM_Base_DeInit(&htim2);
HAL_TIM_Base_DeInit(&htim6);
MX_USB_DEVICE_DeInit();
HAL_UART_DeInit(&huart2);
HAL_SPI_DeInit(&hspi1);
//HAL_SPI_DeInit(&hspi3);
HAL_DAC_DeInit(&hdac);
HAL_ADC_DeInit(&hadc2);
HAL_RTC_DeInit(&hrtc);
__HAL_RCC_GPIOE_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
}
int main(void)
{
// uint8_t result;
// uint8_t Pinstate;
// static uint32_t last_ss = 0;
/* USER CODE BEGIN 1 */
//SCB->VTOR = 0x0800F000;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
// modFlashJumpToBootloader();
//jumpToBootLoader();
//HAL_Delay(2000);
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
// HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(HL2_GPIO_Port, HL2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(HL3_GPIO_Port, HL3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(HL5_GPIO_Port, HL5_Pin, GPIO_PIN_SET);
HAL_Delay(1000);
HAL_GPIO_WritePin(HL2_GPIO_Port, HL2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(HL3_GPIO_Port, HL3_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(HL5_GPIO_Port, HL5_Pin, GPIO_PIN_RESET);
HAL_Delay(1000);
// jumpToBootLoader();
MX_RTC_Init();
MX_ADC2_Init();
//MX_CAN1_Init();
//MX_CAN2_Init();
CAN_SetSpeed(CAN_SPD_100, &hcan1);
CAN_SetSpeed(CAN_SPD_100, &hcan2);
//HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, 1);
MX_DAC_Init();
MX_SPI1_Init();
// MX_SPI3_Init();
MX_USART2_UART_Init();
MX_USB_DEVICE_Init();
MX_TIM6_Init();
MX_TIM2_Init();
MX_FATFS_Init();
// mainWatchDogInitAndStart();
//HAL_Delay(2000);
Battery_Serial = 0;
modem_init();
SD_Card_data_init();
//jumpToBootLoader();// here it works
/* USER CODE BEGIN 2 */
generalConfig = modConfigInit(); // Tell EEPROM the needed size for ConfigStruct
generalStateOfCharge = modStateOfChargeInit(&packState,generalConfig); // Tell EEPROM the needed size for StatOfChargeStruct
driverSWStorageManagerInit(); // Initializes EEPROM Memory
modConfigStoreAndLoadDefaultConfig(); // Store default config if needed -> load config from EEPROM
modStateOfChargeStoreAndLoadDefaultStateOfCharge(); // Determin SoC from cell voltage if needed -> load StateOfCharge from EEPROM
modCommandsInit(&packState,generalConfig);
modUARTInit(); // Will act on UART message requests
modPowerElectronicsInit(&packState,generalConfig);
UpdateGSMParamsFromConfig();
Battery_Serial = generalConfig->serialNumber;
HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_Base_Start_IT(&htim2);
SimStatus_Struct.Status_flag[__STATUS_CHARGING_DISCONNECT]=1;
SimStatus_Struct.Status_flag[__STATUS_TAKE_BRUSH]=1;
SimStatus_Struct.Active_State = __GLSTATUS_IDLE;
SimStatus_Struct.Previous_Active_State = __GLSTATUS_IDLE;
/* USER CODE BEGIN WHILE */
//jumpToBootLoader();// here it doesn't work
while (1)
{
// mainWatchDogReset();
// modUARTTask();
//HAL_GPIO_WritePin(GSM_RST_GPIO_Port, GSM_RST_Pin, GPIO_PIN_RESET);
// Sim processing function
// all service operations for sim is here
SIM800_Processing(&SIM800_Struct, &UART_Buffer);
// SD processing function
// all service operations for SD is here
SD_Card_Processing(&SD_Global_Struct);
SD_Global_Struct.SD_CARD_ChipDetect = !HAL_GPIO_ReadPin(SD_CD_GPIO_Port, SD_CD_Pin);
SD_Global_Struct.Battery_Serial = Battery_Serial;
if (SD_Global_Struct.Mount_Flag) HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, GPIO_PIN_SET);
else HAL_GPIO_WritePin(HL4_GPIO_Port, HL4_Pin, GPIO_PIN_RESET);
if (SD_Global_Struct.SD_CARD_ChipDetect && SIM800_Struct.Sim_Main_States.GPRS_Established){
LED_Blink_Delay = __BLINK_GSM_AND_SD_OK;
}
else if (!SD_Global_Struct.SD_CARD_ChipDetect && SIM800_Struct.Sim_Main_States.GPRS_Established){
LED_Blink_Delay = __BLINK_GSM_OK_NO_SD;
}
else if (SD_Global_Struct.SD_CARD_ChipDetect && !SIM800_Struct.Sim_Main_States.GPRS_Established){
LED_Blink_Delay = __BLINK_SD_OK_NO_GSM;
}
else LED_Blink_Delay = __BLINK_INIT;
if (SD_Global_Struct.SD_CARD_ChipDetect){
// if (!SD_Global_Struct.Mount_Flag){
// SD_Global_Struct.Mount_Flag = SD_Mount();
// SD_Ready2Send_Flag=0;
// }
// else if (SD_Global_Struct.Mount_Flag) {
SD_Ready2Send_Flag=1;
SD_Event_and_Param_Processing();
// }
}
else {
SD_Global_Struct.Mount_Flag=0;
}
//Global_Reset_Timer(__GRT_PERIOD);
// Pinstate = HAL_GPIO_ReadPin(SD_CD_GPIO_Port, SD_CD_Pin);
if (TIM_Clock>__DELAY_FOR_SIM || SS_Ready2Send_Flag){ //it is better to get time via sim
if (SD_Ready2Send_Flag){
if (DPC_TO_Check(TO_SD_Filename)==TO_OUT_TOOK){
SD_Global_Struct.Filename_Check_Done=0;
DPC_TO_Set(TO_SD_Filename, __FILENAME_UPDATE_TIMEOUT);
}
if (!SD_Global_Struct.Filename_Check_Done){
SD_Update_Filename(&SD_Global_Struct);
SD_Update_Path(&SD_Global_Struct);
//SD_Set_Command(&SD_Global_Struct, SD_OP_DELETEOLD, 30000);
}
SD_Event_and_Param_Processing();
}
if (!SimStatus_Struct.Load_Params_After_Reboot){
Restore_shutdown_data();
memcpy(&SD_CARD_Struct.Shutdown_time,&SimStatus_Struct.Shutdown_time, sizeof(SimStatus_Struct.Shutdown_time));
if (SimStatus_Struct.Active_State!=0){
Status_Save(__STATUS_POWER_OFF);
SD_Status_Save(__STATUS_POWER_OFF);
Parameters_Send_to_Buf(SimStatus_Struct.Active_State);
SD_Params_Send_to_Buf(SimStatus_Struct.Active_State);
Set_Shutdown_Data();
Parameters_Send_to_Buf(__GLSTATUS_SHUTDOWN);
SD_Params_Send_to_Buf(__GLSTATUS_SHUTDOWN);
}
else {
Set_Shutdown_Data();
//Parameters_Send_to_Buf(__GLSTATUS_SHUTDOWN);
}
SimStatus_Struct.Active_State = __GLSTATUS_IDLE;
Parameters_Save();
RTC_Get_Values(&SimStatus_Struct.Started_at_time);
SimStatus_Struct.Battery_Level_At_Start = (uint16_t) packState.SoC;
SimStatus_Struct.Battery_Voltage_At_Start = packState.packVoltage;
Status_Save(__STATUS_POWER_ON);
SD_Status_Save(__STATUS_POWER_ON);
SimStatus_Struct.Load_Params_After_Reboot=1;
}
}
if(SIM800_Struct.Sim_Main_States.GPRS_Established == 1) {
HAL_GPIO_WritePin(HL4_GPIO_Port, HL3_Pin, GPIO_PIN_SET);
SS_Sync_GPS();
if (SS_Ready2Send_Flag){
SS_Event_and_Param_Processing();
}
else {
if( SS_Sync_Time() ){
SS_Ready2Send_Flag = 1;
}
}
}
else HAL_GPIO_WritePin(HL4_GPIO_Port, HL3_Pin, GPIO_PIN_RESET);
// HAL_Delay(100);
heart_beat();
USB_Check_Timeout();
updateLimitsFromMem();
// indicator control
Display_Control();
Check_Status();
//TODO: REMOVE BEFORE FLIGHT
//Test_Output(__TO_TIME_ON, __TO_TIME_OFF);
if (SimStatus_Struct.Load_Params_After_Reboot) Check_Events_and_Parameters();
if ( (Pilot_Status == 1) && // charge
(Maximum_Charge_Current_Status == 1) && // current above max
(Maximum_Voltage_Status == 1) && // voltage above max
(Maximum_Temp_Status == 1)&& // temp above max
(Deep_Discharge_Status == 1)) { // No Deep discharge
charge_switch(_ON);
load_switch(_OFF);
charge_switch_state = 1;
load_switch_state = 0;
} else if ( (Pilot_Status == 0) && // no charge
(Maximum_Load_Current_Status == 1) && // current above max
(Minimum_Voltage_Status == 1) && // voltage higher min
(Maximum_Temp_Status == 1)&& // temp above max
(Deep_Discharge_Status == 1)) { // No Deep discharge
load_switch(_ON);
charge_switch(_OFF);
charge_switch_state = 0;
load_switch_state = 1;
} else {
if( (Check_Maximum_Voltage() == 0) &&
(Check_Pilot() == 1) ) {
modStateOfChargeVoltageEvent(EVENT_FULL);
}
load_switch(_OFF);
charge_switch(_OFF);
charge_switch_state = 0;
load_switch_state = 0;
}
//Brush_Control();
// try to comment out state task !!!
// modPowerStateTask();
// try to comment out state task !!!
// modOperationalStateTask();
//modPowerElectronicsCellMonitorsEnableBalanceResistors(0x00);
//modPowerElectronicsCellMonitorsEnableBalanceResistors(0x00000f80);
// balance is disable
if(modPowerElectronicsTask()){
// !!! check how works eeprom save !!! // Handle power electronics task
if (packState.serial_number!=0){
Battery_Serial = packState.serial_number;
}
modStateOfChargeProcess();
}
// If there is new data handle SoC estimation
// mainWatchDogReset();
transmitCan1Packet();
transmitCan2Packet();
outputControl();
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC
|RCC_PERIPHCLK_USB;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV3;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the Systick interrupt time
*/
__HAL_RCC_PLLI2S_ENABLE();
}
static void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 999;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
static void MX_TIM6_Init(void)
{
/* USER CODE BEGIN TIM6_Init 0 */
/* USER CODE END TIM6_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 71;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 999;
htim6.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM6_Init 2 */
/* USER CODE END TIM6_Init 2 */
}
static void MX_ADC2_Init(void)
{
/* USER CODE BEGIN ADC2_Init 0 */
/* USER CODE END ADC2_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC2_Init 1 */
/* USER CODE END ADC2_Init 1 */
/** Common config
*/
hadc2.Instance = ADC2;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC2_Init 2 */
/* USER CODE END ADC2_Init 2 */
}
/**
* @brief CAN1 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_15TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if ( huart->Instance == USART2){
SIM800_Interrupt_Handler(&SIM800_Struct,(uint8_t*)UART_Buffer,Size);
HAL_UARTEx_ReceiveToIdle_IT(&huart2, (uint8_t*)UART_Buffer, 1023);
}
}
/**
* @brief CAN2 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN2_Init 0 */
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 16;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = ENABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
/* USER CODE END CAN2_Init 2 */
}
/**
* @brief DAC Initialization Function
* @param None
* @retval None
*/
static void MX_DAC_Init(void)
{
/* USER CODE BEGIN DAC_Init 0 */
/* USER CODE END DAC_Init 0 */
DAC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN DAC_Init 1 */
/* USER CODE END DAC_Init 1 */
/** DAC Initialization
*/
hdac.Instance = DAC;
if (HAL_DAC_Init(&hdac) != HAL_OK)
{
Error_Handler();
}
/** DAC channel OUT1 config
*/
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DAC_Init 2 */
/* USER CODE END DAC_Init 2 */
}
/**
* @brief SPI1 Initialization Function
* @param None
* @retval None
*/
static void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
/**
* @brief SPI3 Initialization Function
* @param None
* @retval None
*/
//static void MX_SPI3_Init(void)
//{
//
// /* USER CODE BEGIN SPI3_Init 0 */
//
// /* USER CODE END SPI3_Init 0 */
//
// /* USER CODE BEGIN SPI3_Init 1 */
//
// /* USER CODE END SPI3_Init 1 */
// /* SPI3 parameter configuration*/
// hspi3.Instance = SPI3;
// hspi3.Init.Mode = SPI_MODE_MASTER;
// hspi3.Init.Direction = SPI_DIRECTION_2LINES;
// hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
// hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
// hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;
// hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
// hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
// hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
// hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
// hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
// hspi3.Init.CRCPolynomial = 7;
// if (HAL_SPI_Init(&hspi3) != HAL_OK)
// {
// Error_Handler();
// }
// /* USER CODE BEGIN SPI3_Init 2 */
//
// /* USER CODE END SPI3_Init 2 */
//
//}
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, Output_2_Pin|Output_3_Pin|Output_4_Pin|Output_5_Pin
|GSM_RST_Pin|HL4_Pin|HL5_Pin|HL3_Pin|HL2_Pin|Output_0_Pin
|Output_1_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(SPI3_CS_GPIO_Port, SPI3_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(SD_CS_GPIO_Port, SD_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(Charging_GPIO_Port, Charging_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : Output_2_Pin Output_3_Pin Output_4_Pin Output_5_Pin
HL3_Pin HL2_Pin Output_0_Pin Output_1_Pin */
GPIO_InitStruct.Pin = Output_2_Pin|Output_3_Pin|Output_4_Pin|Output_5_Pin
|HL5_Pin|HL3_Pin|HL4_Pin|HL2_Pin|Output_0_Pin|Output_1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : PE6 */
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : SD_CD_Pin */
GPIO_InitStruct.Pin = SD_CD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(SD_CD_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : SPI3_CS_Pin */
GPIO_InitStruct.Pin = SPI3_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(SPI3_CS_GPIO_Port, &GPIO_InitStruct);
// GPIO_InitStruct.Pin = LTC6804_CS_Pin;
//GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
//GPIO_InitStruct.Pull = GPIO_NOPULL;
//GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
//GPIO_InitStruct.Alternate = 0;
//HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : Input_1_Pin Input_2_Pin Input_3_Pin */
GPIO_InitStruct.Pin = Input_1_Pin|Input_2_Pin|Input_3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pin : GSM_RST_Pin */
GPIO_InitStruct.Pin = GSM_RST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GSM_RST_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : SD_CS_Pin */
GPIO_InitStruct.Pin = SD_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SD_CS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : Charging_Pin */
GPIO_InitStruct.Pin = Charging_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Charging_GPIO_Port, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/