Mock out mgos_i2c.h to work with Linux.

This commit is contained in:
Pim van Pelt
2018-04-02 13:30:45 +02:00
commit cef7c5107d
8 changed files with 491 additions and 0 deletions

227
src/mgos_i2c.c Normal file
View File

@ -0,0 +1,227 @@
#include "mgos_i2c.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include <sys/ioctl.h>
#include <unistd.h>
struct mgos_i2c {
int fd;
char *filename;
};
static struct mgos_i2c *s_global_i2c_bus = NULL;
bool mgos_i2c_read(struct mgos_i2c *i2c, uint16_t addr, void *data, size_t len, bool stop) {
size_t ret;
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
ret = read(i2c->fd, data, len);
return (ret == len);
}
bool mgos_i2c_write(struct mgos_i2c *i2c, uint16_t addr, const void *data, size_t len, bool stop) {
size_t ret;
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
ret = write(i2c->fd, data, len);
return (ret == len);
}
void mgos_i2c_stop(struct mgos_i2c *i2c) {
return;
}
int mgos_i2c_get_freq(struct mgos_i2c *i2c) {
return MGOS_I2C_FREQ_100KHZ;
}
bool mgos_i2c_set_freq(struct mgos_i2c *i2c, int freq) {
if (freq==MGOS_I2C_FREQ_100KHZ) return true;
return false;
}
int mgos_i2c_read_reg_b(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg) {
uint8_t data;
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return -1;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return -1;
}
if (1 != write(i2c->fd, &reg, 1)) {
LOG(LL_ERROR, ("Cannot select register 0x%02x on device 0x%04x", reg, addr));
return -1;
}
if (1 != read(i2c->fd, &data, 1)) {
LOG(LL_ERROR, ("Cannot read register 0x%02x on device 0x%04x", reg, addr));
return -1;
}
return data;
}
int mgos_i2c_read_reg_w(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg) {
uint16_t data;
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return -1;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return -1;
}
if (1 != write(i2c->fd, &reg, 1)) {
LOG(LL_ERROR, ("Cannot select register 0x%02x on device 0x%04x", reg, addr));
return -1;
}
if (2 != read(i2c->fd, &data, 2)) {
LOG(LL_ERROR, ("Cannot read register 0x%02x on device 0x%04x", reg, addr));
return -1;
}
return data;
}
bool mgos_i2c_read_reg_n(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg, size_t n, uint8_t *buf) {
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
if (1 != write(i2c->fd, &reg, 1)) {
LOG(LL_ERROR, ("Cannot select register 0x%02x on device 0x%04x", reg, addr));
return false;
}
if (n != read(i2c->fd, buf, n)) {
LOG(LL_ERROR, ("Cannot read %lu bytes at register 0x%02x on device 0x%04x", n, reg, addr));
return false;
}
return true;
}
bool mgos_i2c_write_reg_b(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg, uint8_t value) {
uint8_t data[2];
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
data[0]=reg;
data[1]=value;
if (2 != write(i2c->fd, data, 2)) {
LOG(LL_ERROR, ("Cannot write to register 0x%02x on device 0x%04x", reg, addr));
return false;
}
return true;
}
bool mgos_i2c_write_reg_w(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg, uint16_t value) {
uint8_t data[3];
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
data[0]=reg;
data[1]=(uint8_t)(0xFF & (value >> 0));
data[2]=(uint8_t)(0xFF & (value >> 8));
if (3 != write(i2c->fd, data, 3)) {
LOG(LL_ERROR, ("Cannot write to register 0x%02x on device 0x%04x", reg, addr));
return false;
}
return true;
}
bool mgos_i2c_write_reg_n(struct mgos_i2c *i2c, uint16_t addr, uint8_t reg, size_t n, const uint8_t *buf) {
if (!i2c) {
LOG(LL_ERROR, ("No I2C bus"));
return false;
}
if (ioctl(i2c->fd,I2C_SLAVE,addr) < 0) {
LOG(LL_ERROR, ("Cannot select slave 0x%04x on I2C bus", addr));
return false;
}
if (1 != write(i2c->fd, &reg, 1)) {
LOG(LL_ERROR, ("Cannot select register 0x%02x on device 0x%04x", reg, addr));
return false;
}
if (n != write(i2c->fd, buf, n)) {
LOG(LL_ERROR, ("Cannot write to register 0x%02x on device 0x%04x", reg, addr));
return false;
}
return true;
}
void mgos_i2c_close(struct mgos_i2c *i2c) {
return;
}
struct mgos_i2c *mgos_i2c_get_global(void) {
return s_global_i2c_bus;
}
// User provided function to interface with Linux I2C driver
bool mgos_i2c_open(int busnr) {
int fd;
char filename[20];
struct mgos_i2c *i2c;
sprintf(filename,"/dev/i2c-%d",busnr);
if ((fd = open(filename,O_RDWR)) < 0) {
LOG(LL_ERROR, ("Could not open %s", filename));
return false;
}
i2c = calloc(1, sizeof(struct mgos_i2c));
if (!i2c) {
LOG(LL_ERROR, ("Could not allocate mgos_i2c handle for %s", filename));
return false;
}
i2c->fd=fd;
i2c->filename=strdup(filename);
s_global_i2c_bus=i2c;
LOG(LL_INFO, ("Opened I2C bus on %s", filename));
return true;
}