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.

MSPM0L1228: How to Prevent DL_I2C_startControllerTransferAdvanced from Automatically Triggering Data Read During I2C Read Phase?

Part Number: MSPM0L1228

Tool/software:

Hi everyone,

I'm working on an I2C driver to meet a client's application requirements. I've broken down the I2C Controller operations into several phases:

  1. i2c_start_write
  2. i2c_start_read
  3. i2c_write
  4. i2c_read
  5. i2c_stop

Currently, the write operations (start_writewrite) are functioning correctly. However, I'm encountering issues with the read operations (start_readreadstop). Here's what's happening:

Issue:

When I execute the following sequence:

start_write > write > start_read > read > stop

During the start_read phase, the function DL_I2C_startControllerTransferAdvanced automatically triggers a data read operation. This results in the read data clock being generated unexpectedly. Although the target address (addr) is being sent out, the data read should not start automatically at this stage.

Expected Behavior:

In the start_read phase, the system should:

  1. Generate the START condition.
  2. Send out the target address (addr).
  3. Stop there without initiating the data read.
  4. The actual data read should be manually triggered in the subsequent read phase.

Relevant Code Snippet:

static bool i2c_start_read(void) {
    // Wait until I2C controller is idle
    if (!retry_until_condition(BUS0_I2C_INST, MAX_RETRIES, 10, is_i2c_idle)) {
        uart_printf("%s I2C not idle; retry limit reached before starting read transfer\n", TAG);
        return false;
    }

    // Flush RX FIFO and reset transfer
    DL_I2C_flushControllerRXFIFO(BUS0_I2C_INST);
    DL_I2C_resetControllerTransfer(BUS0_I2C_INST);

    // Set only the START condition, print debug message
#if DEBUG_START
    uart_printf("%s Starting I2C read transfer (START only)\n", TAG);
#endif

    DL_I2C_startControllerTransferAdvanced(
        BUS0_I2C_INST,
        addr,
        DL_I2C_CONTROLLER_DIRECTION_RX,
        0,  // Transmission length set to 0
        DL_I2C_CONTROLLER_START_ENABLE,
        DL_I2C_CONTROLLER_STOP_DISABLE,
        DL_I2C_CONTROLLER_ACK_ENABLE
    );

    // Check for transfer errors
    if (DL_I2C_getControllerStatus(BUS0_I2C_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
        uart_printf("%s Read start transfer error\n", TAG);
        return false;
    }

    return true;
}

Additional Context:

According to the I2C Controller documentation:

  • To initiate a transfer, set the START bit in the MCTR register to generate the START condition. The controller should then send the START condition followed by the target address once it detects the bus is free.
  • The MBLEN field specifies the number of bytes to transmit. Setting MBLEN to 0 may prevent the address from being sent correctly.

What I've Tried:

  1. Ensuring MBLEN is Set Correctly:

    • Made sure that the MBLEN field is set to at least 1 to guarantee the address is sent.
    • Enabled BURSTRUN to start the operation.
  2. Adjusting i2c_start_read Function:

    • Flushed the RX FIFO and reset the transfer before setting the START condition.
    • Confirmed that only the START condition is set without initiating any data operations.

Despite these changes, the issue persists where DL_I2C_startControllerTransferAdvanced still automatically triggers a data read during the i2c_start_read phase, causing the read data clock to be generated unexpectedly.

Normal Behavior Example:

When executing i2c_start_read, the system should:

  1. Generate the START condition.
  2. Send out the target address (addr).
  3. Stop without generating the read data clock.
  4. Manually trigger the data read in the read phase.

Any Suggestions or Solutions?

How can I modify the I2C controller operations to ensure that during the start_read phase, only the START condition is generated without automatically initiating a data read? Is there a specific register setting or sequence of operations I might be missing?

Thanks in advance for your help!


Best regards,

Eason Tsai

  • Hi, 

    Stop without generating the read data clock.

    How this Stop works?

    Just stop sending clock and then waiting for i2c_read is called and then sending the read clock one byte by one byte?

    During the start_read phase, the function DL_I2C_startControllerTransferAdvanced automatically triggers a data read operation. This results in the read data clock being generated unexpectedly. Although the target address (addr) is being sent out, the data read should not start automatically at this stage.

    So in your test result, set len = 1 and MSPM0's I2C can not only send the I2C address but also first read byte included?

    What's the test result of setting len = 0? I2C won't send anything include address?

    Regards,

    Helic

  • Hi Helic,

    Thank you for your prompt response and suggestions.

    Regarding your questions:

    1. How the Stop works:

    Stop condition should terminate the I2C transaction after sending the START condition and the address. It shouldn't generate any read data clock until the i2c_read function is called to manually initiate data reading.

    2. Testing len settings:

    Setting len = 1:

    The I2C controller successfully sends out the target address (addr).
    However, it immediately triggers the read data clock, initiating a data read operation automatically, which is not desired at this stage.

    Setting len = 0:

    Surprisingly, the I2C controller still sends out the target address (addr).
    It also automatically triggers the read data clock, just like when len = 1. I expected that setting len = 0 might prevent the address from being sent, but it doesn't.

    Is there a way to configure the I2C controller so that during the start_read phase, it only generates the START condition and sends the target address without automatically initiating the data read? Are there specific register settings or a sequence of operations I might be missing?

    Thank you for your assistance!

    Best regards,

    Eason Tsai

  • Hi, 

    I will try this test from my side~

    Regards,

    Helic

  • Hi, 

    I have tried some method to avoid the first byte to be read from Target, all of them not work.

    Regards,

    Helic