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.

MSP430F5419A: I2C communication problem with EEPROM

Expert 1060 points

Part Number: MSP430F5419A

Hi experts,

I have I2C communication problem with EEPROM.

I've referred to the E2E reference And Application Note slaa208a

http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/636507/2352597?tisearch=e2e-sitesearch&keymatch=MSP430F5419A eeprom#2352597

But I still couldn't find the what is the problem of Read/Write operation.

Please find the attached file to lookup the source.

//==========================================================
//  Subroutine for EEPROM 24C04
//
//==========================================================
#include <msp430.h> 

#include <Project.h>

#define	BYTE_READ		0xa1		// Serial eeprom Read command
#define	BYTE_WRITE		0xa0		// Serial eeprom Write command

/*
#define	SetSDA()		pSDA = 1
#define	ResSDA()		pSDA = 0
#define	ChkSDA()		pSDA
#define	SetSCL()		pSCL = 1
#define	ResSCL()		pSCL = 0
*/

void SetSDA(void);
void ResSDA(void);
uint8_t ChkSDA(void);
void SetSCL(void);
void ResSCL(void);

void _SendStart(void);
void _SendStop(void);
uint8_t _SendData(uint8_t dat);
void _ReadData(uint8_t *dat);
uint8_t _SendAddr(uint8_t dat);

uint8_t ReadEprom(uint16_t addr, uint8_t *rdata);
uint8_t WriteEprom(uint16_t addr, uint8_t wdata);



//==========================================================
void SetSDA(void)
{
	P3DIR &= EEPROM_SDA;
	P3OUT |= EEPROM_SDA;
}

void ResSDA(void)
{
	P3DIR &= EEPROM_SDA;
	P3OUT &= ~EEPROM_SDA;
}

uint8_t ChkSDA(void)
{
	uint8_t tSDA;
	
	P3DIR &= ~EEPROM_SDA;
	tSDA = (P3IN & EEPROM_SDA) >> 1;
	
	return tSDA;
}

void SetSCL(void)
{
	P3DIR &= EEPROM_CLK;
	P3OUT |= EEPROM_CLK;
}

void ResSCL(void)
{
	P3DIR &= EEPROM_CLK;
	P3OUT &= ~EEPROM_CLK;
}

void _SendStart(void)			// Start condition
{
	SetSDA();
	SetSCL();
	ResSDA();
	ResSCL();
}

void _SendStop(void)				// Stop condition
{
	ResSCL();
	ResSDA();
	SetSCL();
	SetSDA();
}

uint8_t _SendData(uint8_t dat)
{
	uint8_t ack;
	uint8_t	i;

	for (i=0; i<8; i++){			// Write 8 bit
		if (dat & 0x80) SetSDA();
		else            ResSDA();
		SetSCL();
		ResSCL();
		dat <<= 1;
	}

	SetSDA();						// Check ACK
	SetSCL();
	if (!ChkSDA()) ack = 1;
	else           ack = 0;
	ResSCL();

	return ack;
}

void _ReadData(uint8_t *dat)
{
	uint8_t	i;
	uint8_t	rdat = 0;

	SetSDA();						// Read 8 bit
	for (i=0; i<8; i++){
		rdat <<= 1;
		SetSCL();
		if (ChkSDA()) rdat |= 1;
		ResSCL();
	} /* endfor */

	SetSCL();						// Check ACK
	ResSCL();

	*dat = rdat;
}

uint8_t _SendAddr(uint8_t dat)			// Send address
{
	_SendStart();
	return (_SendData(dat));		// return ACK
}

//==========================================================
uint8_t ReadEprom(uint16_t addr, uint8_t *rdata)
{
    uint8_t ack;
	uint8_t	bank;
	uint8_t	dat;
	uint8_t	retry = 50;

	bank = (addr >> 7) & 0x0e;
	addr &= 0xff;

	do {
		ack = _SendAddr(BYTE_WRITE | bank);
	} while ( !ack && --retry );

	if (ack){
		_SendData(addr);
		_SendStart();
		_SendData(BYTE_READ | bank);
		_ReadData(&dat);
	}
	_SendStop();

	if (ack) *rdata = dat;
	return(ack);
	
	//*rdata = dat;
	//return(ack);
}

