#ifdef __linux__
#include "port.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __ANDROID__
#define I2C_SLAVE 0x0703 /* Use this slave address */
#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
#else
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#endif
#include <sys/ioctl.h>
static varlen_cmd i2c_cmd_get_reply[] = {
{0x10, 11},
{0x11, 17},
{0x12, 18},
{0}};
PortI2c::PortI2c(const port_options&ops):Port("i2c",PORT_STRETCH_W,i2c_cmd_get_reply) {}
port_if::err_t port_i2c::open(const port_options *ops) {
int ret;
unsigned long funcs;
/* 1. check device name match */
if (strncmp(ops->device, "/dev/i2c-", strlen("/dev/i2c-"))) return ERR_NODEV;
/* 2. check options */
addr = ops->bus_addr;
if (addr < 0x03 || addr > 0x77) {
fprintf(stderr, "I2C address out of range [0x03-0x77]\n");
return ERR_UNKNOWN;
}
/* 3. open it */
fd = open(ops->device, O_RDWR);
if (fd < 0) {
fprintf(stderr, "Unable to open special file \"%s\"\n",ops->device);
return ERR_UNKNOWN;
}
/* 3.5. Check capabilities */
ret = ioctl(fd, I2C_FUNCS, &funcs);
if (ret < 0) {
fprintf(stderr, "I2C ioctl(funcs) error %d\n", errno);
close(fd);
return ERR_UNKNOWN;
}
if (!(funcs & 1)) {
fprintf(stderr, "Error: controller is not I2C, only SMBUS.\n");
close(fd);
return ERR_UNKNOWN;
}
/* 4. set options */
ret = ioctl(fd, I2C_SLAVE, addr);
if (ret < 0) {
fprintf(stderr, "I2C ioctl(slave) error %d\n", errno);
close(fd);
return ERR_UNKNOWN;
}
return OK;
}
port_if::err_t port_i2c::close() {
close(fd);
return ERR_OK;
}
port_if::err_t PortI2c::read(void*buf, unsigned nbyte) const{
return read(fd, buf, nbyte)==(int)nbyte ? OK : ERR_UNKNOWN;
}
port_if::err_t PortI2c::write(const void *buf, unsigned nbyte) const{
return write(fd, buf, nbyte)==(int)nbyte ? OK : ERR_UNKNOWN;
}
port_if::err_t PortI2c::gpio(serial_gpio_t,bool) {return OK};
const char*PortI2c::get_cfg_str() const{
static char str[12];
snprintf(str, sizeof(str), "addr 0x%2x", addr);
return str;
}
port_if::err_t PortI2c::flush() const{return OK;}
#endif
Vorgefundene Kodierung: UTF-8 | 0
|