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 MSP430F2274 problems in understandin the code

Genius 4170 points
Other Parts Discussed in Thread: MSP430F2274

HEllo,

 

i am currently trying to get a external FRAM running via I2C and my MSP.

First of all i tried to use the Example-Code from appnote "slaa382": Using the USCI I2C Master:

It is workin somehow, but i really do not understand the code which is behind it. I do know how to access my FRAM and i can see the first byte sent is my address, as it is supposed to be. But after my address i do not really understand how to send the right bytes.

 

So if smoeone really is into the I2C stuff and would like to give me some hnits i would be really glad.

 

First of all i write my main.c routine for sending and recieving, it is basically the same as the one used by the app note, with some addiotial thnigs in it. As some might have read before hte I2C tends to get stuck on a low SDA line, so is mine so i toggle both lines as GPIOs several times to get rid of this effect. I dont know what exactly is happening there, but i read this solution in another forum and i tried and and it always gets my I2C to work again after it got stuck by some reasons i do not really understand neither :)

 

#include "msp430f2274.h"
#include "TI_USCI_I2C_master.h"

unsigned char timercounter;
unsigned char array[40] = { 0x0, 0x0, 0x7, 0x6, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb };
unsigned char store[40] = { 13, 13, 13, 13, 13, 13, 13, 0, 0, 0};


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

  BCSCTL1 = CALBC1_8MHZ;
  DCOCTL = CALDCO_8MHZ;
 
   // I2C wieder in Tritt bekommen
   P3SEL &=  ~SDA_PIN;
   P3SEL &=  ~SCL_PIN;

   P3OUT &= ~SCL_PIN;  
   P3OUT &= ~SDA_PIN;  

   P3DIR |= SCL_PIN;   
   P3DIR &= ~SDA_PIN;   
  int temp;
  for(temp = 0; temp<1000; temp++){
   P3OUT ^= SDA_PIN;
   P3OUT ^= SCL_PIN;    
  }

  _EINT();

  TI_USCI_I2C_transmitinit(0xA1,0x14);  // init transmitting with USCI
  while ( TI_USCI_I2C_notready() );         // wait for bus to be free
  if ( TI_USCI_I2C_slave_present(0x50) )    // slave address may differ from
  {                                         // initialization
   
     
    TI_USCI_I2C_transmitinit(0x50,0x14);  // init transmitting with
    while ( TI_USCI_I2C_notready() );         // wait for bus to be free
    TI_USCI_I2C_transmit(4,array);       // start transmitting
   
    TI_USCI_I2C_receiveinit(0x50,0x14);   // init receiving with USCI
    while ( TI_USCI_I2C_notready() );         // wait for bus to be free
    TI_USCI_I2C_receive(4,store);
    while ( TI_USCI_I2C_notready() );         // wait for bus to be free
  }
 
  //LPM3;
 
}

 

 

So i thought i simply write something into my FRAM, at the addresses beginngin from 0x00, and afterwards i could read them out with the   TI_USCI_I2C_receive(4,store); routine.

 

But as always it isnt working that logically, somehow i wont get the bits i was trying to transmit to these addresses.

Lets do that one by one:

unsigned char array[40] = { 0x0, 0x0, 0x7, 0x6, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb };

TI_USCI_I2C_transmit(4,array);       // start transmitting

 

With this i want to write to the FRAM, the first 2 cars in the array are supposed to be my address internally in the FRAM, so starting from address 0x00 i then write another 2 chars in it, the 0x7 and the 0x6. This by the way i cannot see in the osciloscope, perhaps because i set the wrong breakpoints, but frmo my experience i suppose that is should be sent and be available in the FRAM for later actions.

 

TI_USCI_I2C_receive(4,store);

With this i try to get out the written memory blocks from before. This part i can clearly seein the osciloscope, but i see the wron bit patterns, it isnt 7 and 6 i am gettnig but somethign different like only 0 or F( all bits high).

 

 

I am kind of confused about the routine TI presents, if someone is familiar with it,  suppose there are way too many stop conditions in those Interrupt subroutines, that does not really fit my FRAM.

 

Could it be that i have to write a very own routine for my special fujitsu FRAM or should the I2C be the same for every purpose?

Please feel free to help me, or i am wasting another hours on this communication stuff.

 

Thanks for tmie and help.

Seb

 

  • seb said:
    Could it be that i have to write a very own routine for my special fujitsu FRAM or should the I2C be the same for every purpose?

    Yes and no.

    The problem is, I2C is sort of half duplex. During a transaction you can only read or only warite. This was okay for the very first I2C devices, which were simple fire-and-forget output expanders or such. But with increasing device complexity, it became necessary to send commands and retrieve the answers.

    The Ti sample code is not sufficient for that, especially not for devices which require e.g. no stop condition but jsut a repeated start between sending e.g. an address and retrieveing the data from this address.

    So I fear it is best for you to write your own I2C functions. The library funcitons are too high-level to put the required protocol together by calling them, but too low-level to 'just use' them for your purpose.
    There are a large number of I2C devices which can be accessed with these functions (e.g. D/A converters, some digital resistor devices etc.) but there are even more which require a protocol that cannot be simulated with them. And there are a few which cannot be accessed with the USCI I2C at all (requiring a NACK where the USCI doesn't allow you to NACK etc.). In these (luckily rare) cases, you'll need to do bit-banging I2C in software.

    But you can try the following:

    Currently, it looks like your code starts @0x0000, writes two bytes to 0x0000 and 0x0001 and then continues reading 4 bytes from 0x0002 to 0x0005.

    So after writing the bytes to FRAM, you must send another address (2 bytes only this time) to the FRAM and then do a read of 2 bytes. I guess, that the first two bytes of a write will set the address. Any subsequent write or read will increment the address. At least the I2C realtime clock I use works this way. (with a 1-byte address).

    Well, without the datasheet of your FRAM I cannot say for sure.

  • Hello Jens,

     

    indeed you are right, i figured that out yesterday in the evening, now at least the basic read and write codes are working. As you describes i send just a 2 Byte data into the FRAM to determine the address and afterwards i can read out specific memory slots at this address and n,n+1, etc.

     

    I will however try to use the I2C MSP430 MAster Code without DMA access and try to tweak it for my purposes.

     

    Ah and another question, my FRAM seems to be initialised with only High bits. Because when i read out random Bytes i always got 0xF , can you ro someone confirm this, is that normal for every FRAM or even for EEPROM in general, i suppose for EEPROM it isnt since you can only set 1 but have to delete to get 0.

     

    Thank you for your time.

    Seb

  • seb said:
    my FRAM seems to be initialised with only High bits. Because when i read out random Bytes i always got 0xF , can you ro someone confirm this, is that normal for every FRAM or even for EEPROM in general, i suppose for EEPROM it isnt since you can only set 1 but have to delete to get 0.

    FRAM has no global erase funciton. Each bit can be written individually. So there is no 'default' value. It may be that the production test leaves the cells with '1' written. Or intentionally clears them. Whatever. There is no way you can detect whether the FRAM is still unused or so. All you can do us writing a 'magic value' somehwere, and if the magic value isn't there, you can initialize the whole FRAM with your own default value. Like formatting a HD that doesn't have a valid MBR.

    For Flash, the inner working of the flash cells requires that erasing a segments sets all to 1, and cyou can only individually write them to 0. Same for good old UV Eproms. I don't kow about EEprom.
    Even SRAM has a preferred init value, which depends on racing conditions of the stoarge flipflow when power is applied. So most (but not necessarily all) cells have the same content, usually 1, when power is applied.

**Attention** This is a public forum