From fd572858e2a5536ceba3985ef3441025145e2e2d Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Sun, 1 Sep 2019 11:41:43 -0700 Subject: [PATCH] Lots of I2C bugs Still need to fix more --- src/pxa260/pxa260I2c.c | 103 ++++++++++++++++++++++----------------- src/pxa260/pxa260I2c.h | 1 - src/pxa260/pxa260_GPIO.c | 8 +++ src/tps65010.c | 48 +++++++++++------- 4 files changed, 97 insertions(+), 63 deletions(-) diff --git a/src/pxa260/pxa260I2c.c b/src/pxa260/pxa260I2c.c index 63785ee..987b467 100644 --- a/src/pxa260/pxa260I2c.c +++ b/src/pxa260/pxa260I2c.c @@ -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"); } diff --git a/src/pxa260/pxa260I2c.h b/src/pxa260/pxa260I2c.h index 46a80c6..a1f6d77 100644 --- a/src/pxa260/pxa260I2c.h +++ b/src/pxa260/pxa260I2c.h @@ -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); diff --git a/src/pxa260/pxa260_GPIO.c b/src/pxa260/pxa260_GPIO.c index d190602..0cee5e8 100644 --- a/src/pxa260/pxa260_GPIO.c +++ b/src/pxa260/pxa260_GPIO.c @@ -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: diff --git a/src/tps65010.c b/src/tps65010.c index 6af1286..d8d71f1 100644 --- a/src/tps65010.c +++ b/src/tps65010.c @@ -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;