This commit is contained in:
Hamza Tamim 2024-07-14 16:42:54 +03:00
parent ebd149bbe5
commit a8d8b6d696
9 changed files with 70 additions and 56 deletions

View File

@ -76,3 +76,9 @@ V1.12
- added current_soc to logging data - added current_soc to logging data
- removed void sm_balancing() (the AMS should do it automatically if we set it to charging state) - removed void sm_balancing() (the AMS should do it automatically if we set it to charging state)
- changed the colors for the states in status_LED - changed the colors for the states in status_LED
V1.13
- moved macros and libraries from eeprom.c to h
- added can.h to state_machine.h
- added balancing to AMS_HighLevel.c (hopefully)
- fixed can_handle_dump()

View File

@ -9,10 +9,22 @@
#define INC_EEPROM_H_ #define INC_EEPROM_H_
#include <stm32f3xx_hal.h> #include <stm32f3xx_hal.h>
#include "ADBMS_LL_Driver.h"
#include "soc_estimation.h"
#include <state_machine.h> #include <state_machine.h>
#include "stm32f3xx_hal_def.h"
#include "stm32f3xx_hal_i2c.h"
#include "TMP1075.h"
// see Datasheet for these values
#define EEPROM_I2C_ADDR 0xA4 // 0xA4 for the the first 2⁸ addresses and 0xA6 for the the last 2⁸ addresses
#define EERROM_MEMORY_ADDR_SIZE 2 // it is controlled by A17 in the address Byte, see datasheet
#define EEPROM_MEMORY_SIZE 131072 // in bytes
#define EEPROM_PAGE_SIZE 32 // in bytes
extern uint32_t write_address, read_address;
void eeprom_init(I2C_HandleTypeDef* hi2c); void eeprom_init(I2C_HandleTypeDef* hi2c);
void eeprom_dump_status();
void eeprom_write_status(); void eeprom_write_status();
HAL_StatusTypeDef eeprom_read(uint8_t* data, uint16_t data_length); HAL_StatusTypeDef eeprom_read(uint8_t* data, uint16_t data_length);

View File

@ -12,6 +12,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "ADBMS_LL_Driver.h" #include "ADBMS_LL_Driver.h"
#include <AMS_HighLevel.h> #include <AMS_HighLevel.h>
#include <can.h>
#include <eeprom.h> #include <eeprom.h>
#include <errors.h> #include <errors.h>
#include <PWM_control.h> #include <PWM_control.h>

View File

