257 lines
9.0 KiB
C
257 lines
9.0 KiB
C
|
/******************************************************************************
|
|||
|
* @file bsp_adbms1818.c
|
|||
|
* @brief LT6820-ADBMS1818<EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD>оƬ<EFBFBD>ɼ<EFBFBD>
|
|||
|
* @version V1.0
|
|||
|
* @author Gary 2024-11-13
|
|||
|
* @copyright
|
|||
|
******************************************************************************/
|
|||
|
#include "bsp_adbms1818.h"
|
|||
|
#include "kit_debug.h"
|
|||
|
|
|||
|
#define ENABLED 1
|
|||
|
#define DISABLED 0
|
|||
|
#define DATALOG_ENABLED 1
|
|||
|
#define DATALOG_DISABLED 0
|
|||
|
|
|||
|
/*******************************************************************
|
|||
|
Setup Variables
|
|||
|
The following variables can be modified to configure the software.
|
|||
|
********************************************************************/
|
|||
|
const uint8_t TOTAL_IC = 10; //!< Number of ICs in the daisy chain
|
|||
|
|
|||
|
/********************************************************************
|
|||
|
ADC Command Configurations. See ADBMS181x.h for options
|
|||
|
*********************************************************************/
|
|||
|
const uint8_t ADC_OPT = ADC_OPT_ENABLED; //!< ADC Mode option bit
|
|||
|
const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ; //!< ADC
|
|||
|
|
|||
|
const uint8_t ADC_DCP = DCP_DISABLED; //!< Discharge Permitted
|
|||
|
const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; //!< Channel Selection for ADC conversion
|
|||
|
const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; //!< Channel Selection for ADC conversion
|
|||
|
const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; //!< Channel Selection for ADC conversion
|
|||
|
const uint8_t SEL_ALL_REG = REG_ALL; //!< Register Selection
|
|||
|
const uint8_t SEL_REG_A = REG_1; //!< Register Selection
|
|||
|
const uint8_t SEL_REG_B = REG_2; //!< Register Selection
|
|||
|
|
|||
|
const uint16_t MEASUREMENT_LOOP_TIME = 100; //!< Loop Time in milliseconds(ms)
|
|||
|
|
|||
|
// Under Voltage and Over Voltage Thresholds
|
|||
|
const uint16_t OV_THRESHOLD = 41000; //!< Over voltage threshold ADC Code. LSB = 0.0001 ---(4.1V)
|
|||
|
const uint16_t UV_THRESHOLD = 30000; //!< Under voltage threshold ADC Code. LSB = 0.0001 ---(3V)
|
|||
|
|
|||
|
// Loop Measurement Setup. These Variables are ENABLED or DISABLED. Remember ALL CAPS
|
|||
|
const uint8_t WRITE_CONFIG = ENABLED; //!< This is to ENABLED or DISABLED writing into to configuration registers in a continuous loop
|
|||
|
const uint8_t READ_CONFIG = ENABLED; //!< This is to ENABLED or DISABLED reading the configuration registers in a continuous loop
|
|||
|
const uint8_t MEASURE_CELL = ENABLED; //!< This is to ENABLED or DISABLED measuring the cell voltages in a continuous loop
|
|||
|
const uint8_t MEASURE_AUX = DISABLED; //!< This is to ENABLED or DISABLED reading the auxiliary registers in a continuous loop
|
|||
|
const uint8_t MEASURE_STAT = DISABLED; //!< This is to ENABLED or DISABLED reading the status registers in a continuous loop
|
|||
|
const uint8_t PRINT_PEC = DISABLED; //!< This is to ENABLED or DISABLED printing the PEC Error Count in a continuous loop
|
|||
|
/************************************
|
|||
|
END SETUP
|
|||
|
*************************************/
|
|||
|
|
|||
|
/*******************************************************
|
|||
|
Global Battery Variables received from 181x commands
|
|||
|
These variables store the results from the ADBMS1818
|
|||
|
register reads and the array lengths must be based
|
|||
|
on the number of ICs on the stack
|
|||
|
******************************************************/
|
|||
|
cell_asic BMS_IC[TOTAL_IC]; //!< Global Battery Variable
|
|||
|
|
|||
|
/*************************************************************************
|
|||
|
Set configuration register. Refer to the data sheet
|
|||
|
**************************************************************************/
|
|||
|
bool REFON = false; //!< Reference Powered Up Bit
|
|||
|
bool ADCOPT = false; //!< ADC Mode option bit
|
|||
|
bool GPIOBITS_A[5] = {false, false, true, true, true}; //!< GPIO Pin Control // Gpio 1,2,3,4,5
|
|||
|
bool GPIOBITS_B[4] = {false, false, false, false}; //!< GPIO Pin Control // Gpio 6,7,8,9
|
|||
|
uint16_t UV = UV_THRESHOLD; //!< Under voltage Comparison Voltage
|
|||
|
uint16_t OV = OV_THRESHOLD; //!< Over voltage Comparison Voltage
|
|||
|
bool DCCBITS_A[12] = {false, false, false, false, false, false, false, false, false, false, false, false}; //!< Discharge cell switch //Dcc 1,2,3,4,5,6,7,8,9,10,11,12
|
|||
|
bool DCCBITS_B[7] = {false, false, false, false, false, false, false}; //!< Discharge cell switch //Dcc 0,13,14,15
|
|||
|
bool DCTOBITS[4] = {true, false, true, false}; //!< Discharge time value //Dcto 0,1,2,3 // Programed for 4 min
|
|||
|
/*Ensure that Dcto bits are set according to the required discharge time. Refer to the data sheet */
|
|||
|
bool FDRF = false; //!< Force Digital Redundancy Failure Bit
|
|||
|
bool DTMEN = true; //!< Enable Discharge Timer Monitor
|
|||
|
bool PSBITS[2] = {false, false}; //!< Digital Redundancy Path Selection//ps-0,1
|
|||
|
|
|||
|
|
|||
|
cell_asic* bsp_adbms1818_global(void)
|
|||
|
{
|
|||
|
return (cell_asic*)BMS_IC; //!< Global Battery Variable
|
|||
|
}
|
|||
|
|
|||
|
/* Helper function to initialize CFG variables */
|
|||
|
void ADBMS1818_init_cfg(uint8_t total_ic, // Number of ICs in the system
|
|||
|
cell_asic *ic // A two dimensional array that stores the data
|
|||
|
)
|
|||
|
{
|
|||
|
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
|||
|
{
|
|||
|
for (int j = 0; j < 6; j++)
|
|||
|
{
|
|||
|
ic[current_ic].config.tx_data[j] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ADBMS1818_init_cfgb(uint8_t total_ic, cell_asic *ic)
|
|||
|
{
|
|||
|
for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++)
|
|||
|
{
|
|||
|
for (int j = 0; j < 6; j++)
|
|||
|
{
|
|||
|
ic[current_ic].configb.tx_data[j] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void check_error(int error)
|
|||
|
{
|
|||
|
if (error == -1)
|
|||
|
{
|
|||
|
KIT_DEBUG_PRINTF("A PEC error was detected in the received data");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*!************************************************************
|
|||
|
\brief Prints cell voltage codes to the seeger
|
|||
|
@return void
|
|||
|
*************************************************************/
|
|||
|
void print_cells(uint8_t datalog_en)
|
|||
|
{
|
|||
|
for (int current_ic = 0; current_ic < TOTAL_IC; current_ic++)
|
|||
|
{
|
|||
|
if (datalog_en == 0)
|
|||
|
{
|
|||
|
KIT_DEBUG_PRINTF(" IC ");
|
|||
|
// KIT_DEBUG_PRINTF(current_ic + 1, DEC);
|
|||
|
KIT_DEBUG_PRINTF(", ");
|
|||
|
for (int i = 0; i < BMS_IC[0].ic_reg.cell_channels; i++)
|
|||
|
{
|
|||
|
KIT_DEBUG_PRINTF(" C");
|
|||
|
// KIT_DEBUG_PRINTF(i + 1, DEC);
|
|||
|
// KIT_DEBUG_PRINTF(":");
|
|||
|
// KIT_DEBUG_PRINTF(BMS_IC[current_ic].cells.c_codes[i] * 0.0001, 4);
|
|||
|
KIT_DEBUG_PRINTF(",");
|
|||
|
}
|
|||
|
KIT_DEBUG_PRINTF("\n");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
KIT_DEBUG_PRINTF(" Cells, ");
|
|||
|
for (int i = 0; i < BMS_IC[0].ic_reg.cell_channels; i++)
|
|||
|
{
|
|||
|
// KIT_DEBUG_PRINTF(BMS_IC[current_ic].cells.c_codes[i] * 0.0001, 4);
|
|||
|
KIT_DEBUG_PRINTF(",");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
KIT_DEBUG_PRINTF("\n");
|
|||
|
}
|
|||
|
|
|||
|
void ADBMS1818_reset_crc_count(uint8_t total_ic, cell_asic *ic)
|
|||
|
{
|
|||
|
for (int current_ic = 0; current_ic < total_ic; current_ic++)
|
|||
|
{
|
|||
|
ic[current_ic].crc_count.pec_count = 0;
|
|||
|
ic[current_ic].crc_count.cfgr_pec = 0;
|
|||
|
for (int i = 0; i < 6; i++)
|
|||
|
{
|
|||
|
ic[current_ic].crc_count.cell_pec[i] = 0;
|
|||
|
}
|
|||
|
for (int i = 0; i < 4; i++)
|
|||
|
{
|
|||
|
ic[current_ic].crc_count.aux_pec[i] = 0;
|
|||
|
}
|
|||
|
for (int i = 0; i < 2; i++)
|
|||
|
{
|
|||
|
ic[current_ic].crc_count.stat_pec[i] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ADBMS1818_init_reg_limits(uint8_t total_ic, cell_asic *ic)
|
|||
|
{
|
|||
|
for(uint8_t cic=0; cic<total_ic; cic++)
|
|||
|
{
|
|||
|
ic[cic].ic_reg.cell_channels=18;
|
|||
|
ic[cic].ic_reg.stat_channels=4;
|
|||
|
ic[cic].ic_reg.aux_channels=9;
|
|||
|
ic[cic].ic_reg.num_cv_reg=6;
|
|||
|
ic[cic].ic_reg.num_gpio_reg=4;
|
|||
|
ic[cic].ic_reg.num_stat_reg=2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//init adbms1818
|
|||
|
void ADBMS1818_init(uint8_t total_ic, cell_asic *ic)
|
|||
|
{
|
|||
|
ADBMS1818_init_cfg(total_ic, ic);
|
|||
|
ADBMS1818_init_cfgb(total_ic, ic);
|
|||
|
|
|||
|
ADBMS1818_reset_crc_count(total_ic, ic);
|
|||
|
ADBMS1818_init_reg_limits(total_ic, ic);
|
|||
|
}
|
|||
|
|
|||
|
void run_command(uint32_t cmd,uint16_t total_ic)
|
|||
|
{
|
|||
|
//uint8_t streg = 0;
|
|||
|
int8_t error = 0;
|
|||
|
uint32_t conv_time = 0;
|
|||
|
//int8_t s_pin_read = 0;
|
|||
|
switch (cmd)
|
|||
|
{
|
|||
|
case 1: // Write and read Configuration Register
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
ADBMS1818_wrcfg(total_ic, BMS_IC); // Write into Configuration Register
|
|||
|
ADBMS1818_wrcfgb(total_ic, BMS_IC); // Write into Configuration Register B
|
|||
|
|
|||
|
wakeup_idle(total_ic);
|
|||
|
error = ADBMS1818_rdcfg(total_ic, BMS_IC); // Read Configuration Register
|
|||
|
error = ADBMS1818_rdcfgb(total_ic, BMS_IC); // Read Configuration Register B
|
|||
|
check_error(error);
|
|||
|
break;
|
|||
|
|
|||
|
case 2: // Read Configuration Register
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
error = ADBMS1818_rdcfg(total_ic, BMS_IC);
|
|||
|
check_error(error);
|
|||
|
error = ADBMS1818_rdcfgb(total_ic, BMS_IC);
|
|||
|
check_error(error);
|
|||
|
break;
|
|||
|
|
|||
|
case 3: // Start Cell ADC Measurement
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
ADBMS1818_adcv(ADC_CONVERSION_MODE, ADC_DCP, CELL_CH_TO_CONVERT);
|
|||
|
conv_time = ADBMS1818_pollAdc();
|
|||
|
// print_conv_time(conv_time);
|
|||
|
break;
|
|||
|
|
|||
|
case 4: // Read Cell Voltage Registers
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
error = ADBMS1818_rdcv(SEL_ALL_REG, total_ic, BMS_IC); // Set to read back all cell voltage registers
|
|||
|
check_error(error);
|
|||
|
print_cells(DATALOG_DISABLED);
|
|||
|
break;
|
|||
|
|
|||
|
case 5: // Start GPIO ADC Measurement
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
ADBMS1818_adax(ADC_CONVERSION_MODE, AUX_CH_TO_CONVERT);
|
|||
|
conv_time = ADBMS1818_pollAdc();
|
|||
|
// print_conv_time(conv_time);
|
|||
|
break;
|
|||
|
|
|||
|
case 6: // Read AUX Voltage Registers
|
|||
|
wakeup_sleep(total_ic);
|
|||
|
error = ADBMS1818_rdaux(SEL_ALL_REG, total_ic, BMS_IC); // Set to read back all aux registers
|
|||
|
check_error(error);
|
|||
|
// print_aux(DATALOG_DISABLED);
|
|||
|
break;
|
|||
|
default:
|
|||
|
conv_time = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|