req
Dependents: BMS_BMUCore_Max_DummyData BMS_BMUCore_Max
Fork of LTC6804 by
SPI_Parser.cpp@6:47ffbe9ee110, 2017-08-19 (annotated)
- Committer:
- DasSidG
- Date:
- Sat Aug 19 20:45:03 2017 +0000
- Revision:
- 6:47ffbe9ee110
- Parent:
- 5:324a19dcfdec
- Child:
- 9:1c94bbb97eaa
Fixed annoying PEC ERROR message formatting; now properly formatted (and hidden behind an if (DEBUG));
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DasSidG | 5:324a19dcfdec | 1 | #include "SPI_Parser.h" |
DasSidG | 5:324a19dcfdec | 2 | |
DasSidG | 5:324a19dcfdec | 3 | //Define SPI and I2C I/O pins |
DasSidG | 5:324a19dcfdec | 4 | SPI spi(p5, p6, p7); // mosi, miso, sclk |
DasSidG | 5:324a19dcfdec | 5 | DigitalOut chipSelect(p8); |
DasSidG | 5:324a19dcfdec | 6 | |
DasSidG | 5:324a19dcfdec | 7 | uint8_t ADCV[2]; |
DasSidG | 5:324a19dcfdec | 8 | uint8_t ADAX[2]; |
DasSidG | 5:324a19dcfdec | 9 | |
DasSidG | 5:324a19dcfdec | 10 | //I2C i2c(p9, p10); This line gives conflicting definition errors |
DasSidG | 5:324a19dcfdec | 11 | |
DasSidG | 5:324a19dcfdec | 12 | |
DasSidG | 5:324a19dcfdec | 13 | void wake_LTC6804() |
DasSidG | 5:324a19dcfdec | 14 | { |
DasSidG | 5:324a19dcfdec | 15 | spi.format(8,3);//All data transfer on LTC6804 occur in byte groups. LTC6820 set up such that POL=1 and PHA=3, this corresponds to mode 3 in mbed library. spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 16 | spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 17 | chipSelect=0; |
DasSidG | 5:324a19dcfdec | 18 | wait_us(70); |
DasSidG | 5:324a19dcfdec | 19 | spi.write(0x00); //Ensures isoSPI is in ready mode |
DasSidG | 5:324a19dcfdec | 20 | wait_us(30); |
DasSidG | 5:324a19dcfdec | 21 | chipSelect=1; |
DasSidG | 5:324a19dcfdec | 22 | } |
DasSidG | 5:324a19dcfdec | 23 | |
DasSidG | 5:324a19dcfdec | 24 | void wake_SPI() |
DasSidG | 5:324a19dcfdec | 25 | { |
DasSidG | 5:324a19dcfdec | 26 | chipSelect=0; |
DasSidG | 5:324a19dcfdec | 27 | wait(0.000025); |
DasSidG | 5:324a19dcfdec | 28 | chipSelect=1; |
DasSidG | 5:324a19dcfdec | 29 | } |
DasSidG | 5:324a19dcfdec | 30 | |
DasSidG | 5:324a19dcfdec | 31 | void LTC6804_init(uint8_t mode, uint8_t balancingEn, uint8_t cellCh, uint8_t gpioCh) |
DasSidG | 5:324a19dcfdec | 32 | { |
DasSidG | 5:324a19dcfdec | 33 | uint8_t bitSetter; |
DasSidG | 5:324a19dcfdec | 34 | |
DasSidG | 5:324a19dcfdec | 35 | bitSetter = (mode & 0x02) >> 1; |
DasSidG | 5:324a19dcfdec | 36 | ADCV[0] = bitSetter + 0x02; |
DasSidG | 5:324a19dcfdec | 37 | bitSetter = (mode & 0x01) << 7; |
DasSidG | 5:324a19dcfdec | 38 | ADCV[1] = bitSetter + 0x60 + (balancingEn<<4) + cellCh; |
DasSidG | 5:324a19dcfdec | 39 | |
DasSidG | 5:324a19dcfdec | 40 | bitSetter = (mode & 0x02) >> 1; |
DasSidG | 5:324a19dcfdec | 41 | ADAX[0] = bitSetter + 0x04; |
DasSidG | 5:324a19dcfdec | 42 | bitSetter = (mode & 0x01) << 7; |
DasSidG | 5:324a19dcfdec | 43 | ADAX[1] = bitSetter + 0x60 + gpioCh; |
DasSidG | 5:324a19dcfdec | 44 | } |
DasSidG | 5:324a19dcfdec | 45 | |
DasSidG | 5:324a19dcfdec | 46 | void LTC6804_acquireVoltageTx() |
DasSidG | 5:324a19dcfdec | 47 | { |
DasSidG | 5:324a19dcfdec | 48 | uint8_t broadcastCmd[4]; |
DasSidG | 5:324a19dcfdec | 49 | uint16_t pec; |
DasSidG | 5:324a19dcfdec | 50 | |
DasSidG | 5:324a19dcfdec | 51 | broadcastCmd[0]=ADCV[0]; |
DasSidG | 5:324a19dcfdec | 52 | broadcastCmd[1]=ADCV[1]; |
DasSidG | 5:324a19dcfdec | 53 | |
DasSidG | 5:324a19dcfdec | 54 | pec=pec15_calc(2, ADCV); |
DasSidG | 5:324a19dcfdec | 55 | broadcastCmd[2] = (uint8_t)(pec>>8); |
DasSidG | 5:324a19dcfdec | 56 | broadcastCmd[3] = (uint8_t)(pec); |
DasSidG | 5:324a19dcfdec | 57 | |
DasSidG | 5:324a19dcfdec | 58 | wake_SPI(); |
DasSidG | 5:324a19dcfdec | 59 | //chipSelect=1; |
DasSidG | 5:324a19dcfdec | 60 | chipSelect=0; //select LTC6820 by driving pin low |
DasSidG | 5:324a19dcfdec | 61 | spi_write_array(4, broadcastCmd); |
DasSidG | 5:324a19dcfdec | 62 | chipSelect=1; //de-select LTC6820 by driving pin high |
DasSidG | 5:324a19dcfdec | 63 | } |
DasSidG | 5:324a19dcfdec | 64 | |
DasSidG | 5:324a19dcfdec | 65 | uint8_t LTC6804_acquireAllVoltageRegRx(uint8_t reg, uint8_t cmuCount, uint16_t cell_codes[][12]) |
DasSidG | 5:324a19dcfdec | 66 | { |
DasSidG | 5:324a19dcfdec | 67 | //rdcv |
DasSidG | 5:324a19dcfdec | 68 | const uint8_t NUM_RX_BYT = 8; |
DasSidG | 5:324a19dcfdec | 69 | const uint8_t BYT_IN_REG = 6; |
DasSidG | 5:324a19dcfdec | 70 | const uint8_t CELL_IN_REG = 3; |
DasSidG | 5:324a19dcfdec | 71 | |
DasSidG | 5:324a19dcfdec | 72 | uint8_t *cell_data; |
DasSidG | 5:324a19dcfdec | 73 | int8_t pec_error = 0; |
DasSidG | 5:324a19dcfdec | 74 | uint16_t parsed_cell; |
DasSidG | 5:324a19dcfdec | 75 | uint16_t received_pec; |
DasSidG | 5:324a19dcfdec | 76 | uint16_t data_pec; |
DasSidG | 5:324a19dcfdec | 77 | uint8_t data_counter = 0; |
DasSidG | 5:324a19dcfdec | 78 | cell_data = (uint8_t *)malloc((NUM_RX_BYT*cmuCount) * sizeof(uint8_t)); |
DasSidG | 5:324a19dcfdec | 79 | |
DasSidG | 5:324a19dcfdec | 80 | if (reg == 0) { |
DasSidG | 5:324a19dcfdec | 81 | for (uint8_t cell_reg = 1; cell_reg < 5; cell_reg++) { |
DasSidG | 5:324a19dcfdec | 82 | data_counter = 0; |
DasSidG | 5:324a19dcfdec | 83 | LTC6804_acquireSingleVoltageRegRx(cell_reg, cmuCount, cell_data); |
DasSidG | 5:324a19dcfdec | 84 | for (uint8_t current_cmu = 0; current_cmu < cmuCount; current_cmu++) { |
DasSidG | 5:324a19dcfdec | 85 | for (uint8_t current_cell = 0; current_cell < CELL_IN_REG; current_cell++) { |
DasSidG | 5:324a19dcfdec | 86 | parsed_cell = cell_data[data_counter] + (cell_data[data_counter + 1] << 8); |
DasSidG | 5:324a19dcfdec | 87 | cell_codes[current_cmu][current_cell + ((cell_reg - 1)*CELL_IN_REG)] = parsed_cell; |
DasSidG | 5:324a19dcfdec | 88 | data_counter = data_counter + 2; |
DasSidG | 5:324a19dcfdec | 89 | } |
DasSidG | 5:324a19dcfdec | 90 | received_pec = (cell_data[data_counter] << 8) + cell_data[data_counter + 1]; |
DasSidG | 5:324a19dcfdec | 91 | data_pec = pec15_calc(BYT_IN_REG, &cell_data[current_cmu*NUM_RX_BYT]); |
DasSidG | 5:324a19dcfdec | 92 | if (received_pec != data_pec) { |
DasSidG | 6:47ffbe9ee110 | 93 | if (DEBUG) printf(" PEC ERROR \r\n"); |
DasSidG | 5:324a19dcfdec | 94 | pec_error--;//pec_error=-1; |
DasSidG | 5:324a19dcfdec | 95 | } |
DasSidG | 5:324a19dcfdec | 96 | data_counter = data_counter + 2; |
DasSidG | 5:324a19dcfdec | 97 | } |
DasSidG | 5:324a19dcfdec | 98 | } |
DasSidG | 5:324a19dcfdec | 99 | } |
DasSidG | 5:324a19dcfdec | 100 | |
DasSidG | 5:324a19dcfdec | 101 | else { |
DasSidG | 5:324a19dcfdec | 102 | LTC6804_acquireSingleVoltageRegRx(reg, cmuCount, cell_data); |
DasSidG | 5:324a19dcfdec | 103 | for (uint8_t current_cmu = 0; current_cmu < cmuCount; current_cmu++) { |
DasSidG | 5:324a19dcfdec | 104 | for (uint8_t current_cell = 0; current_cell < CELL_IN_REG; current_cell++) { |
DasSidG | 5:324a19dcfdec | 105 | parsed_cell = cell_data[data_counter] + (cell_data[data_counter + 1] << 8); |
DasSidG | 5:324a19dcfdec | 106 | cell_codes[current_cmu][current_cell + ((reg - 1)*CELL_IN_REG)] = 0X0000FFFF & parsed_cell; |
DasSidG | 5:324a19dcfdec | 107 | data_counter = data_counter + 2; |
DasSidG | 5:324a19dcfdec | 108 | } |
DasSidG | 5:324a19dcfdec | 109 | received_pec = (cell_data[data_counter] << 8) + cell_data[data_counter + 1]; |
DasSidG | 5:324a19dcfdec | 110 | data_pec = pec15_calc(BYT_IN_REG, &cell_data[current_cmu*NUM_RX_BYT*(reg - 1)]); |
DasSidG | 5:324a19dcfdec | 111 | if (received_pec != data_pec) { |
DasSidG | 5:324a19dcfdec | 112 | cout << " PEC ERROR " << endl; |
DasSidG | 5:324a19dcfdec | 113 | pec_error--;//pec+error=-1; |
DasSidG | 5:324a19dcfdec | 114 | } |
DasSidG | 5:324a19dcfdec | 115 | } |
DasSidG | 5:324a19dcfdec | 116 | } |
DasSidG | 5:324a19dcfdec | 117 | free(cell_data); |
DasSidG | 5:324a19dcfdec | 118 | return(pec_error); |
DasSidG | 5:324a19dcfdec | 119 | } |
DasSidG | 5:324a19dcfdec | 120 | |
DasSidG | 5:324a19dcfdec | 121 | void LTC6804_acquireSingleVoltageRegRx(uint8_t reg, uint8_t cmuCount, uint8_t *data) |
DasSidG | 5:324a19dcfdec | 122 | { |
DasSidG | 5:324a19dcfdec | 123 | //rdcv_reg |
DasSidG | 5:324a19dcfdec | 124 | uint8_t cmd[4]; |
DasSidG | 5:324a19dcfdec | 125 | uint16_t temporary_pec; |
DasSidG | 5:324a19dcfdec | 126 | |
DasSidG | 5:324a19dcfdec | 127 | if (reg == 1) { |
DasSidG | 5:324a19dcfdec | 128 | cmd[1] = 0x04; |
DasSidG | 5:324a19dcfdec | 129 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 130 | } else if (reg == 2) { |
DasSidG | 5:324a19dcfdec | 131 | cmd[1] = 0x06; |
DasSidG | 5:324a19dcfdec | 132 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 133 | } else if (reg == 3) { |
DasSidG | 5:324a19dcfdec | 134 | cmd[1] = 0x08; |
DasSidG | 5:324a19dcfdec | 135 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 136 | } else if (reg == 4) { |
DasSidG | 5:324a19dcfdec | 137 | cmd[1] = 0x0A; |
DasSidG | 5:324a19dcfdec | 138 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 139 | } |
DasSidG | 5:324a19dcfdec | 140 | |
DasSidG | 5:324a19dcfdec | 141 | wake_SPI(); |
DasSidG | 5:324a19dcfdec | 142 | |
DasSidG | 5:324a19dcfdec | 143 | for (int current_cmu = 0; current_cmu < cmuCount; current_cmu++) { |
DasSidG | 5:324a19dcfdec | 144 | cmd[0] = 0x80 + (current_cmu << 3);//setting address |
DasSidG | 5:324a19dcfdec | 145 | temporary_pec = pec15_calc(2, cmd); |
DasSidG | 5:324a19dcfdec | 146 | cmd[2] = (uint8_t)(temporary_pec >> 8); |
DasSidG | 5:324a19dcfdec | 147 | cmd[3] = (uint8_t)(temporary_pec); |
DasSidG | 5:324a19dcfdec | 148 | chipSelect = 0; |
DasSidG | 5:324a19dcfdec | 149 | spi_write_read(cmd,4,&data[current_cmu*8],8); |
DasSidG | 5:324a19dcfdec | 150 | chipSelect = 1; |
DasSidG | 5:324a19dcfdec | 151 | } |
DasSidG | 5:324a19dcfdec | 152 | } |
DasSidG | 5:324a19dcfdec | 153 | |
DasSidG | 5:324a19dcfdec | 154 | void LTC6804_setConfigReg(uint8_t cmuCount, uint8_t config[][6]) |
DasSidG | 5:324a19dcfdec | 155 | { |
DasSidG | 5:324a19dcfdec | 156 | const uint8_t BYTES_IN_REG = 6; |
DasSidG | 5:324a19dcfdec | 157 | const uint8_t CMD_LEN = 4 + (8 * cmuCount); |
DasSidG | 5:324a19dcfdec | 158 | uint8_t *cmd; |
DasSidG | 5:324a19dcfdec | 159 | uint16_t temporary_pec; |
DasSidG | 5:324a19dcfdec | 160 | uint8_t cmd_index; |
DasSidG | 5:324a19dcfdec | 161 | |
DasSidG | 5:324a19dcfdec | 162 | cmd = (uint8_t *)malloc(CMD_LEN * sizeof(uint8_t)); |
DasSidG | 5:324a19dcfdec | 163 | |
DasSidG | 5:324a19dcfdec | 164 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 165 | cmd[1] = 0x01; |
DasSidG | 5:324a19dcfdec | 166 | cmd[2] = 0x3d; |
DasSidG | 5:324a19dcfdec | 167 | cmd[3] = 0x6e; |
DasSidG | 5:324a19dcfdec | 168 | |
DasSidG | 5:324a19dcfdec | 169 | cmd_index = 4; |
DasSidG | 5:324a19dcfdec | 170 | for (int8_t current_cmu = cmuCount; current_cmu > 0; current_cmu--) { |
DasSidG | 5:324a19dcfdec | 171 | for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) { |
DasSidG | 5:324a19dcfdec | 172 | cmd[cmd_index] = config[current_cmu - 1][current_byte]; |
DasSidG | 5:324a19dcfdec | 173 | cmd_index = cmd_index + 1; |
DasSidG | 5:324a19dcfdec | 174 | } |
DasSidG | 5:324a19dcfdec | 175 | temporary_pec = (uint16_t)pec15_calc(BYTES_IN_REG, &config[current_cmu - 1][0]); |
DasSidG | 5:324a19dcfdec | 176 | cmd[cmd_index] = (uint8_t)(temporary_pec >> 8); |
DasSidG | 5:324a19dcfdec | 177 | cmd[cmd_index + 1] = (uint8_t)temporary_pec; |
DasSidG | 5:324a19dcfdec | 178 | cmd_index = cmd_index + 2; |
DasSidG | 5:324a19dcfdec | 179 | } |
DasSidG | 5:324a19dcfdec | 180 | |
DasSidG | 5:324a19dcfdec | 181 | //wake_SPI(); |
DasSidG | 5:324a19dcfdec | 182 | for (int current_cmu = 0; current_cmu < cmuCount; current_cmu++) { |
DasSidG | 5:324a19dcfdec | 183 | cmd[0] = 0x80 + (current_cmu << 3); |
DasSidG | 5:324a19dcfdec | 184 | temporary_pec = pec15_calc(2, cmd); |
DasSidG | 5:324a19dcfdec | 185 | cmd[2] = (uint8_t)(temporary_pec >> 8); |
DasSidG | 5:324a19dcfdec | 186 | cmd[3] = (uint8_t)(temporary_pec); |
DasSidG | 5:324a19dcfdec | 187 | chipSelect = 0; |
DasSidG | 5:324a19dcfdec | 188 | wait_us(350); |
DasSidG | 5:324a19dcfdec | 189 | spi_write_array(4, cmd); |
DasSidG | 5:324a19dcfdec | 190 | spi_write_array(8,&cmd[4+(8*current_cmu)]); |
DasSidG | 5:324a19dcfdec | 191 | chipSelect=1; |
DasSidG | 5:324a19dcfdec | 192 | } |
DasSidG | 5:324a19dcfdec | 193 | free(cmd); |
DasSidG | 5:324a19dcfdec | 194 | } |
DasSidG | 5:324a19dcfdec | 195 | |
DasSidG | 5:324a19dcfdec | 196 | |
DasSidG | 5:324a19dcfdec | 197 | uint16_t pec15_calc(uint8_t len, uint8_t *data) |
DasSidG | 5:324a19dcfdec | 198 | { |
DasSidG | 5:324a19dcfdec | 199 | uint16_t remainder,addr; |
DasSidG | 5:324a19dcfdec | 200 | |
DasSidG | 5:324a19dcfdec | 201 | remainder = 16;//initialize the PEC |
DasSidG | 5:324a19dcfdec | 202 | for(uint8_t i = 0; i<len; i++) { // loops for each byte in data array |
DasSidG | 5:324a19dcfdec | 203 | addr = ((remainder>>7)^data[i])&0xff;//calculate PEC table address |
DasSidG | 5:324a19dcfdec | 204 | remainder = (remainder<<8)^crc15Table[addr]; |
DasSidG | 5:324a19dcfdec | 205 | } |
DasSidG | 5:324a19dcfdec | 206 | return(remainder*2);//The CRC15 has a 0 in the LSB so the remainder must be multiplied by 2 |
DasSidG | 5:324a19dcfdec | 207 | } |
DasSidG | 5:324a19dcfdec | 208 | |
DasSidG | 5:324a19dcfdec | 209 | |
DasSidG | 5:324a19dcfdec | 210 | void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port |
DasSidG | 5:324a19dcfdec | 211 | uint8_t data[] //Array of bytes to be written on the SPI port |
DasSidG | 5:324a19dcfdec | 212 | ) |
DasSidG | 5:324a19dcfdec | 213 | { |
DasSidG | 5:324a19dcfdec | 214 | wait_us(70); |
DasSidG | 5:324a19dcfdec | 215 | spi.format(8,3); //All data transfer on LTC6804 occur in byte groups. LTC6820 set up such that POL=1 and PHA=3, this corresponds to mode 3 in mbed library. spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 216 | spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 217 | for (uint8_t i = 0; i < len; i++) { |
DasSidG | 5:324a19dcfdec | 218 | spi.write((char)data[i]); |
DasSidG | 5:324a19dcfdec | 219 | wait_us(110); |
DasSidG | 5:324a19dcfdec | 220 | } |
DasSidG | 5:324a19dcfdec | 221 | } |
DasSidG | 5:324a19dcfdec | 222 | |
DasSidG | 5:324a19dcfdec | 223 | |
DasSidG | 5:324a19dcfdec | 224 | void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port |
DasSidG | 5:324a19dcfdec | 225 | uint8_t tx_len, //length of the tx data arry |
DasSidG | 5:324a19dcfdec | 226 | uint8_t *rx_data,//Input: array that will store the data read by the SPI port |
DasSidG | 5:324a19dcfdec | 227 | uint8_t rx_len //Option: number of bytes to be read from the SPI port |
DasSidG | 5:324a19dcfdec | 228 | ) |
DasSidG | 5:324a19dcfdec | 229 | { |
DasSidG | 5:324a19dcfdec | 230 | //cout<<" SPI Write Read Called" << endl; |
DasSidG | 5:324a19dcfdec | 231 | spi.format(8,3);//All data transfer on LTC6804 occur in byte groups. LTC6820 set up such that POL=1 and PHA=3, this corresponds to mode 3 in mbed library. spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 232 | spi.frequency(spiBitrate); |
DasSidG | 5:324a19dcfdec | 233 | //printf("\r\n"); |
DasSidG | 5:324a19dcfdec | 234 | //uint8_t ret; |
DasSidG | 5:324a19dcfdec | 235 | |
DasSidG | 5:324a19dcfdec | 236 | chipSelect=0; |
DasSidG | 5:324a19dcfdec | 237 | wait_us(70); |
DasSidG | 5:324a19dcfdec | 238 | for (uint8_t i = 0; i < tx_len; i++) { |
DasSidG | 5:324a19dcfdec | 239 | //printf("index is %d: %d \r\n",i,tx_Data[i]); |
DasSidG | 5:324a19dcfdec | 240 | //cout << (int)tx_Data[i] << " , " << endl; |
DasSidG | 5:324a19dcfdec | 241 | spi.write(tx_Data[i]); |
DasSidG | 5:324a19dcfdec | 242 | wait_us(110); |
DasSidG | 5:324a19dcfdec | 243 | //printf("writing has returned %d \r\n", ret); |
DasSidG | 5:324a19dcfdec | 244 | } |
DasSidG | 5:324a19dcfdec | 245 | for (uint8_t i = 0; i < rx_len; i++) { |
DasSidG | 5:324a19dcfdec | 246 | rx_data[i] = (uint8_t)spi.write(0x00); |
DasSidG | 5:324a19dcfdec | 247 | wait_us(110); |
DasSidG | 5:324a19dcfdec | 248 | //ret = rx_data[i]; |
DasSidG | 5:324a19dcfdec | 249 | //printf("reading has returned %d \r\n", ret); |
DasSidG | 5:324a19dcfdec | 250 | } |
DasSidG | 5:324a19dcfdec | 251 | chipSelect=1; |
DasSidG | 5:324a19dcfdec | 252 | |
DasSidG | 5:324a19dcfdec | 253 | for (uint8_t i = 0; i < tx_len; i++) { |
DasSidG | 5:324a19dcfdec | 254 | //printf("index is %d: %d \r\n",i,tx_Data[i]); |
DasSidG | 5:324a19dcfdec | 255 | break; |
DasSidG | 5:324a19dcfdec | 256 | cout << "Transmit Data " ; |
DasSidG | 5:324a19dcfdec | 257 | cout << (int)tx_Data[i] << " , " ; |
DasSidG | 5:324a19dcfdec | 258 | cout << endl; |
DasSidG | 5:324a19dcfdec | 259 | } |
DasSidG | 5:324a19dcfdec | 260 | |
DasSidG | 5:324a19dcfdec | 261 | } |
DasSidG | 5:324a19dcfdec | 262 | |
DasSidG | 5:324a19dcfdec | 263 | |
DasSidG | 5:324a19dcfdec | 264 | |
DasSidG | 5:324a19dcfdec | 265 | int8_t LTC6804_rdcfg(uint8_t total_ic, uint8_t r_config[][8]) |
DasSidG | 5:324a19dcfdec | 266 | { |
DasSidG | 5:324a19dcfdec | 267 | //cout<<"Read Config function called" << endl; |
DasSidG | 5:324a19dcfdec | 268 | const uint8_t BYTES_IN_REG = 8; |
DasSidG | 5:324a19dcfdec | 269 | |
DasSidG | 5:324a19dcfdec | 270 | uint8_t cmd[4]; |
DasSidG | 5:324a19dcfdec | 271 | uint8_t *rx_data; |
DasSidG | 5:324a19dcfdec | 272 | int8_t pec_error = 0; |
DasSidG | 5:324a19dcfdec | 273 | uint16_t data_pec; |
DasSidG | 5:324a19dcfdec | 274 | uint16_t received_pec; |
DasSidG | 5:324a19dcfdec | 275 | rx_data = (uint8_t *) malloc((8*total_ic)*sizeof(uint8_t)); |
DasSidG | 5:324a19dcfdec | 276 | //1 |
DasSidG | 5:324a19dcfdec | 277 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 278 | cmd[1] = 0x02; |
DasSidG | 5:324a19dcfdec | 279 | cmd[2] = 0x2b; |
DasSidG | 5:324a19dcfdec | 280 | cmd[3] = 0x0A; |
DasSidG | 5:324a19dcfdec | 281 | |
DasSidG | 5:324a19dcfdec | 282 | //2 |
DasSidG | 5:324a19dcfdec | 283 | //wake_SPI(); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed. |
DasSidG | 5:324a19dcfdec | 284 | //3 |
DasSidG | 5:324a19dcfdec | 285 | for(int current_ic = 0; current_ic<total_ic; current_ic++) { |
DasSidG | 5:324a19dcfdec | 286 | cmd[0] = 0x80 + (current_ic<<3); //Setting address |
DasSidG | 5:324a19dcfdec | 287 | data_pec = pec15_calc(2, cmd); |
DasSidG | 5:324a19dcfdec | 288 | cmd[2] = (uint8_t)(data_pec >> 8); |
DasSidG | 5:324a19dcfdec | 289 | cmd[3] = (uint8_t)(data_pec); |
DasSidG | 5:324a19dcfdec | 290 | //ut << "RdConf cmd:" << (int)cmd[0] << endl; |
DasSidG | 5:324a19dcfdec | 291 | spi_write_read(cmd,4,&rx_data[current_ic*8],8); |
DasSidG | 5:324a19dcfdec | 292 | } |
DasSidG | 5:324a19dcfdec | 293 | //for (int i=0; i<8; i++) { |
DasSidG | 5:324a19dcfdec | 294 | //cout << (int)rx_data[i] << " , "; |
DasSidG | 5:324a19dcfdec | 295 | //} |
DasSidG | 5:324a19dcfdec | 296 | //cout << endl; |
DasSidG | 5:324a19dcfdec | 297 | |
DasSidG | 5:324a19dcfdec | 298 | for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) { //executes for each LTC6804 in the stack |
DasSidG | 5:324a19dcfdec | 299 | //4.a |
DasSidG | 5:324a19dcfdec | 300 | for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) { |
DasSidG | 5:324a19dcfdec | 301 | r_config[current_ic][current_byte] = rx_data[current_byte + (current_ic*BYTES_IN_REG)]; |
DasSidG | 5:324a19dcfdec | 302 | } |
DasSidG | 5:324a19dcfdec | 303 | //4.b |
DasSidG | 5:324a19dcfdec | 304 | received_pec = (r_config[current_ic][6]<<8) + r_config[current_ic][7]; |
DasSidG | 5:324a19dcfdec | 305 | //cout << "Rxpec " << received_pec << endl; |
DasSidG | 5:324a19dcfdec | 306 | data_pec = pec15_calc(6, &r_config[current_ic][0]); |
DasSidG | 5:324a19dcfdec | 307 | //cout << "Datpec" << data_pec << endl; |
DasSidG | 5:324a19dcfdec | 308 | if(received_pec != data_pec) { |
DasSidG | 5:324a19dcfdec | 309 | pec_error = -1; |
DasSidG | 5:324a19dcfdec | 310 | cout << "PEC error!!!" << endl; |
DasSidG | 5:324a19dcfdec | 311 | } |
DasSidG | 5:324a19dcfdec | 312 | } |
DasSidG | 5:324a19dcfdec | 313 | free(rx_data); |
DasSidG | 5:324a19dcfdec | 314 | //5 |
DasSidG | 5:324a19dcfdec | 315 | //cout << r_config << endl; |
DasSidG | 5:324a19dcfdec | 316 | return(pec_error); |
DasSidG | 5:324a19dcfdec | 317 | } |
DasSidG | 5:324a19dcfdec | 318 | /* |
DasSidG | 5:324a19dcfdec | 319 | 1. Load cmd array with the write configuration command and PEC |
DasSidG | 5:324a19dcfdec | 320 | 2. wakeup isoSPI port, this step can be removed if isoSPI status is previously guaranteed |
DasSidG | 5:324a19dcfdec | 321 | 3. read configuration of each LTC6804 on the stack |
DasSidG | 5:324a19dcfdec | 322 | 4. For each LTC6804 in the stack |
DasSidG | 5:324a19dcfdec | 323 | a. load configuration data into r_config array |
DasSidG | 5:324a19dcfdec | 324 | b. calculate PEC of received data and compare against calculated PEC |
DasSidG | 5:324a19dcfdec | 325 | 5. Return PEC Error |
DasSidG | 5:324a19dcfdec | 326 | |
DasSidG | 5:324a19dcfdec | 327 | */ |
DasSidG | 5:324a19dcfdec | 328 | |
DasSidG | 5:324a19dcfdec | 329 | |
DasSidG | 5:324a19dcfdec | 330 | int8_t LTC6804_rdstat(uint8_t total_ic, uint8_t r_config[][8]) |
DasSidG | 5:324a19dcfdec | 331 | { |
DasSidG | 5:324a19dcfdec | 332 | cout<<"Read Config function called" << endl; |
DasSidG | 5:324a19dcfdec | 333 | const uint8_t BYTES_IN_REG = 8; |
DasSidG | 5:324a19dcfdec | 334 | |
DasSidG | 5:324a19dcfdec | 335 | uint8_t cmd[4]; |
DasSidG | 5:324a19dcfdec | 336 | uint8_t *rx_data; |
DasSidG | 5:324a19dcfdec | 337 | int8_t pec_error = 0; |
DasSidG | 5:324a19dcfdec | 338 | uint16_t data_pec; |
DasSidG | 5:324a19dcfdec | 339 | uint16_t received_pec; |
DasSidG | 5:324a19dcfdec | 340 | rx_data = (uint8_t *) malloc((8*total_ic)*sizeof(uint8_t)); |
DasSidG | 5:324a19dcfdec | 341 | //1 |
DasSidG | 5:324a19dcfdec | 342 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 343 | cmd[1] = 0x12; |
DasSidG | 5:324a19dcfdec | 344 | |
DasSidG | 5:324a19dcfdec | 345 | //2 |
DasSidG | 5:324a19dcfdec | 346 | //wake_SPI(); //This will guarantee that the LTC6804 isoSPI port is awake. This command can be removed. |
DasSidG | 5:324a19dcfdec | 347 | //3 |
DasSidG | 5:324a19dcfdec | 348 | for(int current_ic = 0; current_ic<total_ic; current_ic++) { |
DasSidG | 5:324a19dcfdec | 349 | cmd[0] = 0x80 + (15<<3); //Setting address |
DasSidG | 5:324a19dcfdec | 350 | data_pec = pec15_calc(2, cmd); |
DasSidG | 5:324a19dcfdec | 351 | cmd[2] = (uint8_t)(data_pec >> 8); |
DasSidG | 5:324a19dcfdec | 352 | cmd[3] = (uint8_t)(data_pec); |
DasSidG | 5:324a19dcfdec | 353 | //ut << "RdConf cmd:" << (int)cmd[0] << endl; |
DasSidG | 5:324a19dcfdec | 354 | spi_write_read(cmd,4,&rx_data[current_ic*8],8); |
DasSidG | 5:324a19dcfdec | 355 | } |
DasSidG | 5:324a19dcfdec | 356 | //for (int i=0; i<8; i++) { |
DasSidG | 5:324a19dcfdec | 357 | //cout << (int)rx_data[i] << " , "; |
DasSidG | 5:324a19dcfdec | 358 | //} |
DasSidG | 5:324a19dcfdec | 359 | //cout << endl; |
DasSidG | 5:324a19dcfdec | 360 | |
DasSidG | 5:324a19dcfdec | 361 | for (uint8_t current_ic = 0; current_ic < total_ic; current_ic++) { //executes for each LTC6804 in the stack |
DasSidG | 5:324a19dcfdec | 362 | //4.a |
DasSidG | 5:324a19dcfdec | 363 | for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) { |
DasSidG | 5:324a19dcfdec | 364 | r_config[current_ic][current_byte] = rx_data[current_byte + (current_ic*BYTES_IN_REG)]; |
DasSidG | 5:324a19dcfdec | 365 | } |
DasSidG | 5:324a19dcfdec | 366 | //4.b |
DasSidG | 5:324a19dcfdec | 367 | received_pec = (r_config[current_ic][6]<<8) + r_config[current_ic][7]; |
DasSidG | 5:324a19dcfdec | 368 | //cout << "Rxpec " << received_pec << endl; |
DasSidG | 5:324a19dcfdec | 369 | data_pec = pec15_calc(6, &r_config[current_ic][0]); |
DasSidG | 5:324a19dcfdec | 370 | //cout << "Datpec" << data_pec << endl; |
DasSidG | 5:324a19dcfdec | 371 | if(received_pec != data_pec) { |
DasSidG | 5:324a19dcfdec | 372 | pec_error = -1; |
DasSidG | 5:324a19dcfdec | 373 | //cout << "PEC error!!!" << endl; |
DasSidG | 5:324a19dcfdec | 374 | } |
DasSidG | 5:324a19dcfdec | 375 | } |
DasSidG | 5:324a19dcfdec | 376 | free(rx_data); |
DasSidG | 5:324a19dcfdec | 377 | //5 |
DasSidG | 5:324a19dcfdec | 378 | //cout << r_config << endl; |
DasSidG | 5:324a19dcfdec | 379 | return(pec_error); |
DasSidG | 5:324a19dcfdec | 380 | } |
DasSidG | 5:324a19dcfdec | 381 | |
DasSidG | 5:324a19dcfdec | 382 | |
DasSidG | 5:324a19dcfdec | 383 | void LTC6804_wrcfg(uint8_t total_ic,uint8_t config[][6]) |
DasSidG | 5:324a19dcfdec | 384 | { |
DasSidG | 5:324a19dcfdec | 385 | const uint8_t BYTES_IN_REG = 6; |
DasSidG | 5:324a19dcfdec | 386 | const uint8_t CMD_LEN = 4+(8*total_ic); |
DasSidG | 5:324a19dcfdec | 387 | uint8_t *cmd; |
DasSidG | 5:324a19dcfdec | 388 | uint16_t temp_pec; |
DasSidG | 5:324a19dcfdec | 389 | uint8_t cmd_index; //command counter |
DasSidG | 5:324a19dcfdec | 390 | |
DasSidG | 5:324a19dcfdec | 391 | cmd = (uint8_t *)malloc(CMD_LEN*sizeof(uint8_t)); |
DasSidG | 5:324a19dcfdec | 392 | //1 |
DasSidG | 5:324a19dcfdec | 393 | cmd[0] = 0x00; |
DasSidG | 5:324a19dcfdec | 394 | cmd[1] = 0x01; |
DasSidG | 5:324a19dcfdec | 395 | cmd[2] = 0x3d; |
DasSidG | 5:324a19dcfdec | 396 | cmd[3] = 0x6e; |
DasSidG | 5:324a19dcfdec | 397 | |
DasSidG | 5:324a19dcfdec | 398 | //2 |
DasSidG | 5:324a19dcfdec | 399 | cmd_index = 4; |
DasSidG | 5:324a19dcfdec | 400 | for (uint8_t current_ic = total_ic; current_ic > 0; current_ic--) { // executes for each LTC6804 in stack, |
DasSidG | 5:324a19dcfdec | 401 | for (uint8_t current_byte = 0; current_byte < BYTES_IN_REG; current_byte++) { // executes for each byte in the CFGR register |
DasSidG | 5:324a19dcfdec | 402 | // i is the byte counter |
DasSidG | 5:324a19dcfdec | 403 | |
DasSidG | 5:324a19dcfdec | 404 | cmd[cmd_index] = config[current_ic-1][current_byte]; //adding the config data to the array to be sent |
DasSidG | 5:324a19dcfdec | 405 | cmd_index = cmd_index + 1; |
DasSidG | 5:324a19dcfdec | 406 | } |
DasSidG | 5:324a19dcfdec | 407 | //3 |
DasSidG | 5:324a19dcfdec | 408 | temp_pec = (uint16_t)pec15_calc(BYTES_IN_REG, &config[current_ic-1][0]);// calculating the PEC for each board |
DasSidG | 5:324a19dcfdec | 409 | cmd[cmd_index] = (uint8_t)(temp_pec >> 8); |
DasSidG | 5:324a19dcfdec | 410 | cmd[cmd_index + 1] = (uint8_t)temp_pec; |
DasSidG | 5:324a19dcfdec | 411 | cmd_index = cmd_index + 2; |
DasSidG | 5:324a19dcfdec | 412 | } |
DasSidG | 5:324a19dcfdec | 413 | |
DasSidG | 5:324a19dcfdec | 414 | //4 //This will guarantee that the LTC6804 isoSPI port is awake.This command can be removed. |
DasSidG | 5:324a19dcfdec | 415 | //5 |
DasSidG | 5:324a19dcfdec | 416 | for (int current_ic = 0; current_ic<total_ic; current_ic++) { |
DasSidG | 5:324a19dcfdec | 417 | cmd[0] = 0x80 + (current_ic<<3); //Setting address |
DasSidG | 5:324a19dcfdec | 418 | temp_pec = pec15_calc(2, cmd); |
DasSidG | 5:324a19dcfdec | 419 | cmd[2] = (uint8_t)(temp_pec >> 8); |
DasSidG | 5:324a19dcfdec | 420 | cmd[3] = (uint8_t)(temp_pec); |
DasSidG | 5:324a19dcfdec | 421 | chipSelect=0; |
DasSidG | 5:324a19dcfdec | 422 | wait_us(350); |
DasSidG | 5:324a19dcfdec | 423 | spi_write_array(4,cmd); |
DasSidG | 5:324a19dcfdec | 424 | spi_write_array(8,&cmd[4+(8*current_ic)]); |
DasSidG | 5:324a19dcfdec | 425 | chipSelect=1; |
DasSidG | 5:324a19dcfdec | 426 | } |
DasSidG | 5:324a19dcfdec | 427 | free(cmd); |
DasSidG | 5:324a19dcfdec | 428 | } |