Saving to flash

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
niprc_3742601
Level 4
Level 4
5 likes given First like received First like given

Hello,

I would like to be able to permanently store data to flash of my PSoC5 processor and being able to retrieve it after rebooting the processor.  I found sample project "Flash Example" that seems to be doing just that.

This is the code snippet how they store data to flash:

...

            CySetTemp();

            returnValue = CyWriteRowData(ARRAY_ID, ARRAY_ID_ROW_ADDR, rowPattern);

            /* Check if operration is successful */

            if (returnValue != CYRET_SUCCESS)

            {

                LED_Error_Write(LIGHT_ON);

                CyHalt(0x00u);

...

It writes data to the flash and then immediately reads it and matches to what was stored.  Everything works fine here.  But if I modify this code such that when it runs first time it ONLY writes the data and the second it ONLY reads the data then the stored data is lost.  So it looks like the stored data didn't survive the reboot OR reprogramming of the chip (I had to do it to comment out the code that writes data to flash).

Is there a way to burn something to flash so it stays there until explicitly erased?

Thanks!

Nikolay

0 Likes
1 Solution

Question: Can I protect a flash region from being cleared during chip programming?

Answer: If you program the device use PSOC Programmer or Creator(include a mini programmer), you cannot protect a flash region from being cleared during chip programming because device flash is erased all first before program, this process is preset and fixed in software tool.  Change the flash block protection level cannot prevent protected flash block be erased from external.

1.jpg

I think there are two ways to fix this issue:

(1) Store data in EEPROM of PSoC5LP, erase flash won't change EEPROM region.

(2) Design device program script use cli (command line),  custom you own programming steps instead of use ready-made programming tools. Post 6. Re: Saving to flash also mentioned this method("unless you implement a custom program step).  You can search "PSoC Programmer CLI User Guide.pdf" file on your PC to know how to do that.

If your design is a bootloader-bootlodable system, you can define a checksum-exclude region which won't be modified when bootlodable is upgrading by bootloader.

View solution in original post

0 Likes
10 Replies
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Have you tried using the EEPROM component?  I think it just emulates EEPROM in flash, but it might make interfacing a little nicer than working with the flash directly.

Also have a look at these threads:

Limitations with Emulated EEPROM

EEPROM write and read back

Lost EEPROM settings

There is another advantage of using the EmEEPROM component, wear leveling.  Basically you can write to flash too many times and it will stick.

That said you are likely to lose your data when reprogramming the chip, unless you implement a custom program step.  (There are other ways, but I don't have the documentation handy right now.)

If you just want to debug without programming, there is that option as well as attaching to a running target.

0 Likes

I just verified that writing to flash saves the data that survives a reboot.  However, programming the chip clears the data.

So my original question comes to this one: can I protect a flash region from being cleared during chip programming?

Thank you, everybody, for help!

Nikolay

0 Likes

I didn't think it would write over the EEPROM unless "Include EEPROM image in hex file" was checked in the EEPROM section of the design-wide resources.  But it could be the case of it just writes 0xFF to all those EEPROM addresses unless you tick the box and give it something custom.

If you know exactly what addresses in flash you're saving into, you could perhaps mark it protected in the "Flash Security" tab in the design-wide resources.  Mark the addresses 'R' and no external device should be able to clear it.  I think the PSoC CPU should still be able to modify it.  Check the PSoC Creator Help (search for "Flash Security") for more info on it.

0 Likes
lock attach
Attachments are accessible only for community members.

In the "Flash Security" tab I marked the row as "external write protect", but the result is the same.

The output of my program is below: when booted the first time the no data is saved in flash (expected).  Then I hit Reset button a few times and the program can read the data from flash.  Then I program the chip, it boots and the data is lost despite the flash row is marked as "external write protected"

What am I doing wrong?

Thanks!

Nikolay

P.S.

My test project is attached.

pastedImage_1.png

0 Likes

Dang I thought the Flash Protection would have been it.

Are you running a Release or Debug build?

Does the same thing happen if you program via PSoC Programmer rather than through Creator?  It seems unlikely but might be worth trying.  Maybe Creator wipes it but Programmer wouldn't for some reason?

Just throwing stuff out there to try, since Flash Protection, as described in the help documentation, sounds like exactly what you want.  it's really strange that didn't work.

0 Likes

Programming with the Release build and/or PSoC Programmer didn't fix the problem.

Did I select the correct flash row to protect?  I used the computations from the "Flash Example".  Those macros, that they used, have a bit weird names and I keep confusing one with another.  I think that the global row ID is 1022 which corresponds to array 3 with array's row ID 254.  So I protected row 1022.  Does it seem to be correct to you?

Thank you for your help!

Nikolay

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

If you don't mind using an EEPROM,

this seems to be working, too.

Note: Before the last line, I cycled the power of CY8CKIT-050.

001-TeraTerm-log.JPG

schematic

002-schematic.JPG

main.c

===================

#include "project.h"

#include <CyFlash.h>

#include <stdio.h>

/* added on 28-Feb-2019 */

void print(char *str)

{

    Debug_PutString(str) ;

}

int erase_EEPROM(void)

{

    int sector_number = 0 ;

    cystatus result ;   

    print("Erasing EEPROM ...") ;

    EEPROM_UpdateTemperature();

    result = EEPROM_StartErase(sector_number) ; /* use sectorNumber = 0 */

    if (result != CYRET_SUCCESS) {

        return( result ) ;

    }

    while((result = EEPROM_Query()) == CYRET_STARTED) {

        ; /* wait erase to finish */

    }

    if (result != CYRET_SUCCESS) {

        print("Failed\n\r") ;

        return( result ) ;

    }

    print("Done\n\r") ;  

    return( result ) ;

}

int blank_check_EEPROM(int address, int bytes)

{

    int i ;

    uint8_t data ;

    int is_blank = 1 ;

    EEPROM_UpdateTemperature();

    for (i = 0 ; i < bytes ; i++ ) {

        data = EEPROM_ReadByte(address + i) ;

        if (data != 0) {

            is_blank = 0 ;

            break ;

        }

    }

    return( is_blank ) ;

}

int

eeprom_store( uint8 *buf, uint16 sz )

{

    cystatus result ;

    uint16_t i ;

   

    EEPROM_UpdateTemperature();

    for (i = 0 ; i < sz ; i++ ) {

        result = EEPROM_WriteByte(buf, i) ;

        if (result != CYRET_SUCCESS) {

            break;

        }

    }

    return( result ) ;

}

void

eeprom_read( uint8 *buf, uint16 sz )

{

    uint16_t i ;

   

    EEPROM_UpdateTemperature();

    for (i = 0 ; i < sz ; i++ ) {

        buf = EEPROM_ReadByte(i) ;

    }

}

/************************/

#define CY_TEST_FLASH_ROW       (CY_FLASH_NUMBER_ROWS - 2u)                           //  global ID of the row of interest

#define CY_TEST_FLASH_ADDR      (CY_TEST_FLASH_ROW * CY_FLASH_SIZEOF_ROW)             //  address if the global row of interest

#define ARRAY_ID                ((uint8)(CY_TEST_FLASH_ROW / CY_FLASH_SIZEOF_ROW))    //  ID of the array that contains the row of interest

#define ARRAY_ID_ROW_ADDR       ((uint16)(CY_FLASH_SIZEOF_ROW - 2u))                  //  address offset of the row of interest

//------------------------------------------------------------------------------

//

void

flash_store( uint8* buf, uint16 sz )

{

#ifndef CY_PSOC5

   

    return;

#else

    if( sz > CYDEV_FLS_ROW_SIZE )  return;

    uint8 flash_row[ CYDEV_FLS_ROW_SIZE ];

    memmove( flash_row, buf, sz );

   

    cystatus ret = CYRET_SUCCESS;

    CySetTemp();

    ret = CyWriteRowData( ARRAY_ID, ARRAY_ID_ROW_ADDR, flash_row );

    if( ret != CYRET_SUCCESS )

    {

        Debug_PutString( "CyWriteRowData(...) failed\n\r\b" );

        //CyHalt( 0x00u );

        return;

    }

   

   

#endif  // (CY_PSOC5)

}

//------------------------------------------------------------------------------

//

void

flash_read( uint8* buf, uint16 sz )

{

#ifndef CY_PSOC5

    return;

   

#else

   

    uint16 i = 0;

    volatile uint8 flash_byte = 0;

   

    if( sz > CYDEV_FLS_ROW_SIZE )  return;

   

    for( i = 0u; i < sz; i++)

    {

        flash_byte = ( *( (uint8*) ( CYDEV_FLS_BASE + CY_TEST_FLASH_ADDR + i ) ) );

        buf[ i ] = flash_byte;

    } 

       

#endif

}

//------------------------------------------------------------------------------

//

int

main( void )

{

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    EEPROM_Start() ;

    Debug_Start();

   

    LED1_Write( 1 );

    LED2_Write( 0 );

    const static uint16 SZ = 8;

    uint8 buf1[] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x01, 0x02, 0x03, 0x04 };

//    uint8 buf1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // for testing

    uint8 buf2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    Debug_ClearTxBuffer();

    Debug_PutString( "booted: " );

   

    if (blank_check_EEPROM(0, SZ)) {

        erase_EEPROM() ;

    }

   

    eeprom_read(buf2, SZ) ;

//    flash_read( buf2, SZ );

    if( 0 == memcmp( buf2, buf1, SZ ) )

    {

        Debug_PutString( "data is stored\n\r\b" );

    }

    else

    {

        Debug_PutString( "data is not stored, storing ..." );

//        flash_store( buf1, SZ );

        erase_EEPROM() ;

        eeprom_store(buf1, SZ) ;

       

//            flash_read( buf2, SZ );

        eeprom_read(buf2, SZ) ;

        if( 0 == memcmp( buf2, buf1, SZ ) )

        {

            Debug_PutString( " stored\n\r\b" );

        }

        else

        {

            Debug_PutString( " not stored\n\r\b" );

        }

    }

    for( ;; )

    {

        LED1_Write( ! LED1_Read() );

        LED2_Write( ! LED2_Read() );

        CyDelay( 250 );

       

    }

}

===================

moto

Question: Can I protect a flash region from being cleared during chip programming?

Answer: If you program the device use PSOC Programmer or Creator(include a mini programmer), you cannot protect a flash region from being cleared during chip programming because device flash is erased all first before program, this process is preset and fixed in software tool.  Change the flash block protection level cannot prevent protected flash block be erased from external.

1.jpg

I think there are two ways to fix this issue:

(1) Store data in EEPROM of PSoC5LP, erase flash won't change EEPROM region.

(2) Design device program script use cli (command line),  custom you own programming steps instead of use ready-made programming tools. Post 6. Re: Saving to flash also mentioned this method("unless you implement a custom program step).  You can search "PSoC Programmer CLI User Guide.pdf" file on your PC to know how to do that.

If your design is a bootloader-bootlodable system, you can define a checksum-exclude region which won't be modified when bootlodable is upgrading by bootloader.

0 Likes

Writing to EEPROM solves the problem!

Thank you everybody!