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.

I2C important points to be noted for SDA left shift

Other Parts Discussed in Thread: MSP430F2274

Hi all,

          I got  a left   SHIFT  problem on  DAta line  SDA  while using module:USCI_B0 for I2C on  MSP430F2274 that is for device address 0xA0 while checked on the scope it is 0x40 hence I need to make an adjustment 0x50

for device adddress 0x64 u need to put 0x32 and (this is not mention in the user guide or MSPFX22x4  related  mauals but I got this point from SLAA208 page 3 which says intercaing EEprom using I2c) check it once

 

also not some errata USCI25 and USCI27 as given below from slaz043g for msp430f2274

USCI25 - Bug description  Module: USCI, Function: TXIFG is not reset when NACK is received in I2C mode

 

 Description: When the USCI_B module is configured as an I2C master transmitter the TXIFG is not reset after a NACK is received if the master is configured to send a restart (UCTXSTT = 1 and UCTXSTP = 0). 

 

Workaround: Reset TXIFG in software within the NACKIFG interrupt service routine.

 

USCI27 - Bug description  Module: USCI_B, Function: Timing of USCI interrupts may cause device reset due to automatic clear of an IFG.

 

  When certain USCI I2C interrupt flags (IFG) are set and an automatic flag-clearing event on the I2C bus occurs, the program counter may become corrupted. This happens only when the IFG is cleared within a critical time window (~6 CPU clock cycles) after a USCI interrupt request occurs and before the interrupt servicing is initiated.

 

 The affected interrupts are UCBxTXIFG, UCSTPIFG, UCSTTIFG and UCNACKIFG.  The automatic flag-clearing scenarios are described in the following situations:

 

1)      A pending UCBxTXIFG interrupt request is cleared on the falling SCL clock edge following a NACK

2)      . 2) A pending UCSTPIFG, UCSTTIFG, or UCNACKIFG interrupt request is cleared by a following Start condition.

 

 Workaround: 1) Polling the affected flags instead of enabling the interrupts. or 2) Ensuring the above mentioned flag-clearing events occur after a time delay of 6 CPU clock cycles has elapsed since the interrupt request occurred and was accepted. 

 

 

SDA BIT SHIFTing