uint8_t WriteEprom(uint16_t addr, uint8_t wdata)
{
	uint8_t ack;
	uint8_t bank;
	uint8_t retry = 20;

	bank = (addr >> 7) & 0x0e;
	addr &= 0xff;

	do {
		ack = _SendAddr(BYTE_WRITE | bank);
	} while ( !ack && --retry );

	if (ack){
		_SendData(addr);
		_SendData(wdata);
	}
	_SendStop();

	return(ack);
}

/*
//=======================================================================
//	Load & Save Setup value
//=======================================================================
uint8_t LoadEprom(void)
{
	uint8_t	*dp, chksum = 0;
	uint16_t	i;

	dp = (uint8_t *)&setup;
	for (i=0; i<sizeof(setup); i++){
		ReadEprom(i, dp);
		chksum += *dp++;
	}
	if (chksum) return 0;
	return 1;
}

//------------------------------------------------------------------------
void	UpdateEprom(void)
{
	uint8_t	*dp, chksum = 0;
	uint16_t	i;

	dp = (uint8_t *)&setup;
	for (i=0; i<sizeof(setup)-1; i++){
		WriteEprom(i, *dp);
		chksum += *dp++;
	}
	WriteEprom(i, ~chksum + 1);
}
*/

#include <msp430.h>				

#include <project.h>




// general variable
volatile uint16_t SysTick=0;
uint16_t Delay10msec=0;

uint8_t Blink_CNT;

uint8_t SEC_CNT;

uint8_t	DIS_SecTimer=0;
uint8_t DIS_mSecTimer=0;


volatile uint8_t BFND_DisplayFlag=0;		// system Big FND Display On/Off Flag

volatile uint8_t FlowFlag;
volatile uint8_t I2CBuffer;

volatile int PtrTransmit;
volatile uint8_t I2CBufferArray[10];


// External variable
extern volatile uint16_t Comp_3minTimer; // timer, 60 x 3 = 180sec
extern volatile uint32_t HotGas_Timer;	// timer, 60 x 60 x 20 = 72000sec (20 hours) 
extern volatile uint8_t Cur_CoinCNT;		// M. count

extern volatile uint16_t HotGas_OnTimer;

extern volatile uint8_t VendMagicNumber;

extern volatile uint8_t Pick_SecTimer;

// External function
extern void S_FND(uint8_t Num);
extern void Init_TimerB(void);		// FND Swing
extern void ADC_Start(void);

extern void COIN_Check(void);
extern void Key_SCAN(void);
extern void FRONT_Check(void);
extern void Limit_Check(void);

extern void Main_Process(void);

extern void Relay_CTRL(uint8_t Relay_CH,uint8_t OnOff);
extern void BillCounter_(uint8_t OnOff);

// function define
void SetVcoreUp(unsigned int level);
void Init_GPIO(void);
void Init_Clock(void);
void Init_UART0(void);		// for debug
void Init_TimerA(void);		// system tick
void Init_ADC(void);		// for temp sensor

void Init_I2C(void);		// for EEPROM

void I2CWriteInit(void);
void I2CReadInit(void);

void EEPROM_ByteWrite(uint16_t Address, uint8_t Data);
uint8_t EEPROM_ByteRead(uint16_t Address);
void EEPROM_AckPolling(void);


//extern uint8_t ReadEprom(uint16_t addr, uint8_t *rdata);
//extern uint8_t WriteEprom(uint16_t addr, uint8_t wdata);

void Delay_10msec(uint16_t DelayCNT);

// test define
extern volatile uint16_t temp_ADC;
extern volatile uint16_t volt;
extern volatile uint16_t volt_old;
extern volatile uint8_t  temp_dir;

extern volatile int8_t   Sen_Cel;

extern void Volt2Cel(uint16_t SenVolt);

extern void Display_BFND(uint16_t B_Num);
extern void Display_sFND(uint16_t s_Num);

extern void Display_PatEdge(uint8_t pat,uint8_t dir);
extern void Display_Obounce(void);
extern void Display_8Shift(void);
extern void Display_Bill(uint8_t CurBill);
extern void Display_VendQty(uint8_t VendQty);
extern void Display_Err(void);
extern void Display_Temp(void);
/**
 * main.c
 */
