Import Master_Control code

This commit is contained in:
jazzpi 2022-08-08 11:06:17 +02:00
parent 1618f7d6b0
commit c64d25d42c
18 changed files with 1253 additions and 177 deletions

View File

@ -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;

View File

@ -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_ */

18
Core/Inc/AMS_Errorcodes.h Normal file
View File

@ -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_ */

View File

@ -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_ */

34
Core/Inc/Clock_Sync.h Normal file
View File

@ -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_

30
Core/Inc/Error_Check.h Normal file
View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 -----------------------------------------------------------*/

View File

@ -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;
}
}

View File

@ -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 <stdint.h>
#include <string.h>
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;
}
}

35
Core/Src/Clock_Sync.c Normal file
View File

@ -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);
}
}

13
Core/Src/Error_Check.c Normal file
View File

@ -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;
}

104
Core/Src/Slave_Monitoring.c Normal file
View File

@ -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 <string.h>
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;
}

View File

@ -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 */
/**

View File

@ -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

View File

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [3.17.1] date: [Mon Aug 08 02:48:24 CEST 2022]
# File automatically-generated by tool: [projectgenerator] version: [3.17.1] date: [Mon Aug 08 11:01:56 CEST 2022]
##########################################################################################################################
# ------------------------------------------------

View File

@ -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 \

View File

@ -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