Skip to main content

24C02 Smart IC Card

24C02 is a simple EEPROM IC card with 256 bytes of memory and an I2C interface. It functions the same as a 24C02 EEPROM chip, but in a smart card form factor. There is no read or write protection or other security, the entire memory can be accessed without a password.

tip

24C04 (512 bytes), 24C08 (1024 bytes), and 24C16 (2048 bytes) IC cards are also common. Capacities up to 64K are available, but not as common.

Connections

Common IC cards usually follow the ISO 7816-3 standard and have the same pinout and contact shape. Image source.

Bus Pirate24C02Description
IO0/SDAC7 - I/OI2C Data
IO1/SCLC3 - CLKI2C Clock
VoutC1 - VCC5volt power supply
GNDC5 - GNDGround

Connect the Bus Pirate to the smart card as shown in the table above.

Card Identification

The card on the left with the smaller 6 pin contact area is a SLE4442. The card on the right with the larger 8 pin contact area is a 24C02 EEPROM card.

Smart IC Card and SIM card adapter

It's possible to gently solder wires on to each pad of the chip, but a KF-011C (or similar) smart card socket is useful if you don't want to destroy the card.

tip

A smart IC card and SIM card adapter is available for Bus Pirate 5 with the correct connections already set. The adapter accepts most ISO 7816-3 smart cards and mini/micro/nano SIM cards.

Setup

Bus Pirate [/dev/ttyS0]
HiZ> m

Mode selection
1. HiZ
... 5. I2C
... x. Exit
Mode > 5

I2C speed
1kHz to 1000kHz
x. Exit
kHz (400kHz*) > 100
Mode: I2C
I2C>

24C02 IC cards use the common and friendly I2C interface. Speeds under 100kHz should work with most cards, though speed demons might try up to 400kHz.

-Use the m command and and select I2C mode

  • Configure I2C for 100kHz
Bus Pirate [/dev/ttyS0]
I2C> W 5
5.00V requested, closest value: 5.00V
Current limit:Disabled

Power supply:Enabled
Vreg output: 4.9V, Vref/Vout pin: 4.9V, Current: 3.4mA

I2C>

This is old tech - it needs a 5 volt power supply.

  • Enable the onboard power supply at 5volts with the W 5 command
Bus Pirate [/dev/ttyS0]
I2C> P
Pull-up resistors: Enabled (10K ohms @ 4.9V)
I2C>

I2C is an open collector output bus, the Bus Pirate and the 24C02 can only pull the line low to 0 (ground). A pull-up resistor is needed to pull the line high to 1 (5 volts). The Bus Pirate has built-in pull-up resistors that can be enabled with the P command.

  • P - Enable the onboard pull-up resistors.
caution

Be sure to enable the pull-up resistors. The data line will never go high without them and you'll read only 0s.

I2C address scan

Bus Pirate [/dev/ttyS0]
I2C> scan
I2C address search:
0x50 (0xA0 W) (0xA1 R)

Found 2 addresses, 1 W/R pairs.

I2C>

Let's see if we can find the card I2C address. We could look in the datasheet, or we can be lazy and run an I2C address scan.

  • scan - Scan the I2C bus for devices

The scanner found an I2C device at address 0x50 (0xA0 write, 0xA1 read). That's the 24C02 EEPROM.

tip

If the scanner doesn't find the device, ensure the power supply is enabled W 5 and the pull-up resistors are enabled P. Also check that slide switches SW1 and SW2 select VOUT and GND respectively.

Write & Read Bytes

24C02 EEPROMs can read and write single bytes of data anywhere in the memory range. This may seem like a simple and obvious feature, but some EEPROMs can only write multiple byte pages.

Write Byte

Bus Pirate [/dev/ttyS0]
I2C> [0xa0 0x09 0x12]

I2C START
TX: 0xA0 ACK 0x09 ACK 0x12 ACK
I2C STOP
I2C>

First, let's write a byte to the EEPROM. 0xa0 is the I2C write address, and let's put our data at address 0x09 inside the EEPROM. Address 0x09 (9) is the 10th byte inside the EEPROM because the first byte is at address 0. You can write any data value between 0x00 and 0xFF (0-255), but we'll use 0x12 (18) for the demo.

  • [ - I2C START bit
  • 0xa0 - I2C address and write bit
  • 0x09 - EEPROM address pointer, address 9
  • 0x12 - Data to write
  • ] - I2C STOP bit

Read Byte

Reading a byte is a two step process.

  • First, set the address pointer to the location we want to read.
  • Then, read data from that location using a second I2C transaction.

Set address pointer

Bus Pirate [/dev/ttyS0]
I2C> [0xa0 0x9]

I2C START
TX: 0xA0 ACK 0x09 ACK
I2C STOP
I2C>

A 0xa0 write command is used to set the address pointer back to 0x09. This time we won't include any data. The address pointer will be updated, but nothing is written to the EEPROM.

  • [ - I2C START bit
  • 0xa0 - I2C address and write bit
  • 0x09 - EEPROM address pointer, address 9
  • ] - I2C STOP bit

The address pointer has been set to 0x09, the location of the data we want to read. This command didn't include a data byte, so nothing was written to the EEPROM.

Read Byte From EEPROM

Bus Pirate [/dev/ttyS0]
I2C> [0xa1 r]

I2C START
TX: 0xA1 ACK
RX: 0x12 NACK
I2C STOP
I2C>

Now that the address pointer is set to 0x09, we can read the data at that location using the I2C read address 0xa1.

  • [ - I2C START bit
  • 0xa1 - I2C address and read bit
  • r - Read 1 byte
  • ] - I2C STOP bit

The data read from the EEPROM (RX:) is 0x12, the same value we wrote earlier.