void main(void)
{
	volatile uint8_t tSTEP=0;

	volatile uint8_t ptdata[1];
	
	uint8_t seq_no=0;//,tACK;//,toggle=1;


	WDTCTL = WDTPW | WDTHOLD;		// stop watchdog timer

	// Clock initial
	Init_Clock();

	// port initial
	Init_GPIO();

	// timer initial
	Init_TimerA();		// system tick
	Init_TimerB();		// FND Swing
	
	// adc initial
	Init_ADC();		// for temp sensor
	
	// Uart0 initial ; Debug
	Init_UART0();

	// I2C initial
	Init_I2C();
	
	printf("\r\n\r\n ******** \r\n");
	
	__enable_interrupt();
	
	BillCounter_(DISABLE);

	EEPROM_ByteWrite(0x0001, 0x9a);
	EEPROM_AckPolling();					// Wait for EEPROM write cycle
	
//	EEPROM_ByteWrite(0x0002, 0xbc);
//	EEPROM_AckPolling();					// Wait for EEPROM write cycle

	//tACK=WriteEprom(0x0001, 0x9a);
	//printf("\r\neeprom write test 0x001 ACK [%d]\r\n",tACK);
	//tACK=WriteEprom(0x0002, 0xbc);
	//printf("\r\neeprom write test 0x002 ACK [%d]\r\n",tACK);

	tSTEP=0;
	tSTEP = EEPROM_ByteRead(0x0001);
	printf("\r\neeprom read test 0x001 [0x%x]\r\n",tSTEP);

//	tSTEP=0;
//	tSTEP = EEPROM_ByteRead(0x0002);
//	printf("\r\neeprom read test 0x002 [0x%x]\r\n\n",tSTEP);

	//tACK=ReadEprom(0x0001, ptdata);
	//printf("\r\neeprom read test 0x001 [ACK : %d][0x%x]\r\n",tACK,ptdata[0]);
	
	//tACK=ReadEprom(0x0002, ptdata);
	//printf("\r\neeprom read test 0x002 [ACK : %d][0x%x]\r\n",tACK,ptdata[0]);
	
	tSTEP=0;
	
	while(1)
	{
		Main_Process();
		
// system tick soft timer
		if(SysTick == 10)	// 100msec
		{
			SysTick = 0;
			
			DIS_mSecTimer++;
			
			Blink_CNT++;	// board led blink 

			SEC_CNT++;

			if(SEC_CNT == 10)
			{
				SEC_CNT=0;
			
				ADC_Start();		
				Comp_3minTimer++;
				HotGas_Timer++;
				HotGas_OnTimer++;
				
				DIS_SecTimer++;
				Pick_SecTimer++;
				
				Display_Temp();
			}

			if(BFND_DisplayFlag == 1)	// Big FND Display ON (IDLE State)
			{
				uint8_t Seq[10][3]={//{speed,pattern number,display time(sec)}
									{1,1,5},	// 100msec,1led cw,5sec
									{2,1,5},	// 200msec,1led cw,5sec

									{1,2,5},	// 100msec,1led ccw,5sec
									{2,2,5},	// 200msec,1led ccw,5sec

									{1,3,5},	// 100msec,2led cw,5sec
									{2,3,5},	// 200msec,2led cw,5sec

									{1,4,5},	// 100msec,2led ccw,5sec
									{2,4,5},	// 200msec,2led ccw,5sec
									
									{2,5,10},	// 200msec,O bounce,10sec

									{2,6,20}	// 200msec,8 shift,10sec
											};
				
				if(Seq[seq_no][0] == DIS_mSecTimer)
				{
					DIS_mSecTimer = 0;

					switch(Seq[seq_no][1])
					{
						case 1:
							Display_PatEdge(1,1);		// back ground fnd display
						break;

						case 2:
							Display_PatEdge(1,2);		// back ground fnd display
						break;

						case 3:
							Display_PatEdge(2,1);		// back ground fnd display
						break;

						case 4:
							Display_PatEdge(2,2);		// back ground fnd display
						break;
						
						case 5:
							Display_Obounce();
						break;
						
						case 6:
							Display_8Shift();
						break;
					}

					if(Seq[seq_no][2] == DIS_SecTimer)
					{
						DIS_SecTimer = 0;
						
						seq_no++;
						
						if(seq_no == 10)
							seq_no=0;
					}
				}
			}
			
//			if(BFND_DisplayFlag == 2)	// Big FND Display ON (Bill State)
			else if(BFND_DisplayFlag == 2)	// Big FND Display ON (Bill State)
			{
				Display_Bill(Cur_CoinCNT);	// display
			}
			
			else if(BFND_DisplayFlag == 3)
			{
				// display
				Display_VendQty(VendMagicNumber);
			}

			else if(BFND_DisplayFlag == 4)
			{
				// error status
				Display_Err();
			}
		}

		if(Blink_CNT == 5)
		{
			Blink_CNT = 0;
			
			P1OUT ^= 0x80;		// board led blink 
/*			
			toggle ^= 1;

			if(toggle == 1)
			{
//			    EEPROM_ByteWrite(0x0001, 0xaa);

//				Delay_10msec(10);

			    EEPROM_ByteWrite(0x0002, 0x55);

				Delay_10msec(10);
			}

			else if(toggle == 0)
			{
				toggle = EEPROM_ByteRead(0x0001);
				printf("\r\neeprom read test 0x001 [0x%x]\r\n",toggle);
				toggle = 0;

				Delay_10msec(10);
				
				toggle = EEPROM_ByteRead(0x0002);
				printf("\r\neeprom read test 0x002 [0x%x]\r\n",toggle);
				toggle = 0;

				Delay_10msec(10);				
			}
*/
		}
	}
}

