DC2100A  1.2.0
Bi-Directional Cell Balancer Using the LTC3300-1 and the LTC6804-2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
LTC3300-1.c
Go to the documentation of this file.
1 /*
2  Linear Technology DC2100A Demonstration Board.
3  Driver File for LTC3300-1 High Efficiency Bidirectional Multicell Battery Balancer.
4  All datasheet references in this file refer to Linear Technology Corp. document 33001fa.pdf.
5 
6  @verbatim
7  The LTC3300-1 is a fault-protected controller IC for
8  transformer-based bidirectional active balancing of multicell
9  battery stacks. All associated gate drive circuitry,
10  precision current sensing, fault detection circuitry and a
11  robust serial interface with built-in watchdog timer are
12  integrated.
13  Each LTC3300-1 can balance up to 6 series-connected battery
14  cells with an input common mode voltage up to 36V.
15  Charge from any selected cell can be transferred at high
16  efficiency to or from 12 or more adjacent cells. A unique
17  level-shifting SPI-compatible serial interface enables
18  multiple LTC3300-1 devices to be connected in series,
19  without opto-couplers or isolators, allowing for balancing
20  of every cell in a long string of series-connected batteries.
21  When multiple LTC3300-1 devices are connected in series
22  they can operate simultaneously, permitting all cells in
23  the stack to be balanced concurrently and independently.
24  Fault protection features include readback capability, cyclic
25  redundancy check (CRC) error detection, maximum
26  on-time volt-second clamps, and overvoltage shutoffs.
27  @endverbatim
28 
29  http://www.linear.com/product/LTC3300
30 
31  http://www.linear.com/product/LTC3300#demoboards
32 
33  REVISION HISTORY
34  $Revision: 692 $
35  $Date: 2014-09-08 11:51:35 -0400 (Mon, 08 Sep 2014) $
36 
37  Copyright (c) 2013, Linear Technology Corp.(LTC)
38  All rights reserved.
39 
40  Redistribution and use in source and binary forms, with or without
41  modification, are permitted provided that the following conditions are met:
42 
43  1. Redistributions of source code must retain the above copyright notice, this
44  list of conditions and the following disclaimer.
45  2. Redistributions in binary form must reproduce the above copyright notice,
46  this list of conditions and the following disclaimer in the documentation
47  and/or other materials provided with the distribution.
48 
49  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
50  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
53  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
55  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
56  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 
60  The views and conclusions contained in the software and documentation are those
61  of the authors and should not be interpreted as representing official policies,
62  either expressed or implied, of Linear Technology Corp.
63 
64  */
65 
66 //! @defgroup LTC3300-1 LTC3300-1 High Efficiency Bidirectional Multicell Battery Balancer
67 /*! @file
68  @ingroup LTC3300-1
69  Driver File for LTC3300-1 High Efficiency Bidirectional Multicell Battery Balancer
70  */
71 
72 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
73 // Includes
74 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
75 #include "Typedefs.h"
76 #include "LTC3300-1.h"
77 #include "LTC3300-1_Config.h"
78 #include <string.h>
79 
80 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
81 // Definitions
82 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
83 
84 // Command Byte format and address specified in datasheet Table 2
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
88 
89 // Command Bit codes specified in datasheet Table 3
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
95 // Balance Command Register specified in datasheet Table 4
96 // Read Status Register specified in datasheet Table 6
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)
100 
101 // Cell Balancer Control Bits specified in datasheet Table 5
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)
104 
105 // Status Bits specified in datasheet Table 6
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)
118 
119 // Baud Rate from datasheet page 5
120 #define LTC3300_BAUD_RATE 1000 // in kHz, Clock Frequency (FCLK in datasheet)
121 
122 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
123 // Global Data
124 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
125 
126 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
127 // Local Data
128 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
129 
130 // Table implements Telecommunication Union CRC-4 polynomial from datasheet figure 16
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};
133 
134 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
135 // Local Prototypes
136 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
137 unsigned int8 ltc3300_crc_calc(int8* ltc3300_data);
138 BOOLEAN ltc3300_crc_check(int8* ltc3300_data);
139 
140 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
141 // Global Functions
142 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
143 
144 // Initializes the LTC3300-1 code module.
145 void LTC3300_Init(void)
146 {
147  // No local data needs to be initialized by this code module.
148 }
149 
150 // Writes the balancer control bits for a number of cells controlled by a chain of LTC3300-1 ICs at a specific logical address.
151 void LTC3300_Command_Write(int8 board_num, int8* balancer_command_ptr)
152 {
153  int8 ltc3300_num;
154  int8 balancer_num;
155  int16 balancer_command;
156  int8 ltc3300_data[LTC3300_COMMAND_SIZE+ LTC3300_CONFIG_NUM_ICS_PER_ADDRESS * LTC3300_REGISTER_SIZE];
157  int8* ltc3300_data_ptr;
158 
159  // Build Command as specified in datasheet Table 4. Note that last LTC3300 in chain gets the command bytes sent first,
160  // since bytes are passed serially and the highest potential cells must be connected to the last LTC3300 in the series
161  ltc3300_data_ptr = LAST_BYTE(ltc3300_data) ;
162  for (ltc3300_num = 0; ltc3300_num < LTC3300_CONFIG_NUM_ICS_PER_ADDRESS; ltc3300_num++)
163  {
164  // Start with command byte cleared.
165  balancer_command = 0;
166 
167  for (balancer_num = 0; balancer_num < LTC3300_NUM_CELLS; balancer_num++)
168  {
169  balancer_command <<= LTC3300_BALANCER_CONTROL_SIZE;
170  balancer_command |= *balancer_command_ptr++;
171  }
172 
173  // Adjust for CRC position
174  balancer_command <<= LTC3300_CRC_SIZE;
175 
176  // Ensure endianess is correct for the LTC3300.
177  *ltc3300_data_ptr-- = LOWER_BYTE(balancer_command);
178  *ltc3300_data_ptr = UPPER_BYTE(balancer_command);
179 
180  // Add CRC to command byte
181  *(ltc3300_data_ptr + 1) |= ltc3300_crc_calc(ltc3300_data_ptr);
182  ltc3300_data_ptr--;
183  }
184 
185  *ltc3300_data_ptr = LTC3300_COMMAND_BALANCE_WRITE;
186 
187  // Send the command to the LTC3300s
188  LTC3300_CONFIG_SPI_WRITE(board_num, ltc3300_data, sizeof(ltc3300_data), LTC3300_BAUD_RATE);
189 
190  return;
191 }
192 
193 // Reads the balancer control bits for a number of cells controlled by a chain of LTC3300-1 ICs at a specific logical address.
194 BOOLEAN LTC3300_Command_Read(int8 board_num, int8* balancer_command_ptr)
195 {
196  BOOLEAN success = TRUE;
197  int8 ltc3300_num;
198  int8 balancer_num;
199  int16 balancer_command;
200  int8 ltc3300_data[LTC3300_CONFIG_NUM_ICS_PER_ADDRESS * LTC3300_REGISTER_SIZE];
201  int8* ltc3300_data_ptr;
202 
203  // Broadcast reads are not possible through the 6804
204  if(board_num == LTC6804_BROADCAST)
205  {
206  return FALSE;
207  }
208 
209  // Build Command.
210  ltc3300_data[0] = LTC3300_COMMAND_BALANCE_READ;
211 
212  // Send the command to the LTC3300s
213  LTC3300_CONFIG_SPI_READ(board_num, ltc3300_data, sizeof(ltc3300_data) + 1, LTC3300_BAUD_RATE);
214 
215  // Read Balance Command uses the Write Balance Command specified in datasheet Table 4
216  // Note that last LTC3300 in chain sends its command bytes last, since bytes are
217  // passed serially and the highest potential cells must be connected to the last LTC3300 in the series
218  ltc3300_data_ptr = ltc3300_data;
219 
220  for (ltc3300_num = 0; ltc3300_num < LTC3300_CONFIG_NUM_ICS_PER_ADDRESS; ltc3300_num++)
221  {
222  // Verify data, and extract it if valid.
223  if(ltc3300_crc_check(ltc3300_data_ptr) == TRUE)
224  {
225  // Extract balancer command in an endianess independent way.
226  balancer_command = (((int16) (*ltc3300_data_ptr)) << 8) + *(ltc3300_data_ptr + 1);
227 
228  // Adjust for CRC position
229  balancer_command >>= LTC3300_CRC_SIZE;
230 
231  // Read out balancer command information, with highest cell first
232  for (balancer_num = LTC3300_NUM_CELLS; balancer_num > 0; balancer_num--)
233  {
234  *(balancer_command_ptr + balancer_num - 1) = (balancer_command & LTC3300_BALANCER_CONTROL_MASK);
235  balancer_command >>= LTC3300_BALANCER_CONTROL_SIZE;
236  }
237  }
238  else
239  {
240  LTC3300_CONFIG_ERROR_CRC(board_num, ltc3300_num, LTC3300_COMMAND_BALANCE_READ, ltc3300_data_ptr, LTC3300_REGISTER_SIZE);
241  success = FALSE;
242  }
243 
244  // point to data locations for balancer commands from next ltc3300.
245  balancer_command_ptr += LTC3300_NUM_CELLS;
246  ltc3300_data_ptr += LTC3300_REGISTER_SIZE;
247  }
248 
249  return success;
250 }
251 
252 // Reads the status bits for a chain of LTC3300-1 ICs at a specific logical address.
253 BOOLEAN LTC3300_Status_Read(int8 board_num, int8* gate_drive_ok, int8* cells_ov_ok, int8* stack_ov_ok, int8* temp_ok)
254 {
255  BOOLEAN success = TRUE;
256  int8 ltc3300_num;
257  int8 cell_num;
258  int16 status;
259  int16 status_mask;
260  int8 gate_drive_ok_mask;
261  int8 ltc3300_data[LTC3300_CONFIG_NUM_ICS_PER_ADDRESS * LTC3300_REGISTER_SIZE];
262  int8* ltc3300_data_ptr;
263 
264  // Broadcast reads are not possible through the 6804
265  if(board_num == LTC6804_BROADCAST)
266  {
267  return FALSE;
268  }
269 
270  // Build Command.
271  ltc3300_data[0] = LTC3300_COMMAND_STATUS_READ;
272 
273  // Send the command to the LTC3300s
274  LTC3300_CONFIG_SPI_READ(board_num, ltc3300_data, sizeof(ltc3300_data) + 1, LTC3300_BAUD_RATE);
275 
276  // Note that last LTC3300 in chain sends its command bytes last, since bytes are
277  // passed serially and the highest potential cells must be connected to the last LTC3300 in the series
278  ltc3300_data_ptr = ltc3300_data;
279 
280  for (ltc3300_num = 0; ltc3300_num < LTC3300_CONFIG_NUM_ICS_PER_ADDRESS; ltc3300_num++)
281  {
282  // Verify data, and extract it if valid.
283  if(ltc3300_crc_check(ltc3300_data_ptr) == TRUE)
284  {
285  // Extract balancer command in an endianess independent way.
286  status = (((int16) (*ltc3300_data_ptr)) << 8) + *(ltc3300_data_ptr + 1);
287 
288  // return gate_drive_ok bits ordered such that cell 1 is in bit position 0
289  status_mask = (1L << (LTC3300_STATUS_GATE_DRIVE_OK_POSITION + LTC3300_STATUS_GATE_DRIVE_OK_SIZE - 1));
290  gate_drive_ok_mask = 1;
291  *gate_drive_ok = 0;
292  for (cell_num = 0; cell_num < LTC3300_NUM_CELLS; cell_num++)
293  {
294  if((status & status_mask) != 0)
295  {
296  *gate_drive_ok |= gate_drive_ok_mask;
297  }
298  gate_drive_ok_mask <<= 1;
299  status_mask >>= 1;
300  }
301  gate_drive_ok++;
302 
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;
306  }
307  else
308  {
309  LTC3300_CONFIG_ERROR_CRC(board_num, ltc3300_num, LTC3300_COMMAND_STATUS_READ, ltc3300_data_ptr, LTC3300_REGISTER_SIZE);
310  success = FALSE;
311  }
312 
313  ltc3300_data_ptr += LTC3300_REGISTER_SIZE;
314  }
315 
316  return success;
317 }
318 
319 // Commands a chain of LTC3300s at a specific logical address to execute their balance commands.
320 void LTC3300_Execute(int8 board_num)
321 {
322  int8 ltc3300_data[LTC3300_COMMAND_SIZE];
323 
324  // Build Command. Note that last LTC3300 in chain gets the command bytes sent first, since bytes are
325  // passed serially and the highest potential cells must be connected to the last LTC3300 in the series
326  ltc3300_data[0] = LTC3300_COMMAND_EXECUTE;
327 
328  // Send the command to the LTC3300s
329  LTC3300_CONFIG_SPI_WRITE(board_num, ltc3300_data, sizeof(ltc3300_data), LTC3300_BAUD_RATE);
330 
331  return;
332 }
333 
334 // Commands a chain of LTC3300s at a specific logical address to suspend their balance commands.
335 void LTC3300_Suspend(int8 board_num)
336 {
337  int8 ltc3300_data[LTC3300_COMMAND_SIZE];
338 
339  // Build Command. Note that last LTC3300 in chain gets the command bytes sent first, since bytes are
340  // passed serially and the highest potential cells must be connected to the last LTC3300 in the series
341  ltc3300_data[0] = LTC3300_COMMAND_SUSPEND;
342 
343  // Send the command to the LTC3300s
344  LTC3300_CONFIG_SPI_WRITE(board_num, ltc3300_data, sizeof(ltc3300_data), LTC3300_BAUD_RATE);
345 
346  return;
347 }
348 
349 // Sends a benign command to all chains of LTC3300s at all logical addresses to reset their watchdog timers.
351 {
352  int8 ltc3300_data[LTC3300_COMMAND_SIZE];
353 
354  // Build Command.
355  ltc3300_data[0] = LTC3300_COMMAND_STATUS_READ;
356 
357  // Send the command to the LTC3300s. Do not bother reading back the registers, as it will just be using time.
358  LTC3300_CONFIG_SPI_WRITE(LTC6804_BROADCAST, ltc3300_data, LTC3300_COMMAND_SIZE, LTC3300_BAUD_RATE);
359 
360  return;
361 }
362 
363 // Sends a raw string of bytes to a chain of LTC3300s at a specific logical address.
364 void LTC3300_Raw_Write(int8 board_num, int8* ltc3300_data, int8 num_bytes)
365 {
366  // Send the command to the LTC3300s
367  LTC3300_CONFIG_SPI_WRITE(board_num, ltc3300_data, num_bytes, LTC3300_BAUD_RATE);
368 
369  return;
370 }
371 
372 // Receives a raw string of bytes from a chain of LTC3300s at a specific logical address.
373 void LTC3300_Raw_Read(int8 board_num, int8* ltc3300_data, int8 num_bytes)
374 {
375  // Send the command to the LTC3300s and read the results
376  LTC3300_CONFIG_SPI_READ(board_num, ltc3300_data, num_bytes + 1, LTC3300_BAUD_RATE);
377 
378  return;
379 }
380 
381 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
382 // Local Functions
383 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
384 
385 // Calculates the CRC for an LTC3300-1 Register
386 // return the LTC3300-1 CRC calculated for these bytes.
387 unsigned int8 ltc3300_crc_calc(int* ltc3300_data // The bytes to be written to an LTC3300-1 Register
388  )
389 {
390  unsigned int8 nybble_num;
391  unsigned int8 addr;
392  unsigned int8 data[LTC3300_BALANCER_CONTROL_SIZE*LTC3300_NUM_CELLS/BITS_PER_NIBBLE];
393  unsigned int8 CRC = 0;
394 
395  data[0] = UPPER_NIBBLE(ltc3300_data[0]);
396  data[1] = LOWER_NIBBLE(ltc3300_data[0]);
397  data[2] = UPPER_NIBBLE(ltc3300_data[1]);
398 
399  for (nybble_num = 0; nybble_num < LTC3300_BALANCER_CONTROL_SIZE*LTC3300_NUM_CELLS/BITS_PER_NIBBLE; nybble_num++)
400  {
401  addr = ((CRC >> (LTC3300_CRC_SIZE - BITS_PER_NIBBLE)) ^ data[nybble_num]) & MASK(BITS_PER_NIBBLE, 0); // calculate table address
402  CRC = (CRC << BITS_PER_NIBBLE) ^ ltc3300_crc_table[addr]; // get value from table
403  }
404 
405  return (~CRC) & 0x0F;
406 }
407 
408 // Calculates the CRC for an LTC3300-1 register and compares it to the CRC recieved with the register.
409 // return True is the CRC matches, False if the CRC does not match.
410 BOOLEAN ltc3300_crc_check(int* ltc3300_data)
411 {
412  // Calc and check CRC
413  if(ltc3300_crc_calc(ltc3300_data) == (ltc3300_data[1] & 0x0F))
414  {
415  return TRUE;
416  }
417  else
418  {
419  return FALSE;
420  }
421 }
422 
void LTC3300_Execute(int8 board_num)
Commands a chain of LTC3300s at a specific logical address to execute their balance commands...
Definition: LTC3300-1.c:320
#define LTC3300_NUM_CELLS
Number of cells controlled by one LTC3300.
Definition: LTC3300-1.h:85
#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...
Definition: LTC6804-2.h:89
void LTC3300_Init(void)
Initializes the LTC3300-1 code module.
Definition: LTC3300-1.c:145
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.
Definition: LTC3300-1.c:373
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...
Definition: LTC3300-1.c:151
void LTC3300_Suspend(int8 board_num)
Commands a chain of LTC3300s at a specific logical address to suspend their balance commands...
Definition: LTC3300-1.c:335
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...
Definition: LTC3300-1.c:350
#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...
Definition: LTC3300-1.c:194
#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. ...
Definition: LTC3300-1.c:253
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. ...
Definition: LTC3300-1.c:364