1 | /***********************************************//**
|
2 | \brief Reads and parses the LTC6804 cell voltage registers.
|
3 |
|
4 | The function is used to read the cell codes of the LTC6804.
|
5 | This function will send the requested read commands parse the data_spi
|
6 | and store the cell voltages in cell_codes variable.
|
7 |
|
8 | @param[in] uint8_t reg; This controls which cell voltage register is read back.
|
9 |
|
10 | 0: Read back all Cell registers
|
11 |
|
12 | 1: Read back cell group A
|
13 |
|
14 | 2: Read back cell group B
|
15 |
|
16 | 3: Read back cell group C
|
17 |
|
18 | 4: Read back cell group D
|
19 |
|
20 | @param[in] uint8_t total_ic; This is the number of ICs in the daisy chain(-1 only)
|
21 |
|
22 | @param[out] uint16_t cell_codes[]; An array of the parsed cell codes from lowest to highest. The cell codes will
|
23 | be stored in the cell_codes[] array in the following format:
|
24 | | cell_codes[0][0]| cell_codes[0][1] | cell_codes[0][2]| ..... | cell_codes[0][11]| cell_codes[1][0] | cell_codes[1][1]| ..... |
|
25 | |------------------|------------------|------------------|--------------|-------------------|-------------------|-----------------|----------|
|
26 | |IC1 Cell 1 |IC1 Cell 2 |IC1 Cell 3 | ..... | IC1 Cell 12 |IC2 Cell 1 |IC2 Cell 2 | ..... |
|
27 |
|
28 | @return int8_t, PEC Status.
|
29 |
|
30 | 0: No PEC error detected
|
31 |
|
32 | -1: PEC error detected, retry read
|
33 |
|
34 |
|
35 | *************************************************/
|
36 | uint8_t LTC6804_rdcv(uint8_t reg, // Controls which cell voltage register is read back.
|
37 | uint8_t total_ic, // the number of ICs in the system
|
38 | uint16_t cell_codes[][12] // Array of the parsed cell codes
|
39 | )
|
40 | {
|
41 |
|
42 |
|
43 | const uint8_t NUM_RX_BYT = 8;
|
44 | const uint8_t BYT_IN_REG = 6;
|
45 | const uint8_t CELL_IN_REG = 3;
|
46 |
|
47 | uint8_t *cell_data_spi;
|
48 | uint16_t pec_error = 0;
|
49 | uint16_t parsed_cell;
|
50 | uint16_t received_pec;
|
51 | uint16_t data_spi_pec, data_spi_pec_h;
|
52 | uint8_t data_spi_counter=0; //data_spi counter
|
53 | uint8_t cell_reg;
|
54 | uint8_t current_ic;
|
55 | uint8_t current_cell;
|
56 |
|
57 | cell_data_spi = (uint8_t *) malloc((NUM_RX_BYT*total_ic)*sizeof(uint8_t));
|
58 | //The pec_error variable is simply set negative if any PEC errors
|
59 | Lcd_Out(2,1, "rdcv_readcellvlt");
|
60 |
|
61 | //1.a
|
62 | if (reg == 0)
|
63 | {
|
64 | //a.i
|
65 | for(cell_reg = 1; cell_reg<5; cell_reg++) //executes once for each of the LTC6804 cell voltage registers
|
66 | {
|
67 | data_spi_counter = 0;
|
68 | LTC6804_rdcv_reg(cell_reg, total_ic,cell_data_spi ); //Reads a single Cell voltage register
|
69 |
|
70 | for (current_ic = 0 ; current_ic < total_ic; current_ic++) // executes for every LTC6804 in the daisy chain
|
71 | { // current_ic is used as the IC counter
|
72 |
|
73 | //a.ii
|
74 | for(current_cell = 0; current_cell<CELL_IN_REG; current_cell++) // This loop parses the read back data_spi into cell voltages, it
|
75 | { // loops once for each of the 3 cell voltage codes in the register
|
76 |
|
77 | parsed_cell = cell_data_spi[data_spi_counter] + (cell_data_spi[data_spi_counter + 1] << 8);//Each cell code is received as two bytes and is combined to
|
78 | // create the parsed cell voltage code
|
79 |
|
80 | cell_codes[current_ic][current_cell + ((cell_reg - 1) * CELL_IN_REG)] = parsed_cell;
|
81 | data_spi_counter = data_spi_counter + 2; //Because cell voltage codes are two bytes the data_spi counter
|
82 | //must increment by two for each parsed cell code
|
83 | }
|
84 | //a.iii
|
85 | received_pec = (cell_data_spi[data_spi_counter] << 8) + cell_data_spi[data_spi_counter+1]; //The received PEC for the current_ic is transmitted as the 7th and 8th //after the 6 cell voltage data_spi bytes
|
86 | data_spi_pec = pec15_calc(BYT_IN_REG, &cell_data_spi[current_ic * NUM_RX_BYT]);
|
87 | data_spi_pec_h = pec15_calc_h(BYT_IN_REG, &cell_data_spi[current_ic * NUM_RX_BYT]);
|
88 |
|
89 | sprintf(lcd_line1, "PECvgl=%x, %x", received_pec, data_spi_pec_h); //The pec_error variable is simply set negative if any PEC errors
|
90 | Lcd_Out(1,1, lcd_line1);
|
91 | Delay_ms(3000);
|
92 | if(received_pec != data_spi_pec_h)
|
93 | {
|
94 | pec_error = -1;
|
95 | //The pec_error variable is simply set negative if any PEC errors
|
96 | Lcd_Cmd(_LCD_CLEAR); // Clear display
|
97 | Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
|
98 | Delay_ms(1000);
|
99 | sprintf(lcd_line1, "PEC_ERR = %d", pec_error); //The pec_error variable is simply set negative if any PEC errors
|
100 | Lcd_Out(1,1, lcd_line1); //are detected in the serial data_spi
|
101 | }
|
102 | data_spi_counter=data_spi_counter+2; //Because the transmitted PEC code is 2 bytes long the data_spi_counter
|
103 | //must be incremented by 2 bytes to point to the next ICs cell voltage data_spi
|
104 | }
|
105 | }
|
106 | }
|
107 | //1.b
|
108 | else
|
109 | {
|
110 | //b.i
|
111 | //....
|
112 | }
|
113 |
|
114 | //2
|
115 | FreeMem(cell_data_spi, sizeof(cell_data_spi));
|
116 | return(pec_error);
|
117 | }
|
118 | /*
|
119 | LTC6804_rdcv Sequence
|
120 |
|
121 | 1. Switch Statement:
|
122 | a. Reg = 0
|
123 | i. Read cell voltage registers A-D for every IC in the daisy chain
|
124 | ii. Parse raw cell voltage data_spi in cell_codes array
|
125 | iii. Check the PEC of the data_spi read back vs the calculated PEC for each read register command
|
126 | b. Reg != 0
|
127 | i.Read single cell voltage register for all ICs in daisy chain
|
128 | ii. Parse raw cell voltage data_spi in cell_codes array
|
129 | iii. Check the PEC of the data_spi read back vs the calculated PEC for each read register command
|
130 | 2. Return pec_error flag
|
131 | */
|