Tool/software: Code Composer Studio
I am using the TMS320F28020 as a slave transmitter with slave address 0x24. The above waveform shows the device addressed correctly, and address data =0x0000 sent, then repeated start and addressed as slave with R/W=1, then the SCL line appears to be in contention. I do not get a AAS interrupt, not sure why. below is the init and interrupt code.
Initialization code:
void I2Cinit(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1; // Start the I2C clock
EDIS;
I2caRegs.I2CMDR.bit.IRS = CLR; // held in reset state to allow changes to registers
// 7bit address master/slave, single master, master mode, I2C mode, asynchronous mode
I2caRegs.I2CMDR.bit.MST = CLR; // Set slave mode
I2caRegs.I2CMDR.bit.TRX = CLR; // Clear TX mode, set RX mode
// SMCLK, ack normally
I2caRegs.I2CPSC.bit.IPSC = 0x3; // divide I2C clock to generate frequency = 40MHz/(1+3) = 10MHz
I2caRegs.I2CCLKL = 100;
I2caRegs.I2CCLKH = 100; // Master clock = 10MHz/[(100+5)+(100+5)] = 47619Hz
// prescaler high byte, prescaler = (UC0BR0 + UC0BR1 x 256)
// Serial I2C ADDRESS
I2caRegs.I2COAR = I2C_SERIAL_DSP_ADDR; // Load the DSP address
I2caRegs.I2CMDR.bit.IRS = SET; // release form reset
iicRxpacketptr = iicRxDat; // set pointer to the start of the array.
iicTxpacketptr = iicTxDat; // set pointer to the start of the array.
I2caRegs.I2CSTR.bit.RRDY = 1; // Clear rx rdy interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.XRDY = 1; // Clear tx empty interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.AAS = 1; // Clear addr as slave interrupt flag by writing 1 to it
I2caRegs.I2CIER.bit.RRDY = SET; // Set receiver data ready interrupt enable
I2caRegs.I2CIER.bit.SCD = SET; // Set STOP received interrupt enable
I2caRegs.I2CIER.bit.AAS = SET; // Set Addressed as slave interrupt enable
}
Interrupt code:
#pragma CODE_SECTION(_IICIsr, "ramfuncs");
#define NOINT 0x00 // None
#define ALINT 0x01 // Arbitration lost
#define NACKINT 0x02 // NACK detected
#define ARDYINT 0x03 // Registers ready to be accessed
#define RRDYINT 0x04 // Receiver data ready
#define XRDYINT 0x05 // Transmit data ready
#define SCDINT 0x06 // Stop condition detected
#define AASINT 0x07 // Addressed as slave
__interrupt void _IICIsr(void)
{
uint16_t intsrc;
intsrc = I2caRegs.I2CISRC.all & 0x0007; // read interrupt source
switch(intsrc)
{
case RRDYINT: // RRDYINT Receive Data Ready Interrupt
I2caRegs.I2CSTR.bit.RRDY = 1; // Clear rx rdy interrupt flag by writing 1 to it
if(iicRxpacketptr-iicRxDat < MAX_IIC_DATA_BUFF) // dont overflow buffer
*iicRxpacketptr++ = (uint8_t) I2caRegs.I2CDRR; // read D0...Dn-1
else
iicRxpacketptr = iicRxDat; // set pointer to the start of the array.
break;
case SCDINT: // SCDINT Stop condition detected
I2caRegs.I2CSTR.bit.SCD = 1; // Clear stop condition interrupt flag by writing 1 to it
iicRxpacketptr = iicRxDat; // set pointer to the start of the array.
break;
case XRDYINT: // XRDYINT Transmit Data Ready Interrupt
I2caRegs.I2CSTR.bit.XRDY = 1; // Clear tx rdy interrupt flag by writing 1 to it
if(iicTxpacketptr-iicTxDat < MAX_IIC_DATA_BUFF) // dont overflow buffer
I2caRegs.I2CDXR = *iicTxpacketptr++; //
else
iicTxpacketptr = iicTxDat; // set pointer to the start of the array.
break;
case AASINT:
I2caRegs.I2CSTR.bit.AAS = 1; // Clear addr as slave interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.RRDY = 1; // Clear rx rdy interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.XRDY = 1; // Clear tx rdy interrupt flag by writing 1 to it
if(I2caRegs.I2CDRR & 1) // READ cmd from main
{
I2caRegs.I2CMDR.bit.TRX = SET; // SET TX mode, clr RX mode
I2caRegs.I2CIER.bit.RRDY = CLR; // CLR receiver data ready interrupt enable
I2caRegs.I2CIER.bit.XRDY = SET; // SET TX data ready interrupt enable
I2caRegs.I2CDXR = *iicTxpacketptr++; // send out first byte
}
else
{
I2caRegs.I2CSTR.bit.SDIR = 1; // slave direction, clear bit to indicate slave receiver
I2caRegs.I2CMDR.bit.TRX = CLR; // CLR TX mode, set RX mode
I2caRegs.I2CIER.bit.RRDY = SET; // Set receiver data ready interrupt enable
I2caRegs.I2CIER.bit.XRDY = CLR; // CLR TX data ready interrupt enable
}
break;
default:
break;
}
I2caRegs.I2CSTR.bit.RRDY = 1; // Clear rx rdy interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.XRDY = 1; // Clear tx empty interrupt flag by writing 1 to it
I2caRegs.I2CSTR.bit.AAS = 1; // Clear addr as slave interrupt flag by writing 1 to it
PieCtrlRegs.PIEACK.all |= PIEACK_GROUP8;
// PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}