Port FT22 code

This commit is contained in:
Jasper Blanckenburg 2023-03-12 21:06:23 +01:00
parent b453286f08
commit 4f43895235
20 changed files with 794 additions and 51 deletions

View File

@ -6,6 +6,11 @@ SourceFiles=../Core/Src/main.c;../Core/Src/stm32f3xx_it.c;../Core/Src/stm32f3xx_
HeaderPath=../Drivers/STM32F3xx_HAL_Driver/Inc;../Drivers/STM32F3xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F3xx/Include;../Drivers/CMSIS/Include;../Core/Inc;
CDefines=USE_HAL_DRIVER;STM32F302xC;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousUsedMakefileFiles]
SourceFiles=Core/Src/main.c;Core/Src/stm32f3xx_it.c;Core/Src/stm32f3xx_hal_msp.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c;Drivers/CMSIS/Device/ST/STM32F3xx/Source/Templates/system_stm32f3xx.c;Core/Src/system_stm32f3xx.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c;Drivers/CMSIS/Device/ST/STM32F3xx/Source/Templates/system_stm32f3xx.c;Core/Src/system_stm32f3xx.c;;;
HeaderPath=Drivers/STM32F3xx_HAL_Driver/Inc;Drivers/STM32F3xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32F3xx/Include;Drivers/CMSIS/Include;Core/Inc;
CDefines=USE_HAL_DRIVER;STM32F302xC;USE_HAL_DRIVER;USE_HAL_DRIVER;
[PreviousGenFiles]
AdvancedFolderStructure=true
HeaderFileListSize=3
@ -23,8 +28,3 @@ SourceFolderListSize=1
SourcePath#0=../Core/Src
SourceFiles=;
[PreviousUsedMakefileFiles]
SourceFiles=Core/Src/main.c;Core/Src/stm32f3xx_it.c;Core/Src/stm32f3xx_hal_msp.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c;Drivers/CMSIS/Device/ST/STM32F3xx/Source/Templates/system_stm32f3xx.c;Core/Src/system_stm32f3xx.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c;Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c;Drivers/CMSIS/Device/ST/STM32F3xx/Source/Templates/system_stm32f3xx.c;Core/Src/system_stm32f3xx.c;;;
HeaderPath=Drivers/STM32F3xx_HAL_Driver/Inc;Drivers/STM32F3xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32F3xx/Include;Drivers/CMSIS/Include;Core/Inc;
CDefines=USE_HAL_DRIVER;STM32F302xC;USE_HAL_DRIVER;USE_HAL_DRIVER;

28
Core/Inc/can.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef INC_CAN_H
#define INC_CAN_H
#include "stm32f3xx_hal.h"
#include "stm32f3xx_hal_can.h"
#include "stm32f3xx_hal_def.h"
#define CAN_ID_SLAVE_PANIC 0x009
#define CAN_ID_AMS_STATUS 0x00A
#define CAN_ID_AMS_IN 0x00B
#define CAN_ID_SLAVE_LOG 0x4F4
#define CAN_ID_SHUNT_BASE 0x520
#define CAN_ID_SHUNT_CURRENT 0x521
#define CAN_ID_SHUNT_VOLTAGE1 0x522
#define CAN_ID_SHUNT_VOLTAGE2 0x523
#define CAN_ID_SHUNT_VOLTAGE3 0x524
#define CAN_ID_SHUNT_TEMP 0x525
#define CAN_ID_SHUNT_POWER 0x526
#define CAN_ID_SHUNT_CURRENT_COUNTER 0x527
#define CAN_ID_SHUNT_ENERGY_COUNTER 0x528
void can_init(CAN_HandleTypeDef *handle);
HAL_StatusTypeDef can_transmit(uint8_t id, uint8_t *data, size_t datalen);
HAL_StatusTypeDef can_send_status();
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *handle);
#endif // INC_CAN_H

View File

@ -0,0 +1,29 @@
#ifndef INC_SHUNT_MONITORING_H
#define INC_SHUNT_MONITORING_H
#include <stdint.h>
#include "stm32f3xx_hal.h"
#define THRESH_OVERCURRENT 300000 // mA
typedef struct {
int32_t current;
int32_t voltage1;
int32_t voltage2;
int32_t voltage3;
int32_t busbartemp;
int32_t power;
int32_t energy;
int32_t current_counter;
uint32_t last_message;
} ShuntData;
extern ShuntData shunt_data;
void shunt_init();
void shunt_check();
void shunt_handle_can_msg(CAN_RxHeaderTypeDef *header, uint8_t *data);
#endif // INC_SHUNT_MONITORING_H

