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.

400 KByte flash writing MSP430F6659

Other Parts Discussed in Thread: MSP430F6659, CCSTUDIO

Hi,

I need to store a lot of data in flash of MSP430F6659 - up to 400KBytes. My program is about 10 KBytes. As far as I understood from .map file, I have the necessary amount:

FLASH2                00010000   00078000  00000000  00078000  RWIX

I have seen the examples of writing to flash, they are ok, but my questions are:

1) Should I call erasing every 512 bytes? (every segment)

2)Which type of writing would be better? (I know that long-word is quicker, but still)

Thank you!

  • Did you consider to use smaller msp430 and external memory IC? Could be cheaper solution.

  • I did, but there are other requirements leading to the usage of this MC, or at least 5658.

    But thank you for a quick answer anyway

  • Not only price might be a problem (external flash costs too), erase/rewrite cycles are usually much more for external flash.  Also one negative aspect of the internal MSP430 flash is, that during flash erase/write operation, no other flash operations can occur - which effectively means that the µC is on hold during flash erase.

    H.

  • Andrey Dodonov said:
    1) Should I call erasing every 512 bytes? (every segment)

    I am not sure I understand this question. You shall erase segments one by one. By doing erase whole segment becomes erased.

    Andrey Dodonov said:
    2)Which type of writing would be better? (I know that long-word is quicker, but still)

    One that's better for your application. Unfortunately you don't specify data you want to write - it's one bit or hole segment or in between

  • In the first question I asked if I should erase each segment before writing, or I can erase multiple segments and then write to them. So erase-erase-erase and then write-write-write or should it be erase-write erase-write erase-write?

    Anyway, now I'm using this code:

    #define segmentSize 512

    ...

    void writeDataToFlash(uint8_t* ptrX, uint8_t* data, uint16_t dataLength)
    {
    	int numOfBlocks = dataLength / segmentSize;
    	if (dataLength % segmentSize != 0)
    		numOfBlocks++;
    
    	uint16_t i;
    	for (i=0; i<numOfBlocks; ++i)
    	{
    		eraseFlashSegment(ptrX + segmentSize*i);
    		writeFlashSegment(ptrX + segmentSize*i, data+segmentSize*i);
    
    	}
    }
    
    void eraseFlashSegment(uint8_t* ptrX)
    {
    	_DINT();
    	while(BUSY & FCTL3);
    	FCTL1 = FWKEY|ERASE;                      // Set Erase bit
    	FCTL3 = FWKEY;                            // Clear Lock bit
    	*ptrX = 0;                          // Dummy write to erase Flash
    	while(BUSY & FCTL3);
    	FCTL1 = FWKEY;                            // Clear WRT bit
    	FCTL3 = FWKEY|LOCK;                       // Set LOCK bit
    	_EINT();
    }
    
    void writeFlashSegment(uint8_t* ptrX, uint8_t* data)
    {
    	_DINT();
    	FCTL3 = FWKEY;
    	FCTL1 = FWKEY|WRT;                        // Set WRT bit for write operation
    	int i;
    	for(i=0; i <segmentSize; i++)
    	{
    		*ptrX++ = data[i];
    	}
    
    	FCTL1 = FWKEY;                            // Clear WRT bit
    	FCTL3 = FWKEY|LOCK;                       // Set LOCK bit
    	_EINT();
    }

    Let's say for now I want to store only 4000 bytes. If I call writeDataToFlash and pass values in range 0xA000 - 0xE000, it works wonderful. For example:

     

    Flash_ptrX = (uint8_t *) 0xB000;
    writeDataToFlash(Flash_ptrX, tmpDataForFlash, 4000);

    However, if i give values in higher, supposedly free areas, for example in the next bank:

    Flash_ptrX = (uint8_t *) 0x28000;
    writeDataToFlash(Flash_ptrX, tmpDataForFlash, 4000);

    then my USB connection is instantly lost and I can not restart even by restarting the whole firmware program. Only erasing the whole flash and reloading program saves the situation.

    But this area is supposed to be free. Or no?

    Thanks in advance!

  • sizeof(uint8_t *) == 2  ??

    H.

    PS: if you are not using something like a "large data" memory model, you have to use 20bit read/writes which are fed with uint32_t

  • Andrey Dodonov said:
    In the first question I asked if I should erase each segment before writing, or I can erase multiple segments and then write to them. So erase-erase-erase and then write-write-write or should it be erase-write erase-write erase-write?

    Both ways are ok. Use one that's best suited for your application. Note that you don't need to write whole sector in single pass, information to sector can be "appended" as it comes in.

  • As Hardy points out, your pointer is too small to address flash regions at 0x10000 and above. You need to pass a 32-bit parameter which holds a 20-bit pointer. You should read up on the medium and large data models in your tool's user's guide.

  • Thank you guys! I just went to Project Properties -> Build -> Advanced Options -> Runtime Model Options and checked "User large-data memory model" checkbox there. BTW, I'm using CCStudio.

    Now it is working fine!

  • Andrey, you can do it multiple ways. Yes, you can first erase all segments, then write to them. You can erase a segment, and write to it later. You can ever write to it later multiple times, but you cannot write a ‘1’ where there is already a ‘0’, and the total number of writes to a segment before it needs to be erased again is limited (if you write to it too often, then bits will start flipping from 1 to 0 unintentionally, after years, days or seconds.).The limit is the time the programming voltage is applied to this segment. See the datasheet for details.

    Also, the 5x/6x family flash controller supports bank erase. You can erase 64k of flash in one shot. See the datasheet which 64k of memory belong to one bank. While a bank is being erased, code from another bank will be executed (during a normal segment erase, no part of flash is accessible, so code execution will be stopped).

    As for the access of the ram, IAR (CCS too?) provides intrinsic to read and write to a 20 bit address even in small data model (which results in smaller code and higher execution speed than large code model). If you don’t need to access the data above 64k regularly, you can use these intrinsic for reading as well as for the flash erase and write operations.

  • Michael, thank you very much!

    I knew that after erasing flash contains only '1's, but that accessibility trick is very useful, thank you!

    As for intrinsic functions, after your advice I've read application report slaa376 http://www.ti.com/lit/an/slaa376/slaa376.pdf  

    It seems that for CCS (unlike IAR) these functions have to be user-defined, but it is not a problem, since examples are given in this application report. 

  • Andrey Dodonov said:
    after your advice I've read application report slaa376 http://www.ti.com/lit/an/slaa376/slaa376.pdf  

    This application report is from 2007 and talks about CCE2 and IAR3. I don’t know what the current versions of CCS (CCE has been superseded by a unified CCS since) and IAR do.

    Also, the functions presented there for CCE have a serious flaw: you need to save the status register and clear GIE bit before doing the read/write access. If an interrupt happens between setting up the address register and doing the access, the address register content might be truncated to 16 bit by the ISR (unless you use large code model, which will preserve 20 bit register contents, but then you don’t need these functions at all)

  • Yeah, truncated... you're right as always. SLAU157z (Revised September 2013) says the following:

    B.2 Intrinsic Functions
    CCS and IAR tools use the same instructions for MSP430 processor-specific intrinsic functions.

    It seems to be more up-to-date info.

  • I found another old manual with the list of intrinsics, not regarding the environment:

    http://tina.bu.edu/ec450s10/materials/Handouts/CH5_6_%20from_C_compiler-slau132b.pdf

**Attention** This is a public forum