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.

UART does not work if i2c is initialized.

Hi i am using MSP430FR2522IRHLR. I2C and UART as different projects works fine. When i try to integrate them uart fails.

i.e. UART works fine until i2c is not initialized . If i2c Initialized then uart sends garbage on serial terminal.

Below is my code:

#include <msp430.h> 
#include "eusci_b_i2c.h"
#include "eusci_a_uart.h"
#include "gpio.h"
#include "cs.h"


/*-------------------------------------- MACROS ----------------------------------------*/

#define LCD_BACKLIGHT         0x08
#define LCD_NOBACKLIGHT       0x00
#define LCD_FIRST_ROW         0x80
#define LCD_SECOND_ROW        0xC0
#define LCD_THIRD_ROW         0x94
#define LCD_FOURTH_ROW        0xD4
#define LCD_CLEAR             0x01
#define LCD_RETURN_HOME       0x02
#define LCD_ENTRY_MODE_SET    0x04
#define LCD_CURSOR_OFF        0x0C
#define LCD_UNDERLINE_ON      0x0E
#define LCD_BLINK_CURSOR_ON   0x0F
#define LCD_MOVE_CURSOR_LEFT  0x10
#define LCD_MOVE_CURSOR_RIGHT 0x14
#define LCD_TURN_ON           0x0C
#define LCD_TURN_OFF          0x08
#define LCD_SHIFT_LEFT        0x18
#define LCD_SHIFT_RIGHT       0x1E
#define LCD_TYPE              2 // 0 -> 5x7 | 1 -> 5x10 | 2 -> 2 lines

#define RX_BUFF_LENGTH      200
#define SLAVE_ADDRESS       0x27;
/*--------------------------------------------------------------------------------------*/



/*-------------------------------------VARIABLES----------------------------------------*/
unsigned char RS, i2c_add, BackLight_State = LCD_BACKLIGHT;
volatile uint8_t TXByteCtr;
volatile uint8_t TXData[200] = {0};
volatile uint8_t index =0;



volatile uint8_t RX_BUFF[ RX_BUFF_LENGTH ] ={0};
volatile uint16_t RX_INDEX = 0 ;
volatile uint8_t RX_AVAILABLE = 0 ;

/*--------------------------------------------------------------------------------------*/


/*--------------------------------FUNCTION DECLARATION----------------------------------*/
void LCD_Write_4Bit(unsigned char Nibble);
void LCD_CMD(unsigned char CMD);
void LCD_Write_Char(char Data);
void LCD_Write_String(char* Str);
void Backlight();
void noBacklight();
void LCD_SL();
void LCD_SR();
void LCD_Clear();
void LCD_Init(unsigned char I2C_Add);
void LCD_Set_Cursor(unsigned char ROW, unsigned char COL);
void IO_Expander_Write(unsigned char Data);


void I2C_INIT(void);
void I2C_write(uint8_t data);

uint8_t UART_INITALIZATION( void );
void UART_TRANSMIT_DATA( uint8_t *data , uint16_t data_len );;
void CLEAR_BUFF( uint8_t * data , uint16_t data_len );;
void DIR_RX(void);
void DIR_TX(void);



/*--------------------------------------------------------------------------------------*/
/**
 * main.c
 */
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
 
UART_INITALIZATION();
delay_ms(1000);
UART_TRANSMIT_DATA("ROHAN1234566",12);
I2C_INIT();
UART_TRANSMIT_DATA("ROHAN1234566",12);
LCD_Init(0x27);
    LCD_Set_Cursor(1, 1);
    LCD_Write_String("ROHAN");
    LCD_Set_Cursor(2, 1);
    LCD_Write_String(" 27 C");

__enable_interrupt();
while(1)
{

}

return 0;
}


/*--------------------------------FUNCTION DEFINATION-----------------------------------*/

/*-----------------------------------LCD FUNCTIONS--------------------------------------*/
void I2C_write(uint8_t data)
{




    EUSCI_B_I2C_masterSendSingleByte (EUSCI_B0_BASE,data);

    while (EUSCI_B_I2C_SENDING_STOP == EUSCI_B_I2C_masterIsStopSent(EUSCI_B0_BASE));
    delay_ms(5);
   // while( TXByteCtr );
}