void Init_Clock(void)
{
	SetVcoreUp(PMMCOREV_1);
	SetVcoreUp(PMMCOREV_2);					// Set VCore to 1.8MHz for 20MHz

	P11DIR = BIT2 + BIT1 + BIT0;			// P11.2,1,0 to output direction
	P11SEL = BIT2 + BIT1 + BIT0;			// P11.2 to output SMCLK, P11.1
											// to output MCLK and P11.0 to
											// output ACLK
	P5SEL |= 0x0C;							// Port select XT2
	P7SEL |= 0x03;							// Port select XT1

	UCSCTL6 &= ~(XT1OFF + XT2OFF);			// Set XT1 & XT2 On
	UCSCTL6 |= XCAP_3;						// nternal load cap

	// Loop until XT1,XT2 & DCO stabilizes
	do
	{
		UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
											// Clear XT2,XT1,DCO fault flags
		SFRIFG1 &= ~OFIFG;					// Clear fault flags
	}while(SFRIFG1&OFIFG);					// Test oscillator fault flag

	UCSCTL6 &= ~XT2DRIVE0;					// Decrease XT2 Drive according to
											// expected frequency
//	UCSCTL4 |= SELA_0 + SELS_5;						// Select SMCLK, ACLK source and DCO source
	UCSCTL4 |= SELA_0 + SELS_5 + SELM__XT2CLK;		// Select SMCLK, ACLK source and DCO source
}

void Init_GPIO(void)
{
    P1DIR |= BD_LED;		// p1.7 output 0x80
    P1OUT &= ~BD_LED;		// board led on

	P2DIR = 0x00;			// key

	P3DIR |= EEPROM_WP|EEPROM_SDA|EEPROM_CLK;     // P3.0 output 0x01 i2c , uart0 use
	P3OUT &= ~EEPROM_WP;  // eeprom wp low

	P4DIR |= (FND_DP|FND_G|FND_F|FND_E|FND_D|FND_C|FND_B|FND_A);        // all output 0xff
	P4OUT = 0x80;
    
//	P5DIR = ;				// uart1 use

	P6DIR |= (M2_N|M2_P|M1_N|M1_P);		// P6.0 ,adc 0 use // P6.7 ~ P6.4 output 0xf0
	P6OUT = 0x00;						// motor initial stop

	P7DIR |= SPEAKER_EN;		// p7.2 output 0x04
	P7OUT |= SPEAKER_EN;		// speaker enable high

	P8DIR |= (B_DIG4|DIG1|DIG2|DIG3|DIG4);//|COIN_STOP4);	// P8.7, 8.4, 8.3, 8.2, 8.1, 8.0 output 0x8f
	P8OUT = 0xff;

	P9DIR |= (B_DIG1|B_DIG2|B_DIG3);		// P9.2, 9.1, 9.0 output 0x07 uart2 use
	P9OUT = 0xff;
	
	P10DIR |= (HOTGAS_CTRL|FAN_CTRL|COMP_CTRL|COIN_STOP5);		// P10.2, 10.1, 10.0 output // P10.4 P10.3 input
	P10OUT = 0x00;		// relay low ; relay drive tr(npn) off
}

