This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BQ76952: Issues in Charge Mosfet while enabling protection.

Part Number: BQ76952

Greetings,

I am enabling Protections ,Chg protection, Dsg protection and configuring the thresholds related to OCC , while breaching the threshold the charge MOSFET is turning OFF and ON continuously unless it is disconnected from the Power supply, when we disconnect from the power supply the Charge and Discharge Mosfet is turned ON and We don't observe the charge Mosfet to be turned OFF continuously the charge FET is keep on toggling.

  • Where in the case of COV we observe the charge MOSFET to be turned ON even when the protection is breached ,so we doubted the charge Mosfet and called the CHG_PCHG_OFF() and FET_CONTROL() by setting the bit to turn OFF the charge Fet but we don't observe the turning OFF of the Fet ,when we tried to call ALL_FETS_OFF function at that time the charge Fet is turned OFF and we assume that charge FET is operating normal.
  • What are the necessary actions to be taken to turn on Precharge , Charge and other Mosfets separately.
  • I have attached my C code and wanted to make sure I'm writing my thresholds and registers in right way.

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>© Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include<stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define DEV_ADDR 0x10    // Device address
#define CRC_Mode  0  // 0 for disabled, 1 for enabled
#define MAX_BUFFER_SIZE     10  //Max buffer size
//#define DEBUG_RX_DO_Pin GPIO_PIN_10
//#define DEBUG_RX_DO_GPIO_Port GPIOA
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
uint8_t spiData [2];
uint8_t spiRxData [2];
uint8_t rxdata [2];
uint8_t busyData [2] = {0xFF, 0xFF};
uint8_t TX_1Byte_P[14] = {0x78, 0x7B, 0x75, 0x7c, 0x82, 0x84, 0x8A, 0x80, 0x86, 0x87, 0xA0, 0xA2, 0xA3, 0xA5};
uint8_t TX_Byte_data[14] = {0x51, 0x4F, 0x44, 0x55, 0x12, 0x15, 0x38, 0x07, 0x46, 0x21, 0x5A, 0x4B, 0x2D, 0x28};
                              //COV  0x51            //COVR            //CUV 0x44 0x48  //CUV release      //OCD1            //OCD2             //OCD3           //OCC              //SCD             //SCD Delay   //OT Fet           //OT Fet rec       //OT Init      //OT Init release
