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.

MSP430FR5043: I2C interfacing with HDC2022 using MSP430 API

Part Number: MSP430FR5043
Other Parts Discussed in Thread: HDC2022

Hi

I'm trying to interface HDC2022 with MSP430FR5043 using API provided. I'm able to read temperature, device ID, registers through separate codes but when tried to read one after another the value read is getting corrupted. When reset is pressed and MSP430 is booted again, it is able to read first register properly. Delay functions are added everywhere required.

Please let me know possible issue here.

  • Hi,

    This seems weird. Which API you are using to interface with the HDC2022?

    Best regards,

    Cash Hao

  • Hi,

    Please find the code below.

    uint8_t i2c_read_temp(uint8_t reg_address)
    {
        uint8_t temp = 0;
    
        while (EUSCI_B_I2C_SENDING_STOP
                == EUSCI_B_I2C_masterIsStopSent(EUSCI_B1_BASE))
            ;
    
        Serial_String("\r\n");
        Serial_String("out of first while loop in i2c read");
    
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B1_BASE, reg_address);
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, reg_address);
    
        Serial_String("\r\n");
        Serial_String("Reading from register");
    
        //  printf(test, "%d ", reg_address);
    
        //Serial_String("\r\n");
    
        //Serial_String("out of mastersend func in i2c read");
        __delay_cycles(1000);
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
        //Serial_String("\r\n");
        // Serial_String("out of second while loop in i2c read");
    
        EUSCI_B_I2C_masterReceiveStart(EUSCI_B1_BASE);
    
        temp = EUSCI_B_I2C_masterReceiveSingle(EUSCI_B1_BASE);
    
        EUSCI_B_I2C_masterReceiveMultiByteStop(EUSCI_B1_BASE);
    
        return temp;
    }
    
        LSB = i2c_read_temp(0xFE);
    
        MSB = i2c_read_temp(0xFF);

    Here  LSB = i2c_read_temp(0xFE); gives D0 but    MSB = i2c_read_temp(0xFF); gives 72.

    This is observed when the function is called one after another in a loop after a delay.

    But when only once the functions are called , then i'm observing LSB as D0 and MSB as 7 which is correct as per datasheet.

    Please check.

  • Hi

    Please reply.

  • Hi Bivin,

    I do not have any clue now why the read functions can work normally when you called once at a time.

    Could you use a scope or a logic analyzer to capture the I2C signals? And compare the signals between calling the read function continuously and separately.

    That can give us some clue to fix this issue.

    Best regards,

    Cash Hao 

  • Hi

    Please see the screenshots of I2C attached.

    We observe that HDC IC is responding properly by giving proper register values every time we read, but  we found below issue.

    Consider we are reading registers in below order.

    LSB1 = i2c_read_temp(0xFE) -- D0

    MSB1 = i2c_read_temp(0xFE) -- 07

    LSB2 = i2c_read_temp(0xFC) -- 49

    MSB2 = i2c_read_temp(0xFD) -- 54

    Here we are getting LSB1 & MSB 1 properly, but for LSB2 we get 0x07 (which corresponds to I2C data read in previous step) and MSB2 as 0x49 (which corresponds to I2C data read in previous step).

    It appears the data in MSP buffer is not getting cleared or interrupt cleared before data cleared.

    Please let me know how to fix this issue. Code used is same as shown above.

    Regards,

    Bivin

  • Hi

    Please update

  • Can you post your I2C initialization code? EUSCI_B_I2C_masterReceiveSingle() cares about whether UCRXIE0 is set.

  • Hi

    Please see the codes below.

    void i2c_reinit(void)
    {
        GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN5);
        GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN6);
    
        GPIO_setOutputHighOnPin(GPIO_PORT_P5, GPIO_PIN5 + GPIO_PIN6);
    
        __delay_cycles(1000000);
    
        GPIO_setOutputLowOnPin(GPIO_PORT_P5, GPIO_PIN5 + GPIO_PIN6);
    
        GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_P5,
                                                   GPIO_PIN5 + GPIO_PIN6,
                                                   GPIO_SECONDARY_MODULE_FUNCTION);
    
        Serial_String("\r\n");
        Serial_String("I2C re-initialization is started");
    
        EUSCI_B_I2C_initMasterParam param = { 0 };
    
        param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
        param.i2cClk = CS_getSMCLK();
        param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
        param.byteCounterThreshold = 0;
        param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
        EUSCI_B_I2C_initMaster(EUSCI_B1_BASE, &param);
    
        //Specify slave address
        EUSCI_B_I2C_setSlaveAddress(EUSCI_B1_BASE, SLAVE_ADDRESS);
    
        //Set Master in receive mode
        EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
    
        //Enable I2C Module to start operations
        EUSCI_B_I2C_enable(EUSCI_B0_BASE);
    
        EUSCI_B_I2C_clearInterrupt(
                EUSCI_B1_BASE,
                EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
    
    }
    
    
    void i2c_write(uint8_t reg_address, uint8_t data)
    {
    
        while (EUSCI_B_I2C_SENDING_STOP
                == EUSCI_B_I2C_masterIsStopSent(EUSCI_B1_BASE))
            ;
        Serial_String("\r\n");
        Serial_String("Starting write operation");
    
        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B1_BASE, reg_address);
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, reg_address);
        Serial_String("\r\n");
        Serial_String("reg address sent");
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
    
        Serial_String("\r\n");
        Serial_String("ack received");
    
        //EUSCI_B_I2C_masterSendSingleByte(EUSCI_B1_BASE, data);
        EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B1_BASE, data);
        Serial_String("\r\n");
        Serial_String("data sent");
    
        while (!(UCB1IFG & UCTXIFG0))
            ;
    
        Serial_String("\r\n");
        Serial_String("data ack received");
    
        EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B1_BASE);
    
    }
    

    We call i2c_reinit() first after that i2c_write() and then i2c_read_temp().

    Please comment.

    Regards,

    Bivin

  • I don’t see anything obviously wrong here. Driving the i2c pins even for 1 second is very unusual, though if you only do it once (ever) I can’t think of a reason it would cause your trouble. That said, is there a reason for doing this?

  • Hi

    1 second delay was added just for test purpose. No specific reason for the same.

    You mentioned "EUSCI_B_I2C_masterReceiveSingle() cares about whether UCRXIE0 is set.", is this an issue in above code.

    What we observe is as mentioned earlier , the data read from a register comes on the next I2C read. Is there a way to clear I2C read buffer or FIFO before read operation.

    Please comment.

    Regards,

    Bivin

  • Your symptom suggests that something isn’t waiting for UCRXIFG to go high. ReceiveSingle only waits if UCRXIE=0, so I was looking for a call to EUSCI_B_EnableInterrupt,which I don’t see in these fragments.

    Would it be possible to breakpoint at the call to ReceiveSingle and screen-shot tithe EUSCI_B1 config in the Registers View? That would tell us for sure.

    Unsolicited: the call to I2C_enable references EUSCI_B0, not B1. I wonder if there is another call to I2C_enable somewhere.

**Attention** This is a public forum