Raspberry pi and i2c. Connecting a 24Cxx eeprom.

If you followed my previous blog entry, you have a nice raspberry pi system with support for i2c.

Now it is time to test if the i2c bus and the driver is working.
Let’s try to connect a i2c eeprom to the raspberry, since it is the only i2c device that I have in my drawer.

This code has been tested with a 24C16. It will probably work with smaller one, and bigger with code changes ( page size, and page number )

Connect the device

Easy, just connect the 3,3v, the gnd, the SCL and the SDA pins.


Load the i2c driver

modprob i2c-dev

You can also add the line i2c-dev to the /dev/modules file

Detecting the device.

root@raspberrypi:~# i2cdetect -y -a 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: 50 51 52 53 54 55 56 57 -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 

Reading the eeprom

For testing the reading I am using a test program from i2ctools

root# wget http://www.lm-sensors.org/browser/i2c-tools/trunk/eepromer/eeprom.c?format=txt
root# gcc –o eeprom eeprom.c
root# ./eeprom –r –f data
base-address of eeproms       : 0x50
number of pages to read       : 8 (0x50 .. 0x57)
file opened for writing       : d
            on filedescriptor : 3
i2c-devicenode is             : /dev/i2c-0
            on filedescriptor : 4

Read 16 bytes from eeprom at 0x50, offset 00000000
...
Read 16 bytes from eeprom at 0x57, offset 000000f0

The program should work out of the box, and the content of the eeprom must be save into data.
If you are using a 24C16 the file should be 2048 bytes length.

Writing the eeprom.

