Cell voltages fork (SoC)
Dependencies: CUER_CAN CUER_DS1820 LTC2943 LTC6804 mbed PowerControl
IVTA.cpp
- Committer:
- DasSidG
- Date:
- 2017-08-19
- Revision:
- 57:a84af3673c9b
- Parent:
- 54:f18d3af300ba
- Child:
- 58:40d318825b0d
File content as of revision 57:a84af3673c9b:
#include "IVTA.h"; DigitalOut IVTA_SS(p11); SPI spi_ivta(p5, p6, p7); // mosi, miso, sclk int ivta_transfer(uint8_t * txrx) { char i;// j; uint16_t crc; //pc.printf("*** Into a transfer*** \r \n"); // Activate IVT-A and send packet. IVTA_SS = 0; //pc.printf("Data sent"); wait_us(3); for(i = 0; i < 9; i++) { spi_ivta.write(txrx[i]); wait_us(3); } wait_us(3); IVTA_SS = 1; /* Note: we ignore the packet sent by the IVT-A during this communication phase. Similarly, we only receive data in the next phase. Essentially we run the IVT-A in half-duplex mode. */ wait_us(500); // Wait between packets IVTA_SS = 0; // Activate IVT-A and receive packet. wait_us(3); for(i = 0; i < 9; i++) { txrx[i] = spi_ivta.write(0x00); // Write some dummy data(half duplex) wait_us(3); } wait_us(3); IVTA_SS = 1; return 0; } /* Initialise IVT-A. Write configuration: + Current in 300A range measured on channel A. + Temperature measured on channel B (currently unused). + Average data over 10 samples. */ int ivta_init(void) { IVTA_SS = 1; spi_ivta.format(8,0); // The format works for 0 or 1, most of testing done with 0 spi_ivta.frequency(500000); /* The last 2 bytes of the package are the CRC check, upper 4 bits in the command are the command code */ int transfer; uint8_t packet[9] = {0x90,1,5,200,0,0,0,0x78,0xB8}; //if (DEBUG) printf("Calculated init crc is %x ", calculate_IVTA_crc(packet)); transfer = ivta_transfer(packet); return transfer; } bool ivta_get_current(int32_t ¤t) //returns true if crc check succeeded, false otherwise { //printf("In get current \r \n"); //int r_val; uint8_t packet[9] = {0x10,1,0,0,0,0,0,0x0B,0x10}; // Command code 1. //printf("Calculated current crc is %x ", calculate_IVTA_crc(packet)); //printf("In get current \r \n"); int r_val = ivta_transfer(packet); /* printf("Packet1 : %d \r", packet[1]); printf("Packet1 : %d \r", packet[2]); printf("Packet1 : %d \r", packet[3]); printf("Packet1 : %d \r", packet[4]);*/ uint8_t measurements[6]; uint8_t received_crc_bytes[2]; measurements[0] = packet[1]; // Must shift the index of the packet measurements[1] = packet[2]; measurements[2] = packet[3]; measurements[3] = packet[4]; measurements[4] = packet[5]; measurements[5] = packet[6]; received_crc_bytes[0] = packet[7]; received_crc_bytes[1] = packet[8]; uint16_t calculated_crc = calculate_IVTA_crc(packet); //printf("calculated current crc is %x \r\n", calculated_crc); uint16_t received_crc = (uint16_t) received_crc_bytes[0]; received_crc |= (uint16_t) received_crc_bytes[1] <<8; //printf("received current crc is %x \r\n", received_crc); /*for (int i = 0; i < 6; ++i) { printf ("Current measurements %d is %d \r\n", i, measurements[i]); }*/ if (calculated_crc == received_crc) { uint32_t unsigned_current = ((uint32_t)measurements[0]); unsigned_current = unsigned_current | (((uint32_t)measurements[1]<<8)); unsigned_current = unsigned_current | (((uint32_t)measurements[2]<<16)); if(measurements[2] & 0x80){ //For some reason converting using 2's complement ¯\_(ツ)_/¯ uint32_t convertedData = ((~unsigned_current) + 1) & 0x00FFFFFF; int32_t convertedData2 = (~convertedData)+1; if (DEBUG) printf("*** Signed IVT-A Current measurement value: %d *** \r \n",convertedData2); current = convertedData2; } else{ if (DEBUG) printf("*** Unsigned IVT-A Current measurement value: %d *** \r \n", (int32_t)unsigned_current); current = unsigned_current; } return true; } else return false; } void ivta_reset_Ah_meter() { //sets Ah meter to zero uint8_t packet[9] = {0xA0,0x01,0x00,0x00,0x00,0x00,0x00,0xBA,0xDB}; // Command code 10. ivta_transfer(packet); } bool ivta_read_Ah_meter(float &Ah) { //return Ah meter reading in units of Ah uint8_t packet[9] = {0x50,0x01,0x00,0x00,0x00,0x00,0x00,0x4A,0xD4}; // Command code 5. //printf("Calculated read_Ah crc is %x ", calculate_IVTA_crc(packet)); ivta_transfer(packet); uint8_t measurements[6]; uint8_t received_crc_bytes[2]; measurements[0] = packet[1]; // Must shift the index of the packet measurements[1] = packet[2]; measurements[2] = packet[3]; measurements[3] = packet[4]; measurements[4] = packet[5]; measurements[5] = packet[6]; received_crc_bytes[0] = packet[7]; received_crc_bytes[1] = packet[8]; uint16_t calculated_crc = calculate_IVTA_crc(packet); uint16_t received_crc = (uint16_t) received_crc_bytes[0]; received_crc |= (uint16_t) received_crc_bytes[1] <<8; /*for (int i = 0; i < 6; ++i) { printf ("Ah Measurements %d is %d \r\n", i, measurements[i]); }*/ if (received_crc == calculated_crc) { uint64_t mAs = ((uint64_t)measurements[0]); mAs = mAs | (((uint64_t)measurements[1]<<8)); mAs = mAs | (((uint64_t)measurements[2]<<16)); mAs = mAs | (((uint64_t)measurements[3]<<24)); mAs = mAs | (((uint64_t)measurements[4]<<32)); mAs = mAs | (((uint64_t)measurements[5]<<40)); if(measurements[5] & 0x80){ //For some reason converting using 2's complement ¯\_(ツ)_/¯ uint64_t convertedData = ((~mAs) + 1) & 0x0000FFFFFFFFFFFF; uint64_t convertedData2 = (~convertedData)+1; Ah = convertedData2/(1000.0*3600); if(DEBUG) printf("*** Signed IVT-A Ah measurement value: %f *** \r \n",Ah); } else{ Ah = mAs /(1000.0*3600); if(DEBUG) printf("*** Unsigned IVT-A Ah measurement value: %f *** \r \n", Ah); } return true; } else return false; } uint16_t calculate_IVTA_crc(uint8_t data[]) { uint16_t crc = 0xFFFF; for (int i = 0; i < 7; ++i) { crc = crc16_update(crc, data[i]); } return crc; } uint16_t crc16_update(uint16_t crc, uint8_t a) { crc ^= a; for (int i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } return crc; }