Jump to content
Sign in to follow this  
-KP-

Flash write time

Recommended Posts

Hi,

I'm using the Stellaris Launchpad as part of sequencer/sampler musical instrument that I'm working on right now. I use the internal flash to record and store a couple of short 1-sec clips of audio, sampled at 21kHz - 12 bit. With the FlashProgram() function of the peripheral driver library, I store two words or four samples consecutively, so: record 4 samples - write to flash - record 4 samples - write to flash - etc.

The recording happens on a timer interrupt, however the program skips an interrupt every 4 times, exactly when FlashProgram() is doing its thing. So I dove in the FlashProgram() code and adjusted the part where it is waiting, or polling, until the write is complete. This way, I thought, my program could continue running while the flash took its time to get written, 50µs or so.

But it still continues skipping while it's writing to flash. Any suggestions to solve this? Or is it just impossible to 'do' anything while flash is being written?

 

Share this post


Link to post
Share on other sites

Hi,

The data sheet specify a write time for a maximum 300 microseconds, while typical is 50. Do not rely on typical, since this is not explained in what context is supposed to be true. Always count on maximum in these cases. Your 21KHz sampling rate gives a possible write time 47.5 microseconds, not even typical...

About your goals here - you may try to define in RAM two big enough ping-pong buffers, aligned at 8, if you have enough RAM (TM4C123xx is short in RAM, only 32K, 129 series is much bigger, 256K). Fill up the first buffer and start to transfer to flash while filling up the second and then reverse to first - but check for timing first...

Another possible solution can be an external EEPROM like Atmel or a flash stick, based on high speed SPI transfer.

Share this post


Link to post
Share on other sites

Hi,

Conceptually it is possible, but depends - if you use the driverlib function FlashProgram, you may note the waiting for write accomplishment (the code is in flash.c file) - but also there is a flash interrupt routine, so in this case you must modify or write your own function if you need to use interrupts.

L

Share this post


Link to post
Share on other sites

But is it possible to 'do' something, continue with the program, while flash is being written, or do you just have to wait for it?

 

It is possible. My (MSP430) flasher doing 3 proces in parallel: receiving data from PC (over USB), transfering data to target device, and writing to flash on target device. And all this without any impact on (close to max possible) flashing rate...

http://forum.43oh.com/topic/2972-sbw-msp430f550x-based-programmer/?p=41143

 

You can try to measure flash writing interval, and than use constant period (colecting samples) as delay for flash write operation. Depending on word position or.... maybe you will have more than one different constant periods. And use some buffer.

 

Can you add FlashProgram() source here?

Share this post


Link to post
Share on other sites

Can you add FlashProgram() source here?

 

As you can see, I have just commented out the while loops waiting for the flash being programmed.

long
FlashProgram(unsigned long *pulData, unsigned long ulAddress,
             unsigned long ulCount)
{
    //
    // Check the arguments.
    //
    ASSERT(!(ulAddress & 3));
    ASSERT(!(ulCount & 3));

    //
    // Clear the flash access and error interrupts.
    //
    HWREG(FLASH_FCMISC) = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
                           FLASH_FCMISC_INVDMISC | FLASH_FCMISC_PROGMISC);

    //
    // See if this device has a write buffer.
    //
    if(HWREG(SYSCTL_NVMSTAT) & SYSCTL_NVMSTAT_FWB)
    {
        //
        // Loop over the words to be programmed.
        //
        while(ulCount)
        {
            //
            // Set the address of this block of words.
            //
            HWREG(FLASH_FMA) = ulAddress & ~(0x7f);

            //
            // Loop over the words in this 32-word block.
            //
            while(((ulAddress & 0x7c) || (HWREG(FLASH_FWBVAL) == 0)) &&
                  (ulCount != 0))
            {
                //
                // Write this word into the write buffer.
                //
                HWREG(FLASH_FWBN + (ulAddress & 0x7c)) = *pulData++;
                ulAddress += 4;
                ulCount -= 4;
            }

            //
            // Program the contents of the write buffer into flash.
            //
            HWREG(FLASH_FMC2) = FLASH_FMC2_WRKEY | FLASH_FMC2_WRBUF;

            //
            // Wait until the write buffer has been programmed.
            //
/*            while(HWREG(FLASH_FMC2) & FLASH_FMC2_WRBUF)
            {
            }
*/        }
    }
    else
    {
        //
        // Loop over the words to be programmed.
        //
        while(ulCount)
        {
            //
            // Program the next word.
            //
            HWREG(FLASH_FMA) = ulAddress;
            HWREG(FLASH_FMD) = *pulData;
            HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;

            //
            // Wait until the word has been programmed.
            //
/*            while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
            {
            }
*/
            //
            // Increment to the next word.
            //
            pulData++;
            ulAddress += 4;
            ulCount -= 4;
        }
    }

    //
    // Return an error if an access violation occurred.
    //
    if(HWREG(FLASH_FCRIS) & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
                             FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS))
    {
        return(-1);
    }

    //
    // Success.
    //
    return(0);
}

