MSPM0G1507: Unexplained data transmit during I2C Controller Operation

Part Number: MSPM0G1507


Hi experts,

My customer has created a prototype board using the MSPM0G1507, but they have observed unexplained behavior in the I2C controller.
The phenomenon is that once communication fails, subsequent attempts either fail or transmit values different from what is intended.

Q1: In I2C controller mode, could you explain cases where the process does not complete (with data remaining in the shift register) and the state transitions to IDLE?
If there are similar known cases, please share them.
Like this:(+) MSPM0G3507: I2C controller mode handling NACK - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums 

Q2: Also, when the state described in Q1 occurs, what is the recommended recovery procedure?
Currently, after entering I2CController_ Read/Write(), they has added the following reset process.

DL_I2C_reset(I2C1_INST);
DL_I2C_enablePower(I2C1_INST);
SYSCFG_DL_I2C1_init(); 

The root cause is still under investigation, but we suspect something around the power supply.
We assume that some error occurred during communication, leaving data in the shift register, and the process exited prematurely.
The code structure monitors the I2C controller state and waits until the state becomes IDLE before ending the process.
They also added checks for flags such as TxDONE, but the phenomenon did not change.

Please let us know if any additional information is needed.

Best regards,
O.H

  • Hi O.H.

    Would you be able to further describe how your I2c communication is implemented? Or if possible, can you send your application code for us to try to recreate the issues you're observing?

    Best Regards,
    Brian

  • Hi Brain,

    Sharing the program is limited to the following scope. (After checking the waveforms, we believe the cause is that I²C communication is occurring during the power ramp-up.)
    At this point, what they want to confirm is whether the following countermeasure is appropriate, or if there is a better approach.
    I’m sorry the information is limited, but could you share your thoughts?
    bool ***_I2CController_Write(uint8_t target_addr, uint8_t mem_addr, uint8_t* buffer, uint8_t length){
        // ...
        
        // I2C reset (added as a workaround for the issue)
        DL_I2C_reset(I2C1_INST);
        DL_I2C_enablePower(I2C1_INST);
        SYSCFG_DL_I2C1_init();
    
        // ... (setting mem_addr and write data into s_tx_packet)
    
        s_tx_count = DL_I2C_fillControllerTXFIFO(I2C1_INST, &s_tx_packet[0], s_tx_len); 
        // Note: s_tx_packet already contains mem_addr and write data
    
        // ... (includes status register checks)
    
        DL_I2C_startControllerTransfer(I2C1_INST, target_addr, DL_I2C_CONTROLLER_DIRECTION_TX, s_tx_len);
    
        // ... (includes status register checks)
    }
    
    bool ***_I2CController_Read(uint8_t target_addr, uint8_t mem_addr, uint8_t* buffer, uint8_t length){
        // ...
        
        // I2C reset (added as a workaround for the issue)
        DL_I2C_reset(I2C1_INST);
        DL_I2C_enablePower(I2C1_INST);
        SYSCFG_DL_I2C1_init();
    
        // ... (setting mem_addr into s_tx_packet)
    
        s_tx_count = DL_I2C_fillControllerTXFIFO(I2C1_INST, &s_tx_packet[0], s_tx_len); 
        // Note: s_tx_packet already contains mem_addr
    
        // ... (includes status register checks)
    
        DL_I2C_startControllerTransfer(I2C1_INST, target_addr, DL_I2C_CONTROLLER_DIRECTION_TX, s_tx_len); 
        // Note: transmit mem_addr
    
        // ... (includes status register checks)
    
        DL_I2C_startControllerTransfer(I2C1_INST, target_addr, DL_I2C_CONTROLLER_DIRECTION_RX, s_rx_len); 
        // Note: receive
    
        // Harvest read data
        while (s_rx_count < s_rx_len) {
            if (!DL_I2C_isControllerRXFIFOEmpty(I2C1_INST)) {
                s_rx_packet[s_rx_count] = DL_I2C_receiveControllerData(I2C1_INST); 
                // Note: collect the received data
                s_rx_count++;
            }
        }
    
        // ... (includes status register checks)
    }
    
    Best regards,
    O.H
  • Hi O.H,

    This is a valid workaround, but I would recommend waiting to initialize the I2C module until after the power ramp up. A delay could be added when first initializing the peripherals, or an ADC can be used to monitor the supply and once a threshold is met, initialize I2C.

    Best Regards,
    Brian