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.

[MSP430FR5729][I2C][READ COMMAND/WRITE COMMAND]

Other Parts Discussed in Thread: MSP430FR5729

Hi,

I'm using MSP430FR5729 controller in CCS6.1.0 version.

In below code  i'll send one cmd from master and enabling Receiver interrupt.
At slave side first rx interrupt is enabled and after receiving one byte i'm enabling the Tx from slave.
when i execute this code is working fine and result i get is as expected.
This will fail if master sends WRITE cmd.
my doubt is how to send r/w bit from master and how to recognize command received is read or write.
Please suggest me the corrections to be made in my code so that the slave can respond to read / write command respectively.
Master Code:

#include <msp430fr5729.h>

//#define I2C_Master_Tx_Mode 1
#define I2C_Master_Rx_Mode 1

#define I2C_Flag_PEC (1<<0)
#define Max_data_count 4

void CRC8_add(unsigned char* crc, unsigned char data);
void I2C_Receive_data(unsigned char rx,unsigned char count);
void I2C_Master_Tx_mode(void);
void I2C_Master_Rx_mode(void);

static const unsigned char _CRC8_table[256] =
{
  0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24,
        0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48,
        0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc,
        0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90,
        0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4,
        0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff,
        0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab,
        0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27,
        0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03,
        0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f,
        0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80, 0x95,
        0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 0xf9,
        0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd,
        0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51,
        0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05,
        0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e,
        0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a,
        0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06,
        0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2,
        0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde,
        0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa,
        0xfd, 0xf4, 0xf3 };

//*****************************************************************************
// Add the next value to the CRC. The calculations are pre-done and stored in
// the above lookup table, this makes this a very fast operation at the expense
// of 256 bytes of code space.
//*****************************************************************************
void CRC8_add(unsigned char* crc, unsigned char data)
{
    *crc = _CRC8_table[*crc ^ data];
}	//	CRC8_add

enum
{
	ER_OK = 0,
	ER_CRC,
};

enum
{
	I2C_CMD = 0x00,
	I2C_Data_LSB,
	I2C_Data_MSB,
	I2C_Read_last,
	I2C_IDLE,
	I2C_Done,
};

struct I2Cstate
{
	unsigned char state;
	unsigned char addr;
	unsigned char cmd;
	unsigned char data[Max_data_count];
	unsigned char count;
	unsigned char PecCalculated;
	unsigned char PecReceived;
	unsigned char flags;

};

static volatile struct I2Cstate I2C;


#ifdef I2C_Master_Tx_Mode
//unsigned long TXData[8][2] ={{0x10,0x20},{0x11,0x5F},{0x12,0x36},{0x14,0x7B},{0x10,0x35},{0x11,0x54},{0x12,0x10},{0x14,0xE0}};                    // TX data Variable
//unsigned long TXData[4][2] ={{0x10,0x20},{0x11,0x5F},{0x12,0x36},{0x14,0x7B}};
 unsigned long TXData[6][3] ={{0x10,0x20,0x00},{0x12,0x30,0x00},{0x15,0x02,0x01},{0x15,0xF4,0x01},{0x15,0x7B,0x00},{0x15,0x24,0x00}};
#endif

#ifdef I2C_Master_Rx_Mode
 unsigned long TXData[6][3] = {{0x10,0x00,0x00},{0x10,0x00,0x00},{0x12,0x00,0x00},{0x13,0x00,0x00},{0x14,0x00,0x00},{0x15,0x00,0x00}};
#endif

unsigned char RXData[3];
unsigned char TXByteCtr;
unsigned char RXByteCtr;
unsigned char i=0,j=0;
unsigned char err;

void I2C_init(void)
{
	I2C.count = 4;			// Inital count value
	I2C.flags = 1;			// PEC Enabled
	I2C.state = I2C_IDLE;

}

void I2C_Master_Tx_mode(void)
{
	I2C.count = 4;			// Inital count value
	I2C.flags = 1;			// PEC Enabled
	I2C.state = I2C_IDLE;


}

