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.

Problem with interfacing to eeprom 24aa64 via I2c urgent help needed

Hi,

   I need urgent help in interfacing with eeprom 24aa64. I am writing 2 bytes in the eeprom and want to read back those written 2 bytes .In the first run of my code I read successfully those written 2 bytes and the code runs well but in the second run I am unable to read the two bytes and my program stucks and I do nt get any Interrupt from RX Isr but in the first run I get the Rx isr and read the two written bytes.I am using cc430f51137.I need urgent help.If anyone knows about this then kindly please help me out.I have stuck here for 10 days.

#include <msp430.h>
#include <stdint.h>
#include<string.h>
#include <stdio.h>
#include <stdbool.h>

unsigned char txdata[3];
volatile unsigned char receive[2];
bool c=false;
bool d=false;
unsigned char high=0x00;
unsigned char low=0x00;
int j;
unsigned char tx_limit;
unsigned char rx_limit;
unsigned char tx_counter=0;
unsigned char rx_counter=0;
unsigned char tx_rx;

void i2c_tx(unsigned char low,unsigned char high,unsigned char tx_count)
{
txdata[0]=high;
txdata[1]=low;
if(low==0x00)
txdata[2]=0x48;
else
txdata[2]=0x49;
tx_rx = 0;

tx_limit = tx_count;

if(tx_count==3)
d=true;


UCB0CTL1 |= UCTR + UCTXSTT;

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

}

void i2c_rx(unsigned char rx_count)
{
tx_rx = 1;
// rx_byte_count = rx_count + 1;
rx_limit = rx_count; // Load RX byte counter
UCB0CTL1 &= ~UCTR; // I2C RX
UCB0CTL1 |= UCTXSTT; // I2C start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
// Remain in LPM0 until all data is RX'd
}

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; //Stop WDT
P3DIR |= BIT6 +BIT7;
P3OUT &= ~(BIT6 +BIT7);

P1SEL |= BIT2 + BIT3; // Select P1.2 & P1.3 to I2C function


UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 16; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;


UCB0I2CSA = 0x50; // Slave Address is 050h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCTXIE;
UCB0IE |= UCRXIE;
UCB0IE |= UCNACKIE;

for(;;){
__delay_cycles(100000); //Just a start up delay
for (j=0;j<2;j++){
i2c_tx(low,high,3);
__delay_cycles(5000);


while (c)
{

printf("%s","for transmission problem");
i2c_tx(low,high,3);
__delay_cycles(5000);

}
low++;
if(j==1){
low=0x00;
}
}

i2c_tx(low,high,2);  //sending address   for receiving data 

while (c)
{
printf("%s","for transmission problem");
i2c_tx(low,high,2);
}
i2c_rx(2);
while (c)
{
printf("%s","for receiving problem");
i2c_rx(2);
}

printf("%c",receive[0]);
printf("%c",receive[1]);

printf("%s","how r u"); //i2c RX data
}
}


#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: P3OUT |=BIT6; break; // Vector 2: ALIFG
case 4:

P3OUT |=BIT7; 
c=true; 

__bic_SR_register_on_exit(LPM0_bits);// Exit LPM0

break; // Vector 4: NACKIFG
case 6:


__bic_SR_register_on_exit(LPM0_bits);
break; // Vector 6: STTIFG
case 8:

__bic_SR_register_on_exit(LPM0_bits);
break; // Vector 8: STPIFG
case 10:
if(tx_rx == 1)
{
if ( rx_counter< rx_limit) //Check RX byte counter
{
receive[rx_counter] = UCB0RXBUF;

if (rx_counter==1){
UCB0CTL1 |= UCTXSTP;
}
rx_counter++;

}
else
{
rx_counter=0;
c=false; // I2C stop condition
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
break; // Vector 10: RXIFG
case 12: // Vector 12: TXIFG
if(tx_rx == 0)
{
if (tx_counter < tx_limit) //Check TX byte counter
{
UCB0TXBUF = txdata[tx_counter]; // Load TX buffer
tx_counter++; 
}
else if(d)
{
d=false;
c=false;
tx_counter=0;
UCB0CTL1 |= UCTXSTP; //I2C stop condition
while (UCB0CTL1 & UCTXSTP); //Ensure stop condition got sent //Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); //Exit LPM0
}
else{

c=false;
tx_counter=0;
__bic_SR_register_on_exit(LPM0_bits);
}
}
break;
default: break;


}

}

  • Hi,

    I think it is better to use a logic analyzer or OSC to capture the Clock and Data signals when you are trying to access the EEPROM. Try to figure out whether there is a ACK from the EEPROM.

    Thank you

  • Hello,

    This is not the ideal solution however this might work. Try re-initializing i2C everytime just before reading from EEPROM.

    Regards,

    Arthi Bhat

  • Hello ,

    I am starting I2C everytime just before reading but my code stucks.

    void i2c_rx(unsigned char rx_count)
    {
    tx_rx = 1;
    // rx_byte_count = rx_count + 1;
    rx_limit = rx_count; // Load RX byte counter
    UCB0CTL1 &= ~UCTR; // I2C RX
    UCB0CTL1 |= UCTXSTT; // I2C start condition
    __bis_SR_register(LPM0_bits + GIE);     //My program stucks here  after successfully completing the first run of my                                                                    whole code  where I wrote 2 bytes in eeprom and read back again                                                                                successfully those written 2 bytes but upon second run of whole code ,my                                                                     program stucks onto this line  

    }

     

    Can you tell me the reason ?

  • Faisal khan2 said:
    Can you tell me the reason ?

    Umm, because setting LPM0_bits in the SR register halts the CPU. Read up on how the LPM modes work.

  • Dear Brian,

                        I am also turning on receiver mode and recieve interrupt is also enabled then it must jump to the ISR ,my code jumps to the Rx isr in the first run of code and reads the two written bytes but in the second run it stucks there.

    Regards

    Faisal

**Attention** This is a public forum