Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/tms-common/library.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "tms-common",
"version": "0.1.0",
"description": "Platform-independent TMS logic: temperature sensing, BMS broadcast packing, and fan control.",
"dependencies": {
"Embedded Template Library": "^20",
"atomic_buffer": "*",
"can": "*",
"lookup_table": "*",
"moving_average": "*",
"periph": "*"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ void FanController::Update(float temperature, float update_period_ms) {
pwm_roc_ * elapsed_sec);

pwm_.SetDutyCycle(current_pwm + pwm_step);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ class FanController {

/// @brief Maximum PWM rate of change in %/second.
const float pwm_roc_ = 20.0f;
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ float TempSensor::Read() {
macfe::LookupTable::Evaluate(volt_ts_to_degC, volt_at_stm);

return temperature;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ class TempSensor {
{2.44f, -40.0f},
// clang-format on
});
};
};
88 changes: 88 additions & 0 deletions lib/tms-common/tms-common/tms-common.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "tms-common.hpp"

#include "generated/can/veh_messages.hpp"

namespace macfe::tms {

using namespace ::generated::can;

TxTMSValues TMSBroadcast(const std::array<float, kSensorCount>& temperatures) {
return TxTMSValues{
.val1 = static_cast<uint8_t>(temperatures[0] * 50.0f),
.val2 = static_cast<uint8_t>(temperatures[1] * 50.0f),
.val3 = static_cast<uint8_t>(temperatures[2] * 50.0f),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the 50.0 factor here?

It should be a named constant

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This factor was already implemented prior. Additionally, the logic before made no sense. Take a look:

TxTMSValues TMSBroadcast(const std::array<float, kSensorCount>& temperatures) { return TxTMSValues{ .val1 = static_cast<uint8_t>(bindings::temp_sensor_adc_1.ReadVoltage() * 50.0f), .val2 = static_cast<uint8_t>(bindings::temp_sensor_adc_2.ReadVoltage() * 50.0f), .val3 = static_cast<uint8_t>(bindings::temp_sensor_adc_3.ReadVoltage() * 50.0f), .val4 = static_cast<uint8_t>(bindings::temp_sensor_adc_4.ReadVoltage() * 50.0f), .val5 = static_cast<uint8_t>(bindings::temp_sensor_adc_5.ReadVoltage() * 50.0f), .val6 = static_cast<uint8_t>(bindings::temp_sensor_adc_6.ReadVoltage() * 50.0f), }; }

We pass in temperatures but read from bindings, which doesnt make sense. This version actually uses the passed in param

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that is pretty bad. Global variables are not good

Glad to have it fixed.

You should open a github issue "figure out what this TMS constant is"

.val4 = static_cast<uint8_t>(temperatures[3] * 50.0f),
.val5 = static_cast<uint8_t>(temperatures[4] * 50.0f),
.val6 = static_cast<uint8_t>(temperatures[5] * 50.0f),
};
}

TxBmsBroadcast PackBmsBroadcast(
const std::array<float, kSensorCount>& temperatures) {
// Compute the min, max, and avg temperatures
uint8_t low_index = 0;
uint8_t high_index = 0;
int8_t low_temp = temperatures[0];
int8_t high_temp = temperatures[0];

float temperature_sum = temperatures[0];
for (uint8_t i = 1; i < temperatures.size(); i++) {
temperature_sum += temperatures[i];

auto t = static_cast<int8_t>(temperatures[i]);
if (t < low_temp) {
low_temp = t;
low_index = i;
}
if (t > high_temp) {
high_temp = t;
high_index = i;
}
}
int8_t avg_temp = static_cast<int8_t>(temperature_sum / kSensorCount);

// This is a constant defined by Orion. It was discovered by
// decoding the CAN traffic coming from the Orion Thermal Expansion Pack.
const uint8_t kBmsChecksumConstant = 0x41;
const uint8_t kThermistorModuleNumber = 0;
uint8_t checksum = kThermistorModuleNumber + low_temp + high_temp +
avg_temp + kSensorCount + high_index + low_index +
kBmsChecksumConstant;

return TxBmsBroadcast{
.therm_module_num = kThermistorModuleNumber,
.low_therm_value = low_temp,
.high_therm_value = high_temp,
.avg_therm_value = avg_temp,
.num_therm_en = kSensorCount,
.high_therm_id = high_index,
.low_therm_id = low_index,
.checksum = checksum,
};
}

/***************************************************************
Program Logic
***************************************************************/
void ReadAndSendTemperatures(
float update_period_ms, VehBus& veh_can_bus, FanController& fan_controller,
etl::array<TempSensor, kSensorCount>& temp_sensors) {
// Read the temperature sensors
std::array<float, kSensorCount> temperatures;
float avg_temp = 0;
for (size_t i = 0; i < kSensorCount; i++) {
temperatures[i] = temp_sensors[i].Update();
avg_temp += temperatures[i] / kSensorCount;
}

// Send the temperatures to the BMS
TxBmsBroadcast bms_broadcast = PackBmsBroadcast(temperatures);
TxTMSValues tms = TMSBroadcast(temperatures);

veh_can_bus.Send(bms_broadcast);
veh_can_bus.Send(tms);

// Adjust the fan speed based on the average temperature
fan_controller.Update(avg_temp, update_period_ms);
}
} // namespace macfe::tms
29 changes: 29 additions & 0 deletions lib/tms-common/tms-common/tms-common.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <array>
#include <cstdint>
#include <span>

#include "etl/array.h"
#include "fan_controller.hpp"
#include "generated/can/veh_bus.hpp"
#include "periph/analog_input.hpp"
#include "temp_sensor.hpp"

namespace macfe::tms {

using ::generated::can::TxBmsBroadcast;
using ::generated::can::TxTMSValues;
using ::generated::can::VehBus;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use using in a header file. It pollutes the namespace. Write out the full path

It's ok to use in in the cc file


inline constexpr size_t kSensorCount = 6;

TxTMSValues TMSBroadcast(const std::array<float, kSensorCount>& temperatures);

TxBmsBroadcast PackBmsBroadcast(
const std::array<float, kSensorCount>& temperatures);

void ReadAndSendTemperatures(
float update_period_ms, VehBus& veh_can_bus, FanController& fan_controller,
etl::array<TempSensor, kSensorCount>& temp_sensors);
} // namespace macfe::tms
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.h
* @brief This file contains all the function prototypes for

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regenerate the code from cubemx and run post_cubemx.sh. These files shouldn't have a git diff. They should've just been renamed

* the adc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ADC_H__
#define __ADC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_ADC1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __ADC_H__ */
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file adc.h
* @brief This file contains all the function prototypes for
* the adc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ADC_H__
#define __ADC_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern ADC_HandleTypeDef hadc1;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_ADC1_Init(void);

/* USER CODE BEGIN Prototypes */

/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __ADC_H__ */
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.h
* @brief This file contains all the function prototypes for
* the can.c file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern CAN_HandleTypeDef hcan2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_CAN2_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __CAN_H__ */
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.h
* @brief This file contains all the function prototypes for
* the can.c file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

extern CAN_HandleTypeDef hcan2;

/* USER CODE BEGIN Private defines */

/* USER CODE END Private defines */

void MX_CAN2_Init(void);

/* USER CODE BEGIN Prototypes */

/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __CAN_H__ */
Loading
Loading