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.

CC430F5137: Facing the problem while i am trying to interface the microcontroller with EEPROM via I2C communication

Part Number: CC430F5137

Hi,

i am working with cc430f5137 based project. Here i am facing following problem actually i am trying to interfacing the EEPROM with Microcontroller via I2C protocal.

1. Here i am using software protocal for I2c communication and i am using following bits are P1.3 for SDA,P1.2 for SCL and P1.1 for WP. 

2. First i am trying to send the address to eeprom for identify the slave, here successfully write the add and eeprom gave the ACK to master.

3 After that i am trying to send add word to it , here the eeprom didn't give the ACK to master. 

this is the actual problem facing 

EEPROM part no is : AT24LC024

Here i have attached my firmware details. Please help me.

/*******************************Main.c*************************************/

#include "cc430f5137.h"
#include "EEPROM.h"
#include <msp430.h>
//#include "TI_USCI_I2C_master.h"


unsigned int i=0;

void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

UCSCTL3 |= SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO

// Initialize DCO to 8MHz
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_5; // Set RSELx for DCO = 16MHz
UCSCTL2 = FLLD_1 + 249; // Set DCO Multiplier for 8MHz
// (N + 1) * FLLRef = Fdco
// (74 + 1) * 32768 = 8MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
__delay_cycles(250000);

Registers_write1();
Registers_read();
}

/******************************************************************************************/

/************************************EEPROM.c*****************************************/

#include "cc430f5137.h"
#include "EEPROM.h"

#define EEPROM_PAGE_SIZE 128 //64 //AT24C256 has 64-byte page size
unsigned char uart_buffer[35], ruart_buffer[35],rrbuffer[40],Internal_Flash_Values[40]={'1','2','3','4','5','6','7','8','9','0'};


//TI_CC_Wait(35); Delay time 5.6uS at DCO Running with 8MhZ
//TI_CC_Wait(70); Delay Time 11.2uS at DCO Running with 8MhZ
void TI_CC_Wait(unsigned int cycles)
{
while(cycles>15) // 15 cycles consumed by overhead
cycles = cycles - 6; // 6 cycles consumed each iteration
}
void start(void)
{
sdaout();
EEPROM_OUT |= SDA_EEPROM;
EEPROM_OUT |= SCL_EEPROM;
EEPROM_OUT &= ~SDA_EEPROM;
TI_CC_Wait(35);//delay 5.6uS
EEPROM_OUT &= ~SCL_EEPROM;
}

void stop(void)
{
sdaout();
EEPROM_OUT &= ~SDA_EEPROM;
EEPROM_OUT &= ~SCL_EEPROM;
EEPROM_OUT |= SCL_EEPROM;
TI_CC_Wait(35);//delay 5.6uS
EEPROM_OUT |= SDA_EEPROM;
}

void sendb(unsigned char c)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(c&0x80)
{
EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM; //SDA=1
TI_CC_Wait(35);//delay 5.6uS
}
else
{
EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT&=~SDA_EEPROM; //SDA=0;
TI_CC_Wait(35);//delay 5.6uS
}
c=c<<1;

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT |=SCL_EEPROM; // SCL=1;
TI_CC_Wait(35);//delay 5.6uS

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT&=~SCL_EEPROM; //SCL=0;
TI_CC_Wait(35);//delay 5.6uS
}
}

unsigned char getack_ee(void)
{
unsigned char ack=0;

EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM; //SDA=1
TI_CC_Wait(10);//delay 1.6uS

EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT &= ~SCL_EEPROM; //SCL=0;
TI_CC_Wait(35);//delay 5.6uS

EEPROM_DIR &= ~(SDA_EEPROM); //
EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT |= SCL_EEPROM; // SCL=1;
TI_CC_Wait(35);//delay 5.6uS

ack=(char)(EEPROM_IN & SDA_EEPROM);
EEPROM_DIR |= SCL_EEPROM;
EEPROM_OUT &= ~SCL_EEPROM; //SCL=0;
TI_CC_Wait(35);//delay 5.6uS

return (ack & SDA_EEPROM);
}