uint8_t TX_Byte_arr[15][3] ={{0x78,0x92,0x51}, {0x7B,0x92,0x02}, {0x75,0x92,0x3D}, {0x7C,0x92,0x02}, {0x82,0x92,0x12}, {0x84,0x92,0x15}, {0x8A,0x92,0x38}, {0x80,0x92,0x02}, {0x86,0x92,0x46}, {0x87,0x92,0x21}, {0xA0,0x92,0x5A}, {0xA2,0x92,0x4B}, {0xA3,0x92,0x2D},{0xA1,0x92,0x02}, {0xA5,0x92,0x28}} ;
uint8_t TX_2Byte [2] = {0x00, 0x00};
uint8_t TX_3Byte [3] = {0x00, 0x00, 0x00};
uint8_t TX_4Byte [4] = {0x00, 0x00, 0x00, 0x00};
uint8_t TX_6Byte [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t TX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

uint8_t RX_2Byte [2] = {0x00, 0x00};
uint8_t RX_3Byte [3] = {0x00, 0x00, 0x00};
uint8_t RX_4Byte [4] = {0x00, 0x00, 0x00, 0x00};
uint8_t RX_6Byte [6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t RX_12Byte [12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t RX_32Byte [32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00 ,0x00, 0x00, 0x00, 0x00,0x00, 0x00};
uint8_t RX_Buffer [MAX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned int RX_CRC_Check = 0;
// Variables for cell voltages, temperatures, CC2 current, Stack voltage, PACK Pin voltage, LD Pin voltage
uint16_t CellVoltage [16] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
float Temperature [3] = {0,0,0};
float FET_Temperature = 0;
float HDQ_Temp = 0;
float DCHG_Temp = 0;
float DDSG_Temp = 0;
uint16_t result_bin = 0;
uint16_t Stack_Voltage = 0x00;
uint16_t LD_Voltage = 0x00;
uint16_t PACK_Voltage = 0x00;
uint16_t PACK_Current = 0x00;
float Current = 0;
uint16_t AlarmBits = 0x00;
uint32_t Samp1[2] ={0x00, 0x00};
uint32_t Res = 0;
uint32_t Min_cell = 0;
uint32_t Battery_voltage_sum = 0;
uint32_t Avg_cell_temp = 0;
uint32_t Fet_temp = 0;
uint32_t Max_cell_temp = 0;
uint32_t Min_cell_temp = 0;
uint32_t Avg_min_max_temp = 0;
uint32_t Max_cell = 0;
uint32_t CC3_Current;
uint32_t CC1_Current;
uint32_t Raw_CC2_Count;
uint32_t Raw_CC3_Count;
char hex_num[10];
char Val[100];
uint8_t SafetyStatusA;  // Safety Status Register A
uint8_t SafetyStatusB;  // Safety Status Register B
uint8_t SafetyStatusC;  // Safety Status Register C
uint8_t PFStatusA;   // Permanent Fail Status Register A
uint8_t PFStatusB;   // Permanent Fail Status Register B
uint8_t PFStatusC;   // Permanent Fail Status Register C
uint8_t FET_Status;  // FET Status register contents See TRM Section 12.2.20  - Shows states of FETs
uint8_t Alert_B;
uint8_t OTF = 0;
uint16_t CB_ActiveCells;  // Cell Balancing Active Cells
uint16_t DEVICE_NUMBER;

uint8_t	UV_Fault = 0;   // under-voltage fault state
uint8_t	OV_Fault = 0;   // over-voltage fault state
uint8_t	SCD_Fault = 0;  // short-circuit fault state
uint8_t	OCD_Fault = 0;  // over-current fault state
uint8_t OCC_Fault = 0;
uint8_t OTF_Fault = 0;
uint8_t LD_ON = 0;							// Load Detect status bit
uint8_t DCHG = 0;   // discharge FET state
uint8_t CHG = 0;   // charge FET state
uint8_t PCHG = 0;  // pre-charge FET state
uint8_t PDSG = 0;  // pre-discharge FET state
uint8_t DDSG = 0;
uint32_t AccumulatedCharge_Int;
uint32_t AccumulatedCharge_Frac;
uint32_t AccumulatedCharge_Time;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_TIM1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
void delayUS(uint32_t us) {   // Sets the delay in microseconds.
	//uint8_t tim = 0;
	__HAL_TIM_SET_COUNTER(&htim1,0);  // set the counter value a 0
	while (__HAL_TIM_GET_COUNTER(&htim1) < us);
}

void delay_ticks(uint32_t ticks)
{
    SysTick->LOAD = ticks;
    SysTick->VAL = 0;
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
    // COUNTFLAG is a bit that is set to 1 when counter reaches 0.
    // It's automatically cleared when read.
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
    SysTick->CTRL = 0;
}

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
        dest[copyIndex] = source[copyIndex];
    }
}

unsigned char Checksum(unsigned char *ptr, unsigned char len)
	// Calculates the checksum when writing to a RAM register. The checksum is the inverse of the sum of the bytes.
{
	unsigned char i;
	unsigned char checksum = 0;

	for(i=0; i<len; i++)
		checksum += ptr[i];

	checksum = 0xff & ~checksum;

	return(checksum);
}



unsigned char CRC8(unsigned char *ptr, unsigned char len)
{
	unsigned char i;
	unsigned char crc=0;
	while(len--!=0)
	{
		for(i=0x80; i!=0; i/=2)
		{
			if((crc & 0x80) != 0)
			{
				crc *= 2;
				crc ^= 0x107;
			}
			else
				crc *= 2;

			if((*ptr & i)!=0)
				crc ^= 0x107;
		}
		ptr++;
	}
	return(crc);
}

void I2C_WriteReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
		#if CRC_Mode
		{
		uint8_t crc_count = 0;
		crc_count = count * 2;
		uint8_t crc1stByteBuffer [3] = {0x10, reg_addr, reg_data[0]};
		unsigned int j;
		unsigned int i;
		uint8_t temp_crc_buffer [3];

		TX_Buffer[0] = reg_data[0];
		TX_Buffer[1] = CRC8(crc1stByteBuffer,3);

		j = 2;
		for(i=1; i<count; i++)
		{
			TX_Buffer[j] = reg_data[i];
			j = j + 1;
			temp_crc_buffer[0] = reg_data[i];
			TX_Buffer[j] = CRC8(temp_crc_buffer,1);
			j = j + 1;
		}
		HAL_I2C_Mem_Write(&hi2c1, DEV_ADDR, reg_addr, 1, TX_Buffer, count, 1000);
		}
		#endif

		#if CRC_Mode < 1
		 HAL_StatusTypeDef state = HAL_OK;
		state=HAL_I2C_Mem_Write(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
		if(state != HAL_OK)
				{

				}
		#endif
}


int I2C_ReadReg(uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
	unsigned int RX_CRC_Fail = 0;  // reset to 0. If in CRC Mode and CRC fails, this will be incremented.

	#if CRC_Mode
	{
		uint8_t crc_count = 0;
		uint8_t ReceiveBuffer [10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
		crc_count = count * 2;
		unsigned int j;
		unsigned int i;
		unsigned char CRCc = 0;
		uint8_t temp_crc_buffer [3];

		HAL_I2C_Mem_Read(&hi2c1, DEV_ADDR, reg_addr, 1, ReceiveBuffer, crc_count, 1000);
		uint8_t crc1stByteBuffer [4] = {0x10, reg_addr, 0x11, ReceiveBuffer[0]};
		CRCc = CRC8(crc1stByteBuffer,4);
		if (CRCc != ReceiveBuffer[1])
			RX_CRC_Fail += 1;

		RX_Buffer[0] = ReceiveBuffer[0];

		j = 2;
		for (i=1; i<count; i++)
		{
			RX_Buffer[i] = ReceiveBuffer[j];
			temp_crc_buffer[0] = ReceiveBuffer[j];
			j = j + 1;
			CRCc = CRC8(temp_crc_buffer,1);
			if (CRCc != ReceiveBuffer[j])
				RX_CRC_Fail += 1;
			j = j + 1;
		}
		CopyArray(RX_Buffer, reg_data, crc_count);
	}
	#endif

	#if CRC_Mode < 1
	// HAL_StatusTypeDef state = HAL_OK;
		 HAL_I2C_Mem_Read(&hi2c1, DEV_ADDR, reg_addr, 1, reg_data, count, 1000);
		//if(state != HAL_OK)
		//{

		//}
	#endif

	  return 0;
}

int Dec_to_Bin(int n){
	int binaryNum[32];
	 int Convert_Num[32];
	    // counter for binary array
	    int i = 0;
	    while (n > 0) {

	        // storing remainder in binary array
	        binaryNum[i] = n % 2;
	        n = n / 2;
	        i++;
	    }

	    // printing binary array in reverse order
	    for (int j = i - 1; j >= 0; j--)
	    {

	    	Convert_Num[j] = binaryNum[j];
	    }
	    	int k;
	    	    for (k = 16-1 ; k >= 0 ; k--)
	    	        if (Convert_Num[k] == '1')
	    	            break;

	    	    // If there exists no '1' concatenate 1 at the
	    	    // starting of string
	    	    if (k == -1)
	    	        return '1' + Convert_Num;

	    	    // Continue traversal after the position of
	    	    // first '1'
	    	    for (int j = k-1 ; j >= 0; j--)
	    	    {
	    	        //Just flip the values
	    	        if (Convert_Num[j] == '1')
	    	        	Convert_Num[j] = '0';
	    	        else
	    	        	Convert_Num[j] = '1';
	    	    }

	    	return Convert_Num;

}
void AFE_Reset() {
	// Reset command. Resets all registers to default values or the values programmed in OTP.
	TX_2Byte[0] = 0x12; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_Init() {
	// Configures all parameters in device RAM

	// Enter CONFIGUPDATE mode (Subcommand 0x0090) - It is required to be in CONFIG_UPDATE mode to program the device RAM settings
	// See TRM Section 7.6 for full description of CONFIG_UPDATE mode
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);

	delayUS(2000);

	// After entering CONFIG_UPDATE mode, RAM registers can be programmed. When programming RAM, checksum and length must also be
	// programmed for the change to take effect. All of the RAM registers are described in detail in Chapter 13 of the BQ76952 TRM.
	// An easier way to find the descriptions is in the BQStudio Data Memory screen. When you move the mouse over the register name,
	// a full description of the register and the bits will pop up on the screen.
	// A summary of the Data Memory is also in Section 13.9 of the TRM.

	// 'Power Config' - Set DSLP_LDO  - 0x9234 = 0x2D82  (See TRM section 13.3.2)
	// Setting the DSLP_LDO bit allows the LDOs to remain active when the device goes into Deep Sleep mode
  TX_4Byte[0] = 0x34; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x82; TX_4Byte[3] = 0x2D;
  I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// 'REG0 Config' - set REG0_EN bit to enable pre-regulator
	TX_3Byte[0] = 0x37; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// 'REG12 Config' - Enable REG1 with 3.3V output
	TX_3Byte[0] = 0x36; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0D;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// 'VCell Mode' - Enable 16 cells - 0x9304 = 0x0000  (See TRM section 13.3.2.19)
	// 0x0000 sets the default value of 16 cells.
  TX_4Byte[0] = 0x04; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
  I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// 'Default Alarm Mask' - Enable FullScan and ADScan bits
	// 0xF882
  TX_4Byte[0] = 0x6D; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x82; TX_4Byte[3] = 0xF8;
  I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Enable protections in 'Enabled Protections A' 0x9261 = 0xBC (See TRM section 13.3.3.2)
	// Enables SCD (short-circuit), OCD1 (over-current in discharge), OCC (over-current in charge),
	// COV (over-voltage), CUV (under-voltage)
	TX_3Byte[0] = 0x61; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xFC;  //0xFC
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Enable all protections in 'Enabled Protections B' 0x9262 = 0xF7 (See TRM section 13.3.3.3)
	// Enables OTF (over-temperature FET), OTINT (internal over-temperature), OTD (over-temperature in discharge),
	// OTC (over-temperature in charge), UTINT (internal under-temperature), UTD (under-temperature in discharge), UTC (under-temperature in charge)
	TX_3Byte[0] = 0x62; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xF7;  //0xF7
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Charge fet protection A
			TX_3Byte[0] = 0x65; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x98;  //0xF7
			  I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
			  I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

		//Charge fet protection B
		TX_3Byte[0] = 0x66; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xD5;  //0xF7
		  I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		  I2C_WriteReg(0x60, TX_2Byte, 2);
			delayUS(1000);

#if 1
	// Set TS1 to measure Cell Temperature - 0x92FD = 0x07   (See TRM Section 13.3.2.12)
	TX_3Byte[0] = 0xFD; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x07;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Set TS3 to measure FET Temperature - 0x92FF = 0x0F   (See TRM Section 13.3.2.14)
	TX_3Byte[0] = 0xFF; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0F;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);
#endif
#if 1
	// Set DFETOFF pin to control BOTH CHG and DSG FET - 0x92FB = 0x42 (set to 0x00 to disable)
	// See TRM section 13.3.2.10, Table 13-7
#if 0
	TX_3Byte[0] = 0xFB; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xC2;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);
#endif
	// Set up Alert Pin - 0x92FC = 0x2A  - See TRM Section 13.3.2.11, Table 13-8
	// This configures the Alert pin to drive high (REG1 voltage) when enabled.
	// Other options available include active-low, drive HiZ, drive using REG18 (1.8V), weak internal pull-up and pull-down
	TX_3Byte[0] = 0xFC; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x2A;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);
#endif

#if 0
	// Set up Cell Balancing Configuration - 0x9335 = 0x03   -  Automated balancing while in Relax or Charge modes
	// See TRM Section 13.3.11. Chapter 10 of TRM describes Cell Balancing in detail
	// Also see "Cell Balancing with BQ76952, BQ76942 Battery Monitors" document on ti.com
	TX_3Byte[0] = 0x35; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x03;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Set up COV (over-voltage) Threshold - 0x9278 = 0x55 (4301 mV)
	// COV Threshold is this value multiplied by 50.6mV  See TRM section 13.6.2
	TX_3Byte[0] = 0x78; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x55;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Set up SCD Threshold - 0x9286 = 0x05 (100 mV = 100A across 1mOhm sense resistor)
	// See TRM section 13.6.7    0x05=100mV
	TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x05;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Set up SCD Delay - 0x9287 = 0x03 (30 us)    See TRM section 13.6.7
	// Units of 15us
	TX_3Byte[0] = 0x87; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x03;
  I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// Set up SCDL Latch Limit to 1 to set SCD recovery only with load removal 0x9295 = 0x01
	// If this is not set, then SCD will recover based on time (SCD Recovery Time parameter).
	// See TRM section 13.6.11.1
	TX_3Byte[0] = 0x95; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);