void Init_UART0(void)	// for debug
{
	P3SEL |= 0x30;			// P3.4,5 = USCI_A0 TXD/RXD

	UCA0CTL1 |= UCSWRST;	// **Put state machine in reset**

	UCA0CTL1 |= UCSSEL_2;	// SMCLK
	UCA0BR0 = 104;			// 12MHz 115200 (see User's Guide)
	UCA0BR1 = 0;			// 12MHz 115200

	UCA0MCTL |= (UCBRS_1|UCBRF_0);		// Modulation UCBRSx=1, UCBRFx=0

  	UCA0CTL1 &= ~UCSWRST;		// **Initialize USCI state machine**
	
	UCA0IE &= ~(UCRXIE);		// Disable USCI_A0 RX interrupt
}

void Init_ADC(void)		// for temp sensor
{
	ADC12CTL0 = ADC12SHT02 + ADC12ON;	// Sampling time, ADC12 on
	ADC12CTL1 = ADC12SHP;				// Use sampling timer
	ADC12IE = 0x01;						// Enable interrupt
	ADC12CTL0 |= ADC12ENC;
  
	P6SEL |= 0x01;						// P6.0 ADC option select
}

#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void)
{
	uint16_t tVolt;
	
	switch(__even_in_range(ADC12IV,34))
	{
		case  0: break;					// Vector  0:  No interrupt
		case  2: break;					// Vector  2:  ADC overflow
		case  4: break;					// Vector  4:  ADC timing overflow
		case  6:						// Vector  6:  ADC12IFG0

			temp_ADC = ADC12MEM0;

//			printf("ADC ; 0x%x ",temp_ADC);
			
			tVolt = (uint16_t)(((uint32_t)temp_ADC*3300)/0xFFF);
//			printf("Volt ; %d.%d%d%dV [0x%x] ",tVolt/1000,tVolt%1000/100,tVolt%1000%100/10,tVolt%1000%100%10,tVolt);

			Volt2Cel(tVolt);
//			printf("Temp : %dC[%s]\r\n",Sen_Cel,(temp_dir==1) ? "up" : "down");

		break;
		default: break; 
	}
}

void Init_TimerA(void)		// system tick
{
	TA1CCTL0 = CCIE;		// CCR0 interrupt enabled
	TA1CCR0 = 14924;		// 10msec

	TA1CTL = TASSEL_2+ID_3+MC_2+TACLR+TAIE;  // SMCLK(XT2,12MHz), contmode, clear TAR, Div 8(12/8 = 1.5Mhz)
	TA1R = 0;
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
//	P1OUT ^= 0x80;			// Toggle P1.0
	TA1R = 0;

	SysTick++;
	Delay10msec++;
	
	COIN_Check();
	Key_SCAN();
	FRONT_Check();
	Limit_Check();
}

void SetVcoreUp (unsigned int level)
{
	// Open PMM registers for write
	PMMCTL0_H = PMMPW_H;

	// Set SVS/SVM high side new level
	SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;

	// Set SVM low side to new level
	SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;

	// Wait till SVM is settled
	while((PMMIFG & SVSMLDLYIFG) == 0);

	// Clear already set flags
	PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);

	// Set VCore to new level
	PMMCTL0_L = PMMCOREV0 * level;

	// Wait till new level reached
	if((PMMIFG & SVMLIFG))
		while((PMMIFG & SVMLVLRIFG) == 0);

	// Set SVS/SVM low side to new level
	SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;

	// Lock PMM registers for write access
	PMMCTL0_H = 0x00;
}

void Delay_10msec(uint16_t DelayCNT)
{
	Delay10msec = 0;
	
	while(Delay10msec >= DelayCNT)
	{
		_nop();
	}
}

void Init_I2C(void)
{
	// UCB0 - I2C
	P3SEL |= EEPROM_CLK + EEPROM_SDA;		// p3.1 , p3.2

	// Recommended initialization steps of I2C module as shown in User Guide:
	UCB0CTL1 |= UCSWRST;						// Enable SW reset
	UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;		// I2C Master, synchronous mode
	UCB0CTL1 = UCSSEL_2 + UCTR + UCSWRST;				// Use SMCLK, keep SW reset
//	UCB0BR0 = 30;								// fSCL = SMCLK/30 = ~400kHz
    UCB0BR0 = 120;                              // fSCL = SMCLK/120 = ~100kHz
	UCB0BR1 = 0;
	UCB0I2CSA = 0x50;					// 7bit address

//	UCB0IE |= UCTXIE + UCRXIE;
	UCB0CTL1 &= ~UCSWRST;				// Clear SW reset, resume operation
	
	if (UCB0STAT & UCBBUSY)				// test if bus to be free
	{									// otherwise a manual Clock on is
										// generated
		P3SEL &= ~EEPROM_CLK;			// Select Port function for SCL
		P3OUT &= ~EEPROM_CLK;			//
		P3DIR |= EEPROM_CLK;			// drive SCL low
		P3SEL |= EEPROM_SDA + EEPROM_CLK;		// select module function for the
												// used I2C pins
	}
}

