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.

MSP430FG6426: I2C pulled low after transmission - making the bus busy

Part Number: MSP430FG6426

Hi,

I'm trying to bring up the I2C peripheral on an MSP430FG6426 in slave mode (BeagleBoneBlack - BBB is master).

What I know:

1. I can used "i2cdetect -y 1" on BBB to detect MSP and other devices on the bus.

2. I can transfer data on the same I2C bus from another device to the BBB.

3. When I execute the read I get the chars below. "`abcdpqrst" are the chars I'm expecting and I get exactly 64 bytes again as expected.

Address: 0x55
rx_len: 64
Data:
`abcdpqrst`abcdpqrst`abcdpqrst`abcdpqrst`abcdpqrst`abcdpqrst`abc
omap_i2c 4802a000.i2c: controller timed out
Error: Connection timed out (os error 110)
omap_i2c 4802a000.i2c: timeout waiting for bus ready
Error: Connection timed out (os error 110)

4. From the scope I can clearly see that both SCL & SDA are pulled low. The moment I reset the MSP SCL & SDA returns to 3.29V, indicating that in fact the MSP is holding it low.

5. I'm using a slightly modified driverlib example code (usci_b_i2c_ex4_slaveTxMultiple.c) with TI compiler v21.6 LTS. Biggest modifications: 1. it is not alone (while loop is not here), 2. I'm using USCI_B1. For clarity here is the whole code

#define SLAVE_ADDRESS 0x55

#define TXLENGTH 0x09

uint8_t transmitData[] = { 0x60, 0x61, 0x62, 0x63, 0x64,
                           0x70, 0x71, 0x72, 0x73, 0x74};
uint8_t *transmitDataPointer;
uint8_t transmitLength = TXLENGTH;

//38.3.4.1.1 I2C Slave Transmitter Mode
void i2c_init(void)
{
    //Assign I2C pins to USCI_B1
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P8, GPIO_PIN5 + GPIO_PIN6);

    //Initialize I2C as a slave device
    USCI_B_I2C_initSlave(USCI_B1_BASE, SLAVE_ADDRESS);

    //Set in transmit mode
    USCI_B_I2C_setMode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE);

    //Enable I2C Module to start operations
    USCI_B_I2C_enable(USCI_B1_BASE);

    //Enable master transmit interrupt
    USCI_B_I2C_clearInterrupt(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT + USCI_B_I2C_STOP_INTERRUPT);
    USCI_B_I2C_enableInterrupt(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT + USCI_B_I2C_STOP_INTERRUPT);

    transmitDataPointer = transmitData;
    transmitLength = TXLENGTH;

    //Enter low power mode 0 with interrupts enabled.
//        __bis_SR_register(LPM0_bits + GIE);
//        __no_operation();
}

//******************************************************************************
//
//This is the USCI_B1 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B1_VECTOR)))
#endif
void USCI_B1_ISR(void)
{
    uint16_t iv = UCB1IV;
    USCI_A_UART_transmitData(USCI_A0_BASE, iv + 0x61);

    switch (__even_in_range(iv, 12))
    {
    case USCI_I2C_UCSTPIFG:
        //Exit LPM0 if data was transmitted
        __bic_SR_register_on_exit(LPM0_bits);
        break;
    case USCI_I2C_UCTXIFG:
        //Transmit data
        //if (transmitLength > 0x00)
        {
            USCI_B_I2C_slavePutData(USCI_B1_BASE, *transmitDataPointer++);
            //transmitLength--;
            if (transmitDataPointer >= (transmitData+10))
            {
                transmitDataPointer = transmitData;
            }
        }

        break;
    default:
        break;
    }
}

Questions:

1. Why are both the SCL & SDA pulled low?

2. Separately how can I indicate to master that I have nothing to send? Do I just send 0x0 or 0x20 and on the other end that should mean I should not be asking anymore?

3. Is there a way to force MSP to release I2C bus?

  • Here is a scope plot of the event:

    100ms resolution. It looks like the transmission happens, then about 30ms later MSP pulls it low.

  • Hi Peter,

    I am expected to give some feedbacks on next Monday, thanks for your patience!

    B.R.

    Sal

  • Hi Sal,

    I'm looking forward to it.

    I've been reading up on the topic and found a few conditions when the bus can stall, like when I receive a character but don't read the from the buffer. But I don't even now how that would be possible given I don't setup i2c like that.

    Also potentially related how do I debug an isr_trap? Is there a way to figure out what interrupt got triggered? I only have i2c interrupt and ctsd16 enabled.

    Cheers,

    Peter

  • 've been reading up on the topic and found a few conditions when the bus can stall, like when I receive a character but don't read the from the buffer. But I don't even now how that would be possible given I don't setup i2c like that.

    Since you configured as a slave you had better be prepared to receive data because it is up to the master. If it sends, and you have no code to handle that case there will be trouble.

  • Hi Peter,

    Sorry for the late response.

    I've been reading up on the topic and found a few conditions when the bus can stall, like when I receive a character but don't read the from the buffer.

    David gives the clarification and it is described in user's guide:

    1. Why are both the SCL & SDA pulled low?

    Have the master generate the STOP signal? if not the slave will pull them low:

    2. Separately how can I indicate to master that I have nothing to send?

    I think generate the STOP signal is OK for this.

    3. Is there a way to force MSP to release I2C bus?

    My suggestion is that - you can use a timer that count the time of bus forced, if MSP force the I2C bus longer than specific time, use timer interrupt isr to reset I2C bus and re-configure it. Or something like this.

    B.R.

    Sal

  • Thanks for the info. Yes it was receiving characters, which my code was not handling. I think it would make sense to include these in the example codes.

  • Hi Peter,

    I will close this thread and feel free to post new thread in the forum if you have any other issues.

    Have a good day.

    B.R.

    Sal

**Attention** This is a public forum