HOW-TO: Access Bus Pirate v4 on-board I2C EEPROM

in how-to, tutorials by DP | 2 comments


Bus Pirate v4 has an on-board 24xx64 8Kbyte data storage chip called an  EEPROM (IC3). It can be used to store various settings and preferences, but cooler, the EEPROM’s I2C interface can be accessed from within the Bus Pirate’s I2C mode. First time users can get familiar with the Bus Pirate without any added components!

Two 2K pull-up resistors (R8, R9) are connected to the I2C lines. The chip is powered at 3.3volts and gets a 0.1uF decoupling capacitor (C6) on the power supply pin.

24AA- series I2C EEPROM from Microchip come in a ton of sizes. AA parts work from 1.8volts to 5.5volts, while the 24LC- parts have a 2.5volt minimum requirement.

If you are a first time BP user please read Bus Pirate 101 tutorial first. Get familiar with I2C terminal commands from  I2C. Continue reading below on how to interface with the on board EEPROM.

Connections

  • The on-board 24xx64 EEPROM is internally connected to alternate hardware I2C interface.
  • Connect the BP4 to PC through a micro USB cable. No other connection is required.

Bus Pirate setup
1.Enter Mode command by typing m

 HiZ>
HiZ>m
1. HiZ
2. 1-WIRE
3. UART
4. I2C
5. SPI
6. 2WIRE
7. 3WIRE
8. KEYB
9. LCD
10. PIC
11. DIO
x. exit(without change) 

2.Configure I2C mode by selecting mode 4.

 (1)>4 

3.Configure Hardware based I2C

  I2C mode:
1. Software
2. Hardware

(1)>2 

4. Set I2C clock speed to 400Khz (any speed listed below can be used for EEPROM).

  Set speed:
1. 100KHz
2. 400KHz
3. 1MHz
(1)>2
Ready 

5.List the available macros for I2C mode using (0) command

  I2C>(0)
0.Macro menu
1.7bit address search
2.I2C sniffer
3.Connect to on-board EEPROM
4.Enable Writing the on-board EEPROM 

We will be using macros (3), (4) and (1) for accessing onboard 24XX64 EEPROM

6.Use (3) macro to connect to the on-board EEPROM. This mode uses an alternate I2C hardware interface different from the one available in the BP4 connector.

 I2C>(3)
Now using on-board EEPROM I2C interface 

7.Use (1) to search for I2C slave address. This is always found in product datasheet. Bus Pirate can search this for us.

  I2C>(1)
Searching I2C address space. Found devices at:
0xA0(0x50 W) 0xA1(0x50 R) 

In the above output, address 0xA0 is used for writing data to the EEPROM and address 0xA1 is used for reading data from the EEPROM. This information is found in the device data sheet.

Configure the chip

The 24XX64 EEPROM is write protected when WP pin is set to high. The write protect has to be disabled by clearing the WP pin (i.e set to 0). WP pin is not connected to AUX as in an the case of external I2C EEPROM. This pin is internally wired and always set to 1 during setup.

Use macro (4) to disable write protection

 I2C>(4)
On-board EEPROM write protect disabled 

Interfacing

Write and read operation is accomplished with two command 0b1010 000 0 (i,e 0xA0) and 0b1010 000 1 (i,e 0xA1).

  • In this 0b1010 is base address common to 24AA EEPROMs.
  • It is followed by 000 for SOT23 package 24AA devices like 24AA64.
  • The least significant bit indicate write (1) or read (0) operation

Writing to EEPROM

The simplest form of write operation is Page Write. In this operation, we can write data sequentially to EEPROM without sending a stop condition until reaching byte 31.

 START_CONDITION|WRITE_COMMAND|ADDRESS_HIGH|ADDRESS_LOW|DATA1|DATA2|...DATAn| STOP_CONDITION 

Please note that the start address should always be at page boundary. We can write any data up to the maximum of the page boundary in one operation.

  I2C> [0xA0 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13]