#endif
#if 0
	//CUV
	TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x3D;
			I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
			I2C_WriteReg(0x60, TX_2Byte, 2);
			delayUS(1000);
	//CUV recovery hystersis
			TX_3Byte[0] = 0x7B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02;
						I2C_WriteReg(0x3E, TX_3Byte, 3);
						delayUS(1000);
						TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
						I2C_WriteReg(0x60, TX_2Byte, 2);
						delayUS(1000);

						//OCC
						TX_3Byte[0] = 0x80; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x03; //; 0x4B;
						I2C_WriteReg(0x3E, TX_3Byte, 3);
						delayUS(1000);
						TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
						I2C_WriteReg(0x60, TX_2Byte, 2);
						delayUS(1000);

						//OCC delay
						TX_3Byte[0] = 0x81; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x7F;
						I2C_WriteReg(0x3E, TX_3Byte, 3);
						delayUS(1000);
						TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
						I2C_WriteReg(0x60, TX_2Byte, 2);
						delayUS(1000);

						//Recovery Common
						TX_3Byte[0] = 0xAF; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x09; //; 0x4B;
						I2C_WriteReg(0x3E, TX_3Byte, 3);
						delayUS(1000);
						TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
						I2C_WriteReg(0x60, TX_2Byte, 2);
						delayUS(1000);
#if 0
						//OCD1
						TX_3Byte[0] = 0x82; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02; //; 0x4B;
						I2C_WriteReg(0x3E, TX_3Byte, 3);
						delayUS(1000);
						TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
						I2C_WriteReg(0x60, TX_2Byte, 2);
						delayUS(1000);

						//OCD Recovery
						TX_4Byte[0] = 0x8D; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0xE8; TX_4Byte[3] = 0x03;
						  I2C_WriteReg(0x3E, TX_4Byte, 4);
							delayUS(1000);
							TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
						  I2C_WriteReg(0x60, TX_2Byte, 2);
							delayUS(1000);
#endif
							//SCD
							TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00; //; 0x4B;
							I2C_WriteReg(0x3E, TX_3Byte, 3);
							delayUS(1000);
							TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
							I2C_WriteReg(0x60, TX_2Byte, 2);
							delayUS(1000);
#endif

#if 1
	// precharge start V
	TX_4Byte[0] = 0x0A; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0xB8; TX_4Byte[3] = 0x0B; // 0x48 0xF4
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// precharge stop V
	TX_4Byte[0] = 0x0C; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x1C; TX_4Byte[3] = 0x03;  //0x1C F3;
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	// predischarge time out
	TX_3Byte[0] = 0x0E; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x00;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//predischarge stop delta
	TX_3Byte[0] = 0x0F; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x00;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//discharge current threshold
	TX_4Byte[0] = 0x10; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x64; TX_4Byte[3] = 0x00;  //0xE2; 0xFF
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	// HAL_Delay(1);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//charge current threshold
	TX_4Byte[0] = 0x12; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x32; TX_4Byte[3] = 0x00; //0xF6 0xFF;
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	// HAL_Delay(1);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

