linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Available user-level tool for I2C device?
@ 2005-09-29 12:35 Sam Song
  2005-09-29 16:57 ` Eugene Surovegin
  2005-09-29 18:59 ` Tolunay Orkun
  0 siblings, 2 replies; 7+ messages in thread
From: Sam Song @ 2005-09-29 12:35 UTC (permalink / raw)
  To: linuxppc-embedded

Hi all,

I'd like to ask whether there is user-level utility
for I2C device registers access like lspci/setpci for
PCI device?

I have a RTC chip DS1337 on a 8248 target. It can
work right in u-boot and linux. If no similar utility,
I will switch to change hwclock.c in busybox to make
it. Any idea?

Thanks in advance,

Sam

__________________________________________________
赶快注册雅虎超大容量免费邮箱?
http://cn.mail.yahoo.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-09-29 12:35 Available user-level tool for I2C device? Sam Song
@ 2005-09-29 16:57 ` Eugene Surovegin
  2005-10-01  3:50   ` Sam Song
  2005-09-29 18:59 ` Tolunay Orkun
  1 sibling, 1 reply; 7+ messages in thread
From: Eugene Surovegin @ 2005-09-29 16:57 UTC (permalink / raw)
  To: Sam Song; +Cc: linuxppc-embedded

On Thu, Sep 29, 2005 at 08:35:35PM +0800, Sam Song wrote:
> I have a RTC chip DS1337 on a 8248 target. It can
> work right in u-boot and linux. If no similar utility,
> I will switch to change hwclock.c in busybox to make
> it. Any idea?

Right approach would be making standard in-kernel RTC driver for this 
chip. In fact, such driver was already posted to lm-sensors list some 
time ago.

-- 
Eugene

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-09-29 12:35 Available user-level tool for I2C device? Sam Song
  2005-09-29 16:57 ` Eugene Surovegin
@ 2005-09-29 18:59 ` Tolunay Orkun
  2005-10-01  3:58   ` Sam Song
  1 sibling, 1 reply; 7+ messages in thread
From: Tolunay Orkun @ 2005-09-29 18:59 UTC (permalink / raw)
  To: Sam Song; +Cc: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 530 bytes --]

Sam,

Sam Song wrote:
> Hi all,
> 
> I'd like to ask whether there is user-level utility
> for I2C device registers access like lspci/setpci for
> PCI device?
> 
> I have a RTC chip DS1337 on a 8248 target. It can
> work right in u-boot and linux. If no similar utility,
> I will switch to change hwclock.c in busybox to make
> it. Any idea?
> 
> Thanks in advance,
> 
> Sam

I've a hwclock.c implementation for DS1307/DS1338. I do not know how
close DS1337 was but it should not be too difficult to adapt.

Best regards,
Tolunay

