Skip to content
Snippets Groups Projects

dev/i2c_eeprom.c: Use negative offset when addr>0xff is mangled with dev addr

3 unresolved threads
+ 30
6
@@ -7,10 +7,27 @@
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <stdlib.h>
#include "board.h"
#include "dev/bb_i2c.h"
#include "dev/i2c_eeprom.h"
static uint8_t i2c_get_address_for_virtual_devices( struct i2c_eeprom_device *dev, int offset)
{
uint8_t addr = dev->addr;
/*
* See explanation in i2c_eeprom.h for negative offsets
*/
if (dev->offset_bytes < 0) {
uint8_t offset_bits_mask = (1 << (-dev->offset_bytes)) - 1;
addr = dev->addr | ((offset >> 8) & offset_bits_mask);
}
return addr;
}
int i2c_eeprom_create( struct i2c_eeprom_device *dev, struct i2c_bus *bus, uint8_t i2c_addr, int offset_bytes )
{
dev->bus = bus;
@@ -23,9 +40,10 @@ int i2c_eeprom_read(struct i2c_eeprom_device *dev, int offset, void *buf, int co
{
int i;
unsigned char *cb = buf;
uint8_t addr = i2c_get_address_for_virtual_devices(dev, offset);
bb_i2c_start(dev->bus);
if (bb_i2c_put_byte(dev->bus, dev->addr << 1) < 0) {
if (bb_i2c_put_byte(dev->bus, addr << 1) < 0) {
bb_i2c_stop(dev->bus);
return -1;
}
@@ -35,7 +53,7 @@ int i2c_eeprom_read(struct i2c_eeprom_device *dev, int offset, void *buf, int co
bb_i2c_put_byte(dev->bus, offset & 0xff);
bb_i2c_repeat_start(dev->bus);
bb_i2c_put_byte(dev->bus, (dev->addr << 1) | 1);
bb_i2c_put_byte(dev->bus, (addr << 1) | 1);
for (i = 0; i < count - 1; ++i) {
bb_i2c_get_byte(dev->bus, cb, 0);
cb++;
@@ -51,11 +69,14 @@ int i2c_eeprom_write(struct i2c_eeprom_device *dev, int offset, void *buf, int c
{
int i, busy;
unsigned char *cb = buf;
uint8_t addr;
for (i = 0; i < count; i++) {
bb_i2c_start(dev->bus);
if (bb_i2c_put_byte(dev->bus, dev->addr << 1) < 0) {
addr = i2c_get_address_for_virtual_devices(dev, offset);
if (bb_i2c_put_byte(dev->bus, addr << 1) < 0) {
bb_i2c_stop(dev->bus);
return -1;
}
@@ -70,7 +91,7 @@ int i2c_eeprom_write(struct i2c_eeprom_device *dev, int offset, void *buf, int c
do { /* wait until the chip becomes ready */
bb_i2c_start(dev->bus);
busy = bb_i2c_put_byte(dev->bus, dev->addr << 1);
busy = bb_i2c_put_byte(dev->bus, addr << 1);
bb_i2c_stop(dev->bus);
} while (busy);
@@ -81,11 +102,14 @@ int i2c_eeprom_write(struct i2c_eeprom_device *dev, int offset, void *buf, int c
int i2c_eeprom_erase(struct i2c_eeprom_device *dev, int offset, int count)
{
int i, busy;
uint8_t addr;
for (i = 0; i < count; i++) {
bb_i2c_start(dev->bus);
if (bb_i2c_put_byte(dev->bus, dev->addr << 1) < 0) {
addr = i2c_get_address_for_virtual_devices(dev, offset);
if (bb_i2c_put_byte(dev->bus, addr << 1) < 0) {
bb_i2c_stop(dev->bus);
return -1;
}
@@ -100,7 +124,7 @@ int i2c_eeprom_erase(struct i2c_eeprom_device *dev, int offset, int count)
do { /* wait until the chip becomes ready */
bb_i2c_start(dev->bus);
busy = bb_i2c_put_byte(dev->bus, dev->addr << 1);
busy = bb_i2c_put_byte(dev->bus, addr << 1);
bb_i2c_stop(dev->bus);
} while (busy);