/* Copyright 2012, Sebastian Reichel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ public errordomain I2CError { IO_ERROR, ERRNO, } public class I2CDevice : Device { private int fd; public void setup(uint8 dev, uint8 addr) throws I2CError { string file = "/dev/i2c-%u".printf(dev); fd = Posix.open(file, Posix.O_RDWR); if(fd < 0) throw new I2CError.IO_ERROR("Could not open device!"); setup_address(addr); } ~I2CDevice() { Posix.close(fd); } protected void setup_address(uint8 addr) throws I2CError { if(Posix.ioctl(fd, Linux.I2C.SLAVE, addr) < 0) throw new I2CError.IO_ERROR("Could not seek to I2C device 0x%02x!", addr); } protected void write_byte(uint8 byte) throws I2CError { if(Linux.I2C.SMBUS.write_byte(fd, byte) < 0) { throw new I2CError.ERRNO("Could not write to I2C device: %s!", Posix.strerror(Posix.errno)); } } protected uint8 read_byte() throws I2CError { int rc = Linux.I2C.SMBUS.read_byte(fd); if(rc < 0) throw new I2CError.ERRNO("Could not read from I2C device: %s!", Posix.strerror(Posix.errno)); return (uint8) rc; } protected uint8 get_byte(uint8 addr) throws I2CError { int rc = Linux.I2C.SMBUS.read_word_data(fd, addr); if(rc < 0) throw new I2CError.ERRNO("Could not get byte %d from I2C device: %s!", addr, Posix.strerror(Posix.errno)); return (uint8) rc; } protected void set_byte(uint8 addr, uint8 val) throws I2CError { int rc = Linux.I2C.SMBUS.write_word_data(fd, addr, val); if(rc < 0) throw new I2CError.ERRNO("Could not set byte %d to %d from I2C device: %s!", addr, val, Posix.strerror(Posix.errno)); } protected uint16 get_big_word(uint8 addr) throws I2CError { int rc = Linux.I2C.SMBUS.read_word_data(fd, addr); if(rc < 0) throw new I2CError.ERRNO("Could get word %d from I2C device: %s!", addr, Posix.strerror(Posix.errno)); return uint16.from_big_endian((uint16) rc); } protected uint16 get_little_word(uint8 addr) throws I2CError { int rc = Linux.I2C.SMBUS.read_word_data(fd, addr); if(rc < 0) throw new I2CError.ERRNO("Could get word %d from I2C device: %s!", addr, Posix.strerror(Posix.errno)); return uint16.from_little_endian((uint16) rc); } protected uint8[] get_block(uint8 addr, uint8 size) throws I2CError { uint8[] data = new uint8[size]; int rc = Linux.I2C.SMBUS.read_i2c_block_data(fd, addr, data); if(rc < 0) throw new I2CError.ERRNO("Could get word %d from I2C device: %s!", addr, Posix.strerror(Posix.errno)); return data; } }