This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP432P401R: I2C in CCS is different from Keil

Part Number: MSP432P401R
Other Parts Discussed in Thread: TCA9535

Tool/software: Code Composer Studio

For some reason, i have to change the IDE from keil to ccs, and i found that when i use software i2c in keil ,after one read process,it will halt long time,but in ccs it didn't. And the ccs may cause read/write error because  the break between two read process is to short.

following image show the problem:

keil:

it took over 100ms after first read.

first read:

second read:

ccs:

it did the second read right after first read,it only break few time i set to delay.

i don't konw why,should i set some compile para in ccs or what? thanks. 

  • Can you send the master/slave software you are using, or let me know which example this is if you are using an example from the SimpleLink SDK?
  • hi Bob, i'm using io simulate i2c like this

    void I2C_SendByte(C_U32 a_u32SclPort, C_U32 a_u32SclPin, C_U32 a_u32SdaPort, C_U32 a_u32SdaPin, C_U8 a_u8Data) 
    {
        C_U8 i = 0;
    
        SCL_LOW(a_u32SclPort, a_u32SclPin);
    
        for ( i = 0; i < 8; i ++)
        {
            (a_u8Data & 0x80) ? SDA_HIGH(a_u32SdaPort, a_u32SdaPin) : SDA_LOW(a_u32SdaPort, a_u32SdaPin);
            Delay(DELAY_MS); // ***
            SCL_HIGH(a_u32SclPort, a_u32SclPin);
            Delay(DELAY_MS);
            Delay(DELAY_MS); // ***
            SCL_LOW(a_u32SclPort, a_u32SclPin);
            Delay(DELAY_MS);
            a_u8Data <<= 1;
        }
    }
    static void TCA9535_Write(ST_TCA9535* a_pstTCA9535, C_U8 a_u8RegAddr, C_U8 a_u8RegData)
    {
       
    	I2C_Start(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN);
    
       
    	I2C_SendByte(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN, a_pstTCA9535->m_DevAddrW);
    	if (!I2C_CheckAck(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN))
        {
            I2C_Stop(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN);
            Printf("error: %s, %d,addr:%x\r\n", __FILE__, __LINE__,a_pstTCA9535->m_DevAddrR>>1);
            return ;
        }
    
       
        I2C_SendByte(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN, a_u8RegAddr);
    	if (!I2C_CheckAck(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN))
        {
            I2C_Stop(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN);
            Printf("error: %s, %d,addr:%x\r\n", __FILE__, __LINE__,a_pstTCA9535->m_DevAddrR>>1);
            return ;
        }
    
        /* Data */
        I2C_SendByte(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN, a_u8RegData);
    	if (!I2C_CheckAck(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN))
        {
            I2C_Stop(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN);
            Printf("error: %s, %d,addr:%x\r\n", __FILE__, __LINE__,a_pstTCA9535->m_DevAddrR>>1);
            return ;
        }
    
       
    	I2C_Stop(SCL_PORT, SCL_PIN, SDA_PORT, SDA_PIN);
    }

  • Is there a reason you are trying to do this with a Software-driven approach rather than using the I2C peripheral and driverlib code? I would first look at our I2C examples in Resource Explorer. I would start with the master/slave pair below:

    i2c_master_w_multibyte-slave_code

    i2c_master_w_multibyte-master_code

    Regards,

      Bob

  • well,first i try to use the demo code in light sensor to read data from TCA9535,like this 

    const eUSCI_I2C_MasterConfig i2cConfig =
    {
            EUSCI_B_I2C_CLOCKSOURCE_SMCLK,          // SMCLK Clock Source
            24000000,                               // SMCLK = 48MHz
            EUSCI_B_I2C_SET_DATA_RATE_100KBPS,      // Desired I2C Clock of 100khz
            0,                                      // No byte counter threshold
            EUSCI_B_I2C_NO_AUTO_STOP                // No Autostop
    };
    
    static void TCA9535_Write(ST_TCA9535* a_pstTCA9535, C_U8 a_u8RegAddr, C_U8 a_u8RegData)
    {
    
    /* Specify slave address for I2C */
    I2C_setSlaveAddress(EUSCI_B3_BASE,
    	(a_pstTCA9535->m_DevAddr));
      
    /* Enable and clear the interrupt flag */
    I2C_clearInterruptFlag(EUSCI_B3_BASE,
    	EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    
    /* Set master to transmit mode PL */
       I2C_setMode(EUSCI_B3_BASE,
    	   EUSCI_B_I2C_TRANSMIT_MODE);
     
       /* Clear any existing interrupt flag PL */
       I2C_clearInterruptFlag(EUSCI_B3_BASE,
    	   EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    
       /* Wait until ready to write PL */
       while (I2C_isBusBusy(EUSCI_B3_BASE));
     
    
       /* Initiate start and send first character */
       I2C_masterSendMultiByteStart(EUSCI_B3_BASE,
    	   a_u8RegAddr);
    
       while(!I2C_getInterruptStatus(EUSCI_B3_BASE,
            EUSCI_B_I2C_STOP_INTERRUPT));
    	 
       I2C_masterSendMultiByteFinish(EUSCI_B3_BASE,
    	  a_u8RegData);
    	  while(!I2C_getInterruptStatus(EUSCI_B3_BASE,
            EUSCI_B_I2C_STOP_INTERRUPT));
    }
    
    static void TCA9535_Read(ST_TCA9535* a_pstTCA9535, C_U8 a_u8RegAddr, C_U8* a_u8RegData)
    {
    	
    	/* Specify slave address for I2C */
    	I2C_setSlaveAddress(EUSCI_B3_BASE,
    		(a_pstTCA9535->m_DevAddr));
    	
    	/* Enable and clear the interrupt flag */
    	I2C_clearInterruptFlag(EUSCI_B3_BASE,
    		EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
    
    
        /* Set master to transmit mode PL */
        I2C_setMode(EUSCI_B3_BASE,
            EUSCI_B_I2C_TRANSMIT_MODE);
     
        /* Clear any existing interrupt flag PL */
        I2C_clearInterruptFlag(EUSCI_B3_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    
        /* Wait until ready to write PL */
        while (I2C_isBusBusy(EUSCI_B3_BASE));
    
        /* Initiate start and send first character */
        I2C_masterSendMultiByteStart(EUSCI_B3_BASE, a_u8RegAddr);
    
        /* Wait for TX to finish */
        while(!(I2C_getInterruptStatus(EUSCI_B3_BASE,
            EUSCI_B_I2C_TRANSMIT_INTERRUPT0)));
    
        /* Initiate stop only */
        I2C_masterSendMultiByteStop(EUSCI_B3_BASE);
    
        /* Wait for Stop to finish */
        while(!I2C_getInterruptStatus(EUSCI_B3_BASE,
            EUSCI_B_I2C_STOP_INTERRUPT));
    
        /*
         * Generate Start condition and set it to receive mode.
         * This sends out the slave address and continues to read
         * until you issue a STOP
         */
    		*a_u8RegData = I2C_masterReceiveSingleByte(EUSCI_B3_BASE);
        //I2C_masterReceiveStart(EUSCI_B3_BASE);
    
        /* Wait for RX buffer to fill */
      //  while(!(I2C_getInterruptStatus(EUSCI_B3_BASE,
           // EUSCI_B_I2C_RECEIVE_INTERRUPT0)));
    
        /* Receive second byte then send STOP condition */
       // *a_u8RegData = I2C_masterReceiveMultiByteFinish(EUSCI_B3_BASE);
    	
    }
    
    void TCA9535_Init(ST_TCA9535* a_pstTCA9535, C_U8 a_u8DevAddr)
    {
        a_pstTCA9535->m_DevAddrW = (a_u8DevAddr << 1) | 0; // Addr + Write
        a_pstTCA9535->m_DevAddrR = (a_u8DevAddr << 1) | 1; // Addr + Read
        a_pstTCA9535->m_DevAddr = a_u8DevAddr;
    	
        GPIO_setAsPeripheralModuleFunctionOutputPin(
                SCL_PORT,
                SCL_PIN,
                GPIO_SECONDARY_MODULE_FUNCTION);
    
        GPIO_setAsPeripheralModuleFunctionOutputPin(
                SDA_PORT,
                SDA_PIN,
                GPIO_SECONDARY_MODULE_FUNCTION);
    
    			/* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
    	  I2C_initMaster(EUSCI_B3_BASE, &i2cConfig);
    	
    	  /* Disable I2C module to make changes */
    	  I2C_disableModule(EUSCI_B3_BASE);
    	
    	  /* Enable I2C Module to start operations */ 
    	 I2C_enableModule(EUSCI_B3_BASE);
    	  /* Select I2C function for I2C_SCL(P6.5) & I2C_SDA(P6.4) */
    }

      it will stuck in 

    while (I2C_isBusBusy(EUSCI_B3_BASE));
    because the UCBBUSY is alwasy set.
    And i found that UCBBUSY is set right after i do I2C_enableModule(EUSCI_B3_BASE);
    and never reset, but i haven't begun to send a byte.

    the second reason is because i'm using another i2c to communicate with a device that will switch scl and sda, that means, if i read or write error, i will switch scl and sda and try again,
    so i'm using software driven.And i use this in communicating with TCA9535 too for convenience.

  • It looks like this issue was answered in this post, so closing the thread here.