I2C should be working now

This commit is contained in:
meepingsnesroms
2019-08-02 18:29:46 -07:00
parent ad53041077
commit 814d180642
3 changed files with 66 additions and 22 deletions

View File

@@ -1,4 +1,5 @@
#include <stdint.h>
#include <stdbool.h>
#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");
}

View File

@@ -2,6 +2,7 @@
#define PXA260_I2C_H
#include <stdint.h>
#include <stdbool.h>
#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

View File

@@ -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){