#endif
// Maufcturing status init
	TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x50; TX_4Byte[3] = 0x00;
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	// HAL_Delay(1);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

//Fet options
	TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0F;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Protection config
	TX_4Byte[0] = 0x5F; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
		I2C_WriteReg(0x3E, TX_4Byte, 4);
		delayUS(1000);
		// HAL_Delay(1);
		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);

		//Discharg protection A
		TX_3Byte[0] = 0x69; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xE4;
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);
//COVL
		TX_3Byte[0] = 0x7E; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x02;
			I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
			I2C_WriteReg(0x60, TX_2Byte, 2);
			delayUS(1000);
		//Discharg protection B
		TX_3Byte[0] = 0x6A; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0xE6;
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);

		//Discharg protection C
		TX_3Byte[0] = 0x6B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);

		//Body diode
		TX_4Byte[0] = 0x73; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0xEC; TX_4Byte[3] = 0xFF;
				I2C_WriteReg(0x3E, TX_4Byte, 4);
				delayUS(1000);
				// HAL_Delay(1);
				TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

		//CC Gain
				TX_6Byte[0] = 0xA8; TX_6Byte[1] = 0x91; TX_6Byte[2] = 0xF2; TX_6Byte[3] = 0x41; TX_6Byte[4] = 0x6F; TX_6Byte[5] = 0x41;
				  I2C_WriteReg(0x3E, TX_6Byte, 6);
				  delayUS(1000);
				  TX_2Byte[0] = Checksum(TX_6Byte, 6); TX_2Byte[1] = 0x08;  // Checksum and Length
				  I2C_WriteReg(0x60, TX_2Byte, 2);
				  delayUS(1000);

			//HDQ config
				TX_3Byte[0] = 0x00; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0F; //0x0B;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

				//DCHG thermistor config
				TX_3Byte[0] = 0x01; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0F; //0x0B;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);
#if 1
				//TS1 temp offset
				TX_3Byte[0] = 0xCE; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

				//TS3 temp offset
				TX_3Byte[0] = 0xD0; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

				//HDQ temp offset
				TX_3Byte[0] = 0xD1; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

				//DCHG temp offset
				TX_3Byte[0] = 0xD2; TX_3Byte[1] = 0x91; TX_3Byte[2] = 0x19;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);

#endif
#if 0
				//Data Status
				TX_2Byte[0] = 0x76; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
				delayUS(1000);
				I2C_ReadReg(0x40, RX_12Byte, 12);
				CC3_Current = (RX_12Byte[21]<<8) + (RX_12Byte[20]);
				CC1_Current = (RX_12Byte[23]<<8) + (RX_12Byte[22]);
				Raw_CC2_Count = ((RX_12Byte[27]<<24) + (RX_12Byte[26]<<16) + (RX_12Byte[25]<<8) + RX_12Byte[24]);
				Raw_CC3_Count = ((RX_12Byte[31]<<24) + (RX_12Byte[30]<<16) + (RX_12Byte[29]<<8) + RX_12Byte[28]);
				delayUS(1000);
#endif
#if 0
				//TS3
				TX_3Byte[0] = 0xFF; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);
				//TS1
				TX_3Byte[0] = 0xFD; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x0B;
				I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
				I2C_WriteReg(0x60, TX_2Byte, 2);
				delayUS(1000);
#endif


#if 0
//******** Manufacturing Status******//
		 TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x50; TX_4Byte[3] = 0x00;
		  I2C_WriteReg(0x3E, TX_4Byte, 4);
			delayUS(1000);
		 // HAL_Delay(1);
			TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
		  I2C_WriteReg(0x61, TX_2Byte, 2);
		  delayUS(1000);
//*********************************//
//******Fet options***************//
		  TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x1F;
		  	  I2C_WriteReg(0x3E, TX_3Byte, 3);
		  		delayUS(1000);
		  		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		  	  I2C_WriteReg(0x60, TX_2Byte, 2);
		  	  delayUS(1000);
//*********************************//
//**************All fets On*************//
		  	TX_2Byte[0] = 0x96; TX_2Byte[1] = 0x00;
		  		I2C_WriteReg(0x3E,TX_2Byte,2);
		  		 delayUS(1000);
//***************************************//
		  		AFE_ReadFETStatus();
#endif
	// Exit CONFIGUPDATE mode  - Subcommand 0x0092
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	delayUS(1000);
}
#if 0
void AFE_Protection_Thresholds()
{
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	//Cell OV
	TX_3Byte[0] = 0x78; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x51;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Cell ov Release
	TX_3Byte[0] = 0x7B; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4F;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Cell UV
	TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x44;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Cell UV Release
	TX_3Byte[0] = 0x7C; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x55;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//OCD1
	TX_3Byte[0] = 0x82; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x12;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//OCD2
	TX_3Byte[0] = 0x84; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x15;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//OCD3
	TX_4Byte[0] = 0x8A; TX_4Byte[1] = 0x92; TX_4Byte[2] = 0x38; TX_4Byte[3] = 0x00;
	I2C_WriteReg(0x3E, TX_4Byte, 4);
	delayUS(1000);
	// HAL_Delay(1);
	TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	I2C_WriteReg(0x61, TX_2Byte, 2);
	delayUS(1000);

	//OCC
	TX_3Byte[0] = 0x80; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x07;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//SCD
	TX_3Byte[0] = 0x86; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x46;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//SCD Delay
	TX_3Byte[0] = 0x87; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x21;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Fet temp
	TX_3Byte[0] = 0xA0; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x5A;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Fet temp release
	TX_3Byte[0] = 0xA2; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4B;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Internal temp
	TX_3Byte[0] = 0xA3; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x2D;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);

	//Internal temp release
	TX_3Byte[0] = 0xA5; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x28;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);
	delayUS(1000);
}
#endif

