38
+ − 1 /**
+ − 2 ******************************************************************************
+ − 3 * @file batteryGasGauge.c
+ − 4 * @author heinrichs weikamp gmbh
+ − 5 * @version V0.0.1
+ − 6 * @date 09-Dec-2014
+ − 7 * @brief LTC2942 Battery Gas Gauge
+ − 8 *
+ − 9 @verbatim
+ − 10 ==============================================================================
+ − 11 ##### stm32f4xx_hal_i2c.c modification #####
+ − 12 ==============================================================================
+ − 13 The LTC2942 requires an repeated start condition without stop condition
+ − 14 for data reception.
+ − 15
+ − 16 @endverbatim
+ − 17 ******************************************************************************
+ − 18 * @attention
+ − 19 *
+ − 20 * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+ − 21 *
+ − 22 ******************************************************************************
+ − 23 */
+ − 24 /* Includes ------------------------------------------------------------------*/
330
+ − 25 #include <string.h> /* memset */
38
+ − 26 #include "batteryGasGauge.h"
+ − 27 #include "baseCPU2.h"
+ − 28 #include "stm32f4xx_hal.h"
+ − 29 #include "i2c.h"
+ − 30
662
+ − 31 static float battery_f_voltage = BATTERY_DEFAULT_VOLTAGE; /* max assumed voltage */
228
+ − 32 static float battery_f_charge_percent = 0;
668
+ − 33 static uint8_t chargeValueKnown = 0; /* indicator if the charge of the battery is known (for example after a full charge cycle) */
+ − 34
38
+ − 35
+ − 36 #define BGG_BATTERY_OFFSET (26123) //; 65536-(3,35Ah/0,085mAh)
228
+ − 37 #define BGG_BATTERY_DIVIDER (394) //; 3,35Ah/0,085mAh/100 [%]
38
+ − 38
+ − 39 float get_voltage(void)
+ − 40 {
+ − 41 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 42 return 3.0f;
+ − 43 #endif
+ − 44
+ − 45 return battery_f_voltage;
+ − 46 }
+ − 47
+ − 48
+ − 49 float get_charge(void)
+ − 50 {
+ − 51 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 52 return 100.0f;
+ − 53 #endif
+ − 54
+ − 55 return battery_f_charge_percent;
+ − 56 }
+ − 57
+ − 58
+ − 59 void init_battery_gas_gauge(void)
+ − 60 {
+ − 61 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 62 return;
+ − 63 #endif
+ − 64
+ − 65 uint8_t buffer[2];
+ − 66 buffer[0] = 0x01;
228
+ − 67
+ − 68 // F8 = 11111000:
433
+ − 69 // ADC auto mode (11)
228
+ − 70 // Prescale M = 128 (111)
668
+ − 71 // AL/CC pin disable (00)
228
+ − 72 // Shutdown (0)
+ − 73 buffer[1] = 0xF8;
+ − 74 I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
38
+ − 75 }
+ − 76
330
+ − 77 uint8_t battery_gas_gauge_CheckConfigOK(void)
+ − 78 {
+ − 79 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 80 return;
+ − 81 #endif
+ − 82
+ − 83 uint8_t retval = 0;
+ − 84 uint8_t bufferReceive[10];
+ − 85
+ − 86 memset(bufferReceive,0,sizeof(bufferReceive));
+ − 87
+ − 88 I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10);
+ − 89 if(bufferReceive[1] == 0xf8)
+ − 90 {
+ − 91 retval = 1;
+ − 92 }
+ − 93 return retval;
+ − 94 }
+ − 95
242
+ − 96 static void disable_adc(void)
+ − 97 {
+ − 98 uint8_t buffer[2];
+ − 99 buffer[0] = 0x01;
+ − 100
+ − 101 // according to the datasheet of the LTC2942, the adc shall
+ − 102 // be disabled when writing to the gauge registers
+ − 103
+ − 104 // 0xF9 = 11111001:
+ − 105 // see init_battery_gas_gauge()
+ − 106 // Shutdown (1)
+ − 107 buffer[1] = 0xF9;
+ − 108 I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
+ − 109 }
+ − 110
38
+ − 111
+ − 112 void battery_gas_gauge_get_data(void)
+ − 113 {
+ − 114 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 115 return;
+ − 116 #endif
+ − 117
+ − 118 float battery_f_voltage_local;
+ − 119 float battery_f_charge_percent_local;
+ − 120
+ − 121 uint8_t bufferReceive[10];
408
+ − 122
+ − 123 if(I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10) == HAL_OK)
+ − 124 {
+ − 125 battery_f_voltage_local = (float)(bufferReceive[8] * 256);
+ − 126 battery_f_voltage_local += (float)(bufferReceive[9]);
+ − 127 battery_f_voltage_local *= (float)6 / (float)0xFFFF;
+ − 128
+ − 129 // max/full: 0.085 mAh * 1 * 65535 = 5570 mAh
+ − 130 battery_f_charge_percent_local = (float)(bufferReceive[2] * 256);
+ − 131 battery_f_charge_percent_local += (float)(bufferReceive[3]);
433
+ − 132 battery_f_charge_percent_local -= BGG_BATTERY_OFFSET; /* Because of the prescalar 128 the counter assumes a max value of 5570mAh => normalize to 3350mAh*/
+ − 133 battery_f_charge_percent_local /= BGG_BATTERY_DIVIDER; /* transform to percentage */
38
+ − 134
408
+ − 135 if(battery_f_charge_percent_local < 0)
+ − 136 battery_f_charge_percent_local = 0;
+ − 137
+ − 138 battery_f_voltage = battery_f_voltage_local;
+ − 139 battery_f_charge_percent = battery_f_charge_percent_local;
+ − 140 }
38
+ − 141 }
+ − 142
+ − 143
+ − 144 void battery_gas_gauge_set_charge_full(void)
+ − 145 {
242
+ − 146 disable_adc();
38
+ − 147 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 148 return;
+ − 149 #endif
+ − 150
+ − 151 uint8_t bufferSend[3];
+ − 152 bufferSend[0] = 0x02;
+ − 153 bufferSend[1] = 0xFF;
+ − 154 bufferSend[2] = 0xFF;
+ − 155 I2C_Master_Transmit( DEVICE_BATTERYGAUGE, bufferSend, 3);
242
+ − 156 init_battery_gas_gauge();
668
+ − 157 chargeValueKnown = 1;
38
+ − 158 }
+ − 159
+ − 160
+ − 161 void battery_gas_gauge_set(float percentage)
+ − 162 {
242
+ − 163
+ − 164 disable_adc();
38
+ − 165 #ifdef OSTC_ON_DISCOVERY_HARDWARE
+ − 166 return;
+ − 167 #endif
+ − 168
+ − 169 uint16_t mAhSend;
+ − 170
+ − 171 if(percentage >= 100)
+ − 172 mAhSend = 0xFFFF;
228
+ − 173 else {
+ − 174 mAhSend = (percentage * BGG_BATTERY_DIVIDER) + BGG_BATTERY_OFFSET;
+ − 175 }
38
+ − 176
+ − 177 uint8_t bufferSend[3];
+ − 178 bufferSend[0] = 0x02;
+ − 179 bufferSend[1] = (uint8_t)(mAhSend / 256);
+ − 180 bufferSend[2] = (uint8_t)(mAhSend & 0xFF);
+ − 181 I2C_Master_Transmit( DEVICE_BATTERYGAUGE, bufferSend, 3);
242
+ − 182 init_battery_gas_gauge();
668
+ − 183 chargeValueKnown = 1;
38
+ − 184 }
+ − 185
668
+ − 186 uint8_t battery_gas_gauge_isChargeValueValid(void)
+ − 187 {
+ − 188 return chargeValueKnown;
+ − 189 }
+ − 190
+ − 191 void battery_gas_gauge_setChargeValueValid(void)
+ − 192 {
+ − 193 chargeValueKnown = 1;
+ − 194 }
38
+ − 195
+ − 196 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/