View File

@ -0,0 +1,49 @@
#ifndef INC_SLAVE_MONITORING_H
#define INC_SLAVE_MONITORING_H
#include <stdint.h>
#define N_SLAVES 6
#define N_CELLS_SERIES 17
#define N_CELLS_PARALLEL 5
#define N_TEMP_SENSORS 32
#define SLAVE_TIMEOUT 500
#define SLAVE_PANIC_OT 0
#define SLAVE_PANIC_UT 1
#define SLAVE_PANIC_OV 2
#define SLAVE_PANIC_UV 3
typedef enum {
SLAVE_ERR_NONE,
SLAVE_ERR_TIMEOUT,
SLAVE_ERR_OT,
SLAVE_ERR_UT,
SLAVE_ERR_OV,
SLAVE_ERR_UV
} SlaveErrorKind;
typedef struct {
SlaveErrorKind kind;
uint32_t data; // Cell/temperature ID etc
} SlaveError;
typedef struct {
uint8_t id;
SlaveError error;
uint16_t voltages[N_CELLS_SERIES];
int16_t temperatures[N_TEMP_SENSORS];
uint32_t last_message;
} SlaveHandle;
extern SlaveHandle slaves[N_SLAVES];
extern uint16_t min_voltage;
extern int16_t max_temp;
void slaves_init();
void slaves_check();
void slaves_handle_panic(uint8_t *data);
void slaves_handle_log(uint8_t *data);
#endif // INC_SLAVE_MONITORING_H

11
Core/Inc/soc_estimation.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef INC_SOC_ESTIMATION_H
#define INC_SOC_ESTIMATION_H
#include <stdint.h>
extern uint8_t current_soc;
void soc_init();
void soc_update();
#endif // INC_SOC_ESTIMATION_H

View File

@ -55,6 +55,7 @@ void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void USB_LP_CAN_RX0_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */

View File

@ -0,0 +1,60 @@
#ifndef INC_TS_STATE_MACHINE_H
#define INC_TS_STATE_MACHINE_H
#include "stm32f3xx_hal.h"
#include <stdint.h>
// Minimum vehicle side voltage to exit precharge
#define MIN_VEHICLE_SIDE_VOLTAGE 150000 // mV
// Time to wait after reaching 95% of battery voltage before exiting precharge
#define PRECHARGE_95_DURATION 500 // ms
// Time to wait after there is no more error condition before exiting TS_ERROR
#define NO_ERROR_TIME 1000 // ms
// Time to wait for charger voltage before going to TS_ERROR
#define MAX_CHARGING_CHECK_DURATION 2000 // ms
// Time to wait between closing relays
#define RELAY_CLOSE_WAIT 10 // ms
typedef enum {
TS_INACTIVE,
TS_ACTIVE,
TS_PRECHARGE,
TS_DISCHARGE,
TS_ERROR,
TS_CHARGING_CHECK,
TS_CHARGING
} TSState;
#define TS_ERROR_SOURCE_SHUNT (1 << 0)
#define TS_ERROR_SOURCE_SLAVES (1 << 1)
typedef struct {
TSState current_state;
TSState target_state;
uint32_t error;
} TSStateHandle;
extern TSStateHandle ts_state;
void ts_sm_init();
void ts_sm_update();
TSState ts_sm_update_inactive();
TSState ts_sm_update_active();
TSState ts_sm_update_precharge();
TSState ts_sm_update_discharge();
TSState ts_sm_update_error();
TSState ts_sm_update_charging_check();
TSState ts_sm_update_charging();
typedef enum { RELAY_NEG, RELAY_POS, RELAY_PRECHARGE } Relay;
void ts_sm_set_relay_positions(TSState state);
void ts_sm_set_relay_position(Relay relay, int closed);
void ts_sm_check_close_wait(int *is_closed, int should_close);
void ts_sm_handle_ams_in(uint8_t *data);
void ts_sm_set_error_source(uint32_t flag, int state);
#endif // INC_TS_STATE_MACHINE_H

12
Core/Inc/util.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef INC_UTIL_H
#define INC_UTIL_H
#include <stdint.h>
void set_error_led();
uint64_t ntohll(uint64_t netlonglong);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
#endif // INC_UTIL_H