//----------------------------------------------------------------------------
//	Description:
//	Initialization of the I2C Module for Write operation.
//----------------------------------------------------------------------------
void I2CWriteInit(void)
{
	UCB0CTL1 |= UCTR;			// UCTR=1 => Transmit Mode (R/W bit = 0)
	UCB0IFG &= ~UCTXIFG;
	UCB0IE &= ~UCRXIE;			// disable Receive ready interrupt
	UCB0IE|= UCTXIE;			// enable Transmit ready interrupt
}

//----------------------------------------------------------------------------
// Description:
//   Initialization of the I2C Module for Read operation.
//----------------------------------------------------------------------------
void I2CReadInit(void)
{
	UCB0CTL1 &= ~UCTR;			// UCTR=0 => Receive Mode (R/W bit = 1)
	UCB0IFG &= ~UCRXIFG;
	UCB0IE &= ~UCTXIE;			// disable Transmit ready interrupt
	UCB0IE |= UCRXIE;			// enable Receive ready interrupt
}

//----------------------------------------------------------------------------
// Description:
//   Byte Write Operation. The communication via the I2C bus with an I2C
//   (24c04) is realized. A data byte is written into a user defined address.
//----------------------------------------------------------------------------

void EEPROM_ByteWrite(uint16_t Address, uint8_t Data)
{
	uint8_t adr_hi;
	uint8_t adr_lo;

//	FlowFlag = 1;
	while (UCB0STAT & UCBUSY);			// wait until I2C module has
										// finished all operations.

	adr_hi = Address >> 8;				// calculate high byte
	adr_lo = Address & 0xFF;			// and low byte of address

	I2CBufferArray[2] = adr_hi;			// Low byte address.
	I2CBufferArray[1] = adr_lo;			// High byte address.
	I2CBufferArray[0] = Data;
	PtrTransmit = 2;					//

//	UCB0I2CSA = 0x50;					// 7bit address

	I2CWriteInit();
	UCB0CTL1 |= UCTXSTT;				// TX Mode , start condition generation
										// => I2C communication is started
//	while(FlowFlag);
//	FlowFlag = 1;
	__bis_SR_register(LPM0_bits + GIE);	// Enter LPM0 w/ interrupts

	UCB0CTL1 |= UCTXSTP;				// I2C stop condition
	while(UCB0CTL1 & UCTXSTP);			// Ensure stop condition got sent
}

//----------------------------------------------------------------------------
// Description:
//   Random Read Operation. Data is read from the I2C. The I2C
//   address is defined with the parameter Address.
//----------------------------------------------------------------------------
uint8_t EEPROM_ByteRead(uint16_t Address)
{
	uint8_t adr_hi;
	uint8_t adr_lo;

	while (UCB0STAT & UCBUSY);			// wait until I2C module has
										// finished all operations

	adr_hi = Address >> 8;				// calculate high byte
	adr_lo = Address & 0xFF;			// and low byte of address

	I2CBufferArray[1] = adr_hi;			// store single bytes that have to
	I2CBufferArray[0] = adr_lo;			// be sent in the I2CBuffer.
	PtrTransmit = 1;

	// Write Address first
	I2CWriteInit();
	UCB0CTL1 |= UCTXSTT;				// start condition generation
										// => I2C communication is started
	__bis_SR_register(LPM0_bits + GIE);	// Enter LPM0 w/ interrupts

	// Read Data byte
	I2CReadInit();

	UCB0CTL1 |= UCTXSTT;				// I2C start condition

	while(UCB0CTL1 & UCTXSTT);			// Start condition sent?
	UCB0CTL1 |= UCTXSTP;				// I2C stop condition

	__bis_SR_register(LPM0_bits + GIE);	// Enter LPM0 w/ interrupts

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

	return I2CBuffer;
}