void Registers_write1(void)
{
int i;
EEPROM_DIR |= 0x0E;//0X07;
EEPROM_OUT &= ~EEPROM_WP;
TI_CC_Wait(35);
for (i=0;i<10;i++)
{
eeprom_w_byte(i,Internal_Flash_Values[i]);
TI_CC_Wait(35);
}
EEPROM_OUT |= EEPROM_WP;
TI_CC_Wait(35);
}

void eeprom_w_byte(unsigned char add,unsigned char value)
{
start(); // starting the i2c communication
sendb(0xA0); // sending the address of the device
if(getack_ee())
{
stop();
}
sendb(add); // sending the higher byte of the address word
if(getack_ee())
{
stop();
}
sendb(value); // sending the data of array
if(getack_ee())
{
stop();
}
stop(); // stop condition for i2c communication
}

void Registers_read(void)
{
int i;
EEPROM_DIR |= 0x0E;//0X07;
TI_CC_Wait(35);
for (i=0;i<10;i++)
{
eeprom_r_byte(i,&ruart_buffer[i]);
TI_CC_Wait(35);
}
TI_CC_Wait(35);
}

void eeprom_r_byte(unsigned char add,unsigned char *buffer)
{
start(); // starting the i2c communication
sendb(0xA0); // sending the address of the device
if(getack_ee())
{
stop();
}
sendb(add); //sending the higher byte of the address word
if(getack_ee())
{
stop();
}
start(); // starting the i2c communication
sendb(0xA1); // sending the data of array
if(getack_ee())
{
stop();
}
*buffer = read(); // reading a byte from eeprom
putack_i2c(0);
stop(); // stop condition for i2c communication
}

void putack_i2c(unsigned char ack)
{
if(ack==0)
{
EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT&=~SDA_EEPROM; //SDA=0;
TI_CC_Wait(10);
}
else
{
EEPROM_DIR |=SDA_EEPROM;
EEPROM_OUT |=SDA_EEPROM; //SDA=1
TI_CC_Wait(10);
}

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT |=SCL_EEPROM; // SCL=1;
TI_CC_Wait(10);

EEPROM_DIR |=SCL_EEPROM;
EEPROM_OUT&=~SCL_EEPROM; //SCL=0;
TI_CC_Wait(10);
}