Share this post


Link to post
Share on other sites

From device datasheet...

 

A 32-word write buffer provides the capability to perform faster write accesses to the Flash memory
by programming 2 32-bit words at a time, allowing 32 words to be programmed in the same time
as 16 would take using the method described above. The data for the buffered write is written to
the Flash Write Buffer (FWBn) registers.

 

For max speed, flash write buffer must be used. It is not clear if buffer can be updated (on the fly) during flashing, but if it can, than things became very simple. Samples can be directly written to flash write buffer, and flashing can be triggered in advance when buffer is not full (for example in half). When flashing is done, it can be retrigered again, because first half of buffer will be ready.

 

You can measure flashing time by timer, and adjust things that flashing can follow sampling rate.

 

If flashing is slower, big circular RAM buffer can be used to give flashing some more time. 

Share this post


Link to post
Share on other sites

I'm not using the whole buffer, but I've got it set up so that 2 words (or 4 samples) are programmed at a time (see first post); The problem I'm having is that, even with the adjusted one I posted in my previous post, FlashProgram() still takes >50µs. In this time TMR interrupt gets skipped and so I still have to wait for it to finish...

Share this post


Link to post
Share on other sites

I'm not using the whole buffer, but I've got it set up so that 2 words (or 4 samples) are programmed at a time (see first post); The problem I'm having is that, even with the adjusted one I posted in my previous post, FlashProgram() still takes >50µs. In this time TMR interrupt gets skipped and so I still have to wait for it to finish...

 

For max speed you must use full buffer. Make some writing time measurement for writing full buffer at once, and if speed is OK, adapt your code for full buffer writing.

Share this post


Link to post
Share on other sites

Will try, but how will writing 32 words be faster then 2?

 

You must collect all samples for 32 words and than trigger flash writing (with full buffer), not 2 by 2.

Share this post


Link to post
Share on other sites

So I did, writing 32 words (full buffer) takes 1 ms! As I expected this doesn't help a thing.

Help!

 

If you measure that writing 32 words with aligned address takes 1 ms, than flashing rate is...

32 * 2 * 1000 / 1 * 1024 = 62.5 KB / s

 

If this is TI ARM max flashing rate, than I am disappointed, because MSP430F5xx can go over 200 KB/s.

 

if 62.5 KB/s is enough for you recording, than you need to inject writing flash code to your sampling code, or opposite, to have both processes working together, completely in parallel.

Share this post


Link to post
Share on other sites

If you measure that writing 32 words with aligned address takes 1 ms, than flashing rate is...

32 * 2 * 1000 / 1 * 1024 = 62.5 KB / s

 

If this is TI ARM max flashing rate, than I am disappointed, because MSP430F5xx can go over 200 KB/s.

 

if 62.5 KB/s is enough for you recording, than you need to inject writing flash code to your sampling code, or opposite, to have both processes working together, completely in parallel.

 

Just looking at the TM4C123GH6PM datasheet (I presume the older Stellaris LP is similar), Tprog64 = Program time for double-word-aligned 64 bits of data ... min 30, nominal 50, max 300 uS.

 

32 words = 32 * 32 bits = 1024 bits.  1024/64 = 16... 50uS * 16 = 800uS, or 300uS * 16 = 4800uS, so it sounds like that's the typical write rate for the flash.

 

Also the TM4C123GH6PM datasheet, page 530, it's quite clear that "During a Flash memory operation (write, page erase, or mass erase) access to the Flash memory is inhibited.  As a result, instruction and literal fetches are held off until the Flash memory operation is complete.  If instruction execution is required during a Flash memory operation, the code that is executing must be placed in SRAM and executed from there while the flash operation is in progress."

Share this post


Link to post
Share on other sites

Also the TM4C123GH6PM datasheet, page 530, it's quite clear that "During a Flash memory operation (write, page erase, or mass erase) access to the Flash memory is inhibited.  As a result, instruction and literal fetches are held off until the Flash memory operation is complete.  If instruction execution is required during a Flash memory operation, the code that is executing must be placed in SRAM and executed from there while the flash operation is in progress."

 

Jep, that might be it, thanks for clearing that! However I don't know to execute code from SRAM, so I'll just work with an external SRAM. But thanks anyway.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...