void EEPROM_AckPolling(void)
{
	while(UCB0STAT & UCBUSY);		// wait until I2C module has
									// finished all operations
	do
	{
		UCB0STAT = 0x00;			// clear I2C interrupt flags
		UCB0CTL1 |= UCTR;			// I2CTRX=1 => Transmit Mode (R/W bit = 0)
		UCB0CTL1 &= ~UCTXSTT;
		UCB0CTL1 |= UCTXSTT;		// start condition is generated

		while(UCB0CTL1 & UCTXSTT)	// wait till I2CSTT bit was cleared
		{
			if(!(UCNACKIFG & UCB0STAT))		// Break out if ACK received
				break;
		}
		UCB0CTL1 |= UCTXSTP;		// stop condition is generated after
									// slave address was sent => I2C communication is started

		while(UCB0CTL1 & UCTXSTP);	// wait till stop bit is reset
		__delay_cycles(500);		// Software delay
	}
	while(UCNACKIFG & UCB0STAT);
}

#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
	switch(__even_in_range(UCB0IV,12))
	{
		case  0: break;				// Vector  0: No interrupts
		case  2: break;				// Vector  2: ALIFG
		case  4: break;				// Vector  4: NACKIFG
		case  6: break;
		case  8: break;

		case 10:					// Vector 10: RXIFG
			I2CBuffer = UCB0RXBUF;	// store received data in buffer
			__bic_SR_register_on_exit(LPM0_bits);	// Exit LPM0
		break;

		case 12:					// Vector 12: TXIFG
			UCB0TXBUF = I2CBufferArray[PtrTransmit];	// Load TX buffer
			PtrTransmit--;								// Decrement TX byte counter

			if(PtrTransmit < 0)
			{
				while(!(UCB0IFG & UCTXIFG));
				UCB0IE &= ~UCTXIE;						// disable interrupts.
				UCB0IFG &= ~UCTXIFG;					// Clear USCI_B0 TX int flag
				__bic_SR_register_on_exit(LPM0_bits);	// Exit LPM0
			}
		break;

		default: break;
	}
}
/*
void Init_I2C(void)
{
	P3SEL |= EEPROM_SDA + EEPROM_CLK;		// Assign I2C pins to USCI_B0

	// Recommended initialisation steps of I2C module as shown in User Guide:
	UCB0CTL1 |= UCSWRST;					// Enable SW reset
	UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;	// I2C Master, synchronous mode
	UCB0CTL1 = UCSSEL_2 + UCTR + UCSWRST;	// Use SMCLK, TX mode, keep SW reset
	UCB0BR0 = 120;							// fSCL = SMCLK/120 = ~100kHz
	UCB0BR1 = 0;
	UCB0I2CSA  = 0x50;		// define Slave Address
											// In this case the Slave Address
											// defines the control byte that is
											// sent to the EEPROM.
//	UCB0I2COA = 0x01A5;						// own address.
	UCB0CTL1 &= ~UCSWRST;					// Clear SW reset, resume operation

	if(UCB0STAT & UCBBUSY)					// test if bus to be free
	{										// otherwise a manual Clock on is
											// generated
		P3SEL &= ~EEPROM_CLK;				// Select Port function for SCL
		P3OUT &= ~EEPROM_CLK;				//
		P3DIR |= EEPROM_CLK;				// drive SCL low
		P3SEL |= EEPROM_SDA + EEPROM_CLK;	// select module function for the
											// used I2C pins
	}
}

void I2CWriteInit(void)
{
	UCB0CTL1 |= UCTR;			// UCTR=1 => Transmit Mode (R/W bit = 0)
	UCB0IFG &= ~UCTXIFG;
	UCB0IE &= ~UCRXIE;			// disable Receive ready interrupt
	UCB0IE|= UCTXIE;			// enable Transmit ready interrupt
}

void I2CReadInit(void)
{
	UCB0CTL1 &= ~UCTR;			// UCTR=0 => Receive Mode (R/W bit = 1)
	UCB0IFG &= ~UCRXIFG;
	UCB0IE &= ~UCTXIE;			// disable Transmit ready interrupt
	UCB0IE |= UCRXIE;			// enable Receive ready interrupt
}

void EEPROM_ByteWrite(uint16_t Address, uint8_t Data)
{
	uint8_t adr_hi;
	uint8_t adr_lo;

	while(UCB0STAT & UCBUSY);		// wait until I2C module has
									// finished all operations.

	adr_hi = Address >> 8;			// calculate high byte
	adr_lo = Address & 0xFF;		// and low byte of address

	I2CBufferArray[2] = adr_hi;		// Low byte address.
	I2CBufferArray[1] = adr_lo;		// High byte address.
	I2CBufferArray[0] = Data;
	PtrTransmit = 2;				// set I2CBufferArray Pointer

	I2CWriteInit();
	UCB0CTL1 |= UCTXSTT;			// start condition generation
									// => I2C communication is started
	__bis_SR_register(LPM0_bits + GIE);		// Enter LPM0 w/ interrupts
	UCB0CTL1 |= UCTXSTP;			// I2C stop condition
	while(UCB0CTL1 & UCTXSTP);		// Ensure stop condition got sent
}

uint8_t EEPROM_ByteRead(uint16_t Address)
{
	uint8_t adr_hi;
	uint8_t adr_lo;

	while(UCB0STAT & UCBUSY);		// wait until I2C module has
									// finished all operations

	adr_hi = Address >> 8;			// calculate high byte
	adr_lo = Address & 0xFF;		// and low byte of address

	I2CBufferArray[1] = adr_hi;		// store single bytes that have to
	I2CBufferArray[0] = adr_lo;		// be sent in the I2CBuffer.
	PtrTransmit = 1;				// set I2CBufferArray Pointer

	// Write Address first
	I2CWriteInit();
	UCB0CTL1 |= UCTXSTT;			// start condition generation
									// => I2C communication is started
	__bis_SR_register(LPM0_bits + GIE);		// Enter LPM0 w/ interrupts

	// Read Data byte
	I2CReadInit();

	UCB0CTL1 |= UCTXSTT;			// I2C start condition
	while(UCB0CTL1 & UCTXSTT);		// Start condition sent?

	UCB0CTL1 |= UCTXSTP;			// I2C stop condition
	__bis_SR_register(LPM0_bits + GIE);		// Enter LPM0 w/ interrupts

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

	return I2CBuffer;
}

void EEPROM_AckPolling(void)
{
	while(UCB0STAT & UCBUSY);		// wait until I2C module has
									// finished all operations
	do
	{
		UCB0STAT = 0x00;			// clear I2C interrupt flags
		UCB0CTL1 |= UCTR;			// I2CTRX=1 => Transmit Mode (R/W bit = 0)
		UCB0CTL1 &= ~UCTXSTT;
		UCB0CTL1 |= UCTXSTT;		// start condition is generated

		while(UCB0CTL1 & UCTXSTT)	// wait till I2CSTT bit was cleared
		{
			if(!(UCNACKIFG & UCB0STAT))		// Break out if ACK received
				break;
		}
		UCB0CTL1 |= UCTXSTP;		// stop condition is generated after
									// slave address was sent => I2C communication is started

		while(UCB0CTL1 & UCTXSTP);	// wait till stop bit is reset
		__delay_cycles(500);		// Software delay

	}
	while(UCNACKIFG & UCB0STAT);
}


#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
{
	switch(__even_in_range(UCB0IV,12))
	{
		case  0: break;				// Vector  0: No interrupts
		case  2: break;				// Vector  2: ALIFG
		case  4: break;				// Vector  4: NACKIFG
		case  6: break;
		case  8: break;
		case 10:					// Vector 10: RXIFG
			I2CBuffer = UCB0RXBUF;                  // store received data in buffer
			__bic_SR_register_on_exit(LPM0_bits);   // Exit LPM0
		break;

		case 12:					// Vector 12: TXIFG
			UCB0TXBUF = I2CBufferArray[PtrTransmit];	// Load TX buffer
			PtrTransmit--;								// Decrement TX byte counter

			if(PtrTransmit < 0)
			{
				while(!(UCB0IFG & UCTXIFG));
				UCB0IE &= ~UCTXIE;                     // disable interrupts.
				UCB0IFG &= ~UCTXIFG;                   // Clear USCI_B0 TX int flag
				__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
			}
		break;

		default: break;
	}
}
*/

slaa208a.zip

When you see the main.c, I modify based on slaa208a.

when Read opration, after set the TX address then move to LPM0. then even though TX interrupt is coming, it doesn't awake and it is stopped after lpm0.

Please check whether there's another problem except I2C or let me know where I need to modify.

if you have the reference with 5419 and eeprom please introduce it.

Best Regards,

Jay.

**Attention** This is a public forum