The program provided by lmsensor seems to be bugged, basically when it write to the eeprom, we must way until the content has been written before continuing.
This is well documented in the datasheet (http://www.bookly.com/images/24C64-BM.pdf ) as Acknowledge (ACK) Polling
Is it a bug in the driver, or in the application level ?
Anyway, I find a solution, I simply reposition the eeprom read-pointer until it succeded.
If you have a more elegant solution, I will be glad to hear about it.

root# wget https://raw.github.com/dgallot/i2c-tools/master/eepromer/eeprom.c
root# gcc –o eeprom eeprom.c
root# ./eeprom -f data -w
base-address of eeproms       : 0x50
number of pages to read       : 8 (0x50 .. 0x57)
file opened for reading       : data
            on filedescriptor : 3
i2c-devicenode is             : /dev/i2c-0
            on filedescriptor : 4

**WARNING**
 - 	You have chosen to WRITE to this eeprom.
	Make sure that this tiny chip is *NOT* vital to the
	operation of your computer as you can easily corrupt
	the configuration memory of your SDRAM-memory-module,
	your IBM ThinkPad or whatnot...! Fixing these errors can be
	a time-consuming and very costly process!

Things to consider:
 - 	You can have more than one i2c-bus, check in /proc/bus/i2c
	and specify the correct one with -d
	right now you have chosen to use '/dev/i2c-0'
 - 	A eeprom can occupy several i2c-addresses (one per page)
	so please make sure that there is no vital eeprom in your computer
	sitting at addresses between 0x50 and 0x57
Enter 'yes' to continue:yes

Wrote 16 bytes to eeprom at 0x50, offset 00000000
... acked 
Wrote 16 bytes to eeprom at 0x50, offset 00000010
..... acked 
Wrote 16 bytes to eeprom at 0x50, offset 00000020
...... acked 
Wrote 16 bytes to eeprom at 0x50, offset 00000030
...... acked 
Wrote 16 bytes to eeprom at 0x57, offset 000000f0
....... acked 

Credits:

http://elinux.org/RPi_Low-level_peripherals
http://www.lm-sensors.org/browser/i2c-tools/trunk/eepromer/eeprom.c

11 Responses to “Raspberry pi and i2c. Connecting a 24Cxx eeprom.”


  1. 1Dominic Clifton

    Thanks for publishing this, one problem though:

    what base image of linux were you using when you compiled the ‘eeprom’ tool in your github account – https://github.com/dgallot/i2c-tools
    When I compile it myself using gcc in the raspbian image (2012-08-16-wheezy-raspbian.zip) it fails to compile:

    pi@raspberrypi ~/24c08 $ git clone https://github.com/dgallot/i2c-tools.git i2c-tools-dgallot
    pi@raspberrypi ~/24c08 $ cd i2c-tools-dgallot
    pi@raspberrypi ~/24c08/i2c-tools-dgallot/eepromer $ make
    cc eepromer.o -o eepromer
    cc -O2 -I../include -Wall -c -o eeprom.o eeprom.c
    eeprom.c: In function ‘eeprom_write’:
    eeprom.c:43:29: error: storage size of ‘i2cmsg’ isn’t known
    eeprom.c:43:29: warning: unused variable ‘i2cmsg’ [-Wunused-variable]
    eeprom.c: In function ‘eeprom_read’:
    eeprom.c:93:29: error: storage size of ‘i2cmsg’ isn’t known
    eeprom.c:108:17: error: ‘I2C_M_RD’ undeclared (first use in this function)
    eeprom.c:108:17: note: each undeclared identifier is reported only once for each function it appears in
    eeprom.c:93:29: warning: unused variable ‘i2cmsg’ [-Wunused-variable]
    eeprom.c: In function ‘main’:
    eeprom.c:242:2: warning: pointer targets in passing argument 1 of ‘fgets’ differ in signedness [-Wpointer-sign]
    /usr/include/stdio.h:624:14: note: expected ‘char * __restrict__’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘strlen’ differ in signedness [-Wpointer-sign]
    /usr/include/string.h:399:15: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strlen’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strcmp’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strlen’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strcmp’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strcmp’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘__builtin_strcmp’ differ in signedness [-Wpointer-sign]
    eeprom.c:246:2: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    eeprom.c:246:2: warning: pointer targets in passing argument 1 of ‘strncmp’ differ in signedness [-Wpointer-sign]
    /usr/include/string.h:146:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
    make: *** [eeprom.o] Error 1

  2. 2Dominique Gallot

    I am using a sightly updated version of the Chris boot image, you may download it from here
    In your case your are probably just missing the i2c header.
    But anyway you must have a kernel which have support for i2c, either my version of the kernel or the one bundle in the Chris image.

    Cheers,
    Dominique

  3. 3Tony

    when I use 24c32 , i2cdetect only found in 0×50, not like your from 0×50 to 0×57 , and with -16 the program always fault, what side 24cxx you use? and pin 1,2,3 a0,a1,a2 should be ground right?

  4. 4Benjamin S.

    add missing include
    #include

    is compiling then for me :)

  5. 5Dominique Gallot

    @Tony
    Sorry for this late response, I missed these comments.

    I left all wire un-connected. A0, A1, A2 allows to change the default i2c address ( to have multiple device in the bus ).
    The default of the tools is for a 24C16.
    The header states : this program can read 24C16 (and probably smaller ones, too)
    You can probably tweak it for bigger eeprom by changing the number of page, and the page size.

    Cheers,
    Dominique

  6. 6alex3314

    root# wget http://www.gallot.be/resources/eeprom.c

    Error 404 Not Found
    Where can I found eeprom.c?
    Thank you

  7. 7Dominique Gallot

    I removed the file by mistake, the file is available from http://www.lm-sensors.org/browser/i2c-tools/trunk/eepromer/eeprom.c?format=txt

  8. 8Gabriel

    I aint get it

    root@controller-1:/home/pi/eprom1# ./eeprom –r –f data
    base-address of eeproms : 0×50
    number of pages to read : 8 (0×50 .. 0×57)
    i2c-devicenode is : /dev/i2c-0
    on filedescriptor : 3

    Positioned pointer in eeprom at 0×50 to offset 00000000
    ioctl(): Input/output error
    ioctl returned -1

    root@controller-1:/home/pi/eprom1# i2cdetect -y 0
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
    10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
    20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
    30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
    40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
    50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
    60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
    70: 70 71 72 73 74 75 76 77

    #############################################

    root@controller-1:/home/pi/eprom1# i2cdetect -y 1
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — – — – — – — – — – — – —
    10: — – — – — – — – — – — – — – — –
    20: — – — – — – — – — – — – — – — –
    30: — – — – — – — – — – — – — – — –
    40: — – — – — – — – — – — – — – — –
    50: — – — – — – — – — – — – — – — –
    60: — – — – — – — – — – — – — – — –
    70: — – — – — – — –
    root@controller-1:/home/pi/eprom1#

    Is 24c01 crashed ?

  9. 9Gabriel

    Done ! indeed it is burned .

    Bought new ones and it is ok now ! Cheers

    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — – — – — – — – — – — – —
    10: — – — – — – — – — – — – — – — –
    20: — – — – — – — – — – — – — – — –
    30: — – — – — – — – — – — – — – — –
    40: — – — – — – — – — – — – — – — –
    50: 50 51 52 53 54 55 56 57 — – — – — – — –
    60: — – — – — – — – — – — – — – — –
    70: — – — – — – — –
    pi@controller-1 ~ $

  10. 10Gabriel

    Got back here ! How do you write a 24c16 without WP pin 7 being pooled to gnd ?

    Got errors in the process as shown below , with or without pin7 WP

    Enter ‘yes’ to continue:yes
    Wrote 8 bytes to eeprom at 0×50, offset 00000000
    ioctl(): Input/output error
    ioctl returned -1

  11. 11Dave Ansell

    Something wierd I have just noticed is that I only seem to be able to write to the eeprom when logged into the pi itself, but reading will work from an ssh session too. I guess this is something subtle about how linux works.

Leave a Reply