RRC3570 Li-ion battery charger(LTC4015) firmware

RRC3570 Li-ion battery charger(LTC4015) firmware

In this article we are going to implement the firmware for stm32l0 microcontroller which is interfaced through I2C port to LTC4015 charger IC to perform the basic charging functionality.The content of main.c file is given as below.


/* USER CODE BEGIN Header */

/**

******************************************************************************

* @file : main.c

* @brief : Main program body

******************************************************************************

* @attention

*

* Copyright (c) 2023 STMicroelectronics.

* All rights reserved.

*

* This software is licensed under terms that can be found in the LICENSE file

* in the root directory of this software component.

* If no LICENSE file comes with this software, it is provided AS-IS.

*

******************************************************************************

*/

/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/

#include "main.h"


/* Private includes ----------------------------------------------------------*/

/* USER CODE BEGIN Includes */


/* USER CODE END Includes */


/* Private typedef -----------------------------------------------------------*/

/* USER CODE BEGIN PTD */







/* USER CODE END PTD */


/* Private define ------------------------------------------------------------*/

/* USER CODE BEGIN PD */

/* USER CODE END PD */


/* Private macro -------------------------------------------------------------*/

/* USER CODE BEGIN PM */


/* USER CODE END PM */


/* Private variables ---------------------------------------------------------*/

I2C_HandleTypeDef hi2c1;


UART_HandleTypeDef huart1;


/* USER CODE BEGIN PV */

static const uint8_t PCA9546A_DEVICE_ADDRESS = 0xE0;//device address with write operation

static const uint8_t LTC4015_DEVICE_ADDRESS_READ = 0xD1;//for read operation

static const uint8_t LTC4015_DEVICE_ADDRESS_WRITE = 0xD0;//for write operation

static const uint8_t CONTROL_REG1 = 0x01;//select channel 0 of multiplexer ltc4015_1

static const uint8_t CONTROL_REG2 = 0x02;//select channel 1 of multiplexer battery_1

static const uint8_t CONTROL_REG3 = 0x04;//select channel 2 of multiplexer ltc4015_2

static const uint8_t CONTROL_REG4 = 0x08;//select channel 3 of multiplexer battery_2


/* 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_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */

static void rrc3570_battery_comm_check(void);

static void ltc_4015_init(void);

static void start_charging(void);

static void stop_charging(void);

/* USER CODE END PFP */


/* Private user code ---------------------------------------------------------*/

/* USER CODE BEGIN 0 */


/* USER CODE END 0 */


/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{

/* USER CODE BEGIN 1 */

HAL_StatusTypeDef ret;

uint8_t buf[1];

uint8_t read_buf_word[2];

uint16_t register_value = 0;


/* 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_USART1_UART_Init();

/* USER CODE BEGIN 2 */

rrc3570_battery_comm_check();//rrc_3570 battery communication check

HAL_UART_Transmit(&huart1,(uint8_t*) "battery Communication done\r\n", sizeof("Battery Communication done\r\n"), HAL_MAX_DELAY);

HAL_Delay(500);//wait for some time

ltc_4015_init();//ltc4015 alert limit,en_limit_alerts,en_charger_state_alerts configuration

HAL_UART_Transmit(&huart1,(uint8_t*) "ltc4015 successfully initialized\r\n", sizeof("ltc4015 sucessfully initialized\r\n"), HAL_MAX_DELAY);

HAL_Delay(500);//wait for some time

// stop_charging();//initially stop charging rrc3570 battery

// HAL_UART_Transmit(&huart1,(uint8_t*) "battery charging stopped\r\n", sizeof("battery charging stopped\r\n"), HAL_MAX_DELAY);

// HAL_Delay(2000);//wait for some time

start_charging();//start charging the rrc3570 battery

HAL_UART_Transmit(&huart1,(uint8_t*) "battery charging started\r\n", sizeof("battery charging started\r\n"), HAL_MAX_DELAY);

HAL_Delay(2000);//wait for some time


/* USER CODE END 2 */


/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */


/* USER CODE BEGIN 3 */

HAL_Delay(500);//put some delay



//step-1

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

HAL_Delay(500);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

HAL_Delay(500);//put some delay



//step-2

buf[0] = CONTROL_REG1;

ret = HAL_I2C_Master_Transmit(&hi2c1,PCA9546A_DEVICE_ADDRESS,buf,1,HAL_MAX_DELAY);//select channel 0 for i2c switch

if (ret != HAL_OK)

{

Error_Handler();

}


//check charge_status

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x35,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));







//check limit_alerts

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x36,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//check charger_state_alerts

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x37,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//check system_status

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x39,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));




//read VBATSENS = 26.498v

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3A,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//read VIN = 35.621volt

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3B,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//read VSYS = 35.5volt

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3C,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//read IBAT = 0.063721845

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3D,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));





//read IIN = 0.01269554 amp

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3E,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//read DIE_TEMP = 41.798 degree centigrade

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x3F,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//read BSR = 0ohm

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x41,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//read ICHARGE_DAC = 11

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x44,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//read VCHARGE_DAC=31

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x45,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));







//VBAT_FILT=26 volt

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x47,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));





//MEAS_SYS_VALID

ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x4A,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));




//check charger state as battery detection

if ( HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x34,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY) == HAL_OK )

{

register_value = 0;

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));

if ( ( register_value & 0x2 ) == 0 )//checking battery detection

{

HAL_UART_Transmit(&huart1,(uint8_t*) "battery is detected by ltc4015\r\n", sizeof("battery is detected by ltc4015\r\n"), HAL_MAX_DELAY);


}

else

{

//print message

HAL_UART_Transmit(&huart1, (uint8_t*) "battery is not detected by ltc4015\r\n", sizeof("battery is not detected by ltc4015\r\n"), HAL_MAX_DELAY);

}

}

else

{

Error_Handler();

}





//check charger state as cc_cv_charge state

if ( HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x34,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY) == HAL_OK )

{

register_value = 0;

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));

if ( ( register_value & 0x0040 ) != 0 )//checking CC_CV state

{

//print message

HAL_UART_Transmit(&huart1,(uint8_t*) "charger has entered into cc_cv state & battery is charging\r\n", sizeof("charger has entered into cc_cv state & battery is charging\r\n"), HAL_MAX_DELAY);

HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);//blink led if battery is charging

}

else

{

//print message

HAL_UART_Transmit(&huart1, (uint8_t*) "charger has not entered into cc_cv state & battery is not charging\r\n", sizeof("charger has not entered into cc_cv state & battery is not charging\r\n"), HAL_MAX_DELAY);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1,GPIO_PIN_SET);//on the led if battery is not charging

}

}

else

{

Error_Handler();

}




// ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x37,I2C_MEMADD_SIZE_8BIT,(uint16_t*)(&register_value), 2, HAL_MAX_DELAY);//checking battery missing fault alert

// if (ret != HAL_OK)

// {

// Error_Handler();

// }


}

/* 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};


/** Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);


/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;

RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;

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_1) != 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();

}

}


/**

* @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 = 0x00707CBB;

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 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};

/* USER CODE BEGIN MX_GPIO_Init_1 */

/* USER CODE END MX_GPIO_Init_1 */


/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();


/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);


/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4|GPIO_PIN_7, GPIO_PIN_RESET);


/*Configure GPIO pins : PA0 PA1 */

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;

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 pins : PB4 PB7 */

GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/*Configure GPIO pin : PB5 */

GPIO_InitStruct.Pin = GPIO_PIN_5;

GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


/* EXTI interrupt init*/

HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);


/* USER CODE BEGIN MX_GPIO_Init_2 */

/* USER CODE END MX_GPIO_Init_2 */

}


/* USER CODE BEGIN 4 */

// External Interrupt ISR Handler CallBackFun

//SMBALERT interrupt input pin from ltc4015 to stm32l0

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

//if(GPIO_Pin == GPIO_PIN_5) // INT Source is pin B5

//{

//HAL_Delay(100);

//HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);//do some task

// }

}



//rrc3570_battery_comm_check function

static void rrc3570_battery_comm_check(void)

{

HAL_StatusTypeDef ret;

uint8_t buf[1];

uint8_t read_buf_block[10];


HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_RESET);//initially Disable the battery

HAL_Delay(500);//wait for 500ms

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0,GPIO_PIN_SET);//Enable the battery


