diff --git a/.mxproject b/.mxproject index d3df932..be0c470 100644 --- a/.mxproject +++ b/.mxproject @@ -6,6 +6,11 @@ SourceFiles=../Core/Src/main.c;../Core/Src/stm32g4xx_it.c;../Core/Src/stm32g4xx_ HeaderPath=../Drivers/STM32G4xx_HAL_Driver/Inc;../Drivers/STM32G4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32G4xx/Include;../Drivers/CMSIS/Include;../Core/Inc; CDefines=USE_HAL_DRIVER;STM32G431xx;USE_HAL_DRIVER;USE_HAL_DRIVER; +[PreviousUsedMakefileFiles] +SourceFiles=Core/Src/main.c;Core/Src/stm32g4xx_it.c;Core/Src/stm32g4xx_hal_msp.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;;; +HeaderPath=Drivers/STM32G4xx_HAL_Driver/Inc;Drivers/STM32G4xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32G4xx/Include;Drivers/CMSIS/Include;Core/Inc; +CDefines=USE_HAL_DRIVER;STM32G431xx;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/stm32g4xx_it.c;Core/Src/stm32g4xx_hal_msp.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_fdcan.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_rcc_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_flash_ramfunc.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_gpio.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_exti.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_dma_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c;Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c;Drivers/CMSIS/Device/ST/STM32G4xx/Source/Templates/system_stm32g4xx.c;Core/Src/system_stm32g4xx.c;;; -HeaderPath=Drivers/STM32G4xx_HAL_Driver/Inc;Drivers/STM32G4xx_HAL_Driver/Inc/Legacy;Drivers/CMSIS/Device/ST/STM32G4xx/Include;Drivers/CMSIS/Include;Core/Inc; -CDefines=USE_HAL_DRIVER;STM32G431xx;USE_HAL_DRIVER;USE_HAL_DRIVER; - diff --git a/Core/Inc/AIR_State_Maschine.h b/Core/Inc/AIR_State_Maschine.h new file mode 100644 index 0000000..5f285eb --- /dev/null +++ b/Core/Inc/AIR_State_Maschine.h @@ -0,0 +1,61 @@ +/* + * AIR_State_Maschine.h + * + * Created on: Jun 15, 2022 + * Author: max + */ + +#ifndef INC_AIR_STATE_MASCHINE_H_ +#define INC_AIR_STATE_MASCHINE_H_ + +#include "main.h" + +#include "stm32g431xx.h" +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_gpio.h" + +#define TS_INACTIVE 0 +#define TS_PRECHARGE 2 +#define TS_DISCHARGE 3 +#define TS_ERROR 4 +#define TS_ACTIVE 1 +#define TS_CHARGING_CHECK 5 +#define TS_CHARGING 6 + +#define ADC_READ_TIMEOUT 500 // in ms +#define SDC_LOWER_THRESHOLD 2500 // in ADC Values +#define PRECHARGE_95_DURATION 1000 // in ms +#define PRECHARGE_OPEN_AFTER 1000 // in ms +// FIXME +#define LOWER_VEHICLE_SIDE_VOLTAGE_LIMIT 150000 // in mV + +typedef struct { + + int32_t BatteryVoltageVehicleSide; + int32_t BatteryVoltageBatterySide; + int32_t shuntCurrent; + uint8_t targetTSState; + uint8_t currentTSState; + uint32_t precharge95ReachedTimestamp; + uint32_t chargingCheckTimestamp; + +} AIRStateHandler; + +AIRStateHandler init_AIR_State_Maschine(); + +void Update_AIR_Info(AIRStateHandler* airstate); +uint8_t Update_AIR_State(AIRStateHandler* airstate); +void Activate_TS(AIRStateHandler* airstate); +void Deactivate_TS(AIRStateHandler* airstate); + +void AIR_Precharge_Position(); +void AIR_Inactive_Position(); +void AIR_Discharge_Position(); +void AIR_Active_Position(); +void AIR_Error_Position(); + +typedef enum { RELAY_AIR_NEG, RELAY_AIR_POS, RELAY_PRECHARGE } Relay; + +void Set_Relay_Position(Relay relay, GPIO_PinState position); + +#endif /* INC_AIR_STATE_MASCHINE_H_ */ diff --git a/Core/Inc/AMS_Errorcodes.h b/Core/Inc/AMS_Errorcodes.h new file mode 100644 index 0000000..63b3bb5 --- /dev/null +++ b/Core/Inc/AMS_Errorcodes.h @@ -0,0 +1,18 @@ +/* + * AMS_Errorcodes.h + * + * Created on: Jun 16, 2022 + * Author: max + */ + +#ifndef INC_AMS_ERRORCODES_H_ +#define INC_AMS_ERRORCODES_H_ + +#include "main.h" + +#define SlavesTimeoutError 1 +#define SlavesErrorFrameError 2 +#define SLAVES_FRAME_TIMEOUT_ERROR 3 +#define SLAVES_TOO_FEW_TEMPS 4 + +#endif /* INC_AMS_ERRORCODES_H_ */ diff --git a/Core/Inc/CAN_Communication.h b/Core/Inc/CAN_Communication.h new file mode 100644 index 0000000..efe258e --- /dev/null +++ b/Core/Inc/CAN_Communication.h @@ -0,0 +1,52 @@ +/* + * CAN_Communication.h + * + * Created on: Apr 26, 2022 + * Author: max + */ + +#ifndef INC_CAN_COMMUNICATION_H_ +#define INC_CAN_COMMUNICATION_H_ + +#include "AMS_Errorcodes.h" +#include "Slave_Monitoring.h" +#include "main.h" + +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" + +#define CANFRAMEBUFFERSIZE 512 + +// Frame ID = Base Address + Slave ID + MessageNr. +#define SLAVE_STATUS_BASE_ADDRESS 0x600 +#define SLAVE_CMD_BASE_ADDRESS 0x500 // +#define SLAVE_EMERGENCY_ADDRESS 0x001 // Emergency Frame +#define CLOCK_SYNC_ADDRESS 0x002 +#define MASTER_HEARTBEAT_ADDRESS 0x010 +#define SLAVE_EEPROM_WRITE_ADDRESS 0x020 + +typedef struct { + int16_t FrameID; + uint8_t data[8]; + uint8_t length; + uint32_t timestamp; + uint8_t error; + +} canFrame; + +extern canFrame framebuffer[CANFRAMEBUFFERSIZE]; + +extern uint32_t framebufferwritepointer; +extern uint32_t framebufferreadpointer; +extern uint32_t frames_read; + +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef* handle, + uint32_t interrupt_flags); + +void CAN_Init(FDCAN_HandleTypeDef* hcan); +uint8_t CAN_Receive(FDCAN_HandleTypeDef* hcan); +uint8_t CAN_Transmit(FDCAN_HandleTypeDef* hcan, uint16_t frameid, + uint8_t* buffer, uint8_t datalen); +void updateSlaveInfo(uint8_t slaveID, uint8_t MessageID, canFrame rxFrame); + +#endif /* INC_CAN_COMMUNICATION_H_ */ diff --git a/Core/Inc/Clock_Sync.h b/Core/Inc/Clock_Sync.h new file mode 100644 index 0000000..b4213c6 --- /dev/null +++ b/Core/Inc/Clock_Sync.h @@ -0,0 +1,34 @@ +#ifndef INC_CLOCK_SYNC_H_ +#define INC_CLOCK_SYNC_H_ + +/** + * @file Clock_Sync.h + * @author Jasper v. Blanckenburg (j.blanckenburg@fasttube.de) + * @brief Clock synchronization mechanism -- master side + * @version 0.1 + * @date 2022-08-01 + * + * @copyright Copyright (c) 2022 + * + * The slaves' clocks are fairly inaccurate -- too inaccurate for reliable CAN + * communication. In order to synchronize the clock frequencies, the slaves need + * an external clock source. Since the HSE doesn't work on all slaves, we use + * the master as the external clock source. For more detail, take a look at the + * clock sync section in the slave code. + * + * This file handles the master part of the clock sync mechanism: It sends + * CLOCK_SYNC frames every 1000 ms and MASTER_HEARTBEAT frames every 100 ms. In + * order to keep the time between packets accurate, they are sent from timer + * interrupts. + */ + +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" +#include "stm32g4xx_hal_tim.h" + +void clock_sync_init(FDCAN_HandleTypeDef* can, TIM_HandleTypeDef* sync_timer, + TIM_HandleTypeDef* heartbeat_timer); + +void clock_sync_handle_timer_complete(TIM_HandleTypeDef* timer); + +#endif // INC_CLOCK_SYNC_H_ diff --git a/Core/Inc/Error_Check.h b/Core/Inc/Error_Check.h new file mode 100644 index 0000000..9cb9ebf --- /dev/null +++ b/Core/Inc/Error_Check.h @@ -0,0 +1,30 @@ +/* + * Error_Check.h + * + * Created on: Jun 16, 2022 + * Author: max + */ + +#ifndef INC_ERROR_CHECK_H_ +#define INC_ERROR_CHECK_H_ + +#include "main.h" + +typedef struct { + uint8_t IMD_ERROR; + uint8_t AMS_ERROR_LED; + uint8_t IMD_ERROR_LED; + + uint8_t TS_no_voltage_error; + uint8_t positive_AIR_or_PC_error; + uint8_t negative_AIR_error; + + uint8_t HV_inactive; + uint8_t negative_AIR_open; + uint8_t positive_AIR_and_PC_open; + +} ErrorFlags; + +ErrorFlags CheckErrorFlags(); + +#endif /* INC_ERROR_CHECK_H_ */ diff --git a/Core/Inc/Slave_Monitoring.h b/Core/Inc/Slave_Monitoring.h new file mode 100644 index 0000000..362453e --- /dev/null +++ b/Core/Inc/Slave_Monitoring.h @@ -0,0 +1,44 @@ +/* + * Slave_Monitoring.h + * + * Created on: Jun 15, 2022 + * Author: max + */ + +#ifndef INC_SLAVE_MONITORING_H_ +#define INC_SLAVE_MONITORING_H_ + +#include "AMS_Errorcodes.h" +#include "Error_Check.h" +#include "main.h" + +#include "stm32g431xx.h" + +#define NUMBEROFSLAVES 9 +#define NUMBEROFCELLS 10 +#define NUMBEROFTEMPS 32 + +#define SLAVETIMEOUT 5000 +#define SLAVE_HEARTBEAT_FRAMES 11 +// 30% * 90 = 27, each sensor measures 2 cells +#define SLAVE_MIN_TEMP_SENSORS 14 + +typedef struct { + + uint16_t slaveID; + uint16_t cellVoltages[NUMBEROFCELLS]; + uint16_t cellTemps[NUMBEROFTEMPS]; + uint32_t timestamp; + uint8_t error; + uint8_t timeout; + uint32_t frame_timestamps[SLAVE_HEARTBEAT_FRAMES]; + uint8_t error_frame[8]; + +} SlaveHandler; + +extern SlaveHandler slaves[NUMBEROFSLAVES]; + +void initSlaves(); +uint8_t checkSlaveTimeout(); + +#endif /* INC_SLAVE_MONITORING_H_ */ diff --git a/Core/Inc/main.h b/Core/Inc/main.h index d887f3a..dd1814f 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -36,7 +36,10 @@ extern "C" { /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ - +typedef struct { + uint8_t errorcode; + uint8_t errorarg[8]; +} AMSErrorHandle; /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ @@ -55,7 +58,7 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim); void Error_Handler(void); /* USER CODE BEGIN EFP */ - +void AMS_Error_Handler(AMSErrorHandle*); /* USER CODE END EFP */ /* Private defines -----------------------------------------------------------*/ diff --git a/Core/Src/AIR_State_Maschine.c b/Core/Src/AIR_State_Maschine.c new file mode 100644 index 0000000..20fe32b --- /dev/null +++ b/Core/Src/AIR_State_Maschine.c @@ -0,0 +1,263 @@ +/* + * AIR_State_Maschine.c + * + * Created on: Jun 15, 2022 + * Author: max + */ + +#include "AIR_State_Maschine.h" + +#include "main.h" + +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_gpio.h" + +DMA_HandleTypeDef* air_current_dma = {0}; +DMA_HandleTypeDef* sdc_voltage_dma = {0}; + +uint8_t air_adc_complete = 0; +uint8_t sdc_adc_complete = 0; + +static uint32_t pos_air_change_timestamp, neg_air_change_timestamp, + precharge_change_timestamp; +static GPIO_PinState neg_air_state, pos_air_state, precharge_state; + +AIRStateHandler init_AIR_State_Maschine() { + AIRStateHandler airstate = {0}; + + airstate.targetTSState = TS_INACTIVE; + airstate.currentTSState = TS_INACTIVE; + airstate.BatteryVoltageBatterySide = 0; + airstate.BatteryVoltageVehicleSide = 0; + + return airstate; +} + +void Update_AIR_Info(AIRStateHandler* airstate) { + uint16_t relay_adc_buffer[4] = {0}; + uint16_t sdc_adc_buffer[1] = {0}; + + /*//HAL_ADC_Start_DMA(air_current_adc, (uint32_t*)relay_adc_buffer, 4); + //HAL_ADC_Start_DMA(sdc_voltage_adc, (uint32_t*)sdc_adc_buffer, 1); + HAL_ADC_Start(sdc_voltage_adc); + HAL_StatusTypeDef status = HAL_ADC_PollForConversion(sdc_voltage_adc, 10); + uint32_t adcval1 = HAL_ADC_GetValue(sdc_voltage_adc); + HAL_ADC_Stop(sdc_voltage_adc); + + HAL_ADC_Start(air_current_adc); + status = HAL_ADC_PollForConversion(air_current_adc, 10); + uint32_t adcval2 = HAL_ADC_GetValue(air_current_adc); + HAL_ADC_Start(air_current_adc); + status = HAL_ADC_PollForConversion(air_current_adc, 10); + uint32_t adcval3 = HAL_ADC_GetValue(air_current_adc); + HAL_ADC_Start(air_current_adc); + status = HAL_ADC_PollForConversion(air_current_adc, 10); + uint32_t adcval4 = HAL_ADC_GetValue(air_current_adc); + HAL_ADC_Start(air_current_adc); + status = HAL_ADC_PollForConversion(air_current_adc, 10); + uint32_t adcval5 = HAL_ADC_GetValue(air_current_adc); + HAL_ADC_Stop(air_current_adc);*/ +} + +uint8_t Update_AIR_State(AIRStateHandler* airstate) { + Update_AIR_Info(airstate); + + //--------------------------------------------------State Transition + // Rules---------------------------------------------------------- + + /*if(airstate->currentTSState == airstate->targetTSState) //Target TS + State is Equal to actual TS State + { + return airstate->currentTSState; + }*/ + + if (airstate->currentTSState == TS_ERROR) // No Escape from TS Error State + { + // Don't change anything, but prevent any other if from being entered + } + + else if (airstate->targetTSState == + TS_ERROR) // Error State is Entered if Target State is Error State + { + airstate->currentTSState = TS_ERROR; + } + + else if ((airstate->currentTSState == TS_INACTIVE) && + (airstate->targetTSState == + TS_ACTIVE)) // Transition from Inactive to Active via Precharge + { + airstate->currentTSState = TS_PRECHARGE; + airstate->precharge95ReachedTimestamp = 0; + } + + else if ((airstate->currentTSState == TS_INACTIVE) && + (airstate->targetTSState == TS_CHARGING)) { + airstate->currentTSState = TS_CHARGING_CHECK; + airstate->chargingCheckTimestamp = HAL_GetTick(); + } + + // TODO: Is it correct that we also go from precharge to discharge? + else if ((airstate->currentTSState == TS_ACTIVE || + airstate->currentTSState == TS_PRECHARGE || + airstate->currentTSState == TS_CHARGING_CHECK || + airstate->currentTSState == TS_CHARGING) && + (airstate->targetTSState == + TS_INACTIVE)) // Transition from Active to Inactive via Discharge + { + airstate->currentTSState = TS_DISCHARGE; + } + + else if ((airstate->targetTSState == TS_CHARGING) && + (airstate->currentTSState == TS_CHARGING_CHECK)) { + if (airstate->BatteryVoltageVehicleSide > + airstate->BatteryVoltageBatterySide) { + airstate->currentTSState = TS_CHARGING; + } else if (HAL_GetTick() > airstate->chargingCheckTimestamp + 2000) { + airstate->currentTSState = TS_ERROR; + } + } + + else if (airstate->currentTSState == TS_CHARGING) { + if (airstate->shuntCurrent < 0) { + airstate->currentTSState = TS_ERROR; + } + } + + else if (airstate->currentTSState == + TS_PRECHARGE) // Change from Precharge to Active at 95% TS Voltage at + // Vehicle Side + { + if ((airstate->BatteryVoltageVehicleSide > + LOWER_VEHICLE_SIDE_VOLTAGE_LIMIT)) { + if (airstate->BatteryVoltageVehicleSide > + (airstate->BatteryVoltageBatterySide * 0.95)) { + if (airstate->precharge95ReachedTimestamp == 0) { + airstate->precharge95ReachedTimestamp = HAL_GetTick(); + } else if (HAL_GetTick() - airstate->precharge95ReachedTimestamp >= + PRECHARGE_95_DURATION) { + airstate->currentTSState = TS_ACTIVE; + } + } + } + } + + else if (airstate->currentTSState == + TS_DISCHARGE) // Change from Discharge to Inactive at 95% TS + // Voltage at Vehicle Side + { + airstate->currentTSState = TS_INACTIVE; + } + + //_-----------------------------------------------AIR + // Positions-------------------------------------------------------- + + if (airstate->currentTSState == TS_PRECHARGE) { + AIR_Precharge_Position(); + } + + if (airstate->currentTSState == TS_DISCHARGE) { + AIR_Discharge_Position(); + } + + if (airstate->currentTSState == TS_CHARGING_CHECK) { + AIR_Precharge_Position(); + } + + if (airstate->currentTSState == TS_CHARGING) { + AIR_Active_Position(); + } + + if (airstate->currentTSState == TS_ACTIVE) { + AIR_Active_Position(); + } + + if (airstate->currentTSState == TS_INACTIVE) { + AIR_Inactive_Position(); + } + + if (airstate->currentTSState == TS_ERROR) { + AIR_Error_Position(); + } + + return airstate->currentTSState; +} + +void Activate_TS(AIRStateHandler* airstate) { + airstate->targetTSState = TS_ACTIVE; +} + +void Deactivate_TS(AIRStateHandler* airstate) { + airstate->targetTSState = TS_INACTIVE; +} + +void AIR_Precharge_Position() { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_SET); + Set_Relay_Position(RELAY_AIR_NEG, GPIO_PIN_SET); + Set_Relay_Position(RELAY_AIR_POS, GPIO_PIN_RESET); +} + +void AIR_Inactive_Position() { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_RESET); + Set_Relay_Position(RELAY_AIR_NEG, GPIO_PIN_RESET); + Set_Relay_Position(RELAY_AIR_POS, GPIO_PIN_RESET); +} + +void AIR_Discharge_Position() { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_SET); + Set_Relay_Position(RELAY_AIR_NEG, GPIO_PIN_SET); + Set_Relay_Position(RELAY_AIR_POS, GPIO_PIN_RESET); +} + +void AIR_Active_Position() { + if (pos_air_state == GPIO_PIN_SET && + HAL_GetTick() - pos_air_change_timestamp > PRECHARGE_OPEN_AFTER) { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_RESET); + } else { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_SET); + } + Set_Relay_Position(RELAY_AIR_NEG, GPIO_PIN_SET); + Set_Relay_Position(RELAY_AIR_POS, GPIO_PIN_SET); +} + +void AIR_Error_Position() { + Set_Relay_Position(RELAY_PRECHARGE, GPIO_PIN_RESET); + Set_Relay_Position(RELAY_AIR_NEG, GPIO_PIN_RESET); + Set_Relay_Position(RELAY_AIR_POS, GPIO_PIN_RESET); +} + +void Set_Relay_Position(Relay relay, GPIO_PinState position) { + // Add a small delay after closing relays in order to not draw too much + // current + switch (relay) { + case RELAY_AIR_NEG: + HAL_GPIO_WritePin(NEG_AIR_CTRL_GPIO_Port, NEG_AIR_CTRL_Pin, position); + if (position != neg_air_state) { + neg_air_change_timestamp = HAL_GetTick(); + } + if (position == GPIO_PIN_SET && neg_air_state == GPIO_PIN_RESET) { + HAL_Delay(10); + } + neg_air_state = position; + break; + case RELAY_AIR_POS: + HAL_GPIO_WritePin(POS_AIR_CTRL_GPIO_Port, POS_AIR_CTRL_Pin, position); + if (position != pos_air_state) { + pos_air_change_timestamp = HAL_GetTick(); + } + if (position == GPIO_PIN_SET && pos_air_state == GPIO_PIN_RESET) { + HAL_Delay(10); + } + pos_air_state = position; + break; + case RELAY_PRECHARGE: + HAL_GPIO_WritePin(PRECHARGE_CTRL_GPIO_Port, PRECHARGE_CTRL_Pin, position); + if (position != precharge_state) { + precharge_change_timestamp = HAL_GetTick(); + } + if (position == GPIO_PIN_SET && precharge_state == GPIO_PIN_RESET) { + HAL_Delay(10); + } + precharge_state = position; + break; + } +} diff --git a/Core/Src/CAN_Communication.c b/Core/Src/CAN_Communication.c new file mode 100644 index 0000000..6223891 --- /dev/null +++ b/Core/Src/CAN_Communication.c @@ -0,0 +1,210 @@ +/* + * CAN_Communication.c + * + * Created on: Apr 26, 2022 + * Author: max + */ + +#include "CAN_Communication.h" + +#include "Error_Check.h" + +#include "stm32g4xx_hal_fdcan.h" + +#include +#include + +const uint16_t slave_CAN_id_to_slave_index[10] = { + 0, 1, 2, 3, 4, 5, 6, 7, 255, 8}; // TODO: Make this pretty pls +canFrame framebuffer[CANFRAMEBUFFERSIZE] = {0}; +uint32_t framebufferwritepointer = 0; +uint32_t framebufferreadpointer = 0; +uint32_t frames_read = 0; + +void CAN_Init(FDCAN_HandleTypeDef* hcan) { + HAL_FDCAN_Stop(hcan); + + framebufferreadpointer = 0; + framebufferwritepointer = 0; + + FDCAN_FilterTypeDef fdfilter = {0}; + + fdfilter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + fdfilter.FilterID1 = 0x000; // ID + fdfilter.FilterID2 = 0x000; // Mask + fdfilter.FilterIndex = 0; + + fdfilter.FilterType = FDCAN_FILTER_MASK; + fdfilter.IdType = FDCAN_STANDARD_ID; + + HAL_FDCAN_ConfigFilter(hcan, &fdfilter); + + HAL_StatusTypeDef status = HAL_FDCAN_Start(hcan); + + if (status) { + return; + } + + status = + HAL_FDCAN_ActivateNotification(hcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); +} + +uint8_t CAN_Receive(FDCAN_HandleTypeDef* hcan) { + frames_read = 0; + while (framebufferreadpointer != framebufferwritepointer) { + framebufferreadpointer++; + + if (framebufferreadpointer >= CANFRAMEBUFFERSIZE) { + framebufferreadpointer = 0; + } + + canFrame rxFrame = framebuffer[framebufferreadpointer]; + frames_read++; + + if ((rxFrame.FrameID & SLAVE_STATUS_BASE_ADDRESS) == + SLAVE_STATUS_BASE_ADDRESS) { + uint16_t msg = rxFrame.FrameID - SLAVE_STATUS_BASE_ADDRESS; + uint8_t slaveID = (msg & 0x0F0) >> 4; + slaveID = slave_CAN_id_to_slave_index[slaveID]; + uint8_t messageID = msg & 0x00F; + updateSlaveInfo(slaveID, messageID, rxFrame); + } else if (rxFrame.FrameID == SLAVE_EMERGENCY_ADDRESS) { + uint8_t slave_id = rxFrame.data[0]; + slaves[slave_id].error = 1; + memcpy(slaves[slave_id].error_frame, rxFrame.data, 8); + } + } + + return 0; +} + +uint8_t CAN_Transmit(FDCAN_HandleTypeDef* hcan, uint16_t frameid, + uint8_t* buffer, uint8_t datalen) { + FDCAN_TxHeaderTypeDef txheader = {0}; + + txheader.Identifier = frameid; + txheader.IdType = FDCAN_STANDARD_ID; + txheader.TxFrameType = FDCAN_FRAME_CLASSIC; + txheader.DataLength = ((uint32_t)datalen) << 16; + txheader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; + txheader.BitRateSwitch = FDCAN_BRS_OFF; + txheader.FDFormat = FDCAN_CLASSIC_CAN; + txheader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; + txheader.MessageMarker = 0; + + HAL_FDCAN_AddMessageToTxFifoQ(hcan, &txheader, buffer); + + return 0; +} +void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef* hcan) {} + +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef* handle, + uint32_t interrupt_flags) { + + FDCAN_RxHeaderTypeDef rxFrameHeader; + uint8_t data[8]; + framebufferwritepointer++; + + if (framebufferwritepointer >= CANFRAMEBUFFERSIZE) { + framebufferwritepointer = 0; + } + + if (!(interrupt_flags & FDCAN_IT_RX_FIFO0_NEW_MESSAGE)) { + return; + } + + if (HAL_FDCAN_GetRxMessage(handle, FDCAN_RX_FIFO0, &rxFrameHeader, data) != + HAL_OK) { + framebuffer[framebufferwritepointer].error = 1; + } else { + framebuffer[framebufferwritepointer].error = 0; + } + + if (rxFrameHeader.IdType != FDCAN_STANDARD_ID) { + return; + } + + framebuffer[framebufferwritepointer].FrameID = + (int16_t)rxFrameHeader.Identifier; + framebuffer[framebufferwritepointer].length = + (uint8_t)rxFrameHeader.DataLength >> 16; + + for (int i = 0; i < (rxFrameHeader.DataLength >> 16); i++) { + framebuffer[framebufferwritepointer].data[i] = data[i]; + } + + framebuffer[framebufferwritepointer].timestamp = HAL_GetTick(); +} + +void updateSlaveInfo(uint8_t slaveID, uint8_t MessageID, canFrame rxFrame) { + if (slaveID < NUMBEROFSLAVES) { + switch (MessageID) { + case 0x00: + slaves[slaveID].cellVoltages[0] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellVoltages[1] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellVoltages[2] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellVoltages[3] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x01: + slaves[slaveID].cellVoltages[4] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellVoltages[5] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellVoltages[6] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellVoltages[7] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x02: + slaves[slaveID].cellVoltages[8] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellVoltages[9] = rxFrame.data[2] | rxFrame.data[3] << 8; + break; + case 0x03: + slaves[slaveID].cellTemps[0] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[1] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[2] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[3] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x04: + slaves[slaveID].cellTemps[4] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[5] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[6] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[7] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x05: + slaves[slaveID].cellTemps[8] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[9] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[10] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[11] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x06: + slaves[slaveID].cellTemps[12] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[13] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[14] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[15] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x07: + slaves[slaveID].cellTemps[16] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[17] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[18] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[19] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x08: + slaves[slaveID].cellTemps[20] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[21] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[22] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[23] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x09: + slaves[slaveID].cellTemps[24] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[25] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[26] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[27] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + case 0x0A: + slaves[slaveID].cellTemps[28] = rxFrame.data[0] | rxFrame.data[1] << 8; + slaves[slaveID].cellTemps[29] = rxFrame.data[2] | rxFrame.data[3] << 8; + slaves[slaveID].cellTemps[30] = rxFrame.data[4] | rxFrame.data[5] << 8; + slaves[slaveID].cellTemps[31] = rxFrame.data[6] | rxFrame.data[7] << 8; + break; + } + slaves[slaveID].timestamp = rxFrame.timestamp; + slaves[slaveID].frame_timestamps[MessageID] = rxFrame.timestamp; + } +} diff --git a/Core/Src/Clock_Sync.c b/Core/Src/Clock_Sync.c new file mode 100644 index 0000000..78f4067 --- /dev/null +++ b/Core/Src/Clock_Sync.c @@ -0,0 +1,35 @@ +#include "Clock_Sync.h" + +#include "CAN_Communication.h" + +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" +#include "stm32g4xx_hal_tim.h" + +static FDCAN_HandleTypeDef* can; +static TIM_HandleTypeDef* sync_timer; +static TIM_HandleTypeDef* heartbeat_timer; + +static uint8_t clock_sync_counter = 0; + +void clock_sync_init(FDCAN_HandleTypeDef* can_handle, + TIM_HandleTypeDef* sync_timer_handle, + TIM_HandleTypeDef* heartbeat_timer_handle) { + can = can_handle; + sync_timer = sync_timer_handle; + heartbeat_timer = heartbeat_timer_handle; + HAL_TIM_Base_Start_IT(heartbeat_timer); + // Delay between starting the timers so the interrupts don't fire at the same + // time + HAL_Delay(50); + HAL_TIM_Base_Start_IT(sync_timer); +} + +void clock_sync_handle_timer_complete(TIM_HandleTypeDef* timer) { + if (timer == sync_timer) { + CAN_Transmit(can, CLOCK_SYNC_ADDRESS, &clock_sync_counter, 1); + clock_sync_counter++; + } else if (timer == heartbeat_timer) { + CAN_Transmit(can, MASTER_HEARTBEAT_ADDRESS, NULL, 0); + } +} diff --git a/Core/Src/Error_Check.c b/Core/Src/Error_Check.c new file mode 100644 index 0000000..0720708 --- /dev/null +++ b/Core/Src/Error_Check.c @@ -0,0 +1,13 @@ +/* + * Error_Check.c + * + * Created on: Jun 16, 2022 + * Author: max + */ + +#include "Error_Check.h" + +ErrorFlags CheckErrorFlags() { + ErrorFlags errors = {0}; + return errors; +} diff --git a/Core/Src/Slave_Monitoring.c b/Core/Src/Slave_Monitoring.c new file mode 100644 index 0000000..74fd075 --- /dev/null +++ b/Core/Src/Slave_Monitoring.c @@ -0,0 +1,104 @@ +/* + * Slave_Monitoring.c + * + * Created on: Jun 15, 2022 + * Author: max + */ + +#include "Slave_Monitoring.h" + +#include "AMS_Errorcodes.h" +#include "main.h" + +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_gpio.h" + +#include + +SlaveHandler slaves[NUMBEROFSLAVES]; + +void initSlaves() { + HAL_GPIO_WritePin(SLAVES_ENABLE_GPIO_Port, SLAVES_ENABLE_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(BOOT0_FF_DATA_GPIO_Port, BOOT0_FF_DATA_Pin, GPIO_PIN_RESET); + + for (int i = 0; i < NUMBEROFSLAVES + 5; i++) { + HAL_GPIO_WritePin(BOOT0_FF_CLK_GPIO_Port, BOOT0_FF_CLK_Pin, GPIO_PIN_SET); + HAL_Delay(1); + HAL_GPIO_WritePin(BOOT0_FF_CLK_GPIO_Port, BOOT0_FF_CLK_Pin, GPIO_PIN_RESET); + HAL_Delay(1); + } + + HAL_Delay(5); + HAL_GPIO_WritePin(SLAVES_ENABLE_GPIO_Port, SLAVES_ENABLE_Pin, GPIO_PIN_SET); + + for (int n = 0; n < NUMBEROFSLAVES; n++) { + for (int i = 0; i < NUMBEROFTEMPS; i++) + slaves[n].cellTemps[i] = 0; + + for (int j = 0; j < NUMBEROFCELLS; j++) + slaves[n].cellVoltages[j] = 32768; + + slaves[n].error = 0; + slaves[n].timeout = 0; + slaves[n].timestamp = HAL_GetTick(); + slaves[n].slaveID = n; + for (int i = 0; i < SLAVE_HEARTBEAT_FRAMES; i++) { + slaves[n].frame_timestamps[i] = HAL_GetTick(); + } + } +} + +uint8_t checkSlaveTimeout() { + if (HAL_GetTick() < 10000) { + return 0; + } + + for (int n = 0; n < NUMBEROFSLAVES; n++) { + if (((int)(HAL_GetTick() - slaves[n].timestamp)) > SLAVETIMEOUT) { + slaves[n].timeout = 1; + + AMSErrorHandle timeouterror; + timeouterror.errorcode = SlavesTimeoutError; + timeouterror.errorarg[0] = n; + + AMS_Error_Handler(&timeouterror); + return 1; + } + + if (slaves[n].error) { + AMSErrorHandle errorframe; + errorframe.errorcode = SlavesErrorFrameError; + memcpy(errorframe.errorarg, slaves[n].error_frame, 7); + AMS_Error_Handler(&errorframe); + return 1; + } + + for (int i = 0; i < SLAVE_HEARTBEAT_FRAMES; i++) { + if ((int)(HAL_GetTick() - slaves[n].frame_timestamps[i]) > + SLAVETIMEOUT * 2) { + slaves[n].timeout = 1; + AMSErrorHandle timeouterror; + timeouterror.errorcode = SLAVES_FRAME_TIMEOUT_ERROR; + timeouterror.errorarg[0] = n; + timeouterror.errorarg[1] = i; + AMS_Error_Handler(&timeouterror); + return 1; + } + } + + int working_cell_temps = 0; + for (int i = 0; i < NUMBEROFTEMPS; i++) { + if (slaves[n].cellTemps[i] != 0) { + working_cell_temps++; + } + } + if (working_cell_temps < SLAVE_MIN_TEMP_SENSORS) { + AMSErrorHandle temperror; + temperror.errorcode = SLAVES_TOO_FEW_TEMPS; + temperror.errorarg[0] = n; + AMS_Error_Handler(&temperror); + return 1; + } + } + return 0; +} diff --git a/Core/Src/main.c b/Core/Src/main.c index b2deb5a..10e62b7 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -21,7 +21,11 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ - +#include "AIR_State_Maschine.h" +#include "CAN_Communication.h" +#include "Clock_Sync.h" +#include "Error_Check.h" +#include "Slave_Monitoring.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -41,7 +45,9 @@ /* Private variables ---------------------------------------------------------*/ FDCAN_HandleTypeDef hfdcan1; +TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim3; +TIM_HandleTypeDef htim8; /* USER CODE BEGIN PV */ @@ -52,13 +58,17 @@ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM3_Init(void); static void MX_FDCAN1_Init(void); +static void MX_TIM1_Init(void); +static void MX_TIM8_Init(void); /* USER CODE BEGIN PFP */ - +void setAMSError(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ - +AIRStateHandler airstates; +ErrorFlags errorflags; +AMSErrorHandle defaulterrorhandle = {0}; /* USER CODE END 0 */ /** @@ -91,8 +101,13 @@ int main(void) { MX_GPIO_Init(); MX_TIM3_Init(); MX_FDCAN1_Init(); + MX_TIM1_Init(); + MX_TIM8_Init(); /* USER CODE BEGIN 2 */ - + airstates = init_AIR_State_Maschine(); + CAN_Init(&hfdcan1); + clock_sync_init(&hfdcan1, &htim1, &htim8); + initSlaves(); /* USER CODE END 2 */ /* Infinite loop */ @@ -101,6 +116,11 @@ int main(void) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ + CAN_Receive(&hfdcan1); // Run CAN Event Loop + errorflags = CheckErrorFlags(); // Check for Errors + Update_AIR_Info(&airstates); + checkSlaveTimeout(); // check for Slave Timeout + Update_AIR_State(&airstates); // Update AIR State Maschine } /* USER CODE END 3 */ } @@ -181,6 +201,48 @@ static void MX_FDCAN1_Init(void) { /* USER CODE END FDCAN1_Init 2 */ } +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) { + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 1599; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 9999; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ +} + /** * @brief TIM3 Initialization Function * @param None @@ -225,6 +287,48 @@ static void MX_TIM3_Init(void) { HAL_TIM_MspPostInit(&htim3); } +/** + * @brief TIM8 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM8_Init(void) { + + /* USER CODE BEGIN TIM8_Init 0 */ + + /* USER CODE END TIM8_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM8_Init 1 */ + + /* USER CODE END TIM8_Init 1 */ + htim8.Instance = TIM8; + htim8.Init.Prescaler = 1599; + htim8.Init.CounterMode = TIM_COUNTERMODE_UP; + htim8.Init.Period = 999; + htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim8.Init.RepetitionCounter = 0; + htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim8) != HAL_OK) { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK) { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN TIM8_Init 2 */ + + /* USER CODE END TIM8_Init 2 */ +} + /** * @brief GPIO Initialization Function * @param None @@ -282,7 +386,27 @@ static void MX_GPIO_Init(void) { } /* USER CODE BEGIN 4 */ +void AMS_Error_Handler(AMSErrorHandle* errorinfo) { + while (1) { + setAMSError(); + airstates.targetTSState = TS_ERROR; + Update_AIR_State(&airstates); + CAN_Receive(&hfdcan1); + errorflags = CheckErrorFlags(); + } +} +void setAMSError() { + static int errors = 0; + errors++; + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = AMS_ERR_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(AMS_ERR_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_WritePin(AMS_ERR_GPIO_Port, AMS_ERR_Pin, GPIO_PIN_RESET); +} /* USER CODE END 4 */ /** diff --git a/Core/Src/stm32g4xx_hal_msp.c b/Core/Src/stm32g4xx_hal_msp.c index 92a9719..c029ed9 100644 --- a/Core/Src/stm32g4xx_hal_msp.c +++ b/Core/Src/stm32g4xx_hal_msp.c @@ -158,6 +158,39 @@ void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* hfdcan) } +/** +* @brief TIM_Base MSP Initialization +* This function configures the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspInit 0 */ + + /* USER CODE END TIM1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM1_CLK_ENABLE(); + /* USER CODE BEGIN TIM1_MspInit 1 */ + + /* USER CODE END TIM1_MspInit 1 */ + } + else if(htim_base->Instance==TIM8) + { + /* USER CODE BEGIN TIM8_MspInit 0 */ + + /* USER CODE END TIM8_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_TIM8_CLK_ENABLE(); + /* USER CODE BEGIN TIM8_MspInit 1 */ + + /* USER CODE END TIM8_MspInit 1 */ + } + +} + /** * @brief TIM_PWM MSP Initialization * This function configures the hardware resources used in this example @@ -206,6 +239,39 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) } } +/** +* @brief TIM_Base MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param htim_base: TIM_Base handle pointer +* @retval None +*/ +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) +{ + if(htim_base->Instance==TIM1) + { + /* USER CODE BEGIN TIM1_MspDeInit 0 */ + + /* USER CODE END TIM1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM1_CLK_DISABLE(); + /* USER CODE BEGIN TIM1_MspDeInit 1 */ + + /* USER CODE END TIM1_MspDeInit 1 */ + } + else if(htim_base->Instance==TIM8) + { + /* USER CODE BEGIN TIM8_MspDeInit 0 */ + + /* USER CODE END TIM8_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM8_CLK_DISABLE(); + /* USER CODE BEGIN TIM8_MspDeInit 1 */ + + /* USER CODE END TIM8_MspDeInit 1 */ + } + +} + /** * @brief TIM_PWM MSP De-Initialization * This function freeze the hardware resources used in this example diff --git a/Makefile b/Makefile index f1c3365..25a6a49 100644 --- a/Makefile +++ b/Makefile @@ -1,40 +1,40 @@ -########################################################################################################################## -# File automatically-generated by tool: [projectgenerator] version: [3.17.1] date: [Mon Aug 08 02:48:24 CEST 2022] -########################################################################################################################## - -# ------------------------------------------------ -# Generic Makefile (based on gcc) -# -# ChangeLog : -# 2017-02-10 - Several enhancements + project update mode -# 2015-07-22 - first version -# ------------------------------------------------ - -###################################### -# target -###################################### -TARGET = ams-master - - -###################################### -# building variables -###################################### -# debug build? -DEBUG = 1 -# optimization -OPT = -Og - - -####################################### -# paths -####################################### -# Build path -BUILD_DIR = build - -###################################### -# source -###################################### -# C sources +########################################################################################################################## +# File automatically-generated by tool: [projectgenerator] version: [3.17.1] date: [Mon Aug 08 11:01:56 CEST 2022] +########################################################################################################################## + +# ------------------------------------------------ +# Generic Makefile (based on gcc) +# +# ChangeLog : +# 2017-02-10 - Several enhancements + project update mode +# 2015-07-22 - first version +# ------------------------------------------------ + +###################################### +# target +###################################### +TARGET = ams-master + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization +OPT = -Og + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources C_SOURCES = \ Core/Src/main.c \ Core/Src/stm32g4xx_it.c \ @@ -55,137 +55,137 @@ Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_pwr_ex.c \ Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_cortex.c \ Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim.c \ Drivers/STM32G4xx_HAL_Driver/Src/stm32g4xx_hal_tim_ex.c \ -Core/Src/system_stm32g4xx.c - -# ASM sources +Core/Src/system_stm32g4xx.c + +# ASM sources ASM_SOURCES = \ -startup_stm32g431xx.s - - -####################################### -# binaries -####################################### -PREFIX = arm-none-eabi- -# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) -# either it can be added to the PATH environment variable. -ifdef GCC_PATH -CC = $(GCC_PATH)/$(PREFIX)gcc -AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp -CP = $(GCC_PATH)/$(PREFIX)objcopy -SZ = $(GCC_PATH)/$(PREFIX)size -else -CC = $(PREFIX)gcc -AS = $(PREFIX)gcc -x assembler-with-cpp -CP = $(PREFIX)objcopy -SZ = $(PREFIX)size -endif -HEX = $(CP) -O ihex -BIN = $(CP) -O binary -S - -####################################### -# CFLAGS -####################################### -# cpu -CPU = -mcpu=cortex-m4 - -# fpu -FPU = -mfpu=fpv4-sp-d16 - -# float-abi -FLOAT-ABI = -mfloat-abi=hard - -# mcu -MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) - -# macros for gcc -# AS defines -AS_DEFS = - -# C defines +startup_stm32g431xx.s + + +####################################### +# binaries +####################################### +PREFIX = arm-none-eabi- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)gcc -x assembler-with-cpp +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +HEX = $(CP) -O ihex +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -mcpu=cortex-m4 + +# fpu +FPU = -mfpu=fpv4-sp-d16 + +# float-abi +FLOAT-ABI = -mfloat-abi=hard + +# mcu +MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = + +# C defines C_DEFS = \ -DUSE_HAL_DRIVER \ --DSTM32G431xx - - -# AS includes -AS_INCLUDES = - -# C includes +-DSTM32G431xx + + +# AS includes +AS_INCLUDES = + +# C includes C_INCLUDES = \ -ICore/Inc \ -IDrivers/STM32G4xx_HAL_Driver/Inc \ -IDrivers/STM32G4xx_HAL_Driver/Inc/Legacy \ -IDrivers/CMSIS/Device/ST/STM32G4xx/Include \ --IDrivers/CMSIS/Include - - -# compile gcc flags -ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections - -ifeq ($(DEBUG), 1) -CFLAGS += -g -gdwarf-2 -endif - - -# Generate dependency information -CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" - - -####################################### -# LDFLAGS -####################################### -# link script -LDSCRIPT = STM32G431CBTx_FLASH.ld - -# libraries -LIBS = -lc -lm -lnosys -LIBDIR = -LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections - -# default action: build all -all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin - - -####################################### -# build the application -####################################### -# list of objects -OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) -vpath %.c $(sort $(dir $(C_SOURCES))) -# list of ASM program objects -OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) -vpath %.s $(sort $(dir $(ASM_SOURCES))) - -$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) - $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ - -$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) - $(AS) -c $(CFLAGS) $< -o $@ - -$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile - $(CC) $(OBJECTS) $(LDFLAGS) -o $@ - $(SZ) $@ - -$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - $(HEX) $< $@ - -$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) - $(BIN) $< $@ - -$(BUILD_DIR): - mkdir $@ - -####################################### -# clean up -####################################### -clean: - -rm -fR $(BUILD_DIR) - -####################################### -# dependencies -####################################### --include $(wildcard $(BUILD_DIR)/*.d) - -# *** EOF *** \ No newline at end of file +-IDrivers/CMSIS/Include + + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = STM32G431CBTx_FLASH.ld + +# libraries +LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) +vpath %.s $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ + +$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) + $(AS) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(HEX) $< $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/STM32Make.make b/STM32Make.make index 55fa41e..6b7fb02 100644 --- a/STM32Make.make +++ b/STM32Make.make @@ -36,6 +36,11 @@ BUILD_DIR = build ###################################### # C sources C_SOURCES = \ +Core/Src/AIR_State_Maschine.c \ +Core/Src/CAN_Communication.c \ +Core/Src/Clock_Sync.c \ +Core/Src/Error_Check.c \ +Core/Src/Slave_Monitoring.c \ Core/Src/main.c \ Core/Src/stm32g4xx_hal_msp.c \ Core/Src/stm32g4xx_it.c \ diff --git a/ams-master.ioc b/ams-master.ioc index 32fe544..b6afbd3 100644 --- a/ams-master.ioc +++ b/ams-master.ioc @@ -20,8 +20,10 @@ Mcu.IP0=FDCAN1 Mcu.IP1=NVIC Mcu.IP2=RCC Mcu.IP3=SYS -Mcu.IP4=TIM3 -Mcu.IPNb=5 +Mcu.IP4=TIM1 +Mcu.IP5=TIM3 +Mcu.IP6=TIM8 +Mcu.IPNb=7 Mcu.Name=STM32G431C(6-8-B)Tx Mcu.Package=LQFP48 Mcu.Pin0=PF0-OSC_IN @@ -38,6 +40,8 @@ Mcu.Pin18=PB5 Mcu.Pin19=VP_SYS_VS_Systick Mcu.Pin2=PA3 Mcu.Pin20=VP_SYS_VS_DBSignals +Mcu.Pin21=VP_TIM1_VS_ClockSourceINT +Mcu.Pin22=VP_TIM8_VS_ClockSourceINT Mcu.Pin3=PA4 Mcu.Pin4=PA5 Mcu.Pin5=PA6 @@ -45,7 +49,7 @@ Mcu.Pin6=PA7 Mcu.Pin7=PB0 Mcu.Pin8=PB1 Mcu.Pin9=PB2 -Mcu.PinsNb=21 +Mcu.PinsNb=23 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32G431CBTx @@ -202,10 +206,20 @@ RCC.VCOInputFreq_Value=16000000 RCC.VCOOutputFreq_Value=128000000 SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4 SH.S_TIM3_CH4.ConfNb=1 +TIM1.IPParameters=Prescaler,PeriodNoDither +TIM1.PeriodNoDither=9999 +TIM1.Prescaler=1599 TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM3.IPParameters=Channel-PWM Generation4 CH4 +TIM8.IPParameters=Prescaler,PeriodNoDither +TIM8.PeriodNoDither=999 +TIM8.Prescaler=1599 VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM1_VS_ClockSourceINT.Mode=Internal +VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT +VP_TIM8_VS_ClockSourceINT.Mode=Internal +VP_TIM8_VS_ClockSourceINT.Signal=TIM8_VS_ClockSourceINT board=custom