void I2C_Master_Rx_mode(void)
{
	TXByteCtr = 1;
	I2C.flags = 1;			// PEC Enabled
	I2C.state = I2C_IDLE;
	I2C.count = 0;
}

void run_I2C(void)
{
	if(I2C.state == I2C_Done)
	{
		if((I2C.flags == I2C_Flag_PEC) && (I2C.PecCalculated!= I2C.PecReceived))
		{
			err = ER_CRC;		// CRC Error
		}
		else
		{
			err = ER_OK;		// Transcation is ok
		}

	}
}

void I2C_Receive_data(unsigned char rx,unsigned char count)
{
	if(count == 0)
	{
		I2C.data[0] = rx;
        if(I2C.flags & I2C_Flag_PEC)
        {
        	CRC8_add((unsigned char *) &I2C.PecCalculated, rx);
        }
	}
	else if(count == 1)
	{
		if(TXData[j][0] == 0x15)
		{
			I2C.data[1] = rx;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, rx);
			}
		}
		else
		{
			I2C.PecReceived = rx;
			I2C.state = I2C_Done;
			I2C.count = 0;
		}
	}
	else if (count == 2)
	{
		I2C.PecReceived = rx;
		I2C.state = I2C_Done;
		I2C.count = 0;
	}
}

int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;
    // Init SMCLK = MCLk = ACLK = 1MHz
    CSCTL0_H = 0xA5;
    CSCTL1 |= DCOFSEL0 + DCOFSEL1;          // Set max. DCO setting = 8MHz
    CSCTL2 = SELA_3 + SELS_3 + SELM_3;      // set ACLK = MCLK = DCO
    CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0;      // set all dividers to 1MHz
    // Configure Pins for I2C
    P1SEL1 |= BIT6 + BIT7;                  // Pin init

    UCB0CTLW0 |= UCSWRST;                   // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 + UCMST + UCSSEL_2;// I2C master mode, SMCLk
//    UCB0BRW = 0x8;                          // baudrate = SMCLK / 8
    UCB0I2CSA = 0x33;                       // address slave is 48hex
    UCB0CTLW0 &=~ UCSWRST;	            //clear reset register
    UCB0IE |= UCTXIE0 | UCRXIE0 | UCNACKIE;           //transmit, Receive and NACK interrupt enable
    __bis_SR_register(GIE);        // Enter LPM0 w/ interrupts
                                                     // Remain in LPM0 until all data
                                                     // is TX'd
//    UCB0CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition

	#ifdef I2C_Master_Tx_Mode
    I2C_Master_Tx_mode();
	#endif
	#ifdef I2C_Master_Rx_Mode
   		I2C_Master_Rx_mode();
	#endif

    while(1)
    {
    __delay_cycles(1000);                   // Delay between transmissions

	#ifdef I2C_Master_Tx_Mode
	{
		if(TXData[j][0] == 0x15)
		{
			TXByteCtr = 4;
		}
		else
		{
			TXByteCtr = 3;
		}

	while (UCB0CTLW0 & UCTXSTP);            // Ensure stop condition got sent
	run_I2C();

	UCB0CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition

	}
	#endif

	#ifdef I2C_Master_Rx_Mode
	{
		while (UCB0CTLW0 & UCTXSTP);            // Ensure stop condition got sent
		run_I2C();

		UCB0CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition
	}
	#endif

    __delay_cycles(10000000);
    __delay_cycles(10000000);
    __delay_cycles(10000000);
    __delay_cycles(10000000);


//    	TXData=0x10;
 //   TXData++;                               // Increment data byte
    }

}




