Guide How To Connect I2C Device To BBB board.
As example we use the 24LC252 EEPROM (https://ww1.microchip.com/downloads/en/devicedoc/21754m.pdf)
The connection diagram:
Check if the connection between BBB and 24LC512 is correct
We can use the standard Linux i2c tools to test your i2c setup.
debian@beaglebone:~$ i2cdetect -l
i2c-1 i2c OMAP I2C adapter I2C adapter
i2c-2 i2c OMAP I2C adapter I2C adapter
i2c-0 i2c OMAP I2C adapter I2C adapter
To scan all addresses connected to i2c-2 type the command
debian@beaglebone:~$ i2cdetect -r 2
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-2 using receive byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n]
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: -- -- -- -- -- -- -- --
You should see active device with address 0x50 as the 24LC512 address is calculated:
The application for read/write I2C bus from Linux.
#include <stdint.h>
#include <sys/cdefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define MAX_WRITE_SIZE 128
int fd = -1;
/*
* Open I2C device for RD/WR
*/
void open_I2C(const char *device)
{
fd = open(device, O_RDWR);
if(fd < 0)
{
printf("%s\n", strerror(errno));
exit(1);
}
}
/*
* Read data from an i2c device
*/
int i2c_read(int fd, uint8_t deviceAddress, uint8_t *buffer, uint16_t startAddress, uint16_t length)
{
struct i2c_msg msg[2];
struct i2c_rdwr_ioctl_data rdwr;
msg[0].addr = deviceAddress;
msg[0].flags = 0;
msg[0].len = sizeof(startAddress);
msg[0].buf = (uint8_t *)&startAddress;
msg[1].addr = deviceAddress;
msg[1].flags = I2C_M_RD;
msg[1].len = length;
msg[1].buf = buffer;
rdwr.nmsgs = 2;
rdwr.msgs = msg;
if (ioctl(fd, I2C_RDWR, &rdwr) < 0) {
printf("read i2C device(): %s\n", strerror(errno));
return -1;
}
return 0;
}
/*
* Write data to an i2c device
*/
int i2c_write(int fd, uint8_t deviceAddress, uint8_t *buffer,uint16_t startAddress, uint16_t length)
{
struct i2c_msg msg;
struct i2c_rdwr_ioctl_data rdwr;
uint8_t writeBuffer[MAX_WRITE_SIZE + 2];
if(length > MAX_WRITE_SIZE + 2)
{
printf("Length > MAX_WRITE_SIZE (%u) \n", MAX_WRITE_SIZE);
return -1;
}
writeBuffer[0] = (uint8_t)((startAddress >> 8) & 0x00FF);
writeBuffer[1] = (uint8_t)(startAddress & 0x00FF);
for(size_t i= 0; i < length; i++)
{
writeBuffer[2+i] = buffer[i];
}
msg.addr = deviceAddress;
msg.flags = 0;
msg.len = length + 2;
msg.buf = writeBuffer;
rdwr.msgs = &msg;
rdwr.nmsgs = 1;
if(ioctl(fd,I2C_RDWR,&rdwr)<0)
{
printf("write i2c device(): %s\n", strerror(errno));
return -1;
}
return 0;
}
int main()
{
uint8_t buffer[MAX_WRITE_SIZE];
open_I2C("/dev/i2c-2" );
//Fill the buffer with '#'
memset((void *)buffer, '#', sizeof(buffer));
printf("Write data to /dev/i2c-2 \n");
//write the buffer to eeprom at addres 0x50
i2c_write(fd, 0x50, buffer,0, sizeof(buffer));
usleep(10000);
// For sanity checking fill the buffer with '@'!
memset((void *)buffer, '@', sizeof(buffer));
i2c_read(fd, 0x50, buffer,0, sizeof(buffer));
printf("Read %d bytes from address 0 : ", sizeof(buffer));
for (size_t i = 0; i < sizeof(buffer); i++)
printf("%c ", buffer[i]);
printf("\n");
close(fd);
exit(0);
}