100
Core/Src/can.c Normal file
View File

@ -0,0 +1,100 @@
#include "can.h"
#include "main.h"
#include "shunt_monitoring.h"
#include "slave_monitoring.h"
#include "soc_estimation.h"
#include "stm32f3xx_hal_can.h"
#include "stm32f3xx_hal_gpio.h"
#include "ts_state_machine.h"
#include "util.h"
#include <stdint.h>
static CAN_HandleTypeDef *hcan;
void can_init(CAN_HandleTypeDef *handle) {
hcan = handle;
CAN_FilterTypeDef filter;
filter.FilterIdHigh = CAN_ID_SHUNT_BASE & 0xFF0;
filter.FilterMaskIdHigh = 0xFF0;
filter.FilterIdLow = CAN_ID_AMS_IN;
filter.FilterMaskIdLow = 0xFFF;
filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
filter.FilterBank = 0;
filter.FilterMode = CAN_FILTERMODE_IDMASK;
filter.FilterScale = CAN_FILTERSCALE_16BIT;
if (HAL_CAN_ConfigFilter(hcan, &filter) != HAL_OK) {
Error_Handler();
}
// TODO: Slave status?
filter.FilterIdHigh = CAN_ID_SLAVE_PANIC;
filter.FilterMaskIdHigh = 0xFFF;
filter.FilterIdLow = CAN_ID_SLAVE_LOG;
filter.FilterMaskIdLow = 0xFFF;
filter.FilterBank = 1;
if (HAL_CAN_ConfigFilter(hcan, &filter) != HAL_OK) {
Error_Handler();
}
if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING) !=
HAL_OK) {
Error_Handler();
}
if (HAL_CAN_Start(hcan) != HAL_OK) {
Error_Handler();
}
}
HAL_StatusTypeDef can_transmit(uint8_t id, uint8_t *data, size_t datalen) {
static CAN_TxHeaderTypeDef header;
header.StdId = id;
header.IDE = CAN_ID_STD;
header.RTR = CAN_RTR_DATA;
header.DLC = datalen;
uint32_t mailbox;
return HAL_CAN_AddTxMessage(hcan, &header, data, &mailbox);
}
HAL_StatusTypeDef can_send_status() {
uint8_t data[4];
data[0] = ts_state.current_state;
data[1] = current_soc;
data[2] = min_voltage >> 8;
data[3] = max_temp >> 8;
return can_transmit(CAN_ID_AMS_STATUS, data, 4);
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *handle) {
if (handle != hcan) {
return;
}
CAN_RxHeaderTypeDef header;
uint8_t data[8];
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &header, data) != HAL_OK) {
set_error_led();
return;
}
if (header.IDE != CAN_ID_STD) {
return;
}
if ((header.StdId & 0xFF0) == CAN_ID_SHUNT_BASE) {
shunt_handle_can_msg(&header, data);
return;
}
switch (header.StdId) {
case CAN_ID_SLAVE_PANIC:
slaves_handle_panic(data);
break;
case CAN_ID_SLAVE_LOG:
slaves_handle_log(data);
break;
case CAN_ID_AMS_IN:
ts_sm_handle_ams_in(data);
break;
}
}

View File