#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  switch(__even_in_range(UCB0IV,0x1E))
  {
        case 0x00: break;                    // Vector 0: No interrupts break;
        case 0x02: break;
        case 0x04:
          UCB0CTLW0 |= UCTXSTT;             //resend start if NACK
          break;                            // Vector 4: NACKIFG break;
        case 0x16:
		#ifdef I2C_Master_Rx_Mode
        	if(RXByteCtr)
        	{
				if(RXByteCtr == 1)
				{
	        		UCB0CTLW0 |= UCTXSTP;           // I2C stop condition
				}
        		RXData[I2C.count] = UCB0RXBUF;
				I2C_Receive_data(RXData[I2C.count],I2C.count);
				I2C.count++;
				RXByteCtr--;
        	}
        	else
        	{
                UCB0IFG &= ~UCRXIFG;            // Clear USCI_B0 RX int flag
//        		UCB0CTLW0 |= UCTXSTP;           // I2C stop condition

//                UCB0CTLW0 |= UCTR + UCTXSTT;     // I2C TX, start condition
                i = 0;
                if(j==5)
                {
                	j = 0;
                }
                else
                {
                    j++;
                }
        	}
		#endif
          break;
        case 0x18:

		#ifdef I2C_Master_Tx_Mode
        {
          if(TXByteCtr)                    // Check TX byte counter
          {
		  	if(TXByteCtr == 1)
			{
//				UCB0TXBUF = _CRC8_table[I2C.PecCalculated ^ TXData[j][i]];             // Load TX buffer
		  		UCB0TXBUF = I2C.PecCalculated;             // Load TX buffer
				TXByteCtr--;                    // Decrement TX byte counter
				i = 0;
			}
		  	else
		  	{
				UCB0TXBUF = TXData[j][i];             // Load TX buffer
				if(I2C.flags & I2C_Flag_PEC)
				{
				   CRC8_add((unsigned char *) &I2C.PecCalculated,TXData[j][i]);
				}
				TXByteCtr--;                    // Decrement TX byte counter
				i++;
		  	}
          }
          else
          {
            UCB0CTLW0 |= UCTXSTP;           // I2C stop condition
            UCB0IFG &= ~UCTXIFG;            // Clear USCI_B0 TX int flag
            i=0;

            if(j==5)
            {
            	j = 0;
            }
            else
            {
                j++;
            }
//            __bic_SR_register_on_exit(CPUOFF);// Exit LPM0
          }
        }
		#endif

		#ifdef I2C_Master_Rx_Mode
        {
            if(TXByteCtr)                    // Check TX byte counter
            {
            	UCB0TXBUF = TXData[j][i];
            	if(TXData[j][0] == 0x15)
            	{
            		RXByteCtr = 3;
            	}
            	else
            	{
            		RXByteCtr = 2;
            	}
            	TXByteCtr--;
            }
            else
            {
            	UCB0IFG &= ~UCTXIFG;             		// Clear USCI_B0 TX int flag
            	UCB0CTLW0 &= ~UCTR;						// Clear I2C TX
                UCB0CTLW0 |=  UCTXSTT;            		// I2C RX, start condition
            }
        }
		#endif
          break;                            // Vector 26: TXIFG0 break;
        default: break;
  }
}



Slave Code:
#include <msp430fr5729.h>
#define SLAVEADD 0x33

//#define I2C_Slave_Rx_mode 1
#define I2C_Slave_Tx_mode 1
unsigned char TXData;
unsigned int TXByteCtr;
extern unsigned long RXData;
#define Max_data_count 4				// 1st byte cmd 2nd & 3rd byte data and 4th PEC
#define I2C_Flag_PEC (1<<0)
//unsigned char Batt1SOC_data, Batt2SOC_data, SystemStatus_data, PowerStatus_data, ErrorValue_data;
//unsigned int RemainingTime_data;
unsigned char Rxdata[3],Txdata[3],err;
extern unsigned int ui_batt1_soc,ui_batt2_soc,ui_sys_status_data,ui_pow_status,ui_err,ui_time_remain;
extern uchar write_cmd_recd;
void I2C_Receive_data(unsigned char Rx,unsigned char i);
void I2C_Transmit_data(void);
void I2C_display_cmd_data(unsigned char cmd, unsigned char *data);
unsigned char run_I2C(void);
void I2C_init(void);
enum
{
	IDLE				=	0x00,		//No Interrupt
	ARBITRATION_LOST	=	0X02,		//ALIFG
	NO_ACK				=	0X04,		//NACKIFG
	START_RECD			=	0x06,		//STTIFG
	STOP_RECD			=	0X08,		//STPIFG
	SLAVE3_DATA_RECD	=	0X0A,		//RXIFG3
	SLAVE3_TX_BUFF_EMP	=	0x0C,		//TXIFG3
	SLAVE2_DATA_RECD	=	0X0E,		//RXIFG2
	SLAVE2_TX_BUFF_EMP	=	0x10,		//TXIFG2
	SLAVE1_DATA_RECD	=	0X12,		//RXIFG1
	SLAVE1_TX_BUFF_EMP	=	0X14,		//TXIFG1
	DATA_RECD			=	0x16,		//RXIFG0
	TX_BUFF_EMP			=	0X18,		//TXIFG0
	BYTE_CNT_ZERO		=	0X1A,		//BCNTIFG
	CLK_LOW_TIMEOUT		=	0x1C,		//CLOCK LOW TIMEOUT
	NINTH_BIT_POSITION	=	0X1E		//9TH BIT

};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
enum
{
	ER_OK = 0,
	ER_CRC
};

