alix-usv/Host/i2c-test.c

161 lines
2.8 KiB
C
Raw Normal View History

2009-03-11 21:25:34 +01:00
/*
* config file:
* - i2c device
* - i2c address
* - email-address
* - reporting config (when logging / mailing)
* - thresholds for do shutdown
*
* parameters:
* -d run as daemon
* -f foreground
* -v debug
* -c [idle|charge|test|poweroff] command (not with -d)
* --config
* --help
*
* in command mode try to use daemon first (via unix-socket)
* then fallback to i2c
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
2009-03-11 21:57:57 +01:00
#include "i2c-dev.h"
2009-03-11 21:25:34 +01:00
2009-03-11 21:57:57 +01:00
enum {
REG_STATUS = 0x00,
REG_CURRENT = 0x10,
REG_UBAT = 0x11,
REG_UIN = 0x12,
REG_UIN_LOSS = 0x20,
REG_UIN_RESTORE = 0x21,
REG_UBAT_FULL = 0x22,
REG_UBAT_LOW = 0x23,
REG_UBAT_CRIT = 0x24,
REG_IBAT_FULL = 0x25,
REG_CRC = 0x26,
};
struct usv_data {
uint16_t sys_state;
2009-03-11 21:25:34 +01:00
int16_t adc_current;
int16_t adc_ubat;
int16_t adc_uin;
int16_t uin_loss;
int16_t uin_restore;
int16_t ubat_full;
int16_t ubat_low;
int16_t ubat_critical;
int16_t ibat_full;
uint16_t crc16;
2009-03-11 21:57:57 +01:00
};
2009-03-11 21:25:34 +01:00
enum {
STATE_IDLE = 0x01,
STATE_TEST = 0x02,
STATE_CHARGE = 0x04,
STATE_DISCHARGE = 0x08,
STATE_POWEROFF = 0x10,
};
static char * state2str(uint8_t state)
{
switch (state) {
case STATE_IDLE:
return "STATE_IDLE";
case STATE_TEST:
return "STATE_TEST";
case STATE_CHARGE:
return "STATE_CHARGE";
case STATE_DISCHARGE:
return "STATE_DISCHARGE";
case STATE_POWEROFF:
return "STATE_POWEROFF";
default:
return "<UNKNOWN>";
}
}
static int i2c_open(const char *path)
{
int fd = open(path, O_RDWR);
if (fd < 0) {
perror("open()");
return -1;
}
unsigned long funcs;
if (ioctl(fd, I2C_FUNCS, &funcs)) {
perror("ioctl(I2C_FUNCS)");
close(fd);
return -1;
}
2009-03-11 21:57:57 +01:00
if ((funcs & I2C_FUNC_SMBUS_WORD_DATA) != I2C_FUNC_SMBUS_WORD_DATA) {
fprintf(stderr, "I2C_FUNC_SMBUS_WORD_DATA not supported!\n");
2009-03-11 21:25:34 +01:00
close(fd);
return -1;
}
return fd;
}
static int i2c_setaddress(int fd, int address)
{
if (ioctl(fd, I2C_SLAVE, address) < 0) {
perror("ioctl(I2C_SLAVE)");
close(fd);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int fd = i2c_open("/dev/i2c-0");
if (fd < 0)
exit(-1);
if (i2c_setaddress(fd, 0x10) < 0)
exit(-1);
while (1) {
2009-03-11 21:57:57 +01:00
struct usv_data usv;
memset(&usv, 0, sizeof(usv));
2009-03-11 21:25:34 +01:00
2009-03-11 21:57:57 +01:00
usv.sys_state = i2c_smbus_read_word_data(fd, REG_STATUS);
usv.adc_current = i2c_smbus_read_word_data(fd, REG_CURRENT);
usv.adc_ubat = i2c_smbus_read_word_data(fd, REG_UBAT);
usv.adc_uin = i2c_smbus_read_word_data(fd, REG_UIN);
2009-03-11 21:25:34 +01:00
printf("state:0x%02x I:%5dmA Ubat:%5dmV Usup:%5dmV (%s) [%5d,%5d,%5d,%5d,%5d,%5d,0x%04x]\n",
2009-03-11 21:57:57 +01:00
usv.sys_state, usv.adc_current, usv.adc_ubat,
usv.adc_uin, state2str(usv.sys_state),
usv.uin_loss, usv.uin_restore, usv.ubat_full,
usv.ubat_low, usv.ubat_critical, usv.ibat_full,
usv.crc16);
2009-03-11 21:25:34 +01:00
sleep(1);
}
close(fd);
return 0;
}