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.

EXP-MSP430FR5994 Use eUSCI_B2 for I2C. TX Interrupt flag is not set.

Other Parts Discussed in Thread: MSP430FR5994, CC2511

Hi. all

I use MSP430FR5994 LaunchPad Development Kit .  eUSCI_B0 are used for connection with SD Card. So, I want use eUSCI_B2 for i2C bus.

I use example code from 'driverlib' for i2c master multibyte transmission. I fixed the code for use with eUSCI_B2 (Port7. Pin0=SDA, Pin1-SCL).

But my code is not working. 

After these commands:
......

 //Send start condition.
    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;   
     
    
      //Send single byte data.
    HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
    
    //Reinstate transmit interrupt enable
    HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;

 __bis_SR_register(GIE);

In this point Tx Interrup flag must be set by eUSCI teh, but this is not happening. ((

I already have pull-up resistors on the SDA and SCL lines. My slave unit  working fine  with CC2511 using I2C bus.

What's wrong with my code (or with MCU?)

Thank you.

My code is listed below:

void main(void)
{
    WDT_A_hold(WDT_A_BASE);

    //Set DCO frequency to 1MHz
    CS_setDCOFreq(CS_DCORSEL_0,CS_DCOFSEL_0);
    //Set ACLK = VLO with frequency divider of 1
    CS_initClockSignal(CS_ACLK,CS_VLOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    //Set SMCLK = DCO with frequency divider of 1
    CS_initClockSignal(CS_SMCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    //Set MCLK = DCO with frequency divider of 1
    CS_initClockSignal(CS_MCLK,CS_DCOCLK_SELECT,CS_CLOCK_DIVIDER_1);

    // Configure Pins for I2C
    //Set P1.6 and P1.7 as Secondary Module Function Input.
    /*

     * Select Port 1
     * Set Pin 6, 7 to input Secondary Module Function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
     */
    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_P7,
        GPIO_PIN0 + GPIO_PIN1,
        GPIO_SECONDARY_MODULE_FUNCTION
        );

    /*
     * Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */
    PMM_unlockLPM5();

    EUSCI_B_I2C_initMasterParam param = {0};
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk = CS_getSMCLK();
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
    param.byteCounterThreshold = 0;
    param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
    EUSCI_B_I2C_initMaster(EUSCI_B2_BASE, &param);

    //Specify slave address
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B2_BASE,
                                SLAVE_ADDRESS
                                );

    //Set Master in receive mode
    EUSCI_B_I2C_setMode(EUSCI_B2_BASE,
                        EUSCI_B_I2C_TRANSMIT_MODE
                        );

    //Enable I2C Module to start operations
    EUSCI_B_I2C_enable(EUSCI_B2_BASE);

    EUSCI_B_I2C_clearInterrupt(EUSCI_B2_BASE,
                               EUSCI_B_I2C_TRANSMIT_INTERRUPT2 +
                               EUSCI_B_I2C_NAK_INTERRUPT
                               );
    
    //Enable master Receive interrupt
    EUSCI_B_I2C_enableInterrupt(EUSCI_B2_BASE,
                                EUSCI_B_I2C_TRANSMIT_INTERRUPT2 +
                                EUSCI_B_I2C_NAK_INTERRUPT
                                );
    
    
   
    while(1)
    {
        __delay_cycles(1000);               // Delay between transmissions
        TXByteCtr = 24;                      // Load TX byte counter
        TXData = 0;

        while(EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent
                  (EUSCI_B2_BASE))
        {
            ;
        }

        EUSCI_B_I2C_masterSendMultiByteStart(EUSCI_B2_BASE,
                                             LcdInitString[i]);

        __bis_SR_register(GIE);    // Enter LPM0 w/ interrupts
        // Remain in LPM0 until all data
        // is TX'd
        // Increment data byte
    }
}

//------------------------------------------------------------------------------
// The USCIAB0TX_ISR is structured such that it can be used to transmit any
// number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData
// points to the next byte to transmit.
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B2_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B2_VECTOR)))
#endif
void USCIB2_ISR(void)
{
    switch(__even_in_range(UCB2IV,0x1E))
    {
    case 0x00: break;                                // Vector 0: No interrupts break;
    case 0x02: break;
    case 0x04:
        //resend start if NACK
        EUSCI_B_I2C_masterSendStart(EUSCI_B2_BASE);
        break;                                // Vector 4: NACKIFG break;
    case 0x18:
        if(TXByteCtr)                         // Check TX byte counter
        {
          
            EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B2_BASE,
                                                LcdInitString[i]);
            i++;
            TXByteCtr--;                        // Decrement TX byte counter
        }
        else
        {
            EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B2_BASE);

            __bic_SR_register_on_exit(CPUOFF);    // Exit LPM0
        }
        break;                                // Vector 26: TXIFG0 break;
    default: break;
    }
}

void EUSCI_B_I2C_masterSendMultiByteStart(uint16_t baseAddress,
                                          uint8_t txData)
{
    //Store current transmit interrupt enable
    uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE2;

    //Disable transmit interrupt enable
    HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE2);

    //Send start condition.
    HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;   
     
    
      //Send single byte data.
    HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
    
    //Reinstate transmit interrupt enable
    HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;

   
    /*
            //Poll for transmit interrupt flag.
    while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG2))
    {
        ;
    }
*/ 
    

}

  • Hi Alex,

    The first issue is that UCB2 is the primary module on P7.0 & P7.1 (Table 6-33 of the Datasheet). The second is that in master mode with own address disabled and only one slave device connected, the TXIFG0 flag should be used (Section 26.3 of the User's Guide). There could be more issues beyond these recommendations.

    Regards,
    Ryan

**Attention** This is a public forum