req

Dependents:   BMS_BMUCore_Max_DummyData BMS_BMUCore_Max

Fork of LTC6804 by Max Vigdorchik

Cell_Voltage.cpp

Committer:
DasSidG
Date:
2017-09-16
Revision:
9:1c94bbb97eaa
Parent:
8:e3a5393dfbac

File content as of revision 9:1c94bbb97eaa:

//#include "SPI_Parser.h"
#include "mbed.h"
#include "CAN_Data.h"
#include "CAN_IDs.h"
#include <stdlib.h>
#include "Cell_Voltage.h"

//Define SoC ALCC digital in pins might be necessary as a setup, testing needed
//DigitalIn alcc(p20);
//Timer t;

/**
* Sets the values of the cellvoltage array with units 100 uV from all of the CMUs
* Uses the NO_CMUS parameter for the first dimension of cellcodes
* @param cellcodes[NO_CMUS][12] Will hold the voltage values for every cell in uV.
*/
void LTC6804_acquireVoltage(uint16_t cellcodes [][12])
{
    //This code seems to have had an error for multiple CMUs in writing the config.
    //The "write" array is being changed, but this is untested, revert change 
    //if necessary
    uint8_t write [1][6];
    write[0][0]=0x00;
    write[0][1]=0x00;
    write[0][2]=0x00;
    write[0][3]=0x00;
    write[0][4]=0x00;
    write[0][5]=0x00;
    
    LTC6804_init(MD_FAST, DCP_DISABLED, CELL_CH_ALL, AUX_CH_VREF2);
    /*uint8_t write [NO_CMUS][6];
    for(int i = 0; i < NO_CMUS; i++)
        for(int j = 0; j < 6; j++)
            write[i][j] = 0x00;
    }*/
    //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);
    //spi.frequency(spiBitrate);
     wake_LTC6804();//ensures CMU's are in ready state and wakes it up from low power mode
     LTC6804_wrcfg(NO_CMUS,write);
     wait_us(330);
     wake_LTC6804(); //This might need to be removed
     LTC6804_acquireVoltageTx();
     wait_us(930);
     LTC6804_acquireAllVoltageRegRx(0, NO_CMUS, cellcodes);   
}

/**
Sets the balancing transistors by adjusting the configuration states of the 
LTC6804. This version of the function writes all 12 states for a chosen 
transistor. If other forms end up being more useful I will add other overloaded
versions.
 
@param uint8_t ic The specific IC to write to (can be changed in favor of a 
states array of size 12*total_ic if preferred)
 
@param uint8_t states[12] For Sn in S1-S12 set states[n-1] to 1 to enable 
balancing and 0 to disable balancing.
*/
void LTC6804_balance(uint8_t ic, uint8_t states[12])
{
        uint8_t total_ic = NO_CMUS;
        //Consider using this to define the configs: (uint8_t *)malloc(total_ic*sizeof(uint8_t));
        uint8_t r_config[total_ic][8];
        uint8_t w_config[total_ic][6];//Size is smaller because there aren't PEC codes
        wake_LTC6804();
        wait_us(330);
        LTC6804_rdcfg(total_ic, r_config); 
        
        /*for (int i=0; i<8; i++) {
            printf("TEST %d config \r\n", (uint8_t)r_config[0][i]); 
        } */
        
        uint8_t cfgr4 = 0; //This entire configuration is DCC states
        uint8_t cfgr5 = r_config[ic][5];
        
        for(int i = 0; i < 8; i++)
        {
               //Note: This disgusting thing is written by someone who has not used c++ in a long time
               cfgr4 = states[i] ? cfgr4 | (1u << i) : cfgr4 & ~(1u << i);
        }
        
        for(int i = 8; i < 12; i++)
        {
               cfgr5 = states[i] ? cfgr5 | (1u << (i-8)) : cfgr5 & ~(1u << (i-8));
        }
        
        //printf("cfgr4 %d \r\n", (uint8_t)cfgr4);
        //printf("cfgr5 %d \r\n", (uint8_t)cfgr5);
        for(int i =0 ; i < total_ic; i++)
        {
           for(int j = 0; j < 6; j++)
            {
                w_config[i][j] = r_config[i][j];   
            }   
        }
        w_config[ic][4] = cfgr4;
        w_config[ic][5] = cfgr5;
        
        wake_LTC6804();
        wait_us(330);
        LTC6804_wrcfg(total_ic,w_config); //Make sure this is written in the write order
}
/**
Takes a set of voltages corresponding to cell voltage measurements and a voltage
limit (presumably 4200 mV) and then drains all cells as needed. If current state
of balancing is needed outside of this function, it can be modified.

Current implementation of this function just uses the hard limit, so it might end
up constantly enabling and disabling balancing as it hits the limit then goes under.
That behavior can be improved upon if needed. One idea is to use derivative of
voltage with time to predict when it will hit maxVoltage so there is no risk of 
going over, or allow them to drain such that all of the cells are at the same voltage.

@param uint16_t voltages[][12] Measured voltages to be used for deciding what to
balance. The dimensions must be [total_ic][12].

@param uint16_t maxVoltage voltage limit for the cells 
*/
void LTC6804_balanceVoltage(uint16_t voltages[][12], uint16_t maxVoltage)
{
        uint8_t total_ic = NO_CMUS;
        //Consider making states a parameter as a pointer so it can be referenced outside of the function easier.
        uint8_t states[total_ic][12];
        for(int i = 0; i < total_ic; i++)
        {
            for(int j = 0; j < 12; j++)
            {
                states[i][j] = voltages[i][j] >= maxVoltage ? 1 : 0; //Not sure if ternary operator is needed in C.    
            }
            LTC6804_balance(i, states[i]);    
        }
}