implemented working epsc precharge and current monitoring

This commit is contained in:
2025-03-21 16:37:37 +01:00
parent 26aa408e96
commit 9ca69a2494
114 changed files with 16855 additions and 13200 deletions

View File

@ -8,10 +8,13 @@
#include "can_communication.h"
#include "channel_control.h"
#include "current_monitoring.h"
#include "plausibility_check.h"
rx_status_frame rxstate = {};
volatile uint8_t canmsg_received = 0;
extern enable_gpios update_ports;
extern current_measurements current_measurements_adc_val;
extern uint8_t error_data[16];
extern uint32_t lastheartbeat;
@ -67,7 +70,7 @@ void can_sendloop(){
data[5] = current_measurements_adc_val.ebs3 & 0xFF;
data[6] = current_measurements_adc_val.drs >> 8;
data[7] = current_measurements_adc_val.drs & 0xFF;
ftcan_transmit(CUR_CHANNLES_3_ID, data, 8);
ftcan_transmit(CUR_CHANNELS_3_ID, data, 8);
break;
case 3:
@ -77,17 +80,54 @@ void can_sendloop(){
data[3] = current_measurements_adc_val.lvms_v & 0xFF;
data[4] = current_measurements_adc_val.asms_v >> 8;
data[5] = current_measurements_adc_val.asms_v & 0xFF;
data[6] = 0x01; // not used (transmits 313)
data[7] = 0x39; // not used (transmits 313)
data[6] = current_measurements_adc_val.epsc_precharge >> 8; // not used (transmits 313)
data[7] = current_measurements_adc_val.epsc_precharge & 0xFF; // not used (transmits 313)
ftcan_transmit(CUR_CHANNELS_4_ID, data, 8);
break;
default:
break;
}
additionaltxcounter = (additionaltxcounter + 1) % 4;
}
void can_error_report(){
static int error_loop = 0;
uint8_t data[8];
switch (error_loop){
case 0: // 1 = error 0 = no error
data[0] = error_data[0]; // SDC-Status
data[1] = error_data[1]; // power draw critical (550W)
data[2] = error_data[2]; // power limit (> 600W)
data[3] = error_data[3]; // acc-cooling false OFF
data[4] = error_data[4]; // ts-cooling false OFF
data[5] = error_data[5]; // drs false OFF
data[6] = error_data[6]; // acu false OFF
data[7] = error_data[7]; // epsc false OFF
ftcan_transmit(ERROR_ID, data, 8);
break;
case 1: // 3 = error 2 = no error
data[8] = error_data[8]; // inverter false OFF
data[9] = error_data[9]; // lidar false OFF
data[10] = error_data[10]; // misc false OFF
data[11] = error_data[11]; // always on false OFF
data[12] = error_data[12]; // sdc false OFF
data[13] = error_data[13]; // ebs1 false OFF
data[14] = error_data[14]; // ebs2 false OFF
data[15] = error_data[15]; // ebs3 false OFF
ftcan_transmit(ERROR_ID, data, 8);
break;
default:
break;
}
error_loop = (error_loop + 1) % 2;
}
void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t* data){
canmsg_received = 1;
if((id == RX_STATUS_MSG_ID) && (datalen == 3)){

View File

@ -6,42 +6,51 @@
*/
#include "channel_control.h"
#include "current_monitoring.h"
#include "main.h"
volatile enable_gpios enable;
extern enable_gpios update_ports;
extern current_measurements current_measurements_adc_val;
extern int inhibit_SDC;
extern int prev_epsc_state;
volatile int prev_epsc_state;
void ChannelControl_init(){
enable.porta.porta = 0;
enable.portb.portb = 0;
enable.portb.alwayson = 1;
ChannelControl_UpdateGPIOs(enable);
update_ports.porta.porta = 0;
update_ports.portb.portb = 0;
update_ports.portb.alwayson = 1;
ChannelControl_UpdateGPIOs(update_ports);
prev_epsc_state = 0;
}
void ChannelControl_UpdateGPIOs(enable_gpios UpdatePorts){
UpdatePorts.portb.alwayson = 1;
if (inhibit_SDC == 1){
UpdatePorts.portb.sdc = 0;
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, 1);
}
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, (GPIO_PinState)UpdatePorts.porta.acc_cooling); // Acc-Cooling
HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, (GPIO_PinState)UpdatePorts.porta.acc_cooling); // Acc-Cooling
HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, (GPIO_PinState)UpdatePorts.porta.ts_cooling); // TS-Cooling
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, (GPIO_PinState)UpdatePorts.porta.drs); // DRS
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, (GPIO_PinState)UpdatePorts.porta.acu); // ACU
if (prev_epsc_state == 0 && ((UpdatePorts.porta.porta >> 4) & 1) == 1){ // will be replaced by precharge
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 1); // precharge activate
HAL_Delay(2000); // contiuosly read precharge voltage
HAL_GPIO_WritePin(IN5_GPIO_Port, IN5_Pin, (GPIO_PinState)UpdatePorts.porta.epsc); // if precharge voltage > 95% 24V enable PROFET
HAL_Delay(100); // after few ms disengage precharge
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 0);
prev_epsc_state = UpdatePorts.porta.epsc;
HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, (GPIO_PinState)UpdatePorts.porta.drs); // DRS
HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, (GPIO_PinState)UpdatePorts.porta.acu); // ACU
if (prev_epsc_state == 0 && UpdatePorts.porta.epsc == 1){
HAL_GPIO_WritePin(PC_EN_GPIO_Port, PC_EN_Pin, 1); // enable precharge
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 1);
if (current_measurements_adc_val.epsc_precharge >= (0.95f * current_measurements_adc_val.asms_v)) { // precharge complete
HAL_GPIO_WritePin(IN5_GPIO_Port, IN5_Pin, (GPIO_PinState)UpdatePorts.porta.epsc); // switch PROFET
HAL_GPIO_WritePin(PC_EN_GPIO_Port, PC_EN_Pin, 0); // disengage precharge
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, 0);
prev_epsc_state = UpdatePorts.porta.epsc;
}
}
else {
if ((prev_epsc_state == 1 && UpdatePorts.porta.epsc == 0) || (prev_epsc_state == UpdatePorts.porta.epsc)){
HAL_GPIO_WritePin(PC_EN_GPIO_Port, PC_EN_Pin, 0); // ensure precharge is disabled, when not needed or stopped
HAL_GPIO_WritePin(IN5_GPIO_Port, IN5_Pin, (GPIO_PinState)UpdatePorts.porta.epsc);
prev_epsc_state = UpdatePorts.porta.epsc;
}
HAL_GPIO_WritePin(IN6_GPIO_Port, IN6_Pin, (GPIO_PinState)UpdatePorts.porta.inverter); // inverter
HAL_GPIO_WritePin(IN7_GPIO_Port, IN7_Pin, (GPIO_PinState)UpdatePorts.porta.lidar); // lidar
HAL_GPIO_WritePin(IN8_GPIO_Port, IN8_Pin, (GPIO_PinState)UpdatePorts.porta.misc); // MISC

View File

@ -7,14 +7,15 @@
#include "current_monitoring.h"
#include "main.h"
#include "plausibility_check.h"
volatile union adc1_channels {
struct {
uint16_t isense11; // ebs1, ebs2, ebs3 (DSEL0, DSEL1)
uint16_t lvms_vsense; // LVMS-Vsense
uint16_t isense1; // acc-cooling
uint16_t isense2; // ts-cooling
uint16_t isense9; // always on
uint16_t isense11; // ebs1, ebs2, ebs3 (DSEL0, DSEL1)
uint16_t asms_vsense; // ASMS-Vsense
uint16_t isense10; // sdc
uint16_t isense6; // inverter
@ -48,8 +49,8 @@ void current_monitor_init(ADC_HandleTypeDef* hadc1, ADC_HandleTypeDef* hadc2, TI
adc1 = hadc1;
adc2 = hadc2;
HAL_TIM_Base_Start(trigtim);
HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_channels1.adcbuffer, 6);
HAL_ADC_Start_DMA(hadc2, (uint32_t*)adc_channels2.adcbuffer, 5);
HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_channels1.adcbuffer, 8);
HAL_ADC_Start_DMA(hadc2, (uint32_t*)adc_channels2.adcbuffer, 6);
}
uint8_t current_monitor_checklimits() {return 0;} // TODO: implement properly
@ -57,38 +58,40 @@ uint8_t current_monitor_checklimits() {return 0;} // TODO: implement properly
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
if (hadc == adc1){
if (valve2 == GPIO_PIN_RESET && valve3 == GPIO_PIN_RESET){
current_measurement_adc_val.ebs1 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
current_measurements_adc_val.ebs1 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
valve2 = GPIO_PIN_SET;
}
if (valve2 == GPIO_PIN_SET && valve3 == GPIO_PIN_RESET){
current_measurement_adc_val.ebs2 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
current_measurements_adc_val.ebs2 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
valve2 = GPIO_PIN_RESET;
valve3 = GPIO_PIN_SET;
}
if (valve2 == GPIO_PIN_RESET && valve3 == GPIO_PIN_SET){
current_measurement_adc_val.ebs3 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
current_measurements_adc_val.ebs3 = adc_channels1.adcbank1.isense11 * CURR_SENSE_FACTOR_1A;
valve3 = GPIO_PIN_RESET;
}
}
else {
current_measurement_adc_val.lvms_v = adc_channels1.adcbank1.lvms_vsense * LV_SENSE_FACTOR;
current_measurement_adc_val.acc_cooling = adc_channels1.adcbank1.isense1 * CURR_SENSE_FACTOR_9A;
current_measurement_adc_val.ts_cooling = adc_channels1.adcbank1.isense2 * CURR_SENSE_FACTOR_9A;
current_measurement_adc_val.alwayson = adc_channels1.adcbank1.isense9 * CURR_SENSE_FACTOR_9A;
current_measurement_adc_val.asms_v = adc_channels1.adcbank1.asms_vsense * LV_SENSE_FACTOR;
current_measurement_adc_val.sdc = adc_channels1.adcbank1.isense10 * CURR_SENSE_FACTOR_4_5A;
current_measurement_adc_val.inverter = adc_channels1.adcbank1.isense6 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.lvms_v = adc_channels1.adcbank1.lvms_vsense * LV_SENSE_FACTOR;
current_measurements_adc_val.acc_cooling = adc_channels1.adcbank1.isense1 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.ts_cooling = adc_channels1.adcbank1.isense2 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.alwayson = adc_channels1.adcbank1.isense9 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.asms_v = adc_channels1.adcbank1.asms_vsense * LV_SENSE_FACTOR;
current_measurements_adc_val.sdc = adc_channels1.adcbank1.isense10 * CURR_SENSE_FACTOR_4_5A;
current_measurements_adc_val.inverter = adc_channels1.adcbank1.isense6 * CURR_SENSE_FACTOR_9A;
HAL_GPIO_WritePin(DSEL0_GPIO_Port, DSEL0_Pin, valve3);
HAL_GPIO_WritePin(DSEL1_GPIO_Port, DSEL1_Pin, valve2);
}
if (hadc == adc2){
current_measurement_adc_val.drs = adc_channels2.adcbank2.isense3 * CURR_SENSE_FACTOR_4_5A;
current_measurement_adc_val.misc = adc_channels2.adcbank2.isense8 * CURR_SENSE_FACTOR_4_5A;
current_measurement_adc_val.acu = adc_channels2.adcbank2.isense4 * CURR_SENSE_FACTOR_9A;
current_measurement_adc_val.epsc = adc_channels2.adcbank2.isense5 * CURR_SENSE_FACTOR_9A;
current_measurement_adc_val.epsc_precharge = adc_channels2.adcbank2.pc_read * PC_VSENSE_FACTOR;
current_measurement_adc_val.lidar = adc_channels2.adcbank2.isense7 * CURR_SENSE_FACTOR_4_5A;
current_measurements_adc_val.drs = adc_channels2.adcbank2.isense3 * CURR_SENSE_FACTOR_4_5A;
current_measurements_adc_val.misc = adc_channels2.adcbank2.isense8 * CURR_SENSE_FACTOR_4_5A;
current_measurements_adc_val.acu = adc_channels2.adcbank2.isense4 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.epsc = adc_channels2.adcbank2.isense5 * CURR_SENSE_FACTOR_9A;
current_measurements_adc_val.epsc_precharge = adc_channels2.adcbank2.pc_read * LV_SENSE_FACTOR;
current_measurements_adc_val.lidar = adc_channels2.adcbank2.isense7 * CURR_SENSE_FACTOR_4_5A;
}
check_plausibility();
}

