85 #define LTC3300_COMMAND_SIZE sizeof(int8) // 8 bit command
86 #define LTC3300_COMMAND(address, cmd, parity) ((address << 3) + (cmd <<1) + parity)
87 #define LTC3300_ADDRESS 0x15
90 #define LTC3300_COMMAND_BALANCE_WRITE LTC3300_COMMAND(LTC3300_ADDRESS, 0x0 ,1) // Write Balance Command (without Executing)
91 #define LTC3300_COMMAND_BALANCE_READ LTC3300_COMMAND(LTC3300_ADDRESS, 0x1 ,0) // Readback Balance Command
92 #define LTC3300_COMMAND_STATUS_READ LTC3300_COMMAND(LTC3300_ADDRESS, 0x2 ,0) // Read Balance Status
93 #define LTC3300_COMMAND_EXECUTE LTC3300_COMMAND(LTC3300_ADDRESS, 0x3 ,1) // Execute Balance Command
94 #define LTC3300_COMMAND_SUSPEND LTC3300_COMMAND(LTC3300_ADDRESS, 0x3 ,0) // Suspend Balance Command
97 #define LTC3300_REGISTER_SIZE sizeof(int16) // 16 bit balance command and status registers
98 #define LTC3300_CRC_SIZE 4 // 4 bit CRC used for registers
99 #define LTC3300_REGISTER_BITS (LTC3300_REGISTER_SIZE*BITS_PER_BYTE - LTC3300_CRC_SIZE)
102 #define LTC3300_BALANCER_CONTROL_SIZE 2 // 2 bits for DnA and DnB
103 #define LTC3300_BALANCER_CONTROL_MASK ((1 << LTC3300_BALANCER_CONTROL_SIZE) - 1)
106 #define LTC3300_STATUS_GATE_DRIVE_OK_SIZE LTC3300_NUM_CELLS // number of Gate Drive OK status bits
107 #define LTC3300_STATUS_GATE_DRIVE_OK_POSITION 10 // Gate Drive OK bit positions in status register
108 #define LTC3300_STATUS_GATE_DRIVE_OK_MASK MASK(LTC3300_STATUS_GATE_DRIVE_OK_SIZE, LTC3300_STATUS_GATE_DRIVE_OK_POSITION)
109 #define LTC3300_STATUS_CELLS_NOT_OV_SIZE 1 // number of Cells Not OV status bits
110 #define LTC3300_STATUS_CELLS_NOT_OV_POSITION 8 // Cells Not OV bit position in status register
111 #define LTC3300_STATUS_CELLS_NOT_OV_MASK MASK(LTC3300_STATUS_CELLS_NOT_OV_SIZE, LTC3300_STATUS_CELLS_NOT_OV_POSITION)
112 #define LTC3300_STATUS_STACK_NOT_OV_SIZE 2 // number of Stack Not OV status bits
113 #define LTC3300_STATUS_STACK_NOT_OV_POSITION 8 // Stack Not OV bit positions in status register
114 #define LTC3300_STATUS_STACK_NOT_OV_MASK MASK(LTC3300_STATUS_STACK_NOT_OV_SIZE, LTC3300_STATUS_STACK_NOT_OV_POSITION)
115 #define LTC3300_STATUS_TEMP_OK_SIZE 1 // number of Temp OK status bits
116 #define LTC3300_STATUS_TEMP_OK_POSITION 7 // Temp OK bit position in status register
117 #define LTC3300_STATUS_TEMP_OK_MASK MASK(LTC3300_STATUS_TEMP_OK_SIZE, LTC3300_STATUS_TEMP_OK_POSITION)
120 #define LTC3300_BAUD_RATE 1000 // in kHz, Clock Frequency (FCLK in datasheet)
131 const unsigned int8 ltc3300_crc_table[1 << BITS_PER_NIBBLE] = {0x00, 0x13, 0x26, 0x35, 0x4C, 0x5F, 0x6A, 0x79,
132 0x9B, 0x88, 0xBD, 0xAE, 0xD7, 0xC4, 0xF1, 0xE2};
137 unsigned int8 ltc3300_crc_calc(int8* ltc3300_data);
138 BOOLEAN ltc3300_crc_check(int8* ltc3300_data);
155 int16 balancer_command;
157 int8* ltc3300_data_ptr;
161 ltc3300_data_ptr = LAST_BYTE(ltc3300_data) ;
165 balancer_command = 0;
169 balancer_command <<= LTC3300_BALANCER_CONTROL_SIZE;
170 balancer_command |= *balancer_command_ptr++;
174 balancer_command <<= LTC3300_CRC_SIZE;
177 *ltc3300_data_ptr-- = LOWER_BYTE(balancer_command);
178 *ltc3300_data_ptr = UPPER_BYTE(balancer_command);
181 *(ltc3300_data_ptr + 1) |= ltc3300_crc_calc(ltc3300_data_ptr);
185 *ltc3300_data_ptr = LTC3300_COMMAND_BALANCE_WRITE;
196 BOOLEAN success = TRUE;
199 int16 balancer_command;
201 int8* ltc3300_data_ptr;
210 ltc3300_data[0] = LTC3300_COMMAND_BALANCE_READ;
218 ltc3300_data_ptr = ltc3300_data;
223 if(ltc3300_crc_check(ltc3300_data_ptr) == TRUE)
226 balancer_command = (((int16) (*ltc3300_data_ptr)) << 8) + *(ltc3300_data_ptr + 1);
229 balancer_command >>= LTC3300_CRC_SIZE;
234 *(balancer_command_ptr + balancer_num - 1) = (balancer_command & LTC3300_BALANCER_CONTROL_MASK);
235 balancer_command >>= LTC3300_BALANCER_CONTROL_SIZE;
240 LTC3300_CONFIG_ERROR_CRC(board_num, ltc3300_num, LTC3300_COMMAND_BALANCE_READ, ltc3300_data_ptr, LTC3300_REGISTER_SIZE);
246 ltc3300_data_ptr += LTC3300_REGISTER_SIZE;
253 BOOLEAN
LTC3300_Status_Read(int8 board_num, int8* gate_drive_ok, int8* cells_ov_ok, int8* stack_ov_ok, int8* temp_ok)
255 BOOLEAN success = TRUE;
260 int8 gate_drive_ok_mask;
262 int8* ltc3300_data_ptr;
271 ltc3300_data[0] = LTC3300_COMMAND_STATUS_READ;
278 ltc3300_data_ptr = ltc3300_data;
283 if(ltc3300_crc_check(ltc3300_data_ptr) == TRUE)
286 status = (((int16) (*ltc3300_data_ptr)) << 8) + *(ltc3300_data_ptr + 1);
289 status_mask = (1L << (LTC3300_STATUS_GATE_DRIVE_OK_POSITION + LTC3300_STATUS_GATE_DRIVE_OK_SIZE - 1));
290 gate_drive_ok_mask = 1;
294 if((status & status_mask) != 0)
296 *gate_drive_ok |= gate_drive_ok_mask;
298 gate_drive_ok_mask <<= 1;
303 *cells_ov_ok++ = (status & LTC3300_STATUS_CELLS_NOT_OV_MASK) >> LTC3300_STATUS_CELLS_NOT_OV_POSITION;
304 *stack_ov_ok++ = (status & LTC3300_STATUS_STACK_NOT_OV_MASK) >> LTC3300_STATUS_STACK_NOT_OV_POSITION;
305 *temp_ok++ = (status & LTC3300_STATUS_TEMP_OK_MASK) >> LTC3300_STATUS_TEMP_OK_POSITION;
309 LTC3300_CONFIG_ERROR_CRC(board_num, ltc3300_num, LTC3300_COMMAND_STATUS_READ, ltc3300_data_ptr, LTC3300_REGISTER_SIZE);
313 ltc3300_data_ptr += LTC3300_REGISTER_SIZE;
322 int8 ltc3300_data[LTC3300_COMMAND_SIZE];
326 ltc3300_data[0] = LTC3300_COMMAND_EXECUTE;
337 int8 ltc3300_data[LTC3300_COMMAND_SIZE];
341 ltc3300_data[0] = LTC3300_COMMAND_SUSPEND;
352 int8 ltc3300_data[LTC3300_COMMAND_SIZE];
355 ltc3300_data[0] = LTC3300_COMMAND_STATUS_READ;
387 unsigned int8 ltc3300_crc_calc(
int* ltc3300_data
390 unsigned int8 nybble_num;
392 unsigned int8 data[LTC3300_BALANCER_CONTROL_SIZE*
LTC3300_NUM_CELLS/BITS_PER_NIBBLE];
393 unsigned int8 CRC = 0;
395 data[0] = UPPER_NIBBLE(ltc3300_data[0]);
396 data[1] = LOWER_NIBBLE(ltc3300_data[0]);
397 data[2] = UPPER_NIBBLE(ltc3300_data[1]);
399 for (nybble_num = 0; nybble_num < LTC3300_BALANCER_CONTROL_SIZE*
LTC3300_NUM_CELLS/BITS_PER_NIBBLE; nybble_num++)
401 addr = ((CRC >> (LTC3300_CRC_SIZE - BITS_PER_NIBBLE)) ^ data[nybble_num]) & MASK(BITS_PER_NIBBLE, 0);
402 CRC = (CRC << BITS_PER_NIBBLE) ^ ltc3300_crc_table[addr];
405 return (~CRC) & 0x0F;
410 BOOLEAN ltc3300_crc_check(
int* ltc3300_data)
413 if(ltc3300_crc_calc(ltc3300_data) == (ltc3300_data[1] & 0x0F))
void LTC3300_Execute(int8 board_num)
Commands a chain of LTC3300s at a specific logical address to execute their balance commands...
#define LTC3300_NUM_CELLS
Number of cells controlled by one LTC3300.
#define LTC3300_CONFIG_SPI_WRITE(address, data_ptr, num_bytes, baud_khz)
Configures interface through which LTC3300-1 driver module sends SPI bytes to a chain of LTC3300-1 IC...
#define LTC6804_BROADCAST
Code for application code to indicate an LTC6804 command is to be broadcast to all boards...
void LTC3300_Init(void)
Initializes the LTC3300-1 code module.
void LTC3300_Raw_Read(int8 board_num, int8 *ltc3300_data, int8 num_bytes)
Receives a raw string of bytes from a chain of LTC3300s at a specific logical address.
void LTC3300_Command_Write(int8 board_num, int8 *balancer_command_ptr)
Writes the balancer control bits for a number of cells controlled by a chain of LTC3300-1 ICs at a sp...
void LTC3300_Suspend(int8 board_num)
Commands a chain of LTC3300s at a specific logical address to suspend their balance commands...
API Header File for LTC3300-1 High Efficiency Bidirectional Multicell Battery Balancer.
void LTC3300_Watchdog_Kick(void)
Sends a benign command to all chains of LTC3300s at all logical addresses to reset their watchdog tim...
#define LTC3300_CONFIG_SPI_READ(address, data_ptr, num_bytes, baud_khz)
Configures interface through which LTC3300-1 driver module receives SPI bytes from a chain of LTC3300...
BOOLEAN LTC3300_Command_Read(int8 board_num, int8 *balancer_command_ptr)
Reads the balancer control bits for a number of cells controlled by a chain of LTC3300-1 ICs at a spe...
#define LTC3300_CONFIG_NUM_ICS_PER_ADDRESS
Configures the number of LTC3300-1 ICs in a chain at each logical address.
#define LTC3300_CONFIG_ERROR_CRC(address, ic_num, command, data_ptr, num_bytes)
Configures interface through which LTC3300-1 driver module reports its CRC errors.
BOOLEAN LTC3300_Status_Read(int8 board_num, int8 *gate_drive_ok, int8 *cells_ov_ok, int8 *stack_ov_ok, int8 *temp_ok)
Reads the status bits for a chain of LTC3300-1 ICs at a specific logical address. ...
Driver Configuration Header File for LTC3300-1 High Efficiency Bidirectional Multicell Battery Balanc...
void LTC3300_Raw_Write(int8 board_num, int8 *ltc3300_data, int8 num_bytes)
Sends a raw string of bytes to a chain of LTC3300s at a specific logical address. ...