Part Number: TMS320F28377D
Tool/software: Code Composer Studio
Good morning.
I configured I2C module setting GPIO (there are external pull-up resistor) and esecute the follow inizialization:
void I2CB_Init(void)
{
// Init I2C GPIO
I2CB_Init_GPIO();
// INIT I2C-B Module
I2cbRegs.I2CMDR.bit.IRS = 0; // DB - Reset I2C Module for settings [TMR pag. 2034]
I2cbRegs.I2CSAR.all = 0x0000; // Slave address
// Prescaler - need 7-12 Mhz on module clk
/*
I2cbRegs.I2CPSC.all = 27; // DB - PERx.SYSCLK/(IPSC+1) = 7.14MHz @200MHz [TMR pag. 2034 7-12MHz OK]
I2cbRegs.I2CCLKL = 8; // NOTE: must be non zero
I2cbRegs.I2CCLKH = 7; // NOTE: must be non zero
// T=1/7.14MHz*[(ICLKL+d)+(ICLKH+d)] = 3,5us @ 286kbps @ d=5 - IPSC > 1 [TMR pag. 2035]
// I2cbRegs.I2CIER.all = 0x24; // Enable SCD & ARDY __interrupts
*/
// T=1/11.76MHz*[(ICLKL+d)+(ICLKH+d)] = 5,014us @ 199,4kbps @ d = 5 - IPSC > 1
I2cbRegs.I2CPSC.all = 16; // DB - PERx.SYSCLK/(IPSC+1) = 11.76MHz @200MHz [TMR pag. 2034 7-12MHz OK]
I2cbRegs.I2CCLKL = 19; // NOTE: must be non zero
I2cbRegs.I2CCLKH = 30; // NOTE: must be non zero
I2cbRegs.I2CIER.all = 0x0000; // Enable NO interrupts
I2cbRegs.I2CMDR.bit.XA = 0; // DB - 7bit Address
I2cbRegs.I2CMDR.bit.FDF = 0; // DB - No Free Data Format
// I2cbRegs.I2COAR.bit.OAR = 1; // DB - Owner Address in SLAVE mode
// I2cbRegs.I2CSAR.bit.SAR = 1; // DB - SLAVE Address in MASTER mode
I2cbRegs.I2CMDR.bit.DLB = 0; // DB - Disable LoopBack Mode
I2cbRegs.I2CMDR.bit.FREE = 1; // DB - Free mode
I2cbRegs.I2CMDR.bit.MST = 1; // DB - Master mode
I2cbRegs.I2CFFTX.bit.TXFFRST = 0; // BB - Reset TX FIFO
I2cbRegs.I2CFFTX.bit.I2CFFEN = 1; // DB - Set Tx FIFO mode
I2cbRegs.I2CFFTX.bit.TXFFIL = 15; // DB - Tx FIFO Level
I2cbRegs.I2CFFTX.bit.TXFFRST = 1; // DB - Disable Tx FIFO
I2cbRegs.I2CFFTX.bit.TXFFIENA = 0; // DB - Disable TX FIFO Interrupt
I2cbRegs.I2CFFTX.bit.TXFFRST = 1; // BB - Release Reset TX FIFO
I2cbRegs.I2CFFRX.bit.RXFFRST = 0; // BB - Reset RX FIFO
I2cbRegs.I2CFFRX.bit.RXFFIL = 15; // DB - Rx FIFO Level
I2cbRegs.I2CFFRX.bit.RXFFINTCLR = 1;// DB - Clear FFIntFlag
I2cbRegs.I2CFFRX.bit.RXFFRST = 1; // DB - Disable Rx FIFO
I2cbRegs.I2CFFRX.bit.RXFFIENA = 0; // DB - Disable RX FIFO Interrupt
I2cbRegs.I2CFFRX.bit.RXFFRST = 1; // BB - Release Reset RX FIFO
I2cbRegs.I2CMDR.bit.IRS = 1; // DB - Relase Reset to I2C Module
}
Unfortunatelly, I try to modify I2C's speed to resolve my issue (see two speed configurations) that I want to explan supported by my
scope. The first action that I doing is execute the follow function:
I2CB_EE_write16((unsigned int)(PTR_MEASURE_BEGIN + (PTR_ABS_TIME_H * 2)), (unsigned int)0x1111);
where is defined as:
unsigned int I2CB_EE_write16(unsigned int EE_addr, unsigned int data_byte)
{
unsigned int I2C_error;
I2C_error = I2CB_EE_write8(EE_addr, (data_byte & 0x00FF));
DELAY_US(500L); // DELAY TO REDUCE AT MINIMUM
I2C_error = I2CB_EE_write8(EE_addr + 1, (data_byte & 0xFF00) >> 8);
DELAY_US(500L); // DELAY TO REDUCE AT MINIMUM
return 1;
}
Naturally, I want to execute two 8 bit EE writings at time. This 8 bit EE writing function is that:
unsigned int I2CB_EE_write8(unsigned int EE_addr, unsigned int data_byte)
{
#define RESET_I2C_TIMEOUT 0x0FFF
unsigned int I2C_error, I2C_timeout;
// Disable Write Protection Line
GpioDataRegs.GPCCLEAR.bit.GPIO82 = 1;
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
//
I2C_timeout = RESET_I2C_TIMEOUT;
while(I2cbRegs.I2CMDR.bit.STP && (I2C_timeout > 0))
I2C_timeout--;
if(I2C_timeout == 0)
return I2C_BUS_BUSY_ERROR;
// Setup slave address
I2cbRegs.I2CSAR.all = EEPROM_I2C_ADDRESS;
// Check if bus busy
I2C_timeout = RESET_I2C_TIMEOUT;
while(I2cbRegs.I2CSTR.bit.BB && (I2C_timeout > 0))
I2C_timeout--;
if(I2C_timeout == 0)
return I2C_BUS_BUSY_ERROR;
// Setup number of bytes to send
// Control Byte + Address H & L
I2cbRegs.I2CCNT = 3;
// Setup data to send
I2cbRegs.I2CDXR.all = ((EE_addr >> 8) & 0x00FF);
I2cbRegs.I2CDXR.all = (EE_addr & 0x00FF);
I2cbRegs.I2CDXR.all = data_byte;
// Send start as master transmitter WITH STOP
I2cbRegs.I2CMDR.all = 0xEE20;
// DB - NACKMOD[15] = X -> In Slave generates ACK [X if in TX Mode]
// DB - FREE[14] = 1 -> Run Free over breakpoints
// DB - STT[13] = 1 -> Generates START in Master Mode
// DB - Reserved = 0
// DB - STP[11] = 1 -> STOP generated by module
// DB - MST[10] = 1 -> Master mode enabled
// DB - TRX[9] = 1 -> Tx mode enabled
// DB - XA[8] = 0 -> 7bit Address
// DB - RM[7] = 0 -> No Repeat Mode
// DB - DLB[6] = 0 -> LoopBack mode
// DB - IRS[5] = 1 -> I2C Module enabled
// DB - STB[4] = 0 -> No Start Byte
// DB - FDF[3] = 0 -> No Free Data Mode;
// DB - BC[2-0] = 000 -> 8bit;
// Activate Write Protection Line
DELAY_US(300);
GpioDataRegs.GPCSET.bit.GPIO82 = 1;
return 1;
}
If I execute I2CB_EE_write16 when two I2CB_EE_write8 are doing sequentially togheter I notice, after second write action, that the
I2C bus are not released. If I execute, with breakpoints one I2CB_EE_write8 at time, the EE writing process execute correctly. So I
think the code is right but, for same asynchronuos reason, there are sometings that block clock I2C module generation after second
write action: I2C bus remain low despite I execute the same I2CMDR word that it wants to generate STOP condition after sendings 3
byte (please, see scopes: two relative a separate writings, and one togheter); unfortunatelly, only control byte exit in the 2nd write...
I hope in your helpings.
Regards.
Diego Bellachioma
P.S.: Follow the scopes, please.
Two 8b EE writings togheter [issue].bmp
1st 8b EE writing [I2C bus released].bmp
2st 8b EE writing [I2C bus released].bmp