void Protections_AFE(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);

	for(int i=0; i<15; i++)
	{
	TX_3Byte[0] = TX_1Byte_P[i]; TX_3Byte[1] = 0x92 ,TX_3Byte[2] = TX_Byte_data[i];
	I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);
	}

	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
			I2C_WriteReg(0x3E,TX_2Byte,2);
}
void Temp_protection(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
				delayUS(1000);
	//Fet temp
		TX_3Byte[0] = 0x75; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x48;
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);
#if 0
		//Fet temp release
		TX_3Byte[0] = 0xA2; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x4B;
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);
#endif
		TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
						I2C_WriteReg(0x3E,TX_2Byte,2);


}
void alert_protection_B(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
				delayUS(1000);

	I2C_ReadReg(0x04, RX_2Byte, 2);
	Alert_B = (RX_2Byte[1]*256 + RX_2Byte[0]);
	OTF = 0x8 & RX_2Byte[0];
	delayUS(1000);
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
}
void protect_AFE(){

	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
			I2C_WriteReg(0x3E,TX_2Byte,2);
			delayUS(1000);
	for(int i=0; i<16; i++)
	{
		for(int j =0 ; j<4 ; j++)
		{
			TX_3Byte[j] = TX_Byte_arr[i][j];
		}
		I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		I2C_WriteReg(0x60, TX_2Byte, 2);
		delayUS(1000);

	}
	delayUS(1000);
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
				I2C_WriteReg(0x3E,TX_2Byte,2);
}


void Enable_REG1()
{
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
		// 'REG0 Config' - set REG0_EN bit to enable pre-regulator
			TX_3Byte[0] = 0x37; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x01;
		  I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		  I2C_WriteReg(0x60, TX_2Byte, 2);
			delayUS(1000);

			// 'REG12 Config' - Enable REG1 with 3.3V output
			TX_3Byte[0] = 0x36; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x0D;
		  I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		  I2C_WriteReg(0x60, TX_2Byte, 2);
			delayUS(1000);
		  // Exit CONFIGUPDATE mode  - Subcommand 0x0092
		  	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
		  	I2C_WriteReg(0x3E,TX_2Byte,2);
		  	//delayUS(1000);

}

// ************************** Functions Written by Rohith********************//
void AFE_FETOptions(){
	TX_3Byte[0] = 0x08; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x1F;
	  I2C_WriteReg(0x3E, TX_3Byte, 3);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	  I2C_WriteReg(0x60, TX_2Byte, 2);
	  delayUS(1000);
}

void AFE_ManufacturingStatus(){

	 TX_4Byte[0] = 0x43; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x50; TX_4Byte[3] = 0x00;
	  I2C_WriteReg(0x3E, TX_4Byte, 4);
		delayUS(1000);
	 // HAL_Delay(1);
		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	  I2C_WriteReg(0x61, TX_2Byte, 2);
	  delayUS(1000);

}
void Manufacturing_Status_Read(){

}
void PDSG_TEST(){
	TX_2Byte[0] = 0x1C; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
}
void PCHG_TEST(){
	TX_2Byte[0] = 0x1E; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
}
void CHG_TEST(){
	TX_2Byte[0] = 0x1F; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
}
void DSG_TEST(){
	TX_2Byte[0] = 0x20; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
}
void Charge_Pump(){
	TX_3Byte[0] = 0x09; TX_3Byte[1] = 0x93; TX_3Byte[2] = 0x01;
		  I2C_WriteReg(0x3E, TX_3Byte, 3);
			delayUS(1000);
			TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
		  I2C_WriteReg(0x60, TX_2Byte, 2);
		  delayUS(1000);
}

void Comm_Type(){
	TX_3Byte[0] = 0x39; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x12;
			  I2C_WriteReg(0x3E, TX_3Byte, 3);
				delayUS(1000);
				TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
			  I2C_WriteReg(0x60, TX_2Byte, 2);
}

void Swap_Comm_Mode(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);


	TX_3Byte[0] = 0x39; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x12;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	//delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);

	TX_2Byte[0] = 0xBC; TX_2Byte[1] = 0x29;
	I2C_WriteReg(0x3E,TX_2Byte,2);

	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}
void Dfet_off(){

	TX_3Byte[0] = 0xFB; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);

}

void Cfet_off(){

	TX_3Byte[0] = 0xFA; TX_3Byte[1] = 0x92; TX_3Byte[2] = 0x00;
	I2C_WriteReg(0x3E, TX_3Byte, 3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
	I2C_WriteReg(0x60, TX_2Byte, 2);

}
void Status_Read(){
	uint8_t rd_data;
	TX_2Byte[0] = 0x57; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);
		delayUS(2000);
		I2C_ReadReg(0x40, RX_2Byte, 2);
		rd_data = (RX_2Byte[1]*256 + RX_2Byte[0]);
}
void Vcell(){
	 TX_4Byte[0] = 0x04; TX_4Byte[1] = 0x93; TX_4Byte[2] = 0x00; TX_4Byte[3] = 0x00;
	  I2C_WriteReg(0x3E, TX_4Byte, 4);
		delayUS(1000);
		TX_2Byte[0] = Checksum(TX_4Byte, 4); TX_2Byte[1] = 0x06;  // Checksum and Length
	  I2C_WriteReg(0x60, TX_2Byte, 2);
}
//**************** End *************//
//  ********************************* FET Control Commands  ***************************************