I2C START BIT
WRITE: 0xA0 ACK
WRITE: 0x00 ACK
WRITE: 0x00 ACK
WRITE: 0x00 ACK
WRITE: 0x01 ACK
WRITE: 0x02 ACK
WRITE: 0x03 ACK
WRITE: 0x04 ACK
WRITE: 0x05 ACK
WRITE: 0x06 ACK
WRITE: 0x07 ACK
WRITE: 0x08 ACK
WRITE: 0x09 ACK
WRITE: 0x0A ACK
WRITE: 0x0B ACK
WRITE: 0x0C ACK
WRITE: 0x0D ACK
I2C STOP BIT
I2C> 

In the above operation, 0xA0 is write command. Followed by 0 and 0 are high and low begin addresses. 0 1 2 3 …. 13 are set of data written sequentially to EEPROM starting at address 0×0.

For each correct operation we get an ACK

Reading from EEPROM

Let us look into a simple read operation using Page Read. Let us read the data already written using the above Page Write operation.

1. Set the internal address pointer to address 0×0.

 START_CONDITION |WRITE_COMMAND|ADDRESS_HIGH|ADDRESS_LOW| STOP_CONDITION  

 

  I2C>[0xA0 0 0]
I2C START BIT
WRITE: 0xA0 ACK
WRITE: 0x00 ACK
WRITE: 0x00 ACK
I2C STOP BIT 

2.Read the data sequentially

 START_CONDITION|READ_COMMAND|rrrrrrrrrrrrrr| STOP_CONDITION 

 

 I2C>[0xA1 rrrrrrrrrrrrrr]
I2C START BIT
WRITE: 0xA1 ACK
READ: 0x00
READ: ACK 0x01
READ: ACK 0x02
READ: ACK 0x03
READ: ACK 0x04
READ: ACK 0x05
READ: ACK 0x06
READ: ACK 0x07
READ: ACK 0x08
READ: ACK 0x09
READ: ACK 0x0A
READ: ACK 0x0B
READ: ACK 0x0C
READ: ACK 0x0D
NACK
I2C STOP BIT  

For reading each byte, we have used a r. Totally 14 bytes were read sequentially. The data returned are same as the one we wrote with write (0xA0) operation

Random READ and WRITE Operations

Data can be written or read one byte at a time using the following operations

Byte WRITE

 START_CONDITION |WRITE_COMMAND|HIGH_ADDRESS|LOW_ADDRESS|ONE_BYTE_DATA| STOP_CONDITION 

 

  I2C>[0xA0 0x1 0xA 0xE]
I2C START BIT
WRITE: 0xA0 ACK
WRITE: 0x01 ACK
WRITE: 0x0A ACK
WRITE: 0x0E ACK
I2C STOP BIT 

0×1 is high address, 0xA  is low address and 0xE is one byte data.

Byte READ

 START_CONDITION |WRITE_COMMAND|HIGH_ADDRESS|LOW_ADDRESS| <strong>START_CONDITION</strong> |READ_COMMAND|r| STOP_CONDITION 

 

  I2C&gt;[0xA0 0x1 0xA [0xA1 r]
I2C START BIT
WRITE: 0xA0 ACK
WRITE: 0x01 ACK
WRITE: 0x0A ACK
I2C START BIT
WRITE: 0xA1 ACK
READ: 0x0E
NACK
I2C STOP BIT
I2C&gt; 

0×1 is high address, 0xA is low address and r is to read one byte data. We read the correct data 0x0E.

This entry was posted in how-to, tutorials and tagged , , .

Comments

  1. eff zog says:

    This is more of an EEprom DP parts list forum question: For my own lab stock and designs I would like to standardize on one eeprom part, at least 2K bytes (flexible here), jellybean common and cheap and probably I2C interface. I’d also like to stay in common with DP partslist, but you use many different parts!

    My immediate use is to store configuration data in a STM32F407 controller board but I also want to be somewhat future proof for subsequent projects and have to stock only 1 generic part. What do community members choose in this situation?

  2. Doegox says:

    > The least significant bit indicate write (1) or read (0) operation
    I think it’s the opposite as 0xA0=Write & 0xA1=Read

Leave a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.