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.

MSP430FR5994: INTERFACING ISSUE

Part Number: MSP430FR5994

Hi.

I was trying to store and retrieve ADXL345 accelerometer data into AT24C256 EEPROM.But when i run the program some garbage values are printing on output. The accelerometer output is not storing into EEPROM.I'm sharing the piece of code please help me.

///////////////////  main.c  /////////////////

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


    LPM1_Clock_config();
    // I2C pins
    P7SEL0 |= BIT0 | BIT1;
    P7SEL1 &= ~(BIT0 | BIT1);
    PM5CTL0 &= ~LOCKLPM5;
    // i2c Configuration
    initI2C();
    uart_config();
    power_ctrl();
    while (1)
    {

        int ADXL345_Dev_id, res_data,bw_data,data_format,count;
        I2C_Master_ReadReg(0x53,0x32,6);
        X1=((ReceiveBuffer[1]<<8)|ReceiveBuffer[0]);
        Y1=((ReceiveBuffer[3]<<8)|ReceiveBuffer[2]);
        Z1=((ReceiveBuffer[5]<<8)|ReceiveBuffer[4]);
        memset(addr,0,sizeof(addr));
        sprintf(addr,"X1=%d,Y1=%d,Z1=%d\r\n",X1,Y1,Z1);
        count=strlen(addr);
       // id_print(addr);
      //  if(count<=5)
        //{
        I2C_Master_WriteReg(0x50,0x00,addr,count);
        //count++;
        //}
        __delay_cycles(8000000);
        I2C_Master_ReadReg(0x50,0x00,count);
        for(i=0;i<=count;i++)
        {
        X[i]=ReceiveBuffer[i];
        }
       // i= atoi(X);
        // printf("%s\r\n",i);
        //sprintf(addr1,"x=%d,y=%d,z=%d\r\n",i);
        sprintf(addr1,"x=%d,y=%d,z=%d\r\n",X);
        id_print(addr1);

        UCA0IE &= ~UCTXIE;
        UCA0IE &= ~UCTXCPTIE;
        __delay_cycles(8000000);
    }
    return 0;
}


////////////////  i2c.h   //////////////////


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

//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************

#define LED_OUT     P1OUT
#define LED_DIR     P1DIR
#define LED0_PIN    BIT0
#define LED1_PIN    BIT1

//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************

#define SLAVE_ADDR  0x50

/* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
 * The slave will send example SlaveTypeX buffers in response.
 *
 * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
 * The slave will initialize itself to receive MasterTypeX example buffers.
 * */

#define CMD_TYPE_0_SLAVE      0
#define CMD_TYPE_1_SLAVE      1
#define CMD_TYPE_2_SLAVE      2

#define CMD_TYPE_0_MASTER      3
#define CMD_TYPE_1_MASTER      4
#define CMD_TYPE_2_MASTER      5

#define TYPE_0_LENGTH   1
#define TYPE_1_LENGTH   2
#define TYPE_2_LENGTH   6

#define MAX_BUFFER_SIZE     20

volatile int Rx_index=0;
volatile unsigned int Rx_key=0;
volatile int Tx_index=0;
volatile unsigned int Tx_key=0;
int size=0;
unsigned char Data[15]="";
unsigned char RXData[5]="";
//uint8_t address1;
//uint8_t address2;
/* MasterTypeX are example buffers initialized in the master, they will be
 * sent by the master to the slave.
 * SlaveTypeX are example buffers initialized in the slave, they will be
 * sent by the slave to the master.
 * */

uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};


uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};

//******************************************************************************
// General I2C State Machine ***************************************************
//******************************************************************************

typedef enum I2C_ModeEnum{
    IDLE_MODE,
    NACK_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_LSB_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    SWITCH_TO_RX_MODE,
    SWITHC_TO_TX_MODE,
    TIMEOUT_MODE
} I2C_Mode;


/* Used to track the state of the software state machine*/
I2C_Mode MasterMode = IDLE_MODE;

/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;
uint8_t TransmitRegAddr_1 = 0;
/* ReceiveBuffer: Buffer used to receive data in the ISR
 * RXByteCtr: Number of bytes left to receive
 * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
 * TransmitBuffer: Buffer used to transmit data in the ISR
 * TXByteCtr: Number of bytes left to transfer
 * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
 * */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;



/* I2C Write and Read Functions */

/* For slave device with dev_addr, writes the data specified in *reg_data
 *
 * dev_addr: The slave device address.
 *           Example: SLAVE_ADDR
 * reg_addr: The register or command to send to the slave.
 *           Example: CMD_TYPE_0_MASTER
 * *reg_data: The buffer to write
 *           Example: MasterType0
 * count: The length of *reg_data
 *           Example: TYPE_0_LENGTH
 *  */
I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count);

/* For slave device with dev_addr, read the data specified in slaves reg_addr.
 * The received data is available in ReceiveBuffer
 *
 * dev_addr: The slave device address.
 *           Example: SLAVE_ADDR
 * reg_addr: The register or command to send to the slave.
 *           Example: CMD_TYPE_0_SLAVE
 * count: The length of data to read
 *           Example: TYPE_0_LENGTH
 *  */
