Rasberry Pi I2C EEPROM Program
Contents
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 #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
write
root@raspberrypi:/tmp/eeprog-0.7.6-tear12# date | ./eeprog -f -16 -w 0 -t 5 /dev/i2c-0 0x53
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
Bus: /dev/i2c-0, Address: 0x53, Mode: 16bit
Operation: write at offset 0, Input file: <stdin>
Write cycle time: 5 milliseconds
Writing <stdin> starting at address 0x0
.............................
read
root@raspberrypi:/tmp/eeprog-0.7.6-tear12# ./eeprog -xf /dev/i2c-0 0x53 -16 -r 0x00:0x100
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
Bus: /dev/i2c-0, Address: 0x53, Mode: 16bit
Operation: read 256 bytes from offset 0, Output file: <stdout>
Reading 256 bytes from 0x0
0000| 46 72 69 20 41 75 67 20 31 35 20 32 32 3a 32 36
0010| 3a 33 35 20 55 54 43 20 32 30 31 34 0a 00 00 00
0020| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0030| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0040| 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
<SNIP>
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.
root@raspberrypi:/tmp/eeprog-0.7.6-tear12# i2cdump -y 0 0x53 i
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 46 72 69 20 41 75 67 20 31 35 20 32 32 3a 32 36 Fri Aug 15 22:26
10: 3a 33 35 20 55 54 43 20 32 30 31 34 0a 00 00 00 :35 UTC 2014?...
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
<SNIP>
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'
$ dd if=/dev/urandom bs=1 count=256 > 256.dump
256+0 records in
256+0 records out
256 bytes (256 B) copied, 0.0156784 s, 16.3 kB/s
(you may need to do; $ sudo apt-get install hexdump)
$ hexdump -C 256.dump
00000000 6a d6 48 db a3 ef 7a 86 6c ab be 12 2b 6b 50 79 |j.H...z.l...+kPy|
00000010 e7 10 7c c0 0d 16 b9 d0 d6 43 77 58 83 46 c8 31 |..|......CwX.F.1|
00000020 17 90 f9 3c 26 64 38 8b 96 81 d1 57 42 a0 04 c0 |...<&d8....WB...|
00000030 3a ef ae 40 6a c9 98 89 24 5f 0d 6d 26 1e 70 03 |:..@j...$_.m&.p.|
00000040 95 88 dc 61 bf ee 8a ca 30 05 4b f4 cc 4d f7 c5 |...a....0.K..M..|
00000050 c1 9e 38 48 f9 70 01 7c 8f 66 0a bc 43 c6 2b 99 |..8H.p.|.f..C.+.|
00000060 d9 7b f9 54 c6 e9 da 1c be 57 ef 8f 00 ae 39 3d |.{.T.....W....9=|
00000070 cd a1 cf e3 51 3f 99 48 51 64 47 35 31 34 bb 18 |....Q?.HQdG514..|
00000080 ae 24 98 cf 83 ce cd 63 dd 39 26 d1 ec 41 9c 07 |.$.....c.9&..A..|
00000090 d2 28 23 1c 14 0f 70 97 94 1e d9 e2 77 b4 18 d8 |.(#...p.....w...|
000000a0 1b bc 2e b2 f8 f4 f9 19 c7 95 a9 2b b9 ae 2c 60 |...........+..,`|
000000b0 14 97 ac 5a a8 ff 73 d8 d1 61 53 c3 a6 00 1b d7 |...Z..s..aS.....|
000000c0 6e d4 86 6e e7 b1 26 c7 56 12 4c d2 07 3f fe b7 |n..n..&.V.L..?..|
000000d0 79 6f fb 51 3d a3 a9 8f 88 98 25 b3 ef 1d 4f 57 |yo.Q=.....%...OW|
000000e0 65 05 b6 94 51 85 ec 02 6f 18 1d b4 56 5f 59 6b |e...Q...o...V_Yk|
000000f0 7c 24 c9 84 e9 96 d6 29 32 56 3b ea 1a 8a 39 ac ||$.....)2V;...9.|
00000100
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)
$ ./eeprog -f -16 -i 256.dump -w 0x00 -t 5 /dev/i2c-0 0x53
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
Bus: /dev/i2c-0, Address: 0x53, Mode: 16bit
Operation: write at offset 0, Input file: 256.dump
Write cycle time: 5 milliseconds
Writing 256.dump starting at address 0x0
................................................................................................................................................................................................................................................................
write out the 256 byte of random data to eeprom, after first one (first is 00 to FF, then this is 100 to 1FF)
./eeprog -f -16 -i 256.dump -w 0x100 -t 5 /dev/i2c-0 0x53
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
Bus: /dev/i2c-0, Address: 0x53, Mode: 16bit
Operation: write at offset 256, Input file: 256.dump
Write cycle time: 5 milliseconds
Writing 256.dump starting at address 0x100
................................................................................................................................................................................................................................................................
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.
$ sudo ./eeprog -xf /dev/i2c-0 0x53 -16 -r 0x00:0x200
eeprog 0.7.6-tear12, a 24Cxx EEPROM reader/writer
Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved.
Copyright (c) 2011 by Kris Rusocki - All rights reserved.
Bus: /dev/i2c-0, Address: 0x53, Mode: 16bit
Operation: read 512 bytes from offset 0, Output file: <stdout>
Reading 512 bytes from 0x0
0000| 6a d6 48 db a3 ef 7a 86 6c ab be 12 2b 6b 50 79
0010| e7 10 7c c0 0d 16 b9 d0 d6 43 77 58 83 46 c8 31
0020| 17 90 f9 3c 26 64 38 8b 96 81 d1 57 42 a0 04 c0
0030| 3a ef ae 40 6a c9 98 89 24 5f 0d 6d 26 1e 70 03
0040| 95 88 dc 61 bf ee 8a ca 30 05 4b f4 cc 4d f7 c5
0050| c1 9e 38 48 f9 70 01 7c 8f 66 0a bc 43 c6 2b 99
0060| d9 7b f9 54 c6 e9 da 1c be 57 ef 8f 00 ae 39 3d
0070| cd a1 cf e3 51 3f 99 48 51 64 47 35 31 34 bb 18
0080| ae 24 98 cf 83 ce cd 63 dd 39 26 d1 ec 41 9c 07
0090| d2 28 23 1c 14 0f 70 97 94 1e d9 e2 77 b4 18 d8
00a0| 1b bc 2e b2 f8 f4 f9 19 c7 95 a9 2b b9 ae 2c 60
00b0| 14 97 ac 5a a8 ff 73 d8 d1 61 53 c3 a6 00 1b d7
00c0| 6e d4 86 6e e7 b1 26 c7 56 12 4c d2 07 3f fe b7
00d0| 79 6f fb 51 3d a3 a9 8f 88 98 25 b3 ef 1d 4f 57
00e0| 65 05 b6 94 51 85 ec 02 6f 18 1d b4 56 5f 59 6b
00f0| 7c 24 c9 84 e9 96 d6 29 32 56 3b ea 1a 8a 39 ac
0100| 6a d6 48 db a3 ef 7a 86 6c ab be 12 2b 6b 50 79
0110| e7 10 7c c0 0d 16 b9 d0 d6 43 77 58 83 46 c8 31
0120| 17 90 f9 3c 26 64 38 8b 96 81 d1 57 42 a0 04 c0
0130| 3a ef ae 40 6a c9 98 89 24 5f 0d 6d 26 1e 70 03
0140| 95 88 dc 61 bf ee 8a ca 30 05 4b f4 cc 4d f7 c5
0150| c1 9e 38 48 f9 70 01 7c 8f 66 0a bc 43 c6 2b 99
0160| d9 7b f9 54 c6 e9 da 1c be 57 ef 8f 00 ae 39 3d
0170| cd a1 cf e3 51 3f 99 48 51 64 47 35 31 34 bb 18
0180| ae 24 98 cf 83 ce cd 63 dd 39 26 d1 ec 41 9c 07
0190| d2 28 23 1c 14 0f 70 97 94 1e d9 e2 77 b4 18 d8
01a0| 1b bc 2e b2 f8 f4 f9 19 c7 95 a9 2b b9 ae 2c 60
01b0| 14 97 ac 5a a8 ff 73 d8 d1 61 53 c3 a6 00 1b d7
01c0| 6e d4 86 6e e7 b1 26 c7 56 12 4c d2 07 3f fe b7
01d0| 79 6f fb 51 3d a3 a9 8f 88 98 25 b3 ef 1d 4f 57
01e0| 65 05 b6 94 51 85 ec 02 6f 18 1d b4 56 5f 59 6b
01f0| 7c 24 c9 84 e9 96 d6 29 32 56 3b ea 1a 8a 39 ac
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 <snip>
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
blog comments powered by Disqus