/***************************************************************************************/

  • This is not the correct way to set the CPU frequency; you have to check the fault flags. (See the example code files for details.)

    Why are you not using the hardware I²C?

    It is hard to see what this code does. Please show an oscilloscope or logic analyzer trace.
  • i am also willing to use hardware i2c, but i can't find it's supported library files. can you send me, if you have?

  • Thank for reply Clemens Ladisch and Please keep on help me.
  • The cc430x513x_uscib0_i2c_xx.c files in the example code package show how to use the I²C module.
  • Thank you.
    i found it and work on it. i will update you.
  • Hi,

    by you reffed. I am using hardware i2c protocol, i am using following source code, in this code i called following function for slave is present or not(TI_USCI_I2C_slave_present(0xA0)). Now i got positive result means slave presented(i = 1). After that i called following function for write 5bytes into the EEPROM (TI_USCI_I2C_transmit(5,TxData);), here i has send first byte from master to slave and Master wait for ACK from Slave for first byte completion, but the Slave Gave NACK to Mster. This is my actual problem


    SOURCE CODE:

    #include "cc430x613x.h"
    #include"main.h"

    unsigned char *PTxData; // Pointer to TX data
    unsigned char TXByteCtr;
    unsigned char *PRxData; // Pointer to RX data
    unsigned char RXByteCtr;

    extern signed char byteCtr;
    extern unsigned char *TI_receive_field;
    extern unsigned char *TI_transmit_field;
    volatile unsigned char RxBuffer[10]; // Allocate 128 byte of RAM
    unsigned int i=0,j=0;
    unsigned char TxData[] ={ 'A','B','C','D','E'};

    int main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    PMAPPWD = 0x02D52; // Get write-access to port mapping regs
    P1MAP3 = PM_UCB0SDA; // Map UCB0SDA output to P1.3
    P1MAP2 = PM_UCB0SCL; // Map UCB0SCL output to P1.2
    PMAPPWD = 0; // Lock port mapping registers

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


    TI_USCI_I2C_notready();
    TI_USCI_I2C_transmitinit(0xa0,0x12);
    TI_USCI_I2C_notready();
    i = TI_USCI_I2C_slave_present(0xA0);
    TI_USCI_I2C_notready();
    TI_USCI_I2C_transmitinit(0xa0,0x12);
    TI_USCI_I2C_transmit(5,TxData);
    TI_USCI_I2C_notready();
    TI_USCI_I2C_receiveinit(0xa1,0x12);
    TI_USCI_I2C_receive(5,PRxData);
    TI_USCI_I2C_notready();
    for(j=0;j<5;j++)
    RxBuffer[j] = PRxData[j];


    return 0;
    }
    //------------------------------------------------------------------------------
    // void TI_USCI_I2C_transmitinit(unsigned char slave_address,
    // unsigned char prescale)
    //
    // This function initializes the USCI module for master-transmit operation.
    //
    // IN: unsigned char slave_address => Slave Address
    // unsigned char prescale => SCL clock adjustment
    //------------------------------------------------------------------------------
    void TI_USCI_I2C_transmitinit(unsigned char slave_address, unsigned char prescale)
    {
    P1SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
    UCB0CTL1 = UCSWRST; // Enable SW reset
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB0BR0 = prescale; // set prescaler
    UCB0BR1 = 0;
    UCB0I2CSA = slave_address; // Set slave address
    UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB0IE = UCNACKIE | UCTXIE; // Enable TX ready interrupt

    }


    //------------------------------------------------------------------------------
    // void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field)
    //
    // This function is used to start an I2C commuincation in master-transmit mode.
    //
    // IN: unsigned char byteCount => number of bytes that should be transmitted
    // unsigned char *field => array variable. Its content will be sent.
    //------------------------------------------------------------------------------
    void TI_USCI_I2C_transmit(unsigned char byteCount, unsigned char *field)
    {
    TI_transmit_field = field;
    byteCtr = byteCount;
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    }

    #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:
    if(UCNACKIFG) // send STOP if slave sends NACK
    {
    UCB0CTL1 |= UCTXSTP;
    UCB0STAT &= ~UCNACKIFG;
    }
    break; // Vector 4: NACKIFG
    case 6: break; // Vector 6: STTIFG
    case 8: break; // Vector 8: STPIFG
    case 10: // Vector 10: RXIFG
    byteCtr--; // Decrement RX byte counter
    if(byteCtr)
    {
    *TI_receive_field++ = UCB0RXBUF; // Move RX data to address PRxData
    if (byteCtr == 1) // Only one byte left?
    UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition
    }
    else
    {
    *TI_receive_field = UCB0RXBUF; // Move final RX data to PRxData
    __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
    }
    break;
    case 12: // Vector 12: TXIFG
    if(byteCtr) // Check TX byte counter
    {
    UCB0TXBUF = *TI_transmit_field++; // Load TX buffer
    byteCtr--; // Decrement TX byte counter
    __delay_cycles(60000);
    }
    else
    {
    UCB0CTL1 |= UCTXSTP; // I2C stop condition
    UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
    __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
    }
    break;
    default: break;
    }
    }




    Please help me am I using correct way or not?

  • Hello,

    When posting code to the forum, please use the advanced editor by clicking the "Insert Code, Attach Files and more..." link on the bottom right hand side of your reply box. Once in this view, to insert code, use the </> box. this will format code to a readable form.

    For help in debugging I2C communication, please see the following app note:
    http://www.ti.com/lit/slaa734

    Also, please see the following code example. It is made for a similar device so some porting will be needed, but it is a complete I2C example.
    See in the following link:
    MSP430F55xx_usci_i2c_standard_master.c
    MSP430F55xx_usci_i2c_standard_slave.c
    dev.ti.com/.../

**Attention** This is a public forum