enum
{
	I2C_CMD = 0x00,
	I2C_Data_LSB,
	I2C_Data_MSB,
	I2C_Read_last,
	I2C_IDLE,
	I2C_Done
};

struct I2Cstate
{
	unsigned char state;
	unsigned char cmd;
	unsigned char data[Max_data_count];
	unsigned char count;
	unsigned char PecCalculated;
	unsigned char PecReceived;
	unsigned char flags;

};

static volatile struct I2Cstate I2C;

void I2C_init(void)
{
	I2C.count = 0;			// Inital count value
	I2C.flags = 1;			// PEC Enabled
	I2C.state = I2C_IDLE;
}

unsigned char run_I2C(void)
{
	if(I2C.state == I2C_Done)
	{
		if((I2C.flags == I2C_Flag_PEC) && (I2C.PecCalculated!= I2C.PecReceived))
		{
			return ER_CRC;		// CRC Error
		}
		else
		{
			return ER_OK;		// Transcation is ok
		}

	}

}
/****************************************************************************************************************************************************
 * Function Name   : I2C_slaveinit
 * Purpose         : This function initialise the device as a I2C slave
 * Input           : Slave Address
 * Return          : None
 *****************************************************************************************************************************************************/
void I2C_slaveinit(unsigned char slave_address)
{

	P1SEL1 |= I2C_SDA + I2C_SCL;
//	Slave Config
	UCB0CTL1 |= UCSWRST;                      	// Enable SW reset
	UCB0CTLW0 = UCMODE_3 + UCSYNC;            	// I2C Slave, synchronous mode
	UCB0I2COA0 = slave_address+UCOAEN;               	// set own (slave) address
	UCB0CTL1 &= ~UCSWRST;                     	// Clear SW reset, resume operation
	UCB0IE |= UCRXIE0;     			// Enable Rx interrupt Enable						
	ui_batt1_soc=50;						
	ui_batt2_soc=80;						
	ui_sys_status_data=0x35;				
	ui_pow_status=0x00;						
	ui_err=989;							
	ui_time_remain=314;						
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void)
{
	  switch(__even_in_range(UCB0IV,0x1E))
	    {
	      case IDLE:

	    	  break;                     		// Vector 0: No interrupts break;

	      case ARBITRATION_LOST:

	    	  break;                     		// Vector 2: ALIFG break;

	      case NO_ACK:

	    	  break;                     		// Vector 4: NACKIFG break;

	      case START_RECD:

 	    	  break;                     		// Vector 6: STTIFG break;

	      case STOP_RECD:

	    	  UCB0IFG &= ~UCSTPIFG;				// Clear stop condition int flag
	    	  UCB0IE &=  ~UCTXIE0;						//------R

	    	  break;     		                // Vector 8: STPIFG break;

	      case SLAVE3_DATA_RECD:

	    	  break;            		         // Vector 10: RXIFG3 break;

	      case SLAVE3_TX_BUFF_EMP:

	    	  break;                    		 // Vector 14: TXIFG3 break;

	      case SLAVE2_DATA_RECD:

	    	  break;                     		// Vector 16: RXIFG2 break;

	      case SLAVE2_TX_BUFF_EMP:

	    	  break;                     		// Vector 18: TXIFG2 break;

	      case SLAVE1_DATA_RECD:

	    	  break;                     		// Vector 20: RXIFG1 break;

	      case SLAVE1_TX_BUFF_EMP:

	    	  break;                     		// Vector 22: TXIFG1 break;

	      case DATA_RECD:

			#ifdef I2C_Slave_Rx_mode
			{
				Rxdata[I2C.count] = UCB0RXBUF;                 // Get RX data
				I2C_Receive_data(Rxdata[I2C.count],I2C.count);
				I2C.count++;
				if(Rxdata[0] == 0x15)
				{
					if(I2C.count == 4)
					{
					  I2C.count = 0;
					  I2C_display_cmd_data(I2C.cmd, &I2C.data);
					}
				}
				else
				{
					if(I2C.count == 3)
					{
					  I2C.count = 0;
					  I2C_display_cmd_data(I2C.cmd, &I2C.data);
					}
				}
				break;                              // Vector 24: RXIFG0 break;
			}
			#endif

			#ifdef I2C_Slave_Tx_mode
			{
				Rxdata[0] = UCB0RXBUF;                 // Get RX data
				if(Rxdata[0] == 0x15)
				{
					TXByteCtr = 3;
				}
				else
				{
					TXByteCtr = 2;
				}
				UCB0IE |=  UCTXIE0;						
				 UCB0IFG &= ~UCTXIFG;						
				break;                              // Vector 24: RXIFG0 break;						
			}
			#endif

	      case TX_BUFF_EMP:

			#ifdef I2C_Slave_Tx_mode
			{

				I2C_Transmit_data();
			}
			#endif

	    	  break;		                     // Vector 26: TXIFG0 break;

	      case BYTE_CNT_ZERO:

	    	  break;                     // Vector 28: BCNTIFG break;

	      case CLK_LOW_TIMEOUT:

	    	  break;                     // Vector 30: clock low timeout break;

	      case NINTH_BIT_POSITION:

	    	  break;                     // Vector 32: 9th bit break;

	      default:

	    	  break;

	    }

}

