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.

MSP432E401Y: I2C-- How to send arbitrary I2C payloads?

Part Number: MSP432E401Y

Tool/software:

Hi there,

I am currently trying to use the MSP432 to communicate with I2C devices, and I was wondering how you would recommend implementing this routine for sending custom I2C "transactions" with the following format:

  1. Signal START
  2. Write 1-N arbitrary bytes to the bus
  3. Read 0-N arbitrary bytes from the bus
  4. Signal STOP

What sort of commands do I have to send to the FSM to achieve this behavior? 

I've been running into the following issues:

  • The I2C peripheral seems to get caught if the peripheral does not ACK the initial byte.
  • I'm not sure how to write just one byte to the bus without reading.

I'm using the GCC compiler, no RTOS, and DriverLib.

Thanks!

  • Hi,

      This application report demonstrates how to use the feature I2C master on the MSP432E4 microcontrollers to communicate with  slave devices in a system. 

    https://www.ti.com/lit/pdf/slaa776

      There are also quite a few examples in the MSP432E SDK for I2C module. I will suggest you start with the i2c_mastermode_simple_transfer and then the ic2_mastermode_repeatestart_transfer. 

    The I2C peripheral seems to get caught if the peripheral does not ACK the initial byte.

    If the slave does not ACK then it is most likely that the slave is not addressed correctly. I suppose you have proper pullup resistor on both the SCL and SDA buses, right? What slave do you have? If you can show a logic analyzer capture on the I2C bus then I can help look at it. 

  • Hi Charles,

    I have proper pullups on SCL and SDA. I can't share what device I'm communicating with, but I can say that it has an initialization sequence that requires a single byte to be written to the I2C bus and NACK'ed.

    I understand this is nonstandard behavior, but I was wondering how the I2C FSM works and how I could get it to send just a single byte.

    • When the I2C peripheral receives a NACK, is the transmission halted? Do I need to do anything to "clear" that error flag?
    • The docs you sent indicate I should use I2C_MASTER_CMD_SINGLE_SEND/RECEIVE or  I2C_MASTER_CMD_BURST_SEND/RECEIVE_START to get the address and direction bit written to the bus. What should I do afterwards to "reset" the FSM to an idle state?

    EDIT: Also, can the burst mode be used to achieve equivalent behavior to the single-byte commands?

    Thanks!

  • that requires a single byte to be written to the I2C bus and NACK'ed.
    • When the I2C peripheral receives a NACK, is the transmission halted? Do I need to do anything to "clear" that error flag?

    Hi Shranav,

      I'm only very clear here. Are you saying you are expecting a NACK from the slave device and that is a real intended behavior? If that is the case, the FSM will get an error. If the master receives a NACK then it will STOP and abort the transfer. 

    18.3.1.4 Acknowledge
    All bus transactions have a required acknowledge clock cycle that is generated by the master. During
    the acknowledge cycle, the transmitter (which can be the master or slave) releases the SDA line.
    To acknowledge the transaction, the receiver must pull down SDA during the acknowledge clock
    cycle. The data transmitted out by the receiver during the acknowledge cycle must comply with the
    data validity requirements described in “Data Validity” on page 1280.
    When a slave receiver does not acknowledge the slave address, SDA must be left High by the slave
    so that the master can generate a STOP condition and abort the current transfer. If the master
    device is acting as a receiver during a transfer, it is responsible for acknowledging each transfer
    made by the slave. Because the master controls the number of bytes in the transfer, it signals the
    end of data to the slave transmitter by not generating an acknowledge on the last data byte. The
    slave transmitter must then release SDA to allow the master to generate the STOP or a repeated
    START condition.
    If the slave is required to provide a manual ACK or NACK, the I2C Slave ACK Control
    (I2CSACKCTL) register allows the slave to NACK for invalid data or command or ACK for valid
    data or command. When this operation is enabled, the MCU slave module I2C clock is pulled low
    after the last data bit until this register is written with the indicated response.

    • The docs you sent indicate I should use I2C_MASTER_CMD_SINGLE_SEND/RECEIVE or  I2C_MASTER_CMD_BURST_SEND/RECEIVE_START to get the address and direction bit written to the bus. What should I do afterwards to "reset" the FSM to an idle state?

    If data is NACKed during a BURST and the STOP bit is set
    in the I2CMCS register, the transfer terminates. If the STOP bit is not set, the software application
    must issue a repeated STOP or START when a NACK interrupt is asserted. In the case of a NACK,
    the I2CMBCNT register can be used to determine the amount of data that was transferred prior to
    the BURST termination. If the Address is NACKed during a transfer, then a STOP is issued.

  • Are you saying you are expecting a NACK from the slave device and that is a real intended behavior?

    Yes, that is what I am expecting from the device. Sorry if that complicates things.

    So based on what you've sent me, I would do the following:

    I2CMasterSlaveAddrSet(..., deviceAddr, false);
    while (I2CMasterBusBusy(...)) {}
    I2CMasterDataPut(..., 0x00); // 0x00 will never be sent since we expect a NACK
    I2CMasterControl(I2C_MASTER_CMD_SINGLE_SEND); // addr is sent and NACK'ed.

    assert I2CMasterErr(...) == I2C_MASTER_ERR_ADDR_ACK;

    And to send data afterwards I could just retry according to the example code in the DriverLib SDK?

  • And to send data afterwards I could just retry according to the example code in the DriverLib SDK

    Yes, please retry the operation after the master has aborted due to NACK and see if that resolves the issue.