From 814d1806425527bb11744d38812e7576cd1db8cd Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Fri, 2 Aug 2019 18:29:46 -0700 Subject: [PATCH] I2C should be working now --- src/pxa260/pxa260I2c.c | 84 +++++++++++++++++++++++++++++---------- src/pxa260/pxa260I2c.h | 3 ++ src/pxa260/pxa260Timing.c | 1 + 3 files changed, 66 insertions(+), 22 deletions(-) diff --git a/src/pxa260/pxa260I2c.c b/src/pxa260/pxa260I2c.c index b64aded..76a8217 100644 --- a/src/pxa260/pxa260I2c.c +++ b/src/pxa260/pxa260I2c.c @@ -1,4 +1,5 @@ #include +#include #include "../emulator.h" #include "../tps65010.h" @@ -20,14 +21,23 @@ uint8_t pxa260I2cBuffer; uint16_t pxa260I2cIcr; uint16_t pxa260I2cIsr; uint16_t pxa260I2cIsar; +bool pxa260I2cUnitBusy; +static void pxa260I2cUpdateInterrupt(void){ + if(pxa260I2cIcr & 0x0100 && pxa260I2cIsr & 0x0040 || pxa260I2cIcr & 0x0200 && pxa260I2cIsr & 0x0080) + pxa260icInt(&pxa260Ic, PXA260_I_I2C, true); + else + pxa260icInt(&pxa260Ic, PXA260_I_I2C, false); +} + void pxa260I2cReset(void){ pxa260I2cBus = I2C_FLOATING_BUS; pxa260I2cBuffer = 0x00; pxa260I2cIcr = 0x0000; pxa260I2cIsr = 0x0000; pxa260I2cIsar = 0x0000; + pxa260I2cUnitBusy = false; } uint32_t pxa260I2cReadWord(uint32_t address){ @@ -72,36 +82,59 @@ void pxa260I2cWriteWord(uint32_t address, uint32_t value){ if(value & 0x0001) tps65010I2cExchange(I2C_START); if(value & 0x0008){ - uint8_t index; + if(pxa260I2cIsr & 0x0001){ + //receive + uint8_t index; - debugLog("I2C transfer attempted\n"); + debugLog("I2C transfer(receive) attempted\n"); - for(index = 0; index < 8; index++){ - uint8_t receiveValue = tps65010I2cExchange((pxa260I2cBuffer & 1 << 7 - index) ? I2C_1 : I2C_0); - - if(receiveValue != I2C_FLOATING_BUS){ + for(index = 0; index < 8; index++){ pxa260I2cBuffer <<= 1; - pxa260I2cBuffer |= receiveValue == I2C_1; - pxa260I2cBus = receiveValue; + pxa260I2cBuffer |= tps65010I2cExchange(I2C_FLOATING_BUS) & I2C_1; } - } - pxa260TimingQueueEvent(200, PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY); + pxa260I2cUnitBusy = true; + pxa260TimingQueueEvent(200, PXA260_TIMING_CALLBACK_I2C_RECEIVE_FULL); + } + 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; + pxa260TimingQueueEvent(200, PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY); + } } - if(value & 0x0002) + if(value & 0x0002){ tps65010I2cExchange(I2C_STOP); + + //clear read/write bit + pxa260I2cIsr &= 0xFFFE; + } return; - case ISR: - //TODO: clear bits when written with 1s - if(value & 0x0080){ - //IDBR RECEIVE FULL - //TODO: interrupt stuff - } + case ISR:{ + if(value & 0x0080){ + //IDBR RECEIVE FULL + pxa260I2cIsr &= 0xFF7F; + } - if(value & 0x0040){ - //IDBR TRANSMIT EMPTY - //TODO: interrupt stuff + if(value & 0x0040){ + //IDBR TRANSMIT EMPTY + pxa260I2cIsr &= 0xFFBF; + } + + //unit busy + pxa260I2cIsr |= pxa260I2cUnitBusy << 2; + + //read write setting + pxa260I2cIsr = pxa260I2cIsr & 0xFFFE | value & 0x0001; + + pxa260I2cUpdateInterrupt(); } return; @@ -117,7 +150,14 @@ void pxa260I2cWriteWord(uint32_t address, uint32_t value){ void pxa260I2cTransmitEmpty(void){ pxa260I2cIsr |= 0x0040; - if(pxa260I2cIcr & 0x0100) - pxa260icInt(&pxa260Ic, PXA260_I_I2C, true); + pxa260I2cUnitBusy = false; + pxa260I2cUpdateInterrupt(); debugLog("I2C transmit empty triggered\n"); } + +void pxa260I2cReceiveFull(void){ + pxa260I2cIsr |= 0x0080; + pxa260I2cUnitBusy = false; + pxa260I2cUpdateInterrupt(); + debugLog("I2C receive full triggered\n"); +} diff --git a/src/pxa260/pxa260I2c.h b/src/pxa260/pxa260I2c.h index e86ae15..e1d14e8 100644 --- a/src/pxa260/pxa260I2c.h +++ b/src/pxa260/pxa260I2c.h @@ -2,6 +2,7 @@ #define PXA260_I2C_H #include +#include #define PXA260_I2C_BASE 0x40300000 #define PXA260_I2C_SIZE 0x00010000 @@ -26,6 +27,7 @@ extern uint8_t pxa260I2cBuffer; extern uint16_t pxa260I2cIcr; extern uint16_t pxa260I2cIsr; extern uint16_t pxa260I2cIsar; +extern bool pxa260I2cUnitBusy; void pxa260I2cReset(void); @@ -33,5 +35,6 @@ uint32_t pxa260I2cReadWord(uint32_t address); void pxa260I2cWriteWord(uint32_t address, uint32_t value); void pxa260I2cTransmitEmpty(void); +void pxa260I2cReceiveFull(void); #endif diff --git a/src/pxa260/pxa260Timing.c b/src/pxa260/pxa260Timing.c index 92d4cf0..ea9f393 100644 --- a/src/pxa260/pxa260Timing.c +++ b/src/pxa260/pxa260Timing.c @@ -25,6 +25,7 @@ static int32_t pxa260TimingGetDurationUntilNextEvent(int32_t duration/*call with void pxa260TimingInit(void){ pxa260TimingCallbacks[PXA260_TIMING_CALLBACK_I2C_TRANSMIT_EMPTY] = pxa260I2cTransmitEmpty; + pxa260TimingCallbacks[PXA260_TIMING_CALLBACK_I2C_RECEIVE_FULL] = pxa260I2cReceiveFull; } void pxa260TimingReset(void){