Compare commits

...

7 Commits

Author SHA1 Message Date
jazzpi ec1383960b Use new AMS CAN interface 2022-06-23 14:55:10 +02:00
jazzpi 2acde9d565 Save all measured temperatures 2022-06-23 14:24:08 +02:00
jazzpi e58b9ffae0 Move main UART RX callback to main.c 2022-06-23 13:05:39 +02:00
jazzpi 839a9a930a Continue balancing on fault 2022-06-23 12:48:06 +02:00
jazzpi 8f0e661e18 Fix BQ initialization 2022-06-23 12:41:46 +02:00
jazzpi 9f69121203 Change AMS CAN to 500kbaud 2022-06-23 12:08:22 +02:00
jazzpi d54635c17e Transmit BQ CRC big-endian 2022-06-23 12:07:18 +02:00
13 changed files with 169 additions and 103 deletions

View File

@ -71,7 +71,7 @@ IncludeCategories:
- Regex: '^[<"]stm'
Priority: 2
SortPriority: 0
- Regex: "^<std"
- Regex: "^<(std|string)"
Priority: 4
SortPriority: 0
- Regex: ".*"

View File

@ -8,9 +8,15 @@
#ifndef INC_AMS_CAN_H_
#define INC_AMS_CAN_H_
#include "stm32f4xx_hal.h"
#include "main.h"
#define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x100
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_can.h"
#include "stm32f4xx_hal_def.h"
#define CAN_ID_SLAVE_ERROR 0x001
#define CAN_ID_AMS_SLAVE_HEARTBEAT_BASE 0x600
#define CAN_HEARTBEAT_TX_TIMEOUT 5 /* ms */
void ams_can_init(CAN_HandleTypeDef* ams, CAN_HandleTypeDef* car);
@ -18,5 +24,9 @@ void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data);
void ams_can_handle_car_msg(CAN_RxHeaderTypeDef* header, uint8_t* data);
void ams_can_send_heartbeat();
void ams_can_send_error(AMS_ErrorCode error_code);
HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle,
uint32_t timeout);
#endif /* INC_AMS_CAN_H_ */

View File

@ -61,6 +61,7 @@ void afe_update_Checksum();
void afe_config_measurement_channels();
void afe_config_communication();
void afe_config_power();
void afe_config_balancing();
void afe_balance_channels(uint16_t channelstobalance);

View File

@ -199,4 +199,18 @@
#define OV_FAULT_SUM (1 << 14)
#define UV_FAULT_SUM (1 << 15)
#define CBCONFIG_BAL_TIME_FOREVER (0 << 4)
#define CBCONFIG_BAL_TIME_1SEC (1 << 4)
#define CBCONFIG_BAL_TIME_1MIN (2 << 4)
#define CBCONFIG_BAL_TIME_2MIN (3 << 4)
#define CBCONFIG_BAL_TIME_5MIN (4 << 4)
#define CBCONFIG_BAL_TIME_10MIN (5 << 4)
#define CBCONFIG_BAL_TIME_15MIN (6 << 4)
#define CBCONFIG_BAL_TIME_20MIN (7 << 4)
#define CBCONFIG_BAL_TIME_30MIN (8 << 4)
#define CBCONFIG_BAL_TIME_60MIN (9 << 4)
#define CBCONFIG_BAL_CONTINUE (1 << 3)
#define DEVCONFIG_REG_DISABLE (1 << 5)
#endif /* INC_BQ_REGISTER_DEFINITIONS_H_ */

View File