void IO_Expander_Write(unsigned char Data)
{

    EUSCI_B_I2C_masterSendSingleByte (EUSCI_B0_BASE,Data | BackLight_State);

}



void LCD_Write_4Bit(unsigned char Nibble)
{
  // Get The RS Value To LSB OF Data
  Nibble |= RS;
  IO_Expander_Write(Nibble | 0x04);
  IO_Expander_Write(Nibble & 0xFB);
 // delay_ms(50);
}

void LCD_CMD(unsigned char CMD)
{
  RS = 0; // Command Register Select
  LCD_Write_4Bit(CMD & 0xF0);
  LCD_Write_4Bit((CMD << 4) & 0xF0);
}

void LCD_Write_Char(char Data)
{
  RS = 1; // Data Register Select
  LCD_Write_4Bit(Data & 0xF0);
  LCD_Write_4Bit((Data << 4) & 0xF0);
}

void LCD_Write_String(char* Str)
{
    int i = 0 ;
  for(i=0; Str[i]!='\0'; i++)
  {
    LCD_Write_Char(Str[i]);

  }
}


void Backlight()
{
  BackLight_State = LCD_BACKLIGHT;
  IO_Expander_Write(0);
}

void noBacklight()
{
  BackLight_State = LCD_NOBACKLIGHT;
  IO_Expander_Write(0);
}


void LCD_SL()
{
  LCD_CMD(0x18);
  delay_ms(40);
}


void LCD_SR()
{
  LCD_CMD(0x1C);
  delay_ms(40);
}

void LCD_Clear()
{
  LCD_CMD(0x01);
  delay_ms(40);
}


void LCD_Init(unsigned char I2C_Add)
{
  i2c_add = I2C_Add;
  IO_Expander_Write(0x00);
  delay_ms(30);
  LCD_CMD(0x03);
 // delay_ms(5);
  LCD_CMD(0x03);
 // delay_ms(5);
  LCD_CMD(0x03);
 // delay_ms(5);
  LCD_CMD(LCD_RETURN_HOME);
 // delay_ms(5);
  LCD_CMD(0x20 | (LCD_TYPE << 2));
//  delay_ms(50);
  LCD_CMD(LCD_TURN_ON);
//  delay_ms(50);
  LCD_CMD(LCD_CLEAR);
 // delay_ms(50);
  LCD_CMD(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
 // delay_ms(50);
}


void LCD_Set_Cursor(unsigned char ROW, unsigned char COL)
{
  switch(ROW)
  {
    case 2:
      LCD_CMD(0xC0 + COL-1);
      break;
    case 3:
      LCD_CMD(0x94 + COL-1);
      break;
    case 4:
      LCD_CMD(0xD4 + COL-1);
      break;
    // Case 1
    default:
      LCD_CMD(0x80 + COL-1);
  }
}

/*--------------------------------------------------------------------------------------*/

/*-----------------------------------I2C FUNCTION---------------------------------------*/
void I2C_INIT(void)
{

    GPIO_setAsPeripheralModuleFunctionInputPin(
    GPIO_PORT_P1,
                                               GPIO_PIN2 | GPIO_PIN3,
                                               GPIO_PRIMARY_MODULE_FUNCTION);




    EUSCI_B_I2C_initMasterParam param;
    param.autoSTOPGeneration = EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG;
    param.byteCounterThreshold = 1;
    param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
    param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
    param.i2cClk =CS_getSMCLK();
    //param.i2cClk = CS_getMCLK();
    //msclk = CS_getMCLK();

    EUSCI_B_I2C_initMaster( EUSCI_B0_BASE ,&param);
    EUSCI_B_I2C_setSlaveAddress( EUSCI_B0_BASE, 0x27);
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_MODE);
    EUSCI_B_I2C_enable(EUSCI_B0_BASE);
    EUSCI_B_I2C_clearInterrupt( EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
    EUSCI_B_I2C_enableInterrupt( EUSCI_B0_BASE,EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

    PM5CTL0 &= ~LOCKLPM5;
}

/*---------------------------------------------------------------------------------------*/

/*-----------------------------------UART FUNCTION---------------------------------------*/
uint8_t UART_INITALIZATION( void )
{

    GPIO_setAsPeripheralModuleFunctionOutputPin(
            GPIO_PORT_P1,                       // UART TX 1,
            GPIO_PIN4,                          // UCA0TXD,
            GPIO_PRIMARY_MODULE_FUNCTION
    );

    GPIO_setAsPeripheralModuleFunctionInputPin(
            GPIO_PORT_P1,                       // UART RX 1,
            GPIO_PIN5,                          // UCA0RXD,
            GPIO_PRIMARY_MODULE_FUNCTION
    );



    EUSCI_A_UART_initParam param = {0};

    param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
    param.clockPrescalar = 104;//104 => 9600;  26 => 38400;  17 => 57600; 8 => 115200
    param.firstModReg = 0;
    param.secondModReg = 0xD6;
    param.parity = EUSCI_A_UART_NO_PARITY;
    param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
    param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
    param.uartMode = EUSCI_A_UART_MODE;
    param.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;

    if (STATUS_FAIL == EUSCI_A_UART_init(EUSCI_A0_BASE, &param)) {
        return 0;
    }

    EUSCI_A_UART_enable(EUSCI_A0_BASE);

    // Clear USCI_A1 RX interrupt
    EUSCI_A_UART_clearInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    // Enable USCI_A1 RX interrupt
    EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

    GPIO_setAsOutputPin (GPIO_PORT_P1, GPIO_PIN6);
    GPIO_setAsOutputPin (GPIO_PORT_P1, GPIO_PIN7);


    DIR_TX();

    return 1;

}
void UART_TRANSMIT_DATA( uint8_t *data , uint16_t data_len )
{
    uint16_t i;
    for(  i= 0 ; i < data_len ; i++ )
    {
        EUSCI_A_UART_transmitData( EUSCI_A0_BASE , data[i] );
        //delay(8);
    }
}



void CLEAR_BUFF( uint8_t * data , uint16_t data_len )
{
    uint16_t i = 0;

    for( i = 0; i < data_len ; i++ )
    {
        data[ i ] = 0;
    }
}
void DIR_TX(void)
{
    GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6);
    GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);
}