Write & Read Page

Page01234567
00x000x010x020x030x040x050x060x07
10x080x090x0a0x0b0x0c0x0d0x0e0x0f
20x100x110x120x130x140x150x160x17
...........................
310xf80xf90xfa0xfb0xfc0xfd0xfe0xff

Memory inside the 24C02 EEPROM is organized into 8 byte pages. We can write 8 bytes to the EEPROM with a single command, but the write must be aligned to the page boundary. This means 8 bytes can be written to addresses 0x00-0x07, 0x08-0x0F, 0x10-0x17, etc, but can never cross two pages.

caution

If we write 8 bytes to an address in the middle of a page (0x03), the address pointer will roll over at the end of the page (0x07) and continue at the beginning of the page (0x00).

If more than 8 bytes of data are sent, the address pointer will roll over and overwrite previously sent data bytes.

Page Write Size

CardWrite Page Size
24C01, 24C028 bytes
24C04, 24C08, 24C1616 bytes

24C02 has 32 pages of 8 bytes. 24C04 and larger EEPROMs use a 16 byte page, so more data can be written with a single command.

info

Always check the page size in the datasheet to avoid write errors.

Write Page

Bus Pirate [/dev/ttyS0]
I2C> [0xa0 0x00 0x12 0x34 0x 0x56 0x78 0x9a 0xbc 0xde 0xf0]

I2C START
TX: 0xA0 ACK 0x00 ACK 0x12 ACK 0x34 ACK 0x56 ACK 0x78 ACK 0x9A ACK 0xBC ACK
0xDE ACK 0xF0 ACK
I2C STOP
I2C>

Let's write 8 bytes to the first page of memory (0x00) that starts at 0x00 and ends at 0x07.

  • [ - I2C START bit
  • 0xa0 - I2C address and write bit
  • 0 - EEPROM address pointer, address 0, beginning of page 0
  • 0x12 0x34 0x56 0x78 0x9a 0xbc 0xde 0xf0 - Data to write
  • ] - I2C STOP bit
tip

Remember, page writes must be aligned to the page boundary. If you write to an address in the middle of a page, the address pointer will roll over to the beginning of the page.

Read Page

Set address pointer

Bus Pirate [/dev/ttyS0]
I2C> [0xa0 0x00]

I2C START
TX: 0xA0 ACK 0x00 ACK
I2C STOP
I2C>

Set the address pointer to the beginning of page 0, address 0x00.

  • [ - I2C START bit
  • 0xa0 - I2C address and write bit
  • 0x00 - EEPROM address pointer, address 0, beginning of page 0
  • ] - I2C STOP bit

Read Page From EEPROM

Bus Pirate [/dev/ttyS0]
I2C> [0xa1 r:8]

I2C START
TX: 0xA1 ACK
RX: 0x12 ACK 0x34 ACK 0x56 ACK 0x78 ACK 0x9A ACK 0xBC ACK 0xDE ACK 0xF0 NACK

I2C STOP
I2C>

Read the 8 byte page and verify the data was written.

  • [ - I2C START bit
  • 0xa1 - I2C address and read bit
  • r:8 - Read 8 bytes
  • ] - I2C STOP bit

Continuous Read

The full EEPROM can be read in a single operation with a continuous read. After 256 bytes it will roll over and start reading from the beginning again.

Set address pointer

Bus Pirate [/dev/ttyS0]
I2C> [0xa0 0x00]

I2C START
TX: 0xA0 ACK 0x00 ACK
I2C STOP
I2C>

Set the address pointer to the beginning of the EEPROM, address 0x00.

  • [ - I2C START bit
  • 0xa0 - I2C address and write bit
  • 0x00 - EEPROM address pointer, address 0
  • ] - I2C STOP bit

Read Complete EEPROM

Bus Pirate [/dev/ttyS0]
I2C> [0xa1 r:256]

I2C START
TX: 0xA1 ACK
RX: 0x12 ACK 0x34 ACK 0x56 ACK 0x78 ACK 0x9A ACK 0xBC ACK 0xDE ACK 0xF0 ACK
...lines removed....
0xFF ACK 0xFF ACK 0xFF ACK 0xFF ACK 0xFF ACK 0xFF ACK 0xFF ACK 0xFF NACK

I2C STOP
I2C>

Now we can read the entire EEPROM in a single operation.

  • [ - I2C START bit
  • 0xa1 - I2C address and read bit
  • r:256 - Read 256 bytes
  • ] - I2C STOP bit

Other card sizes

CardOrganizationWrite Page SizeSize
24C011 * 128 bytes8 bytes128 bytes
24C021 * 256 bytes8 bytes256 bytes
24C042 * 256 bytes16 bytes512 bytes
24C084 * 256 bytes16 bytes1024 bytes
24C168 * 256 bytes16 bytes2048 bytes

I2C EEPROM cards are available in several common sizes. Less common sizes up to 64K are available (24C512) from a few suppliers.

Bus Pirate [/dev/ttyS0]
I2C> scan
I2C address search:
0x50 (0xA0 W) (0xA1 R)
0x51 (0xA2 W) (0xA3 R)
0x52 (0xA4 W) (0xA5 R)
0x53 (0xA6 W) (0xA7 R)
0x54 (0xA8 W) (0xA9 R)
0x55 (0xAA W) (0xAB R)
0x56 (0xAC W) (0xAD R)
0x57 (0xAE W) (0xAF R)

Found 16 addresses, 8 W/R pairs.

I2C>

Commands are similar among 24Cxx cards. Larger cards have multiple I2C addresses that represent 256 byte memory sections. 24C16, shown here, has 256 bytes of memory at 8 different I2C address pairs.

Get Bus Pirate 5

Community