Cell voltages fork (SoC)
Dependencies: CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl
IVTA.cpp@54:f18d3af300ba, 2017-08-19 (annotated)
- Committer:
- DasSidG
- Date:
- Sat Aug 19 18:57:18 2017 +0000
- Revision:
- 54:f18d3af300ba
- Child:
- 57:a84af3673c9b
Removed all LTC2943 functionality as no longer working. Replaced it with the equivalent functionality from the IVT-A. Preliminary tests seem to suggests that it all works fine, including robustmess to weird power conditions
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DasSidG | 54:f18d3af300ba | 1 | #include "IVTA.h"; |
DasSidG | 54:f18d3af300ba | 2 | |
DasSidG | 54:f18d3af300ba | 3 | DigitalOut IVTA_SS(p11); |
DasSidG | 54:f18d3af300ba | 4 | |
DasSidG | 54:f18d3af300ba | 5 | SPI spi_ivta(p5, p6, p7); // mosi, miso, sclk |
DasSidG | 54:f18d3af300ba | 6 | |
DasSidG | 54:f18d3af300ba | 7 | int ivta_transfer(uint8_t * txrx) |
DasSidG | 54:f18d3af300ba | 8 | { |
DasSidG | 54:f18d3af300ba | 9 | char i;// j; |
DasSidG | 54:f18d3af300ba | 10 | uint16_t crc; |
DasSidG | 54:f18d3af300ba | 11 | |
DasSidG | 54:f18d3af300ba | 12 | //pc.printf("*** Into a transfer*** \r \n"); |
DasSidG | 54:f18d3af300ba | 13 | |
DasSidG | 54:f18d3af300ba | 14 | // Activate IVT-A and send packet. |
DasSidG | 54:f18d3af300ba | 15 | IVTA_SS = 0; |
DasSidG | 54:f18d3af300ba | 16 | //pc.printf("Data sent"); |
DasSidG | 54:f18d3af300ba | 17 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 18 | for(i = 0; i < 9; i++) |
DasSidG | 54:f18d3af300ba | 19 | { |
DasSidG | 54:f18d3af300ba | 20 | spi_ivta.write(txrx[i]); |
DasSidG | 54:f18d3af300ba | 21 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 22 | } |
DasSidG | 54:f18d3af300ba | 23 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 24 | IVTA_SS = 1; |
DasSidG | 54:f18d3af300ba | 25 | /* |
DasSidG | 54:f18d3af300ba | 26 | Note: we ignore the packet sent by the IVT-A |
DasSidG | 54:f18d3af300ba | 27 | during this communication phase. Similarly, |
DasSidG | 54:f18d3af300ba | 28 | we only receive data in the next phase. Essentially |
DasSidG | 54:f18d3af300ba | 29 | we run the IVT-A in half-duplex mode. |
DasSidG | 54:f18d3af300ba | 30 | */ |
DasSidG | 54:f18d3af300ba | 31 | |
DasSidG | 54:f18d3af300ba | 32 | wait_us(500); // Wait between packets |
DasSidG | 54:f18d3af300ba | 33 | IVTA_SS = 0; // Activate IVT-A and receive packet. |
DasSidG | 54:f18d3af300ba | 34 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 35 | for(i = 0; i < 9; i++) |
DasSidG | 54:f18d3af300ba | 36 | { |
DasSidG | 54:f18d3af300ba | 37 | txrx[i] = spi_ivta.write(0x00); // Write some dummy data(half duplex) |
DasSidG | 54:f18d3af300ba | 38 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 39 | } |
DasSidG | 54:f18d3af300ba | 40 | wait_us(3); |
DasSidG | 54:f18d3af300ba | 41 | IVTA_SS = 1; |
DasSidG | 54:f18d3af300ba | 42 | |
DasSidG | 54:f18d3af300ba | 43 | return 0; |
DasSidG | 54:f18d3af300ba | 44 | } |
DasSidG | 54:f18d3af300ba | 45 | |
DasSidG | 54:f18d3af300ba | 46 | /* |
DasSidG | 54:f18d3af300ba | 47 | Initialise IVT-A. |
DasSidG | 54:f18d3af300ba | 48 | Write configuration: |
DasSidG | 54:f18d3af300ba | 49 | + Current in 300A range measured on channel A. |
DasSidG | 54:f18d3af300ba | 50 | + Temperature measured on channel B (currently unused). |
DasSidG | 54:f18d3af300ba | 51 | + Average data over 10 samples. |
DasSidG | 54:f18d3af300ba | 52 | */ |
DasSidG | 54:f18d3af300ba | 53 | int ivta_init(void) |
DasSidG | 54:f18d3af300ba | 54 | { |
DasSidG | 54:f18d3af300ba | 55 | IVTA_SS = 1; |
DasSidG | 54:f18d3af300ba | 56 | spi_ivta.format(8,0); // The format works for 0 or 1, most of testing done with 0 |
DasSidG | 54:f18d3af300ba | 57 | spi_ivta.frequency(500000); |
DasSidG | 54:f18d3af300ba | 58 | /* The last 2 bytes of the package are the CRC check, upper 4 bits in the |
DasSidG | 54:f18d3af300ba | 59 | command are the command code */ |
DasSidG | 54:f18d3af300ba | 60 | int transfer; |
DasSidG | 54:f18d3af300ba | 61 | uint8_t packet[9] = {0x90,1,5,200,0,0,0,0x78,0xB8}; |
DasSidG | 54:f18d3af300ba | 62 | //if (DEBUG) printf("Calculated init crc is %x ", calculate_IVTA_crc(packet)); |
DasSidG | 54:f18d3af300ba | 63 | transfer = ivta_transfer(packet); |
DasSidG | 54:f18d3af300ba | 64 | return transfer; |
DasSidG | 54:f18d3af300ba | 65 | } |
DasSidG | 54:f18d3af300ba | 66 | |
DasSidG | 54:f18d3af300ba | 67 | |
DasSidG | 54:f18d3af300ba | 68 | bool ivta_get_current(int32_t ¤t) //returns true if crc check succeeded, false otherwise |
DasSidG | 54:f18d3af300ba | 69 | { |
DasSidG | 54:f18d3af300ba | 70 | //printf("In get current \r \n"); |
DasSidG | 54:f18d3af300ba | 71 | //int r_val; |
DasSidG | 54:f18d3af300ba | 72 | uint8_t packet[9] = {0x10,1,0,0,0,0,0,0x0B,0x10}; // Command code 1. |
DasSidG | 54:f18d3af300ba | 73 | //printf("Calculated current crc is %x ", calculate_IVTA_crc(packet)); |
DasSidG | 54:f18d3af300ba | 74 | //printf("In get current \r \n"); |
DasSidG | 54:f18d3af300ba | 75 | int r_val = ivta_transfer(packet); |
DasSidG | 54:f18d3af300ba | 76 | |
DasSidG | 54:f18d3af300ba | 77 | /* printf("Packet1 : %d \r", packet[1]); |
DasSidG | 54:f18d3af300ba | 78 | printf("Packet1 : %d \r", packet[2]); |
DasSidG | 54:f18d3af300ba | 79 | printf("Packet1 : %d \r", packet[3]); |
DasSidG | 54:f18d3af300ba | 80 | printf("Packet1 : %d \r", packet[4]);*/ |
DasSidG | 54:f18d3af300ba | 81 | uint8_t measurements[6]; |
DasSidG | 54:f18d3af300ba | 82 | uint8_t received_crc_bytes[2]; |
DasSidG | 54:f18d3af300ba | 83 | |
DasSidG | 54:f18d3af300ba | 84 | measurements[0] = packet[1]; // Must shift the index of the packet |
DasSidG | 54:f18d3af300ba | 85 | measurements[1] = packet[2]; |
DasSidG | 54:f18d3af300ba | 86 | measurements[2] = packet[3]; |
DasSidG | 54:f18d3af300ba | 87 | measurements[3] = packet[4]; |
DasSidG | 54:f18d3af300ba | 88 | measurements[4] = packet[5]; |
DasSidG | 54:f18d3af300ba | 89 | measurements[5] = packet[6]; |
DasSidG | 54:f18d3af300ba | 90 | received_crc_bytes[0] = packet[7]; |
DasSidG | 54:f18d3af300ba | 91 | received_crc_bytes[1] = packet[8]; |
DasSidG | 54:f18d3af300ba | 92 | |
DasSidG | 54:f18d3af300ba | 93 | uint16_t calculated_crc = calculate_IVTA_crc(packet); |
DasSidG | 54:f18d3af300ba | 94 | printf("calculated current crc is %x \r\n", calculated_crc); |
DasSidG | 54:f18d3af300ba | 95 | uint16_t received_crc = (uint16_t) received_crc_bytes[0]; |
DasSidG | 54:f18d3af300ba | 96 | received_crc |= (uint16_t) received_crc_bytes[1] <<8; |
DasSidG | 54:f18d3af300ba | 97 | printf("received current crc is %x \r\n", received_crc); |
DasSidG | 54:f18d3af300ba | 98 | |
DasSidG | 54:f18d3af300ba | 99 | |
DasSidG | 54:f18d3af300ba | 100 | |
DasSidG | 54:f18d3af300ba | 101 | /*for (int i = 0; i < 6; ++i) { |
DasSidG | 54:f18d3af300ba | 102 | printf ("Current measurements %d is %d \r\n", i, measurements[i]); |
DasSidG | 54:f18d3af300ba | 103 | }*/ |
DasSidG | 54:f18d3af300ba | 104 | |
DasSidG | 54:f18d3af300ba | 105 | if (calculated_crc == received_crc) { |
DasSidG | 54:f18d3af300ba | 106 | uint32_t unsigned_current = ((uint32_t)measurements[0]); |
DasSidG | 54:f18d3af300ba | 107 | unsigned_current = unsigned_current | (((uint32_t)measurements[1]<<8)); |
DasSidG | 54:f18d3af300ba | 108 | unsigned_current = unsigned_current | (((uint32_t)measurements[2]<<16)); |
DasSidG | 54:f18d3af300ba | 109 | |
DasSidG | 54:f18d3af300ba | 110 | if(measurements[2] & 0x80){ //For some reason converting using 2's complement ¯\_(ツ)_/¯ |
DasSidG | 54:f18d3af300ba | 111 | uint32_t convertedData = ((~unsigned_current) + 1) & 0x00FFFFFF; |
DasSidG | 54:f18d3af300ba | 112 | int32_t convertedData2 = (~convertedData)+1; |
DasSidG | 54:f18d3af300ba | 113 | if (DEBUG) printf("*** Signed IVT-A Current measurement value: %d *** \r \n",convertedData2); |
DasSidG | 54:f18d3af300ba | 114 | current = convertedData2; |
DasSidG | 54:f18d3af300ba | 115 | } |
DasSidG | 54:f18d3af300ba | 116 | else{ |
DasSidG | 54:f18d3af300ba | 117 | if (DEBUG) printf("*** Unsigned IVT-A Current measurement value: %d *** \r \n", (int32_t)unsigned_current); |
DasSidG | 54:f18d3af300ba | 118 | current = unsigned_current; |
DasSidG | 54:f18d3af300ba | 119 | } |
DasSidG | 54:f18d3af300ba | 120 | |
DasSidG | 54:f18d3af300ba | 121 | return true; |
DasSidG | 54:f18d3af300ba | 122 | } |
DasSidG | 54:f18d3af300ba | 123 | else return false; |
DasSidG | 54:f18d3af300ba | 124 | } |
DasSidG | 54:f18d3af300ba | 125 | |
DasSidG | 54:f18d3af300ba | 126 | void ivta_reset_Ah_meter() { //sets Ah meter to zero |
DasSidG | 54:f18d3af300ba | 127 | uint8_t packet[9] = {0xA0,0x01,0x00,0x00,0x00,0x00,0x00,0xBA,0xDB}; // Command code 10. |
DasSidG | 54:f18d3af300ba | 128 | ivta_transfer(packet); |
DasSidG | 54:f18d3af300ba | 129 | } |
DasSidG | 54:f18d3af300ba | 130 | |
DasSidG | 54:f18d3af300ba | 131 | bool ivta_read_Ah_meter(float &Ah) { //return Ah meter reading in units of Ah |
DasSidG | 54:f18d3af300ba | 132 | uint8_t packet[9] = {0x50,0x01,0x00,0x00,0x00,0x00,0x00,0x4A,0xD4}; // Command code 5. |
DasSidG | 54:f18d3af300ba | 133 | //printf("Calculated read_Ah crc is %x ", calculate_IVTA_crc(packet)); |
DasSidG | 54:f18d3af300ba | 134 | ivta_transfer(packet); |
DasSidG | 54:f18d3af300ba | 135 | uint8_t measurements[6]; |
DasSidG | 54:f18d3af300ba | 136 | uint8_t received_crc_bytes[2]; |
DasSidG | 54:f18d3af300ba | 137 | |
DasSidG | 54:f18d3af300ba | 138 | measurements[0] = packet[1]; // Must shift the index of the packet |
DasSidG | 54:f18d3af300ba | 139 | measurements[1] = packet[2]; |
DasSidG | 54:f18d3af300ba | 140 | measurements[2] = packet[3]; |
DasSidG | 54:f18d3af300ba | 141 | measurements[3] = packet[4]; |
DasSidG | 54:f18d3af300ba | 142 | measurements[4] = packet[5]; |
DasSidG | 54:f18d3af300ba | 143 | measurements[5] = packet[6]; |
DasSidG | 54:f18d3af300ba | 144 | received_crc_bytes[0] = packet[7]; |
DasSidG | 54:f18d3af300ba | 145 | received_crc_bytes[1] = packet[8]; |
DasSidG | 54:f18d3af300ba | 146 | |
DasSidG | 54:f18d3af300ba | 147 | uint16_t calculated_crc = calculate_IVTA_crc(packet); |
DasSidG | 54:f18d3af300ba | 148 | uint16_t received_crc = (uint16_t) received_crc_bytes[0]; |
DasSidG | 54:f18d3af300ba | 149 | received_crc |= (uint16_t) received_crc_bytes[1] <<8; |
DasSidG | 54:f18d3af300ba | 150 | |
DasSidG | 54:f18d3af300ba | 151 | /*for (int i = 0; i < 6; ++i) { |
DasSidG | 54:f18d3af300ba | 152 | printf ("Ah Measurements %d is %d \r\n", i, measurements[i]); |
DasSidG | 54:f18d3af300ba | 153 | }*/ |
DasSidG | 54:f18d3af300ba | 154 | if (received_crc == calculated_crc) { |
DasSidG | 54:f18d3af300ba | 155 | uint64_t mAs = ((uint64_t)measurements[0]); |
DasSidG | 54:f18d3af300ba | 156 | mAs = mAs | (((uint64_t)measurements[1]<<8)); |
DasSidG | 54:f18d3af300ba | 157 | mAs = mAs | (((uint64_t)measurements[2]<<16)); |
DasSidG | 54:f18d3af300ba | 158 | mAs = mAs | (((uint64_t)measurements[3]<<24)); |
DasSidG | 54:f18d3af300ba | 159 | mAs = mAs | (((uint64_t)measurements[4]<<32)); |
DasSidG | 54:f18d3af300ba | 160 | mAs = mAs | (((uint64_t)measurements[5]<<40)); |
DasSidG | 54:f18d3af300ba | 161 | |
DasSidG | 54:f18d3af300ba | 162 | if(measurements[5] & 0x80){ //For some reason converting using 2's complement ¯\_(ツ)_/¯ |
DasSidG | 54:f18d3af300ba | 163 | uint64_t convertedData = ((~mAs) + 1) & 0x0000FFFFFFFFFFFF; |
DasSidG | 54:f18d3af300ba | 164 | uint64_t convertedData2 = (~convertedData)+1; |
DasSidG | 54:f18d3af300ba | 165 | Ah = convertedData2/(1000.0*3600); |
DasSidG | 54:f18d3af300ba | 166 | if(DEBUG) printf("*** Signed IVT-A Ah measurement value: %f *** \r \n",Ah); |
DasSidG | 54:f18d3af300ba | 167 | } |
DasSidG | 54:f18d3af300ba | 168 | else{ |
DasSidG | 54:f18d3af300ba | 169 | Ah = mAs /(1000.0*3600); |
DasSidG | 54:f18d3af300ba | 170 | if(DEBUG) printf("*** Unsigned IVT-A Ah measurement value: %f *** \r \n", Ah); |
DasSidG | 54:f18d3af300ba | 171 | } |
DasSidG | 54:f18d3af300ba | 172 | return true; |
DasSidG | 54:f18d3af300ba | 173 | } |
DasSidG | 54:f18d3af300ba | 174 | else return false; |
DasSidG | 54:f18d3af300ba | 175 | } |
DasSidG | 54:f18d3af300ba | 176 | |
DasSidG | 54:f18d3af300ba | 177 | uint16_t calculate_IVTA_crc(uint8_t data[]) { |
DasSidG | 54:f18d3af300ba | 178 | uint16_t crc = 0xFFFF; |
DasSidG | 54:f18d3af300ba | 179 | for (int i = 0; i < 7; ++i) { |
DasSidG | 54:f18d3af300ba | 180 | crc = crc16_update(crc, data[i]); |
DasSidG | 54:f18d3af300ba | 181 | } |
DasSidG | 54:f18d3af300ba | 182 | return crc; |
DasSidG | 54:f18d3af300ba | 183 | } |
DasSidG | 54:f18d3af300ba | 184 | |
DasSidG | 54:f18d3af300ba | 185 | uint16_t crc16_update(uint16_t crc, uint8_t a) |
DasSidG | 54:f18d3af300ba | 186 | { |
DasSidG | 54:f18d3af300ba | 187 | crc ^= a; |
DasSidG | 54:f18d3af300ba | 188 | for (int i = 0; i < 8; ++i) |
DasSidG | 54:f18d3af300ba | 189 | { |
DasSidG | 54:f18d3af300ba | 190 | if (crc & 1) crc = (crc >> 1) ^ 0xA001; |
DasSidG | 54:f18d3af300ba | 191 | else crc = (crc >> 1); |
DasSidG | 54:f18d3af300ba | 192 | } |
DasSidG | 54:f18d3af300ba | 193 | return crc; |
DasSidG | 54:f18d3af300ba | 194 | } |