Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Starting with TWI (I2C)
PostPosted: Mon Dec 10, 2007 2:20 pm 
Offline

Joined: Mon Aug 20, 2007 1:45 am
Posts: 20
I need to write a driver, which asks first the device on TWI.

I started doing it, but I couldn't find an answer how to that :( Can anyone help me?

What's needed and how should it be done? Any sample code anywhere?

(Kernel 2.6.23, Master: AT91RM9200)

Thanks,

Viper


Last edited by Viper on Tue Feb 26, 2008 10:58 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 04, 2008 3:09 pm 
Offline
User avatar

Joined: Fri Feb 13, 2004 7:53 pm
Posts: 329
You can start by reading the TWI application note:

http://www.atmel.com/dyn/products/app_n ... ily_id=605
then go to the "Application Example and Algorithms" Section

this is the AT91-AN01 App. note.

Rgds,


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 25, 2008 2:28 pm 
Offline

Joined: Thu Feb 03, 2005 11:41 am
Posts: 87
Location: Erfurt/Germany
Hi,

try taking a look into other drivers working with I2C, like the RTC8564. As you might see you only need to provide the addresses and call a scan function.

--
Mike

_________________
Senior IT Consultant
Germany


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 26, 2008 12:00 pm 
Offline

Joined: Fri Sep 28, 2007 2:02 pm
Posts: 5
Hi,

could someone post some C code for Linux I also have to implement a communication with a li-ionen battery.

I don't have any experience in accessing hardware under linux.

How can I open the device and read or write it?

I have to work on a Kernel 2.6.23 (AT91SAM9263)

Tanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 28, 2008 2:42 pm 
Offline

Joined: Wed Jan 23, 2008 12:22 pm
Posts: 6
Location: Germany
Hi,

take a look in the "Linux Device Driver" Book.
It will give you the way to go.

Here http://lwn.net/Kernel/LDD3/ you can download it.

Regards
Markus


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 12, 2008 3:40 pm 
Offline

Joined: Mon Aug 20, 2007 1:45 am
Posts: 20
mwolfram wrote:
Hi,

try taking a look into other drivers working with I2C, like the RTC8564. As you might see you only need to provide the addresses and call a scan function.

--
Mike

I did that one already. But I want to write a low-level driver for my CMOS sensor, which uses I2C for configuration. Should I use standard ioctl's to the AT91's linux driver, or implement my own one (e.g. copy from the linux driver) to my driver and use natively the I2C from the cmos driver?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 26, 2008 11:03 pm 
Offline

Joined: Mon Aug 20, 2007 1:45 am
Posts: 20
I've written an userspace utility to access an SRF08 ultrasonic device via I2C.
My small utility compiles well, but when it tries to open the i2c-0 it get's an error. What can be wrong?

/* I'm using normal read as a file method, not the smbus stub */
/* as I can see the /dev/i2c-0 exists, the kernel loads something e.g. creates the /dev devices - AT91 I2C support complied in the kernel with bitbang algorithm */


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 11, 2008 7:09 pm 
Offline

Joined: Mon May 28, 2007 5:02 pm
Posts: 50
Location: Walton-on-Thames, UK
I have written a user space application to write to I2C devices with no problem.

Before we go into that it might be worth you looking at i2ctools http://www.lm-sensors.org/wiki/I2CTools. If you use these at least you can tell if your hardware is working.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 11, 2008 7:11 pm 
Offline

Joined: Mon May 28, 2007 5:02 pm
Posts: 50
Location: Walton-on-Thames, UK
I have written a user space application to write to I2C devices with no problem.

Before we go into that it might be worth you looking at i2ctools http://www.lm-sensors.org/wiki/I2CTools. If you use these at least you can tell if your hardware is working.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 18, 2008 5:17 pm 
Offline

Joined: Sun Sep 02, 2007 1:39 pm
Posts: 77
fingar wrote:
Before we go into that it might be worth you looking at i2ctools http://www.lm-sensors.org/wiki/I2CTools. If you use these at least you can tell if your hardware is working.


