view Small_CPU/Src/batteryGasGauge.c @ 794:bb37d4f3e50e

Restructure UART based sensor handling: In the previous version every UART sensor instance had its own protocol handling instance (requests, timeout, errors). With the introduction of the multiplexer these functionalities had to be harmonized. E.g. only one errorhandling which is applied to all sensors. In the new structure the sensor communication is split into one function which takes care for the control needs of a sensor and one function which handles the incoming data. The functions behalf the same independend if the sensor are connected to multiplexer or directly to the OSTC. Second big change in the external sensor concepts is that the data processing is no longer focussed at the three existing ADC channels. Every external sensor (up to 3 ADC and 4 UART) sensor has its own instance. If the ADC slots are not in use then they may be used for visiualization of UART sensors by creating a mirror instance but this is no longer a must.
author Ideenmodellierer
date Mon, 31 Jul 2023 19:46:29 +0200
parents 079bb5b22c06
children
line wrap: on
line source

/**
  ******************************************************************************
  * @file    batteryGasGauge.c 
  * @author  heinrichs weikamp gmbh
  * @version V0.0.1
  * @date    09-Dec-2014
  * @brief   LTC2942 Battery Gas Gauge
  *           
  @verbatim                 
  ============================================================================== 
                ##### stm32f4xx_hal_i2c.c modification #####
  ============================================================================== 
	The LTC2942 requires an repeated start condition without stop condition
	for data reception.
	
  @endverbatim
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
  *
  ******************************************************************************
  */ 
/* Includes ------------------------------------------------------------------*/
#include <string.h>	/* memset */
#include "batteryGasGauge.h"
#include "baseCPU2.h"
#include "stm32f4xx_hal.h"
#include "i2c.h"

static float battery_f_voltage = BATTERY_DEFAULT_VOLTAGE;		/* max assumed voltage */
static float battery_f_charge_percent = 0;
static uint8_t chargeValueKnown = 0;							/* indicator if the charge of the battery is known (for example after a full charge cycle) */


#define BGG_BATTERY_OFFSET          (26123)  //; 65536-(3,35Ah/0,085mAh)
#define BGG_BATTERY_DIVIDER         (394)    //; 3,35Ah/0,085mAh/100 [%]

float get_voltage(void)
{
#ifdef OSTC_ON_DISCOVERY_HARDWARE
	return 3.0f;
#endif

	return battery_f_voltage;
}


float get_charge(void)
{
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return 100.0f;
	#endif
	
	return battery_f_charge_percent;
}


void init_battery_gas_gauge(void)
{
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return;
	#endif
	
	uint8_t buffer[2];
	buffer[0] = 0x01;

	// F8 = 11111000:
	// ADC auto mode (11)
	// Prescale M = 128 (111)
	// AL/CC pin disable (00)
	// Shutdown (0)
	buffer[1] = 0xF8;
	I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
}

uint8_t battery_gas_gauge_CheckConfigOK(void)
{
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return;
	#endif

	uint8_t retval = 0;
	uint8_t bufferReceive[10];

	memset(bufferReceive,0,sizeof(bufferReceive));

	I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10);
	if(bufferReceive[1] == 0xf8)
	{
		retval = 1;
	}
	return retval;
}

static void disable_adc(void)
{
	uint8_t buffer[2];
	buffer[0] = 0x01;

	// according to the datasheet of the LTC2942, the adc shall
	// be disabled when writing to the gauge registers

	// 0xF9 = 11111001:
	// see init_battery_gas_gauge()
	// Shutdown (1)
	buffer[1] = 0xF9;
	I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
}


void battery_gas_gauge_get_data(void)
{
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return;
	#endif
	
	float battery_f_voltage_local;
	float battery_f_charge_percent_local;
	
	uint8_t bufferReceive[10];
	
	if(I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10) == HAL_OK)
	{
		battery_f_voltage_local =  (float)(bufferReceive[8] * 256);
		battery_f_voltage_local += (float)(bufferReceive[9]);
		battery_f_voltage_local *= (float)6 / (float)0xFFFF;
	
		// max/full: 0.085 mAh * 1 * 65535 = 5570 mAh
		battery_f_charge_percent_local =  (float)(bufferReceive[2] * 256);
		battery_f_charge_percent_local += (float)(bufferReceive[3]);
		battery_f_charge_percent_local -= BGG_BATTERY_OFFSET;		/* Because of the prescalar 128 the counter assumes a max value of 5570mAh => normalize to 3350mAh*/
		battery_f_charge_percent_local /= BGG_BATTERY_DIVIDER;		/* transform to percentage */

		if(battery_f_charge_percent_local < 0)
			battery_f_charge_percent_local = 0;

		battery_f_voltage = battery_f_voltage_local;
		battery_f_charge_percent = battery_f_charge_percent_local;
	}
}


void battery_gas_gauge_set_charge_full(void)
{
	disable_adc();
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return;
	#endif
	
	uint8_t bufferSend[3];
	bufferSend[0] = 0x02;
	bufferSend[1] = 0xFF;
	bufferSend[2] = 0xFF;
	I2C_Master_Transmit(  DEVICE_BATTERYGAUGE, bufferSend, 3);
	init_battery_gas_gauge();
	chargeValueKnown = 1;
}


void battery_gas_gauge_set(float percentage)
{

	disable_adc();
	#ifdef OSTC_ON_DISCOVERY_HARDWARE
		return;
	#endif

	uint16_t mAhSend;
	
	if(percentage >= 100)
		mAhSend = 0xFFFF;
	else {
		mAhSend = (percentage * BGG_BATTERY_DIVIDER) + BGG_BATTERY_OFFSET;
	}
	
	uint8_t bufferSend[3];
	bufferSend[0] = 0x02;
	bufferSend[1] = (uint8_t)(mAhSend / 256);
	bufferSend[2] = (uint8_t)(mAhSend & 0xFF);
	I2C_Master_Transmit(  DEVICE_BATTERYGAUGE, bufferSend, 3);
	init_battery_gas_gauge();
	chargeValueKnown = 1;
}

uint8_t battery_gas_gauge_isChargeValueValid(void)
{
	return chargeValueKnown;
}

void battery_gas_gauge_setChargeValueValid(void)
{
	chargeValueKnown = 1;
}

/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/