void I2C_Transmit_data(void)
{

	if(Rxdata[0] == 0x10)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else
		{
			UCB0TXBUF = ui_batt1_soc;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ui_batt1_soc);
			}
			TXByteCtr--;
		}
	}
	else if(Rxdata[0] == 0x11)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else if(TXByteCtr == 2)
		{
			UCB0TXBUF = ui_batt2_soc;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ui_batt2_soc);
			}
			TXByteCtr--;
		}
	}
	else if(Rxdata[0] == 0x12)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else
		{
			UCB0TXBUF = ui_sys_status_data;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ui_sys_status_data);
			}
			TXByteCtr--;
		}
	}
	else if(Rxdata[0] == 0x13)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else
		{
			UCB0TXBUF = ui_pow_status;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ui_pow_status);
			}
			TXByteCtr--;
		}
	}
	else if(Rxdata[0] == 0x14)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else
		{
			UCB0TXBUF = ui_err;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ui_err);
			}
			TXByteCtr--;
		}
	}
	else if(Rxdata[0] == 0x15)
	{
		if(TXByteCtr == 1)
		{
			UCB0TXBUF = I2C.PecCalculated;
			TXByteCtr--;
		}
		else if (TXByteCtr == 2)
		{
			UCB0TXBUF = ((ui_time_remain & 0xFF00)>>8);
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, ((ui_time_remain & 0xFF00)>>8));
			}
			TXByteCtr--;
		}
		else if (TXByteCtr == 3)
		{
			UCB0TXBUF = (ui_time_remain & 0x00FF);
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, (ui_time_remain & 0x00FF));
			}
			TXByteCtr--;
		}
	}

}
void I2C_Receive_data(unsigned char rx,unsigned char count)
{
	if(count == I2C_CMD)
	{
//		if(I2C.state == I2C_IDLE)
		{
			I2C.cmd = rx;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, I2C.cmd);
			}
		}
	}
	else if(count == I2C_Data_LSB)
	{
		I2C.data[0] = rx;
        if(I2C.flags & I2C_Flag_PEC)
        {
        	CRC8_add((unsigned char *) &I2C.PecCalculated, rx);
        }
	}
	else if(count == I2C_Data_MSB)
	{
		if(I2C.cmd == 0x15)
		{
			I2C.data[1] = rx;
			if(I2C.flags & I2C_Flag_PEC)
			{
				CRC8_add((unsigned char *) &I2C.PecCalculated, rx);
			}
		}
		else
		{
			I2C.PecReceived = rx;
			I2C.state = I2C_Done;
		}
	}
	else if (count == I2C_Read_last)
	{
		I2C.PecReceived = rx;
		I2C.state = I2C_Done;
	}
}