Perhaps someone can elaborate, I'm trying to use i2cset on a at91sam9263-ek board with a 2.6.22 kernel.
The kernel has all the atmel patches as per instructions on linux4sam, but i2c writing fails.

On the 9263-ek, mn11 (serial eeprom) has address 0x50 (please correct me if wrong). An attempt to write fails:
Code:
#./i2cset 0 80 1 10 b 
WARNING! This program can confuse your I2C bus, cause data loss and worse!
DANGEROUS! Writing to a serial EEPROM on a memory DIMM
may render your memory USELESS and make your system UNBOOTABLE!
I will write to device file /dev/i2c-0, chip address 0x50, data address
0x01, data 0x0a, mode byte.
Continue? [y/N] y
Warning - data mismatch - wrote 0x0a, read back 0xff


Am I doing something wrong ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 25, 2008 10:58 am 
Offline

Joined: Mon May 28, 2007 5:02 pm
Posts: 50
Location: Walton-on-Thames, UK
I forgot to tell you that you need to remove any drivers you have for this device from the kernel before using i2ctools, otherwise they are protected by the kernel and i2ctools can't get at them.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 25, 2008 11:28 am 
Offline

Joined: Sun Sep 02, 2007 1:39 pm
Posts: 77
fingar wrote:
I forgot to tell you that you need to remove any drivers you have for this device from the kernel before using i2ctools, otherwise they are protected by the kernel and i2ctools can't get at them.


When I try something really simple (see code below) it doesn't work as I expected.

I've created 2 executables, one to test a write action, another to test a read action.
Running them through strace, everything appears normal but data never gets writtern (or read), I'll need to investigate that using a scope.

Code:

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

#define TEST_WRITE 1
int main(int argc, char **argv)
{
int fd;
char buf[2];

  fd = open("/dev/i2c-0", O_RDWR);

  if (!fd)
  {
    perror("open(): ");
    return 0;
  }

  ioctl(fd,I2C_SLAVE, 0x50); // set the eeprom address
  ioctl(fd,I2C_TIMEOUT,10);  // set the timeout
  ioctl(fd,I2C_RETRIES,1);   // set the retries

  buf[0] = 0;
  buf[1] = 0;
  if (write(fd,&buf,2) != 2)    // set address to read from/write to
    perror("write()");

#ifdef TEST_WRITE
  buf[0] = 0xAA;
  buf[1] = 0x55;

  if (write(fd, &buf, 2) != 2)
    perror("write(): ");
#else
  if (read(fd, buf, 2) != 2)
    perror("read()");

  printf("0: %02x\n", buf[0]);
  printf("1: %02x\n", buf[1]);
#endif


  close(fd);
  return 0;
}


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 25, 2008 10:43 pm 
Offline

Joined: Sun Sep 02, 2007 1:39 pm
Posts: 77
limpens wrote:
When I try something really simple (see code below) it doesn't work as I expected.




..sigh.. Although I hate to answer my own questions, I'ld like other to benefit from the answers in the forum.

Using proper equipment, I noticed the driver sends the device address, every time I start a write() action. This probably is documentend, but I didn't expect this behaviour.

So, writing to address 0 of device 0x50 (the 24c512 on the 9263-ek board):

Code:
#include <stdio.h>
#include <linux/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define TEST_WRITE 1
int main(int argc, char **argv)
{
int fd;
char buf[4];

  fd = open("/dev/i2c-0", O_RDWR);

  if (!fd)
  {
    perror("open(): ");
    return 0;
  }

  ioctl(fd,I2C_SLAVE, 0x50); // set the eeprom address
  ioctl(fd,I2C_TIMEOUT,10);  // set the timeout
  ioctl(fd,I2C_RETRIES,1);   // set the retries

  buf[0] = 0;
  buf[1] = 0;
  buf[2] = 0xaa;
  buf[3] = 0x55;

  if (write(fd,&buf,4) != 4)    // set address to read from/write to
    perror("write()");

  close(fd);
  return 0;
}


When using a single 'write()', the driver code sends the i2c slave address only once.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: Bing [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: