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.

MSP430FR2355: Multiple bytes register addressing when using the MSP430FR2355 as an I2C slave

Part Number: MSP430FR2355

I have been following msp430fr235x_eusci_standard_master and msp430fr235x_eusci_standard_slave to make a MSP430FR430FR2355 i2c slave device. I have read the slva704 'understanding the i2c bus' and is it possible to have a register address that is 2 or more bytes in length? not the device address, but the register address or command.

In the code:

void I2C_Slave_ProcessCMD(uint8_t cmd)

void I2C_Slave_TransactionDone(uint8_t cmd)

can the cmd be uint16t or even longer? or is it prohibited by i2c protocol, and command/register byte in a packet can max be 8 bits?

Best Regards,

Can

  • I2C per se (UM10204) doesn't say anything about registers. It knows only Reads and Writes.

    The convention that has emerged (common but not universal) is that the first byte(s) of a Write are interpreted by the slave as a register number or pointer, which causes state to be stored in the slave such that a subsequent Read returns data based on that state. Subsequent bytes in a Write are interpreted as data to be stored based on that saved state (which may itself affect the state, e.g. auto-increment).

    The VL53L3 comes to mind as a slave with 2-byte register numbers. A (large) I2C EEPROM might have a 3-byte register number (perhaps more properly called a "pointer" in that case).

    That said, you need to go over the particular code you're interested in to make sure it doesn't have any implicit/accidental dependencies on 1-byte register numbers. E.g. one thing to look for: What happens if the Master does a 1-byte Write?

  • Hello Bruce;

    I want to read from 2 byte registers. Here is my I2C0 receive function:

    uint32_t I2C0Receive(uint32_t slave_addr, uint8_t reg) {

        I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);
        I2CMasterDataPut(I2C0_BASE, reg);
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
        while(I2CMasterBusy(I2C0_BASE));

        I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
        while(I2CMasterBusy(I2C0_BASE));
        return I2CMasterDataGet(I2C0_BASE);
    }

    The first part, I send the slave the register address I want to read from. (reg). Unfortunately in the API, I2CMasterDataPut accepts a uint8_t only. I might be able to repeat code here, and send it twice maybe? How else can I solve this problem?

    So, I basically want to read multiple bytes from a 2 byte address.

    Best regards,

    C.

  • I'm not familiar with the API you're using, but supposing it's for Tiva/MSP432E (8-byte FIFO), I suspect you could do something like replace:

    >   I2CMasterDataPut(I2C0_BASE, reg);

    with

    >  I2CMasterDataPut(I2C0_BASE, (reg >> 8)&0xFF);  // MSB first

    >  I2CMasterDataPut(I2C0_BASE, (reg >> 0)&0xFF);  // LSB second

    I've adopted big-endian (MSByte first) since the >1-byte-register-number devices I've worked with use that. (Admittedly small sample.) If you're writing the other end you get to pick.

    Stating the obvious: You need to know the register-number-size for the slave; if you use the second variant on a slave with 1-byte register numbers, you'll be writing into some register you don't intend to.

**Attention** This is a public forum