void I2C_display_cmd_data(unsigned char cmd, unsigned char *data)
{

	if(cmd == BAT1_SOC)
	{
		ui_batt1_soc = data[0];
		write_cmd_recd = 1;
	}

	else if(cmd == BAT2_SOC)
	{
		ui_batt2_soc = data[0];
		write_cmd_recd = 1;
	}
	else if(cmd == SYS_STATUS)
	{
		ui_sys_status_data = data[0];
		write_cmd_recd = 1;
	}
	else if(cmd == POW_STATUS)
	{
		ui_pow_status = data[0];
		write_cmd_recd = 1;
	}
	else if(cmd == ERROR_VAL)
	{
		ui_err = data[0];
		write_cmd_recd = 1;
	}
	else if(cmd == REM_TIME)
	{
		ui_time_remain = ((data[1]<<8)+data[0]);
		write_cmd_recd = 1;
	}
}


  • Hello Ramesh,

    Most I2C slave devices solve this issue by having two different slave addresses, one for write commands and one for read commands.  The MSP430FR5729 code examples package provides an example of a single FR5729 device leveraging multiple slave addresses, you could use this as a starting point for your application:

    MSP430FR57xx_uscib0_i2c_Master_MultiSlave.c
    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *******************************************************************************
     * 
     *                       MSP430 CODE EXAMPLE DISCLAIMER
     *
     * MSP430 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
     * for an API functional library-approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //******************************************************************************
    //  MSP430FR57xx Demo - USCI_B0 I2C Master TX bytes to Multiple Slaves
    //
    //  Description: This demo connects two MSP430's via the I2C bus. 
    //  The master transmits to 4 different I2C slave addresses 0x0A,0x0B,0x0C&0x0D.
    //  Each slave address has a specific related data in the array TXData[].
    //  At the end of four I2C transactions the slave address rolls over and begins 
    //  again at 0x0A.
    //  ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz
    //  Use with MSP430FR57xx_uscib0_i2c_MultiSlave.c
    //
    //                                /|\  /|\
    //                MSP430FR5739    10k  10k     MSP430FR5739
    //                   slave         |    |         master
    //             -----------------   |    |   -----------------
    //           -|XIN  P1.6/UCB0SDA|<-|----+->|P1.6/UCB0SDA  XIN|-
    //            |                 |  |       |                 |
    //           -|XOUT             |  |       |             XOUT|-
    //            |     P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL     |
    //            |                 |          |                 |
    //
    //   P. Thanigai
    //   Texas Instruments Inc.
    //   August 2010
    //   Built with CCS V4 and IAR Embedded Workbench Version: 5.10
    //******************************************************************************
    #include <msp430.h>
    
    unsigned char TXData[]= {0xA1,0xB1,0xC1,0xD1};// Pointer to TX data
    unsigned char SlaveAddress[]= {0x0A,0x0B,0x0C,0x0D};                         
    unsigned char TXByteCtr;
    unsigned char SlaveFlag = 0;
    
    int main(void)
    
    {
        WDTCTL = WDTPW + WDTHOLD;
        // Init SMCLK = MCLk = ACLK = 1MHz
        CSCTL0_H = 0xA5;
        CSCTL1 |= DCOFSEL0 + DCOFSEL1;          // Set max. DCO setting = 8MHz
        CSCTL2 = SELA_3 + SELS_3 + SELM_3;      // set ACLK = MCLK = DCO
        CSCTL3 = DIVA_3 + DIVS_3 + DIVM_3;      // set all dividers to 1MHz
    
        // Configure Pins for I2C
        P1SEL1 |= BIT6 + BIT7;                  // Pin init
    
        UCB0CTLW0 |= UCSWRST;                   // put eUSCI_B in reset state
        UCB0CTLW0 |= UCMODE_3 + UCMST + UCSSEL_2;// I2C master mode, SMCLk 
        UCB0BRW = 0x8;                          // baudrate = SMCLK / 8
        UCB0CTLW0 &=~ UCSWRST;	            //clear reset register
        UCB0IE |= UCTXIE0 + UCNACKIE;           //transmit and NACK interrupt enable
        SlaveFlag =0;
        while(1)
        {
        UCB0I2CSA = SlaveAddress[SlaveFlag];    // configure slave address
        TXByteCtr = 1;                          // Load TX byte counter              
        while (UCB0CTLW0 & UCTXSTP);            // Ensure stop condition got sent
        UCB0CTLW0 |= UCTR + UCTXSTT;            // I2C TX, start condition
    
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
                                                // Remain in LPM0 until all data
                                                // is TX'd
        // Change Slave address
        SlaveFlag++; 
        if (SlaveFlag>3)                        // Roll over slave address
          {
            SlaveFlag =0;
            __delay_cycles(1000);               // Delay between transmissions
          }
       
        }
    	
    }
    
    
    
    	
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B0_VECTOR 
    __interrupt void USCIB0_ISR(void) 
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {	
      switch(__even_in_range(UCB0IV,0x1E)) 
      {
            case 0x00: break;                   // Vector 0: No interrupts break;
            case 0x02: break;
            case 0x04:
              UCB0CTLW0 |= UCTXSTT;             //resend start if NACK
              break;                            // Vector 4: NACKIFG break;
            case 0x06: break;                   // Vector 6: STTIFG break;
            case 0x08: break;                   // Vector 8: STPIFG break;
            case 0x0a: break;                   // Vector 10: RXIFG3 break;
            case 0x0c: break;                   // Vector 14: TXIFG3 break;
            case 0x0e: break;                   // Vector 16: RXIFG2 break;
            case 0x10: break;                   // Vector 18: TXIFG2 break;
            case 0x12: break;                   // Vector 20: RXIFG1 break;
            case 0x14: break;                   // Vector 22: TXIFG1 break;
            case 0x16: break;                   // Vector 24: RXIFG0 break;  
            case 0x18: 
    	  if (TXByteCtr)                    // Check TX byte counter
              {
                UCB0TXBUF = TXData[SlaveFlag];  // Load TX buffer
                TXByteCtr--;                    // Decrement TX byte counter
              }
              else
              {
                UCB0CTLW0 |= UCTXSTP;           // I2C stop condition
                UCB0IFG &= ~UCTXIFG;            // Clear USCI_B0 TX int flag
                __bic_SR_register_on_exit(CPUOFF);// Exit LPM0
              }
              break;                            // Vector 26: TXIFG0 break;
            default: break;
      }
    }
    	
    

    MSP430FR57xx_uscib0_i2c_MultiSlave.c
    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *******************************************************************************
     * 
     *                       MSP430 CODE EXAMPLE DISCLAIMER
     *
     * MSP430 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
     * for an API functional library-approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //******************************************************************************
    //  MSP430FR57xx Demo - USCI_B0 I2C 4 Hardware I2C slaves
    //
    //  Description: This demo connects two MSP430's via the I2C bus. 
    //  This code configures the MSP430 USCI to be addressed as 4 independent I2C
    //  slaves. Each slave has its owm interrupt flag and data variable to store
    //  incoming data. 
    //  Use with MSP430FR57xx_uscib0_i2c_Master_MultiSlave.c
    //  ACLK = n/a, MCLK = SMCLK = default DCO = ~1.045MHz
    //
    //                                /|\  /|\
    //                MSP430FR5739    10k  10k     MSP430FR5739
    //                   slave         |    |         master
    //             -----------------   |    |   -----------------
    //           -|XIN  P1.6/UCB0SDA|<-|----+->|P1.6/UCB0SDA  XIN|-
    //            |                 |  |       |                 |
    //           -|XOUT             |  |       |             XOUT|-
    //            |     P1.7/UCB0SCL|<-+------>|P1.7/UCB0SCL     |
    //            |                 |          |                 |
    //            |                 |          |                 |
    //
    //   P. Thanigai
    //   Texas Instruments Inc.
    //   August 2010
    //   Built with CCS V4 and IAR Embedded Workbench Version: 5.10
    //******************************************************************************
    
    #include <msp430.h>
    
    unsigned char RXData0=0;  
    unsigned char RXData1=0;
    unsigned char RXData2=0;
    unsigned char RXData3=0;
    
    int main(void)
    
    {
    	
        WDTCTL = WDTPW + WDTHOLD;
    
        // Init SMCLK = MCLk = ACLK = 1MHz
        CSCTL0_H = 0xA5;
        CSCTL1 |= DCOFSEL0 + DCOFSEL1;          // Set max. DCO setting = 8MHz
        CSCTL2 = SELA_3 + SELS_3 + SELM_3;      // set ACLK = MCLK = DCO
        CSCTL3 = DIVA_3 + DIVS_3 + DIVM_3;      // set all dividers to 1MHz
    
        // Configure Pins for I2C
        P1SEL1 |= BIT6 + BIT7;                  // Pin init
        // eUSCI configuration
        UCB0CTLW0 |= UCSWRST ;	            //Software reset enabled
        UCB0CTLW0 |= UCMODE_3  + UCSYNC;	    //I2C mode, sync mode
        UCB0I2COA0 = 0x0A + UCOAEN;   	    //SLAVE0 own address is 0x0A+ enable
        UCB0I2COA1 = 0x0B + UCOAEN;   	    //SLAVE1 own address is 0x0B+ enable	
        UCB0I2COA2 = 0x0C + UCOAEN;   	    //SLAVE2 own address is 0x0C+ enable	
        UCB0I2COA3 = 0x0D + UCOAEN;   	    //SLAVE3 own address is 0x0D+ enable	
    
        UCB0CTLW0 &=~UCSWRST;	            //clear reset register
        UCB0IE |=  UCRXIE0 + UCRXIE1+ UCRXIE2 + UCRXIE3;//receive interrupt enable	
    	
        __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts
        __no_operation();	 
    }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B0_VECTOR 
    __interrupt void USCIB0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    
    {
    
       switch(__even_in_range(UCB0IV,0x1E))
        {
          case 0x00: break;                     // Vector 0: No interrupts break;
          case 0x02: break;                     // Vector 2: ALIFG break;
          case 0x04: break;                     // Vector 4: NACKIFG break;
          case 0x06: break;                     // Vector 6: STTIFG break;
          case 0x08: break;                     // Vector 8: STPIFG break;
          case 0x0a:                            // SLAVE3
            RXData3 = UCB0RXBUF; 
            break;                              // Vector 10: RXIFG3 break;
          case 0x0c: break;                     // Vector 14: TXIFG3 break;
          case 0x0e:                            // SLAVE2
            RXData2 = UCB0RXBUF;
            break;                              // Vector 16: RXIFG2 break;
          case 0x10: break;                     // Vector 18: TXIFG2 break;
          case 0x12:                            // SLAVE1
            RXData1 = UCB0RXBUF;
            break;                              // Vector 20: RXIFG1 break;
          case 0x14: break;                     // Vector 22: TXIFG1 break;
          case 0x16:                            // SLAVE0
            RXData0 = UCB0RXBUF;                // Get RX data
            break;                              // Vector 24: RXIFG0 break;
          case 0x18: break;                     // Vector 26: TXIFG0 break;
          case 0x1a: break;                     // Vector 28: BCNTIFG break;
          case 0x1c: break;                     // Vector 30: clock low timeout break;
          case 0x1e: break;                     // Vector 32: 9th bit break;
          default: break;	
        }
    	
    }	
    
    
    

    Regards, Ryan

**Attention** This is a public forum