I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);


I2C_Mode  I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)//0x53,0,1
{

    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
   // address1=dev_addr;
    if(dev_addr==0x53)
          {
           TransmitRegAddr = reg_addr;
          }
    else
          {
           TransmitRegAddr = (reg_addr >> 8);//MSB
           TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
          }
    RXByteCtr = count;//1
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    /* Initialize slave address and interrupts */
    UCB2I2CSA = dev_addr;//0X53
    UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
    UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB2IE |= UCTXIE;                        // Enable TX interrupt

    UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __enable_interrupt();
    //for(i=0;i<1000;i++);
    __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts

    return MasterMode;
}


I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
{
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    //TransmitRegAddr = reg_addr;//0X32
    //address2=dev_addr;
    if(dev_addr==0x53)
       {
        TransmitRegAddr = reg_addr;
       }
    else
       {
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        }
    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);

    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB2I2CSA = dev_addr;
    UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
    UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB2IE |= UCTXIE;                        // Enable TX interrupt

    UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __bis_SR_register(LPM0_bits + GIE);      // Enter LPM0 w/ interrupts

    return MasterMode;
}

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
        dest[copyIndex] = source[copyIndex];
    }
}


//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB2RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
        rx_val = UCB2RXBUF;
        if (RXByteCtr)
        {
          ReceiveBuffer[ReceiveIndex++] = rx_val;
          RXByteCtr--;
        }

        if (RXByteCtr == 1)
        {
          UCB2CTLW0 |= UCTXSTP;
        }
        else if (RXByteCtr == 0)
        {
          UCB2IE &= ~UCRXIE;
          MasterMode = IDLE_MODE;
          __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
        }
        break;

    case USCI_I2C_UCTXIFG0:                  // Vector 24: TXIFG0

        switch (MasterMode)
        {
          case TX_REG_ADDRESS_MODE:
              if(TransmitRegAddr==0x50)
              {
                 UCB2TXBUF = TransmitRegAddr;   //0X32 MSB
                 MasterMode = TX_LSB_MODE;
              }
              else
              {
                 UCB2TXBUF = TransmitRegAddr;
                 if (RXByteCtr)
                 MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                 else
                 MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
              }
              break;
          case TX_LSB_MODE:
              UCB2TXBUF = TransmitRegAddr_1; //LSB
              if (RXByteCtr)
                  MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
              else
                  MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
              break;
          case SWITCH_TO_RX_MODE:
              UCB2IE |= UCRXIE;              // Enable RX interrupt
              UCB2IE &= ~UCTXIE;             // Disable TX interrupt
              UCB2CTLW0 &= ~UCTR;            // Switch to receiver
              MasterMode = RX_DATA_MODE;     // State state is to receive data
              UCB2CTLW0 |= UCTXSTT;          // Send repeated start
              if (RXByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB2CTLW0 & UCTXSTT));
                  UCB2CTLW0 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (TXByteCtr)
              {
                  UCB2TXBUF = TransmitBuffer[TransmitIndex++];  // data=9
                 // UCB2CTLW0 |= UCTXSTP;
                  TXByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB2CTLW0 |= UCTXSTP;                   // Send stop condition
                  MasterMode = IDLE_MODE;
                  UCB2IE &= ~UCTXIE;                      // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
              }
              break;

          default:
              __no_operation();
              break;
        }
        break;
    default: break;
  }
}

  • >  sprintf(addr1,"x=%d,y=%d,z=%d\r\n",X);

    You can't use sprintf() with an array like this. One possible alternative:

    >  sprintf(addr1,"x=%d,y=%d,z=%d\r\n", X[0], X[1], X[2]);

    ----------

    How is your X[] array declared? You're writing into it using "count", which is the result of a strlen() and thus might be larger than you think.

    ----------

    I don't see any code which writes to the EEPROM.

  • No need to memset() before you use sprintf(). sprintf will append the trailing '\0'.

    Are you sure addr and addr1 are big enough to hold your strings?

  • Hi Bruce

    1) I have changed my sprintf statement as you suggested. And I'm declared my array as unsigned char X[20]; But still some values are getting and those are repeating continuously.

    2) I think writing function is not happening  1st. 

    3)I have a doubt that 1st I'm passing the string(addr) of accelerometer values to eeprom. For example lets assume values as X1=10,Y1=-40,Z=120.I'm passing these values as string therefore each number will store in each address location as 1 byte in EEPROM. So totally 9 locations EEPROM consumes including NULL. But while retrieving  How can we retrieve same data to same as X=10,Y=-40,Z=120. Or If we go with storing integers 1st values can be stored easily but it is again getting tough for storing next X,Y,Z values. So could you please suggest me weather there any better way to solve this issue?

  • That is totally up to you. I would think that storing as an integer would be better, but atoi() can convert a null terminated string to an integer.

  • Hi keith

    Even i thought the same and tried accordingly but no change in the output. First of all the data is not storing in the EEPROM i think.

  • I suggest you take a step back.

    Write a program that only stores and retrieves data from the eeprom.

    Write a program that only gets the accelerometer data

    Combine the two as required.

  • >  case TX_REG_ADDRESS_MODE:
    > if(TransmitRegAddr==0x50)

    I suspect this comparison should be with dev_addr rather than TransmitRegAddr. The data sheet (doc0670) doesn't say what happens if you only send one address byte; it may be that it is ignored, which would cause your read to start at the end of the string in the EEPROM.

    What values do you see in the  UART output? A %c format might be more appropriate. If you breakpoint at strategic spots in main (breakpointing in the i2c routines can be tricky) you can see what data you're actually working with.

    [Edit: fixed typo.]

  • Hi keith

    Yes already i have interfaced accelerometer and eeprom seperately with MSP430FR5994. I could write and read 1 integer value on EEPROM .After confirming that i have started this merging of both.But as u said i tried to write and  read 3 integers into EEPROM But the data is not writing into eeprom.I'm sharing the piece of code here please help me.

    /////////////////////  main.c  ///////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    uint16_t X1;
    uint16_t Y1;
    uint16_t Z1;
    //uint16_t X=Y=Z=0;
    float f=0.004;
    int device_address= 0x50;
    char addr[30]="";
    char device_id[6]="";
    char string[10]="started";
    uint8_t num[5]={27};
    uint8_t x=10;
    uint8_t y=20;
    uint8_t z=30;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
            printf("started\r\n");
            I2C_Master_WriteReg(0x50,0x00,x,1);
            I2C_Master_WriteReg(0x50,0x01,y,1);
            I2C_Master_WriteReg(0x50,0x02,z,1);
            __delay_cycles(8000000);
            I2C_Master_ReadReg(0x50,0x00,1);
            X1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x01,1);
            Y1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x02,1);
            Z1=ReceiveBuffer[0];
            sprintf(addr,"X=%d,Y=%d,Z=%d\r\n",X1,Y1,Z1);
            id_print(addr);
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    
    
    /////////////////// i2c.h    ////////////////////////
    
    
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    
    #define LED_OUT     P1OUT
    #define LED_DIR     P1DIR
    #define LED0_PIN    BIT0
    #define LED1_PIN    BIT1
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x50
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define CMD_TYPE_0_MASTER      3
    #define CMD_TYPE_1_MASTER      4
    #define CMD_TYPE_2_MASTER      5
    
    #define TYPE_0_LENGTH   1
    #define TYPE_1_LENGTH   2
    #define TYPE_2_LENGTH   6
    
    #define MAX_BUFFER_SIZE     20
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    char RXData[5]="";
    
    /* MasterTypeX are example buffers initialized in the master, they will be
     * sent by the master to the slave.
     * SlaveTypeX are example buffers initialized in the slave, they will be
     * sent by the slave to the master.
     * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_LSB_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    uint8_t TransmitRegAddr_1 = 0;
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    
    I2C_Mode  I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __enable_interrupt();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        //TransmitRegAddr = reg_addr;//0X32
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B2_VECTOR
    __interrupt void USCI_B2_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB2RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            rx_val = UCB2RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB2CTLW0 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB2IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
            }
            break;
    
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  UCB2TXBUF = TransmitRegAddr;//0X32 MSB
                  MasterMode = TX_LSB_MODE;
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_1; //LSB
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
              case SWITCH_TO_RX_MODE:
                  UCB2IE |= UCRXIE;              // Enable RX interrupt
                  UCB2IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB2CTLW0 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB2CTLW0 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB2CTLW0 & UCTXSTT));
                      UCB2CTLW0 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB2TXBUF = TransmitBuffer[TransmitIndex++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB2CTLW0 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB2IE &= ~UCTXIE;                       // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;
        default: break;
      }
    }

  • Hi Bruce

    I have compared with dev_addr only I did'nt compared with TransmitRegAddr.  I have given condition as if(dev_addr==0x53).

    I could see some values like this but these are wrong values because all these values are got when i keep the accelerometer in base. if I change the orientation values should change and also negetive values should come.If i interface only accelerometer it is working great but when i merge code with EEPEOM it is not working  and also not storing in EEPROM. 

    X=45,Y=97,Z=110
    X=100,Y=45,Z=97
    X=98,Y=99,Z=100
    X=101,Y=102,Z=103
    X=104,Y=105,Z=106
    X=107,Y=49,Z=61
    X=54,Y=44,Z=89
    X=49,Y=61,Z=49
    X=52,Y=44,Z=90
    X=49,Y=61,Z=49
    X=57,Y=50,Z=13
    X=10,Y=10,Z=13
    X=10,Y=10,Z=0
    X=0,Y=0,Z=0
     

  • When I read these values as ASCII, I see something like: "-and-abcdefghijk1=14,Z1=14,Z1=192\r\n\n\r\n".

    Some of this looks familiar, so I suspect you are writing to the EEPROM but you're not using the (EEPROM) address you think you are. What does that case statement I mentioned look like now?

    Since you're writing a string, you could try formatting X[] using "%s". Just make sure to  add the string terminator with something like X[count]='\0';

  • Hi Bruce

    I'm using EEPROM address as a function argument as 0x50  in function call and comparing the address in write and read function body to store the data. and when i use %s it is not getting the proper data 1st the data is not storing into EEPROM even though  i use the address. I tried to store integer values into EEPROM in seperate program. But in there also it is not storing. I'm sharing that code here. please help me.

    ////////////   main.c  /////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    
    char* X[10];
    uint16_t X1;
    uint16_t Y1;
    uint16_t Z1;
    
    int device_address= 0x50;
    char addr[30]="";
    char device_id[6]="";
    
    int x=10;
    int y=20;
    int z=30;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
            int i;
            id_print("STARTED\r\n");
                                             ///  WRITING
            I2C_Master_WriteReg(0x50,0x00,x,1);
            id_print("x-written\r\n");
            __delay_cycles(8000000);
    
            I2C_Master_WriteReg(0x50,0x01,y,1);
            id_print("y-written\r\n");
            __delay_cycles(8000000);
    
            I2C_Master_WriteReg(0x50,0x02,z,1);
            id_print("z-written\r\n");
            __delay_cycles(8000000);
                                            ///  READING
            I2C_Master_ReadReg(0x50,0x00,1);
            X1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x01,1);
            Y1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x02,1);
            Z1=ReceiveBuffer[0];
            sprintf(addr,"X=%d,Y=%d,Z=%d\r\n",X1,Y1,Z1);
            id_print(addr);
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    
    
    ///////////////////   i2c.h  ///////////////////////
    
    //******************************************************************************
    //   MSP430FR599x Demo - eUSCI_B2, I2C Master multiple byte TX/RX
    //
    //   Description: I2C master communicates to I2C slave sending and receiving
    //   3 different messages of different length. I2C master will enter LPM0 mode
    //   while waiting for the messages to be sent/receiving using I2C interrupt.
    //   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    //                                     /|\ /|\
    //                   MSP430FR5994      4.7k |
    //                 -----------------    |  4.7k
    //            /|\ |             P7.1|---+---|-- I2C Clock (UCB2SCL)
    //             |  |                 |       |
    //             ---|RST          P7.0|-------+-- I2C Data (UCB2SDA)
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //
    //   Nima Eskandari and Ryan Meredith
    //   Texas Instruments Inc.
    //   January 2018
    //   Built with CCS V7.3
    //******************************************************************************
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    
    #define LED_OUT     P1OUT
    #define LED_DIR     P1DIR
    #define LED0_PIN    BIT0
    #define LED1_PIN    BIT1
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x50
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define CMD_TYPE_0_MASTER      3
    #define CMD_TYPE_1_MASTER      4
    #define CMD_TYPE_2_MASTER      5
    
    #define TYPE_0_LENGTH   1
    #define TYPE_1_LENGTH   2
    #define TYPE_2_LENGTH   6
    
    #define MAX_BUFFER_SIZE     20
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    char RXData[5]="";
    
    /* MasterTypeX are example buffers initialized in the master, they will be
     * sent by the master to the slave.
     * SlaveTypeX are example buffers initialized in the slave, they will be
     * sent by the slave to the master.
     * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_LSB_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    uint8_t TransmitRegAddr_1 = 0;
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    
    I2C_Mode  I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __enable_interrupt();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        //Copy register data to TransmitBuffer
        CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(LPM0_bits + GIE);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B2_VECTOR
    __interrupt void USCI_B2_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB2RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            rx_val = UCB2RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB2CTLW0 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB2IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
            }
            break;
    
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
    
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  UCB2TXBUF = TransmitRegAddr;//0X32 MSB
                  MasterMode = TX_LSB_MODE;
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_1; //LSB
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
              case SWITCH_TO_RX_MODE:
                  UCB2IE |= UCRXIE;              // Enable RX interrupt
                  UCB2IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB2CTLW0 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB2CTLW0 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB2CTLW0 & UCTXSTT));
                      UCB2CTLW0 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB2TXBUF = TransmitBuffer[TransmitIndex++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB2CTLW0 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB2IE &= ~UCTXIE;                       // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;
        default: break;
      }
    }
    
    
    
    
    
    
    
    
    
     

  • >  I2C_Master_WriteReg(0x50,0x00,x,1);

    The 3rd argument to WriteReg should be a "uint8_t *"  pointer, and you're supplying it a small integer. This will write the (unknown) value found at location 10 to the EEPROM. (I'm somewhat surprised the compiler didn't issue a Warning for this.) 

    You should declare "uint8_t x" and use:

    >  I2C_Master_WriteReg(0x50,0x00,&x,1);

    Similarly for the WriteReg calls for y and z.

  • Hi Bruce

    I did as you suggested but when i see the output x and  y values are getting proper but z value is getting wrong. and when i try to store string the string is not getting store in EEPROM.So please help me 

  • Which code are we talking about? What wrong value are you getting?

    In the "string" version: Did you fix that case statement (really the if() which follows it) that I mentioned?

  • Hi Bruce

    I was talking about storing integer values in the EEPROM. I have followed the same as you said. When i pass x=10,y=20,z=30 EEPROM is storing these values. But when i pass x=100,y=200,z=300 this EEPROM is storing as x=100 y=200,z=44. And coming to the string storing code YES there also i have followed that if() statement but nothing is storing into it. What i thought was if any of these two ( interger storing version or string storing version) worked fine i will use that code on my main code. But none of them are working good.  So please help me.

  • 10,20, and 30 all fit into a byte (uint8_t), but 300 doesn't. 300(mod 256)=44.

    If you need to write/read values > 255, you should go back to uint16_t for x,y,z, and

    1) For writing, use something like:

    > I2C_Master_WriteReg(0x50,0x00,(uint8_t *)&x, 2);

    where 2=sizeof(uint16_t)

    2) For reading, you need to reconstruct the uint16_t with something like:

    I2C_Master_ReadReg(0x50,0x00,2);
    X1=ReceiveBuffer[0] | (ReceiveBuffer[1] << 8);

    since the high byte is at index [1] ("little endian").

    3) Step your EEPROM addresses by 2 rather than 1.

  • Hi Bruce

    Thankyou for your replay yes I have done the same thing 5hours back and working great but facing issue on storing string. I'm sharing the code here please help me.

    /////////////////  main.c  ////////////////////
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    
    uint16_t X1,Y1,Z1;
    char* X;
    
    uint16_t address1=0x00;
    uint16_t address2=0x00;
    char addr[30]="";
    char addr1[30]="";
    char device_id[6]="";
    int i,count=0,j;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        power_ctrl();
        while (1)
        {
               int i;
               uint8_t len;
            
               I2C_Master_ReadReg(0x53,0x32,6);
               X1=((ReceiveBuffer[1]<<8)|ReceiveBuffer[0]);
               Y1=((ReceiveBuffer[3]<<8)|ReceiveBuffer[2]);
               Z1=((ReceiveBuffer[5]<<8)|ReceiveBuffer[4]);
    
               sprintf(addr,"%d,%d,%d",X1,Y1,Z1);
               len=strlen(addr);
    
                     I2C_Master_WriteReg(0x50,address1,addr,len);
                     address1=len+1;
                    
                
                   I2C_Master_ReadReg(0x50,address2,len);
                   for(i=0;i<=len;i++)
                   {
                   X[i]=ReceiveBuffer[i];
                   }
                   printf("%s",X);
                   address2=len+1;
               UCA0IE &= ~UCTXIE;
               UCA0IE &= ~UCTXCPTIE;
               __delay_cycles(8000000);
           }
    }
    
    
    /////////////////////  i2c.h  /////////////////////
    
    
    #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    
    #define LED_OUT     P1OUT
    #define LED_DIR     P1DIR
    #define LED0_PIN    BIT0
    #define LED1_PIN    BIT1
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x50
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define CMD_TYPE_0_MASTER      3
    #define CMD_TYPE_1_MASTER      4
    #define CMD_TYPE_2_MASTER      5
    
    #define TYPE_0_LENGTH   1
    #define TYPE_1_LENGTH   2
    #define TYPE_2_LENGTH   6
    
    #define MAX_BUFFER_SIZE     20
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    //unsigned char* Data;
    char RXData[5]="";
    //uint8_t address1;
    //uint8_t address2;
    /* MasterTypeX are example buffers initialized in the master, they will be
     * sent by the master to the slave.
     * SlaveTypeX are example buffers initialized in the slave, they will be
     * sent by the slave to the master.
     * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_LSB_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    uint8_t TransmitRegAddr_1 = 0;
    uint8_t TransmitRegAddr_2 = 0;
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);
    
    
    I2C_Mode  I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
       // address1=dev_addr;
        if(dev_addr==0x53)
              {
               TransmitRegAddr = reg_addr;
              }
        else
              {
               TransmitRegAddr_1 = (reg_addr >> 8);//MSB
               TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
              }
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __enable_interrupt();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        //TransmitRegAddr = reg_addr;//0X32
        //address2=dev_addr;
        if(dev_addr==0x53)
           {
            TransmitRegAddr = reg_addr;
           }
        else
           {
            TransmitRegAddr_1 = (reg_addr >> 8);//MSB
            TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
            }
           CopyArray(reg_data, TransmitBuffer, count);
    
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __enable_interrupt();
        __bis_SR_register(LPM0_bits + GIE);      // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B2_VECTOR
    __interrupt void USCI_B2_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB2RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            rx_val = UCB2RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB2CTLW0 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB2IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
            }
            break;
    
        case USCI_I2C_UCTXIFG0:                  // Vector 24: TXIFG0
    
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  if(UCB2I2CSA==0x50)
                  {
                     UCB2TXBUF = TransmitRegAddr_1;   //0X32 MSB
                     MasterMode = TX_LSB_MODE;
                  }
                  else
                  {
                     UCB2TXBUF = TransmitRegAddr;
                     if (RXByteCtr)
                     MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                     else
                     MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  }
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_2; //LSB
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
              case SWITCH_TO_RX_MODE:
                  UCB2IE |= UCRXIE;              // Enable RX interrupt
                  UCB2IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB2CTLW0 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;     // State state is to receive data
                  UCB2CTLW0 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB2CTLW0 & UCTXSTT));
                      UCB2CTLW0 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB2TXBUF = TransmitBuffer[TransmitIndex++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB2CTLW0 |= UCTXSTP;                   // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB2IE &= ~UCTXIE;                      // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;
        default: break;
      }
    }

  • What issue are you seeing?

    > char* X;

    This creates a pointer (your array) to memory location 0 ("reserved" memory) which is at best hazardous. Try instead something like:

    > char X[30];  // Same size as addr[]

  • Hi Bruce 

    i could see the string while reading . I was trying to store the same string contineously and read it back. I'm passing string as "hello" But while reading the string is getting with shuffled after some sometime .I'm sharing that piece of code here please help me

     

    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
    
            
            uint8_t count1;int i;
            count1=strlen(string);
        
            I2C_Master_WriteReg(0x50,address1,string,count1);
            address1=address1+count1;
            sprintf(ad1,"\r\n%x\r\n",address1);
            id_print(ad1);
            __delay_cycles(8000000);
    
          
            I2C_Master_ReadReg(0x50,address2,count1);
            for(i=0;i<=count1;i++)
            {
            X[i]=ReceiveBuffer[i];
            }
            sprintf(addr,"X=%s\r\n",X);
            id_print(addr);
            address2=address2+count1;
            sprintf(ad2,"%x\r\n",address2);
            id_print(ad2);
           
    
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    

  • Can you give an example of the shuffling?

    I suspect you're encountering address wrapping (they call it "roll over"), i.e. what happens when certain addressing boundaries are reached. This is done differently for writes and reads, and is described in data sheet (doc0670) pages 10-11.

    For this reason it is usually best to work with fixed-length records whose size divides the page size (in this case 64) evenly.

  • I'm using AT24C256 EEPROM. It's maximum size is 32kb so maximum address would be 7FFF. I'm not sure weather the data  over-writes from zero'th location or not once it reaches to 7FFF location. But here as I'm incrementing the address manually that address is going beyond 7FFF and printing and wonder is the data is also printing eventhough it crossed the memory. But I'm not able to understand how and  now I'm getting a doubt that is the EEPROM storing data or not. 

    I'm passed the string as "sindhusha" and Here is the shuffled output.

    7e
    X=sindhusha
    7e
    
    87
    X=sidhushaa
    87
    
    90
    X=sindhusha
    90
    
    99
    X=sindhusha
    99
    
    a2
    X=sindhusha
    a2
    
    ab
    X=sindhusha
    ab
    
    b4
    X=sindhusha
    b4
    
    bd
    X=sindhusha
    bd
    
    c6
    X=sinhusha
    c6
    
    cf
    X=sindhusha
    cf
    
    d8
    X=sindhusha
    d8
    
    e1
    X=sindhusha
    e1
    
    ea
    X=sindhusha
    ea
    
    f3
    X=sindhusha
    f3
    
    fc
    X=sindhusha
    fc
    
    105
    X=sindushas
    105
    
    10e
    X=shaasindh
    10e
    
    117
    X=ushasindh
    117
    
    120
    X=ushasindh
    120
    
    129
    X=ushasindh
    129
    
    132
    X=ushasindh
    132
    
    13b
    X=ushasindh
    13b
    
    144
    X=ushasndhu
    144
    
    14d
    X=shaisindh
    14d
    
    156
    X=ushasindh
    156
    
    15f
    X=ushasindh
    15f
    
    168
    X=ushasindh
    168
    
    171
    X=ushasindh
    171
    
    17a
    X=ushasindh
    17a
    
    183
    X=ushasidhu
    183
    
    18c

  • >c6
    >X=sinhusha
    >c6

    This write crossed a page boundary. The write address wrapped, but the read address didn't. At the end of the memory (0x7FFF+1) the write and read addresses will wrap to different values. I encourage you to read pages 10-11 of the datasheet (look for "roll over").

    Something like "hello678" would probably work well.

  • ok i will read but i wanted to use sequential write and read rather using the page concept. Because i wanted to collect the data randomly on my main project so. will the sequential concept works?

  • The page concept (for writing) is imposed on you, so you need to work within it. There is no "sequential write", only "byte" and "page". These are really the same thing, except that writing a (single) byte can't cross a page boundary.

    If you need to write non-divisor-of-64-sized records, you have the option of anticipating when a write will cross a page boundary and splitting it into two transactions. This is a bit of a pain, but can be done.

    If you want to use variable-length records, you should (additionally) put some thought into how you'll find them later.

  • Hi bruce 

    I'm sorry I was using byte write and reading by using sequential read by mistake i have typed like that previously. On my main project i will store variable length only so all ways i need to track the length to store next data.One more thing can you clarify me that will the eeprom will start over-writing from address location of zero once it get filled completely?

  • A Byte Write is a Page Write with size=1. The code above uses size>1, so they are Page Writes.

    You could in theory write each string one byte (transaction size=1) at a time. You would never have to think about Page addressing, but it would be rather slow (5msec "penalty" for each byte).

    If you perform a write which Extends past the end of the current page, the address wraps back to the beginning of that page [datasheet p. 10]. That would apply to the final page in the memory as well. If you Begin a write at address (0x7FFF+1)=0x8000, that will write to address 0x0000 since the high-order address bit is ignored [datasheet Fig. 9].

  • Hi Bruce

    Now my code is working fine but I got a new doubt that I was storing data into eeprom and retrieving but I'm sure that data willl store in the eeprom when the power supply was there. But when i power off the microcontroller and re-connect again will my eeprom is capable to store data from where it stopped.

    for example lets say initially I'm storing x=10,y=20,z=30 in 0x0000,0x0001,0x0002,0x0003 and I'm incrementing the address and data in the next write cycle i.e.,x=11,y=21,z=31 in 0x0004,0x0005,0x0006.and now I have disconnected the microcontroller and re-connected  at this time I wanted to store x=12,y=22,z=32 in 0x0007,0x0008,0x0009. will this be possible? If yes can you please help me to execute this thing. when I try my eeprom is storing from 1st onwards. i.e,x=10,y=20,z=30 in 0x0000,0x0001,0x0002,0x0003. so please help me.  

  • This is in the general case a fairly complex problem. I'm not really in a position to walk you through a complete design, but here are some notions.

    The simpler methods use a memory scan at startup, finding the boundary between newer data and (a) nonsense, perhaps erased bytes, or (b) older data, if you write your data cyclically. This could take a while -- reading the entire memory takes close to a second in the best case.

    All the methods I know add extra data ("redundancy") to allow you to distinguish these cases. Consider adding 2 bytes (total (6+2) byte record). One should be a checksum/CRC to detect nonsense. The other can be used to distinguish old vs new data. A simple use might be a "generation counter" which you increment each time you fill the memory and circle back. If your scan finds a record whose counter is different from that of the previous, that indicates the boundary.

    You could speed up or avoid the startup scan by using a reserved EEPROM area that contains an index to the final record. However, this introduces a different set of complexities since you will be writing this area very often, and could wear out (exceed Write Endurance of) those EEPROM cells. (Keyword: "Wear Leveling")

    People have been doing this for a long time, and a Web search can turn up a collection of methods based on different assumptions and requirements.

  • Hi Bruce

    Can I get example code of FRAM read. I found FRAM write example code but I did'nt find FRAM read. So can you please send me some example code? 

  • If you have a new question you really should start a new thread.

    Nothing special needs to be done to read FRAM. In the Example (msp430fr599x_framwrite.c) you could reference the array FRAM_write by saying (e.g.) "int x = 1 + FRAM_write[3];". If you declare a variable "const" it is normally placed in FRAM.

    Without knowing your goal, it's hard to say more.

  • Hi,

    I'm facing an issue while interfacing storing accelerometer with eeprom while doing I could able to write and read the positive data of accelerometer but I could'nt read the negative values. Instead the negative value is getting stored as its equivalent positive value.I have searched in some sites to know how to store a negative value but i did'nt find proper matter.So can you please help me to slove this issue.I'm sharing EEPROM part of code.Write_address is 0x01.

    .

     read_address=write_address;
            __delay_cycles(8000000);
            I2C_Master_WriteReg(0x50,write_address,X1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"X1=%d\r\n",X1);
            id_print(addr);
    
    
            I2C_Master_WriteReg(0x50,write_address,Y1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"Y1=%d\r\n",Y1);
            id_print(addr);
    
    
            I2C_Master_WriteReg(0x50,write_address,Z1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"Z1=%d\r\n",Z1);
            id_print(addr);
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            x=ReceiveBuffer[0];
            sprintf(addr,"x=%d\r\n",x);
            id_print(addr);
            read_address=read_address+2;
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            y=ReceiveBuffer[0];
            sprintf(addr,"y=%d\r\n",y);
            id_print(addr);
            read_address=read_address+2;
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            z=ReceiveBuffer[0];
            sprintf(addr,"z=%d\r\n",z);
            id_print(addr);
            read_address=read_address+2;
    
    
    
    
            sprintf(addr,"Received_data x=%d,y=%d,z=%d\r\n",x,y,z);
            id_print(addr);
            
            
            /////////////////// i2c.h  ////////////////////
            
            #include <msp430.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    //******************************************************************************
    // Pin Config ******************************************************************
    //******************************************************************************
    
    #define LED_OUT     P1OUT
    #define LED_DIR     P1DIR
    #define LED0_PIN    BIT0
    #define LED1_PIN    BIT1
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    //#define SLAVE_ADDR  0x50
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define CMD_TYPE_0_MASTER      3
    #define CMD_TYPE_1_MASTER      4
    #define CMD_TYPE_2_MASTER      5
    
    #define TYPE_0_LENGTH   1
    #define TYPE_1_LENGTH   2
    #define TYPE_2_LENGTH   6
    
    #define MAX_BUFFER_SIZE     20
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    //unsigned char* Data;
    char RXData[5]="";
    //uint8_t address1;
    //uint8_t address2;
    /* MasterTypeX are example buffers initialized in the master, they will be
     * sent by the master to the slave.
     * SlaveTypeX are example buffers initialized in the slave, they will be
     * sent by the slave to the master.
     * */
    
    uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
    uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
    uint8_t MasterType0 [TYPE_0_LENGTH] = { 11};
    
    
    uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
    uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
    uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    typedef enum I2C_ModeEnum{
        IDLE_MODE,
        NACK_MODE,
        TX_REG_ADDRESS_MODE,
        RX_REG_ADDRESS_MODE,
        TX_LSB_MODE,
        TX_DATA_MODE,
        RX_DATA_MODE,
        SWITCH_TO_RX_MODE,
        SWITHC_TO_TX_MODE,
        TIMEOUT_MODE
    } I2C_Mode;
    
    
    /* Used to track the state of the software state machine*/
    I2C_Mode MasterMode = IDLE_MODE;
    
    /* The Register Address/Command to use*/
    uint8_t TransmitRegAddr = 0;
    uint8_t TransmitRegAddr_1 = 0;
    uint8_t TransmitRegAddr_2 = 0;
    /* ReceiveBuffer: Buffer used to receive data in the ISR
     * RXByteCtr: Number of bytes left to receive
     * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
     * TransmitBuffer: Buffer used to transmit data in the ISR
     * TXByteCtr: Number of bytes left to transfer
     * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
     * */
    uint16_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint16_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 0;
    
    
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint16_t dev_addr, uint16_t reg_addr, uint16_t reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_ReadReg(uint16_t dev_addr, uint16_t reg_addr, uint8_t count);
    void CopyArray(uint16_t *source, uint16_t *dest, uint8_t count);
    
    
    I2C_Mode  I2C_Master_ReadReg(uint16_t dev_addr, uint16_t reg_addr, uint8_t count)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
       // address1=dev_addr;
        if(dev_addr==0x53)
              {
               TransmitRegAddr = reg_addr;
              }
        else
              {
               TransmitRegAddr_1 = (reg_addr >> 8);//MSB
               TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
              }
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __enable_interrupt();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint16_t dev_addr, uint16_t reg_addr, uint16_t reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        if(dev_addr==0x53)
           {
            TransmitRegAddr = reg_addr;
           }
        else
           {
            TransmitRegAddr_1 = (reg_addr >> 8);//MSB
            TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
            }
       // CopyArray(reg_data, TransmitBuffer, count);
        TransmitBuffer[0]=(reg_data & 0xFF);
        TransmitBuffer[1]=((reg_data>>8) & 0xFF);
        TXByteCtr = count;
        RXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
    
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;
        UCB2IFG &= ~(UCTXIFG + UCRXIFG);         // Clear any pending interrupts
        UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
        UCB2IE |= UCTXIE;                        // Enable TX interrupt
    
        UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
        __bis_SR_register(LPM0_bits + GIE);      // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    void CopyArray(uint16_t *source, uint16_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B2_VECTOR
    __interrupt void USCI_B2_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB2RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            rx_val = UCB2RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB2CTLW0 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB2IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
            }
            break;
    
        case USCI_I2C_UCTXIFG0:                  // Vector 24: TXIFG0
    
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  if(UCB2I2CSA==0x50)
                  {
                     UCB2TXBUF = TransmitRegAddr_1;   //0X32 MSB
                     MasterMode = TX_LSB_MODE;
                  }
                  else
                  {
                     UCB2TXBUF = TransmitRegAddr;
                     if (RXByteCtr)
                     MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                     else
                     MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  }
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_2; //LSB
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
              case SWITCH_TO_RX_MODE:
                  UCB2IE |= UCRXIE;              // Enable RX interrupt
                  UCB2IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB2CTLW0 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;     // State state is to receive data
                  UCB2CTLW0 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB2CTLW0 & UCTXSTT));
                      UCB2CTLW0 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB2TXBUF = TransmitBuffer[TransmitIndex++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB2CTLW0 |= UCTXSTP;                   // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB2IE &= ~UCTXIE;                      // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;
        default: break;
      }
    }
    
            
            

  • If X1 is declared as "uint16_t", you should be able to re-interpret it as a 16-bit signed with something like:

    > int16_t signed_X1 = (int16_t)X1;

    Though if that is the case, I expect:

    >  I2C_Master_WriteReg(0x50,write_address,X1,2);

    should be

    >  I2C_Master_WriteReg(0x50,write_address,&X1,2);

**Attention** This is a public forum