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.

DriverLib I2C Read then Write

Other Parts Discussed in Thread: MSP430F6721

I'm using TI's DriverLib to interface with a TMP007 temperature sensor over I2C.  Microcontroller is MSP430F6721, and I'm not using I2C interrupts.  I'm trying to use the "WithTimeout" functions to avoid being trapped in while loops in case of errors.  But the EUSCI_B_I2C_masterReceiveSingle function does not have a "WithTimeout" version.

Here is the function I've written.  It works fine, except for an inability to handle errors in EUSCI_B_I2C_masterReceiveSingle().  Is this the intended order of function calls to do a write-then-read?  Is another function I'm supposed to use instead for a write-then-read?

/**************************************************************************//**
 * @brief       Read a TMP007 register using I2C write-then-read.
 * @param[in]   address - I2C device address (7-bit)
 * @param[in]   reg - TMP007 register to act upon
 * @param[out]  value - contents of the TMP007 Register
 * @retval      true for success; false otherwise
 *****************************************************************************/
static bool tempReadReg (uint8_t address, uint8_t reg, uint16_t *value)
{
    bool result = false;                // pessimistic return value
    uint8_t temp[2] = {0,0};            // data to send over I2C

    // Set the I2C address of the device we wish to talk to.
    EUSCI_B_I2C_setSlaveAddress(I2C_BASEADDR, address);

    // Set write mode.
    EUSCI_B_I2C_setMode(I2C_BASEADDR, EUSCI_B_I2C_TRANSMIT_MODE);

    // Write START + address + register to the sensor.
    result = EUSCI_B_I2C_masterSendSingleByteWithTimeout(I2C_BASEADDR, reg, TEMP_TIMEROUT);

    // Continue only if the write was successful.
    if (result == true)
    {
        // Set read mode.
        EUSCI_B_I2C_setMode(I2C_BASEADDR, EUSCI_B_I2C_RECEIVE_MODE);

        // RESTART.
        EUSCI_B_I2C_masterReceiveStart(I2C_BASEADDR);

        // Read two bytes from the sensor, STOP.
        temp[0] = EUSCI_B_I2C_masterReceiveSingle(I2C_BASEADDR);
        result = EUSCI_B_I2C_masterReceiveMultiByteFinishWithTimeout(I2C_BASEADDR, &(temp[1]), TEMP_TIMEROUT);

        // Parse the sensor's data.
        *value = (uint16_t)(temp[0] << 8 | temp[1]);
    }

    return result;
}

Thanks,

Adam J.

  • Hi Adam,

    This is some good feedback and I also think that it would be a good idea for there to be a timeout version of receive single -it is something that I'm sure others could use as well. I also think it would be good to include a write-then-read example as many applications need there to be no stop bit sent in between so the correct sequence could matter (e.g. I might use EUSCI_B_I2C_masterSendMultiByteStartWithTimeout instead of EUSCI_B_I2C_masterSendSingleByteWithTimeout because EUSCI_B_I2C_masterSendMultiByteStartWithTimeout doesn't send a stop bit). I'll file this as a feature request for driverlib.

    In the meantime, if you are worried about needing a timeout version of EUSCI_B_I2C_masterReceiveSingle, you should be able to create your own since we include the driverlib source code. I would look at how the timeout is implemented on EUSCI_B_I2C_masterReceiveMultiByteFinishWithTimeout, but in this case you only need to check for the timeout on the RX flag (since you aren't sending a stop condition).

    Regards,
    Katie

  • I tried substituting EUSCI_B_I2C_masterSendMultiByteStartWithTimeout() instead of EUSCI_B_I2C_masterSendSingleByteWithTimeout(), but that made the TMP007 return an invalid value. Not sure if that's because of my code or some behavior of the TMP007, but I'd lean more towards my code.

    Since the TMP007 is a TI part, perhaps someone from TI can shed some light on this further?

**Attention** This is a public forum