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.

CCS/EZ430-F2013: ez430-2500rf-seh sleep mode and reset of the mcu

Part Number: EZ430-F2013
Other Parts Discussed in Thread: MSP430F2274

Tool/software: Code Composer Studio

Hello, I am working with ez430-seh dev kit, actually I am using seh sensor monitor demo as my source code and I want to store a table in my msp430. I do so by firsst initializing the table before main{} and then I expect it to be changed each e.g. 30 sec. The problem is that when the light is not available for a moment and the device goes in sleep mode, when it wakes up, the table is reset and the program is run from the very begining. I would like to ask why is that?? The sleep mode should not turn the device off, it should simply preserve the hard times without any light. 

  • Going into sleep mode doesn't cause a reset; it sounds like you're power-cycling.

    The rf2500-seh product page seems to have vanished, and I only vaguely recall what this kit has in it. Is there supposed to be backup power in case the solar collectors don't supply enough?

    The only way for data to survive a power cycle is to write it into Flash. For the F2274, that pretty much means Information memory, which is only (3*64) bytes. (InfoA is used for other things.)
  • Okay, so I tried with operating on Flash memory.
    In my code I have a table[3][48] and current sample (int) which I would like to store in flash, so there I go: (my msp is msp430f2274)

    // definitions //
    unsigned long tab[3][48] = {{1000}};
    unsigned int sample = 0;
    
    
    // main //
    main{
        read_from_flash();
        // do some operations on table
        write_to_flash();
    }
    
    
    // functions to write and read //
    void write_to_flash(void){
        char *Flash_Addr;
        unsigned int i, j;
    
        Flash_Addr = (char*)0x10F0;
    
        BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
        DCOCTL = CALDCO_1MHZ;
        FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
        FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits
        FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
    
        for (i = 0; i < 3; i++){
            for (j = 0; j < 48; j++){
                *Flash_Addr++ = tab[i][j];
            }
        }
        *Flash_Addr = sample;
    
        FCTL1 = FWKEY; // Clear WRT bit
        FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit
    }
    
    
    void read_from_flash (void){
        char *Flash_Addr; // Flash pointer
        unsigned int i, j;
    
        Flash_Addr = (char*)0x10F0; // Initialize Flash pointer
    
        for (i = 0; i < 3; i++){
            for (j = 0; j < 48; j++){
                tab[i][j] = *Flash_Addr++;
            }
        }
        sample = *Flash_Addr;
    }




    My question is, as the tab is a long variable, then maybe the incrementation of Flash_Addr++ is not sufficient? How much can I store in one "pointer area?"

  • 1) In general, you have to erase a Segment before you write it. There are 3 Segments involved here, so that's 3 separate erase operations. Example flashwrite_01.c also demonstrates how to do that.
    2) Information Flash starts at 0x1000. Your address 0x10F0 is up in the InfoA segment. [Ref User Guide (SLAU144J) Fig. 7-2. The "512-byte" inscription looks like a typo.]
    3) sizeof(unsigned long)=4, so your table is 4*3*48=576 bytes long, which will not fit in (3*64)=192 bytes. Consider whether you need all those items, and/or if they could be smaller.

    System design item: Flash has a limited lifetime, measured in (erase+)write cycles. The data sheet (SLAS504G) table on p.56 (keyword: "endurance") only guarantees 10000 cycles. This sounds like a lot, but at e.g. 1 (erase+)write per second that's just over 3 hours. (flashwrite_01.c has a warning about this, but it's not nearly loud enough.) Flash is most useful for "read-mostly" data.

    You're already doing this, but I'll say it anyway: Keep LOCKA on all the time. InfoA contains (among others) CALDCO_1MHZ, which is a pain to recover. (If you have only one of these kits, consider writing down those values at the top of InfoA, just in case.)
  • Sorry, I missed your question at the end. You can write bytes or words, distinguished only by how long it takes. As long as you read them back out the same order, you're fine.

    You can't write long-s, so you need to cast "&tab[0]" to a (char *) to match Flash_Addr. For this particular case I would be tempted to just have a single loop that writes (sizeof(tab)) bytes, but based on the other concerns above your definition of "tab" may end up different.
  • So am I right that I'd better start operating on Flash from 0x1000? And I am still not sure how I should erase the segments

    FCTL1 = ERASE + FWKEY + WRT;
    FCTL2 = ERASE + FWKEY;
    FCTL3 = ERASE + FWKEY;

    I can see that in flashwrite_01.c they do something slightly different, not every FCTL is erased...
    Also, having changed tab[3][48] to short type, is my piece of code at the very beginning correct?

    I'm sorry, I don't feel comfortable with msp controllers

  • 1) sizeof(short)=2, so that's still 2*3*48=288 bytes. If you can live with bytes (unsigned char) it would be 144 bytes, which would fit.

    2) I had forgotten how LOCKA works. Per UG sec. 7.4.3, you should Not write LOCKA, since that clears it.

    3) "In general" glossed over some details. You can only erase a segment (64 bytes in this case) at a time. You can only write each byte in the segment once (without erasing it). For copying en masse (your case) this works out to one erase per (array) write.

    4) The ERASE bit is cleared at the end of the erase cycle (UG section 7.3.2) so you have to issue one erase cycle per segment. Adapted from flashwrite_01.c (not tested, but it looks right):

     // FCTL2 was set earlier
     FCTL3 = FWKEY;                  // Clear Lock bit (once), leave LOCKA set
    
     FCTL1 = FWKEY + ERASE;          // Set Erase bit  (each time)
     *(Flash_ptr+0x00) = 0;          // Dummy write to erase 1st segment
     FCTL1 = FWKEY + ERASE;          // Set Erase bit  (each time)
     *(Flash_ptr+0x40) = 0;          // Dummy write to erase 2nd segment
     FCTL1 = FWKEY + ERASE;          // Set Erase bit  (each time)
     *(Flash_ptr+0x80) = 0;          // Dummy write to erase 3rd segment
    
     FCTL1 = FWKEY + WRT;            // Set WRT bit for write operation
     //[Write some stuff]
     FCTL1 = FWKEY;                  // Clear WRT bit
     FCTL3 = FWKEY + LOCK;           // Set LOCK bit