@ -81,9 +81,10 @@ void AMS_Loop() {
case AMSDEACTIVE: case AMSDEACTIVE:
break; break;
case AMSCHARGING: case AMSCHARGING:
AMS_Balancing_Loop();
break; break;
case AMSIDLEBALANCING: case AMSIDLEBALANCING:
AMS_Idle_Loop(); AMS_Balancing_Loop();
break; break;
case AMSDISCHARGING: case AMSDISCHARGING:
break; break;
@ -184,7 +185,7 @@ uint8_t AMS_Charging_Loop() { return 0; }
uint8_t AMS_Discharging_Loop() { return 0; } uint8_t AMS_Discharging_Loop() { return 0; }
uint8_t AMS_Balancing_Loop() { uint8_t AMS_Balancing_Loop() {
uint8_t id_cell_lowest_voltage = -1; uint8_t id_cell_lowest_voltage = 0;
uint8_t num_of_cells_to_balance = 0; uint8_t num_of_cells_to_balance = 0;
for (int i = 0; i < 13; i++) { for (int i = 0; i < 13; i++) {
if (module.cellVoltages[i] < module.cellVoltages[id_cell_lowest_voltage]) if (module.cellVoltages[i] < module.cellVoltages[id_cell_lowest_voltage])
@ -195,6 +196,8 @@ uint8_t AMS_Balancing_Loop() {
if (module.cellVoltages[i] - CELL_VOLTAGE_DIFF_BALANCING < module.cellVoltages[id_cell_lowest_voltage]){ if (module.cellVoltages[i] - CELL_VOLTAGE_DIFF_BALANCING < module.cellVoltages[id_cell_lowest_voltage]){
amsConfigBalancing((1 << i), 0xF); amsConfigBalancing((1 << i), 0xF);
num_of_cells_to_balance++; num_of_cells_to_balance++;
} else {
amsConfigBalancing((1 << i), 0x0);
} }
} }
if (num_of_cells_to_balance == 0) if (num_of_cells_to_balance == 0)

View File

@ -2,7 +2,7 @@
#define MAX_TEMP ((int16_t)(59 / 0.0625f)) #define MAX_TEMP ((int16_t)(59 / 0.0625f))
#define MAX_FAILED_TEMP 2 //TODO: change value for compliance with the actual number of sensors #define MAX_FAILED_TEMP 2 //TODO: change value for compliance with the actual number of sensors
#warning "change value for compliance with the actual number of sensors", change temps to float // TODO: "change value for compliance with the actual number of sensors", change temps to float
int16_t tmp1075_temps[N_TEMP_SENSORS] = {0}; int16_t tmp1075_temps[N_TEMP_SENSORS] = {0};
uint32_t tmp1075_failed_sensors = 0; uint32_t tmp1075_failed_sensors = 0;
@ -46,7 +46,6 @@ HAL_StatusTypeDef tmp1075_measure() {
temp_error = 1; temp_error = 1;
handle_over_maxtemp(i, tmp1075_temps[i]); handle_over_maxtemp(i, tmp1075_temps[i]);
} }
#warning "check for under temp"
} }
} }
if (nfailed_temp_sensors > MAX_FAILED_TEMP) { if (nfailed_temp_sensors > MAX_FAILED_TEMP) {

View File

@ -10,6 +10,8 @@
#include "can-halal.h" #include "can-halal.h"
#include "eeprom.h" #include "eeprom.h"
#include "soc_estimation.h" #include "soc_estimation.h"
#include "state_machine.h"
#include "stm32f3xx_hal_def.h"
#include <stdint.h> #include <stdint.h>
#define CAN_ID_IN 0x501 #define CAN_ID_IN 0x501
@ -125,26 +127,28 @@ void can_handle_recieve_command(const uint8_t *data){
sm_handle_ams_in(data); sm_handle_ams_in(data);
} else if (data[0] == 0xF0 && data[1] == 0x00) { } else if (data[0] == 0xF0 && data[1] == 0x00) {
sm_handle_ams_in(data); sm_handle_ams_in(data);
} else if (data[0] == 0xF1 && data[1] == 0) { } else if (data[0] == 0xF1 && data[1] == 0x00) {
sm_handle_ams_in(data); sm_handle_ams_in(data);
} else if (data[0] == 0xFF && data[1] == 0) { } else if (data[0] == 0xFF && data[1] == 0x00) {
sm_handle_ams_in(data); sm_handle_ams_in(data);
} }
} }
void can_handle_dump() { void can_handle_dump() {
while (1){ uint8_t* data = {};
uint8_t* data; HAL_StatusTypeDef status = HAL_OK;
while (status == HAL_OK){
if (can_delay_manager > HAL_GetTick()) if (can_delay_manager > HAL_GetTick())
continue; continue;
else else
can_delay_manager = HAL_GetTick() + CAN_DUMP_FREQ; can_delay_manager = HAL_GetTick() + CAN_DUMP_FREQ;
eeprom_read(data, 64); eeprom_read(data, 62);
for (int i = 0; i < 63; i += 8) { for (int i = 0; i < (EEPROM_MEMORY_SIZE-8)/8; i += 8) {
ftcan_transmit(CAN_ID_OUT, &data[i], 8); ftcan_transmit(CAN_ID_OUT, &data[i], 8);
} }
ftcan_transmit(CAN_ID_OUT, 0, 1); ftcan_transmit(CAN_ID_OUT, &data[56], 6);
} }
read_address = 0;
} }
/* /*

View File

@ -4,24 +4,13 @@
* Created on: 10.07.2024 * Created on: 10.07.2024
* Author: Hamza * Author: Hamza
*/ */
#include "ADBMS_LL_Driver.h"
#include "TMP1075.h"
#include "soc_estimation.h"
#include "stm32f3xx_hal_def.h"
#include <eeprom.h> #include <eeprom.h>
// see Datasheet for these values // TODO: test this
#define EEPROM_I2C_ADDR 0xA4 // 0xA4 for the the first 2⁸ addresses and 0xA6 for the the last 2⁸ addresses
#define EERROM_MEMORY_ADDR_SIZE 2 // it is controlled by A17 in the address Byte, see datasheet
#define EEPROM_MEMORY_SIZE 131072 // in bytes
#define EEPROM_PAGE_SIZE 32 // in bytes
static I2C_HandleTypeDef* hi2c; static I2C_HandleTypeDef* hi2c;
uint32_t write_address, read_address; uint32_t write_address, read_address;
#warning TEST THIS
void eeprom_init(I2C_HandleTypeDef* handle) { void eeprom_init(I2C_HandleTypeDef* handle) {
hi2c = handle; hi2c = handle;
write_address = 0; write_address = 0;
@ -29,9 +18,10 @@ void eeprom_init(I2C_HandleTypeDef* handle) {
} }
void eeprom_write_status(){ void eeprom_write_status(){
uint8_t data_length = EEPROM_PAGE_SIZE/8; //32 uint8_t data_length = 62;
uint8_t data[data_length] = {}; uint8_t data[data_length] = {};
// data 0-9
data[0] = ((state.current_state << 4) | (current_powerground_status >> 4)); data[0] = ((state.current_state << 4) | (current_powerground_status >> 4));
data[1] = ((current_powerground_status << 4) | (state.error_source >> 4)); // 4 bit powerground | 4 bit error data[1] = ((current_powerground_status << 4) | (state.error_source >> 4)); // 4 bit powerground | 4 bit error
data[2] = ((state.error_source << 4) | (0)); // 4 bit error | 4 bit state of charge data[2] = ((state.error_source << 4) | (0)); // 4 bit error | 4 bit state of charge
@ -44,37 +34,39 @@ void eeprom_write_status(){
data[9] = (CURRENT_MEASUREMENT); data[9] = (CURRENT_MEASUREMENT);
// data 10-35 // data 10-35
for (int i = 10; i < 36; i += 2) { for (int i = 0; i < 13; i++) {
data[i] = ((int) module.auxVoltages[i]) >> 8; data[(i*2)] = ((int) module.auxVoltages[i]) >> 8;
data[i+1] = ((int) module.auxVoltages[i+1]); data[(i*2)+1] = ((int) module.auxVoltages[i]);
} }
for (int i = 37; i < 63; i += 2) {
data[i] = (tmp1075_temps[i]) >> 8; // data 36-61
data[i+1] = (tmp1075_temps[i+1]); for (int i = 0; i < 13; i++) {
data[(i*2)] = (tmp1075_temps[i]) >> 8;
data[(i*2)+1] = (tmp1075_temps[i]);
} }
eeprom_write(data, 64); eeprom_write(data, 62);
write_address++; write_address++;
} }
HAL_StatusTypeDef eeprom_read(uint8_t* data, uint16_t data_length){ HAL_StatusTypeDef eeprom_read(uint8_t* data, uint16_t data_length){
HAL_StatusTypeDef status = HAL_OK; HAL_StatusTypeDef status = HAL_OK;
HAL_GPIO_WritePin(EEPROM___WC__GPIO_Port, EEPROM___WC__Pin, GPIO_PIN_RESET);
for (size_t i = 0; i < data_length; i++) { for (size_t i = 0; i < data_length; i++) {
if (read_address <= 65535){ if (read_address > EEPROM_MEMORY_SIZE){
status = HAL_I2C_Mem_Write( read_address = 0;
return HAL_BUSY;
} else if (read_address <= 65535){
status = HAL_I2C_Mem_Read(
hi2c, EEPROM_I2C_ADDR, hi2c, EEPROM_I2C_ADDR,
read_address, EERROM_MEMORY_ADDR_SIZE, read_address, EERROM_MEMORY_ADDR_SIZE,
&data[i], 1, 10); &data[i], 1, 10);
} else if (read_address > 65535) { } else if (read_address > 65535) {
status = HAL_I2C_Mem_Write( status = HAL_I2C_Mem_Read(
hi2c, EEPROM_I2C_ADDR + 2, hi2c, EEPROM_I2C_ADDR + 2,
read_address, EERROM_MEMORY_ADDR_SIZE, read_address - 65535, EERROM_MEMORY_ADDR_SIZE,
&data[i], 1, 10); &data[i], 1, 10);
} }
read_address++; read_address++;
} }
HAL_GPIO_WritePin(EEPROM___WC__GPIO_Port, EEPROM___WC__Pin, GPIO_PIN_SET);
return status; return status;
} }
@ -82,7 +74,10 @@ HAL_StatusTypeDef eeprom_write(uint8_t* data, uint16_t data_length){
HAL_StatusTypeDef status = HAL_OK; HAL_StatusTypeDef status = HAL_OK;
HAL_GPIO_WritePin(EEPROM___WC__GPIO_Port, EEPROM___WC__Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(EEPROM___WC__GPIO_Port, EEPROM___WC__Pin, GPIO_PIN_RESET);
for (size_t i = 0; i < data_length; i++) { for (size_t i = 0; i < data_length; i++) {
if (write_address < 65535){ if (write_address > EEPROM_MEMORY_SIZE){
write_address = 0;
return HAL_BUSY;
} else if (write_address <= 65535){
status = HAL_I2C_Mem_Write( status = HAL_I2C_Mem_Write(
hi2c, EEPROM_I2C_ADDR, hi2c, EEPROM_I2C_ADDR,
write_address, EERROM_MEMORY_ADDR_SIZE, write_address, EERROM_MEMORY_ADDR_SIZE,
@ -91,7 +86,7 @@ HAL_StatusTypeDef eeprom_write(uint8_t* data, uint16_t data_length){
} else if (write_address > 65535) { } else if (write_address > 65535) {
status = HAL_I2C_Mem_Write( status = HAL_I2C_Mem_Write(
hi2c, EEPROM_I2C_ADDR + 2, hi2c, EEPROM_I2C_ADDR + 2,
write_address, EERROM_MEMORY_ADDR_SIZE, write_address - 65535, EERROM_MEMORY_ADDR_SIZE,
&data[i], 1, 10); &data[i], 1, 10);
} }
write_address++; write_address++;

View File

@ -5,12 +5,8 @@
* Author: Hamza * Author: Hamza
*/ */
#include "state_machine.h" #include <state_machine.h>
#include "PWM_control.h" #include "AMS_HighLevel.h"
#include "eeprom.h"
#include "main.h"
#include "soc_estimation.h"
#include <stdint.h>
// Time to wait after reaching 95% of battery voltage before exiting precharge // 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 // Set this to 1000 in scruti to demonstrate the voltage on the multimeter
@ -24,7 +20,7 @@
// Max time to wait for CAN messages. If we reach it then we emergency shutdown. // Max time to wait for CAN messages. If we reach it then we emergency shutdown.
#define CAN_TIMEOUT 1000 #define CAN_TIMEOUT 1000
// waiting time between to eeprom writes // waiting time between to eeprom writes
#define EEPROM_WRITE_FREQ_INACTIVE 1000 #define EEPROM_WRITE_FREQ 1000
StateHandle state; StateHandle state;
int32_t RELAY_BAT_SIDE_VOLTAGE; int32_t RELAY_BAT_SIDE_VOLTAGE;
@ -136,10 +132,9 @@ void sm_handle_ams_in(const uint8_t *data){
state.target_state = STATE_CHARGING_PRECHARGE; state.target_state = STATE_CHARGING_PRECHARGE;
} }
break; break;
#warning implement this
case 0xF1: // EEPROM case 0xF1: // EEPROM
if (state.current_state == STATE_INACTIVE) if (state.current_state == STATE_INACTIVE)
sm_eeprom_write_status(); can_handle_dump();
break; break;
case 0xFF: // EMERGENCY SHUTDOWN case 0xFF: // EMERGENCY SHUTDOWN
state.current_state = STATE_DISCHARGE; state.current_state = STATE_DISCHARGE;
@ -243,12 +238,10 @@ void sm_program_powerground(){
void sm_eeprom_write_status(){ void sm_eeprom_write_status(){
if (EEPROM_timer < HAL_GetTick()){ if (EEPROM_timer < HAL_GetTick()){
eeprom_write_status(); eeprom_write_status();
EEPROM_timer = HAL_GetTick() + EEPROM_WRITE_FREQ_INACTIVE; EEPROM_timer = HAL_GetTick() + EEPROM_WRITE_FREQ;
} }
} }
#warning TODO: add error checking for everything here
void sm_check_errors(){ 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; 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;
state.error_type.voltage_error = (error_data.error_sources & (1 << 2)|| error_data.error_sources & (1 << 3)|| error_data.error_sources & (1 << 5) || RELAY_BAT_SIDE_VOLTAGE < 30000) ? 1 : 0; state.error_type.voltage_error = (error_data.error_sources & (1 << 2)|| error_data.error_sources & (1 << 3)|| error_data.error_sources & (1 << 5) || RELAY_BAT_SIDE_VOLTAGE < 30000) ? 1 : 0;
@ -357,9 +350,10 @@ State sm_update_charging_precharge(){
State sm_update_charging(){ State sm_update_charging(){
switch (state.target_state) { switch (state.target_state) {
case STATE_DISCHARGE: case STATE_DISCHARGE:
currentAMSState = AMSIDLE;
return STATE_DISCHARGE; return STATE_DISCHARGE;
default: default:
currentAMSState = AMSCHARGING;
return STATE_CHARGING; return STATE_CHARGING;
} }
} }

View File

@ -11,7 +11,7 @@
#include <status_LED.h> #include <status_LED.h>
#include <stdint.h> #include <stdint.h>
#warning test out pulldown and pushpull settings // TODO test out pulldown and pushpull settings
/* The PWM period (1/FPWM) is defined by the following parameters: /* 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. ARR value, the Prescaler value, and the internal clock itself which drives the timer module FCLK.