Lots of I2C bugs

Still need to fix more
This commit is contained in:
meepingsnesroms
2019-09-01 11:41:43 -07:00
parent d5b6664c73
commit fd572858e2
4 changed files with 97 additions and 63 deletions

View File

@@ -23,7 +23,6 @@ uint8_t pxa260I2cBuffer;
uint16_t pxa260I2cIcr;
uint16_t pxa260I2cIsr;
uint8_t pxa260I2cIsar;
bool pxa260I2cUnitBusy;
static void pxa260I2cUpdateInterrupt(void){
@@ -39,7 +38,6 @@ void pxa260I2cReset(void){
pxa260I2cIcr = 0x0000;
pxa260I2cIsr = 0x0000;
pxa260I2cIsar = 0x00;
pxa260I2cUnitBusy = false;
}
uint32_t pxa260I2cReadWord(uint32_t address){
@@ -47,16 +45,20 @@ uint32_t pxa260I2cReadWord(uint32_t address){
switch(address){
case IBMR:
debugLog("PXA260 direct I2C bus read\n");
return pxa260I2cBus & 0x03;
case IDBR:
//debugLog("PXA260 I2C IDBR read, PC:0x%08X\n", pxa260GetPc());
return pxa260I2cBuffer;
case ICR:
//debugLog("PXA260 I2C ICR read, PC:0x%08X\n", pxa260GetPc());
return pxa260I2cIcr;
case ISR:
debugLog("I2C ISR is currently unimplemented\n");
//TODO: not fully implemeted but the rest seems to be slave mode
//debugLog("PXA260 I2C ISR read, PC:0x%08X\n", pxa260GetPc());
return pxa260I2cIsr;
case ISAR:
@@ -73,63 +75,62 @@ void pxa260I2cWriteWord(uint32_t address, uint32_t value){
switch(address){
case IDBR:
debugLog("PXA260 I2C IDBR write:0x%02X, PC:0x%08X\n", value & 0xFF, pxa260GetPc());
pxa260I2cBuffer = value & 0xFF;
return;
case ICR:
//TODO: this is incomplete
//debugLog("PXA260 ICR write 0x%04X, PC:0x%08X\n", value & 0xFFFF, pxa260GetPc());
pxa260I2cIcr = value & 0xFFFF;
if(!(pxa260I2cIcr & 0x0008) && value & 0x0040){
//I2C unit enabled and not transfering right now, its ok to start a transfer
if(value & 0x0001){
tps65010I2cExchange(I2C_START);
if(value & 0x0001)
tps65010I2cExchange(I2C_START);
if(value & 0x0008){
if(pxa260I2cIsr & 0x0001){
//receive
uint8_t index;
//add unit busy bit
pxa260I2cIsr |= 0x0004;
}
if(value & 0x0008){
if(pxa260I2cIsr & 0x0001){
//receive
uint8_t index;
debugLog("I2C transfer(receive) attempted\n");
debugLog("I2C transfer(receive) attempted\n");
for(index = 0; index < 8; index++){
pxa260I2cBuffer <<= 1;
pxa260I2cBuffer |= !!(tps65010I2cExchange(I2C_FLOATING_BUS) & I2C_1);
for(index = 0; index < 8; index++){
pxa260I2cBuffer <<= 1;
pxa260I2cBuffer |= !!(tps65010I2cExchange(I2C_FLOATING_BUS) & I2C_1);
}
pxa260TimingTriggerEvent(PXA260_TIMING_CALLBACK_I2C_RECEIVE_FULL, PXA260_I2C_TRANSFER_DURATION);
}
else{
//send
uint8_t index;
pxa260I2cUnitBusy = true;
pxa260TimingTriggerEvent(PXA260_TIMING_CALLBACK_I2C_RECEIVE_FULL, PXA260_I2C_TRANSFER_DURATION);
}
else{
//send
uint8_t index;
debugLog("I2C transfer(send) attempted\n");
for(index = 0; index < 8; index++)
tps65010I2cExchange((pxa260I2cBuffer & 1 << 7 - index) ? I2C_1 : I2C_0);
pxa260I2cUnitBusy = true;
pxa260TimingTriggerEvent(PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY, PXA260_I2C_TRANSFER_DURATION);
debugLog("I2C transfer(send) attempted: 0x%02X\n", pxa260I2cBuffer);
for(index = 0; index < 8; index++)
tps65010I2cExchange((pxa260I2cBuffer & 1 << 7 - index) ? I2C_1 : I2C_0);
pxa260TimingTriggerEvent(PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY, PXA260_I2C_TRANSFER_DURATION);
}
}
if(value & 0x0002)
tps65010I2cExchange(I2C_STOP);
}
if(value & 0x0002){
tps65010I2cExchange(I2C_STOP);
//clear read/write bit
pxa260I2cIsr &= 0xFFFE;
}
//cant clear current transfer flag
pxa260I2cIcr = value & 0xFFFF | pxa260I2cIcr & 0x0008;
return;
case ISR:{
//clear IDBR RECEIVE FULL
if(value & 0x0080)
pxa260I2cIsr &= 0xFF7F;
//debugLog("PXA260 I2C write to ISR:0x%04X\n", value & 0xFFFF);
//clear IDBR TRANSMIT EMPTY
if(value & 0x0040)
pxa260I2cIsr &= 0xFFBF;
//unit busy
pxa260I2cIsr |= pxa260I2cUnitBusy << 2;
//clear all clear on write 1 bits
pxa260I2cIsr = pxa260I2cIsr & ~(value & 0x07F0);
//read write setting
pxa260I2cIsr = pxa260I2cIsr & 0xFFFE | value & 0x0001;
@@ -149,17 +150,31 @@ void pxa260I2cWriteWord(uint32_t address, uint32_t value){
}
void pxa260I2cTransmitEmpty(void){
//clear transfer byte
pxa260I2cIcr &= 0xFFF7;
//set transmit empty
pxa260I2cIsr |= 0x0040;
pxa260I2cUnitBusy = false;
//clear read write and unit busy bits if stop was sent
if(pxa260I2cIcr & 0x0002)
pxa260I2cIsr &= 0xFFFA;
pxa260I2cUpdateInterrupt();
debugLog("I2C transmit empty triggered\n");
}
void pxa260I2cReceiveFull(void){
//clear transfer byte
pxa260I2cIcr &= 0xFFF7;
//set receive full
pxa260I2cIsr |= 0x0080;
pxa260I2cUnitBusy = false;
//clear read write and unit busy bits if stop was sent
if(pxa260I2cIcr & 0x0002)
pxa260I2cIsr &= 0xFFFA;
pxa260I2cUpdateInterrupt();
debugLog("I2C receive full triggered\n");
}

View File

@@ -27,7 +27,6 @@ extern uint8_t pxa260I2cBuffer;
extern uint16_t pxa260I2cIcr;
extern uint16_t pxa260I2cIsr;
extern uint8_t pxa260I2cIsar;
extern bool pxa260I2cUnitBusy;
void pxa260I2cReset(void);

View File

@@ -10,6 +10,13 @@ static void pxa260gpioOnOutputPinUpdated(Pxa260gpio* gpio, UInt8 gpioNum){
//debugLog("PXA260 GPIO %d set:%d\n", gpioNum, pxa260gpioGetState(gpio, gpioNum));
switch(gpioNum){
/*
case 19:
case 20:
case 21:
case 22:
*/
case 24:
//TSC2101 chip select
tsc2101SetChipSelect(!!pxa260gpioGetState(gpio, gpioNum));
@@ -106,6 +113,7 @@ Boolean pxa260gpioPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean w
case 8:
pa -= 6;
gpio->latches[pa] |= val;
debugLog("PXA260 GPIO register read:%d\n", pa);
goto recalc;
case 9:

View File

@@ -79,7 +79,6 @@ uint8_t tps65010I2cExchange(uint8_t i2cBus){
if(i2cBus == I2C_START){
tps65010State = I2C_WAIT_FOR_ADDR;
tps65010SelectedRegisterAlreadySet = false;
return I2C_FLOATING_BUS;
}
else if(i2cBus == I2C_STOP){
@@ -89,6 +88,7 @@ uint8_t tps65010I2cExchange(uint8_t i2cBus){
return I2C_FLOATING_BUS;
}
tps65010CurrentI2cByte <<= 1;
tps65010CurrentI2cByte |= (i2cBus == I2C_1);
if(tps65010State == I2C_SENDING){
if(tps65010SelectedRegister < 0x11)
@@ -100,23 +100,35 @@ uint8_t tps65010I2cExchange(uint8_t i2cBus){
if(tps65010CurrentI2cByteBitsRemaining == 0){
//process data from byte
if(tps65010State == I2C_WAIT_FOR_ADDR){
if((tps65010CurrentI2cByte & 0xFE) == 0x90){
//the address is of this device
tps65010State = (tps65010CurrentI2cByte & 0x01) ? I2C_SENDING : I2C_RECEIVING;
}
else{
tps65010State = I2C_NOT_SELECTED;
}
}
else if(tps65010State == I2C_RECEIVING){
if(tps65010SelectedRegisterAlreadySet){
tps65010WriteRegister(tps65010SelectedRegister, tps65010CurrentI2cByte);
}
else{
tps65010SelectedRegister = tps65010CurrentI2cByte;
tps65010SelectedRegisterAlreadySet = true;
}
switch(tps65010State){
case I2C_WAIT_FOR_ADDR:
if((tps65010CurrentI2cByte & 0xFE) == 0x90){
//the address is of this device
tps65010State = (tps65010CurrentI2cByte & 0x01) ? I2C_SENDING : I2C_RECEIVING;
}
else{
tps65010State = I2C_NOT_SELECTED;
}
break;
case I2C_RECEIVING:
if(tps65010SelectedRegisterAlreadySet){
tps65010WriteRegister(tps65010SelectedRegister, tps65010CurrentI2cByte);
tps65010SelectedRegisterAlreadySet = false;
}
else{
tps65010SelectedRegister = tps65010CurrentI2cByte;
tps65010SelectedRegisterAlreadySet = true;
}
break;
case I2C_SENDING:
tps65010SelectedRegisterAlreadySet = false;
break;
default:
debugLog("TPS65010 dont know what to do with byte, cmd:%d\n", tps65010State);
break;
}
tps65010CurrentI2cByteBitsRemaining = 8;