doc: renamed project
This commit is contained in:
committed by
Sylvan Arnold
parent
244e516bd8
commit
32618389d1
454
pico-sensor/McuLib/src/McuLC709203F.c
Normal file
454
pico-sensor/McuLib/src/McuLC709203F.c
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Erich Styger, Sarah Gander
|
||||
* All rights reserved.
|
||||
*
|
||||
* Driver for GPIO pins
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "McuLib.h"
|
||||
#if McuLib_CONFIG_CPU_IS_STM
|
||||
#include "libIIC.h"
|
||||
#endif
|
||||
#include "McuLC709203Fconfig.h"
|
||||
#include "McuLC709203F.h"
|
||||
#include "McuGenericI2C.h"
|
||||
#include "McuUtility.h"
|
||||
#include "McuWait.h"
|
||||
|
||||
#define LC709203F_I2C_SLAVE_ADDR 0x0B
|
||||
|
||||
#define LC709203F_REG_SET_BEFORE_RSOC 0x04 /* Before RSCOC */
|
||||
#define LC709203F_REG_SET_THERMB 0x06 /* Thermistor B */
|
||||
#define LC709203F_REG_INIT_RSOC 0x07 /* Initial RSOC */
|
||||
#define LC709203F_REG_CELL_TEMP 0x08 /* Cell temperature */
|
||||
#define LC709203F_REG_VOLTAGE 0x09 /* Cell voltage */
|
||||
#define LC709203F_REG_CURRENT_DIRECTION 0x0A /* Current direction */
|
||||
#define LC709203F_REG_ADJ_APPLI 0x0B /* APA, Adjustment Pack Application, sets Parasitic impedance */
|
||||
#define LC709203F_REG_APT 0x0C /* APT, Adjustment Pack Thermistor, adjust temperature measurement delay timing */
|
||||
#define LC709203F_REG_RSOC 0x0D /* RSOC, value based 0-100 scale */
|
||||
#define LC709203F_REG_ITE 0x0F /* ITE, Indicator to Empty */
|
||||
#define LC709203F_REG_IC_VER 0x11 /* IC version */
|
||||
#define LC709203F_REG_CHG_PARAM 0x12 /* change of parameter */
|
||||
#define LC709203F_REG_RSOC_ALM 0x13 /* Alarm low RSOC */
|
||||
#define LC709203F_REG_LOW_CELL_VOL_ALM 0x14 /* Alarm Low Cell Voltage */
|
||||
#define lC709203F_REG_PW_MODE 0x15 /* IC Power Mode */
|
||||
#define LC709203F_REG_EN_NTC 0x16 /* Status Bit, enable Thermistor mode */
|
||||
#define LC709203F_REG_NUM_PARAMS 0x1A /* Number of the parameter, display batter profile code */
|
||||
|
||||
#define MCULC_TEMP_ZERO_CELSIUS 0x0AAC /* From the data sheet command table: 0x0AAC is 0 degree Celsius */
|
||||
|
||||
static uint8_t i2cReadCmdData(uint8_t i2cAddr, uint8_t cmd, uint8_t *data, size_t length) {
|
||||
return McuGenericI2C_ReadAddress(i2cAddr, &cmd, sizeof(cmd), data, length);
|
||||
}
|
||||
|
||||
static uint8_t i2cWriteCmdData(uint8_t i2cAddr, uint8_t cmd, uint8_t *data, size_t length) {
|
||||
return McuGenericI2C_WriteAddress(i2cAddr, &cmd, sizeof(cmd), data, length);
|
||||
}
|
||||
|
||||
static uint8_t calcCrc8Atm(uint8_t a, uint8_t b) {
|
||||
/* the sensor uses a CRC-8-ATM,
|
||||
* Polynomial: x8 + x2 + x + 1
|
||||
* Corresponds to: 100000111
|
||||
*/
|
||||
#define POLY_8 0x8380
|
||||
uint8_t i = 0;
|
||||
uint16_t val = 0;
|
||||
|
||||
val = (uint16_t)(a^b);
|
||||
val <<= 8;
|
||||
for(i=0; i<8; i++) {
|
||||
if (val&0x8000 ){
|
||||
val ^= POLY_8;
|
||||
}
|
||||
val <<= 1;
|
||||
}
|
||||
return (uint8_t)(val >> 8);
|
||||
}
|
||||
|
||||
static uint8_t calcCRC_WriteAccess16(uint8_t i2cSlaveAddr, uint8_t cmd, uint8_t low, uint8_t high) {
|
||||
uint8_t crc;
|
||||
|
||||
crc = calcCrc8Atm(0x00, i2cSlaveAddr<<1); /* I2C slave address */
|
||||
crc = calcCrc8Atm(crc, cmd); /* command */
|
||||
crc = calcCrc8Atm(crc, low); /* data byte */
|
||||
return calcCrc8Atm(crc, high); /* data byte */
|
||||
}
|
||||
|
||||
static uint8_t calcCRC_ReadAccess16(uint8_t i2cSlaveAddr, uint8_t cmd, uint8_t low, uint8_t high) {
|
||||
uint8_t crc;
|
||||
|
||||
crc = calcCrc8Atm(0x00, i2cSlaveAddr<<1); /* I2C slave address */
|
||||
crc = calcCrc8Atm(crc, cmd); /* command */
|
||||
crc = calcCrc8Atm(crc, (i2cSlaveAddr<<1)|1); /* I2C address with R bit set */
|
||||
crc = calcCrc8Atm(crc, low); /* data byte */
|
||||
return calcCrc8Atm(crc, high); /* data byte */
|
||||
}
|
||||
|
||||
static uint8_t CheckCrc(uint8_t i2cSlaveAddr, uint8_t cmd, uint8_t low, uint8_t high, uint8_t crc) {
|
||||
uint8_t val;
|
||||
|
||||
val = calcCRC_ReadAccess16(i2cSlaveAddr, cmd, low, high);
|
||||
if (val != crc) {
|
||||
return ERR_FAILED;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static uint8_t CheckI2CErr(uint8_t res) {
|
||||
if (res==ERR_OK) {
|
||||
return ERR_OK; /* ok */
|
||||
}
|
||||
#if MCULC_CONFIG_BLOCK_ON_I2C_ERROR
|
||||
for(;;) { /* I2C Error? wait for the watchdog to kick in... */
|
||||
McuWait_WaitOSms(50);
|
||||
}
|
||||
#endif
|
||||
return ERR_FAILED;
|
||||
}
|
||||
|
||||
static uint8_t WriteCmdWordChecked(uint8_t i2cSlaveAddr, uint8_t cmd, uint8_t low, uint8_t high) {
|
||||
uint8_t data[3];
|
||||
|
||||
data[0] = low;
|
||||
data[1] = high;
|
||||
data[2] = calcCRC_WriteAccess16(i2cSlaveAddr, cmd, data[0], data[1]);
|
||||
return CheckI2CErr(i2cWriteCmdData(i2cSlaveAddr, cmd, data, sizeof(data)));
|
||||
}
|
||||
|
||||
void McuLC_Wakeup(void) {
|
||||
/* Generates wake up signal on SDA, according to the data sheet.
|
||||
* This has to happen before any other I2C communication on the bus:
|
||||
* Pull down SDA for 0.6us, then high again,
|
||||
* wait for 400 us
|
||||
* */
|
||||
#if McuLib_CONFIG_CPU_IS_STM
|
||||
/* set SDA pin of I2C to GPIO Output mode. */
|
||||
HAL_I2C_MspDeInit(&hi2c3);
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
GPIO_InitStruct.Pin = I2C_SDA_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(I2C_SDA_GPIO_Port, I2C_SDA_Pin, GPIO_PIN_RESET);
|
||||
McuWait_Waitus(1); /* SDA min 0.6us low */
|
||||
HAL_GPIO_WritePin(I2C_SDA_GPIO_Port, I2C_SDA_Pin, GPIO_PIN_SET);
|
||||
McuWait_Waitus(400); /* wait 400us */
|
||||
/* set SDA pin of I2C to GPIO Ouput mode. */
|
||||
HAL_I2C_MspInit(&hi2c3);
|
||||
#elif McuLib_CONFIG_SDK_VERSION_USED==McuLib_CONFIG_SDK_PROCESSOR_EXPERT
|
||||
PORT_PDD_SetPinMuxControl(PORTB_BASE_PTR, 3, PORT_PDD_MUX_CONTROL_ALT1); /* MUX SDA/PTB3 as GPIO */
|
||||
PORT_PDD_SetPinOpenDrain(PORTB_BASE_PTR, 3, PORT_PDD_OPEN_DRAIN_ENABLE);
|
||||
GPIO_PDD_SetPortOutputDirectionMask(PTB_BASE_PTR, (1<<3)); /* SDA/PTB3 as output */
|
||||
GPIO_PDD_ClearPortDataOutputMask(PTB_BASE_PTR, 1<<3); /* SDA/PB3 low */
|
||||
McuWait_Waitus(1); /* SDA min 0.6us low */
|
||||
GPIO_PDD_SetPortDataOutputMask(PTB_BASE_PTR, 1<<3); /* SDA/PB3 high */
|
||||
McuWait_Waitus(400); /* wait 400us */
|
||||
/* mux back to normal I2C mode with interrupts enabled */
|
||||
PORTB_PCR3 = (uint32_t)((PORTB_PCR3 & (uint32_t)~(uint32_t)(
|
||||
PORT_PCR_ISF_MASK |
|
||||
PORT_PCR_MUX(0x05)
|
||||
)) | (uint32_t)(
|
||||
PORT_PCR_MUX(0x02)
|
||||
));
|
||||
PORT_PDD_SetPinOpenDrain(PORTB_BASE_PTR, 0x03u, PORT_PDD_OPEN_DRAIN_ENABLE); /* Set SDA pin as open drain */
|
||||
#else
|
||||
/* NYI for NXP SDK yet */
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t ReadCmdWordChecked(uint8_t i2cSlaveAddr, uint8_t cmd, uint16_t *val) {
|
||||
uint8_t data[3];
|
||||
uint8_t res;
|
||||
|
||||
res = CheckI2CErr(i2cReadCmdData(i2cSlaveAddr, cmd, data, sizeof(data)));
|
||||
if (res!=ERR_OK) {
|
||||
return res;
|
||||
}
|
||||
res = CheckI2CErr(CheckCrc(i2cSlaveAddr, cmd, data[0], data[1], data[2]));
|
||||
if (res!=ERR_OK) {
|
||||
return res;
|
||||
}
|
||||
*val = (data[1]<<8) | data[0];
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/* returns cell voltage in mV */
|
||||
uint8_t McuLC_GetVoltage(uint16_t *pVoltage) {
|
||||
return ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_VOLTAGE, pVoltage);
|
||||
}
|
||||
|
||||
/* returns cell temperature (10 = 1 degree C) */
|
||||
uint8_t McuLC_GetTemperature(int16_t *pTemperature) {
|
||||
/* cell temperature is in 0.1C units, from 0x09E4 (-20C) up to 0x0D04 (60C) */
|
||||
uint8_t res;
|
||||
|
||||
res = ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_CELL_TEMP, (uint16_t*)pTemperature);
|
||||
if (res!=ERR_OK) {
|
||||
return res;
|
||||
}
|
||||
*pTemperature -= MCULC_TEMP_ZERO_CELSIUS; /* From the data sheet command table: 0x0AAC is 0 degree Celsius */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
uint8_t McuLC_SetTemperature(int16_t temperature) {
|
||||
/* cell temperature is in 0.1C units, from 0x09E4 (-20C) up to 0x0D04 (60C) */
|
||||
temperature = ((uint16_t)temperature)+MCULC_TEMP_ZERO_CELSIUS; /* From the data sheet command table: 0x0AAC is 0 degree Celsius */
|
||||
return WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_CELL_TEMP, ((uint16_t)temperature)&0xff, (((uint16_t)temperature)>>8)&0xff);
|
||||
}
|
||||
|
||||
/* returns battery Relative State of Charge in percent */
|
||||
uint8_t McuLC_GetRSOC(uint16_t *pRsoc) {
|
||||
return ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_RSOC, pRsoc);
|
||||
}
|
||||
|
||||
/* Indicator to empty, returns battery charge in thousandth */
|
||||
uint8_t McuLC_GetITE(uint16_t *pIte) {
|
||||
return ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_ITE, pIte);
|
||||
}
|
||||
|
||||
/* Indicator to empty, returns battery charge in thousandth */
|
||||
uint8_t McuLC_GetICversion(uint16_t *pVersion) {
|
||||
return ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_IC_VER, pVersion);
|
||||
}
|
||||
|
||||
#if MCULC709203F_CONFIG_PARSE_COMMAND_ENABLED
|
||||
static const unsigned char *McuLC_CurrentDirectionToString(McuLC_CurrentDirection dir) {
|
||||
switch(dir) {
|
||||
case McuLC_CURRENT_DIR_AUTO: return (const unsigned char*)"auto";
|
||||
case McuLC_CURRENT_DIR_CHARGING: return (const unsigned char*)"charging";
|
||||
case McuLC_CURRENT_DIR_DISCHARING: return (const unsigned char*)"discharging";
|
||||
case McuLC_CURRENT_DIR_ERROR:
|
||||
default: return (const unsigned char*)"ERROR";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t McuLC_GetCurrentDirection(McuLC_CurrentDirection *pDir) {
|
||||
uint16_t val;
|
||||
uint8_t res;
|
||||
|
||||
res = ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_CURRENT_DIRECTION, &val);
|
||||
if (res!=ERR_OK) {
|
||||
return res;
|
||||
}
|
||||
switch(val) {
|
||||
case 0: *pDir = McuLC_CURRENT_DIR_AUTO; break;
|
||||
case 1: return McuLC_CURRENT_DIR_CHARGING; break;
|
||||
case 0xffff: return McuLC_CURRENT_DIR_DISCHARING; break;
|
||||
default: return McuLC_CURRENT_DIR_ERROR; break;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
uint8_t McuLC_SetCurrentDirection(McuLC_CurrentDirection direction) {
|
||||
uint8_t low, high;
|
||||
|
||||
switch(direction) {
|
||||
case McuLC_CURRENT_DIR_AUTO: low = 0x00; high = 0x00; break;
|
||||
case McuLC_CURRENT_DIR_CHARGING: low = 0x01; high = 0x00; break;
|
||||
case McuLC_CURRENT_DIR_DISCHARING: low = 0xff; high = 0xff; break;
|
||||
default:
|
||||
CheckI2CErr(ERR_FAILED);
|
||||
return ERR_FAILED;
|
||||
}
|
||||
return WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_CURRENT_DIRECTION, low, high);
|
||||
}
|
||||
|
||||
#if MCULC709203F_CONFIG_PARSE_COMMAND_ENABLED
|
||||
static uint8_t PrintStatus(McuShell_ConstStdIOType *io) {
|
||||
uint8_t buf[32], res;
|
||||
|
||||
McuShell_SendStatusStr((unsigned char*)"LC", (const unsigned char*)"\r\n", io->stdOut);
|
||||
{
|
||||
uint16_t version;
|
||||
|
||||
res = McuLC_GetICversion(&version); /* battery charge in thousandth */
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"0x");
|
||||
McuUtility_strcatNum16Hex(buf, sizeof(buf), version);
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)"\r\n");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR\r\n");
|
||||
}
|
||||
McuShell_SendStatusStr((unsigned char*)" IC version", buf, io->stdOut);
|
||||
}
|
||||
{
|
||||
uint16_t rsoc;
|
||||
|
||||
res = McuLC_GetRSOC(&rsoc); /* battery charge in percent */
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_Num16uToStr(buf, sizeof(buf), rsoc);
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)"\% (0..100)\r\n");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR\r\n");
|
||||
}
|
||||
McuShell_SendStatusStr((unsigned char*)" RSOC", buf, io->stdOut);
|
||||
}
|
||||
{
|
||||
uint16_t ite;
|
||||
|
||||
res = McuLC_GetITE(&ite); /* battery charge in thousandth */
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_Num16uToStr(buf, sizeof(buf), ite);
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" (0..1000)\r\n");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR\r\n");
|
||||
}
|
||||
McuShell_SendStatusStr((unsigned char*)" ITE", buf, io->stdOut);
|
||||
}
|
||||
{
|
||||
int16_t temperature;
|
||||
bool isI2Cmode;
|
||||
|
||||
res = McuLC_GetTemperature(&temperature); /* cell temperature in 1/10-degree C */
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_Num16sToStr(buf, sizeof(buf), temperature/10);
|
||||
McuUtility_chcat(buf, sizeof(buf), '.');
|
||||
if (temperature<0) { /* make it positive */
|
||||
temperature = -temperature;
|
||||
}
|
||||
McuUtility_strcatNum16s(buf, sizeof(buf), temperature%10);
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" C");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR");
|
||||
}
|
||||
if (McuLC_GetTemperatureMeasurementMode(&isI2Cmode)==ERR_OK) {
|
||||
if (isI2Cmode) {
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" (I2C mode)");
|
||||
} else {
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" (Thermistor mode)");
|
||||
}
|
||||
} else {
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" (ERROR!)");
|
||||
}
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)"\r\n");
|
||||
McuShell_SendStatusStr((unsigned char*)" Temperature", buf, io->stdOut);
|
||||
}
|
||||
{
|
||||
uint16_t mVolt;
|
||||
|
||||
res = McuLC_GetVoltage(&mVolt); /* cell voltage in milli-volts */
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_Num16uToStr(buf, sizeof(buf), mVolt);
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)" mV\r\n");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR\r\n");
|
||||
}
|
||||
McuShell_SendStatusStr((unsigned char*)" Voltage", buf, io->stdOut);
|
||||
}
|
||||
{
|
||||
McuLC_CurrentDirection direction;
|
||||
|
||||
res = McuLC_GetCurrentDirection(&direction);
|
||||
if (res==ERR_OK) {
|
||||
McuUtility_strcpy(buf, sizeof(buf), McuLC_CurrentDirectionToString(direction));
|
||||
McuUtility_strcat(buf, sizeof(buf), (const unsigned char*)"\r\n");
|
||||
} else {
|
||||
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR\r\n");
|
||||
}
|
||||
McuShell_SendStatusStr((unsigned char*)" Current dir", buf, io->stdOut);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
#endif /* MCULC709203F_CONFIG_PARSE_COMMAND_ENABLED */
|
||||
|
||||
#if MCULC709203F_CONFIG_PARSE_COMMAND_ENABLED
|
||||
uint8_t McuLC_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) {
|
||||
uint8_t res = ERR_OK;
|
||||
const uint8_t *p;
|
||||
|
||||
if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, "LC help")==0) {
|
||||
McuShell_SendHelpStr((unsigned char*)"LC", (const unsigned char*)"Group of LC709203F commands\r\n", io->stdOut);
|
||||
McuShell_SendHelpStr((unsigned char*)" help|status", (const unsigned char*)"Print help or status information\r\n", io->stdOut);
|
||||
McuShell_SendHelpStr((unsigned char*)" settemp <temp>", (const unsigned char*)"In I2C temperature mode, set the temperature in deci-Celsius\r\n", io->stdOut);
|
||||
*handled = TRUE;
|
||||
return ERR_OK;
|
||||
} else if ((McuUtility_strcmp((char*)cmd, McuShell_CMD_STATUS)==0) || (McuUtility_strcmp((char*)cmd, "LC status")==0)) {
|
||||
*handled = TRUE;
|
||||
return PrintStatus(io);
|
||||
} else if (McuUtility_strncmp((char*)cmd, (char*)"LC settemp ", sizeof("LC settemp ")-1)==0) {
|
||||
int16_t val;
|
||||
|
||||
*handled = TRUE;
|
||||
p = cmd+sizeof("LC settemp ")-1;
|
||||
if (McuUtility_ScanDecimal16sNumber(&p, &val)!=ERR_OK) {
|
||||
return ERR_FAILED;
|
||||
}
|
||||
return McuLC_SetTemperature(val);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif /* MCULC709203F_CONFIG_PARSE_COMMAND_ENABLED */
|
||||
|
||||
uint8_t McuLC_GetTemperatureMeasurementMode(bool *isI2Cmode) {
|
||||
uint16_t val=0;
|
||||
uint8_t res;
|
||||
|
||||
res = ReadCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_EN_NTC, &val);
|
||||
if (res!=ERR_OK) {
|
||||
return res;
|
||||
}
|
||||
*isI2Cmode = val==0; /* 0: i2c, 1: thermistor mode */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
uint8_t McuLC_SetTemperatureMeasurementMode(bool i2cMode) {
|
||||
return WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_EN_NTC, i2cMode?0x00:0x01, 0x0);
|
||||
}
|
||||
|
||||
uint8_t McuLC_SetPowerMode(bool sleepMode) {
|
||||
return WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, lC709203F_REG_PW_MODE, sleepMode?0x02:0x01, 0x00);
|
||||
}
|
||||
|
||||
uint8_t McuLC_Init(void) {
|
||||
/* initializes LC709203F for Renata ICP543759PMT battery */
|
||||
uint8_t res;
|
||||
|
||||
/* operational mode (1: operational, 2: sleep), 0x0001 = operational mode */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, lC709203F_REG_PW_MODE, 0x01, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
/* APA, set parasitic impedance (table 7 in data sheet): 0x000C, value for 280mA */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_ADJ_APPLI, 0x0C, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
/* Battery Profile (table 8 in data sheet): 0x0001 = Type 1 */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_CHG_PARAM, 0x01, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
/* write 0xAA55 to initialize RSOC */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_INIT_RSOC, 0x55, 0xAA);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
/* Set battery measurement mode: 0x0001: thermistor mode. 0x0000: I2C mode */
|
||||
#if MCULC709203F_CONFIG_USE_THERMISTOR
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_EN_NTC, 0x01, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
#else
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_EN_NTC, 0x00, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
#endif
|
||||
/* set the B-constant of the thermistor to be measured */
|
||||
#if MCULC709203F_CONFIG_USE_THERMISTOR
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_SET_THERMB, 0x6B, 0x0D); /* Thermistor B-Constant: 0x0D6B = B=3435 */
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
#endif
|
||||
|
||||
/* Low voltage alarm setting: 0x0C1C = 3100mV = 3.1V, low byte first */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_LOW_CELL_VOL_ALM, 0x1C, 0x0C);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
/* 0x0000 = alarm disable, low byte first */
|
||||
res = WriteCmdWordChecked(LC709203F_I2C_SLAVE_ADDR, LC709203F_REG_RSOC_ALM, 0x00, 0x00);
|
||||
if (res!=ERR_OK) { return ERR_FAILED; }
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void McuLC_Deinit(void) {
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user