@ -21,6 +21,14 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "can.h"
#include "soc_estimation.h"
#include "stm32f3xx_hal.h"
#include "stm32f3xx_hal_gpio.h"
#include "shunt_monitoring.h"
#include "slave_monitoring.h"
#include "ts_state_machine.h"
/* USER CODE END Includes */
@ -97,7 +105,11 @@ int main(void) {
MX_CAN_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
can_init(&hcan);
slaves_init();
shunt_init();
ts_sm_init();
soc_init();
/* USER CODE END 2 */
/* Infinite loop */
@ -106,6 +118,15 @@ int main(void) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(STATUS1_GPIO_Port, STATUS1_Pin);
slaves_check();
shunt_check();
ts_sm_update();
soc_update();
can_send_status();
HAL_Delay(10);
}
/* USER CODE END 3 */
}
@ -223,15 +244,15 @@ static void MX_CAN_Init(void) {
/* USER CODE END CAN_Init 1 */
hcan.Instance = CAN;
hcan.Init.Prescaler = 16;
hcan.Init.Prescaler = 2;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoBusOff = ENABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.AutoRetransmission = ENABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK) {

View File

@ -0,0 +1,67 @@
#include "shunt_monitoring.h"
#include <string.h>
#include "can.h"
#include "ts_state_machine.h"
#include "util.h"
ShuntData shunt_data;
void shunt_init() {
shunt_data.current = 0;
shunt_data.voltage1 = 0;
shunt_data.voltage2 = 0;
shunt_data.voltage3 = 0;
shunt_data.busbartemp = 0;
shunt_data.power = 0;
shunt_data.energy = 0;
shunt_data.current_counter = 0;
shunt_data.last_message = 0;
}
void shunt_check() {
int is_error = shunt_data.current >= THRESH_OVERCURRENT;
ts_sm_set_error_source(TS_ERROR_SOURCE_SHUNT, is_error);
}
void shunt_handle_can_msg(CAN_RxHeaderTypeDef *header, uint8_t *data) {
// All result messages contain a big-endian 6-byte integer
data[7] = 0;
data[8] = 0;
uint64_t result;
memcpy(&result, data, 8);
result = ntohll(result);
// Top two bytes should always be zero in our usecase (or 0xFF for a signed
// number)
if ((result >> 4) != 0 && (result >> 4) != 0xFFFF) {
set_error_led();
}
switch (header->StdId) {
case CAN_ID_SHUNT_CURRENT:
shunt_data.current = result;
break;
case CAN_ID_SHUNT_VOLTAGE1:
shunt_data.voltage1 = result;
break;
case CAN_ID_SHUNT_VOLTAGE2:
shunt_data.voltage2 = result;
break;
case CAN_ID_SHUNT_VOLTAGE3:
shunt_data.voltage3 = result;
break;
case CAN_ID_SHUNT_TEMP:
shunt_data.busbartemp = result;
break;
case CAN_ID_SHUNT_POWER:
shunt_data.power = result;
break;
case CAN_ID_SHUNT_CURRENT_COUNTER:
shunt_data.current_counter = result;
break;
case CAN_ID_SHUNT_ENERGY_COUNTER:
shunt_data.energy = result;
break;
}
}

View File

@ -0,0 +1,84 @@
#include "slave_monitoring.h"
#include "stm32f3xx_hal.h"
#include "ts_state_machine.h"
#include <stdint.h>
#include <string.h>
SlaveHandle slaves[N_SLAVES];
uint16_t min_voltage;
int16_t max_temp;
void slaves_init() {
for (int i = 0; i < N_SLAVES; i++) {
slaves[i].id = i;
slaves[i].error.kind = SLAVE_ERR_NONE;
slaves[i].last_message = 0;
memset(&slaves[i].voltages, 0, sizeof(slaves[i].voltages));
memset(&slaves[i].temperatures, 0, sizeof(slaves[i].temperatures));
}
}
void slaves_check() {
int any_slave_error = 0;
uint32_t now = HAL_GetTick();
uint16_t min_voltage_new = 0xFFFF;
int16_t max_temp_new = 0xFFFF;
for (int i = 0; i < N_SLAVES; i++) {
if (now - slaves[i].last_message >= SLAVE_TIMEOUT) {
// Don't overwrite a different error kind
if (slaves[i].error.kind == SLAVE_ERR_NONE) {
slaves[i].error.kind = SLAVE_ERR_TIMEOUT;
}
} else if (slaves[i].error.kind == SLAVE_ERR_TIMEOUT) {
slaves[i].error.kind = SLAVE_ERR_NONE;
}
for (int j = 0; j < N_CELLS_SERIES; j++) {
uint16_t v = slaves[i].voltages[j];
if (v < min_voltage_new) {
min_voltage_new = v;
}
}
for (int j = 0; j < N_TEMP_SENSORS; j++) {
int16_t t = slaves[i].temperatures[j];
if (t > max_temp_new) {
max_temp_new = t;
}
}
if (slaves[i].error.kind != SLAVE_ERR_NONE) {
any_slave_error = 1;
}
}
min_voltage = min_voltage_new;
max_temp = max_temp_new;
if (any_slave_error) {
ts_sm_set_error_source(TS_ERROR_SOURCE_SLAVES, 1);
}
}
void slaves_handle_panic(uint8_t *data) {
uint8_t slave_id = data[0];
switch (data[1]) {
case SLAVE_PANIC_OT:
slaves[slave_id].error.kind = SLAVE_ERR_OT;
break;
case SLAVE_PANIC_UT:
slaves[slave_id].error.kind = SLAVE_ERR_UT;
break;
case SLAVE_PANIC_OV:
slaves[slave_id].error.kind = SLAVE_ERR_OV;
break;
case SLAVE_PANIC_UV:
slaves[slave_id].error.kind = SLAVE_ERR_UV;
break;
}
memcpy(&slaves[slave_id].error.data, &data[2], 4);
slaves[slave_id].last_message = HAL_GetTick();
}
void slaves_handle_log(uint8_t *data) {
// TODO
}

14
Core/Src/soc_estimation.c Normal file
View File

@ -0,0 +1,14 @@
#include "soc_estimation.h"
#include <stdint.h>
uint8_t current_soc;
void soc_init() {
current_soc = 0;
// TODO
}
void soc_update() {
// TODO
}

View File

@ -166,6 +166,9 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
GPIO_InitStruct.Alternate = GPIO_AF9_CAN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN interrupt Init */
HAL_NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);
/* USER CODE BEGIN CAN_MspInit 1 */
/* USER CODE END CAN_MspInit 1 */
@ -195,6 +198,8 @@ void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN interrupt DeInit */
HAL_NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn);
/* USER CODE BEGIN CAN_MspDeInit 1 */
/* USER CODE END CAN_MspDeInit 1 */

