Connecting an AT24-style EEPROM to a BeagleBone Black

This is Part 1 of a series on using an I2C-bus connected EEPROM with the BeagleBone Black and Yocto. The other parts are:


Motivation

Many current connected devices are based on a System-on-Module (short: SoM) + baseboard architecture. This approach is widely employed as it offers a number of advantages:

  • the SoM brings a known good, tested and easily obtainable combination of CPU and RAM including the required power, clock and reset circuitry. Depending on the exact model and version it can also involve more advanced interfaces such as networking, displays, camera or non-volatile storage (ROM). This means the complex and high layer count PCB, often involving high frequency design considerations.
  • in many cases variants of the SoM are available with different RAM/ROM sizes, CPU frequencies or temperature ratings while keeping form factor and connections constant. This allows for easy and cost effective up- and downgrading without requiring PCB redesign and verification.
  • depending on the form factor or possibly standard, there might even be multiple vendors of compatible solutions, allowing for second sourcing to secure supply chains.
  • the custom baseboard - often also called “carrier” or “mainboard” - can be designed a lot simpler, with fewer layers, again simplifying verification while reducing cost.

A very common communication channel between the SoM and baseboard is the Inter-Integrated Circuit bus (short: I²C or I2C), which is supported by virtually every SoM and offer a huge variety of devices to connect, like RTCs, I/O expanders, sensors, ADCx, DACs, and also EEPROMs.

In the following tutorial, we will show how to connect an EEPROM to a BeagleBone Black via I2C bus and verify the basic communication between the components.

The basics of I2C

I2C is a two-wire bus which means that two connections are shared amonst all devices on a specific bus exposed by the bus master, usually the SoM.
Those two connections are called

  • Clock, often referred to as SCLK or SCL
  • Data, often referred to as SDAT or SDA

In idle state, without ongoing communication, they are “idle high”, which means at VCC level. The most common level currently is probably 3.3V, but others are valid too such as 1.8V or 5V. When designing your hardware, make sure to choose voltage compatible parts!
This requires so-called pull-up resistors to be present to tie the idle bus to VCC. Common values here are 10KOhm or 100kOhm, sometimes those are also integrated in the SoM.

Common clock frequencies on I2C range between a few kHz or even just Hz in extreme cases up to about 400kHz for most applications. Both clock and data are actively pulled to the low (GND) level by the devices upon data transfer.

Summing this up, the signals on an I2C bus might look like this:

You can see the clock and data lines moving between GND and VCC, clock at about 90kHz. With the clock being known from the bus and a few statuses being standardized, such as start of transmission, addressing and acknowledging respectively non-acknowledging, its quite easy for oscilloscopes and logic analyzers to decode the bus traffic.

Wiring things up

As an SoM, we will use the BeagleBone Black. It is widely available, cost efficient, and offers easily accessible peripheral connections. Looking at the pinout map, I2C bus number two, VCC and GND are present on P9:

SDA: P9_20
SCL: P9_19
GND: P9_1 or P9_2
3.3V: P9_3

For this tutorial we will be using a 24C64 EEPROM specifically. It has the speciality of three configurable address bits, allowing to adjust the address between 0x50 and 0x57. For the sake of simplicity we will stick with 0x50, which means all three address pins should be pulled low. Same goes for write protection. We want it to be low and therefore inactive.

Pin 1: A0 - Address pin 0
Pin 2: A1 - Address pin 1
Pin 3: A2 - Address pin 2
Pin 4: GND - Ground
Pin 5: SDA - Serial Data Line
Pin 6: SCL - Serial Clock Line
Pin 7: WP - Write Protect
Pin 8: VCC - Power Supply (3.3V)

Making the Connections

SDA: Connect the SDA pin of the EEPROM (Pin 5) to Pin 4 (P9_20) on the BeagleBone Black.
SCL: Connect the SCL pin of the EEPROM (Pin 6) to Pin 5 (P9_19) on the BeagleBone Black.
GND: Connect the GND pin of the EEPROM (Pin 4) to any GND pin on the BeagleBone Black (e.g., P9_1 or P9_2).
VCC: Connect the VCC pin of the EEPROM (Pin 8) to a 3.3V power supply pin on the BeagleBone Black (e.g., P9_3).
A0, A1, A2: Connect these address pins (Pins 1, 2, and 3) to GND to set the I2C address to 0x50.
WP: Connect the WP pin (Pin 7) to GND to disable write protection.

Here is a simple circuit diagram to illustrate the connections:

Pull-up and -down resistors

I2C requires pull-up resistors on the SDA and SCL lines. The BeagleBone Black has internal pull-up resistors, but if you encounter issues, you can add external resistors between the SDA/SCL lines and the 3.3V supply. Recommended values range betweetn 4.7kOhm and 100kOhm. They are present in the schematic and demo setup.

Tying the address pins and WP to GND directly should be fine, but also here, adding resistors doesn’t hurt so they are present in the schematic and demo setup. Common values for such pull-downs are again 10kOhm-100kOhm.

Testing the Connection

In this section, we will use the i2c-tools package to verify the connection between the BeagleBone Black and the AT24C64 EEPROM. The package provides a set of utilities for interacting with I2C devices. It can be installed using that exact package name on both Debianoids and Yocto.

Scanning for I2C Devices

Use the i2cdetect tool to scan for connected I2C devices. This command will list all devices on the I2C-2 bus:

root@beaglebone-yocto:~# i2cdetect -y -r 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

The output shows a grid with the address 0x50 marked, indicating that the EEPROM is detected at this address.

Reading from the EEPROM

To read data from the EEPROM, you can use the i2cget command. For example, to read a byte from address 0x00:

i2cget -y 2 0x50 0x00

Writing to the EEPROM

To write data to the EEPROM, you can use the i2cset command. For example, to write the value 0x01 to address 0x00:

i2cset -y 2 0x50 0x00 0x01

Verifying the Write

To verify that the data was written correctly, read back the value from the same address:

i2cget -y 2 0x50 0x00

The output should be 0x01, confirming that the write operation was successful.

Conclusion

By following these steps, you have successfully connected an AT24C64 EEPROM to the I2C-2 bus of a BeagleBone Black and verified the basic communication between the components. The BeagleBone Black’s extensive connectivity options and powerful processor make it an ideal platform for developing and prototyping embedded systems.
The I2C bus is a versatile and widely used communication protocol that allows for easy integration of various peripherals. By understanding the basics of I2C and how to connect and test devices, you can expand the capabilities of your BeagleBone Black and create more advanced projects.