//step-1

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

HAL_Delay(500);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

HAL_Delay(500);//put some delay



//step-2

buf[0] = CONTROL_REG2;

ret = HAL_I2C_Master_Transmit(&hi2c1,PCA9546A_DEVICE_ADDRESS,buf,1,HAL_MAX_DELAY);//select channel 1 for battery

if (ret != HAL_OK)

{

Error_Handler();

}



//read battery chemistry as LION for checking battery communication

ret = HAL_I2C_Mem_Read(&hi2c1,0x17,0x22,I2C_MEMADD_SIZE_8BIT,read_buf_block,5,HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

else

{

HAL_UART_Transmit(&huart1,read_buf_block,5, HAL_MAX_DELAY);

HAL_UART_Transmit(&huart1,(uint8_t *)" ",sizeof(" "), HAL_MAX_DELAY);

HAL_UART_Transmit(&huart1,(uint8_t *)"chemistry\r\n",sizeof("chemistry\r\n"), HAL_MAX_DELAY);

}

}//end of rrc3570_battery_comm_check function



//ltc_4015_init function

static void ltc_4015_init(void)

{

HAL_StatusTypeDef ret;

uint8_t buf[1];

uint8_t read_buf_word[2];

uint16_t register_value = 0;


//(ltc4015 section)

//PB5 ALERT pin is configured as interrupt

// HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4,GPIO_PIN_RESET);//EQ1 pin is low as unused

//ntc pin is grounded & unused


//step-1

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

HAL_Delay(500);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

HAL_Delay(500);//put some delay




//step-2

buf[0] = CONTROL_REG1;

ret = HAL_I2C_Master_Transmit(&hi2c1,PCA9546A_DEVICE_ADDRESS,buf,1,HAL_MAX_DELAY);//select channel 0 for i2c switch

if (ret != HAL_OK)

{

Error_Handler();

}



//Configure alert limit registers

//VBAT_LO_ALERT_LIMIT=2.50v*7=17.5v

//first send lower byte & then send higher byte

uint8_t dataBuffer1[2] = {0xcb,0x32};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x01, I2C_MEMADD_SIZE_8BIT, dataBuffer1, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x01,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//VBAT_HI_ALERT_LIMIT=4.2*7 = 29.4v

//send low byte then send high byte

uint8_t dataBuffer2[2] = {0x55,0x55};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x02, I2C_MEMADD_SIZE_8BIT, dataBuffer2, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x02,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//VIN_LO_ALERT_LIMIT 2.8v

//send low then high byte

uint8_t dataBuffer3[2] = {0xa3,0x06};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x03, I2C_MEMADD_SIZE_8BIT, dataBuffer3, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x03,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//VIN_HI_ALERT_LIMIT 35v

//send low byte then high byte

uint8_t dataBuffer4[2] = {0xf6,0x52};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x04, I2C_MEMADD_SIZE_8BIT, dataBuffer4, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x04,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//VSYS_LO_ALERT_LIMIT 2.8v

//send low then send high byte

uint8_t dataBuffer5[2] = {0xa3,0x06};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x05, I2C_MEMADD_SIZE_8BIT, dataBuffer5, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x05,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//VSYS_HI_ALERT_LIMIT 35v

//send low then send high byte

uint8_t dataBuffer6[2] = {0xf6,0x52};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x06, I2C_MEMADD_SIZE_8BIT, dataBuffer6, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x06,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//IN_HI_ALERT_LIMIT 3Amp

//send low then send high byte

uint8_t dataBuffer7[2] = {0x00,0x18};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE, 0x07, I2C_MEMADD_SIZE_8BIT, dataBuffer7, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x07,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//IBAT_LO_ALERT_LIMIT 0amp

//send low then send high byte

uint8_t dataBuffer8[2] = {0x00,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x08, I2C_MEMADD_SIZE_8BIT, dataBuffer8, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x08,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//DIE_TEMP_HI_ALERT_LIMIT 60 degree can be changed as per requirement

//send low then send high byte

uint8_t dataBuffer9[2] = {0x9a,0x39};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x09, I2C_MEMADD_SIZE_8BIT, dataBuffer9, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x09,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//BSR_HI_ALERT_LIMIT 100milliohm & can be changed as per requirement

//send low then send high byte

uint8_t dataBuffer10[2] = {0xfa,0x06};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x0A, I2C_MEMADD_SIZE_8BIT, dataBuffer10, 2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x0A,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//ntc is not used here

//NTC_RATIO_HI_ALERT_LIMIT (Sub-Address 0x0B, Bits 15:0,R/W)

//NTC_RATIO_LO_ALERT_LIMIT (Sub-Address 0x0C, Bits 15:0, R/W)



//Enable limit alerts

//send lower byte then send higher byte

uint8_t dataBuffer11[2] = {0xfc,0xbf};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x0D, I2C_MEMADD_SIZE_8BIT, dataBuffer11,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x0D,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));