View File

@ -55,7 +55,7 @@
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
@ -198,6 +198,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f3xx.s). */
/******************************************************************************/
/**
* @brief This function handles USB low priority or CAN_RX0 interrupts.
*/
void USB_LP_CAN_RX0_IRQHandler(void)
{
/* USER CODE BEGIN USB_LP_CAN_RX0_IRQn 0 */
/* USER CODE END USB_LP_CAN_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan);
/* USER CODE BEGIN USB_LP_CAN_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN_RX0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

210
Core/Src/ts_state_machine.c Normal file
View File

@ -0,0 +1,210 @@
#include "ts_state_machine.h"
#include "main.h"
#include "shunt_monitoring.h"
#include "stm32f3xx_hal.h"
#include "stm32f3xx_hal_gpio.h"
#include <stdint.h>
TSStateHandle ts_state;
static uint32_t precharge_95_reached_timestamp = 0;
static uint32_t charging_check_timestamp = 0;
void ts_sm_init() {
ts_state.current_state = TS_INACTIVE;
ts_state.target_state = TS_INACTIVE;
ts_state.error = 0;
}
void ts_sm_update() {
if (ts_state.error) {
ts_state.current_state = TS_ERROR;
}
switch (ts_state.current_state) {
case TS_INACTIVE:
ts_state.current_state = ts_sm_update_inactive();
break;
case TS_ACTIVE:
ts_state.current_state = ts_sm_update_active();
break;
case TS_PRECHARGE:
ts_state.current_state = ts_sm_update_precharge();
break;
case TS_DISCHARGE:
ts_state.current_state = ts_sm_update_discharge();
break;
case TS_ERROR:
ts_state.current_state = ts_sm_update_error();
break;
case TS_CHARGING_CHECK:
ts_state.current_state = ts_sm_update_charging_check();
break;
case TS_CHARGING:
ts_state.current_state = ts_sm_update_charging();
break;
}
ts_sm_set_relay_positions(ts_state.current_state);
}
TSState ts_sm_update_inactive() {
if (ts_state.target_state == TS_ACTIVE) {
precharge_95_reached_timestamp = 0;
return TS_PRECHARGE;
} else if (ts_state.target_state == TS_CHARGING) {
charging_check_timestamp = HAL_GetTick();
return TS_CHARGING_CHECK;
}
return TS_INACTIVE;
}
TSState ts_sm_update_active() {
if (ts_state.target_state == TS_INACTIVE) {
return TS_DISCHARGE;
}
return TS_ACTIVE;
}
TSState ts_sm_update_precharge() {
if (ts_state.target_state == TS_INACTIVE) {
return TS_DISCHARGE;
}
if (shunt_data.voltage2 > MIN_VEHICLE_SIDE_VOLTAGE &&
shunt_data.voltage2 > 0.95 * shunt_data.voltage3) {
uint32_t now = HAL_GetTick();
if (precharge_95_reached_timestamp == 0) {
precharge_95_reached_timestamp = now;
} else if (now - precharge_95_reached_timestamp >= PRECHARGE_95_DURATION) {
return TS_ACTIVE;
}
}
return TS_PRECHARGE;
}
TSState ts_sm_update_discharge() {
// TODO: Actually wait for discharge
return TS_INACTIVE;
}
TSState ts_sm_update_error() {
static uint32_t no_error_since = 0;
if (ts_state.error == 0) {
uint32_t now = HAL_GetTick();
if (no_error_since == 0) {
no_error_since = now;
} else if (now - no_error_since > NO_ERROR_TIME) {
return TS_INACTIVE;
}
}
return TS_ERROR;
}
TSState ts_sm_update_charging_check() {
if (ts_state.target_state == TS_INACTIVE) {
return TS_DISCHARGE;
}
if (shunt_data.voltage2 > shunt_data.voltage3) {
return TS_CHARGING;
} else if (HAL_GetTick() - charging_check_timestamp >
MAX_CHARGING_CHECK_DURATION) {
return TS_ERROR;
}
return TS_CHARGING_CHECK;
}
TSState ts_sm_update_charging() {
if (ts_state.target_state == TS_INACTIVE) {
return TS_DISCHARGE;
}
if (shunt_data.current < 0) {
return TS_ERROR;
}
return TS_CHARGING;
}
void ts_sm_set_relay_positions(TSState state) {
switch (state) {
case TS_INACTIVE:
case TS_ERROR:
ts_sm_set_relay_position(RELAY_NEG, 0);
ts_sm_set_relay_position(RELAY_POS, 0);
ts_sm_set_relay_position(RELAY_PRECHARGE, 0);
break;
case TS_ACTIVE:
case TS_CHARGING:
case TS_DISCHARGE:
ts_sm_set_relay_position(RELAY_NEG, 1);
ts_sm_set_relay_position(RELAY_POS, 1);
ts_sm_set_relay_position(RELAY_PRECHARGE, 1);
// TODO: Open precharge relay after a while
break;
case TS_PRECHARGE:
case TS_CHARGING_CHECK:
ts_sm_set_relay_position(RELAY_NEG, 1);
ts_sm_set_relay_position(RELAY_POS, 0);
ts_sm_set_relay_position(RELAY_PRECHARGE, 1);
break;
}
}
void ts_sm_set_relay_position(Relay relay, int closed) {
static int neg_closed = 0;
static int pos_closed = 0;
static int precharge_closed = 0;
static uint32_t last_close_timestamp = 0;
GPIO_PinState state = closed ? GPIO_PIN_SET : GPIO_PIN_RESET;
switch (relay) {
case RELAY_NEG:
ts_sm_check_close_wait(&neg_closed, closed);
HAL_GPIO_WritePin(NEG_AIR_CTRL_GPIO_Port, NEG_AIR_CTRL_Pin, state);
break;
case RELAY_POS:
ts_sm_check_close_wait(&pos_closed, closed);
HAL_GPIO_WritePin(POS_AIR_CTRL_GPIO_Port, POS_AIR_CTRL_Pin, state);
break;
case RELAY_PRECHARGE:
ts_sm_check_close_wait(&precharge_closed, closed);
HAL_GPIO_WritePin(PRECHARGE_CTRL_GPIO_Port, PRECHARGE_CTRL_Pin, state);
break;
}
}
void ts_sm_check_close_wait(int *is_closed, int should_close) {
static uint32_t last_close_timestamp = 0;
if (should_close != *is_closed) {
*is_closed = should_close;
if (should_close) {
uint32_t dt = HAL_GetTick() - last_close_timestamp;
if (dt < RELAY_CLOSE_WAIT) {
HAL_Delay(RELAY_CLOSE_WAIT - dt);
}
last_close_timestamp = HAL_GetTick();
}
}
}
void ts_sm_handle_ams_in(uint8_t *data) {
if (data[0] & 0x01) {
ts_state.target_state = TS_ACTIVE;
} else {
ts_state.target_state = TS_INACTIVE;
}
}
void ts_sm_set_error_source(uint32_t flag, int state) {
if (state) {
ts_state.error |= flag;
} else {
ts_state.error &= ~flag;
}
}

26
Core/Src/util.c Normal file
View File

@ -0,0 +1,26 @@
#include "util.h"
#include "main.h"
#include "stm32f3xx_hal_gpio.h"
void set_error_led() {
HAL_GPIO_WritePin(STATUS2_GPIO_Port, STATUS2_Pin, GPIO_PIN_SET);
}
uint64_t ntohll(uint64_t netlonglong) {
uint8_t *p = (uint8_t *)&netlonglong;
return ((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48) |
((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32) |
((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16) |
((uint64_t)p[6] << 8) | ((uint64_t)p[7] << 0);
}
uint32_t ntohl(uint32_t netlong) {
uint8_t *p = (uint8_t *)&netlong;
return ((uint32_t)p[3] << 24) | ((uint32_t)p[2] << 16) |
((uint32_t)p[1] << 8) | ((uint32_t)p[0] << 0);
}
uint16_t ntohs(uint16_t netshort) {
uint8_t *p = (uint8_t *)&netshort;
return ((uint16_t)p[1] << 8) | ((uint16_t)p[0] << 0);
}

View File

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [3.19.2] date: [Sun Mar 12 18:28:15 CET 2023]
# File automatically-generated by tool: [projectgenerator] version: [3.19.2] date: [Sun Mar 12 19:36:18 CET 2023]
##########################################################################################################################
# ------------------------------------------------
@ -35,34 +35,34 @@ BUILD_DIR = build
# source
######################################
# C sources
C_SOURCES = \
Core/Src/main.c \
Core/Src/stm32f3xx_it.c \
Core/Src/stm32f3xx_hal_msp.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c \
Core/Src/system_stm32f3xx.c
C_SOURCES = \
Core/Src/main.c \
Core/Src/stm32f3xx_it.c \
Core/Src/stm32f3xx_hal_msp.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_rcc_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_gpio.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_dma.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_cortex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_pwr_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_flash_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_i2c_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_exti.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_can.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_tim_ex.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_uart_ex.c \
Core/Src/system_stm32f3xx.c
# ASM sources
ASM_SOURCES = \
ASM_SOURCES = \
startup_stm32f302xc.s
@ -106,8 +106,8 @@ MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
AS_DEFS =
# C defines
C_DEFS = \
-DUSE_HAL_DRIVER \
C_DEFS = \
-DUSE_HAL_DRIVER \
-DSTM32F302xC
@ -115,11 +115,11 @@ C_DEFS = \
AS_INCLUDES =
# C includes
C_INCLUDES = \
-ICore/Inc \
-IDrivers/STM32F3xx_HAL_Driver/Inc \
-IDrivers/STM32F3xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS/Device/ST/STM32F3xx/Include \
C_INCLUDES = \
-ICore/Inc \
-IDrivers/STM32F3xx_HAL_Driver/Inc \
-IDrivers/STM32F3xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS/Device/ST/STM32F3xx/Include \
-IDrivers/CMSIS/Include
@ -192,4 +192,4 @@ clean:
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***
# *** EOF ***

View File

@ -36,10 +36,16 @@ BUILD_DIR = build
######################################
# C sources
C_SOURCES = \
Core/Src/can.c \
Core/Src/main.c \
Core/Src/shunt_monitoring.c \
Core/Src/slave_monitoring.c \
Core/Src/soc_estimation.c \
Core/Src/stm32f3xx_hal_msp.c \
Core/Src/stm32f3xx_it.c \
Core/Src/system_stm32f3xx.c \
Core/Src/ts_state_machine.c \
Core/Src/util.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc.c \
Drivers/STM32F3xx_HAL_Driver/Src/stm32f3xx_hal_adc_ex.c \

View File

@ -10,10 +10,15 @@ ADC2.SamplingTimeOPAMP-0\#ChannelRegularConversion=ADC_SAMPLETIME_4CYCLES_5
CAD.formats=
CAD.pinconfig=
CAD.provider=
CAN.CalculateBaudRate=333333
CAN.CalculateTimeBit=3000
CAN.CalculateTimeQuantum=1000.0
CAN.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate
CAN.ABOM=ENABLE
CAN.BS1=CAN_BS1_13TQ
CAN.BS2=CAN_BS2_2TQ
CAN.CalculateBaudRate=500000
CAN.CalculateTimeBit=2000
CAN.CalculateTimeQuantum=125.0
CAN.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,BS1,BS2,Prescaler,ABOM,NART
CAN.NART=ENABLE
CAN.Prescaler=2
File.Version=6
GPIO.groupedBy=
KeepUserPlacement=false
@ -75,6 +80,7 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.USB_LP_CAN_RX0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA0.GPIOParameters=GPIO_Label
PA0.GPIO_Label=HV_MISMATCH_ERR