TC3XX Cannot initiate I2C High-speed mode

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lgacnik97
Level 2
Level 2
10 replies posted 5 replies posted 5 sign-ins

I managed to achieve some basic I2C operation, where both Master and Slave modules used are both part of TC399XE (I2C0 as Master, I2C1 as Slave device). I was able to set up operation, where Master sends address with following data packet and where Slave received all of that data. However, I'm having issues with setting up same kind of operation but in High Speed mode (up to 3,4 Mbps).

Here is the actual waveform measurement and timing diagram from reference manual:

HS_Mode_Init.png

 

HS_Mode_Init_Timing.png

 

As it can be seen, after master code (0x000001XX) has been generated on I2C bus by master, it generates REPEATED START condition (no stop between ACK/NACK and START condition) but master doesn't switch to high speed mode (SCL period remains unchanged; here 400 kbps).

After master code and NACK (no device shouldn't acknowledge master code) only TX_END and NACK requests are generated by master's I2C module (should there also be MC request generated?). Where as slave's I2C module generates MC request in addition, meaning it recognized master code (note: both devices have MCE bit in ADDRCFG register enabled before operation begins).

Following is Master configuration code and HS mode initialization code (in addition with address+data transfer):

 

/************************* I2C Module 0 => MASTER *************************/
  
  /* Enable access for CLC */
  clearWdtEndinit();
  
  /* Clock enable for I2C module */
  I2C0_CLC.B.DISR = 0;              // Enable module
  while( I2C0_CLC.B.DISS == 1 );
  I2C0_CLC1.B.RMC = 1;              // I2C clock division by 1
  while( I2C0_CLC1.B.RMC != 1 );
  I2C0_CLC1.B.DISR = 0;             // Disable module
  while( I2C0_CLC1.B.DISS == 1 );
  
  /* Configure protocol interrupts */
  I2C0_ERRIRQSM.U = 0x0F;
  I2C0_PIRQSM.U = 0x7F;
  I2C0_IMSC.U = 0x3F;
  
  /* Disable I2C0 module */
  I2C0_RUNCTRL.B.RUN = 0;
  
  /* Configure address settings */
  I2C0_ADDRCFG.U = 0;
  I2C0_ADDRCFG.B.TBAM = I2C_config.addressMode;
  I2C0_ADDRCFG.B.MnS = 1;       // Configured as master
  I2C0_ADDRCFG.B.SONA = 0;
  I2C0_ADDRCFG.B.SOPE = 0;
  
  /* Configure FIFO settings */
  I2C0_FIFOCFG.U = 0;
  I2C0_FIFOCFG.B.RXFC = 1;    // RX FIFO as flow controller
  I2C0_FIFOCFG.B.TXFC = 1;    // TX FIFO as flow controller
  
  clearWdtEndinit();
  
  /* Set Baud Rate */
  switch(I2C_config.baudrate)
  {
    /* Fast Mode (100 kbps - 400 kbps) */
    case 100:
      I2C0_FDIVCFG.B.INC = 1;
      I2C0_FDIVCFG.B.DEC = 332;       // 99 kbps
      break;
      
    case 400:
      I2C0_FDIVCFG.B.INC = 1;
      I2C0_FDIVCFG.B.DEC = 78;        // 399 kbps
      break;
    
    /* High Speed Mode (400 kbps - 3400 kbps) */
    case 1000:
      I2C0_FDIVCFG.B.INC = 1;
      I2C0_FDIVCFG.B.DEC = 78;        // 399 kbps
      I2C0_FDIVHIGHCFG.B.INC = 1;
      I2C0_FDIVHIGHCFG.B.DEC = 32;    // 1000 kbps
      I2C0_ADDRCFG.B.MCE = 1;
      break;
    
    case 3400:
      I2C0_FDIVCFG.B.INC = 1;
      I2C0_FDIVCFG.B.DEC = 78;        // 399 kbps
      I2C0_FDIVHIGHCFG.B.INC = 46;
      I2C0_FDIVHIGHCFG.B.DEC = 162;   // 3399 kbps
      I2C0_ADDRCFG.B.MCE = 1;
      break;
      
    case 5000:
      return 1;
      
    default:
      I2C0_FDIVCFG.B.INC = 1;
      I2C0_FDIVCFG.B.DEC = 78;        // 399 kbps
      I2C0_FDIVHIGHCFG.B.INC = 1;
      I2C0_FDIVHIGHCFG.B.DEC = 32;    // 1000 kbps
      I2C0_ADDRCFG.B.MCE = 1;
      break;
  }
  
  clearWdtEndinit();
  
  /*
  I2C0_TIMCFG.B.SDA_DEL_HD_DAT = 0x3F;
  I2C0_TIMCFG.B.FS_SCL_LOW     = 1;
  I2C0_TIMCFG.B.EN_SCL_LOW_LEN = 1;
  I2C0_TIMCFG.B.SCL_LOW_LEN    = 0x20;
  */
  
  /* Configure port settings */
  P15_IOCR4.B.PC4 = 0x1E;         // SCL at P015.5
  P15_IOCR4.B.PC5 = 0x1E;         // SDA at P015.4
  I2C0_GPCTL.B.PISEL = 0x02;      // PORT-C active
  
  /* Enable I2C0 module */
  I2C0_RUNCTRL.B.RUN = 1;

 

There are few notes I would like to add:

  • I'm not sure whether SONA and SOPE bits in ADDRCFG register should be set for HS mode (Master FSM, figure 328 in RM, imples that they should be cleared, but inside iLLD, both are set) - I cleared those bits, as STOP condition after NACK is not an option (after master code is put on I2C bus)
  • If Master module isn't re-enabled (RUN = 0 -> RUN = 1) after master code is put on I2C bus, further transmission won't be executed by I2C hardware, as BUSSTAT indicated master is busy after master code is transmitted. However, refering to Master FSM (figure 328 of reference manual), it implies that I2C module shouldn't be re-enabled before/after MASTER RESTART state (that can be only done while inside LISTENING state). As side note, same master re-enabling process is done in iLLD
  • Master FSM in reference manual implies that after MASTER RESTART state (and after master code + NACK + REPEATED START condition had been generated) only TPS register should be written to (with addition to loading FIFO via TXD with actual data to be transmitted) in order to begin high speed transfer

*P.S.: I'm using iLLD libraries as reference, since I'm using it to solve problems with my own I2C project. I have also set up stand alone I2C project where only iLLD libraries are used for I2C and it demonstrated well up to now, but I'm also not able to initiate high-speed mode with help of iLLD - looks like there might be some issue inside iLLD as well. I'm not sure.

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
Nambi
Moderator
Moderator
Moderator
500 replies posted 50 likes received 5 likes given

Hi,

I could get the High-Speed mode working with ILLD.

I used the "I2C_Read_Ext_Device_1_KIT_TC397_TFT" ADS example as a base and tested it on the TC397 TFT kit.

Below are the changes which I had done compared to the base "I2C_Read_Ext_Device_1_KIT_TC397_TFT" project:
1. File: I2C_Read_Ext_Device.c
i) Macro definition:
Default: #define I2C_BAUDRATE 400000
Modified: #define I2C_BAUDRATE 1000000