//Enable charger state alerts

//send lower byte then send higher byte

uint8_t dataBuffer12[2] = {0xdf,0x01};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x0E, I2C_MEMADD_SIZE_8BIT, dataBuffer12,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x0E,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//Enable charge status alert

//send lower byte then send higher byte

uint8_t dataBuffer13[2] = {0x0f,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x0F, I2C_MEMADD_SIZE_8BIT, dataBuffer13,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x0F,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//state of charge function is not required as it is indicated in battery leds

//QCOUNT_LO_ALERT_LIMIT register is not required to configure

//QCOUNT_HI_ALERT_LIMIT register is not required to configure

//QCOUNT_PRESCALE_FACTOR register is not required to configure

//QCOUNT register is not required to configure


//CONFIG_BITS only suspend_charger bit is required for setting & resetting



//IN_LIMIT_SETTING 3 amp

//send lower byte then send higher byte

uint8_t dataBuffer14[2] = {0x11,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x15, I2C_MEMADD_SIZE_8BIT, dataBuffer14,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x15,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//VIN_UVCL_SETTING not req as its used for solar panel and default value is 0xff

//ICHARGE_TARGET 3amp

uint8_t dataBuffer15[2] = {0x0b,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x1A, I2C_MEMADD_SIZE_8BIT, dataBuffer15,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x1A,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//VCHARGE_SETTING 4.2v/cell

uint8_t dataBuffer16[2] = {0x1f,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x1B, I2C_MEMADD_SIZE_8BIT, dataBuffer16,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x1B,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//C_OVER_X_THRESHOLD default value is set = 2184

//ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x1C,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

//if (ret != HAL_OK)

//{

// Error_Handler();

//}

//register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//MAX_CV_TIME default value = 14,400 i.e 4 hours for lion chemistry

//ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x1D,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

//if (ret != HAL_OK)

//{

// Error_Handler();

//}

//register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));



//MAX_CHARGE_TIME default value = 18.2 hours (65535)for lion chemistry

//ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x1E,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

//if (ret != HAL_OK)

//{

// Error_Handler();

//}

//register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


//CHARGER_CONFIG_BITS only bit 2 en_c_over_x_term will be set

uint8_t dataBuffer17[2] = {0x04,0x00};

ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x29, I2C_MEMADD_SIZE_8BIT, dataBuffer17,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x29,I2C_MEMADD_SIZE_8BIT,read_buf_word,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

register_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));


}//end of function ltc_4015_init()




//start charging function

static void start_charging(void)

{

HAL_StatusTypeDef ret;

uint16_t temp;

uint16_t read_data;

uint8_t read_buf_word_data[2];

uint8_t write_buf_word_data[2];



// ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x14,I2C_MEMADD_SIZE_8BIT,read_buf_word_data,2, HAL_MAX_DELAY);

// if (ret != HAL_OK)

// {

// Error_Handler();

// }

// read_data = ((uint16_t)read_buf_word_data[0] | ((uint16_t)read_buf_word_data[1] << 8));

// temp = read_data | (0x0001<<8);//suspend_charger bit is high

// write_buf_word_data[0] = (uint8_t)(temp & 0x00ff);

// write_buf_word_data[1] =(uint8_t)((temp & 0xff00)>>8);

//

// ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x14, I2C_MEMADD_SIZE_8BIT,write_buf_word_data,2, HAL_MAX_DELAY);

// if (ret != HAL_OK)

// {

// Error_Handler();

// }

//

// HAL_Delay(500);




ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x14,I2C_MEMADD_SIZE_8BIT,read_buf_word_data,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}


read_data = ((uint16_t)read_buf_word_data[0] | ((uint16_t)read_buf_word_data[1] << 8));

temp = read_data &(~(0x0001<<8));////suspend_charger bit is low

write_buf_word_data[0] = (uint8_t)(temp & 0x00ff);

write_buf_word_data[1] =(uint8_t)((temp & 0xff00)>>8);




ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x14, I2C_MEMADD_SIZE_8BIT,write_buf_word_data,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

}//end of function start_charging()