[-- Attachment #2: hwclock_ds1307.c --]
[-- Type: text/x-csrc, Size: 6803 bytes --]

/*
 * Mini hwclock implementation suitable for DS1307/DS1338 RTC chips
 *
 * Copyright (C) 2004 NextIO Inc. - Tolunay Orkun <torkun@nextio.com>
 *
 * Based on GPL licensed code from Busybox and U-boot projects
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
*/

#include <sys/ioctl.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>
#include <stdio.h>
#include <libgen.h>
#include <stdlib.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define DS1307_ADDR	0x68

struct i2c_ioctl_rdwr_data {
	struct i2c_msg *msgs;
	int nmsgs;
};

int i2c_xfer(int addr, char *wbuf, int wcount, char *rbuf, int rcount)
{
	int fd, i;
	int val, nmsgs;
	struct i2c_msg msg[2];
	struct i2c_ioctl_rdwr_data ioctl_rdwr_data;

	memset(msg, 0, sizeof(msg));
	memset(&ioctl_rdwr_data, 0, sizeof(ioctl_rdwr_data));

	nmsgs = 0;
	if (wcount > 0) {
		msg[nmsgs].addr  = addr;
		msg[nmsgs].flags = 0;
		msg[nmsgs].len   = wcount;
		msg[nmsgs].buf   = wbuf;
		nmsgs++;
	}

	if (rcount > 0) {
		msg[nmsgs].addr  = addr;
		msg[nmsgs].flags = I2C_M_RD;
		msg[nmsgs].len   = rcount;
		msg[nmsgs].buf   = rbuf;
		nmsgs++;
	}

	ioctl_rdwr_data.msgs = msg;
	ioctl_rdwr_data.nmsgs = nmsgs;

#ifdef DEBUG
	if (wcount > 0) {
		printf("Writing i2c...\n");
		printf("Addr : %3d (0x%02x)\n", addr, addr);
		printf("Count: %3d (0x%02x)\n", wcount, wcount);
		printf("Data :\n");
		for (i = 0; i < wcount; i++) {
			val = wbuf[i];
			printf("%3d (0x%02x) = %3d (0x%02x)\n", i, i, val, val);
		}
		printf("\n");
	}

	if (rcount > 0) {
		printf("Reading i2c...\n");
		printf("Addr : %3d (0x%02x)\n", addr, addr);
		printf("Count: %3d (0x%02x)\n", rcount, rcount);
	}
#endif

	fd = open("/dev/i2c0", O_RDWR);
	if (fd < 0) {
		fd = open("/dev/i2c/0", O_RDWR);
		if (fd < 0) {
			printf("Can't open i2c\n");
			return 1;
		}
	}

	if (ioctl(fd, I2C_RDWR, &ioctl_rdwr_data) < 0) {
		printf("I2C I/O Error\n");
		close(fd);
		return 2;
	}

#ifdef DEBUG
	if (rcount > 0) {
		printf("Data :\n");
		for (i = 0; i < rcount; i++) {
			val = rbuf[i];
			printf("%3d (0x%02x) = %3d (0x%02x)\n", i, i, val, val);
		}
		printf("\n");
	}
#endif
	
	close(fd);
	return 0;
}

unsigned int bcd2bin(unsigned char n)
{
	return ((((n >> 4) & 0x0f) * 10) + (n & 0x0f));
}

unsigned char bin2bcd(unsigned int n)
{
	return (((n / 10) << 4) | (n % 10));
}

time_t read_rtc(int utc)
{
	char reg = 0; /* register start address for transfer */
	char buf[8];
	struct tm tm;
	char *oldtz = NULL;
	time_t t = 0;

	if (i2c_xfer(DS1307_ADDR, &reg, sizeof(reg), buf, sizeof(buf)) != 0)
		return -1;

	memset(&tm, 0, sizeof(struct tm));
	tm.tm_sec  = bcd2bin(buf[0] & 0x7f);
	tm.tm_min  = bcd2bin(buf[1] & 0x7f);
	tm.tm_hour = bcd2bin(buf[2] & 0x3f);
	tm.tm_wday = bcd2bin(buf[3] & 0x07) - 1;
	tm.tm_mday = bcd2bin(buf[4] & 0x3f);
	tm.tm_mon  = bcd2bin(buf[5] & 0x1f) - 1;
	tm.tm_year = bcd2bin(buf[6]) + 100;
	tm.tm_isdst = -1; /* unknown */

	if (utc) {
		oldtz = getenv("TZ");
		setenv("TZ", "UTC 0", 1);
		tzset();
	}

	t = mktime(&tm);

	if (utc) {
		if (oldtz)
			setenv("TZ", oldtz, 1);
		else
			unsetenv("TZ");
		tzset();
	}

	return t;
}

int write_rtc(time_t t, int utc)
{
	char buf[8];
	struct tm tm;

	tm = *(utc ? gmtime(&t) : localtime(&t));

	buf[0] = 0; /* register start address for transfer */
	buf[1] = bin2bcd(tm.tm_sec);
	buf[2] = bin2bcd(tm.tm_min);
	buf[3] = bin2bcd(tm.tm_hour);
	buf[4] = bin2bcd(tm.tm_wday + 1);
	buf[5] = bin2bcd(tm.tm_mday);
	buf[6] = bin2bcd(tm.tm_mon + 1);
	buf[7] = bin2bcd(tm.tm_year - 100);

	if (i2c_xfer(DS1307_ADDR, buf, sizeof(buf), NULL, 0) != 0)
		return -1;

	return 0;
}

int show_clock(int utc)
{
	time_t t;
	char   buffer[64];
	char   *p;
	int    len;

	buffer[0] = '\0';
	t = read_rtc(utc);
	p = ctime(&t);
	if (p) {
		len = strlen(p) - 1; /* strip newline */
		if (len >= sizeof(buffer))
			len = sizeof(buffer) - 1;
		memcpy(buffer, p, len);
		buffer[len] = '\0';
	}

	printf("%s 0.000000 seconds\n", buffer);
	return 0;
}

int to_sys_clock(int utc)
{
	struct timeval tv;

	memset(&tv, 0, sizeof(tv));
	tv.tv_sec = read_rtc(utc);
	return settimeofday(&tv, NULL);
}

int from_sys_clock(int utc)
{
	struct timeval tv;

	memset(&tv, 0, sizeof(tv));
	gettimeofday(&tv, NULL);
	return write_rtc(tv.tv_sec, utc); 
}

void show_usage(char *progname)
{
	char buf[64];

	strncpy(buf, progname, sizeof(buf));
	buf[sizeof(buf) - 1] = '\0';
	basename(buf);

	printf("%s - query and set the hardware clock (DS1307/1338 RTC)\n\n", buf);
	printf("Usage: %s [options...]\n\n", buf);
	printf("Options:\n");
	printf("\t-r, --show\tread hardware clock and print result\n");
	printf("\t-s, --hctosys\tset the system time from the hardware clock\n");
	printf("\t-w, --systohc\tset the hardware clock to the current system time\n\n");
	printf("\t-u, --utc\tthe hardware clock is kept in universal time\n");
	printf("\t-l, --localtime\tthe hardware clock is kept in local time\n\n");
	exit(-1);
}

int main(int argc, char *argv[])
{
	int  opt_help = 0;
	int  opt_localtime = 0;
	int  opt_utc = 0;
	int  func_show = 0;
	int  func_hctosys = 0;
	int  func_systohc = 0;
	int  func_count;
	int  utc;
	int  c;

	static struct option long_options[] = {
		{ "show",	0, 0, 'r' },
		{ "hctosys",	0, 0, 's' },
		{ "systohc",	0, 0, 'w' },
		{ "localtime",	0, 0, 'l' },
		{ "utc",	0, 0, 'u' },
		{ "help",	0, 0, '?' },
		{ 0,		0, 0, 0   }
	};
	int opt_idx = 0;

	while (1) {
		c = getopt_long(argc, argv, "rswlu?h", long_options, &opt_idx);	
		if (c == -1)
			break;

		switch (c) {
			case 'r':
				func_show = 1;
				break;
			case 's':
				func_hctosys = 1;
				break;
			case 'w':
				func_systohc = 1;
				break;
			case 'l':
				opt_localtime = 1;
				break;
			case 'u':
				opt_utc = 1;
				break;
			default:
				opt_help = 1;
				break;
		}
	}

	func_count = func_show + func_hctosys + func_systohc;
	if (func_count > 1)
		show_usage(argv[0]);
	
	if (opt_localtime && opt_utc)
		show_usage(argv[0]);

	if (opt_help)
		show_usage(argv[0]);

	if (func_hctosys)
		return to_sys_clock(opt_utc);
	else if (func_systohc)
		return from_sys_clock(opt_utc);
	else
		return show_clock(opt_utc);
	
	return 0;
}

/* ex: set sw=4 ts=4: */

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-09-29 16:57 ` Eugene Surovegin
@ 2005-10-01  3:50   ` Sam Song
  0 siblings, 0 replies; 7+ messages in thread
From: Sam Song @ 2005-10-01  3:50 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: linuxppc-embedded

Eugene Surovegin <ebs@ebshome.net>写道:
> Right approach would be making standard in-kernel
> RTC driver for this chip. In fact, such driver was 
> already posted to lm-sensors list some time ago.

I happen to have a LM75 on this board. Your hints 
remind me to follow the lm-sensors list to find 
something special on this point as well.

Thanks a lot,

Sam



	

	
		
___________________________________________________________ 
雅虎免费G邮箱-中国第一绝无垃圾邮件骚扰超大邮箱 
http://cn.mail.yahoo.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-09-29 18:59 ` Tolunay Orkun
@ 2005-10-01  3:58   ` Sam Song
  2005-10-02 13:58     ` Yuli Barcohen
  0 siblings, 1 reply; 7+ messages in thread
From: Sam Song @ 2005-10-01  3:58 UTC (permalink / raw)
  To: Tolunay Orkun; +Cc: linuxppc-embedded

Tolunay Orkun <listmember@orkun.us> wrote:
> I've a hwclock.c implementation for DS1307/DS1338. I
> do not know how close DS1337 was but it should not 
> be too difficult to adapt.

Tolunay, thank you so much for providing me this 
closest stuff. It can just work right on DS1337 on
my board. I just added alarm register operation in it.
After finshing LM75 porting on this board, I'd like
to try to get a common i2c utility just like "imd"
and "imm" in u-boot.

Have a nice weekend,

Sam

__________________________________________________
赶快注册雅虎超大容量免费邮箱?
http://cn.mail.yahoo.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-10-01  3:58   ` Sam Song
@ 2005-10-02 13:58     ` Yuli Barcohen
  2005-10-05  3:33       ` Sam Song
  0 siblings, 1 reply; 7+ messages in thread
From: Yuli Barcohen @ 2005-10-02 13:58 UTC (permalink / raw)
  To: Sam Song; +Cc: Jonathan Masel, linuxppc-embedded

[-- Attachment #1: message body and .signature --]
[-- Type: text/plain, Size: 1201 bytes --]

>>>>> Sam Song writes:

    Sam> Tolunay Orkun <listmember@orkun.us> wrote:
    Tolunay> I've a hwclock.c implementation for DS1307/DS1338. I do not
    Tolunay> know how close DS1337 was but it should not be too
    Tolunay> difficult to adapt.

    Sam> Tolunay, thank you so much for providing me this closest
    Sam> stuff. It can just work right on DS1337 on my board. I just
    Sam> added alarm register operation in it.  After finshing LM75
    Sam> porting on this board, I'd like to try to get a common i2c
    Sam> utility just like "imd" and "imm" in u-boot.

You can try the tool which I wrote to test SPI-connected MMC card and
different I2C chips (EEPROMs, temperature sensors, etc.). As it was
discussed on the list, our implementation of SPI uses I2C infrastructure
so the same tool works for both I2C and SPI. I attached to this mail the
source, brief documentation, and some examples.

-- 
========================================================================
 Yuli Barcohen       | Phone +972-9-765-1788 |  Software Project Leader
 yuli@arabellasw.com | Fax   +972-9-765-7494 | Arabella Software, Israel
========================================================================

[-- Attachment #2: i2cspi.c --]
[-- Type: text/plain, Size: 6220 bytes --]

/*
 * Copyright (C) 2005 Arabella Software Ltd.
 * Yuli Barcohen <yuli@arabellasw.com>
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <getopt.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define READ  0x1234
#define WRITE 0x5678
#define XCHG  0xABCD

__u8 dat[16 * 1024];

struct i2c_msg msgs[256];

struct i2c_rdwr_ioctl_data xchg = {
   msgs,				/* pointers to i2c_msgs */
   sizeof(msgs)/sizeof(struct i2c_msg)	/* number of i2c_msgs */
};

static struct option long_options[] = {
   {"bus",      1, 0, 'b'},
   {"data-out", 1, 0, 'd'},
   {"data-len", 1, 0, 'l'},
   {"in-file",  1, 0, 'i'},
   {"out-file", 1, 0, 'o'},
   {"raw",      0, 0, 'r'},
   {"verbose",  0, 0, 'v'},
   {"help",     0, 0, 'h'},
   {0, 0, 0, 0}
};

int main(int argc, char *argv[])
{
   int opt, lopt_idx = 0;
   int raw = 0, verbose = 0, len = 0;
   char *data = NULL, *busdev = NULL, *infile = NULL, *outfile = NULL;
   long slave;
   int din = 0, dout = 1, dev;
   ssize_t count;
   char buf[128], hex[3];
   int i, j, k, m;
   int cur_msg = -1, ichar, ochar;
   unsigned l, p, cur_cmd = READ;

   while ((opt = getopt_long(argc, argv, "b:d:l:i:o:rvh", long_options, &lopt_idx)) != -1)
   {
      switch (opt)
      {
	 case 'b':
	    busdev = strdup(optarg);
	    break;
	 case 'd':
	    data = strdup(optarg);
	    if (data == NULL)
	    {
	       perror(NULL);
	       return 1;
	    }
	    break;
	 case 'l':
	    len = atoi(optarg);
	    break;
	 case 'i':
	    infile = strdup(optarg);
	    break;
	 case 'o':
	    outfile = strdup(optarg);
	    break;
	 case 'r':
	    raw = 1;
	    break;
	 case 'v':
	    verbose = 1;
	    break;
	 case 'h':
	    return 0;
      }
   }

   if (optind >= argc)
   {
      fprintf(stderr, "No slave address specified\n");
      return 2;
   }

   slave = strtol(argv[optind], NULL, 16);

   if (infile)
   {
      din = open(infile, O_RDONLY);
      if (din < 0)
      {
	 perror(infile);
	 return 3;
      }
   }

   if (outfile)
   {
      dout = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
		  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
      if (dout < 0)
      {
	 perror(outfile);
	 close(din);
	 return 4;
      }
   }

   if (busdev == NULL)
      if (access("/dev/.devfsd", F_OK))
	 busdev = "/dev/i2c-0";
      else
	 busdev = "/dev/i2c/0";

   dev = open(busdev, O_RDWR);
   if (dev < 0)
   {
      perror(busdev);
      close(din);
      close(dout);
      return 5;
   }

   ioctl(dev, I2C_SLAVE, slave);

   hex[2] = 0;
   ochar = 0;
   while (count = read(din, buf, sizeof(buf)))
   {
      ichar = 0;
      while (ichar < count)
      {
	 switch (buf[ichar++])
	 {
	    case 'r': /* Read from the slave */
	       msgs[++cur_msg].addr = cur_cmd = READ;
	       sscanf(buf + ichar, "%u%n", &l, &k);
	       msgs[cur_msg].len = l;
	       msgs[cur_msg].buf = dat + ochar;
	       msgs[cur_msg].flags = I2C_M_RD;
	       ochar += l;
	       ichar += k;
	       break;

	    case 'w': /* Write to the slave */
	       msgs[++cur_msg].addr = cur_cmd = WRITE;
	       msgs[cur_msg].buf = dat + ochar;
	       msgs[cur_msg].len = 0;
	       msgs[cur_msg].flags = 0;
	       break;

	    case 'x': /* Data eXchange (I2C_RDWR) */
	       cur_cmd = XCHG;
	       msgs[++cur_msg].addr = slave;
	       msgs[cur_msg].buf = dat + ochar;
	       msgs[cur_msg].len = 0;
	       sscanf(buf + ichar, "%x%n", &l, &k);
	       msgs[cur_msg].flags = l;
	       ichar += k;
	       break;

	    case 'p': /* Pattern for eXchange timing */
	       if (cur_cmd == XCHG)
	       {
		  sscanf(buf + ichar, "%u%x%n", &l, &p, &k);
		  memset(dat + ochar, p, l);
		  msgs[cur_msg].len += l;
		  ochar += l;
		  ichar += k;
	       }
	       else
	       {
		  fprintf(stderr, "eXchage command required before Pattern\n");
		  goto finish;
	       }
	       break;

	    case 'u': /* rUn */
	       m = 0;
	       while (m <= cur_msg)
	       {
		  if (msgs[m].addr == READ)
		     read(dev, msgs[m].buf, msgs[m].len);
		  else if (msgs[m].addr == WRITE)
		     write(dev, msgs[m].buf, msgs[m].len);
		  else
		  {
		     xchg.msgs  = msgs + m;
		     xchg.nmsgs = 1;
		     m++;
		     while (m <= cur_msg)
		     {
			if ((msgs[m].addr != READ) && (msgs[m].addr != WRITE))
			{
			   xchg.nmsgs++;
			   m++;
			}
			else
			   break;
		     }
		     m--;

		     ioctl(dev, I2C_RDWR, &xchg);
		  }

		  m++;
	       }
	       for (m = 0; m <= cur_msg; m++)
	       {
		  if (msgs[m].flags & I2C_M_RD)
		     if (raw)
			write(dout, msgs[m].buf, msgs[m].len);
		     else
		     {
			for (i = 0; i < msgs[m].len; i++)
			{
			   sprintf(hex, "%2.2X", (unsigned)(msgs[m].buf[i]));
			   write(dout, hex, 2);
			}
			write(dout, "\n", 1);
		     }
	       }
	       cur_msg = -1;
	       ochar = 0;
	       break;

	    case ' ':
	    case '\t':
	    case '\n':
	    case '\r':
	       break;

	    default:
	       if (cur_cmd == READ)
	       {
		  fprintf(stderr, "Write or eXchage command required: %1.1s\n",
			  buf + ichar - 1);
		  goto finish;
	       }

	       if (isxdigit(buf[ichar - 1]) && isxdigit(buf[ichar]))
	       {
		  hex[0] = buf[ichar - 1];
		  hex[1] = buf[ichar++];
		  dat[ochar++] = (char)strtoul(hex, NULL, 16);
		  msgs[cur_msg].len++;
	       }
	       else
	       {
		  fprintf(stderr, "Illegal digit %2.2s\n", buf + ichar - 1);
		  goto finish;
	       }
	 }
      }
   }

  finish:
   close(din);
   close(dout);
   close(dev);

   return 0;
}

[-- Attachment #3: i2cspi.txt --]
[-- Type: text/plain, Size: 3147 bytes --]

                              Using i2cspi

i2cspi takes I2C/SPI-related commands from a file (or standard input),
executes them and writes output read from the I2C/SPI peripherals to a
file (or standard output).

To run i2cspi, type the following:

   i2cspi [-b devname] [-i file] [-o file] [-r] slaveadr

where

   slaveadr	is the address of the I2C peripheral to be accessed.

Optional parameters (where supplied) are used as follows:

   -b devname	selects the bus; "devname" is the full device name of
                the I2C bus. Default is /dev/i2c-0.
   -i file	sets the input file to "file". If not specified, the
                standard input is used.
   -o file	sets the output file to "file". If not specified, the
                standard output is used.
   -r	        specifies raw mode (binary data is dumped raw to output
                instead of formatted by printf via %x). Rarely required. 

i2cspi input file format

The input file for i2cspi is a string of I2C/SPI commands entered as
ASCII text. All white-space (including carriage-returns, tabs, etc) are
taken as delimiters and otherwise ignored, so the commands may be
entered line-by-line or on a single line separated by white space. The
command letters do not need delimiters - they may appear immediately
before or after a numeric value (x1 is equivalent to x 1).

The following commands may be used in i2cspi:

   r n          read n (decimal number) bytes from the slave. In typical
                cases, this is rarely used since a write usually needs
                to precede a read operation.

   w seq	write a sequence of hex bytes to the peripheral. Each
                byte is represented by two hex characters; the sequence
                is terminated by white space. For most SPI peripherals,
                this command is only rarely used.

   x flags seq [p n]	this is the data exchange operation and is the
                        most commonly used SPI operation. Data is
                        written and read to the peripheral in
                        parallel. Note that the same number of clocks
                        are required for both read and write operation,
                        so you need to pad any write sequence to the
                        length of the read sequence that you wish to
                        read. Parameters for the 'x' command are as
                        follows:

      flags	are a hex number and as defined in the Linux I2C
                infrastructure. The two flags of relevance are:

         0x0001 - read data returning from the peripheral in parallel to
                  writing
         0x4000 - do not de-select the peripheral after the operation
                  has completed

      seq	is a sequence of hex bytes (2 characters per byte). If
      [p n] is specified, the sequence is repeated 'n' (decimal)
      times. This is useful for long sequences.

   u EXECUTE ALL PRECEDING COMMANDS. DO NOT FORGET THE 'U' COMMANDS
     SINCE WITHOUT IT NOTHING WILL HAPPEN! IN PARTICULAR, WE DO NOT
     ASSUME 'U' AT EOF, SO MAKE SURE YOUR INPUT FILE ENDS WITH A 'U'
     COMMAND.

[-- Attachment #4: examples --]
[-- Type: text/plain, Size: 437 bytes --]

# Reset MMC card and switch it to SPI mode
echo w400000000095u | i2cspi -b /dev/i2c/1 1

# Poll until the card passes reset and reports ready state
while true; do echo x1 410000000001p8 ffu | i2cspi -b /dev/i2c/1 1; sleep 10; done

# Read OCR
echo x1 7a0000000001ffffffffffffffu | i2cspi -b /dev/i2c/1 1

# Read CSD
echo x1 490000000001 p32 ffu | i2cspi -b /dev/i2c/1 1

# Read CID
echo x1 4a0000000001 p32 ffu | i2cspi -b /dev/i2c/1 1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Available user-level tool for I2C device?
  2005-10-02 13:58     ` Yuli Barcohen
@ 2005-10-05  3:33       ` Sam Song
  0 siblings, 0 replies; 7+ messages in thread
From: Sam Song @ 2005-10-05  3:33 UTC (permalink / raw)
  To: Yuli Barcohen; +Cc: Jonathan Masel, linuxppc-embedded

Yuli Barcohen <yuli@arabellasw.com> wrote:
> so the same tool works for both I2C and SPI. I
> attached to this mail the
> source, brief documentation, and some examples.

Greatly appreciate! This utility is on the top of
what I expected and thought. 

Sam


		
___________________________________________________________ 
雅虎邮箱超强增值服务-2G超大空间、pop3收信、无限量邮件提醒 
http://cn.mail.yahoo.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-10-05  3:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-29 12:35 Available user-level tool for I2C device? Sam Song
2005-09-29 16:57 ` Eugene Surovegin
2005-10-01  3:50   ` Sam Song
2005-09-29 18:59 ` Tolunay Orkun
2005-10-01  3:58   ` Sam Song
2005-10-02 13:58     ` Yuli Barcohen
2005-10-05  3:33       ` Sam Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).