Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
677 lines (614 sloc) 14.7 KB
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/types.h>
#include <string.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include "tca9548.h"
#define CMD_I2C_SLAVE_FORCE 0x0706
#define SLAVE_TCA9548_ADDR 0x70
const static unsigned char cmd_unsealbq27621_wr[][2] =
{
{0x00,0x00},
{0x01,0x80},
{0x00,0x00},
{0x01,0x80},
{0x00,0x13},
{0x01,0x00}
};
static unsigned char cmd_chgChemID_wr[][2] =
{
{0x00,0x31},
{0x01,0x00}
};
static unsigned char cmd_updateblock[][2] =
{
{0x60,0x00},
{0x3e,0x52},
{0x3f,0x00}
};
const static unsigned char cmd_exit_updateblock[][2] =
{
{ 0x00, 0x42 },
{ 0x01, 0x00 },
{ 0x00, 0x20 },
{ 0x01, 0x00 }
};
const static unsigned char cmd_initdata[][2] =
{
#if 0
{ 0x43, 0x18 },
{ 0x44, 0x9c },
#else
{ 0x43, 0x0C },
{ 0x44, 0x4E },
{ 0x45, 0x5B },
{ 0x46, 0x0E },
#endif
{ 0x45, 0x2D },
{ 0x46, 0x87 },
{ 0x49, 0x0c },
{ 0x4a, 0x1C },
{ 0x54, 0x01 },
{ 0x55, 0xFD }
};
const static unsigned char cmd_current_threshold[][2] =
{
{ 0x40, 0x00 },
{ 0x41, 0x64 },
{ 0x42, 0x00 },
{ 0x43, 0x64 },
{ 0x44, 0x01 },
{ 0x45, 0xF4 },
{ 0x46, 0x00 },
{ 0x47, 0x3C },
{ 0x48, 0x3C },
{ 0x49, 0X01 }
};
int open_master(const char *pname)
{
int fd = -1 ;
if(NULL == pname)
{
return -1;
}
return open(I2C_CONTROLLER_NAME,O_RDWR);
}
int select_slave(const int fd,const unsigned int addr)
{
return ioctl(fd,CMD_I2C_SLAVE_FORCE,addr);
}
int enable_switcher_chan(const int fd,const int en_chx)
{
int ret = -1;
unsigned char val = (unsigned char)en_chx;
if((en_chx < 0x01) || ((en_chx > 0x80)))
{
return -1;
}
ret = select_slave(fd,SLAVE_TCA9548_ADDR);
if(ret < 0)
{
return -1;
}
return write_device(fd,&val,1);
}
int disable_switcher_chan(const int fd)
{
int ret = -1;
unsigned char val = DISABLE_TCA9548_ALLCH;
ret = select_slave(fd,SLAVE_TCA9548_ADDR);
if(ret < 0)
{
return -1;
}
return write_device(fd,&val,1);
}
int write_device(const int fd,const unsigned char *pdata,const unsigned int len)
{
if((fd < 0) || (NULL == pdata) || (len < 0))
{
return -1;
}
return write(fd,pdata,len);
}
void close_master(const int *pfd)
{
close(*pfd);
}
/*
1.enable switcher-chan2
2.select_device, use the addr->SLAVE_BQ27621_ADDR
3.return 0,failed to enter configmode,1,successful
*/
int bq27621_unseal(const int fd)
{
int i,ret;
static unsigned char cmd = 0x06;
int flage = 0;
unsigned short status = 0;
for(i=0;i<ARRAY_SIZE(cmd_unsealbq27621_wr);i++) //sizeof(cmd_unsealbq27621_wr[i]
{
ret = write_device(fd,cmd_unsealbq27621_wr[i],sizeof(cmd_unsealbq27621_wr[i]));
#if ZML_DEBUG
printf("\n bq27621_enter_configmode,ret=%d, buf[0]=%x,buf[1]=%x\n",ret,
cmd_unsealbq27621_wr[i][0],
cmd_unsealbq27621_wr[i][1]
);
#endif
}//for
ret = write(fd,&cmd,sizeof(cmd));
for(i=0;i<5;i++)
{
ret = read(fd, &status, sizeof(status));
#if ZML_DEBUG
printf("\nret=%d,status=0x%x\n", ret, status);
#endif
if ((status & 0x0010) == 0x0010)
{
flage = 1;
break;
}
else
{
sleep(1);
}
}
return flage;
}
/*
this function will control the bq27621 exit from config mode,and sealed it again
*/
int bq27621_exit_configmode(const int fd)
{
int ret = -1;
int i;
for (i = 0; i<ARRAY_SIZE(cmd_exit_updateblock); i++)
{
ret = write_device(fd, cmd_exit_updateblock[i], sizeof(cmd_exit_updateblock[i]));
}
return ret;
}
/*you should call bq27621_enter_configmode first
return value, none zero means success!
*/
int bq27621_chg_chemID(const int fd,const unsigned short chemID)
{
int i;
int ret = 1;
if(chemID != INVALID_CHEM_ID)
{
if(CHEM_ID_1210 == chemID)
{
cmd_chgChemID_wr[0][1] = 0x31;
}
else if(CHEM_ID_354 == chemID)
{
cmd_chgChemID_wr[0][1] = 0x32;
}
for(i=0;i<ARRAY_SIZE(cmd_chgChemID_wr);i++)
{
ret = write_device(fd,cmd_chgChemID_wr[i],sizeof(cmd_chgChemID_wr[i]));
#if ZML_DEBUG
printf("\n ret=%d, function=%s \n",ret,__func__);
#endif
}
}//if(chemID != INVALID_CHEM_ID)
return ret ;
}
/*you should call bq27621_enter_configmode first
return value, none zero means success!
type: 0 setup to the update, chksum == 0x00
1 verify the update,you should set the chksum param
*/
int bq27621_update_blcokram(const int fd,const int type,unsigned char chksum)
{
int i,ret;
if (0 == type)
{
cmd_updateblock[0][0] = 0x61;
cmd_updateblock[0][1] = 0x00;
}
else
{
cmd_updateblock[0][0] = 0x60;
cmd_updateblock[0][1] = chksum;
}
for(i=0;i<ARRAY_SIZE(cmd_updateblock);i++)
{
ret = write_device(fd, cmd_updateblock[i], sizeof(cmd_updateblock[i]));
}
return ret;
}
int bq27621_readword(const int fd, const unsigned char reg_offset, unsigned char* buf)
{
unsigned char temp = reg_offset;
if (NULL == buf)
{
return -1;
}
write_device(fd, &(temp), sizeof(temp));
return read(fd, buf, 2);
}
/*
对ba27621的电流阈值等参数进行初始化,设置默认数值,-1失败,1 成功
*/
int init_bq27621_step1(const int fd)
{
int ret = -1;
int value1 = 0;
int value2 = 0;
int temp = 0;
int i;
unsigned short status = 0;
unsigned char old_chksum = 0x0;
unsigned char newchksum = 0x0;
unsigned char old_dsgIrate[2] = { 0x0 };
unsigned char old_chgIrate[2] = { 0x0 };
unsigned char old_quitIrate[2] = { 0x0 };
unsigned char old_dsgRelaxtime[2] = { 0x0 };
unsigned char old_chgRelaxtime[1] = { 0x0 };
unsigned char old_quitRelaxtime[1] = { 0x0 };
unsigned char bufcmd[2] = { 0x0 };
ret = bq27621_unseal(fd);
if (ret != 1)
{
return -1;
}
cmd_updateblock[1][1] = 0x51;
ret = bq27621_update_blcokram(fd,0,0x00);
if (ret < 0)
{
return -1;
}
for (i = 0; i < ARRAY_SIZE(cmd_current_threshold); i++)
{
ret = write_device(fd, (cmd_current_threshold[i]), sizeof(cmd_current_threshold[i]));
}
newchksum = 0xD2;
ret = bq27621_update_blcokram(fd, 1, newchksum);
if (ret < 0)
{
return -1;
}
bq27621_readword(fd, REGOFFSET_CHECKSUM, (unsigned char*)(&status));
printf("\n bq27621_readword,status=0x%x \n",(unsigned char)status);
if ((unsigned char)status == newchksum)
{
ret = 1;
}
else
{
ret = -1;
}
bq27621_exit_configmode(fd);
return ret;
}
/*
对ba27621的Design capcity等参数进行初始化,设置默认数值,-1失败,1 成功
*/
int init_bq27621_step2(const int fd)
{
int ret = -1;
int temp;
int i;
unsigned short status = 0;
unsigned char old_chksum = 0x0;
unsigned char newchksum = 0x0;
unsigned char old_dc[2] = { 0x0 };
unsigned char old_de[2] = { 0x0 };
unsigned char old_tv[2] = { 0x0 };
unsigned char old_tr[2] = { 0x0 };
unsigned char bufcmd[2] = { 0x0 };
ret = bq27621_unseal(fd);
if (ret != 1)
{
return -1;
}
cmd_updateblock[1][1] = 0x52;
ret = bq27621_update_blcokram(fd,0,0x00);
if (ret < 0)
{
return -1;
}
bq27621_readword(fd, REGOFFSET_CHECKSUM, &old_chksum);
bq27621_readword(fd, REGOFFSET_DESIGNCAPCITY, old_dc);
bq27621_readword(fd, REGOFFSET_DESIGNENERGY, old_de);
bq27621_readword(fd, REGOFFSET_TERMINATEVOL, old_tv);
bq27621_readword(fd, REGOFFSET_TAPERATE, old_tr);
temp = 0xFF - old_chksum;
temp -= (old_de[0] + old_de[1] + old_tv[0] + old_tv[1] + old_tr[0] + old_tr[1] + old_dc[0] + old_dc[1]);
for (i = 0; i < ARRAY_SIZE(cmd_initdata); i++)
{
temp += (cmd_initdata[i][1]);
ret = write_device(fd, (cmd_initdata[i]), sizeof(cmd_initdata[i]));
}
newchksum = (unsigned char)temp;
newchksum = 0xFF - newchksum;
ret = bq27621_update_blcokram(fd, 1, newchksum);
if (ret < 0)
{
return -1;
}
bq27621_readword(fd, REGOFFSET_CHECKSUM, (unsigned char*)(&status));
if ((unsigned char)status == newchksum)
{
ret = 1;
}
else
{
ret = -1;
}
bq27621_exit_configmode(fd);
return ret;
}
//int bq27621_gecontrol_status(const int fd)
//{
// unsigned short status = 0;
// int ret = -1;
// unsigned char cmd[1] = { REGOFFSET_CONTROL_STATUS };
//
// write(fd, cmd, 1);
// ret = read(fd, (unsigned char*)(&status), 2);
// return ret;
//}
int bq27621_getflages(const int fd)
{
unsigned short status = 0;
int ret = -1;
unsigned char cmd[1] = { REGOFFSET_GETFLAGS };
write(fd, cmd, 1);
ret = read(fd, (unsigned char*)(&status), 2);
return ret;
}
/*
juge the bq2621 is charging or not,1: discharging, 0 charging,not accurency
*/
int bq27621_ischarging(const int fd)
{
unsigned short status = 0;
int ret = -1;
unsigned char cmd[1] = { REGOFFSET_GETFLAGS };
write(fd, cmd, 1);
ret = read(fd, (unsigned char*)(&status), 2);
if (ret > 0)
{
if (status & 0x0001)
{
return 1;
}
else
{
return 0;
}
}
else
{
return -1;
}
}
/*
show value of the predicted RemainingCapacity( )expressed as a percentage of FullChargeCapacity( ),
with a range of 0 to 100%,-1 means failed
*/
int bq27621_stateofcharg(const int fd)
{
unsigned short status = 0;
int ret = -1;
unsigned char cmd[1] = { REGOFFSET_STATEOFCHARGE };
write(fd, cmd, 1);
ret = read(fd, (unsigned char*)(&status), 2);
if (ret > 0)
{
return status;
}
else
{
return -1;
}
}
/*
get the voltage of bq27621,-1 means failed
*/
int bq27621_getvoltage(const int fd)
{
unsigned short status = 0;
signed int ret = -1;
unsigned char cmd[1] = { REGOFFSET_VOLTAGE };
write(fd,cmd,1);
ret = read(fd, (unsigned char*)(&status), 2);
if (ret > 0)
{
return status;
}
else
{
return -1;
}
}
/*
get the current of bq27621,,value <= 0 means discharging, value>0 charging
*/
int bq27621_getcurrent(const int fd)
{
short status = 0;
unsigned char cmd[1] = { REGOFFSET_CURRENT };
write(fd, cmd, 1);
read(fd, (unsigned char*)(&status), 2);
return status;
}
/*
get the average power of bq27621,value <= 0 means discharging, value>0 charging
*/
int bq27621_getavgpower(const int fd)
{
short status = 0;
//int ret = -1;
unsigned char cmd[1] = { REGOFFSET_AVGPOWER };
write(fd, cmd, 1);
read(fd, (unsigned char*)(&status), 2);
return status;
}
int bq27621_getremainingcapcity(const int fd)
{
short status = 0;
int ret = -1;
unsigned char cmd[1] = { REGOFFSET_GETREMAININGCAPCITY };
write(fd, cmd, 1);
ret = read(fd, (unsigned char*)(&status), 2);
if (ret > 0)
{
return status;
}
else
{
return -1;
}
}
int bq27621_getfullchargecapcity(const int fd)
{
short status = 0;
int ret = -1;
unsigned char cmd[1] = { REGOFFSET_GETRFULLCHARGECAPCITY };
write(fd, cmd, 1);
ret = read(fd, (unsigned char*)(&status), 2);
if (ret > 0)
{
return status;
}
else
{
return -1;
}
}
//--------------------------------------------------------------
#define INVALID_TEMP 0x230
#define MIN_TEMP 0x23e //+40摄氏度
#define MAX_TEMP 0x3f0 //-183摄氏度
#define MAX_RANGE (MAX_TEMP - MIN_TEMP)
#define DIFF_THRESHOLD 3
static short g_bakvalue = INVALID_TEMP;
short int irno_getbootprogress(const int fd)
{
int ret = -1 ;
unsigned short value = 0;
unsigned short diff = 0;
unsigned char ino_rdbuf[2] = {0,0};
unsigned char ino_wrbuf[2] = {0x14,0x02};
struct i2c_rdwr_ioctl_data ioctl_data;
struct i2c_msg msgs[2];
float temp = 0.0;
int percent = -1;
enable_switcher_chan(fd, ENABLE_INFRARED_CH6);
select_slave(fd, SLAVE_INFRARED_ADDR);
msgs[0].addr = SLAVE_INFRARED_ADDR;
msgs[0].len = 2;
msgs[0].flags = 0;
msgs[0].buf = ino_wrbuf;
msgs[1].addr = SLAVE_INFRARED_ADDR;
msgs[1].len = 2;
msgs[1].flags |= I2C_M_RD;
msgs[1].buf = ino_rdbuf;
ioctl_data.nmsgs = 2;
ioctl_data.msgs = msgs;
ret = ioctl(fd,I2C_RDWR,&ioctl_data);
if(ret <= 0)
{
return -1;
}
value = (unsigned short)(ino_rdbuf[0] << 8);
value |= ino_rdbuf[1];
if(g_bakvalue == INVALID_TEMP)
{
g_bakvalue = value;
}
else
{
diff = value - g_bakvalue;
g_bakvalue = value;
if(diff <= DIFF_THRESHOLD)
{
percent = 100;
g_bakvalue = INVALID_TEMP;
}
}
if(percent != 100)
{
temp = ((float)(value - MIN_TEMP)/(float)(MAX_RANGE))*100.0+0.5 ;
percent = (int)temp;
if(percent < 0)
{
percent = 0;
}
else if(percent > 100)
{
percent = 100 ;
}
}
disable_switcher_chan(fd);
#if 1
printf("\n read %s,ret = %d,ino_rdbuf[0]=0x%x,ino_rdbuf[1]=0x%x\n",\
(ret>0) ? "successfully" : "failed",ret,ino_rdbuf[0],ino_rdbuf[1]);
printf("\n read temp value = %d,current percent=%d \n",value,percent);
#endif
return percent;
}
//------------------------获取ADT7410的温度----------------------------------
//return value:INVALID_ADT7410_VALUE means failed
// if return value is avalid,temp_alarm == TEMP_ALARM_FALGE,means temp is too high,
// application should alarm;if return value is unavalid, temp_alarm and cancle_alarm
// are both unavalid too
short int g_overtemp_flage = 0;
short int adt7410_getTemperature(const int fd,short int *temp_alarm,short int *cancle_alarm)
{
int len = 0;
short int value = 0;
unsigned char ino_rdbuf[2] = {0,0};
unsigned char ino_wrbuf[2] = {0,0};
enable_switcher_chan(fd, ENABLE_ADT7410_CH3);
select_slave(fd, SLAVE_ADT7410_ADDR);
ino_wrbuf[0] = REGOFFSET_TEMP_HIGHT;
ino_rdbuf[0] = 0;
ino_rdbuf[1] = 0;
write(fd,ino_wrbuf,1);
len = read(fd,ino_rdbuf,2);
printf("read Temp,valueH=0x%x,valueL=0x%x\n",ino_rdbuf[0],ino_rdbuf[1]);
ino_wrbuf[0] = REGOFFSET_CONFIG;
ino_wrbuf[1] = 0x20;
write(fd,ino_wrbuf,2);
//sleep(1);
disable_switcher_chan(fd);
if(len >= 0)
{
value = ino_rdbuf[0];
value = ((value<<8)|ino_rdbuf[1]);
value >>= 3;
if(0x1000 == (value & 0x1000))
{
value = (value - 8192)>>4;
}
else
{
value >>= 4;
if(value >= TEMP_ALARM_THRESHOLD)
{
g_overtemp_flage = 1;
*temp_alarm = 1;
*cancle_alarm = 0;
}
if((g_overtemp_flage) && (value <= TEMP_CANCELALARM_THRESHOLD))
{
g_overtemp_flage = 0;
*temp_alarm = 0;
*cancle_alarm = 1;
}
}//else
}//if(len>0)
else
{
value = INVALID_ADT7410_VALUE;
}
return value;
}
You can’t perform that action at this time.