//stop charging function

static void stop_charging(void)

{

HAL_StatusTypeDef ret;

uint16_t temp;

uint16_t read_data;

uint8_t read_buf_word_data[2];

uint8_t write_buf_word_data[2];


ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x14,I2C_MEMADD_SIZE_8BIT,read_buf_word_data,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

read_data = ((uint16_t)read_buf_word_data[0] | ((uint16_t)read_buf_word_data[1] << 8));

temp = read_data | (0x0001<<8);//suspend_charger bit is high

write_buf_word_data[0] = (uint8_t)(temp & 0x00ff);

write_buf_word_data[1] =(uint8_t)((temp & 0xff00)>>8);


ret = HAL_I2C_Mem_Write(&hi2c1, LTC4015_DEVICE_ADDRESS_WRITE,0x14, I2C_MEMADD_SIZE_8BIT,write_buf_word_data,2, HAL_MAX_DELAY);

if (ret != HAL_OK)

{

Error_Handler();

}

}//end of function stop_charging()



/* 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();

HAL_UART_Transmit(&huart1,(uint8_t*) "I2C communication error\r\n", sizeof("I2C communication error\r\n"), HAL_MAX_DELAY);

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 */


Note :- This program can be easily modified for more advanced applications.


IDE - STM32cubeide

Microcontroller - STM32L0


Jarno Puff

CTO LikeAbird Ltd and Unmanned Systems Consulting Expert

9 个月

Interesting project. are you open to migrate the same over to microcontrollers?

Satyabrata Senapati

Technical Content Writer , Technical Expert , Mentor , Trainer , & Embedded Software Developer

1 年

Please comment if you find any mistakes.

回复

要查看或添加评论,请登录

Satyabrata Senapati的更多文章

  • How I got a core embedded job by securing only 44.66% in 10th

    How I got a core embedded job by securing only 44.66% in 10th

    In this article we will discuss about my educational qualifications for getting a core job in embedded. Actually I was…

  • Salary of VLSI Engineer

    Salary of VLSI Engineer

    In this article we will discuss salary of a VLSI Engineer. The landscape of VLSI jobs offers positions that command…

  • ESP32 Timers & Timer Interrupt

    ESP32 Timers & Timer Interrupt

    In this article we will study how to use ESP32 internal Timers & generate Timer Interrupt events in Arduino IDE.We’ll…

  • OSEK(Open Systems and their Interfaces for the Electronics in Motor Vehicles)

    OSEK(Open Systems and their Interfaces for the Electronics in Motor Vehicles)

    OSEK (Offene Systeme und deren Schnittstellen für die Elektronik in Kraftfahrzeugen; English: "Open Systems and their…

  • AUTOSAR

    AUTOSAR

    This article will focus on AUTOSAR. AUTOSAR (AUTomotive Open System ARchitecture) is a global development partnership…

  • Embedded AI

    Embedded AI

    In this article we will discuss about Embedded AI. Embedded artificial intelligence (AI) seamlessly integrates AI into…

  • Real Time System

    Real Time System

    In this article we will discuss about real time systems. Hard and Soft Real-Time Operating System A real-time operating…

  • Core jobs after btech electronics & telecommunication engineering

    Core jobs after btech electronics & telecommunication engineering

    In this article we will discuss opportunities after completing b.tech in electronics & telecommunication engineering.

  • Instrument cluster

    Instrument cluster

    In this article we will discuss about different types of instrument clusters. Overview Automotive instrument clusters…

  • Embedded Linux

    Embedded Linux

    Computer operating systems based on the Linux kernel are used in embedded systems such as consumer electronics (eg…

社区洞察

其他会员也浏览了