I2C overhaul part 3: "we finally figured out NCR NVRAM" edition
This commit is contained in:
@@ -103,13 +103,16 @@ gl518sm_i2c_read(void *bus, uint8_t addr, void *priv)
|
||||
uint16_t read = gl518sm_read(dev, dev->addr_register);
|
||||
uint8_t ret = 0;
|
||||
|
||||
if (dev->i2c_state == 0)
|
||||
dev->i2c_state = 1;
|
||||
|
||||
if ((dev->i2c_state == 1) && (dev->addr_register >= 0x07) && (dev->addr_register <= 0x0c)) { /* two-byte registers: read MSB first */
|
||||
dev->i2c_state = 2;
|
||||
ret = read >> 8;
|
||||
} else
|
||||
} else {
|
||||
ret = read;
|
||||
|
||||
dev->addr_register++;
|
||||
dev->addr_register++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -178,6 +181,7 @@ gl518sm_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
break;
|
||||
|
||||
default:
|
||||
dev->i2c_state = 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ static uint8_t lm75_i2c_read(void *bus, uint8_t addr, void *priv);
|
||||
static uint8_t lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv);
|
||||
static void lm75_reset(lm75_t *dev);
|
||||
|
||||
|
||||
#define ENABLE_LM75_LOG 1
|
||||
#ifdef ENABLE_LM75_LOG
|
||||
int lm75_do_log = ENABLE_LM75_LOG;
|
||||
|
||||
@@ -86,23 +86,39 @@ lm75_i2c_read(void *bus, uint8_t addr, void *priv)
|
||||
lm75_t *dev = (lm75_t *) priv;
|
||||
uint8_t ret = 0;
|
||||
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x1 : 0x0);
|
||||
break;
|
||||
if (dev->i2c_state == 0)
|
||||
dev->i2c_state = 1;
|
||||
|
||||
case 0x1: /* configuration */
|
||||
ret = lm75_read(dev, 0x2);
|
||||
break;
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((dev->addr_register > 0x7) && ((dev->addr_register & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, dev->addr_register);
|
||||
ret = i2c_read(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
} else {
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x0 : 0x1);
|
||||
break;
|
||||
|
||||
case 0x2: /* Thyst */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x4 : 0x3);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x6 : 0x5);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
ret = lm75_read(dev, 0x2);
|
||||
break;
|
||||
|
||||
case 0x2: /* Thyst */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x3 : 0x4);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
ret = lm75_read(dev, (dev->i2c_state == 1) ? 0x5 : 0x6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (++dev->i2c_state > 2)
|
||||
dev->i2c_state = 2;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -112,15 +128,7 @@ lm75_read(lm75_t *dev, uint8_t reg)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, reg);
|
||||
ret = i2c_read(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
} else if ((reg & 0x7) == 0x0) /* temperature high byte */
|
||||
if ((reg & 0x7) == 0x0) /* temperature high byte */
|
||||
ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]) >> 8;
|
||||
else if ((reg & 0x7) == 0x1) /* temperature low byte */
|
||||
ret = LM75_TEMP_TO_REG(dev->values->temperatures[dev->local >> 8]);
|
||||
@@ -145,23 +153,37 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x1 : 0x0, data);
|
||||
break;
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((dev->addr_register > 0x7) && ((dev->addr_register & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, dev->addr_register);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, data);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
return 1;
|
||||
} else {
|
||||
switch (dev->addr_register & 0x3) {
|
||||
case 0x0: /* temperature */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x0 : 0x1, data);
|
||||
break;
|
||||
|
||||
case 0x1: /* configuration */
|
||||
lm75_write(dev, 0x2, data);
|
||||
break;
|
||||
case 0x1: /* configuration */
|
||||
lm75_write(dev, 0x2, data);
|
||||
break;
|
||||
|
||||
case 0x2: /* Thyst */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x4 : 0x3, data);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x6 : 0x5, data);
|
||||
break;
|
||||
case 0x2: /* Thyst */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x3 : 0x4, data);
|
||||
break;
|
||||
case 0x3: /* Tos */
|
||||
lm75_write(dev, (dev->i2c_state == 1) ? 0x5 : 0x6, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (++dev->i2c_state > 2)
|
||||
dev->i2c_state = 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -171,17 +193,6 @@ lm75_write(lm75_t *dev, uint8_t reg, uint8_t val)
|
||||
{
|
||||
lm75_log("LM75: write(%02X, %02X)\n", reg, val);
|
||||
|
||||
/* The AS99127F hardware monitor uses the addresses of its LM75 devices
|
||||
to access some of its proprietary registers. Pass this operation on to
|
||||
the main monitor address through an internal I2C call, if necessary. */
|
||||
if ((reg > 0x7) && ((reg & 0xf8) != 0x50) && (dev->as99127f_i2c_addr < 0x80)) {
|
||||
i2c_start(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, reg);
|
||||
i2c_write(i2c_smbus, dev->as99127f_i2c_addr, val);
|
||||
i2c_stop(i2c_smbus, dev->as99127f_i2c_addr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t reg_idx = (reg & 0x7);
|
||||
|
||||
if ((reg_idx <= 0x1) || (reg_idx == 0x7))
|
||||
|
||||
@@ -69,7 +69,7 @@ static uint8_t lm78_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
static uint8_t lm78_write(lm78_t *dev, uint8_t reg, uint8_t val, uint8_t bank);
|
||||
static void lm78_reset(lm78_t *dev, uint8_t initialization);
|
||||
|
||||
|
||||
#define ENABLE_LM78_LOG 1
|
||||
#ifdef ENABLE_LM78_LOG
|
||||
int lm78_do_log = ENABLE_LM78_LOG;
|
||||
|
||||
|
||||
@@ -194,6 +194,8 @@ i2c_has_device(void *bus_handle, uint8_t addr)
|
||||
if (!bus)
|
||||
return 0;
|
||||
|
||||
i2c_log("I2C: has_device(%s, %02X) = %d\n", bus->name, addr, !!bus->devices[addr]);
|
||||
|
||||
return(!!bus->devices[addr]);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the AT24Cxx series of I2C EEPROMs.
|
||||
* Emulation of the 24Cxx series of I2C EEPROMs.
|
||||
*
|
||||
*
|
||||
*
|
||||
@@ -27,22 +27,42 @@
|
||||
|
||||
typedef struct {
|
||||
void *i2c;
|
||||
uint8_t addr;
|
||||
uint8_t *data;
|
||||
uint8_t writable;
|
||||
uint8_t addr, *data, writable;
|
||||
|
||||
uint16_t addr_mask;
|
||||
uint8_t addr_register;
|
||||
uint16_t addr_mask, addr_register;
|
||||
uint8_t i2c_state;
|
||||
} i2c_eeprom_t;
|
||||
|
||||
#define ENABLE_I2C_EEPROM_LOG 1
|
||||
#ifdef ENABLE_I2C_EEPROM_LOG
|
||||
int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
i2c_eeprom_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (i2c_eeprom_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define i2c_eeprom_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
i2c_eeprom_start(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
|
||||
|
||||
i2c_eeprom_log("I2C EEPROM: start()\n");
|
||||
|
||||
dev->i2c_state = 0;
|
||||
dev->addr_register = (addr << 8) & dev->addr_mask;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +70,13 @@ uint8_t
|
||||
i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
|
||||
{
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
|
||||
uint8_t ret = dev->data[dev->addr_register];
|
||||
|
||||
return dev->data[((addr << 8) | dev->addr_register++) & dev->addr_mask];
|
||||
i2c_eeprom_log("I2C EEPROM: read(%04X) = %02X\n", dev->addr_register, ret);
|
||||
if (++dev->addr_register > dev->addr_mask) /* roll-over */
|
||||
dev->addr_register = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,11 +87,16 @@ i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv)
|
||||
|
||||
if (dev->i2c_state == 0) {
|
||||
dev->i2c_state = 1;
|
||||
dev->addr_register = data;
|
||||
} else if (dev->writable)
|
||||
dev->data[((addr << 8) | dev->addr_register++) & dev->addr_mask] = data;
|
||||
else
|
||||
return 0;
|
||||
dev->addr_register = ((addr << 8) | data) & dev->addr_mask;
|
||||
i2c_eeprom_log("I2C EEPROM: write(address, %04X)\n", dev->addr_register);
|
||||
} else {
|
||||
i2c_eeprom_log("I2C EEPROM: write(%04X, %02X) = %s\n", dev->addr_register, data, dev->writable ? "accepted" : "blocked");
|
||||
if (dev->writable)
|
||||
dev->data[dev->addr_register] = data;
|
||||
if (++dev->addr_register > dev->addr_mask) /* roll-over */
|
||||
dev->addr_register = 0;
|
||||
return dev->writable;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -78,6 +108,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint16_t size, uint8_t w
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) malloc(sizeof(i2c_eeprom_t));
|
||||
memset(dev, 0, sizeof(i2c_eeprom_t));
|
||||
|
||||
i2c_eeprom_log("I2C EEPROM: init(%02X, %d, %d)\n", addr, size, writable);
|
||||
|
||||
dev->i2c = i2c;
|
||||
dev->addr = addr;
|
||||
dev->data = data;
|
||||
@@ -96,6 +128,8 @@ i2c_eeprom_close(void *dev_handle)
|
||||
{
|
||||
i2c_eeprom_t *dev = (i2c_eeprom_t *) dev_handle;
|
||||
|
||||
i2c_eeprom_log("I2C EEPROM: close()\n");
|
||||
|
||||
i2c_removehandler(dev->i2c, dev->addr & ~(dev->addr_mask >> 8), (dev->addr_mask >> 8) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, NULL, dev);
|
||||
|
||||
free(dev);
|
||||
|
||||
@@ -52,19 +52,43 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *bus_name;
|
||||
void *i2c;
|
||||
uint8_t scl, sda, state, slave_state, slave_addr,
|
||||
slave_rw, last_sda, pos, transmit, byte;
|
||||
} i2c_gpio_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_I2C_GPIO_LOG
|
||||
int i2c_gpio_do_log = ENABLE_I2C_GPIO_LOG;
|
||||
|
||||
|
||||
static void
|
||||
i2c_gpio_log(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (i2c_gpio_do_log >= level) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define i2c_gpio_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void *
|
||||
i2c_gpio_init(char *bus_name)
|
||||
{
|
||||
i2c_gpio_t *dev = (i2c_gpio_t *) malloc(sizeof(i2c_gpio_t));
|
||||
memset(dev, 0, sizeof(i2c_gpio_t));
|
||||
|
||||
dev->i2c = i2c_addbus(bus_name);
|
||||
i2c_gpio_log(1, "I2C GPIO %s: init()\n", bus_name);
|
||||
|
||||
dev->bus_name = bus_name;
|
||||
dev->i2c = i2c_addbus(dev->bus_name);
|
||||
dev->scl = dev->sda = 1;
|
||||
dev->slave_addr = 0xff;
|
||||
|
||||
@@ -77,6 +101,8 @@ i2c_gpio_close(void *dev_handle)
|
||||
{
|
||||
i2c_gpio_t *dev = (i2c_gpio_t *) dev_handle;
|
||||
|
||||
i2c_gpio_log(1, "I2C GPIO %s: close()\n", dev->bus_name);
|
||||
|
||||
i2c_removebus(dev->i2c);
|
||||
|
||||
free(dev);
|
||||
@@ -87,6 +113,7 @@ void
|
||||
i2c_gpio_next_byte(i2c_gpio_t *dev)
|
||||
{
|
||||
dev->byte = i2c_read(dev->i2c, dev->slave_addr);
|
||||
i2c_gpio_log(1, "I2C GPIO %s: next_byte() = %02X\n", dev->bus_name, dev->byte);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +128,8 @@ i2c_gpio_write(i2c_gpio_t *dev)
|
||||
dev->slave_addr = dev->byte >> 1;
|
||||
dev->slave_rw = dev->byte & 1;
|
||||
|
||||
i2c_gpio_log(1, "I2C GPIO %s: Initiating transfer to address %02X rw %d\n", dev->bus_name, dev->slave_addr, dev->slave_rw);
|
||||
|
||||
if (!i2c_has_device(dev->i2c, dev->slave_addr)) {
|
||||
dev->slave_state = SLAVE_INVALID;
|
||||
break;
|
||||
@@ -120,11 +149,13 @@ i2c_gpio_write(i2c_gpio_t *dev)
|
||||
break;
|
||||
|
||||
case SLAVE_RECEIVEADDR:
|
||||
i2c_gpio_log(1, "I2C GPIO %s: Receiving address %02X\n", dev->bus_name, dev->byte);
|
||||
i2c_write(dev->i2c, dev->slave_addr, dev->byte);
|
||||
dev->slave_state = dev->slave_rw ? SLAVE_SENDDATA : SLAVE_RECEIVEDATA;
|
||||
break;
|
||||
|
||||
case SLAVE_RECEIVEDATA:
|
||||
i2c_gpio_log(1, "I2C GPIO %s: Receiving data %02X\n", dev->bus_name, dev->byte);
|
||||
i2c_write(dev->i2c, dev->slave_addr, dev->byte);
|
||||
break;
|
||||
}
|
||||
@@ -134,7 +165,10 @@ i2c_gpio_write(i2c_gpio_t *dev)
|
||||
void
|
||||
i2c_gpio_stop(i2c_gpio_t *dev)
|
||||
{
|
||||
i2c_stop(dev->i2c, dev->slave_addr);
|
||||
i2c_gpio_log(1, "I2C GPIO %s: Stopping transfer\n", dev->bus_name);
|
||||
|
||||
if (dev->slave_addr != 0xff)
|
||||
i2c_stop(dev->i2c, dev->slave_addr);
|
||||
|
||||
dev->slave_addr = 0xff;
|
||||
dev->slave_state = SLAVE_IDLE;
|
||||
@@ -149,7 +183,9 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
|
||||
switch (dev->state) {
|
||||
case I2C_IDLE:
|
||||
if (dev->scl && scl && dev->last_sda && !sda) { /* start bit */
|
||||
/* !dev->scl check breaks NCR SDMS. */
|
||||
if (/*!dev->scl &&*/ scl && dev->last_sda && !sda) { /* start bit */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Start bit received (from IDLE)\n", dev->bus_name);
|
||||
dev->state = I2C_RECEIVE;
|
||||
dev->pos = 0;
|
||||
}
|
||||
@@ -173,9 +209,11 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
}
|
||||
} else if (dev->scl && scl) {
|
||||
if (sda && !dev->last_sda) { /* stop bit */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Stop bit received (from RECEIVE)\n", dev->bus_name);
|
||||
dev->state = I2C_IDLE;
|
||||
i2c_gpio_stop(dev);
|
||||
} else if (!sda && dev->last_sda) { /* start bit */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Start bit received (from RECEIVE)\n", dev->bus_name);
|
||||
dev->pos = 0;
|
||||
dev->slave_state = SLAVE_IDLE;
|
||||
}
|
||||
@@ -184,6 +222,7 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
|
||||
case I2C_ACKNOWLEDGE:
|
||||
if (!dev->scl && scl) {
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Acknowledging transfer\n", dev->bus_name);
|
||||
sda = 0;
|
||||
dev->pos = 0;
|
||||
dev->state = (dev->transmit == TRANSMITTER_MASTER) ? I2C_RECEIVE_WAIT : I2C_TRANSMIT;
|
||||
@@ -193,12 +232,14 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
case I2C_TRANSACKNOWLEDGE:
|
||||
if (!dev->scl && scl) {
|
||||
if (sda) { /* not acknowledged; must be end of transfer */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: End of transfer\n", dev->bus_name);
|
||||
dev->state = I2C_IDLE;
|
||||
i2c_gpio_stop(dev);
|
||||
} else { /* next byte to transfer */
|
||||
dev->state = I2C_TRANSMIT_START;
|
||||
i2c_gpio_next_byte(dev);
|
||||
dev->pos = 0;
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Next byte = %02X\n", dev->bus_name, dev->byte);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -208,8 +249,10 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
if (dev->last_sda && !sda) { /* start bit */
|
||||
i2c_gpio_next_byte(dev);
|
||||
dev->pos = 0;
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Next byte = %02X\n", dev->bus_name, dev->byte);
|
||||
}
|
||||
if (!dev->last_sda && sda) { /* stop bit */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Stop bit received (from TRANSMIT_WAIT)\n", dev->bus_name);
|
||||
dev->state = I2C_IDLE;
|
||||
i2c_gpio_stop(dev);
|
||||
}
|
||||
@@ -220,6 +263,7 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
if (!dev->scl && scl)
|
||||
dev->state = I2C_TRANSMIT;
|
||||
if (dev->scl && scl && !dev->last_sda && sda) { /* stop bit */
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Stop bit received (from TRANSMIT_START)\n", dev->bus_name);
|
||||
dev->state = I2C_IDLE;
|
||||
i2c_gpio_stop(dev);
|
||||
}
|
||||
@@ -228,13 +272,18 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
|
||||
case I2C_TRANSMIT:
|
||||
if (!dev->scl && scl) {
|
||||
dev->scl = scl;
|
||||
if (!dev->pos)
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Transmit byte %02X\n", dev->bus_name, dev->byte);
|
||||
dev->sda = sda = dev->byte & 0x80;
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Transmit bit %02X %d\n", dev->bus_name, dev->byte, dev->pos);
|
||||
dev->byte <<= 1;
|
||||
dev->pos++;
|
||||
return;
|
||||
}
|
||||
if (dev->scl && !scl && (dev->pos == 8))
|
||||
if (dev->scl && !scl && (dev->pos == 8)) {
|
||||
dev->state = I2C_TRANSACKNOWLEDGE;
|
||||
i2c_gpio_log(2, "I2C GPIO %s: Acknowledge mode\n", dev->bus_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user