View File

@ -23,6 +23,7 @@
/* USER CODE BEGIN Includes */
#include "can_communication.h"
#include "channel_control.h"
//#include "plausibility_check.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -80,7 +81,6 @@ extern volatile uint8_t canmsg_received;
volatile enable_gpios update_ports;
uint32_t lastheartbeat;
int inhibit_SDC; // wenn =1 ist es unmoeglich den SDC zu schliessen
volatile int prev_epsc_state; // used for precharge
/* USER CODE END 0 */
/**
@ -168,16 +168,20 @@ int main(void)
if ((HAL_GetTick() - lasttick) > 100u){
lasttick = HAL_GetTick();
can_sendloop();
//can_error_report();
}
if (((HAL_GetTick() - lastheartbeat) > 125U) && (HAL_GetTick() > 1000U)) {
if (((HAL_GetTick() - lastheartbeat) > 200U) && (HAL_GetTick() > 1000U)) {
inhibit_SDC = 1;
}
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, (GPIO_PinState)!update_ports.portb.sdc); // indicates open SDC
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, (GPIO_PinState)inhibit_SDC); // indicates watchdog-status
// overcurrent check (wenn funktioniert, LED schalten)
ChannelControl_UpdateGPIOs(update_ports);
current_monitor_checklimits(); // currently not implemented
//check_plausibility();
}
/* USER CODE END 3 */
}
@ -279,10 +283,10 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
@ -292,7 +296,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -301,6 +305,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -309,6 +314,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -317,6 +323,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -325,6 +332,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -333,6 +341,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_7;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -341,6 +350,7 @@ static void MX_ADC1_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_8;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
@ -396,7 +406,7 @@ static void MX_ADC2_Init(void)
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
@ -406,6 +416,7 @@ static void MX_ADC2_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
@ -414,6 +425,7 @@ static void MX_ADC2_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
@ -422,6 +434,7 @@ static void MX_ADC2_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
@ -430,6 +443,7 @@ static void MX_ADC2_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
@ -438,6 +452,7 @@ static void MX_ADC2_Init(void)
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{

View File

@ -0,0 +1,113 @@
/*
* plausibility_check.c
*
* Created on: Mar 18, 2025
* Author: janek
*/
#include "plausibility_check.h"
extern enable_gpios update_ports;
extern current_measurements current_measurements_adc_val;
volatile uint8_t error_data[16];
void check_plausibility() {
if (!update_ports.portb.sdc) {error_data[0] = 1;}
else {error_data[0] = 0;}
if (update_ports.porta.acc_cooling == 1 && current_measurements_adc_val.acc_cooling == 0) {
error_data[3] = 1;
}
else {
error_data[3] = 0;
}
if (update_ports.porta.ts_cooling == 1 && current_measurements_adc_val.ts_cooling == 0) {
error_data[4] = 1;
}
else {
error_data[4] = 0;
}
if (update_ports.porta.drs == 1 && current_measurements_adc_val.drs == 0) {
error_data[5] = 1;
}
else {
error_data[5] = 0;
}
if (update_ports.porta.acu == 1 && current_measurements_adc_val.acu == 0) {
error_data[6] = 1;
}
else {
error_data[6] = 0;
}
if (update_ports.porta.epsc == 1 && current_measurements_adc_val.epsc == 0) {
error_data[7] = 1;
}
else {
error_data[7] = 0;
}
if (update_ports.porta.inverter == 1 && current_measurements_adc_val.inverter == 0) {
error_data[8] = 3;
}
else {
error_data[8] = 2;
}
if (update_ports.porta.lidar == 1 && current_measurements_adc_val.lidar == 0) {
error_data[9] = 3;
}
else {
error_data[9] = 2;
}
if (update_ports.porta.misc == 1 && current_measurements_adc_val.misc == 0) {
error_data[10] = 3;
}
else {
error_data[10] = 2;
}
if (update_ports.portb.alwayson == 1 && current_measurements_adc_val.alwayson == 0) {
error_data[11] = 3;
}
else {
error_data[11] = 2;
}
if (update_ports.portb.sdc == 1 && current_measurements_adc_val.sdc == 0) {
error_data[12] = 3;
}
else {
error_data[12] = 2;
}
if (update_ports.portb.ebs1 == 1 && current_measurements_adc_val.ebs1 == 0) {
error_data[13] = 3;
}
else {
error_data[13] = 2;
}
if (update_ports.portb.ebs2 == 1 && current_measurements_adc_val.ebs2 == 0) {
error_data[14] = 3;
}
else {
error_data[14] = 2;
}
if (update_ports.portb.ebs3 == 1 && current_measurements_adc_val.ebs3 == 0) {
error_data[15] = 3;
}
else {
error_data[15] = 2;
}
}

View File

@ -342,6 +342,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
/* USER CODE BEGIN CAN_MspInit 1 */
/* USER CODE END CAN_MspInit 1 */
}
}
@ -399,6 +400,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
/* USER CODE BEGIN TIM6_MspInit 1 */
/* USER CODE END TIM6_MspInit 1 */
}
}
@ -460,6 +462,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE BEGIN UART4_MspInit 1 */
/* USER CODE END UART4_MspInit 1 */
}
}