void DIR_RX(void)
{
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);
}

/*--------------------------------------------------------------------------------------*/



/*--------------------------------------------------------------------------------------*/
void delay_ms(unsigned int ms)
{
    volatile unsigned int i;
    for (i = 0; i<= ms; i++)
       __delay_cycles(1000); // 6000 will give us 1ms
    //(1/6MHz)*X=1ms         MCLK= 6MHz (MCLK is the source for delay cycles)
    //X=6000....this gives 1 ms
}
/*--------------------------------------------------------------------------------------*/


/*-----------------------------------INTERRUPT------------------------------------------*/
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_B0_VECTOR)))
#endif
void USCIB0_ISR(void)
{
    switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
    {
        case USCI_NONE:             // No interrupts break;
            break;
        case USCI_I2C_UCALIFG:      // Arbitration lost
            break;
        case USCI_I2C_UCNACKIFG:    // NAK received (master only)
            // Resend START if NAK'd
            EUSCI_B_I2C_masterSendStart(EUSCI_B0_BASE);
            index=0;
            break;
        case USCI_I2C_UCSTTIFG:     // START condition detected with own address (slave mode only)
            break;
        case USCI_I2C_UCSTPIFG:     // STOP condition detected (master & slave mode)
            break;
        case USCI_I2C_UCRXIFG3:     // RXIFG3
            break;
        case USCI_I2C_UCTXIFG3:     // TXIFG3
            break;
        case USCI_I2C_UCRXIFG2:     // RXIFG2
            break;
        case USCI_I2C_UCTXIFG2:     // TXIFG2
            break;
        case USCI_I2C_UCRXIFG1:     // RXIFG1
            break;
        case USCI_I2C_UCTXIFG1:     // TXIFG1
            break;
        case USCI_I2C_UCRXIFG0:     // RXIFG0
            break;
        case USCI_I2C_UCTXIFG0:     // TXIFG0
            // Check TX byte counter
           if (TXByteCtr)
            {
                EUSCI_B_I2C_masterSendMultiByteNext(EUSCI_B0_BASE,
                    TXData[index]);
                index = index+1;
                // Decrement TX byte counter
                TXByteCtr--;
            }
            else
            {
                EUSCI_B_I2C_masterSendMultiByteStop(EUSCI_B0_BASE);
                // Exit LPM0
                index=0;
                //__bic_SR_register_on_exit(CPUOFF);
            }
            break;
        case USCI_I2C_UCBCNTIFG:    // Byte count limit reached (UCBxTBCNT)
            break;
        case USCI_I2C_UCCLTOIFG:    // Clock low timeout - clock held low too long
            break;
        case USCI_I2C_UCBIT9IFG:    // Generated on 9th bit of a transmit (for debugging)
            break;
        default:
            break;
  }
}




