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.

eeprom random read problem

Other Parts Discussed in Thread: MSP430F6779, MSP430F67791

hi all i am working with the eeprom 24c02  with msp430f6779 controller using the USCB1 I2C module .

I am able to write and read from eeprom but i am facing one problem that when i try to read more then one data with below function

unsigned char EEPROM_RandomRead(unsigned int Address)
{
  unsigned char adr_hi;
  unsigned char adr_lo;

  while (UCB1STAT & 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();
  UCB1CTLW0 |= UCTXSTT;                      // start condition generation
                                                                      // => I2C communication is started
  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupts

  // Read Data byte
  I2CReadInit();

  UCB1CTLW0 |= UCTXSTT;                      // I2C start condition
 //__bis_SR_register(LPM0_bits + GIE);
  while(UCB1CTLW0 & UCTXSTT);                // Start condition sent?
  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0 w/ interrupts
  UCB1CTLW0 |= UCTXSTP;                          // I2C stop condition
 
  while(UCB1CTLW0 & UCTXSTP);                // Ensure stop condition got sent
  return I2CBuffer;

}

above function give me the 2 same data if i read it from say address 0x0000 and 0x0001 it will give me  data stored at address 0x0000 .

  • Hi Patel, I am trying to communicate st eeprom with msp430f6779 mcu. But I can not communicate yet. Can you share your iic software module with me ?

  • hi baycan just see the errata for msp430f6779 mcu.you need to use two times read the eeprom I will see if i get the copy of IIC  i will share with you soon.

  • #include "msp430f6736.h"
    #include "EEprom.h"
    #include <stdint.h>
    
    #define     MAXPAGEWRITE  5
    
    
    #define EEPROM_CONTROL_BITS			0x50		// Constant part of slave adx byte
    
    #define EEPROM_CLOCK_MHZ			32768///8000000
    
    #define EEPROM_SUCCESS				1			// Successful operation return value
    #define	EEPROM_FAIL				0			// Failed operation return value
    
    #define SCL_CLOCK_DIV                          0x12                     // SCL clock devider
    
    
    
    #define EEPROM_SLA_CALC(adx)		(EEPROM_CONTROL_BITS|((adx >> 8) & 0x03))
    
    // Returns 8 LSBs of byte address
    #define EEPROM_ADX_CALC(adx)		(adx & 0x00FF)					
    
    // Transmit given value by writing to TX buffer
    #define EEPROM_I2C_TX_BYTE(B)		UCB0TXBUF = (unsigned char) B
    
    // Stops I2C transaction	
    #define EEPROM_I2C_STOP()			(UCB0CTL1 |= UCTXSTP)		
    
    // Starts I2C transaction
    #define EEPROM_I2C_START()			 (UCB0CTL1 |= UCTXSTT)   
    		
    // Sets USCI for Master TX mode
    #define EEPROM_I2C_MODE_MSTTX()		(UCB0CTL1 |= UCTR)
    			
    // Sets USCI for Master RX mode
    #define EEPROM_I2C_MODE_MSTRX()		(UCB0CTL1 &= ~UCTR)			
    
    // Stores received byte in given variable
    #define EEPROM_I2C_RX_BYTE(mem)		mem = UCB0RXBUF
    				
    // Waits for transmit operation to complete
    #define EEPROM_I2C_TX_WAIT()		 while(!(UCB0IFG & UCTXIFG));UCB0IFG &= ~UCTXIFG;      
    
    // Waits for receive operation to complete
    #define EEPROM_I2C_RX_WAIT()		while(!(UCB0IFG & UCRXIFG)); UCB0IFG &= ~UCRXIFG;    
    
    // Waits for START to be acknowledged	
    #define EEPROM_I2C_START_WAIT()		while(UCB0CTL1 & UCTXSTT)	
    
    // Waits for STOP command to complete
    #define EEPROM_I2C_STOP_WAIT()		while((UCB0CTL1 & UCTXSTP))	
    
    // True if NACK condition occurred (Not Acknowledged)
    #define EEPROM_I2C_NO_ACK()			(UCB0IFG & UCNACKIFG)		
    
    // Clears the NACK flag
    #define EEPROM_I2C_CLEAR_NO_ACK()	(UCB0IFG &= ~UCNACKIFG)	
    
    // EEPROM_I2C_NACK CHECK() checks for a NACK flag and ends operation if it finds one.
    #define EEPROM_I2C_NACK_CHECK()		if(EEPROM_I2C_NO_ACK())		\
    									{							\
    									EEPROM_I2C_CLEAR_NO_ACK();	\
    									EEPROM_I2C_STOP();			\
    									EEPROM_I2C_STOP_WAIT();		\
    									return EEPROM_FAIL;			\
    									}
    // Inline SW delay function with accompanying volatile counter
    #define EEPROM_delay(cycles)		for(s_dly_cnt = 0; s_dly_cnt < cycles; s_dly_cnt++)	
    volatile uint16_t s_dly_cnt;
    
    // Write cycle delay for EEPROM page writes. Could be improved with HW delay (FIXME).
    #define EEPROM_WRITE_DELAY()		EEPROM_delay(200)
    #define TICKS_PER_MS (EEPROM_CLOCK_MHZ/ 1000)
    #define TICKS_PER_US (TICKS_PER_MS / 1000)
    
    void delayI2Cms(uint16_t delay)
    
    {
        while (delay--) __delay_cycles(TICKS_PER_MS);
    }
    
    void delayI2Cus(uint16_t delay)
    {
        while (delay--) __delay_cycles(TICKS_PER_US);
    }
    
    void InitI2C()
    {
       I2C_PORT_SEL |= SDA_PIN + SCL_PIN;        // Assign I2C pins to USCI_B0
    
      // Recommended initialisation steps of I2C module as shown in User Guide:
     
                                               
        UCB0CTLW0 |= UCSWRST;                             // Enable SW reset
        UCB0CTLW0 |= UCMST | UCMODE_3 | UCSSEL_2;         // I2C Master, use SMCLK
        UCB0CTLW0 &= ~UCSLA10;
        UCB0CTLW0 |=UCSYNC;
          
        UCB0BR0= SCL_CLOCK_DIV;                                 // fSCL = SMCLK/12 = ~100kHz
        UCB0BR1 = 0;
        UCB0I2CSA = 0x50;                                  // Slave Address is 048h
       // UCB0I2COA1 = 0x01A5;
        UCB0CTLW0 &= ~UCSWRST;                            // Clear SW reset, resume operation
       // UCB0IE |= UCTXIE;                                // Enable TX interrupt                                       // defines the control byte that is
                                                // sent to the EEPROM.
     
      if (UCB0STAT & UCBBUSY)                   // test if bus to be free
      {                                         // otherwise a manual Clock on is
                                                // generated
        I2C_PORT_SEL &= ~SCL_PIN;               // Select Port function for SCL
        I2C_PORT_OUT &= ~SCL_PIN;               //
        I2C_PORT_DIR |= SCL_PIN;                // drive SCL low
        I2C_PORT_SEL |= SDA_PIN + SCL_PIN;      // select module function for the
                                                // used I2C pins
      }
    }
    
    
    
    
    unsigned char EEPROM_i2c_write( unsigned char* txdPtr, uint16_t len, uint16_t adx)
    {	
    	uint16_t i;							// Counter
    	
    	// Fail if a page overflow will occur.
    	/*if((adx + len - 1)/EEPROM_PAGE_SIZE != adx/EEPROM_PAGE_SIZE)
    	{
    		return EEPROM_FAIL;
    	}*/
    		
    	 UCB0CTLW0 &= ~UCSWRST;					// Clear USCI reset bit
    	
    	EEPROM_I2C_MODE_MSTTX();				// Put USCI in Master TX mode
    //	 UCB0I2CSA = EEPROM_SLA_CALC( adx );		// Set up USCI slave adx byte 
    											//	(device code + 2 MSBs of mem address)
    
    	EEPROM_I2C_START();						// Send start condition and slave adx
    	EEPROM_I2C_TX_WAIT();					// Wait for transmit to complete
    	
    	EEPROM_I2C_TX_BYTE( EEPROM_ADX_CALC( adx ) );           // Send 8 LSBs of EEPROM adx
    	EEPROM_I2C_START_WAIT();				// Wait for EEPROM to acknowledge address
    	
    	EEPROM_I2C_NACK_CHECK();				// Stop and return EEPROM_FAIL if EEPROM
    											//	doesn't acknowledge (NACK flag set).
    
    	// Transmit all data from buffer
    	for(i = 0; i < len; i++)
    	{
    		EEPROM_I2C_TX_WAIT();			// Wait for tx to complete
    		EEPROM_I2C_TX_BYTE( txdPtr[i] );	// Transmit byte
                    EEPROM_delay(10);
    	}
    	
    	EEPROM_I2C_TX_WAIT();					// Wait for transmission to complete
    	EEPROM_I2C_STOP();						// Send stop and wait for USCI
    	EEPROM_I2C_STOP_WAIT();					// 
    	//delayI2Cms(100);
    	EEPROM_WRITE_DELAY();
    	
    	UCB0IFG &= ~UCTXIFG;						// Clear transmit flag
    	UCB0CTLW0 |= UCSWRST; 					// USCI reset(?)
    	
    	return EEPROM_SUCCESS;
    }
    
    
    unsigned char EEPROM_i2c_read( unsigned char* rxdPtr, uint16_t len, uint16_t adx)
    {
    	uint16_t i,k;								// Counter
    	
    	// UCB0I2CSA = EEPROM_SLA_CALC( adx );		// Set up slave address byte of USCI
    	
    	//	Change address with a Write command and address byte.
    		
    	EEPROM_I2C_MODE_MSTTX();				// Set master tx mode
    	
    	UCB0CTLW0 &= ~UCSWRST;					// Clear USCI reset bit		
    	
    	EEPROM_I2C_START();						// Start tx (sends block address)
    	EEPROM_I2C_TX_WAIT();					//
    	EEPROM_I2C_TX_BYTE( EEPROM_ADX_CALC( adx ) );// Send 8 LSBs of address
    	EEPROM_I2C_START_WAIT();				// Wait for EEPROM acknowledgement
    	
    	EEPROM_I2C_NACK_CHECK();				// Fail if EEPROM sends NACK
    	for(k=0;k<2000;k++);
    	// Don't stop here! Now we're ready to read.
    
    	EEPROM_I2C_TX_WAIT();					// Wait for tx to complete
    	EEPROM_I2C_MODE_MSTRX();				// Set master rx mode
    	
              UCB0CTLW0 &= ~UCSWRST;						// Clear USCI reset bit
    	
    	EEPROM_I2C_START();						// Start rx (sends block address)				
    	
    	// Receive selected data from EEPROM and store in buffer.
    	for(i = 0; i < len; i ++)
    	{
    		EEPROM_I2C_RX_WAIT();
    		EEPROM_I2C_RX_BYTE(rxdPtr[i]);
                 //  EEPROM_delay(10);
    	}
    	
    	EEPROM_I2C_RX_WAIT();					// due to errata read again here
            EEPROM_I2C_RX_BYTE(rxdPtr[i]);
    	EEPROM_I2C_STOP();						// End transmission
           
    	EEPROM_I2C_STOP_WAIT();
    	
    	UCB0CTLW0 |= UCSWRST; 					// Reset USCI
    	
    	return EEPROM_SUCCESS;
    }
    
    
    
    

    here the code which i was using and working for me.. hope this would save your couple of days...

  • Hi Patel,

    It has been long time without my answer. First I wanna apolagize for that. I dont know how but I missed your answer. By the way I have wrotten an eeprom library. And I compared with your code. They looks a like. Thank you for your attention. I really appreciated.

    Best Regards.
  • Can you please also share your EEprom.h and your ISR for USCB1 module? I am having some difficulty in reading data from my EEPROM. I also have the same controller (MSP430F67791) and EEPROM (24C02).
  • #include<stdint.h>
    
    #define I2C_PORT_SEL  P2SEL
    #define I2C_PORT_OUT  P2OUT
    #define I2C_PORT_REN  P2REN
    #define I2C_PORT_DIR  P2DIR
    #define SCL_PIN       BIT0                  // UCB0SDA pin
    #define SDA_PIN       BIT1                  // UCB0SCL pin
    
    void InitI2C();
    void EEPROM_ByteWrite(unsigned int Address , unsigned char Data);
    void EEPROM_PageWrite(unsigned int StartAddress , unsigned char * Data , unsigned int Size);
    unsigned char EEPROM_RandomRead(unsigned int Address);
    unsigned char EEPROM_CurrentAddressRead(void);
    void EEPROM_SequentialRead(unsigned int Address , unsigned char * Data , unsigned int Size);
    void EEPROM_AckPolling(void);
    unsigned char EEPROM_i2c_write( unsigned char* txdPtr, uint16_t len, uint16_t adx);
    //unsigned char EEPROM_i2c_read(  uint16_t adx);
    //unsigned char EEPROM_i2c_read( unsigned char rxddata,  uint16_t adx);
    
    //unsigned char EEPROM_i2c_write( unsigned char txddata, uint16_t adx);
    unsigned char EEPROM_i2c_read( unsigned char* rxdPtr, uint16_t len, uint16_t adx);

    check your slave address and hardware connection..

    and for UCB1 you need to do replace USB0 with USB1 in my eeprom c code in earlier post

  • Thanks for the reply....
    What I meant was your ISR code for UCB0. I am checking if there is some issue with my hardware or not so that's why I need the exact code that you said is working for you... This way I will know that the issue is with my hardware.... Can you share your following code....

    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCI_B0_ISR(void)

    {
    switch (__even_in_range(UCB0IV, 30))

    }
  • If you look at my eeprom C code i didn't use interrupts in my InitI2C() function. so i just used the EEPROM_i2c_read() function to read the data from eeprom.I advice you to check your slave address is it correct or not.and if possible then post your code here so i can help you better
  • Can you please share your complete EEprom.c file? The one that you have shared above only has EEPROM_i2c_write and EEPROM_i2c_read implemented.... While in your header you declare
    void EEPROM_ByteWrite(unsigned int Address , unsigned char Data);
    void EEPROM_PageWrite(unsigned int StartAddress , unsigned char * Data , unsigned int Size);
    unsigned char EEPROM_RandomRead(unsigned int Address);
    unsigned char EEPROM_CurrentAddressRead(void);
    void EEPROM_SequentialRead(unsigned int Address , unsigned char * Data , unsigned int Size);
    void EEPROM_AckPolling(void);

    It would be so kind from you as it will save lots of development time for me....

**Attention** This is a public forum