ii) Inside function init_I2C_module()
Default:
i2cConfig.pins = &MCP_PINS;
i2cConfig.baudrate = I2C_BAUDRATE;
Modified:
i2cConfig.pins = &MCP_PINS;
i2cConfig.baudrate = I2C_BAUDRATE;
i2cConfig.mode = IfxI2c_Mode_HighSpeed;

2. File: IfxI2c_I2c.c
i) Inside function IfxI2c_I2c_initDeviceConfig()
Default: i2cDeviceConfig->speedMode = IfxI2c_Mode_StandardAndFast;
Modified: i2cDeviceConfig->speedMode = IfxI2c_Mode_HighSpeed;

I have attached "Waveforms for High-Speed Mode switching.docx" which illustrates the High-Speed mode switch.

Best Regards,
Nambi.

View solution in original post

0 Likes
1 Reply
lock attach
Attachments are accessible only for community members.
Nambi
Moderator
Moderator
Moderator
500 replies posted 50 likes received 5 likes given

Hi,

I could get the High-Speed mode working with ILLD.

I used the "I2C_Read_Ext_Device_1_KIT_TC397_TFT" ADS example as a base and tested it on the TC397 TFT kit.

Below are the changes which I had done compared to the base "I2C_Read_Ext_Device_1_KIT_TC397_TFT" project:
1. File: I2C_Read_Ext_Device.c
i) Macro definition:
Default: #define I2C_BAUDRATE 400000
Modified: #define I2C_BAUDRATE 1000000

ii) Inside function init_I2C_module()
Default:
i2cConfig.pins = &MCP_PINS;
i2cConfig.baudrate = I2C_BAUDRATE;
Modified:
i2cConfig.pins = &MCP_PINS;
i2cConfig.baudrate = I2C_BAUDRATE;
i2cConfig.mode = IfxI2c_Mode_HighSpeed;

2. File: IfxI2c_I2c.c
i) Inside function IfxI2c_I2c_initDeviceConfig()
Default: i2cDeviceConfig->speedMode = IfxI2c_Mode_StandardAndFast;
Modified: i2cDeviceConfig->speedMode = IfxI2c_Mode_HighSpeed;

I have attached "Waveforms for High-Speed Mode switching.docx" which illustrates the High-Speed mode switch.

Best Regards,
Nambi.

0 Likes