I have the following snippet of code using i2c.c library code based upon the demoi2c example. When I pause the system I see that the ICXRDY bit and BB bit are TRUE in the ICSTR register. I am just wondering if I am forgetting something. I just don't get an interrupt at all so it locks up at while(txCompFlag)
void I2CIntRegister(unsigned int channel)
{
I2CPinMuxSetup(0);
// Register the ISR in the Interrupt Vector Table.
IntRegister(SYS_INT_I2CINT0, I2CIsr);
IntChannelSet(SYS_INT_I2CINT0, channel);
// Enable the System Interrupts for AINTC.
IntSystemEnable(SYS_INT_I2CINT0);
}
void I2CConfig(unsigned int slaveAddr, unsigned int speed)
{
// Put i2c in reset/disabled state
I2CMasterDisable(SOC_I2C_0_REGS);
// Configure i2c bus speed to 100khz
I2CMasterInitExpClk(SOC_I2C_0_REGS, 24000000, 8000000, speed);
// Set i2c slave address
I2CMasterSlaveAddrSet(SOC_I2C_0_REGS, slaveAddr);
clearVal = HWREG(SOC_I2C_0_REGS + I2C_ICSTR);
HWREG(SOC_I2C_0_REGS + I2C_ICSTR) = clearVal;
I2CMasterEnable(SOC_I2C_0_REGS);
}
void I2CSlaveRegWrite(unsigned char regAddr, unsigned char regData)
{
// Send the register address and data
slaveData[0] = regAddr;
slaveData[1] = regData;
I2CSendBlocking(2);
}
void I2CSendBlocking(unsigned int dataCnt)
{
txCompFlag = 1;
dataIdx = 0;
while(I2CIsBusy());
I2CSetDataCount(SOC_I2C_0_REGS, dataCnt);
I2CMasterControl(SOC_I2C_0_REGS, I2C_CFG_MST_TX | I2C_CFG_STOP);
I2CMasterIntEnableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY
| I2C_INT_STOP_CONDITION
| I2C_INT_NO_ACK);
I2CMasterStart(SOC_I2C_0_REGS);
// Wait till the data is sent
while(txCompFlag);
while(I2CIsBusy());
}
static void I2CIsr(void)
{
volatile unsigned int intCode = 0;
/* Get interrupt vector code */
intCode = I2CInterruptVectorGet(SOC_I2C_0_REGS);
while(intCode!=0)
{
/* Clear status of interrupt */
#ifdef _TMS320C6X
IntEventClear(SYS_INT_I2C0_INT);
#else
IntSystemStatusClear(15);
#endif
if (intCode == I2C_INTCODE_TX_READY)
{
I2CMasterDataPut(SOC_I2C_0_REGS, slaveData[dataIdx]);
dataIdx++;
}
if(intCode == I2C_INTCODE_RX_READY)
{
slaveData[dataIdx] = I2CMasterDataGet(SOC_I2C_0_REGS);
dataIdx++;
}
if (intCode == I2C_INTCODE_STOP)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_DATA_READY |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
txCompFlag = 0;
}
if (intCode == I2C_INTCODE_NACK)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_DATA_READY |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
/* Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);
I2CStatusClear(SOC_I2C_0_REGS, I2C_CLEAR_STOP_CONDITION);
/* Clear interrupt, if we missed any, in case of error */
#ifdef _TMS320C6X
IntEventClear(SYS_INT_I2C0_INT);
#else
IntSystemStatusClear(15);
#endif
txCompFlag = 0;
}
if (I2CMasterIntStatus(SOC_I2C_0_REGS) & I2C_ICSTR_NACKSNT)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_DATA_READY |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
/* Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);
I2CStatusClear(SOC_I2C_0_REGS, (I2C_CLEAR_NO_ACK_SENT |
I2C_CLEAR_STOP_CONDITION));
/* Clear interrupt, if we missed any, in case of error */
#ifdef _TMS320C6X
IntEventClear(SYS_INT_I2C0_INT);
#else
IntSystemStatusClear(15);
#endif
txCompFlag = 0;
}
intCode = I2CInterruptVectorGet(SOC_I2C_0_REGS);
}
}
Then, I call this function from a timer:
char GetLM87Voltage(unsigned char voltageType)
{
unsigned char address;
unsigned char voltage;
//get the address of the requested voltage
address = 0x20 | voltageType;
I2CConfig(LM87Address, 100000);
I2CSlaveRegWrite(LM87Address, address);
I2CConfig(LM87Address, 100000);
voltage = I2CSlaveRegRead(LM87Address);
return(voltage);
}