Also,thegenerationoftheI2CControlByteisdoneinaspecialway.TheMSP430I2CmodulesendsouttheslaveaddressthatisdefinedinthecontrolregisterI2CSA.Notethattheslaveaddressislocatedwithinthecontrolbyteinthebitpositions1to7.ThenumberthatisdefinedintheregisterI2CSAhastobeshiftedonebitpositiontothelefttogettheEEPROMControlByte(Figure3).ForexampleiftheControlByteshouldbe0xA0theslaveaddress(I2CSA)hastobedefinedas0x50.TheR/Wbit,whichisalsolocatedinthecontrolbyte(bit0),ishandledautomaticallybytheselectedtransmitorreceivemode.ThemodeisselectedusingtheI2CTRXbitintheI2CTCTLcontrolregister

  • hello,

    Just a comment - the USCI I2CSA is indeed right-justified. This is mentioned in the register description in the family user's guide: 

    I2CSAx

     

    The I2CSAx bits contain the slave address of the external device to be addressed by the USCI_Bx module. It is only used in master mode. The address is right justified. In 7-bit slave addressing mode, bit 6 is the MSB and bits 9-7 are ignored. In 10-bit slave addressing mode, bit 9 is the MSB.

     -Priya

     

     

     

     

     

     

     

     

  • hi,

        Thank you priya for the comment , I dint take a look at that particular register , bcoz  by seeing examples from the SLAC123C I was using that register directly and so thought it as a hardware problem ok any ways thank you for the reply it helped me  a lot to correct myself  but there must be a detailed explanation regarding that in the user guide regading how to correct it or use it.

    another thing I want to ask ? is there a device specific data sheet for MSP430F2274 other than SLAU144e if so please provide me with the links.

    and regarding the I2C problem I posted the code below for interfacing EEprom AT24C512 with MSP430F2274   //actual device address for AT24c512 is 0XA0 but Im using 0x50 because of Right justified

    I am able to establish communication between MSP and EEPROm but I am not getting written data correctly from exact location 0x0000 word address from EEPROM

          #include "msp430x22x4.h"      

    void USCI_init(void);      
    void I2C_Tx(void);             //actual device address for AT24c512 is 0XA0 but Im using 0x50 because of Right justified
     void I2C_Rx(void);
        volatile  unsigned char c[2]={0};
     

    void main(void)
    {
       WDTCTL = WDTPW + WDTHOLD;                 // Stop Watchdog Timer
         P3DIR |=0xFF;
         P3OUT |=0x00;

    // Assign I2C pins to USCI_B0
      USCI_init();
     
      // ##################UART mode to display the Date and time thru COM port ###########################
     
                             // P3.4,5 = USCI_A0 TXD/RXD
       
      UCA0CTL1 |= UCSSEL_2;                     // SMCLK
      UCA0BR0 = 0x41;                            // 1MHz 9600
      UCA0BR1 = 0x03;                              // 1MHz 9600
      UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
      UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
      //IE2 |= UCA0RXIE;    
     
        // ##################UART mode to display the Date and time thru COM port ###########################
     

      I2C_Tx();

    I2C_Rx();
       }

     

    void USCI_init(void)
    {

      UCB0CTL1 |= UCSWRST;                      // Enable SW reset
      UCB0CTL0 = UCMST+UCMODE_3+UCSYNC;         // I2C Master, synchronous mode
      UCB0CTL1 = UCSSEL_2+UCSWRST;              // Use SMCLK, keep SW reset
      P3SEL |= 0x16; 
      UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB0BR1 = 0;
      UCB0I2CSA = 0x50;                         // Set slave address //actual device address for AT24c512 is 0XA0 but Im using 0x50 because of Right justified
      UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
     

    }

    void I2C_Tx(void)
    {
                      UCB0I2CSA = 0x50;                         // Set slave address //actual device address for AT24c512 is 0XA0 but Im using 0x50 because of Right justified
                        
                UCB0CTL1 |= UCTR+ UCTXSTT;     //start condition
                 while(UCB0CTL1 & UCTXSTT);    //Check for Device Acknowledgement
                while(!UCB0TXIFG);
                 UCB0TXBUF = 0x00;   //word address
                    while(!(UCB0TXIFG));
                      
                       UCB0TXBUF =0x00;        //word address            
                     while(!(UCB0TXIFG));
                         UCB0TXBUF ='B';                //data           
                     while(!(UCB0TXIFG));
                        UCB0TXBUF ='C';                //data         
                    while(!(UCB0TXIFG));
                       UCB0TXBUF ='D';                  //data          
                              UCB0CTL1 |=UCTXSTP;   //stop condition
              
                        }
              

     

         void I2C_Rx(void)   //Random Read for EEPROM
      { 
         
                        // Set slave address and  DUMMY WRITE

                     UCB0I2CSA = 0x50;  //slave address 
                 
        UCB0CTL1 |= UCTR+ UCTXSTT;     //start condition
                   //write to UCB0TXBUF  after SLAVE address
             while(UCB0CTL1 & UCTXSTT);    //Check for Device Acknowledgement
                while(!(UCB0TXIFG));      // check data start condition);
              
                 UCB0TXBUF = 0x00;    //word address from that particular location where written
                   while(!(UCB0TXIFG));      // check data start condition);
             
               //Random Read for EEPROM
            UCB0TXBUF = 0x00;     //word address   from that particular location where written
                  
               UCB0I2CSA = 0x50;  //slave address
               UCB0CTL1 &=~UCTR;       //REceive mode
               UCB0CTL1 |=UCTXSTT;  //Re-START condition
          
              while(!(UCB0RXIFG));
               c[0]=UCB0RXBUF;   //first data byte
                while(!(UCB0RXIFG));

                UCA0TXBUF=UCB0RXBUF;  //2nd data byte
                  while(!(UCB0RXIFG));
               

             UCA0TXBUF=UCB0RXBUF; // 3rd data byte
                      
               UCB0CTL1 |=UCTXSTP;      ///sTOP condition
                           
      }
      

     

     

     

  • Shalom!

     Did you even get the 2274 to interface the AT24C512 correctly without bit banging.

    If so could you share the code?

    Thanks

  • Shalom!

    I am using the AQ430 Quadrovox compiler and looked at thie include file for the 2274/2 chip.

    I  understand that there are two UART units A0 & B0 of which B0 conatins the I2c and SPI units.

    There are different pins for the normal serial and the I2C I/O but I see only one set of interrupts (TX & RX).

    Does this mean that I can not use the normal A0 uart at the same time as the B0 I2C unit?

    Can I use the B0 I2c unit at the same time of the A0 uart in polling mode?

    If not I will have to just bit bang the pins as I must have the normal uart available at all times in this projects.

    Thanks If anyone can enlighten me!

     

     

     

     

     

  • Yes I got the interface between  EEPROm ( using I2C)  and 2274 plz check te codes from my posts on I2c related u will find the codes

**Attention** This is a public forum