void AFE_FET_ENABLE() {
	// Toggles the FET_EN bit in the Manufacturing Status register. So this command can be used to enable or disable the FETs.
	TX_2Byte[0] = 0x22; TX_2Byte[1] = 0x00;   //0x22
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_FET_Control(uint8_t FET_states) {  // Bit3 = PCHG_OFF, Bit 2 = CHG_OFF, Bit1 = PDSG_OFF, Bit 0 = DSG_OFF
	TX_3Byte[0] = 0x97; TX_3Byte[1] = 0x00; TX_3Byte[2] = FET_states;
	I2C_WriteReg(0x3E,TX_3Byte,3);
	delayUS(1000);
	TX_2Byte[0] = Checksum(TX_3Byte, 3); TX_2Byte[1] = 0x05;
  I2C_WriteReg(0x60, TX_2Byte, 2);
}

void DSG_PDSG_OFF() {
	// Disable discharge (and pre-discharge) FETs
	// Subcommand 0x0093  See TRM Table 5-8  (DSG_PDSG_OFF())
	TX_2Byte[0] = 0x93; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void CHG_PCHG_OFF() {
	// Disable charge (and pre-charge) FETs
	// Subcommand 0x0094  See TRM Table 5-8  (CHG_PCHG_OFF())
	TX_2Byte[0] = 0x94; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_ALL_FETS_OFF() {
	// Disable all FETs with command 0x0095  See TRM Table 5-8
	TX_2Byte[0] = 0x95; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_ALL_FETS_ON() {
	// All all FETs to be enabled with command 0x0096  See TRM Table 5-8
	TX_2Byte[0] = 0x96; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_BOTHOFF () {
	// Disables all FETs using the DFETOFF (BOTHOFF) pin
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);  // DFETOFF pin (BOTHOFF) set low
}

void AFE_RESET_BOTHOFF () {
	// Resets DFETOFF (BOTHOFF) pin
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);  // DFETOFF pin (BOTHOFF) set low
}

void AFE_ReadFETStatus() {
	// Read FET Status to see which FETs are enabled
	I2C_ReadReg(0x7F, RX_2Byte, 2);
  FET_Status = (RX_2Byte[1]*256 + RX_2Byte[0]);
	DCHG = 0x4 & RX_2Byte[0];   // discharge FET state
	CHG = 0x1 & RX_2Byte[0];   // charge FET state
	PCHG = 0x2 & RX_2Byte[0];  // pre-charge FET state
	PDSG = 0x8 & RX_2Byte[0];  // pre-discharge FET state
	DDSG = 0x4 & RX_2Byte[1];
}


// ********************************* End of FET Control Commands *********************************


// ********************************* AFE Cell Balancing Commands   *****************************************

void CB_ACTIVE_CELLS() {
	// Check status of which cells are balancing
	TX_2Byte[0] = 0x83; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	I2C_ReadReg(0x40, RX_2Byte, 2);
  CB_ActiveCells = (RX_2Byte[1]*256 + RX_2Byte[0]);
}

void CFET_OFF_LO(){
	TX_2Byte[0] = 0x28; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E, TX_2Byte, 2);
}
void DFET_OFF_LO(){
	TX_2Byte[0] = 0x28; TX_2Byte[1] = 0x01;
		I2C_WriteReg(0x3E, TX_2Byte, 2);
}
// ********************************* End of AFE Cell Balancing Commands   *****************************************


// ********************************* AFE Power Commands   *****************************************
void AFE_DeepSleep() {
	// Puts the device into DEEPSLEEP mode. See TRM section 7.4
	TX_2Byte[0] = 0x0F; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_ExitDeepSleep() {
	// Exits DEEPSLEEP mode. See TRM section 7.4
	TX_2Byte[0] = 0x0E; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_ShutdownCommand() {
	// Puts the device into SHUTDOWN mode. See TRM section 7.5
	TX_2Byte[0] = 0x10; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_ShutdownPin() {
	// Puts the device into SHUTDOWN mode using the RST_SHUT pin
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);  // Sets RST_SHUT pin
}

void AFE_ReleaseShutdownPin() {
	// Releases the RST_SHUT pin
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);  // Resets RST_SHUT pin
}

void AFE_SLEEP_ENABLE() { // SLEEP_ENABLE 0x0099
	// Allows the device to enter Sleep mode if current is below Sleep Current. See TRM section 7.3
	TX_2Byte[0] = 0x99; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void AFE_SLEEP_DISABLE() { // SLEEP_DISABLE 0x009A
	// Takes the device out of sleep mode. See TRM section 7.3
	TX_2Byte[0] = 0x9A; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

// ********************************* End of AFE Power Commands   *****************************************


// ********************************* AFE Status and Fault Commands   *****************************************

uint16_t AFE_ReadAlarmStatus() {
	// Read this register to find out why the Alert pin was asserted. See section 6.6 of the TRM for full description.
	uint8_t Status = 0;
	I2C_ReadReg(0x62, RX_2Byte, 2);
	Status = (RX_2Byte[1]*256 + RX_2Byte[0]);
	return Status;
}

void AFE_ReadSafetyStatus() {
	// Read Safety Status A/B/C and find which bits are set
	// This shows which primary protections have been triggered
	I2C_ReadReg(0x03, RX_2Byte, 2);
	SafetyStatusA = (RX_2Byte[1]*256 + RX_2Byte[0]);
	UV_Fault = 0x4 & RX_2Byte[0];
	OV_Fault = 0x8 & RX_2Byte[0];
	SCD_Fault = 0x8 & RX_2Byte[1];
	OCD_Fault = 0x2 & RX_2Byte[1];
	OCC_Fault = 0x1 & RX_2Byte[1];
	I2C_ReadReg(0x05, RX_2Byte, 2);
	SafetyStatusB = (RX_2Byte[1]*256 + RX_2Byte[0]);
	OTF_Fault =  0x8 & RX_2Byte[1];
	I2C_ReadReg(0x07, RX_2Byte, 2);
	SafetyStatusC = (RX_2Byte[1]*256 + RX_2Byte[0]);
}

void AFE_ReadPFStatus() {
	// Read Permanent Fail Status A/B/C and find which bits are set
	// This shows which permanent failures have been triggered
	I2C_ReadReg(0x0B, RX_2Byte, 2);
	PFStatusA = (RX_2Byte[1]*256 + RX_2Byte[0]);
	I2C_ReadReg(0x0D, RX_2Byte, 2);
	PFStatusB = (RX_2Byte[1]*256 + RX_2Byte[0]);
	I2C_ReadReg(0x0F, RX_2Byte, 2);
	PFStatusC = (RX_2Byte[1]*256 + RX_2Byte[0]);
}


void AFE_ControlStatus() {
	// Control status register - Bit0 - LD_ON (load detected)
	// See TRM Table 6-1
	I2C_ReadReg(0x00, RX_2Byte, 2);
  LD_ON = 0x1 & RX_2Byte[0];
}

void AFE_BatteryStatus() {
	// Battery status register - See TRM Table 6-2
	I2C_ReadReg(0x12, RX_2Byte, 2);
}

void AFE_ClearFaults() {
	TX_2Byte[0] = 0x00; TX_2Byte[1] = 0xF8;
	I2C_WriteReg(0x62,TX_2Byte,2);
}

void AFE_ClearScanBits() {
	TX_2Byte[0] = 0x82; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x62,TX_2Byte,2);
}

void AFE_PFReset() {
	TX_2Byte[0] = 0x29; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

uint16_t AFE_DeviceID() {
	// Read Device ID using Subcommand 0x0001
	TX_2Byte[0] = 0x01; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	delayUS(500);
	I2C_ReadReg(0x40, RX_2Byte, 2);
	return (RX_2Byte[1]*256 + RX_2Byte[0]);
}
void AFE_STATUS(){

	TX_2Byte[0] = 0x75; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	delayUS(1000);
	I2C_ReadReg(0x40, RX_32Byte, 32);
	Max_cell = (RX_32Byte[5]<<8) + (RX_32Byte[4]);
	Min_cell = (RX_32Byte[7]<<8) + (RX_32Byte[6]);
	Battery_voltage_sum = (RX_32Byte[9]<<8) + (RX_32Byte[8]);
	Avg_cell_temp = (RX_32Byte[11]<<8) + (RX_32Byte[10]);
	Fet_temp = (RX_32Byte[13]<<8) + (RX_32Byte[12]);
	Max_cell_temp = (RX_32Byte[15]<<8) + (RX_32Byte[14]);
	Min_cell_temp = (RX_32Byte[17]<<8) + (RX_32Byte[16]);
	Avg_min_max_temp = (RX_32Byte[19]<<8) + (RX_32Byte[18]);
	CC3_Current = (RX_32Byte[21]<<8) + (RX_32Byte[20]);
	CC1_Current = (RX_32Byte[23]<<8) + (RX_32Byte[22]);
	Raw_CC2_Count = ((RX_32Byte[27]<<24) + (RX_32Byte[26]<<16) + (RX_32Byte[25]<<8) + RX_32Byte[24]);
	Raw_CC3_Count = ((RX_32Byte[31]<<24) + (RX_32Byte[30]<<16) + (RX_32Byte[29]<<8) + RX_32Byte[28]);

	delayUS(1000);
}
// ********************************* End of AFE Status and Fault Commands   *****************************************


// ********************************* AFE Measurement Commands   *****************************************

uint16_t AFE_ReadCellVoltage(uint8_t channel) {
	I2C_ReadReg(channel*2+0x14, RX_2Byte, 2);  //0x14
	return (RX_2Byte[1]*256 + RX_2Byte[0]);     // cell voltage is reported in mV
}

uint16_t AFE_ReadStackVoltage() {
	I2C_ReadReg(0x34, RX_2Byte, 2);
	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
}

uint16_t AFE_ReadPackVoltage() {
	I2C_ReadReg(0x36, RX_2Byte, 2);
	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
}

uint16_t AFE_ReadLDVoltage() {
	I2C_ReadReg(0x38, RX_2Byte, 2);
	return 10 * (RX_2Byte[1]*256 + RX_2Byte[0]);  // voltage is reported in 0.01V units
}

uint16_t AFE_ReadCurrent() {
	//uint8_t cure = 0;
	I2C_ReadReg(0x3A, RX_2Byte, 2);
	return (RX_2Byte[1]*256 + RX_2Byte[0]);  // current is reported in mA
}



float AFE_ReadTemperature(uint8_t channel) {
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
	switch(channel)
	{
		case 0:
			I2C_ReadReg(0x70, RX_2Byte, 2);  // TS1 pin
			break;
		case 1:
			I2C_ReadReg(0x74, RX_2Byte, 2);  // TS3 pin, FET temperature
			break;
		case 2:
			I2C_ReadReg(0x76, RX_2Byte, 2);  // HDQ, FET temperature
			break;
		case 3:
			I2C_ReadReg(0x78, RX_2Byte, 2);  // DCHG pin, FET temperature
			break;
		default: break;
	}
	return (0.1 * (float)(RX_2Byte[1]*256 + RX_2Byte[0])) - 273.15;  // convert from 0.1K to Celcius
}


void AFE_ReadPassQ() {
	// Read Accumulated Charge and Time from DASTATUS6 (See TRM Table 4-6)
	TX_2Byte[0] = 0x76; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
	delayUS(1000);
	I2C_ReadReg(0x40, RX_12Byte, 12);
	AccumulatedCharge_Int = ((RX_12Byte[3]<<24) + (RX_12Byte[2]<<16) + (RX_12Byte[1]<<8) + RX_12Byte[0]);
	AccumulatedCharge_Frac = ((RX_12Byte[7]<<24) + (RX_12Byte[6]<<16) + (RX_12Byte[5]<<8) + RX_12Byte[4]);
	AccumulatedCharge_Time = ((RX_12Byte[11]<<24) + (RX_12Byte[10]<<16) + (RX_12Byte[9]<<8) + RX_12Byte[8]);
}

void AFE_ClearPassQ() {
	// Clear Accumulated Charge and Time, command 0x0082
	TX_2Byte[0] = 0x82; TX_2Byte[1] = 0x00;
	I2C_WriteReg(0x3E,TX_2Byte,2);
}

void config_mode(){
	TX_2Byte[0] = 0x90; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);

}
void Exit_config_mode(){
	TX_2Byte[0] = 0x92; TX_2Byte[1] = 0x00;
		I2C_WriteReg(0x3E,TX_2Byte,2);

}
// ********************************* End of AFE Measurement Commands   *****************************************

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */

 // HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	volatile int i = 0;
	char uart_buf[50];
	int uart_buf_len;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_TIM1_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  //DFET PIN fetofff(low)
  HAL_TIM_Base_Start(&htim1);
 // Protections_AFE();
	//HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET); // DEFET PIN
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);

	delayUS(10000);

	AFE_Reset();
	delayUS(60000);
	//Temp_protection();
	protect_AFE();
	delayUS(10000);
	 // Dec_to_Hex(65521);
	Dec_to_Bin(65521);
	 AFE_Init();

	delayUS(10000);
#if 0 //Test mode
	AFE_FET_Control(0x00);
		AFE_ReadFETStatus();
			delayUS(10000);
		DSG_TEST();
		AFE_ReadFETStatus();
		delayUS(10000);

		CHG_TEST();
		AFE_ReadFETStatus();
			delayUS(10000);
		 PDSG_TEST();
		 AFE_ReadFETStatus();
		 	delayUS(10000);
		 PCHG_TEST();
		 AFE_ReadFETStatus();
		 	delayUS(10000);
#endif
#if 1
	//AFE_FET_ENABLE();
	//delayUS(10000);
	AFE_ALL_FETS_ON();
	delayUS(10000);
	AFE_ReadFETStatus();
	delayUS(10000);
	//AFE_ALL_FETS_OFF();
	//delayUS(10000);
	AFE_ReadFETStatus();
	AFE_SLEEP_DISABLE();
#endif
	delayUS(60000); delayUS(60000); delayUS(60000); delayUS(60000);  //wait to start measurements after FETs close
	CellVoltage[1] = AFE_ReadCellVoltage(1);
	CellVoltage[5] = AFE_ReadCellVoltage(5);
	CellVoltage[10] = AFE_ReadCellVoltage(10);
	Stack_Voltage = AFE_ReadStackVoltage();
	PACK_Voltage = AFE_ReadPackVoltage();
	LD_Voltage = AFE_ReadLDVoltage();
	//PACK_Current = AFE_ReadCurrent();
	//Temperature[0] = AFE_ReadTemperature(0);
	//FET_Temperature = AFE_ReadTemperature(1);
	//HDQ_Temp = AFE_ReadTemperature(2);
	//DCHG_Temp = AFE_ReadTemperature(3);
	//DDSG_Temp = AFE_ReadTemperature(4);

#if 0
  AFE_SLEEP_DISABLE();
  AFE_ManufacturingStatus();
  AFE_ReadFETStatus();
  Charge_Pump();
  AFE_FETOptions();
 // AFE_FET_ENABLE();
  AFE_FET_Control(0x00);
  AFE_ReadFETStatus();
  AFE_ALL_FETS_ON();
  AFE_ReadFETStatus();
#endif



  HAL_StatusTypeDef stat = HAL_OK;
  	stat = HAL_I2C_IsDeviceReady(&hi2c1,0x10,2,10);
  	if(stat == HAL_OK)
  	{


  	}
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	//  alert_protection_B();
	  AFE_ReadAlarmStatus() ;
	//  AFE_STATUS();
	  PACK_Current = AFE_ReadCurrent();
	 // Current = PACK_Current * 14.9538;
	  AFE_ReadFETStatus();
	//  HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1);  //Enable uart1
	 	//	HAL_GPIO_WritePin(UC_DI_DO_RS485_1_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1); // Enable UART1
	 	//	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, 1); // Enable UART1
	  HAL_GPIO_WritePin(DEBUG_RX_DO_GPIO_Port, DEBUG_RDE_DO_Pin, 1);
	  printf("CV \n");
	 		for(int i = 0 ;i <=15; i++)
	 	  {
	 			CellVoltage[i] = AFE_ReadCellVoltage(i);
	 			printf("[%d] = %d|",i,CellVoltage);

	 	  }
	 	 Temperature[0] = AFE_ReadTemperature(0) * 10;
	 	 printf("Temperature ambient : %d",Temperature[0]);
	 	 	FET_Temperature = AFE_ReadTemperature(1) * 10;
	 	 printf("Temperature Mosfet : %d",FET_Temperature);
	 	 HDQ_Temp = AFE_ReadTemperature(2) * 10;
	 	 printf("HDQ Temperature : %d",HDQ_Temp );
	 	 DCHG_Temp = AFE_ReadTemperature(3) * 10;
	 	printf("DCHG Temperature : %d",DCHG_Temp );
	 	// DDSG_Temp = AFE_ReadTemperature(4);
	 	  //pa10 port,pa8 pin,1
	 	 HAL_GPIO_WritePin(DEBUG_RX_DO_GPIO_Port, DEBUG_RDE_DO_Pin, 1);
		//  HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 1);  //Enable uart1
	 	//  HAL_GPIO_WritePin(RDE_DO_GPIO_Port, RDE_DO_Pin, 0);  //Disable uart2
	 	//	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, 1); // Enable UART1
	 	 // 	HAL_GPIO_WritePin(RS485_1_RO_DO_UC_GPIO_Port, UC_RDE_DO_RS485_1_Pin, 0); //Disable UART1
#if 1
	 	AFE_ReadSafetyStatus();
	 	  	if (AlarmBits & 0x82) {
	 	  				AFE_ClearScanBits();
	 	  			}

	 	  			if (AlarmBits & 0xC000) {
	 	  				AFE_ReadSafetyStatus();
	 	  				AFE_ReadPFStatus();
	 	  				AFE_ClearFaults();
	 	  				AFE_PFReset();
	 	  			}

#endif
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 36;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x10808DD3;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief TIM1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM1_Init 1 */

  /* USER CODE END TIM1_Init 1 */
  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 63;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 65535;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */

  /* USER CODE END TIM1_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 63;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 65535;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(RST_SHUT_B_UC_GPIO_Port, RST_SHUT_B_UC_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(DFETOFF_B_UC_GPIO_Port, DFETOFF_B_UC_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, DEBUG_RDE_DO_Pin|UC_TEMP_EN_DO_M_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(RDE_DO_GPIO_Port, RDE_DO_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : RST_SHUT_B_UC_Pin DEBUG_RDE_DO_Pin UC_TEMP_EN_DO_M_Pin */
  GPIO_InitStruct.Pin = RST_SHUT_B_UC_Pin|DEBUG_RDE_DO_Pin|UC_TEMP_EN_DO_M_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : DFETOFF_B_UC_Pin */
  GPIO_InitStruct.Pin = DFETOFF_B_UC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DFETOFF_B_UC_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : RDE_DO_Pin */
  GPIO_InitStruct.Pin = RDE_DO_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(RDE_DO_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Kindly Help ,

Thanks and regards,

Rohith Sai 

  • Hi Rohith, 

    I noticed another one of you posts from yesterday is similar to this so I'll respond here. I'm still looking through your code, but the one thing that currently stands out is in your protect_AFE() function the 'for' loop has "j<4" but this would put 4 bytes of data into the TX_3Byte array so you will need to change this to "j<3". This is a start, but I will get back to you if I notice something else.

    As far as values go when you are configuring the COV and other parameters, these are fine and within spec so there shouldn't be an issue there. 

    My suggestion is to focus on testing one protection at a time for instance just enabling the over voltage protection and ensuring the FETs operate properly, then moving on to the next protection. This will help isolate problem area. 

    Additionally, are you using the BQ76952EVM or your own board design? If you are using your own board design, would you mind sharing it with me to see if there may be an issue in the board? 

    Best,

    Andrew

  • Thanks for the reply,

    I have changed the loop to j<3 and also im configuring the thresholds seperately in the AFe_Init() function, and im also configuring the thresholds seperately and testing the breach value,still I have problesm associated with the charge MSOFET please suggest some other ways

    Problems related to thermoistor readings

    • When I try to read the thermistor readings, I am getting values in negative like(-0.207632) and if I try to add thw offset the value is added to this number with the thermistor connected, while I am using HDQ,TS3,TS1,DCHG pins as thermistors as mentioned in the code
    •  Where I cant able to find any changes when temperature breach happens, Are my temperature configurations are right?

    Regarding Charge Mosfets,

    • How to enable the mosfets Individually and disable individually.

    It would be good if you can share your mail id to share my Board design due to some privacy constrains.

    Please refer to the code attached previously.

    Thanks and Regards,

    Rohith Sai

  • Hi Rohith,

    There are subcommands PCHGTEST, CHGTEST, DSDTEST, PDSGTEST  (0x001E, 0x001F, 0x0020, 0x001C are the subcommands respectively) where you can test and watch if the FETs turn on. In order to use these subcommands you will need to not set the manufacturing status to enable fets (in your case don't call AFE_FET_ENABLE()).

    //Example for CHGTEST subcommand
    TX_2Byte[0] = 0x1FTX_2Byte[1] = 0x00
    I2C_WriteReg(0x3E,TX_2Byte,2);
    delayUS(1000);
     
    This will toggle the FET so use it once to turn on then use it again to turn off. Let me know if this helps show you if the FETs are properly working.
    It looks like you already have these functions in your code (i.e. PDSG_TEST()) 
     
    For the Temp readings, even if not calibrated, should be still close to expected value. However, I noticed in your code you use printf with %d identifier, but the temps calculated in Temperature[] are float values so you will need to use %f for the identifiers if this is how you are acquiring the temperature data. You could also use a debugger tool to step into the portion where it calculates the temp and look at the values being stored into the array.
    Your temp pin configurations look correct using 0x0F.

    Best,
    Andrew