Quelltext /~heha/hsn/bl/stm32flash.zip/src/i2c.cpp

#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: ASCII (7 bit)2