@ -11,8 +11,12 @@
#include "common_defs.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_uart.h"
extern volatile uint16_t temperatures[N_CELLS];
#define N_SENSORS 32
extern volatile uint16_t temperatures[N_SENSORS];
extern volatile uint16_t max_temp;
typedef enum {
TMP144_IDLE,
@ -28,7 +32,6 @@ typedef struct {
uint8_t rxbuf[34];
size_t n_sensors;
uint8_t sensor_mappings[16];
} TMP144Bus;
HAL_StatusTypeDef tmp144_init(UART_HandleTypeDef* busbar_side,
@ -42,4 +45,6 @@ HAL_StatusTypeDef tmp144_read_temps();
HAL_StatusTypeDef tmp144_send_read_temps(TMP144Bus* bus);
HAL_StatusTypeDef tmp144_recv_temps(TMP144Bus* bus);
void tmp144_handle_rx_cplt(UART_HandleTypeDef* handle);
#endif /* INC_TMP144_H_ */

View File

@ -36,11 +36,17 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
typedef enum {
AMS_ERROR_UV,
AMS_ERROR_OV,
AMS_ERROR_UT,
AMS_ERROR_OT
} AMS_ErrorCode;
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern uint8_t slave_id;
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/

View File

@ -9,6 +9,12 @@
#include "BQ_Abstraction_Layer.h"
#include "TMP144.h"
#include "common_defs.h"
#include "main.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_can.h"
static CAN_HandleTypeDef* handle_ams;
static CAN_HandleTypeDef* handle_car;
@ -81,34 +87,71 @@ void ams_can_handle_car_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {}
void ams_can_send_heartbeat() {
static CAN_TxHeaderTypeDef header;
static uint8_t data[8];
static uint8_t SLAVE_ID = 0;
header.IDE = CAN_ID_STD;
header.DLC = 8;
header.RTR = CAN_RTR_DATA;
header.TransmitGlobalTime = DISABLE;
for (int i = 0; i < N_CELLS / 2; i++) {
header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (SLAVE_ID) << 4 | i;
uint16_t v1 = cell_voltages[i * 2];
uint16_t v2 = cell_voltages[i * 2 + 1];
data[0] = v1 >> 8;
data[1] = v1 & 0xFF;
data[2] = v2 >> 8;
data[3] = v2 & 0xFF;
uint16_t t1 = temperatures[i * 2];
uint16_t t2 = temperatures[i * 2 + 1];
data[4] = t1 >> 8;
data[5] = t1 & 0xFF;
data[6] = t2 >> 8;
data[7] = t2 & 0xFF;
uint32_t mailbox;
HAL_StatusTypeDef status;
if ((status = HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox)) !=
// Send voltages
for (int msg_id = 0; msg_id < 3; msg_id++) {
header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (slave_id << 4) | msg_id;
for (int i = 0; i < 4; i++) {
int cell = msg_id * 4 + i;
uint16_t v = (cell < N_CELLS) ? cell_voltages[cell] : 0;
data[2 * i + 0] = v & 0xFF;
data[2 * i + 1] = v >> 8;
}
if (ams_can_wait_for_free_mailbox(handle_ams, CAN_HEARTBEAT_TX_TIMEOUT) ==
HAL_OK) {
Error_Handler();
} else {
HAL_Delay(100);
uint32_t mailbox;
HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox);
}
}
// Send temperatures
for (int temp_msg_id = 0; temp_msg_id < 8; temp_msg_id++) {
int msg_id = temp_msg_id + 3;
header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (slave_id << 4) | msg_id;
for (int i = 0; i < 4; i++) {
int sensor = temp_msg_id * 4 + i;
uint16_t temp = temperatures[sensor];
data[2 * i + 0] = temp & 0xFF;
data[2 * i + 1] = temp >> 8;
}
if (ams_can_wait_for_free_mailbox(handle_ams, CAN_HEARTBEAT_TX_TIMEOUT) ==
HAL_OK) {
uint32_t mailbox;
HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox);
}
}
}
void ams_can_send_error(AMS_ErrorCode error_code) {
static CAN_TxHeaderTypeDef header;
header.IDE = CAN_ID_STD;
header.DLC = 8;
header.RTR = CAN_RTR_DATA;
header.TransmitGlobalTime = DISABLE;
header.StdId = CAN_ID_SLAVE_ERROR;
static uint8_t data[8];
data[0] = slave_id;
data[1] = error_code;
HAL_CAN_AbortTxRequest(handle_ams,
CAN_TX_MAILBOX0 | CAN_TX_MAILBOX1 | CAN_TX_MAILBOX2);
uint32_t mailbox;
HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox);
}
HAL_StatusTypeDef ams_can_wait_for_free_mailbox(CAN_HandleTypeDef* handle,
uint32_t timeout) {
uint32_t end = HAL_GetTick() + timeout;
while (HAL_GetTick() < end) {
if (HAL_CAN_GetTxMailboxesFreeLevel(handle) > 0) {
return HAL_OK;
}
}
return HAL_TIMEOUT;
}

