Rasberry Pi I2C EEPROM Program

=Requirements=

Enable all the I2C bits

/etc/modules
Load the i2c modules on boot (check with lsmod)

snd-bcm2835 i2c-bcm2708 i2c-dev

/etc/modprobe.d/raspi-blacklist.conf
comment out the blacklist of the i2c module, although mine loads modules when still blacklisted here

blacklist spi-bcm2708
 * 1) blacklist i2c-bcm2708

/etc/modprobe.d/i2c.conf
options i2c_bcm2708 baudrate=400000


 * Generally use the lowest you can to mitigate the clock stretching bug, if your device supports clock stretching. (these eeproms dont)

baudrate=400000 for 400kbit. Check actual looking at dmesg

baudrate=1000000 1Mbit

=/etc/boot.txt= For >= 3.18 kernel

Append file with this ; dtparam=i2c0=on dtparam=i2c1=on dtparam=i2c_arm=on

If you are using a newer pi with i2c bus on 1 then only need dtparam=i2c1=on, older just need 0, but doesn't seem to matter setting both.

Without above you will also get(assuming older Pi with i2c on 0) pi@raspberrypi ~ $ sudo i2cdetect -y 0 Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory

=working config=

If all correct lsmod should show at least i2c_bcm2708 and i2c_dev

$ lsmod Module                 Size  Used by lirc_dev               11060  0 rc_core               23581  1 lirc_dev i2c_dev                6730  0 snd_bcm2835           22317  0 snd_pcm               92581  1 snd_bcm2835 snd_seq               61957  0 snd_seq_device         5130  1 snd_seq snd_timer             23454  2 snd_pcm,snd_seq snd                   68161  5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device i2c_bcm2708            6252  0 bcm2835_gpiomem        3703  0 uio_pdrv_genirq        3690  0 uio                   10002  1 uio_pdrv_genirq

and /dev should show this snipit within it, the i2c-0 and/or i2c-1 (depending on what you set in /etc/boot.txt)

$ ls -al /dev

crw--- 1 root root    245,   0 Jan  1  1970 gpiomem crw--- 1 root root     10, 183 Jan  1  1970 hwrng crw-rw---T 1 root i2c      89,   0 Feb  6 12:03 i2c-0 crw-rw---T 1 root i2c      89,   1 Feb  6 12:03 i2c-1 drwxr-xr-x 2 root root          60 Jan  1  1970 input crw-r--r-- 1 root root      1,  11 Jan  1  1970 kmsg srw-rw-rw- 1 root root           0 Feb  6 12:03 log

=programs to get=

i2c-tools and hexedit
sudo apt-get install i2c-tools hexedit

eeprog
eeprog-0.7.6-tear5.tar.gz NOT the original eeprog as it wont program (anything I've tried) on a Pi, you will get this without a write cycle time delay

Writing stdin starting at address 0x0 ..Error i2c_write_3b: Input/output error Error at line 150: write error

=Board Revisions=

Your Pi GPIO pins can be using i2c bus 0 or 1 depending on the board revision. In this case the 'Revision' below is '000e' which is;

'000e' => 'Model B Revision 2.0 512MB', (Sony) i.e. rev 2 = i2c bus 1

(Just to confuse, the examples below were done on a rev.1 board so its on 0!!)

$ cat /proc/cpuinfo processor	: 0 model name	: ARMv6-compatible processor rev 7 (v6l) Features	: swp half thumb fastmult vfp edsp java tls CPU implementer	: 0x41 CPU architecture: 7 CPU variant	: 0x0 CPU part	: 0xb76 CPU revision	: 7

Hardware	: BCM2708 Revision	: 100000e Serial		: 000000003422697f

=Atmel 24C256 EEPROM Programming=

This is set with address pins A0 A1 set high (wired to Vcc) so address is 0x53 not 0x50. (A2 isn't connected on this chip)

chip specs
16 bit addressing (use -16)

262144 bits = 32768 bytes = 32k = 0x8000

Addressable range thus = 0 to 32767, i.e. 0x0 to 0x7FFF


 * Note, confusingly, to read the whole chip, from 0 to 0x7FF you would use -r 0x00:0x8000 as it start:length not start:end


 * Note if you have it in 8 bit mode it may look like its working but the data you get will just be garbage.

=Example 1=

find address
$ sudo i2cdetect -y 0 0 1  2  3  4  5  6  7  8  9  a  b  c  d  e  f 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- 53 -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

So chip is at address 0x53

read with i2cdump
(For some reason this needs running twice to get proper read)

(Update : On another Rev 2 Pi ~ 6 months later it seems to work first time)

i = I2C mode, seems to dump the first 512 bytes.

=Example 2=

This just shows how to offset and uses writing from a source file rather than std input.

Generate 256 bytes of data with dd

dd, input data is random - blocksize = 1 byte, count = 256 of them, output to a file '256.dump'

(you may need to do; $ sudo apt-get install hexdump)

Write to start of eeprom
write out the 256 byte of random data to eeprom at the beginning

suppress warnings (-f), 16 bit (-16), input file (-i), offset 0x00 (-w), 5 ms delay (-t), bus /dev/i2c-0, bus address 0x53 (A0,A1 set high at vcc)

write out the 256 byte of random data to eeprom, after first one (first is 00 to FF, then this is 100 to 1FF)

=read it back=

You should have two copies of the 256 bytes of random data, one after another.

Notice you have to read to 0x200 and not 1FF because it is 512 bytes from 0, not an end address.

To read just the second 256 block you would use ./eeprog -xf /dev/i2c-0 0x53 -16 -r 0x100:0x100

=Atmel 24C02 I2C EPROM=

8 bit addressing

2048 bits = 256 bytes = 1/4k = 0x100

Addressable range = 0 to 255, i.e 0x0 to 0xFF


 * Note, confusingly, to read the whole chip, from 0 to 0xFF you would use -r 0x00:0x100 as it start:length not start:end


 * Note can use thee pins A0,A1,A2 voltage levels to give an address from 0x50 (all grnd) to 0x57 (all at vcc)


 * Note this also needs a 5 ms pause for writing

read, output to file
./eeprog -f -o 2c02.bin -r 0x00:0x100 /dev/i2c-0 0x57

or

./i2cdump -y 0 0x57 i

I am not sure how this knows to use 8 or 16 bit addressing? I think it is probably a lack of my understanding.

write from file
./eeprog -f -i 2c02.bin -w 0x00 -t 5 /dev/i2c-0 0x57

=poke a byte to and address with i2cset= address 0x03 set to 0x35 i2cset -y 0 0x57 0x03 0x35

=Programming I2C via VGA port=

VGA out can often support I2C directly so no need for any external devices. My Toshiba Portege R830 does. vga on bus /dev/i2c-1 $ sudo i2cdetect -l i2c-3	i2c      	i915 gmbus dpc                  	I2C adapter i2c-1	i2c      	i915 gmbus vga                  	I2C adapter i2c-8	i2c      	DPDDC-D                         	I2C adapter Pin 5 Ground

Pin 9 5V (need v cheap i2c level shifter if you are using 3.3v or lower!)

Pin 12 SDA

Pin 15 SCL

$ sudo 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: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --

Fiddling with the settings in eeprogs was needed to get reliable writing depending on what you are doing. (writing to Atmel EPROM in my case)


 * Note eeprogs needs gcc-4.8 to compile and not coredump. In ubuntu 16.04,  make CC=gcc-4.8

=Comments=