I2C overhaul part 5: late, but there's still stuff to do

This commit is contained in:
RichardG867
2020-11-23 14:49:49 -03:00
parent 1e80ac1d15
commit d6b1d2c63a
11 changed files with 227 additions and 145 deletions

View File

@@ -152,9 +152,9 @@ lm75_i2c_write(void *bus, uint8_t addr, uint8_t data, void *priv)
return 0;
} else if (dev->i2c_state == 0) {
dev->i2c_state = 1;
/* Linux lm75.c driver relies on a 3-bit address register that doesn't change if bit 2 is set. */
if ((dev->as99127f_i2c_addr >= 0x80) && !(data & 0x04))
dev->addr_register = (data & 0x7);
/* Linux lm75.c driver relies on the address register not changing if bit 2 is set. */
if ((dev->as99127f_i2c_addr < 0x80) || !(data & 0x04))
dev->addr_register = data;
return 1;
}

View File

@@ -39,7 +39,7 @@ enum {
I2C_TRANSMIT_START,
I2C_TRANSMIT,
I2C_ACKNOWLEDGE,
I2C_NEGACKNOWLEDGE,
I2C_NOTACKNOWLEDGE,
I2C_TRANSACKNOWLEDGE,
I2C_TRANSMIT_WAIT
};
@@ -131,15 +131,13 @@ i2c_gpio_write(i2c_gpio_t *dev)
i2c_gpio_log(1, "I2C GPIO %s: Initiating %s address %02X\n", dev->bus_name, dev->slave_read ? "read from" : "write to", dev->slave_addr);
if (!i2c_has_device(dev->i2c, dev->slave_addr)) {
if (!i2c_has_device(dev->i2c, dev->slave_addr) ||
((i == 0xff) && !i2c_start(dev->i2c, dev->slave_addr, dev->slave_read))) { /* start only once per transfer */
dev->slave_state = SLAVE_INVALID;
dev->slave_addr = 0xff;
return I2C_NEGACKNOWLEDGE;
return I2C_NOTACKNOWLEDGE;
}
if (i == 0xff) /* start only once per transfer */
i2c_start(dev->i2c, dev->slave_addr, dev->slave_read);
if (dev->slave_read) {
dev->slave_state = SLAVE_SENDDATA;
dev->transmit = TRANSMITTER_SLAVE;
@@ -154,17 +152,17 @@ i2c_gpio_write(i2c_gpio_t *dev)
i2c_gpio_log(1, "I2C GPIO %s: Receiving address %02X\n", dev->bus_name, dev->byte);
dev->slave_state = dev->slave_read ? SLAVE_SENDDATA : SLAVE_RECEIVEDATA;
if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte))
return I2C_NEGACKNOWLEDGE;
return I2C_NOTACKNOWLEDGE;
break;
case SLAVE_RECEIVEDATA:
i2c_gpio_log(1, "I2C GPIO %s: Receiving data %02X\n", dev->bus_name, dev->byte);
if (!i2c_write(dev->i2c, dev->slave_addr, dev->byte))
return I2C_NEGACKNOWLEDGE;
return I2C_NOTACKNOWLEDGE;
break;
case SLAVE_INVALID:
return I2C_NEGACKNOWLEDGE;
return I2C_NOTACKNOWLEDGE;
}
return I2C_ACKNOWLEDGE;
@@ -236,9 +234,9 @@ i2c_gpio_set(void *dev_handle, uint8_t scl, uint8_t sda)
}
break;
case I2C_NEGACKNOWLEDGE:
case I2C_NOTACKNOWLEDGE:
if (!dev->scl && scl) {
i2c_gpio_log(2, "I2C GPIO %s: Nacking transfer\n", dev->bus_name);
i2c_gpio_log(2, "I2C GPIO %s: Not acknowledging transfer\n", dev->bus_name);
sda = 1;
dev->pos = 0;
dev->state = I2C_IDLE;

View File

@@ -186,6 +186,47 @@ write_fifo(serial_t *dev, uint8_t dat)
}
#include <windows.h>
#include <86box/pit.h>
HANDLE serialdbg = NULL;
OVERLAPPED serialdbgoverlapped_r;
OVERLAPPED serialdbgoverlapped_w;
uint8_t serialdbg_reading = 0;
DWORD serialdbg_read;
uint8_t serialdbg_buf[1];
pc_timer_t serialdbgtimer;
void
serial_dbg_timer(void *p)
{
double dbps = (double) 115200;
double temp = 0.0;
int word_len = 32;
temp = (double) word_len;
temp = (1000000.0 / dbps) * temp;
if (serialdbg_reading) {
if (HasOverlappedIoCompleted(&serialdbgoverlapped_r)) {
if (!GetOverlappedResult(serialdbg, &serialdbgoverlapped_r, &serialdbg_read, FALSE)) {
return;
}
//pclog("overlapped %d\n", serialdbg_read);
for (uint32_t i = 0; i < serialdbg_read; i++) {
pclog("reading %02X\n", serialdbg_buf[i]);
serial_write_fifo((serial_t *) p, serialdbg_buf[i]);
}
serialdbg_reading = 0;
}// else pclog(" not yet\n");
} else {
if (!ReadFile(serialdbg, serialdbg_buf, sizeof(serialdbg_buf), &serialdbg_read, &serialdbgoverlapped_r) && GetLastError() != ERROR_IO_PENDING) {
pclog("serial broken (read) %08X\n", GetLastError());
CancelIo(serialdbg);
return;
}
serialdbg_reading = 1;
}
timer_on_auto(&serialdbgtimer, temp);//((serial_t *) p)->transmit_period);
}
void
serial_write_fifo(serial_t *dev, uint8_t dat)
{
@@ -193,6 +234,8 @@ serial_write_fifo(serial_t *dev, uint8_t dat)
if (!(dev->mctrl & 0x10))
write_fifo(dev, dat);
else
pclog("fifo not in rx mode?\n");
}
@@ -203,6 +246,14 @@ serial_transmit(serial_t *dev, uint8_t val)
write_fifo(dev, val);
else if (dev->sd->dev_write)
dev->sd->dev_write(dev, dev->sd->priv, val);
if (serialdbg && dev->base_address == SERIAL1_ADDR) {
uint8_t buf[1];
buf[0] = val;
pclog("writing %02X...", buf[0]);
WriteFile(serialdbg, buf, 1, NULL, &serialdbgoverlapped_w);
//while (!HasOverlappedIoCompleted(&serialdbgoverlapped_w));
pclog("written\n");
}
}
@@ -323,6 +374,7 @@ serial_update_speed(serial_t *dev)
if (timer_is_enabled(&dev->timeout_timer))
timer_on_auto(&dev->timeout_timer, 4.0 * dev->bits * dev->transmit_period);
//pclog("SPEED UPDATED!!! %f\n", dev->transmit_period);
}
@@ -704,6 +756,15 @@ serial_init(const device_t *info)
next_inst++;
if (dev->base_address == SERIAL1_ADDR) {
serialdbg = CreateFileA(TEXT("\\\\.\\COM4"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
pclog("%02X\n", GetLastError());
if (serialdbg)
timer_add(&serialdbgtimer, serial_dbg_timer, dev, 1);
else
pclog("serial open failed??\n");
}
return dev;
}

View File

@@ -98,8 +98,8 @@ static void
smbus_piix4_write(uint16_t addr, uint8_t val, void *priv)
{
smbus_piix4_t *dev = (smbus_piix4_t *) priv;
uint8_t smbus_addr, cmd, read, block_len, prev_stat, timer_bytes = 0;
uint16_t i;
uint8_t smbus_addr, cmd, read, block_len, prev_stat;
uint16_t timer_bytes = 0, i;
smbus_piix4_log("SMBus PIIX4: write(%02X, %02X)\n", addr, val);
@@ -207,7 +207,7 @@ smbus_piix4_write(uint16_t addr, uint8_t val, void *priv)
break;
case 0x5: /* block R/W */
timer_bytes++; /* account for the SMBus length byte now */
timer_bytes++; /* count the SMBus length byte now */
/* fall-through */