View File

@ -12,6 +12,9 @@
#include "stm32f4xx_hal.h"
#include <stdint.h>
#include <string.h>
uint16_t cell_voltages[N_CELLS];
BQ_Status bq_status;
@ -36,11 +39,7 @@ void afe_init(UART_HandleTypeDef* uarthandle) {
// Initialise underlying BQ Communication Functions
init_BQCom(uarthandle);
// Turn the AFE on off on to cycle a full reset
afe_wakeup();
HAL_Delay(10);
afe_shutdown();
HAL_Delay(100);
// *Don't* power cycle the AFE to comply with 9.1.2
afe_wakeup();
HAL_Delay(10);
@ -51,6 +50,9 @@ void afe_init(UART_HandleTypeDef* uarthandle) {
afe_config_gpios();
afe_activate_LED();
// Clear FAULT_SYS[SYS_RESET] before writing REG_DISABLE
afe_clear_all_faults();
afe_config_power();
afe_init_fault_thresholds();
@ -60,7 +62,7 @@ void afe_init(UART_HandleTypeDef* uarthandle) {
afe_clear_all_faults();
HAL_Delay(10);
HAL_Delay(100);
afe_check_faults();
}
@ -147,6 +149,7 @@ void afe_check_faults() {
}
void afe_clear_all_faults() {
memset(&bq_error, 0, sizeof(bq_error));
BQ_Write_Register(FAULT_SUM, FAULT_SUM_SIZE, 0xFFC0); // Clear all Faults
bq_status = BQ_STDBY;
HAL_Delay(1);
@ -191,10 +194,18 @@ void afe_config_communication() {
void afe_config_gpios() { BQ_Write_Register(GPIO_DIR, GPIO_DIR_SIZE, 0x01); }
void afe_config_power() {
uint32_t devconfig;
BQ_Read_Register(DEVCONFIG, DEVCONFIG_SIZE, &devconfig);
devconfig |= DEVCONFIG_REG_DISABLE;
BQ_Write_Register(DEVCONFIG, DEVCONFIG_SIZE, devconfig);
}
void afe_activate_LED() { BQ_Write_Register(GPIO_OUT, GPIO_OUT_SIZE, 0x01); }
void afe_config_balancing() {
BQ_Write_Register(CBCONFIG, CBCONFIG_SIZE, 0x10);
BQ_Write_Register(CBCONFIG, CBCONFIG_SIZE,
CBCONFIG_BAL_TIME_1SEC | CBCONFIG_BAL_CONTINUE);
}
void afe_balance_channels(uint16_t channelstobalance) {

View File

@ -53,10 +53,9 @@ uint16_t Calculate_CRC(uint8_t* message_buffer, uint16_t bufferlength) {
wCRC = crc16_table[wCRC & 0x00FF] ^ (wCRC >> 8);
}
message_buffer[bufferlength - 1] =
(wCRC >> 8) & 0xFF; // Upper CRC Byte is LSB of CRC
message_buffer[bufferlength - 2] = (wCRC)&0xFF; // Lower CRC Byte is MSB of
// CRC
// CRC is transmitted big-endian in the last two bytes of the message
message_buffer[bufferlength - 2] = wCRC & 0xFF;
message_buffer[bufferlength - 1] = (wCRC >> 8) & 0xFF;
return 1;
}

View File

@ -7,13 +7,15 @@
#include "TMP144.h"
#include <stdint.h>
#include <string.h>
static const uint8_t TMP144_SEQ_RESET[] = {0x55, 0xB4};
static const uint8_t TMP144_SEQ_ADDR[] = {0x55, 0x8C, 0x90};
static const uint8_t TMP144_SEQ_READ_TEMPS[] = {0x55, 0xF1};
volatile uint16_t temperatures[N_CELLS];
volatile uint16_t temperatures[N_SENSORS];
volatile uint16_t max_temp;
static volatile TMP144Bus bus_busbar;
static volatile TMP144Bus bus_other;
@ -34,32 +36,8 @@ HAL_StatusTypeDef tmp144_init(UART_HandleTypeDef* busbar_side,
bus_other.state = TMP144_IDLE;
// TODO: Configure this in EEPROM
bus_busbar.n_sensors = 11;
bus_busbar.sensor_mappings[0] = 8;
bus_busbar.sensor_mappings[1] = 8;
bus_busbar.sensor_mappings[2] = 8;
bus_busbar.sensor_mappings[3] = 6;
bus_busbar.sensor_mappings[4] = 6;
bus_busbar.sensor_mappings[5] = 4;
bus_busbar.sensor_mappings[6] = 4;
bus_busbar.sensor_mappings[7] = 4;
bus_busbar.sensor_mappings[8] = 2;
bus_busbar.sensor_mappings[9] = 2;
bus_busbar.sensor_mappings[10] = 2;
bus_other.n_sensors = 13;
bus_other.sensor_mappings[0] = 1;
bus_other.sensor_mappings[1] = 1;
bus_other.sensor_mappings[2] = 1;
bus_other.sensor_mappings[3] = 3;
bus_other.sensor_mappings[4] = 3;
bus_other.sensor_mappings[5] = 5;
bus_other.sensor_mappings[6] = 5;
bus_other.sensor_mappings[7] = 5;
bus_other.sensor_mappings[8] = 5;
bus_other.sensor_mappings[9] = 7;
bus_other.sensor_mappings[10] = 7;
bus_other.sensor_mappings[11] = 9;
bus_other.sensor_mappings[12] = 9;
bus_busbar.n_sensors = 16;
bus_other.n_sensors = 16;
CHECK_STATUS(tmp144_init_reset(&bus_busbar));
CHECK_STATUS(tmp144_init_reset(&bus_other));
@ -156,30 +134,26 @@ HAL_StatusTypeDef tmp144_recv_temps(TMP144Bus* bus) {
return HAL_ERROR;
}
// Find max temperature for each cell
uint8_t current_cell = bus->sensor_mappings[0];
uint16_t max_temp = 0;
size_t temperatures_offset = (bus == &bus_busbar) ? 0 : N_SENSORS / 2;
for (size_t i = 0; i < bus->n_sensors; i++) {
uint8_t cell = bus->sensor_mappings[i];
if (cell != current_cell) {
temperatures[current_cell] = max_temp;
current_cell = cell;
max_temp = 0;
}
size_t buf_offset = headerlen + 2 * i;
uint16_t temp =
(bus->rxbuf[buf_offset] >> 4) | (bus->rxbuf[buf_offset + 1] << 4);
if (temp > max_temp) {
max_temp = temp;
temperatures[temperatures_offset + i] = temp;
}
uint16_t max = temperatures[0];
for (size_t i = 1; i < N_SENSORS; i++) {
if (temperatures[i] > max) {
max = temperatures[i];
}
}
temperatures[current_cell] = max_temp;
max_temp = max;
return HAL_OK;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* handle) {
void tmp144_handle_rx_cplt(UART_HandleTypeDef* handle) {
TMP144Bus* bus;
if (handle == bus_busbar.handle) {
bus = &bus_busbar;

View File

@ -24,10 +24,12 @@
#include "BQ_Abstraction_Layer.h"
#include "EEPROM.h"
#include "FanControl.h"
#include "TMP144.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_tim.h"
#include "stm32f4xx_hal_uart.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@ -58,7 +60,7 @@ UART_HandleTypeDef huart3;
UART_HandleTypeDef huart6;
/* USER CODE BEGIN PV */
uint8_t slave_id;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@ -147,10 +149,7 @@ int main(void) {
HAL_Delay(100);
afe_init(&huart2);
eeprom_init(&hi2c1);
uint8_t id;
if (eeprom_read_random(EEPROM_ADDR_SLAVE_ID, &id) == HAL_OK) {
HAL_GPIO_WritePin(STAT_LED4_GPIO_Port, STAT_LED4_Pin, GPIO_PIN_SET);
}
eeprom_read_random(EEPROM_ADDR_SLAVE_ID, &slave_id);
fan_ctrl_init(&htim3, TIM_CHANNEL_4);
/* USER CODE END 2 */
@ -221,15 +220,15 @@ static void MX_CAN1_Init(void) {
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;
hcan1.Init.Prescaler = 2;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_6TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK) {
@ -255,10 +254,10 @@ static void MX_CAN2_Init(void) {
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 5;
hcan2.Init.Prescaler = 2;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_6TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
@ -514,7 +513,11 @@ static void MX_GPIO_Init(void) {
}
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* handle) {
if (handle == &huart1 || handle == &huart3) {
tmp144_handle_rx_cplt(handle);
}
}
/* USER CODE END 4 */
/**

View File

@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Mon Jun 13 23:59:18 CEST 2022]
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Thu Jun 23 11:54:27 CEST 2022]
##########################################################################################################################
# ------------------------------------------------

View File

@ -1,19 +1,19 @@
#MicroXplorer Configuration settings - do not modify
CAN1.BS1=CAN_BS1_6TQ
CAN1.BS1=CAN_BS1_13TQ
CAN1.BS2=CAN_BS2_2TQ
CAN1.CalculateBaudRate=355555
CAN1.CalculateTimeBit=2812
CAN1.CalculateTimeQuantum=312.5
CAN1.CalculateBaudRate=500000
CAN1.CalculateTimeBit=2000
CAN1.CalculateTimeQuantum=125.0
CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,NART,BS1,BS2,Prescaler
CAN1.NART=ENABLE
CAN1.Prescaler=5
CAN2.BS1=CAN_BS1_6TQ
CAN1.NART=DISABLE
CAN1.Prescaler=2
CAN2.BS1=CAN_BS1_13TQ
CAN2.BS2=CAN_BS2_2TQ
CAN2.CalculateBaudRate=355555
CAN2.CalculateTimeBit=2812
CAN2.CalculateTimeQuantum=312.5
CAN2.CalculateBaudRate=500000
CAN2.CalculateTimeBit=2000
CAN2.CalculateTimeQuantum=125.0
CAN2.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,Prescaler,BS1,BS2
CAN2.Prescaler=5
CAN2.Prescaler=2
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
@ -183,7 +183,7 @@ ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_CAN1_Init-CAN1-false-HAL-true,4-MX_CAN2_Init-CAN2-false-HAL-true,5-MX_I2C1_Init-I2C1-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_USART2_UART_Init-USART2-false-HAL-true,8-MX_USART3_UART_Init-USART3-false-HAL-true,9-MX_USART6_UART_Init-USART6-false-HAL-true
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_CAN1_Init-CAN1-false-HAL-true,4-MX_CAN2_Init-CAN2-false-HAL-true,5-MX_I2C1_Init-I2C1-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_USART2_UART_Init-USART2-false-HAL-true,8-MX_USART3_UART_Init-USART3-false-HAL-true,9-MX_USART6_UART_Init-USART6-false-HAL-true,10-MX_TIM3_Init-TIM3-false-HAL-true
RCC.CortexFreq_Value=16000000
RCC.DFSDMFreq_Value=16000000
RCC.FamilyName=M