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 stuck waiting for tx interrupt flag or start condition flag

Part Number: MSP432E401Y


I opening this issue again.  The previous one is here:

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/967908/msp432p401r-i2c-stuck-waiting-for-tx-interrupt-flag-or-start-condition-flag

It has been closed but I really didnt see a fix for it.

I am using the same flavor as the link above but portal does not recognize anymore because it has been "EOL'd"

I recently was having issues with the repeat start condition but this has been resolved,

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1201698/msp432-debuggers-msp432p401r-cannot-get-i2c-repeated-start-condition-to-work-properly/4546672#4546672

However I now run across the stuck condition described above after I2C peripheral has been idle for a while, like 15 minutes and I try to access our KT_MIcro FM Modulator chip to change FM channels and it locks up there while doing a repeated start condition.  You can see the Scope capture showing the start condition of previous write and then then the peripheral hangs.   There is no clock or data.  

void FMTuneFreq(uint16_t frequency) {
    //CHSEL[11:0] = Reg0x1[2:0] : Reg0x0[7:0] : Reg0x2[7]
    uint8_t reg1 = 0, reg2 = 0, reg3 = 0;
    uint8_t u8Buff[2];

    frequency = frequency / 5;

    //Reg0x0[7:0]
    FM_TXDATA[0] = 0x00;
    FM_TXDATA[1] = (frequency & 0x01FE) >> 1;
    FMAPI_I2C_ISR_MultiWrite();

    //Reg0x1[2:0]
    FM_TXDATA[0] = 0x01;

    if (FMAPI_I2C_ISR_WriteRead(FM_TXDATA[0], &reg1) == SUCCESS) {
        FM_TXDATA[1] = (reg1 & 0xF8 ) | ((frequency & 0x0E00) >> 9);
        FMAPI_I2C_ISR_MultiWrite();
    }

uint8_t FMAPI_I2C_ISR_WriteRead(uint8_t TXData, uint8_t * data)
{
    uint8_t status = SUCCESS;

    /* Send out start + address + 1 data byte */
    I2C_masterSendMultiByteStart(EUSCI_B0_BASE, TXData);   //Removed MAP_

   //wait for first byte to be moved to shift register
   while(!(EUSCI_B0->IFG & EUSCI_B_IFG_TXIFG));
   EUSCI_B0->IFG &= ~(EUSCI_B_IFG_TXIFG);

   // Before the restart is sent, app has to wait for current TX byte + ack to complete
   // This takes 9 cycles at 100kHz = 90uS
   // The MCLK default = ~3MHz
   // to complete the 1 byte TX app needs to wait ~270 MCLK cycles at a minimum
   __delay_cycles(2500);

   //clear the TR bit to setup master as receiver
   EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_TR);
   // Send the start + address
   EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTT;

   __delay_cycles(500);    //250 before

   // wait for address to be sent
   while(!(EUSCI_B0->CTLW0 & EUSCI_B_CTLW0_TXSTT));
   // set stop immediately to ensure only one byte is read
   EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
   // poll RX flag
   while(!(EUSCI_B0->IFG & EUSCI_B_IFG_RXIFG0));
   // Read from Receive buffer
   *data = EUSCI_B0->RXBUF;
   // ensure I2C transaction has completed
   while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE));


    return(status);
}

I dont think a delay is going to fix this problem because unlike the repeat start condition issue , adding delays wont fix this issue.  Its almost like the peripheral is locked up and needs to be reinitialized.

I am running the I2C at 100Mhz and MCLK is running 24Mhz.