#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_A1_VECTOR)))
#endif
void EUSCI_A1_ISR(void)
{

    switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
    {
    case USCI_NONE: break;
    case USCI_UART_UCRXIFG:

        // Clear USCI_A1 RX interrupt
        EUSCI_A_UART_clearInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);

        RX_AVAILABLE = 1;

        if( RX_INDEX < RX_BUFF_LENGTH)
        {
            RX_BUFF[ RX_INDEX++ ] = EUSCI_A_UART_receiveData(EUSCI_A0_BASE);
        }
        else
        {
            RX_INDEX = 0;
        }


        GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6);

            // Enable USCI_A1 RX interrupt
        EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
        break;

    case USCI_UART_UCTXIFG: break;
    case USCI_UART_UCSTTIFG: break;
    case USCI_UART_UCTXCPTIFG: break;
    }
}


/*--------------------------------------------------------------------------------------*/

  • Hello,

    When posting code to the forum, please utilize the Insert <-> button to format the code to be readable on the forum. I've edited your post to reflect this change.

    If by initializing your I2C, your UART is not working, then you need to check the functions you are using to setup each peripheral. You can use the debugger to monitor if the eUSCI settings change for either module being used. Also make sure to check if your pin assignments are getting over written as well. 

    One other thing to check is your clock settings after your initialization. Your functions here maybe changing clock settings in order to hit specific I2C speeds or UART baud rates, without considering other module needs. You will need to map out your clocks to make sure if both these modules use the same base clock, that your dividers are set correctly to meet your communication speeds.

  • hi Jace,

    Thank you for replying. sorry for wrong format of code. 

    as you said i checked the clock setting and clock is getting changed i have added screenshots of following

    after uart init and before i2c init:

    https://photos.google.com/share/AF1QipPYm_yRW2eMO5sDjkIQjovmM7-llm_LfDlxTHUBpXw_6fMj9NyAyWypdmmyqxFqsg?key=blFtMXlTS0hac3Y4eWtJazczUHFyZEtKaEFhdnhn

    https://photos.app.goo.gl/khMvhhPbS2kqvknJ9

    after uart init and i2c init:

    https://photos.app.goo.gl/nGmQotutuHHsZp918

    https://photos.app.goo.gl/jam1Y37ziwgbWzhu5

    can you guide me how to map clock?

  • Hello,

    Your initialization functions are conflicting when it comes to setting up the clocks. You would need to modify those in order to make sure only one sets the clock, and those settings are good for both. Ideally, your init functions would only setup the settings of the respective USCIs themselves, and you initial the clocks in a  separate function/section in order to handle being able to support the end frequencies you need.

    Alternatively you can have them operate on different sub clocks (SMCLK - I2C / ACLK - UART), but that depends on your system as a whole and requirements for other modules.

    If you do want to use the same clock domain, back calculate the minimum clock frequency you need for each module. Then find a a common frequency multiple you can utilize with the given dividers. You may need to iterate your module clock dividers to find common ground. Making the subclock you are using faster typically makes finding a common frequency easier, with the tradeoff of more current consumption. I would start with your I2C needs, then back track to UART settings. We also provide a handy table in the user guide (UART Chapter) of different UART settings for common baud rates at various input clock frequencies. 

    So basically, separate out your clock system initialization form your UART/I2C initialization to avoid conflicts here. 

  • Hi Jace thank your for your solution.

    It worked. and sorry for the late reply.

**Attention** This is a public forum