--- /dev/null
+
+STAGING_DIR=/var/www/builder/data/trunk/build_ng/openwrt/staging_dir
+export STAGING_DIR
+CFLAGS=-I.
+#
+# Atheros
+CC= ~/trunk/build_ng/openwrt/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-uclibc-gcc
+#
+# Broadcom
+#CC= ~/trunk/build_ng/openwrt/staging_dir/toolchain-mips_gcc-4.6-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-uclibc-gcc
+
+
+
+ina219:
+ $(CC) -o ina219 ina219.c
+
+bmp085:
+ $(CC) -o bmp085 bmp085.c smbus.c
+
+lm75:
+ $(CC) -o lm75 lm75.c
+
+ds1621:
+ $(CC) -o ds1621 ds1621.c
+
+bh1750:
+ $(CC) -o bh1750 bh1750.c smbus.c
+
+lcdd:
+ $(CC) -o lcdd lcdd.c
+
+mcp_rw:
+ $(CC) -o mcp mcp_rw.c smbus.c
--- /dev/null
+/*
+ AD5602_test1.c
+ ---------------------
+ set the output voltage from the D/A
+ -----------------------------------
+
+ 1) send the i2c address
+ 2) send HI_byte
+ 3) send LO_byte
+
+ usage :- type with spaces but without the < >
+ <AD5602_test1> <address as decimal> <HI_byte> <LO_byte>
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/i2c.h>
+
+int main(int argc, char** argv)
+{
+ int i2c;
+ int HI_byte; /* last 4 bits are output byte HI bits */
+ int LO_byte; /* first 4 bits are output byte LO bits */
+ int buf[1]; /* use to feed the i2c driver */
+ int address; /* i2c bus address */
+
+ if (argc != 4) /* report error if we are not getting just 3 inputs after the program name */
+ {
+ printf("Error. usage (decimal): %s AD5602_test1 address HI_byte LO_byte\n", argv[0]);
+ }
+
+ address = atoi(argv[1]); /* address is the first number after the program name */
+ // address bits are 0 0 0 1 1 1 0 R/W as per manual
+ // the 1 0 before R/W is for the address pin (pin 1) open-circuit
+ // the R/W is 0 for write. Linux see the chip address as 0000 1110 (0E) - shifts a bit to the left - odd!
+ HI_byte = atoi(argv[2]); /* HI_byte is 0 0 0 0 D7 D6 D5 D4 */
+ LO_byte = atoi(argv[3]); /* LO_byte is D3 D2 D1 D0 X X X X (X = anything) */
+
+ i2c = open("/dev/i2c/0",O_RDWR); /* open the i2c-bus number 0 */
+
+ ioctl(i2c,I2C_SLAVE,address); /* set the i2c-bus address of the chip we will talk to */
+
+ buf[0] = HI_byte; /* HI_byte */
+ buf[1] = LO_byte; /* LO_byte */
+
+
+ write(i2c,buf,2); /* we send 2 bytes <HI_byte> <LO_byte> */
+
+ printf("%d\n", buf[0]); /* just to prove it ran!*/
+ printf("%d\n", buf[1]);
+
+ i2c = close(i2c);
+}
+
+// AD5602_test1 14 0 0 gives 0 volts
+// AD5602_test1 14 8 0 gives 2.5 volts 8 = 08 00001000 0 = 00 00000000
+// AD5602_test1 14 15 240 gives 5 volts 15 = 0F 00001111 240 = F0 11110000
+
--- /dev/null
+#!/bin/sh
+
+I2CBUS=0
+I2CADDR=0x48
+
+if [ "$1" == "" ]
+then
+ pin=0
+else
+ pin=$1
+fi
+
+case "$pin" in
+ "0") CFG="0xc583" ;;
+ "1") CFG="0xc593" ;;
+ "2") CFG="0xc5a3" ;;
+ "3") CFG="0xc5b3" ;;
+ *) echo "Bad pin number $pin, must be 0..3" ; exit 1 ;;
+esac
+
+i2cset -y 0 0x48 1 $CFG w
+RES=`i2cget -y 0 0x48 1 w`
+until [ "$RES" = "$CFG" ] ; do
+ RES=`i2cget -y 0 0x48 1 w`
+done
+X=`i2cget -y 0 0x48 0 w`
+
+XX="0x0`echo $X | cut -c 5-6``echo $X | cut -c 3`"
+VIND=$(( ( $XX + 32768 / 40960 ) * 20480 / 32768 ))
+VIN=$(( $VIND / 10 ))
+VINF=$(( $VIND - $VIN * 10 ))
+
+printf "VIN$pin (mv) %d.%01d\n" $VIN $VINF
--- /dev/null
+/*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*
+* Project Home - https://github.com/takagi/am2321
+*
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h> /* for O_RDWR */
+#include <string.h> /* for memcpy */
+#include <linux/i2c-dev.h> /* for I2C_SLAVE */
+
+#include <unistd.h> /* add by paulerr*/
+#include <sys/time.h> /* add by paulerr*/
+
+
+/* I2C character device */
+#define I2C_DEVICE "/dev/i2c-0"
+
+/* I2C address of AM2321 sensor in 7 bits
+ * - the first 7 bits should be passed to ioctl system call
+ * because the least 1 bit of the address represents read/write
+ * and the i2c driver takes care of it
+ */
+#define AM2321_ADDR (0xB8 >> 1)
+
+
+/*
+ * udelay function
+ */
+
+long timeval_to_usec( struct timeval tm ) {
+ return tm.tv_sec * 1000000 + tm.tv_usec;
+}
+
+void udelay( long us ) {
+ struct timeval current;
+ struct timeval start;
+
+ gettimeofday( &start, NULL );
+ do {
+ gettimeofday( ¤t, NULL );
+ } while( timeval_to_usec( current ) - timeval_to_usec( start ) < us );
+}
+
+
+/*
+ * CRC16
+ */
+
+unsigned short crc16( unsigned char *ptr, unsigned char len ) {
+ unsigned short crc = 0xFFFF;
+ unsigned char i;
+
+ while( len-- )
+ {
+ crc ^= *ptr++;
+ for( i = 0; i < 8; i++ ) {
+ if( crc & 0x01 ) {
+ crc >>= 1;
+ crc ^= 0xA001;
+ } else {
+ crc >>= 1;
+ }
+ }
+ }
+
+ return crc;
+}
+
+unsigned char crc16_low( unsigned short crc ) {
+ return crc & 0xFF;
+}
+
+unsigned char crc16_high( unsigned short crc ) {
+ return crc >> 8;
+}
+
+
+/*
+ * st_am2321 Structure
+ */
+
+typedef struct {
+ unsigned char data[8];
+} st_am2321;
+
+void __check_crc16( st_am2321 measured ) {
+ unsigned short crc_m, crc_s;
+
+ crc_m = crc16( measured.data, 6 );
+ crc_s = (measured.data[7] << 8) + measured.data[6];
+ if ( crc_m != crc_s ) {
+ fprintf( stderr, "am2321: CRC16 does not match\n" );
+ exit( 1 );
+ }
+
+ return;
+}
+
+st_am2321 __st_am2321( unsigned char* data ) {
+ st_am2321 result;
+ memcpy( result.data, data, 8 );
+ __check_crc16( result );
+ return result;
+}
+
+void am2321_dump( st_am2321 measured ) {
+ printf( "[ 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x ]\n",
+ measured.data[0], measured.data[1],
+ measured.data[2], measured.data[3],
+ measured.data[4], measured.data[5],
+ measured.data[6], measured.data[7] );
+ return;
+}
+
+short __am2321_temperature( st_am2321 measured ) {
+ return (measured.data[4] << 8) + measured.data[5];
+}
+
+short am2321_temperature_integral( st_am2321 measured ) {
+ return __am2321_temperature( measured ) / 10;
+}
+
+short am2321_temperature_fraction( st_am2321 measured ) {
+ return __am2321_temperature( measured ) % 10;
+}
+
+short __am2321_humidity( st_am2321 measured ) {
+ return (measured.data[2] << 8) + measured.data[3];
+}
+
+short am2321_humidity_integral( st_am2321 measured ) {
+ return __am2321_humidity( measured ) / 10;
+}
+
+short am2321_humidity_fraction( st_am2321 measured ) {
+ return __am2321_humidity( measured ) % 10;
+}
+
+
+/*
+ * Measurement function
+ */
+
+st_am2321 am2321() {
+ int fd;
+ int ret;
+ int retry_cnt;
+ unsigned char data[8];
+
+ /* open I2C device */
+ fd = open( I2C_DEVICE, O_RDWR );
+ if ( fd < 0 ) {
+ perror( "am2321(1)" );
+ exit( 1 );
+ }
+
+ /* set address of I2C device in 7 bits */
+ ret = ioctl( fd, I2C_SLAVE, AM2321_ADDR );
+ if ( ret < 0 ) {
+ perror( "am2321(2)" );
+ exit( 2 );
+ }
+
+ retry_cnt = 0;
+ retry:
+
+ /* wake I2C device up */
+ write( fd, NULL, 0);
+
+ /* write measurement request */
+ data[0] = 0x03; data[1] = 0x00; data[2] = 0x04;
+ ret = write( fd, data, 3 );
+ if ( ret < 0 && retry_cnt++ < 5 ) {
+ fprintf( stderr, "am2321: retry\n" );
+ udelay( 1000 );
+ goto retry;
+ }
+ if ( ret < 0 ) {
+ perror( "am2321(3)" );
+ exit( 3 );
+ }
+
+ /* wait for having measured */
+ udelay( 1500 );
+
+ /* read measured result */
+ memset( data, 0x00, 8 );
+ ret = read( fd, data, 8 );
+ if ( ret < 0 ) {
+ perror( "am2321(4)" );
+ exit( 4 );
+ }
+
+ /* close I2C device */
+ close( fd );
+
+ return __st_am2321( data );
+}
+
+st_am2321 am2321_stub() {
+ unsigned char data[] = { 0x03, 0x04, 0x01, 0x41,
+ 0x00, 0xEA, 0x21, 0x8F };
+ return __st_am2321( data );
+}
+
+
+/*
+ * Print functions
+ */
+
+void print_am2321( st_am2321 measured ) {
+ printf( "%d.%d %d.%d\n",
+ am2321_temperature_integral( measured ),
+ am2321_temperature_fraction( measured ),
+ am2321_humidity_integral( measured ),
+ am2321_humidity_fraction( measured ) );
+ return;
+}
+
+void print_am2321_human_readable( st_am2321 measured ) {
+ printf( "Temperature (C)\t\t%d.%d\n",
+ am2321_temperature_integral( measured ),
+ am2321_temperature_fraction( measured ) );
+ printf( "Humidity (%%)\t\t%d.%d\n",
+ am2321_humidity_integral( measured ),
+ am2321_humidity_fraction( measured ) );
+ return;
+}
+
+/*
+ * Main
+ */
+
+#define OPT_HUMAN_READABLE 0x1
+#define OPT_STUB 0x2
+
+int print_help() {
+ fprintf( stderr,
+ "Usage: am2321 [-r] [-s]\n"
+ "Get temperature and humidity measured with Aosong's AM2321 sensor.\n"
+ " -r human readable output\n"
+ " -s not measure with AM2321, instead stub of 23.4[C] and 32.1[%]\n" );
+ exit( 1 );
+}
+
+int parse_options( int argc, char* argv[]) {
+ int options = 0;
+ int flags = 0;
+
+ while( 1+flags < argc && argv[1+flags][0] == '-' ) {
+ switch( argv[1+flags][1] ) {
+ case 'r': options |= OPT_HUMAN_READABLE; break;
+ case 's': options |= OPT_STUB; break;
+ default:
+ fprintf( stderr, "am2321: Unsupported option \"%s\"\n", argv[1+flags] );
+ print_help();
+ exit( 1 );
+ }
+ flags++;
+ }
+
+ return options;
+}
+
+int is_opt_human_readable( int options ) {
+ return options & OPT_HUMAN_READABLE;
+}
+
+int is_opt_stub( int options ) {
+ return options & OPT_STUB;
+}
+
+int main( int argc, char* argv[] ) {
+ int options;
+ st_am2321 measured;
+
+ /* parse the given options */
+ options = parse_options( argc, argv );
+
+ /* measure temperature and humidity */
+ measured = ! is_opt_stub( options ) ? am2321() : am2321_stub();
+
+ /* print measured temperature and humidity */
+ if ( ! is_opt_human_readable( options ) ) {
+ print_am2321( measured );
+ } else {
+ print_am2321_human_readable( measured );
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ Sample code for the BH1750
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include "smbus.h"
+
+#define BH1750FVI_I2C_ADDRESS 0x23 // ADDR > 0.7 VCC)
+//#define BH1750FVI_I2C_ADDRESS 0x53 // ADDR < 0.3 VCC)
+#define DEBUG 0
+
+#define PowerDown 0x00
+#define PowerOn 0x01
+#define Reset 0x07
+#define ContinuHigh 0x10
+#define ContinuLow 0x13
+#define OneTimeHigh 0x20
+#define OneTimeLow 0x23
+
+int main(int argc, char **argv)
+{
+ int fd;
+ char *fileName = "/dev/i2c-0";
+ int retCode;
+ int readSize;
+ unsigned int res;
+ unsigned int lux;
+ char buf[5];
+ int i;
+
+ // Open port for reading and writing
+ if ((fd = open(fileName, O_RDWR)) < 0) {
+ printf("open error\n");
+ exit(1);
+ }
+
+ // Set the port options and set the address of the device
+ if (ioctl(fd, I2C_SLAVE, BH1750FVI_I2C_ADDRESS) < 0) {
+ printf("ioctl error\n");
+ close(fd);
+ exit(1);
+ }
+
+ retCode=i2c_smbus_write_byte(fd, PowerOn);
+if(DEBUG)printf("Power On retCode=%d\n",retCode);
+ if (retCode < 0) {
+ printf("PowerOn error\n");
+ close(fd);
+ exit(1);
+ }
+
+ retCode=i2c_smbus_write_byte(fd, ContinuHigh);
+if(DEBUG)printf("ContinuHigh retCode=%d\n",retCode);
+ if (retCode < 0) {
+ printf("ContinuHigh error\n");
+ close(fd);
+ exit(1);
+ }
+
+ // Set i<10 for more one check
+ for(i=0;i<1;i++) {
+ sleep(3);
+ readSize = read (fd, buf, 2);
+if(DEBUG)printf("read readSize=%d %x %x\n",readSize,buf[0],buf[1]);
+
+ res = buf[0]*256+buf[1];
+if(DEBUG)printf("res=%x\n",res);
+ lux = res / 1.2;
+ // printf("Lux=%d\n",lux);
+ printf("Brightness (Lux)\t%0.1f\n", ((double)lux));
+ }
+
+ retCode=i2c_smbus_write_byte(fd, PowerDown);
+ close(fd);
+
+ exit (0);
+}
\ No newline at end of file
--- /dev/null
+/*
+ Sample code for the BMP085
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include "smbus.h"
+
+#define BMP085_I2C_ADDRESS 0x77
+
+const unsigned char BMP085_OVERSAMPLING_SETTING = 3;
+
+// Calibration values - These are stored in the BMP085
+short int ac1;
+short int ac2;
+short int ac3;
+unsigned short int ac4;
+unsigned short int ac5;
+unsigned short int ac6;
+short int b1;
+short int b2;
+short int mb;
+short int mc;
+short int md;
+
+int b5;
+
+unsigned int temperature, pressure;
+
+
+// Open a connection to the bmp085
+// Returns a file id
+int bmp085_i2c_Begin()
+{
+ int fd;
+ char *fileName = "/dev/i2c-0";
+
+ // Open port for reading and writing
+ if ((fd = open(fileName, O_RDWR)) < 0)
+ exit(1);
+
+ // Set the port options and set the address of the device
+ if (ioctl(fd, I2C_SLAVE, BMP085_I2C_ADDRESS) < 0) {
+ close(fd);
+ exit(1);
+ }
+
+ return fd;
+}
+
+// Read two words from the BMP085 and supply it as a 16 bit integer
+__s32 bmp085_i2c_Read_Int(int fd, __u8 address)
+{
+ __s32 res = i2c_smbus_read_word_data(fd, address);
+ if (res < 0) {
+ close(fd);
+ exit(1);
+ }
+
+ // Convert result to 16 bits and swap bytes
+ res = ((res<<8) & 0xFF00) | ((res>>8) & 0xFF);
+
+ return res;
+}
+
+//Write a byte to the BMP085
+void bmp085_i2c_Write_Byte(int fd, __u8 address, __u8 value)
+{
+ if (i2c_smbus_write_byte_data(fd, address, value) < 0) {
+ close(fd);
+ exit(1);
+ }
+}
+
+// Read a block of data BMP085
+void bmp085_i2c_Read_Block(int fd, __u8 address, __u8 length, __u8 *values)
+{
+ if(i2c_smbus_read_i2c_block_data(fd, address,length,values)<0) {
+ close(fd);
+ exit(1);
+ }
+}
+
+
+void bmp085_Calibration()
+{
+ int fd = bmp085_i2c_Begin();
+ ac1 = bmp085_i2c_Read_Int(fd,0xAA);
+ ac2 = bmp085_i2c_Read_Int(fd,0xAC);
+ ac3 = bmp085_i2c_Read_Int(fd,0xAE);
+ ac4 = bmp085_i2c_Read_Int(fd,0xB0);
+ ac5 = bmp085_i2c_Read_Int(fd,0xB2);
+ ac6 = bmp085_i2c_Read_Int(fd,0xB4);
+ b1 = bmp085_i2c_Read_Int(fd,0xB6);
+ b2 = bmp085_i2c_Read_Int(fd,0xB8);
+ mb = bmp085_i2c_Read_Int(fd,0xBA);
+ mc = bmp085_i2c_Read_Int(fd,0xBC);
+ md = bmp085_i2c_Read_Int(fd,0xBE);
+ close(fd);
+}
+
+// Read the uncompensated temperature value
+unsigned int bmp085_ReadUT()
+{
+ unsigned int ut = 0;
+ int fd = bmp085_i2c_Begin();
+
+ // Write 0x2E into Register 0xF4
+ // This requests a temperature reading
+ bmp085_i2c_Write_Byte(fd,0xF4,0x2E);
+
+ // Wait at least 4.5ms
+ usleep(5000);
+
+ // Read the two byte result from address 0xF6
+ ut = bmp085_i2c_Read_Int(fd,0xF6);
+
+ // Close the i2c file
+ close (fd);
+
+ return ut;
+}
+
+// Read the uncompensated pressure value
+unsigned int bmp085_ReadUP()
+{
+ unsigned int up = 0;
+ int fd = bmp085_i2c_Begin();
+
+ // Write 0x34+(BMP085_OVERSAMPLING_SETTING<<6) into register 0xF4
+ // Request a pressure reading w/ oversampling setting
+ bmp085_i2c_Write_Byte(fd,0xF4,0x34 + (BMP085_OVERSAMPLING_SETTING<<6));
+
+ // Wait for conversion, delay time dependent on oversampling setting
+ usleep((2 + (3<<BMP085_OVERSAMPLING_SETTING)) * 1000);
+
+ // Read the three byte result from 0xF6
+ // 0xF6 = MSB, 0xF7 = LSB and 0xF8 = XLSB
+ __u8 values[3];
+ bmp085_i2c_Read_Block(fd, 0xF6, 3, values);
+
+ up = (((unsigned int) values[0] << 16) | ((unsigned int) values[1] << 8) | (unsigned int) values[2]) >> (8-BMP085_OVERSAMPLING_SETTING);
+
+ return up;
+}
+
+// Calculate pressure given uncalibrated pressure
+// Value returned will be in units of XXXXX
+unsigned int bmp085_GetPressure(unsigned int up)
+{
+ int x1, x2, x3, b3, b6, p;
+ unsigned int b4, b7;
+
+ b6 = b5 - 4000;
+ // Calculate B3
+ x1 = (b2 * (b6 * b6)>>12)>>11;
+ x2 = (ac2 * b6)>>11;
+ x3 = x1 + x2;
+ b3 = (((((int)ac1)*4 + x3)<<BMP085_OVERSAMPLING_SETTING) + 2)>>2;
+
+ // Calculate B4
+ x1 = (ac3 * b6)>>13;
+ x2 = (b1 * ((b6 * b6)>>12))>>16;
+ x3 = ((x1 + x2) + 2)>>2;
+ b4 = (ac4 * (unsigned int)(x3 + 32768))>>15;
+
+ b7 = ((unsigned int)(up - b3) * (50000>>BMP085_OVERSAMPLING_SETTING));
+ if (b7 < 0x80000000)
+ p = (b7<<1)/b4;
+ else
+ p = (b7/b4)<<1;
+
+ x1 = (p>>8) * (p>>8);
+ x1 = (x1 * 3038)>>16;
+ x2 = (-7357 * p)>>16;
+ p += (x1 + x2 + 3791)>>4;
+
+ return p;
+}
+
+// Calculate temperature given uncalibrated temperature
+// Value returned will be in units of 0.1 deg C
+unsigned int bmp085_GetTemperature(unsigned int ut)
+{
+ int x1, x2;
+
+ x1 = (((int)ut - (int)ac6)*(int)ac5) >> 15;
+ x2 = ((int)mc << 11)/(x1 + md);
+ b5 = x1 + x2;
+
+ unsigned int result = ((b5 + 8)>>4);
+
+ return result;
+}
+
+int main(int argc, char **argv)
+{
+ bmp085_Calibration();
+ temperature = bmp085_GetTemperature(bmp085_ReadUT());
+ pressure = bmp085_GetPressure(bmp085_ReadUP());
+
+ printf("Temperature (C)\t\t%0.1f\n", ((double)temperature)/10);
+ printf("Pressure (mBar)\t%0.2f\n", ((double)pressure)/100);
+ // printf("Pressure (mmHg)\t%0.2f\n", ((double)pressure)/100*0.75006375541921);
+ // printf("Pressure (mmHg)\t\t%0.2f\n", ((double)pressure)/100*0.750061683);
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/* Test DS1621 sur interface I2C GPIO Fonera (3/2008) */
+/* Inspir de "Un bus i2c pour La Fonera" */
+/* http://www.lefinnois.net/wp/index.php/2007/05/05/un-bus-i2c-pour-la-fonera/ */
+
+/* Affichage de la t */
+/* Par domos domos78<at>free<point>fr */
+/* http://vesta.homelinux.net/ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+
+#define I2C_SLAVE 0x0703 // Change slave address
+
+static int i2c_fd ;
+int res ;
+
+#define DEVICE "/dev/i2c-0"
+#define ds1621_addr 0x9E >> 1 // 0x4f - Address (A0+A1+A2 to Vcc)
+
+
+/*------------------------------------------------------------------------------*/
+/* Fonctions i2c */
+/*------------------------------------------------------------------------------*/
+void i2c_init()
+{
+ if ((i2c_fd = open(DEVICE, O_RDWR)) < 0)
+ {
+ fprintf(stderr, "Erreur ouverture port: %s (%d)\n", strerror(errno), errno);
+ exit(EXIT_FAILURE);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SelectSlave(unsigned char slaveaddr)
+{
+ if (ioctl(i2c_fd, I2C_SLAVE, slaveaddr) < 0)
+ {
+ fprintf(stderr, "Erreur selection esclave i2c: %s (%d)\n", strerror(errno), errno);
+ close ( i2c_fd ) ;
+ exit(EXIT_FAILURE) ;
+ }
+}
+
+/*------------------------------------------------------------------------------*/
+/* Fonctions DS1621 */
+/*------------------------------------------------------------------------------*/
+int i2c_init_ds1621(unsigned char addr)
+{
+ int res ;
+ char buff[10] ;
+
+ SelectSlave(addr) ;
+ buff[0] = 0xAC ;
+ buff[1] = 0x01 ;
+ res = write( i2c_fd, buff, 2 );
+ if ( res < 0 )
+ {
+ printf("Erreur init DS1621 addr 0x%x: '%s', Abandon programme !", addr, strerror(errno));
+ close ( i2c_fd );
+ exit(1) ;
+ }
+ /* start temperature conversion */
+ errno = 0 ;
+ buff[0] = 0xEE ;
+ write( i2c_fd, buff, 1 );
+ sleep(1) ;
+ return 1 ;
+}
+
+//-----------------------------------------------------------------------------
+double i2c_gettemp_ds1621(unsigned char addr)
+{
+ int k, count, slope, temp;
+ char buff[10] ;
+
+ SelectSlave(addr) ;
+ /* stop conversion */
+ errno = 0 ;
+ buff[0] = 0x22 ;
+
+ if ( write( i2c_fd, buff, 1 ) < 0 ) return 255 ; // Write retourne -1 et strerror(errno))='Remote I/O error' si adr. i2c non connecte.
+ else
+ {
+ /* Temperature reading (1 Celsius degree precision) */
+ buff[0] = 0xAA ;
+ write( i2c_fd, buff, 1 );
+ read(i2c_fd, buff, 1) ;
+ temp = buff[0] ;
+ /* Counter reading (fraction of degree) ) */
+ buff[0] = 0xA8 ;
+ write( i2c_fd, buff, 1 );
+ read(i2c_fd, buff, 1) ;
+ count = buff[0] ;
+ /* slope reading */
+ buff[0] = 0xA9 ;
+ write( i2c_fd, buff, 1 );
+ read(i2c_fd, buff, 1) ;
+ slope = buff[0] ;
+ k = temp;
+ if (slope != 0)
+ {
+ k = temp*100-25+(100*(slope-count))/slope;
+ }
+ /* start temperature conversion */
+ buff[0] = 0xEE ;
+ write( i2c_fd, buff, 1 );
+ return (float)k/100 ;
+ }
+}
+
+/*------------------------------------------------------------------------------*/
+int main ( int argc, char ** argv )
+{
+ // Init i2c.
+ i2c_init() ;
+
+ // Init ds1621.
+ i2c_init_ds1621(ds1621_addr) ;
+
+ // Affiche la t.
+ printf("%2.1f\n", i2c_gettemp_ds1621(ds1621_addr) ) ;
+
+ close ( i2c_fd );
+}
+
+/*------------------------------------------------------------------------------*/
+
--- /dev/null
+#ifndef _LINUX_ETRAXI2C_H
+#define _LINUX_ETRAXI2C_H
+
+/* etraxi2c _IOC_TYPE, bits 8 to 15 in ioctl cmd */
+
+#define ETRAXI2C_IOCTYPE 44
+
+/* supported ioctl _IOC_NR's */
+
+/* in write operations, the argument contains both i2c
+ * slave, register and value.
+ */
+
+#define I2C_WRITEARG(slave, reg, value) (((slave) << 16) | ((reg) << 8) | (value))
+#define I2C_READARG(slave, reg) (((slave) << 16) | ((reg) << 8))
+
+#define I2C_ARGSLAVE(arg) ((arg) >> 16)
+#define I2C_ARGREG(arg) (((arg) >> 8) & 0xff)
+#define I2C_ARGVALUE(arg) ((arg) & 0xff)
+
+#define I2C_WRITEREG 0x1 /* write to an I2C register */
+#define I2C_READREG 0x2 /* read from an I2C register */
+
+/*
+EXAMPLE usage:
+
+ i2c_arg = I2C_WRITEARG(STA013_WRITE_ADDR, reg, val);
+ ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_WRITEREG), i2c_arg);
+
+ i2c_arg = I2C_READARG(STA013_READ_ADDR, reg);
+ val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg);
+
+*/
+
+/* Extended part */
+#define I2C_READ 0x4 /* reads from I2C device */
+#define I2C_WRITE 0x3 /* writes to I2C device */
+#define I2C_WRITEREAD 0x5 /* writes to I2C device where to start reading */
+
+typedef struct _I2C_DATA
+{
+ unsigned char slave; /* I2C address (8-bit representation) of slave device */
+ unsigned char wbuf[256]; /* Write buffer (length = 256 bytes) */
+ unsigned int wlen; /* Number of bytes to write from wbuf[] */
+ unsigned char rbuf[256]; /* Read buffer (length = 256 bytes) */
+ unsigned int rlen; /* Number of bytes to read into rbuf[] */
+} I2C_DATA;
+
+#endif
--- /dev/null
+#!/bin/sh
+
+I2CBUS=0
+I2CADDR=0x68
+
+sec=`i2cget -y $I2CBUS $I2CADDR 0`
+min=`i2cget -y $I2CBUS $I2CADDR 1`
+hour=`i2cget -y $I2CBUS $I2CADDR 2`
+day=`i2cget -y $I2CBUS $I2CADDR 4`
+month=`i2cget -y $I2CBUS $I2CADDR 5`
+year=`i2cget -y $I2CBUS $I2CADDR 6`
+
+echo 20${year:2:2}-${month:2:2}-${day:2:2} ${hour:2:2}:${min:2:2}:${sec:2:2}
--- /dev/null
+#ifndef _I2C_ERRNO_H
+#define _I2C_ERRNO_H
+
+#define EI2CNOERRORS 0 /* All fine */
+#define EI2CBUSNFREE 1 /* I2C bus not free */
+#define EI2CWADDRESS 2 /* Address write failed */
+#define EI2CRADDRESS 3 /* Address read failed */
+#define EI2CSENDDATA 4 /* Sending data failed */
+#define EI2CRECVDATA 5 /* Receiving data failed */
+#define EI2CSTRTCOND 6 /* Start condition failed */
+#define EI2CRSTACOND 7 /* Repeated start condition failed */
+#define EI2CSTOPCOND 8 /* Stop condition failed */
+#define EI2CNOSNDBYT 9 /* Number of send bytes is 0, while there's a send buffer defined */
+#define EI2CNOSNDBUF 10 /* No send buffer defined, while number of send bytes is not 0 */
+#define EI2CNORCVBYT 11 /* Number of receive bytes is 0, while there's a receive buffer defined */
+#define EI2CNORCVBUF 12 /* No receive buffer defined, while number of receive bytes is not 0 */
+#define EI2CNOACKNLD 13 /* No acknowledge received from slave */
+#define EI2CNOMNUMBR 14 /* No MAJOR number received from kernel while registering the device */
+
+#endif /* _I2C_ERRNO_H */
--- /dev/null
+#!/bin/sh
+#
+# More info: http://cyber-place.ru/showpost.php?p=7797&postcount=82
+
+RAWTEMP=$(i2cget -y 0 0x40 0xe3 w)
+RAWHUMI=$(i2cget -y 0 0x40 0xe5 w)
+
+if (echo "$RAWTEMP"| grep -Eq '0x[0-9a-f]{4}'); then
+ HEXORDERED=$(echo "$RAWTEMP"|sed -r 's/0x([0-9a-f]{2})([0-9a-f]{2})/0x\2\1/')
+ DECRAW=$(($HEXORDERED))
+ echo $DECRAW | awk -v tem=${DECRAW} '{ printf "%.2f stC\n", -46.85+((tem*175.72)/65536)}'
+fi
+if (echo "$RAWHUMI"| grep -Eq '0x[0-9a-f]{4}'); then
+ HEXORDERED=$(echo "$RAWHUMI"|sed -r 's/0x([0-9a-f]{2})([0-9a-f]{2})/0x\2\1/')
+ DECRAW=$(($HEXORDERED))
+ echo $DECRAW | awk -v hum=${DECRAW} '{ printf "%.2f %%RH\n", -6+((hum*125)/65536)}'
+fi
\ No newline at end of file
--- /dev/null
+/*
+* INA219 util - part of PowerCape by AndiceLabs
+*
+* Copyright (C) 2014 AndiceLabs admin@andicelabs.com http://andicelabs.com
+* Copyright (C) 2014 Zig Fisher flyrouter@gmail.com http://zftlab.org
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*
+* Example run and output:
+*
+* OpenWRT:~# ina219 -b 0 -i 60
+*
+* 22:49 12168mV 134.2mA
+* 22:50 12168mV 239.9mA
+* 22:51 12168mV 134.7mA
+*
+*/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <endian.h>
+#include <string.h>
+#include <time.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+
+#define CONFIG_REG 0
+#define SHUNT_REG 1
+#define BUS_REG 2
+#define POWER_REG 3
+#define CURRENT_REG 4
+#define CALIBRATION_REG 5
+
+#define AVR_ADDRESS 0x21
+#define INA_ADDRESS 0x40
+
+typedef enum {
+ OP_DUMP,
+ OP_VOLTAGE,
+ OP_CURRENT,
+ OP_MONITOR,
+ OP_NONE
+} op_type;
+
+op_type operation = OP_DUMP;
+
+int interval = 60;
+int i2c_bus = 0;
+int i2c_address = INA_ADDRESS;
+int handle;
+int whole_numbers = 0;
+
+
+void msleep( int msecs )
+{
+ usleep( msecs * 1000 );
+}
+
+
+int i2c_read( void *buf, int len )
+{
+ int rc = 0;
+
+ if ( read( handle, buf, len ) != len )
+ {
+ printf( "I2C read failed: %s\n", strerror( errno ) );
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
+int i2c_write( void *buf, int len )
+{
+ int rc = 0;
+
+ if ( write( handle, buf, len ) != len )
+ {
+ printf( "I2C write failed: %s\n", strerror( errno ) );
+ rc = -1;
+ }
+
+ return rc;
+}
+
+
+int register_read( unsigned char reg, unsigned short *data )
+{
+ int rc = -1;
+ unsigned char bite[ 4 ];
+
+ bite[ 0 ] = reg;
+ if ( i2c_write( bite, 1 ) == 0 )
+ {
+ if ( i2c_read( bite, 2 ) == 0 )
+ {
+ *data = ( bite[ 0 ] << 8 ) | bite[ 1 ];
+ rc = 0;
+ }
+ }
+
+ return rc;
+}
+
+
+int register_write( unsigned char reg, unsigned short data )
+{
+ int rc = -1;
+ unsigned char bite[ 4 ];
+
+ bite[ 0 ] = reg;
+ bite[ 1 ] = ( data >> 8 ) & 0xFF;
+ bite[ 2 ] = ( data & 0xFF );
+
+ if ( i2c_write( bite, 3 ) == 0 )
+ {
+ rc = 0;
+ }
+
+ return rc;
+}
+
+
+void show_usage( char *progname )
+{
+ fprintf( stderr, "Usage: %s <mode> \n", progname );
+ fprintf( stderr, " Mode (required):\n" );
+ fprintf( stderr, " -h --help Show usage.\n" );
+ fprintf( stderr, " -i --interval Set interval for monitor mode.\n" );
+ fprintf( stderr, " -w --whole Show whole numbers only. Useful for scripts.\n" );
+ fprintf( stderr, " -v --voltage Show battery voltage in mV.\n" );
+ fprintf( stderr, " -c --current Show battery current in mA.\n" );
+ fprintf( stderr, " -a --address <addr> Override I2C address of INA219 from default of 0x%02X.\n", i2c_address );
+ fprintf( stderr, " -b --bus <i2c bus> Override I2C bus from default of %d.\n", i2c_bus );
+ exit( 1 );
+}
+
+
+void parse( int argc, char *argv[] )
+{
+ while( 1 )
+ {
+ static const struct option lopts[] =
+ {
+ { "address", 0, 0, 'a' },
+ { "bus", 0, 0, 'b' },
+ { "current", 0, 0, 'c' },
+ { "help", 0, 0, 'h' },
+ { "interval", 0, 0, 'i' },
+ { "voltage", 0, 0, 'v' },
+ { "whole", 0, 0, 'w' },
+ { NULL, 0, 0, 0 },
+ };
+ int c;
+
+ c = getopt_long( argc, argv, "a:b:chi:vw", lopts, NULL );
+
+ if( c == -1 )
+ break;
+
+ switch( c )
+ {
+ case 'a':
+ {
+ errno = 0;
+ i2c_address = (int)strtol( optarg, NULL, 0 );
+ if ( errno != 0 )
+ {
+ fprintf( stderr, "Unknown address parameter %s.\n", optarg );
+ exit( 1 );
+ }
+ break;
+ }
+
+ case 'b':
+ {
+ errno = 0;
+ i2c_bus = (int)strtol( optarg, NULL, 0 );
+ if ( errno != 0 )
+ {
+ fprintf( stderr, "Unknown bus parameter %s.\n", optarg );
+ exit( 1 );
+ }
+ break;
+ }
+
+ case 'c':
+ {
+ operation = OP_CURRENT;
+ break;
+ }
+
+ default:
+ case 'h':
+ {
+ operation = OP_NONE;
+ show_usage( argv[ 0 ] );
+ break;
+ }
+
+ case 'i':
+ {
+ operation = OP_MONITOR;
+ interval = atoi( optarg );
+ if ( ( interval == 0 ) && ( errno != 0 ) )
+ {
+ fprintf( stderr, "Invalid interval value\n" );
+ exit( 1 );
+ }
+ break;
+ }
+
+ case 'v':
+ {
+ operation = OP_VOLTAGE;
+ break;
+ }
+
+ case 'w':
+ {
+ whole_numbers = 1;
+ break;
+ }
+ }
+ }
+}
+
+
+int get_voltage( float *mv )
+{
+ short bus;
+
+ if ( register_read( BUS_REG, (unsigned short*)&bus ) != 0 )
+ {
+ return -1;
+ }
+
+ *mv = ( float )( ( bus & 0xFFF8 ) >> 1 );
+ return 0;
+}
+
+
+int get_current( float *ma )
+{
+ short shunt;
+
+ if ( register_read( SHUNT_REG, &shunt ) != 0 )
+ {
+ return -1;
+ }
+
+ *ma = (float)shunt / 10;
+ return 0;
+}
+
+
+void show_current( void )
+{
+ float ma;
+
+ if ( get_current( &ma ) )
+ {
+ fprintf( stderr, "Error reading current\n" );
+ return;
+ }
+
+ if ( whole_numbers )
+ {
+ printf( "%4.0f\n", ma );
+ }
+ else
+ {
+ printf( "%04.1f\n", ma );
+ }
+}
+
+
+void show_voltage( void )
+{
+ float mv;
+
+ if ( get_voltage( &mv ) )
+ {
+ fprintf( stderr, "Error reading voltage\n" );
+ return;
+ }
+ printf( "%4.0f\n", mv );
+}
+
+
+void show_voltage_current( void )
+{
+ float mv, ma;
+
+ if ( get_current( &ma ) || get_voltage( &mv ) )
+ {
+ fprintf( stderr, "Error reading voltage/current\n" );
+ return;
+ }
+
+ if ( whole_numbers )
+ {
+ printf( "%04.0fmV %4.0fmA\n", mv, ma );
+ }
+ else
+ {
+ printf( "%04.0fmV %04.1fmA\n", mv, ma );
+ }
+}
+
+
+void monitor( void )
+{
+ struct tm *tmptr;
+ time_t seconds;
+
+ while ( 1 )
+ {
+ seconds = time( NULL );
+ tmptr = localtime( &seconds );
+ printf( "%02d:%02d ", tmptr->tm_hour, tmptr->tm_min );
+ show_voltage_current();
+ sleep( interval );
+ }
+}
+
+
+int main( int argc, char *argv[] )
+{
+ char filename[ 20 ];
+
+ parse( argc, argv );
+
+ snprintf( filename, 19, "/dev/i2c-%d", i2c_bus );
+ handle = open( filename, O_RDWR );
+ if ( handle < 0 )
+ {
+ fprintf( stderr, "Error opening bus %d: %s\n", i2c_bus, strerror( errno ) );
+ exit( 1 );
+ }
+
+ if ( ioctl( handle, I2C_SLAVE, i2c_address ) < 0 )
+ {
+ fprintf( stderr, "Error setting address %02X: %s\n", i2c_address, strerror( errno ) );
+ exit( 1 );
+ }
+
+ switch ( operation )
+ {
+ case OP_DUMP:
+ {
+ show_voltage_current();
+ break;
+ }
+
+ case OP_VOLTAGE:
+ {
+ show_voltage();
+ break;
+ }
+
+ case OP_CURRENT:
+ {
+ show_current();
+ break;
+ }
+
+ case OP_MONITOR:
+ {
+ monitor();
+ break;
+ }
+
+ default:
+ case OP_NONE:
+ {
+ break;
+ }
+ }
+
+ close( handle );
+ return 0;
+}
+
--- /dev/null
+/* Simple daemon to communicate with Newhaven I2C LCD module.
+ *
+ * This is a trivial interface for Newhaven LCD module connected to a Linux machine
+ * over an I2C interface. Any standard Linux I2C bus should work (including USB I2C
+ * adapters that correctly hook into the i2c kernel driver framework).
+ *
+ * Opens a named pipe at /dev/lcd which can be written to by other applications.
+ * Text written to this file will appear on the LCD.
+ * Send a bell ('\b')to clear the screen.
+ *
+ * Tested with NHD-0420D3Z-FL-GBW (Digikey part number NHD-0420D3Z-FL-GBW-ND).
+ * http://www.newhavendisplay.com/specs/NHD-0420D3Z-FL-GBW.pdf
+ * http://www.newhavendisplay.com/index.php?main_page=product_info&cPath=253&products_id=922
+ *
+ * FIXME how to do other commands etc.
+ * FIXME some rate limiting should be added... the I2C controller on the LCD
+ * module gets confused if you write to it too fast.
+ *
+ * Hardware note:
+ * To enable I2C mode of LCD, Pads of R1 must be jumpered on back of LCD
+ * See the manual for the LCD module.
+ *
+ * ./lcdd -a 0x47 -d /dev/i2c-4 -f /dev/lcd -n
+ *
+ * Hugo Vincent, June 2009 - https://github.com/hugovincent/i2c-lcdd
+ * Daemonization based on code by Peter Lombardo <peter@lombardo.info>, 2006
+ */
+
+
+#define _GNU_SOURCE // for strsignal()
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <stdint.h>
+#include <errno.h>
+#include <syslog.h>
+#include <assert.h>
+#include <signal.h>
+#include <poll.h>
+#include <setjmp.h>
+#include <linux/i2c-dev.h>
+
+#define DAEMON_NAME "lcdd"
+#define PID_FILE "/var/run/lcdd.pid"
+
+#define LCD_ADDR 0x27
+
+//#define DEBUG
+
+static int daemonize = 1, running = 1, have_lcd = 1;
+static jmp_buf my_jmp_buf;
+
+#define LOG_MSG(format, ...) if (daemonize == 1) \
+ syslog(LOG_INFO, format, ##__VA_ARGS__); \
+else \
+printf("i2c-lcdd: " format "\n", ##__VA_ARGS__);
+
+void usage(int argc, char **argv)
+{
+ if (argc >=1)
+ {
+ printf("Usage: %s -a 0x50 -d /dev/i2c-3 -f /dev/lcd -n -?\n", argv[0]);
+ printf(" Options:\n");
+ printf(" -a\tI2C slave address (in hex) for LCD module\n");
+ printf(" -d\tI2C device\n");
+ printf(" -f\tnamed pipe for input\n");
+ printf(" -n\tDon't daemonize.\n");
+ printf(" -?\tShow this help screen.\n");
+ }
+}
+
+void signal_handler(int sig)
+{
+ LOG_MSG("received signal %s - exiting", strsignal(sig));
+ running = 0;
+}
+
+void i2c_send(int fd, uint8_t *buf, int count)
+{
+ if (have_lcd)
+ {
+ if (write(fd, buf, count) != count)
+ {
+ LOG_MSG("error writing to I2C: %s", strerror(errno));
+ longjmp(my_jmp_buf, EXIT_FAILURE);
+ //exit(EXIT_FAILURE);
+ }
+ }
+ else
+ {
+#ifdef DEBUG
+ static char tmp[1024];
+ strncpy(tmp, buf, count);
+ tmp[count] = 0;
+ printf("I2C send: \"%s\"\n", tmp);
+#endif
+ }
+}
+
+uint8_t linenum_to_cursor(int linenum)
+{
+ switch (linenum)
+ {
+ case 1:
+ return 0x40;
+ break;
+ case 2:
+ return 0x14;
+ break;
+ case 3:
+ return 0x54;
+ break;
+ case 0:
+ default:
+ return 0x0;
+ break;
+ }
+}
+
+#define min(a, b) ((a <= b) ? a : b)
+
+void handle_pipe_input(int i2c_fd, char *buffer, int size)
+{
+ // FIXME this should handle escape sequences (other than \b, \n) too
+
+ static int line_number = 0;
+
+ // LCD clear
+ if (size >= 1 && buffer[0] == '\b')
+ {
+ uint8_t bytes[] = {0xFE, 0x51};
+ i2c_send(i2c_fd, bytes, sizeof(bytes));
+ buffer++; size--;
+ line_number = 0;
+ }
+
+ // Split input into lines
+ char *line = strtok(buffer, "\n");
+ while (line != NULL)
+ {
+ // Because of weird cursor positioning on the LCD module, if we write
+ // more than 20 characters on line 1 it'll flow over onto line 3, (or
+ // off line 2 on to line 4). Thus, we limit lines to 20 chars.
+
+ i2c_send(i2c_fd, line, min(strlen(line), 20));
+ line_number = (line_number < 3) ? (line_number + 1) : 0;
+
+ // Go to specified line
+ uint8_t bytes[] = {0xFE, 0x45, 0x0};
+ bytes[2] = linenum_to_cursor(line_number);
+ i2c_send(i2c_fd, bytes, sizeof(bytes));
+
+ // Get next line
+ line = strtok(NULL, "\n");
+ }
+}
+
+int main(int argc, char **argv)
+{
+ char device[64] = "/dev/i2c-3", fifo_name[64] = "/dev/lcd";
+ int addr = LCD_ADDR, addr_sscanf_ret = 1;
+
+ // Setup signal handling before we start
+ signal(SIGHUP, signal_handler);
+ siginterrupt(SIGHUP, 1);
+ signal(SIGQUIT, signal_handler);
+ siginterrupt(SIGQUIT, 1);
+ signal(SIGTERM, signal_handler);
+ siginterrupt(SIGTERM, 1);
+ signal(SIGINT, signal_handler);
+ siginterrupt(SIGINT, 1);
+
+ int c;
+ while( (c = getopt(argc, argv, "a:d:f:n?")) != -1) {
+ switch(c){
+ case 'a':
+ addr_sscanf_ret = sscanf(optarg, "0x%x", &addr);
+ break;
+ case 'd':
+ strncpy(device, optarg, sizeof(device));
+ break;
+ case 'f':
+ strncpy(fifo_name, optarg, sizeof(fifo_name));
+ break;
+ case 'n':
+ daemonize = 0;
+ break;
+ case '?':
+ default:
+ usage(argc, argv);
+ exit(0);
+ break;
+ }
+ }
+
+ // Setup syslog logging
+ if (daemonize == 1)
+ {
+ setlogmask(LOG_UPTO(LOG_INFO));
+ openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
+ }
+ LOG_MSG("daemon starting up");
+
+ // Check sscanf above worked (delayed until after syslog is initialized)
+ if (addr_sscanf_ret != 1)
+ LOG_MSG("supplied address invalid, using 0x%02x", addr);
+
+ // Our process ID and Session ID
+ pid_t pid, sid;
+
+ if (daemonize)
+ {
+ // Fork off the parent process
+ pid = fork();
+ if (pid < 0)
+ {
+ LOG_MSG("failed to fork daemon process");
+ exit(EXIT_FAILURE);
+ }
+
+ // If we got a good PID, then we can exit the parent process
+ if (pid > 0)
+ exit(EXIT_SUCCESS);
+
+ // Change the file mode mask
+ umask(0);
+
+ // Create a new SID for the child process
+ sid = setsid();
+ if (sid < 0)
+ {
+ LOG_MSG("failed to set daemon process SID");
+ exit(EXIT_FAILURE);
+ }
+
+ // Change the current working directory
+ if ((chdir("/")) < 0)
+ {
+ LOG_MSG("failed to change daemon working directory");
+ exit(EXIT_FAILURE);
+ }
+
+ // Close out the standard file descriptors
+ close(STDIN_FILENO);
+#ifndef DEBUG
+ close(STDOUT_FILENO);
+#endif
+ close(STDERR_FILENO);
+ }
+
+ //************************************************************************
+
+ addr >>= 1; // to suit LCD addressing sematics of Newhaven LCD modules
+
+ // Initialise FIFO on which to accept input
+ if (mkfifo(fifo_name, S_IRWXU) < 0)
+ {
+ if (errno != EEXIST)
+ {
+ LOG_MSG("error creating named pipe for input: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ LOG_MSG("warning, named pipe already exists: %s", strerror(errno));
+ // FIXME unlink and reopen
+ }
+ }
+
+ // Connect to I2C LCD and set slave address
+ int i2c_fd = open(device, O_RDWR);
+ if (i2c_fd < 0)
+ {
+ LOG_MSG("error opening device: %s", strerror(errno));
+ have_lcd = 0;
+ goto nolcd;
+ }
+ if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0)
+ {
+ LOG_MSG("error setting I2C slave address: %s", strerror(errno));
+ close(i2c_fd);
+ have_lcd = 0;
+ }
+
+nolcd:
+ if (setjmp(my_jmp_buf) == EXIT_FAILURE)
+ goto exit1;
+
+ if (!have_lcd)
+ {
+ LOG_MSG("could not open I2C LCD, printing to stdout for debugging");
+ }
+ else
+ {
+ LOG_MSG("using Nehaven LCD attached to %s at real address 0x%x", device, addr);
+
+ // Initialise LCD
+ uint8_t bytes[] = {0xFE, 0x41}; // LCD on
+ i2c_send(i2c_fd, bytes, sizeof(bytes));
+ bytes[1] = 0x51; // LCD clear
+ i2c_send(i2c_fd, bytes, sizeof(bytes));
+
+ uint8_t *string = (uint8_t*)" Initialising...";
+ i2c_send(i2c_fd, string, strlen((char*)string));
+ }
+
+ char buffer[256];
+ int fifo_fd = -1;
+ struct pollfd fds = { .events = POLLIN };
+
+ // Main Loop: read on named pipe, output on LCD
+ while (running)
+ {
+ if (fifo_fd == -1)
+ {
+#ifdef DEBUG
+ LOG_MSG("waiting for connection on %s...", fifo_name);
+#endif
+ fifo_fd = open(fifo_name, O_RDONLY); // this will block until other end of pipe is opened
+ if (fifo_fd < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ LOG_MSG("error opening named pipe for input: %s", strerror(errno));
+ goto exit3;
+ }
+ fds.fd = fifo_fd;
+#ifdef DEBUG
+ LOG_MSG("connected, accepting input on %s", fifo_name);
+#endif
+ }
+
+ // Wait for input on the named pipe
+ int poll_ret = poll(&fds, 1, 1000);
+ if (poll_ret == 1 && fds.revents | POLLIN)
+ {
+ memset(&buffer, 0, sizeof(buffer));
+ int bytes_read = read(fifo_fd, &buffer, sizeof(buffer));
+
+ // Write input to LCD
+ if (bytes_read > 0)
+ handle_pipe_input(i2c_fd, buffer, bytes_read);
+ else if (bytes_read == 0)
+ {
+#ifdef DEBUG
+ LOG_MSG("named pipe closed");
+#endif
+ close(fifo_fd);
+ fifo_fd = -1;
+ }
+ else
+ {
+ LOG_MSG("error reading from named pipe: %s", strerror(errno));
+ goto exit1;
+ }
+ }
+ else if (poll_ret < 0 && running)
+ {
+ LOG_MSG("error waiting for input on named pipe: %s", strerror(errno));
+ goto exit1;
+ }
+ else
+ {
+ // Timeout in poll(), no need to worry (timeout is only enabled as insurance anyway)
+ }
+ }
+
+ LOG_MSG("daemon exiting cleanly");
+
+ close(fifo_fd);
+ unlink(fifo_name);
+ if (have_lcd)
+ close(i2c_fd);
+
+ return 0;
+
+ // Cleanup on error
+exit1:
+ if (have_lcd)
+ close(i2c_fd);
+exit2:
+ close(fifo_fd);
+exit3:
+ unlink(fifo_name);
+ LOG_MSG("daemon exiting with failure");
+ exit(EXIT_FAILURE);
+}
+
--- /dev/null
+ /*
+ LM75_address.c
+ --------------
+ 1) set the i2c address of the LM75
+ * R/W pulse at end of address byte not included in address 1-0-0-1-A2-A1-A0
+ * example - all lines to 0V - 1001000 = decimal 72
+ 2) calculate the temperature
+ 3) print it
+ usage :- type (without the < >)
+ <LM75_address><space><address as decimal>
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include "smbus.h"
+
+int main(int argc, char** argv)
+{
+ int address; /* i2c bus address */
+
+ if (argc != 2) /* report error if we are not getting just 1 input after the program name */
+ {
+ printf("Error. usage: %s i2c_chip_address\n", argv[0]);
+ }
+ address = atoi(argv[1]); /* address is the first number after the program name */
+
+
+ int f = open("/dev/i2c-0",O_RDWR);
+ char buf[2];
+ if (f>0) {
+ ioctl(f,I2C_SLAVE,address);
+ if (-1 == read(f,buf,2)) {
+ printf("read error.\n");
+ } else { /* calculate the temperature*/
+ int temp = buf[0]*256+buf[1];
+ temp >>=7;
+ if (temp>512)
+ temp &= -1;
+ printf("Temperature (C)\t\t%g\n", (float)temp/2.0);
+ }
+ }
+ return close(f);
+ }
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+#include <string.h>
+// Строки ниже необходимы для rasbian/debian.В Suse должны быть закаментированы.
+#include <linux/i2c.h>
+#include "smbus.h"
+
+#define mcp_I2C_ADDRESS 0x20 // адрес устройства в сети i2c,задается перемычками A0,A1,A2 на микросхеме.
+
+
+// ниже 2 строки задают направление порта ,1 - на ввод,0 - на вывод.
+#define mcp_bank_a 0b00000100 //байты 7 по 0 порт
+#define mcp_bank_b 0b00000000 //байты 8 по 15 порт
+// следущие 2 строки-подтяжка резистором 100 кОм на +, 1 - включен.Актуально для режима на ввод.
+#define gppu_bank_a 0b00000100 //байты 7 по 0 порт
+#define gppu_bank_b 0b00000000 //байты 8 по 15 порт
+// регистры 02 03 для инвертирования
+#define iopol_bank_a 0b00000110 //байты 7 по 0 порт
+#define iopol_bank_b 0b00000000 //байты 8 по 15 порт
+
+
+
+
+
+int fd;
+unsigned int utv;
+int l=1;
+int x=0;
+
+// Open a connection to the mcp
+// Returns a file id
+int mcp_i2c_Begin()
+{
+
+ char *fileName = "/dev/i2c-7"; // указать Ваш адрес
+
+ // Open port for reading and writing
+ if ((fd = open(fileName, O_RDWR)) < 0){
+ printf("i2c device not found \n");
+ exit(1);
+ }
+ // Set the port options and set the address of the device
+ if (ioctl(fd, I2C_SLAVE, mcp_I2C_ADDRESS) < 0) {
+ close(fd);
+ printf("on i2c mcp device not found \n");
+ exit(1);
+ }
+
+ return fd;
+}
+
+// Read a byte to mcp
+__s32 mcp_i2c_Read_byte(int fd, __u8 address)
+{
+ __s32 res = i2c_smbus_read_byte_data(fd, address);
+ if (res < 0) {
+ printf("error \n");
+ close(fd);
+ exit(1);
+ }
+
+ return res;
+}
+
+//Write a byte to mcp
+void mcp_i2c_Write_Byte(int fd, __u8 address, __u8 value)
+{
+ if (i2c_smbus_write_byte_data(fd, address, value) < 0) {
+ close(fd);
+ exit(1);
+ }
+}
+// чтение состояния порта
+int mcp_read (int mcppin)
+{
+ if (mcppin < 0 || mcppin >15) {
+ printf("Please select a valid GPIO pin \n");
+ exit(1);
+ }
+
+ int fd = mcp_i2c_Begin();
+ int regbank;
+
+if (mcppin < 8){
+
+ mcp_i2c_Write_Byte(fd,0x00,mcp_bank_a);
+ mcp_i2c_Write_Byte(fd,0x0c,gppu_bank_a);
+
+ regbank=0x12;
+
+//printf("bank A\n");
+} else {
+
+ mcp_i2c_Write_Byte(fd,0x01,mcp_bank_b);
+ mcp_i2c_Write_Byte(fd,0x0d,gppu_bank_b);
+
+ regbank=0x13;
+ mcppin=mcppin-8;
+
+ // printf("bank B\n");
+}
+
+ utv = mcp_i2c_Read_byte(fd,regbank);
+
+ while(x < mcppin)
+ {
+ x = x+ 1;
+ l=l*2;
+}
+
+
+if (utv & l) return 1;
+else return 0;
+
+close(fd);
+
+}
+
+
+// запрос таблицы статусов портов
+void mcp_state_in () {
+ int fd = mcp_i2c_Begin();
+ utv = mcp_i2c_Read_byte(fd,0x12);
+ // printf ("--%d--\n",utv);
+ while(x < 8)
+ {
+
+ if ((mcp_bank_a & l)) {
+ if ((utv & l)) printf ("%d 1\n",x);
+ else printf ("%d 0\n",x);
+
+} else printf ("%d -\n",x);
+ l=l*2;
+ x = x+ 1;
+
+}
+
+ x=0;
+ l=1;
+
+ utv = mcp_i2c_Read_byte(fd,0x13);
+// printf ("--%d--\n",utv);
+ while(x < 8)
+ {
+ if ((mcp_bank_b & l)) {
+ if ((utv & l)) printf ("%d 1\n",x+8);
+ else printf ("%d 0\n",x+8);
+
+ } else printf ("%d -\n",x+8);
+ l=l*2;
+ x = x+ 1;
+}
+
+close(fd);
+
+}
+// установка состояния порта
+void mcp_write (int mcppin,int mcpst)
+{
+ if (mcppin < 0 || mcppin >15) {
+ printf("Please select a valid GPIO pin \n");
+ exit(1);
+ }
+ if (mcpst != 0 && mcpst != 1) {
+ printf("Не верно задан статус порта 0 или 1\n");
+ exit(1);
+ }
+
+ int fd = mcp_i2c_Begin();
+ int regbank;
+
+if (mcppin < 8){
+
+ mcp_i2c_Write_Byte(fd,0x00,mcp_bank_a);
+ mcp_i2c_Write_Byte(fd,0x0c,gppu_bank_a);
+
+ regbank=0x14;
+
+//printf("bank A\n");
+} else {
+
+ mcp_i2c_Write_Byte(fd,0x01,mcp_bank_b);
+ mcp_i2c_Write_Byte(fd,0x0d,gppu_bank_b);
+
+ regbank=0x15;
+ mcppin=mcppin-8;
+
+ // printf("bank B\n");
+}
+
+ utv = mcp_i2c_Read_byte(fd,regbank);
+
+ while(x < mcppin)
+ {
+ x = x+ 1;
+ l=l*2;
+}
+
+
+if (!(utv & l) && mcpst==1) mcp_i2c_Write_Byte(fd,regbank,utv+l);
+if (utv & l && mcpst==0) mcp_i2c_Write_Byte(fd,regbank,utv-l);
+
+close(fd);
+
+}
+
+
+// запрос таблицы статусов портов
+void mcp_state_out () {
+ int fd = mcp_i2c_Begin();
+ utv = mcp_i2c_Read_byte(fd,0x14);
+ // printf ("--%d--\n",utv);
+ while(x < 8)
+ {
+
+ if (!(mcp_bank_a & l)) {
+ if ((utv & l)) printf ("%d 1\n",x);
+ else printf ("%d 0\n",x);
+
+} else printf ("%d -\n",x);
+ l=l*2;
+ x = x+ 1;
+
+}
+
+ x=0;
+ l=1;
+
+ utv = mcp_i2c_Read_byte(fd,0x15);
+// printf ("--%d--\n",utv);
+ while(x < 8)
+ {
+ if (!(mcp_bank_b & l)) {
+ if ((utv & l)) printf ("%d 1\n",x+8);
+ else printf ("%d 0\n",x+8);
+
+ } else printf ("%d -\n",x+8);
+ l=l*2;
+ x = x+ 1;
+}
+
+close(fd);
+
+}
+// основное тело программы
+
+int main(int argc, char **argv)
+
+{
+ if (argc == 1) {
+ printf("%s <команда>\nin -чтение данных из порта,установленых на ввод\nout-установка состояния порта,установленного на вывод.\n", argv[0]);
+ return 1;
+ }
+ else if (argc == 2) {
+ if(strcmp(argv[1], "out") == 0) mcp_state_out();
+ else if(strcmp(argv[1], "in") == 0) mcp_state_in();
+ else printf("Нет такой команды\n");
+ return 1;
+ }
+
+ if(strcmp(argv[1], "out") == 0) {
+
+ if (argc != 4) {
+ printf("Настройка порта: %s <порт> <состояние>\n", argv[0]);
+
+return 1;
+}
+int mcppin = atoi(argv[2]);
+int mcpst = atoi(argv[3]);
+
+mcp_write (mcppin,mcpst);
+
+
+ }
+ else if(strcmp(argv[1], "in")== 0) {
+ if (argc != 3) {
+ printf("Чтение одного порта: %s <порт>\n", argv[0]);
+ mcp_state_in();
+ return 1;
+ }
+ int mcppin = atoi(argv[2]);
+
+ printf ("%d\n",mcp_read (mcppin));
+
+ }
+
+
+
+
+
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+/*
+PCF8574_addr_byteout_slug.c
+----------------------
+Send address and byte to switch lines on 8 line port of i2c bus PCF8574
+-----------------------------------------------------------------------
+
+1) send the i2c address
+2) send byte to set the 8 port lines on or off
+
+usage :- type with spaces but without the < >
+<PCF8574_addr_byteout_slug> <decimal address> <decimal byte out 0-255>
+
+Home Page - http://www.sunspot.co.uk/Projects/SWEEX/slug/i2c/slug_i2c.html
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#define I2C_SLAVE0x0703/* Change slave address*/
+
+int i2c;
+char filename[20];
+unsigned long address;
+
+int rc;
+unsigned char data[1];
+int main(int argc, char *argv[])
+{
+if (argc != 3) { /* error if we are not getting just 2 inputs after the program name */
+fprintf(stderr, "usage: %s <address> <databyte>\n",argv[0]);
+exit(1);
+}
+
+/* address is the first number after the program name */
+address = atoi(argv[1]);
+/* the byte to send out to the PC8574 is the second number
+place it into the first element of the buf array */
+data[0] = atoi(argv[2]);
+
+i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
+
+rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */
+
+write(i2c,data,1) ; /* send the byte */
+
+i2c = close(i2c);
+return(0);
+}
+
--- /dev/null
+/*
+PCF8574_addr_read_slug.c
+-------------------
+read the data on the 8 line port of an i2c bus PCF8574
+------------------------------------------------------
+
+1) set the i2c address of the PCF8574
+2) send data 255 to turn off all 8 lines - make them inputs
+3) read the data on the 8 port lines as a byte
+usage :- type (without the < >)
+<PCF8574_address_read_4> <space> <i2c_bus_address_of_PCF8574_as_decimal>
+
+Home Page - http://www.sunspot.co.uk/Projects/SWEEX/slug/i2c/slug_i2c.html
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#define I2C_SLAVE0x0703/* Change slave address*/
+
+int i2c;
+char filename[20];
+unsigned long address;
+int rc;
+unsigned char data[1];
+int byte; /* the 8 bit byte that represents the data present on the 8 wire port */
+
+int main(int argc, char ** argv)
+{
+if (argc != 2) { /* error if we are not getting just 1 input after the program name */
+fprintf(stderr, "usage: %s <address> <databyte>\n",argv[0]);
+exit(1);
+}
+
+/* address is the first number after the program name */
+address = atoi(argv[1]);
+
+i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
+rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */
+
+data[0] = 255;
+write(i2c,data,1); /* we send 255 to make all lines go off, ready for input data */
+
+read(i2c,data,1); /* now data(0) contains the byte of data on the 8 port lines*/
+
+byte = data[0];
+
+printf("BYTE = %d \n", byte);
+/* BYTE value is 0-256)*/
+i2c = close(i2c);
+return(0);
+}
--- /dev/null
+/*
+ PCF8574_addr_byteout.c
+ ----------------------
+ Send address and byte to switch lines on 8 line port of i2c bus PCF8574
+ -----------------------------------------------------------------------
+
+ 1) send the i2c address
+ 2) send byte to set the 8 port lines on or off
+
+ usage :- type with spaces but without the < >
+<PCF8574_addr_byteout.c> <address as decimal> <byte out value as decimal 0-255>
+
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/i2c.h>
+
+ int i2c;
+ int buf[1];
+ int address;
+
+int main(int argc, char** argv)
+{
+ if (argc != 3) /* error if we are not getting just 2 inputs after the program name */
+ {
+ printf("Error. usage: %s i2c_chip_address byte_to_send_out\n", argv[0]);
+ }
+
+/* address is the first number after the program name */
+ address = atoi(argv[1]);
+
+/* the byte to send out to the PC8574 is the second number */
+
+/* place it into the first element of the buf array */
+ buf[0] = atoi(argv[2]);
+
+ i2c = open("/dev/i2c/0",O_RDWR); /* open the device on i2c-bus number 0*/
+
+ ioctl(i2c,I2C_SLAVE, address); /* set the i2c chip address */
+
+ write(i2c,buf,1); /* send the byte */
+
+ i2c = close(i2c);
+
+}
+
--- /dev/null
+/*
+ PCF8574_addr_read.c
+ -------------------
+read the data on the 8 line port of an i2c bus PCF8574
+------------------------------------------------------
+
+1) set the i2c address of the PCF8574
+2) send data 255 to turn off all 8 lines - make them inputs
+3) read the data on the 8 port lines as a byte
+ usage :- type (without the < >)
+ <PCF8574_address_read_4> <space> <i2c_bus_address_of_PCF8574_as_decimal>
+*/
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/i2c.h>
+
+ int i2c;
+ int buf[1];
+ int address; /* i2c bus address of the PCF8574 */
+ int byte; /* the 8 bit byte that represents the data present on the 8 wire port */
+
+int main(int argc, char** argv)
+{
+ if (argc != 2) /* report error if we are not getting just 1 input after the program name */
+ {
+ printf("Error. usage: %s i2c_chip_address\n", argv[0]);
+ }
+
+ address = atoi(argv[1]); /* address is the first number after the program name */
+
+ i2c = open("/dev/i2c/0",O_RDWR); /* open the i2c-bus number 0 */
+
+ ioctl(i2c,I2C_SLAVE, address); /* set the address of the chip we will talk to */
+
+ buf[0] = 255;
+ write(i2c,buf,1); /* we send 255 to make all lines go off, ready for input data */
+
+ read(i2c,buf,1); /* now buf(0) contains the byte of data on the 8 port lines*/
+
+ byte = buf[0];
+
+ printf("BYTE = %d \n", byte);
+/* BYTE value is 0-256)*/
+
+ i2c = close(i2c);
+}
+
--- /dev/null
+/*
+PCF8591-all-lines_addr_V-slug.c
+---------------------
+read the voltage on all A/D lines (0-3) and set the output voltage on the D/A pin
+---------------------------------------------------------------------------------
+
+1) send the i2c address
+3) send byte for D/A out
+3) read all 4 A/D lines
+usage :- type with spaces but without the < >
+<PCF8591_address_readvolts> <address as decimal> <D/A value as decimal 0-255>
+(even if the D/A pin is unused type in any value 0-255)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#define I2C_SLAVE0x0703/* Change slave address*/
+int i2c;
+int AD_line; /* line number 0-3 */
+int V_out; /* value for the D/A out line */
+unsigned char buf[1]; /* use to feed the i2c driver */
+unsigned long address; /* i2c bus address */
+int byte_in_0; /* the 8 bit byte that represents the voltage on the AD_line */
+int AD_line_0; /* volts byte on line number 0 */
+int AD_line_1; /* volts byte on line number 1 */
+int AD_line_2; /* volts byte on line number 2 */
+int AD_line_3; /* volts byte on line number 3 */
+int rc;
+
+int main(int argc, char** argv)
+{
+if (argc != 3) /* report error if we are not getting just 2 inputs after the program name */
+
+{
+
+printf("Error. usage: %s i2c_chip_address D/A_Vout(0-255)\n", argv[0]);
+
+}
+
+address = atoi(argv[1]); /* address is the first number after the program name */
+
+V_out = atoi(argv[2]); /* A/D input line 0-3 */
+
+i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
+rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */
+
+AD_line = 0 + 64; /* enable the D/A output pin 0*/
+buf[0] = AD_line; /* A/D input line number is the first data byte sent */
+buf[1] = V_out; /* D/A out value is the second data byte sent */
+write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+sleep (1); /* do it again */
+read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+AD_line_0 = buf[0];
+
+AD_line = 1 + 64; /* enable the D/A output pin 0*/
+buf[0] = AD_line; /* A/D input line number is the first data byte sent */
+buf[1] = V_out; /* D/A out value is the second data byte sent */
+write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+//sleep (1); /* do it again */
+// read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+AD_line_1 = buf[0];
+
+AD_line = 2 + 64; /* enable the D/A output pin 0*/
+buf[0] = AD_line; /* A/D input line number is the first data byte sent */
+buf[1] = V_out; /* D/A out value is the second data byte sent */
+write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+//sleep (1); /* do it again */
+// read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+AD_line_2 = buf[0];
+
+AD_line = 3 + 64; /* enable the D/A output pin 0*/
+buf[0] = AD_line; /* A/D input line number is the first data byte sent */
+buf[1] = V_out; /* D/A out value is the second data byte sent */
+write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+//sleep (1); /* do it again */
+// read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+AD_line_3 = buf[0];
+
+printf("A/D line 0 = %d \n", AD_line_0, " ");
+printf("A/D line 1 = %d \n", AD_line_1, " ");
+printf("A/D line 2 = %d \n", AD_line_2, " ");
+printf("A/D line 3 = %d \n", AD_line_3, " ");
+/*AD_line_x goes 0 to 255 as voltage input goes from 0 to supply voltage*/
+
+i2c = close(i2c);
+return(0);
+}
--- /dev/null
+/*
+ PCF8591_addr_line.c
+ -------------------
+ read the voltage on one A/D line (0-3) and set the output voltage on the D/A pin
+ --------------------------------------------------------------------------------
+
+ 1) send the i2c address as decimal
+ 2) send A/D line number (program adds 64 to enable D/A in control register)
+ 3) send byte for D/A out
+ 4) read the chosen A/D - print it as a raw decimal 0 to 255
+ 5) save the chosen port value to /var/www/ramdisk/AtoD.dat
+ usage :- type with spaces but without the < >
+<PCF8591_address_readvolts> <address as decimal> <A/D line 0-3> <D/A value as decimal 0-255>
+ (even if the D/A pin is unused type in any value 0-255)
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include "smbus.h"
+
+
+int main(int argc, char** argv)
+{
+ int i2c;
+ int AD_line; /* line number 0-3 */
+ int V_out; /* value for the D/A out line */
+ int buf[1]; /* use to feed the i2c driver */
+ int address; /* i2c bus address */
+ int byte_in_0; /* the 8 bit byte that represents the voltage on the AD_line */
+
+ if (argc != 4) /* report error if we are not getting just 3 inputs after the program name */
+ {
+ printf("Error. usage: %s i2c_chip_address A/D_line_(0-3) D/A_Vout(0-255)\n", argv[0]);
+ }
+
+ address = atoi(argv[1]); /* address is the first number after the program name */
+ AD_line = atoi(argv[2]); /* A/D input line 0-3 */
+ AD_line = AD_line + 64; /* enable the D/A output pin */
+ V_out = atoi(argv[3]); /* A/D input line 0-3 */
+
+ i2c = open("/dev/i2c/0",O_RDWR); /* open the i2c-bus number 0 */
+
+ ioctl(i2c,I2C_SLAVE, address); /* set the i2c-bus address of the chip we will talk to */
+
+ buf[0] = AD_line; /* A/D input line number is the first data byte sent */
+ buf[1] = V_out; /* D/A out value is the second data byte sent */
+
+ write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+
+ read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+ /* do it again */
+ read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+
+ printf("BYTE = %d \n", buf[0]);
+ printf("%d\n", buf[0]);
+ /* buf[0] is an integer. It goes 0 to 255 as voltage input goes from 0 to supply voltage*/
+
+ //save AtoD byte to ramdisk
+ FILE *f;
+ f = fopen("/tmp/AtoD.dat","w");
+ fprintf(f, "%d", buf[0]);
+ fclose(f);
+
+ i2c = close(i2c);
+}
+
+
--- /dev/null
+/*
+PCF8591_address_channel_Vout.c
+------------------------------
+read the voltage on one A/D lines (0-3) and set the output voltage on the D/A pin
+---------------------------------------------------------------------------------
+
+1) send the i2c address
+2) choose channel 0-3
+3) send byte for D/A out
+3) read channel volts as (0 to 255) / 255 x 5V
+usage :- type with spaces but without the < >
+<PCF8591_address_readvolts> <address as decimal> <channel 0-3> <D/A value as decimal 0-255>
+(even if the D/A pin is unused type in any value 0-255)
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#define I2C_SLAVE0x0703/* Change slave address*/
+int i2c;
+int channel; /* line number 0-3 */
+int V_out; /* value for the D/A out line */
+unsigned char buf[1]; /* use to feed the i2c driver */
+unsigned long address; /* i2c bus address */
+int byte_in_0; /* the 8 bit byte that represents the voltage on the AD_line */
+int AD_input; /* volts byte on chosen channel */
+
+int rc;
+
+int main(int argc, char** argv)
+{
+if (argc != 4) /* report error if we are not getting just 3 inputs after the program name */
+{
+printf("Error. usage: %s i2c_chip_address channel_to_read D/A_Vout(0-255)\n", argv[0]);
+}
+
+address = atoi(argv[1]); /* decimal address is the first number after the program name */
+channel = atoi(argv[2]); /* choose A to D line to read 0-3 */
+V_out = atoi(argv[3]); /* volts out as decimal 0-255 */
+
+i2c = open("/dev/i2c-0",O_RDWR); /* open the device dev/i2c-0 */
+rc=ioctl(i2c,I2C_SLAVE,address); /* set the i2c chip address */
+
+channel = channel + 64; /* enable the D/A output */
+buf[0] = channel; /* A/D input line number is the first data byte sent */
+buf[1] = V_out; /* D/A out value is the second data byte sent */
+write(i2c,buf,2); /* we send 2 bytes <control register> <D/A value> */
+read(i2c,buf,1); /* buf(0) contains the byte of data in the chip cache */
+usleep (1000); /* do it again */
+read(i2c,buf,1); /* buf(0) now contains the byte of data from the most recent analogue input*/
+AD_input = buf[0];
+
+
+
+printf("%d", AD_input);
+
+
+
+/*AD_line_x goes 0 to 255 as voltage input goes from 0 to supply voltage*/
+
+i2c = close(i2c);
+return(0);
+}
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include "smbus.h"
+#include <ncurses.h> /* sudo apt-get install libncurses5-dev */
+
+// gcc -o pcf8591_2 -lncurses pcf8591_2.c
+
+int main( int argc, char **argv )
+{
+ int i;
+ int r;
+ int fd;
+ int aout;
+ unsigned char command[2];
+ unsigned char value[4];
+ unsigned char str[8];
+ useconds_t delay = 5000;
+
+ char *dev = "/dev/i2c-0";
+ int addr = 0x48;
+
+ int j;
+ int key;
+
+ initscr();
+ noecho();
+ cbreak();
+ nodelay(stdscr, true);
+ curs_set(0);
+ printw("PCF8591");
+
+ mvaddstr(10, 0, "Brightness");
+ mvaddstr(12, 0, "Temperature");
+ mvaddstr(14, 0, "?");
+ mvaddstr(16, 0, "Resistor");
+ refresh();
+ fd = open(dev, O_RDWR );
+ if(fd < 0)
+ {
+ perror("Opening i2c device node\n");
+ return 1;
+ }
+
+ r = ioctl(fd, I2C_SLAVE, addr);
+ if(r < 0)
+ {
+ perror("Selecting i2c device\n");
+ }
+
+ command[1] = 0;
+ aout = 0;
+ while(1)
+ {
+ for(i = 0; i < 4; i++)
+ {
+ command[1]=aout++;
+ command[0] = 0x40 | ((i + 1) & 0x03); // output enable | read input i
+ r = write(fd, &command, 2);
+ usleep(delay);
+ // the read is always one step behind the selected input
+ r = read(fd, &value[i], 1);
+ if(r != 1)
+ {
+ perror("reading i2c device\n");
+ }
+ usleep(delay);
+
+ sprintf(str, "%3d", value[i]);
+ mvaddstr(10+i+i, 12, str);
+ value[i] = value[i] / 4;
+ move(10 + i + i, 16);
+
+ for(j = 0; j < 64; j++)
+ {
+ if(j < value[i])
+ {
+ addch('*');
+ }
+ else
+ {
+ addch(' ');
+ }
+ }
+ }
+ refresh();
+
+ key = getch();
+ if(key == 43)
+ {
+ command[1]++;
+ }
+ else if(key == 45)
+ {
+ command[1]--;
+ }
+ else if(key > -1)
+ {
+ break;
+ }
+ }
+
+ endwin();
+ close(fd);
+ printf("%d\n", key);
+ return(0);
+}
\ No newline at end of file
--- /dev/null
+//***************************************************
+// pcf8591d.c
+//
+// Example to read A/D values from a
+// 4 channel / 8 bit AD converter PCF8591
+// through I2C using the I2C driver improved by
+// Geert Vancompernolle
+// http://www.acmesystems.it/?id=10
+//***************************************************
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "unistd.h"
+#include "sys/ioctl.h"
+#include "fcntl.h"
+#include "time.h"
+#include "string.h"
+
+#include "i2c_errno.h"
+#include "etraxi2c.h"
+
+
+int main( int argc, char **argv ) {
+ int rtc;
+ int fd_i2c;
+ I2C_DATA i2c_d;
+ int ch;
+
+ printf("Reading from a PCF8591 (4 chanel A/D at 8 bits with I2C bus)\n");
+
+ fd_i2c = open( "/dev/i2c-0", O_RDWR );
+ if (fd_i2c<=0) {
+ printf( "Open error on /dev/i2c\n" );
+ exit( 1 );
+ }
+
+ // PCF8591 address scheme
+ // | 1 | 0 | 0 | 1 | A2 | A1 | A0 | R/W |
+// i2c_d.slave =(0x09<<4)|(0x01<<1);
+
+ i2c_d.slave = 0x48;
+
+ for (ch=0;ch<=3;ch++) {
+ // Select the A/D channel
+ i2c_d.wbuf[0] = ch;
+ i2c_d.wlen = 1;
+ if ((rtc=ioctl(fd_i2c,_IO( ETRAXI2C_IOCTYPE, I2C_WRITE), &i2c_d))!=EI2CNOERRORS) {
+ close(fd_i2c);
+ printf( "Error %d on line %d\n",rtc,__LINE__);
+ return ( -1 );
+ }
+
+ i2c_d.rlen = 3;
+ if ((rtc=ioctl(fd_i2c,_IO( ETRAXI2C_IOCTYPE, I2C_READ), &i2c_d))!=EI2CNOERRORS) {
+ close(fd_i2c);
+ printf( "Error %d on line %d\n",rtc,__LINE__);
+ return ( -1 );
+ }
+
+ // Show the voltage level
+ printf("Chanel %d = %.2fv (%02X hex)\n",ch,i2c_d.rbuf[2]*0.012941,i2c_d.rbuf[2]);
+ }
+
+ close(fd_i2c);
+ return(0);
+}
+
--- /dev/null
+#!/bin/sh
+
+I2CBUS=0
+I2CADDR=0x68
+
+if [ "$1" == "" ]
+then
+ date=`date -u +%Y%m%d%H%M%S`
+else
+ date=$1
+fi
+
+year=${date:2:2}
+month=${date:4:2}
+day=${date:6:2}
+
+hour=${date:8:2}
+min=${date:10:2}
+sec=${date:12:2}
+
+i2cset -y $I2CBUS $I2CADDR 0 0x$sec
+i2cset -y $I2CBUS $I2CADDR 1 0x$min
+i2cset -y $I2CBUS $I2CADDR 2 0x$hour
+i2cset -y $I2CBUS $I2CADDR 4 0x$day
+i2cset -y $I2CBUS $I2CADDR 5 0x$month
+i2cset -y $I2CBUS $I2CADDR 6 0x$year
--- /dev/null
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
+
+#include <unistd.h> /* add by paulerr*/
+
+
+#define CHIP "/dev/i2c-0"
+#define CHIP_ADDR 0x40 //HTU21D地址
+#define READ_TEMP 0XE3 //温度转换命令
+#define READ_HUM 0XE5 //湿度转换命令
+
+/* More info: https://github.com/kingmacth/Openwet-SDK/tree/master/package/HTU21D */
+
+unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor);
+
+int main()
+
+{
+ printf("hello,this is HTU21D tester \n");
+ int fd =open(CHIP, O_RDWR);
+ if (fd< 0) {
+ printf("open"CHIP"failed \n");
+ goto exit;
+ }
+
+ if (ioctl(fd,I2C_SLAVE_FORCE, CHIP_ADDR) < 0) { /*设置芯片地址 */
+ printf("oictl:setslave address failed\n");
+ goto close;
+ }
+
+ struct i2c_msg msg;
+
+ unsigned char rddata[3];
+ unsigned char rdaddr[2] = {0x10, 0}; /* 将要读取的数据在芯片中的偏移量 */
+ unsigned char TempAddr[2] = {0xe3, 0}; /* 发送E3读取温度 */
+ unsigned char HumAddr[2] = {0xE5, 0}; /* 发送E5读取湿度 */
+ unsigned short int tmp_dat,CRC_Result;
+ float Temp,Hum;
+ /*printf("inputa char you want to write to E2PROM\n");
+ wrbuf[2]= getchar();
+ printf("writereturn:%d, write data:%x\n", write(fd, wrbuf, 1), wrbuf[2]);
+ sleep(5);*/
+ //printf("Read temp!\n",write(fd, TempAddr, 1)); /* 开启温度转换 */
+ write(fd, TempAddr, 1);
+ usleep(100000);
+ read(fd, &rddata, 3); //读取两字节温度一字节校验
+
+ tmp_dat=rddata[0];
+ tmp_dat=tmp_dat<<8;
+ tmp_dat=tmp_dat+rddata[1];
+ //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
+ CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
+ //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
+ if(CRC_Result==0)
+ {
+ Temp=(tmp_dat*175.72)/65536-46.85;
+ printf("Temp=%.2f\n",Temp);
+ }
+ //printf("Read hum!\n",write(fd, HumAddr, 1)); /* 开启湿度转换 */
+ write(fd, HumAddr, 1);
+ usleep(100000);
+ read(fd, &rddata, 3); //读取两字节湿度一字节校验
+
+ tmp_dat=rddata[0];
+ tmp_dat=tmp_dat<<8;
+ tmp_dat=tmp_dat+rddata[1];
+ //printf("rddata:%x%02x,%x\n", rddata[0], rddata[1],rddata[2]);
+ CRC_Result=HTU21D_Check_CRC(tmp_dat,rddata[2]);
+ //printf("CRC=%x,%x\n",CRC_Result ,tmp_dat);//CRC校验
+ if(CRC_Result==0)
+ {
+ Temp=(tmp_dat*125)/65536-6;
+ printf("Hum=%.2f%%RH\n",Temp);
+ }
+
+close:
+ close(fd);
+exit:
+ return 0;
+
+}
+
+//**************************************************************************************************************
+//两个参数一个是传感器的源数据,另一个是传感器得出的CRC校验值
+//如果校验通过返回0,不通过返回非0
+//From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
+//POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
+#define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes
+//**************************************************************************************************************
+unsigned char HTU21D_Check_CRC(unsigned short int message_from_sensor,unsigned char check_value_from_sensor)
+{
+unsigned char i;
+//Test cases from datasheet:
+//message = 0xDC, checkvalue is 0x79
+//message = 0x683A, checkvalue is 0x7C
+//message = 0x4E85, checkvalue is 0x6B
+unsigned int remainder = (unsigned int)message_from_sensor << 8; //Pad with 8 bits because we have to add in the check value
+unsigned int divsor = (unsigned int)SHIFTED_DIVISOR;
+remainder |= check_value_from_sensor; //Add on the check value
+for (i = 0 ; i < 16 ; i++) //Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
+{
+if( remainder & (unsigned int)1<<(23 - i) ) //Check if there is a one in the left position
+remainder ^= divsor;
+divsor>>=1;//Rotatethedivsormax16timessothatwehave8bitsleftofaremainder
+}
+return(unsigned char)remainder;
+}
--- /dev/null
+/*
+ smbus.c - SMBus level access helper functions
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+ Copyright (C) 2012 Jean Delvare <khali@linux-fr.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+#include <errno.h>
+#include "smbus.h" // NB: Path changed!
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/i2c-dev.h>
+
+//NB: Added by John Burns
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Compatibility defines */
+#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
+#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
+#endif
+#ifndef I2C_FUNC_SMBUS_PEC
+#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
+#endif
+
+__s32 i2c_smbus_access(int file, char read_write, __u8 command,
+ int size, union i2c_smbus_data *data)
+{
+ struct i2c_smbus_ioctl_data args;
+ __s32 err;
+
+ args.read_write = read_write;
+ args.command = command;
+ args.size = size;
+ args.data = data;
+
+ err = ioctl(file, I2C_SMBUS, &args);
+ if (err == -1)
+ err = -errno;
+ return err;
+}
+
+
+__s32 i2c_smbus_write_quick(int file, __u8 value)
+{
+ return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
+}
+
+__s32 i2c_smbus_read_byte(int file)
+{
+ union i2c_smbus_data data;
+ int err;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
+ if (err < 0)
+ return err;
+
+ return 0x0FF & data.byte;
+}
+
+__s32 i2c_smbus_write_byte(int file, __u8 value)
+{
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
+ I2C_SMBUS_BYTE, NULL);
+}
+
+__s32 i2c_smbus_read_byte_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ int err;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
+ I2C_SMBUS_BYTE_DATA, &data);
+ if (err < 0)
+ return err;
+
+ return 0x0FF & data.byte;
+}
+
+__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
+{
+ union i2c_smbus_data data;
+ data.byte = value;
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BYTE_DATA, &data);
+}
+
+__s32 i2c_smbus_read_word_data(int file, __u8 command)
+{
+ union i2c_smbus_data data;
+ int err;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
+ I2C_SMBUS_WORD_DATA, &data);
+ if (err < 0)
+ return err;
+
+ return 0x0FFFF & data.word;
+}
+
+__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_WORD_DATA, &data);
+}
+
+__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
+{
+ union i2c_smbus_data data;
+ data.word = value;
+ if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_PROC_CALL, &data))
+ return -1;
+ else
+ return 0x0FFFF & data.word;
+}
+
+/* Returns the number of read bytes */
+__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i, err;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
+ I2C_SMBUS_BLOCK_DATA, &data);
+ if (err < 0)
+ return err;
+
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+}
+
+__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
+ const __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BLOCK_DATA, &data);
+}
+
+/* Returns the number of read bytes */
+/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
+ ask for less than 32 bytes, your code will only work with kernels
+ 2.6.23 and later. */
+__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
+ __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i, err;
+
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+ data.block[0] = length;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
+ length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
+ I2C_SMBUS_I2C_BLOCK_DATA, &data);
+ if (err < 0)
+ return err;
+
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+}
+
+__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
+ const __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i;
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+ return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
+}
+
+/* Returns the number of read bytes */
+__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
+ __u8 *values)
+{
+ union i2c_smbus_data data;
+ int i, err;
+
+ if (length > I2C_SMBUS_BLOCK_MAX)
+ length = I2C_SMBUS_BLOCK_MAX;
+ for (i = 1; i <= length; i++)
+ data.block[i] = values[i-1];
+ data.block[0] = length;
+
+ err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
+ I2C_SMBUS_BLOCK_PROC_CALL, &data);
+ if (err < 0)
+ return err;
+
+ for (i = 1; i <= data.block[0]; i++)
+ values[i-1] = data.block[i];
+ return data.block[0];
+}
--- /dev/null
+/*
+ smbus.h - SMBus level access helper functions
+
+ Copyright (C) 1995-97 Simon G. Vogl
+ Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+#ifndef LIB_I2C_SMBUS_H
+#define LIB_I2C_SMBUS_H
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+extern __s32 i2c_smbus_access(int file, char read_write, __u8 command,
+ int size, union i2c_smbus_data *data);
+
+extern __s32 i2c_smbus_write_quick(int file, __u8 value);
+extern __s32 i2c_smbus_read_byte(int file);
+extern __s32 i2c_smbus_write_byte(int file, __u8 value);
+extern __s32 i2c_smbus_read_byte_data(int file, __u8 command);
+extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
+extern __s32 i2c_smbus_read_word_data(int file, __u8 command);
+extern __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
+extern __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
+
+/* Returns the number of read bytes */
+extern __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
+extern __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
+ const __u8 *values);
+
+/* Returns the number of read bytes */
+/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
+ ask for less than 32 bytes, your code will only work with kernels
+ 2.6.23 and later. */
+extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
+ __u8 *values);
+extern __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
+ const __u8 *values);
+
+/* Returns the number of read bytes */
+extern __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
+ __u8 *values);
+
+#endif /* LIB_I2C_SMBUS_H */
--- /dev/null
+#!/bin/sh
+
+date -u -s "`gethwclock`"