Write to Em_EEPROM is bricking PSoC4 (can't program afterwards)

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

cross mob
ErHo_1310276
Level 1
Level 1
First like received

Below is my main.c just doing a simple read/write to Em_EEPROM.  This is on a CY8C4247AZI-L475 (PSoc-4).    This is using Creator 4.3 and Em_EEPROM version 2.2

On this first runs I had the write to Em_EEPROM commented out and it simply initialized and read 4-byte from the Em_EEPROM.  The initialization and read gave "success" status and the read of 4-bytes produced 0x00 0x00 0x00 0x00.   Then I introduce a write to the Em_EEPROM writing 0x00 0x01 0x02 0x03.  The write also give success, and I know the write occurred because subsequent resets of the device return that exact data (0x00 0x01 0x02 0x03) for the reads.  The problem is now my device is bricked.  I cannot re-program it.  The programmer says "failed to reacquire the device".  From my debug UART port output it looks like the device is resetting and starting to run the application many times while the programmer is trying to acquire it.  Both creator and stand alone programmer behave this way.  SWD based programmer.  Both Pioneer board and MiniProg3 behave the same.

I thought this was a strange fluke, so I did the same procedure on a new copy of my board.  Same result.  After writing 4-bytes to the Em_EEPROM it can no longer be programmed.   What am I doing wrong here?

-------- my main.c is below --------

cy_en_em_eeprom_status_t returnValue;       // used for EEPROM function returns

int main(void)

{

    uint8_t eep_data[64];

    CyGlobalIntEnable; /* Enable global interrupts. */

    init_periphs(); // initialize debug UART

   

    returnValue = Em_EEPROM_1_Init(&emEeprom[0]);

   

    if (returnValue == CY_EM_EEPROM_SUCCESS) {

        append_msg("success on init\r\n"); // I get this message...it works

    }

    returnValue = Em_EEPROM_1_Read(0,eep_data,4);

   

    if (returnValue == CY_EM_EEPROM_SUCCESS) {

        append_msg("success on read\r\n"); // I get success message...it works

    }

/// The 4-bytes read are all 0x00 (viewed via debug UART) ///

    /// Then I write 4-bytes to address 0 ////

    eep_data[0] = 0;

    eep_data[1] = 1;

    eep_data[2] = 2;

    eep_data[3] = 3;

      

    returnValue = Em_EEPROM_1_Write(0,eep_data,4); // write 4-bytes

   

    if (returnValue == CY_EM_EEPROM_SUCCESS) {

        append_msg("success on write\r\n"); // I get success message

    }

   

/// On subsequent resets of device the 4-bytes read as 0 1 2 3 (what was written)

/// however, I can never again program the device or use the debugger...it is bricked.

   

    for(;;)

    {

}

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Eric-san,

> The erase all does not work with this either.

I'm sorry for hearing that.

Another thing I noticed from your screen shot is that you have a folder (directory) named

"PSoC Creator"

in your path to the project.

I think that path name should not have SPACE " ", or not-regular letters such as language specific letter and Kanji (16bit letter) etc.

So I recommend you to rename the folder to

"PSoC_Creator"

or

"PSoCCreator"

Also I would like to ask you to try the followings.

(1) I see that you selected "10p" for the connector, would you try "5p" instead?

(2) Check AutoDetection "Off" and specify the Device Family and Device in the left side panes.

(3) Try "Power Cycle"  for Programming Mode.

(4) Try slower "Clock Speed"

(5) Double Check the connections of SWD

(6) Double Check the check list in AN88619 below

https://www.cypress.com/file/141176/download

I especially would like to ask you to check chapters

4 Power

6 Reset

7 Programming and Debugging

Appendix C Schematic Checklist

> Chips are cheap and I am pretty good with hot air re-work so not a problem to experiment a bit.

I respect you!

Best Regards,

10-Oct-2020

Motoo Tanaka

View solution in original post

10 Replies
Rakshith
Moderator
Moderator
Moderator
250 likes received 1000 replies posted 750 replies posted

Hi ErHo_1310276​,

Can you please attach your entire project (including the hex file that you used) to this thread? I do not have the same Kit with me but I will check internally so that we can recreate the issue to understand why you are unable to reacquire the device.

Thanks and Regards,

Rakshith M B

Thanks and Regards,
Rakshith M B
0 Likes
lock attach
Attachments are accessible only for community members.

Hello Rakshith,

Attached is a "bundle" of the project, and the .hex file is also attached separately.  This is not being done on a kit, but rather my own board.   Really all you should need to mimic to reproduce it is the same debug UART connections.  The project as built does use the external oscillator at 24.3MHz, but you should be able to switch to using the IMO at 24MHz and it should still work.

Thanks for looking into this:

-Eric

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,

I wrote a test sample for 5LP more than a year ago,

and I tried to port it to PSoC 4 (CY8CKIT-044 (CY8C4247AZI-M485)).

If I remember correct, Em_EEPROM requires larger physical flash than the size of the logical EEPROM.

And the storage needed to be located in a fixed location in the Flash, so I think that we need it to define

it as a global static constant, something like

const uint8 store[Em_EEPROM_PHYSICAL_SIZE]

    __ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};

Please refer to the datasheet of Em_EEPROM for details.

After starting the debugger, it showed

Note: All the data in "Store" are 00

003-TeraTerm-log.JPG

Then I cycled the board and pushed the reset pin

Note: In the "Store" the data F0 ~ FF are remaining, but not from the beginning of the Store.

004-after-reset.JPG

Then I started the debugger again, which erases the Flash

Note: So "Store" is all 00 again

005-second-iteration.JPG

Now my sample project

Schematic

001-schematic.JPG

Em_EEPROM Config

001-Em_EEPROM_config.JPG

Pins

002-pins.JPG

main.c

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

#include "project.h"

#include "stdio.h"

#define STR_LEN 64

char    str[STR_LEN+1] ;

void    print(char *str)

{

UART_UartPutString(str) ; /* PSoC 4 */

// UART_PutString(str) ;     /* PSoC 5 */

}

void cls(void)

{

    print("\033c") ; /* reset */

    CyDelay(20) ;

    print("\033[2J") ; /* clear screen */

    CyDelay(20) ;

}

void splash(char *prog_name)

{

    cls() ;

    if (prog_name && *prog_name) {

        print(prog_name) ;

    }

    print(" (") ;

    print(__DATE__) ;

    print(" ") ;

    print(__TIME__) ;

    print(")\n") ;

}

cy_en_em_eeprom_status_t status;

const uint8 store[Em_EEPROM_PHYSICAL_SIZE]

    __ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};

void print_em_eprom_error(cy_en_em_eeprom_status_t status)

{

    switch(status) {

    case CY_EM_EEPROM_SUCCESS:      print("No Error\n") ; break ;

    case CY_EM_EEPROM_BAD_PARAM:    print("The input parameter is invalid\n") ; break ;

    case CY_EM_EEPROM_BAD_CHECKSUM: print("The data in EEPROM is correupted\n") ; break ;

    case CY_EM_EEPROM_BAD_DATA:     print("Failed to place the EEPROM in flash\n") ; break ;

    case CY_EM_EEPROM_WRITE_FAIL:   print("Write to EEPROM failed\n") ; break ;

    default:

        sprintf(str, "EEPROM Unknown Error %d\n", status) ;

        print(str) ;

        break ;

    }

}

void init_hardware(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    UART_Start() ;

   

    status = Em_EEPROM_Init((uint32_t)store) ;

    if (status != CY_EM_EEPROM_SUCCESS) {

        print_em_eprom_error(status) ;

    }

}

int main(void)

{

    unsigned int i ;

    unsigned int test_size = 16 ;

   

    uint8 zustand[Em_EEPROM_EEPROM_SIZE] = { 0u } ;

    init_hardware() ;

   

    splash("PSoC4 Em_EEPROM Test") ;

   

    sprintf(str, "EEPROM SIZE = %d\n", Em_EEPROM_EEPROM_SIZE) ;

    print(str) ;

   

    print("Store:\n") ;

    for (i = 0 ; i < test_size * 2 ; i++ ) {

        sprintf(str, "%02X ", store) ;

        print(str) ;

        if (i == 0xF) {

            print("\n") ;

        }

    }

    print("\n") ;

    print("Values to be written:\n") ;

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

        zustand = 0xF0 + i ;

        sprintf(str, "%02X ", zustand) ;

        print(str) ;

    }

    print("\n") ;

   

    status = Em_EEPROM_Write((uint32)0, (void*)zustand, test_size) ;

    if (status != CY_EM_EEPROM_SUCCESS) {

        print_em_eprom_error(status) ;

    }

   

    print("Store:\n") ;

    for (i = 0 ; i < test_size * 2 ; i++ ) {

        sprintf(str, "%02X ", store) ;

        print(str) ;

        if (i == 0xF) {

            print("\n") ;

        }

    }

    print("\n") ;

       

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

        zustand = 0 ;

    }

   

    status = Em_EEPROM_Read((uint32)0, zustand, test_size) ;

    if (status != CY_EM_EEPROM_SUCCESS) {

        print_em_eprom_error(status) ;

    }

   

    print("Values read:\n") ;

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

        sprintf(str, "%02X ", zustand) ;

        print(str) ;

    }

    print("\n") ;

    for(;;)

    {

        /* Place your application code here. */

    }

}

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

I hope this can be some hint for you.

moto

0 Likes

Hello Motoo,

  Thanks for the detailed response.  Looking over your example I can't say I see a fundamental difference between what you are doing and what I am doing.  You are doing a few casts of the arguments that perhaps I should but I don't think that is the real difference.  We both declare the EEPROM storage the same way and with the same size.

const uint8 store[Em_EEPROM_PHYSICAL_SIZE]

    __ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};

In the datasheet for Em_EEPROM they have a section on: "Placing EEPROM Storage at Fixed Address".  I did not do this, and from what I can see in your code you did not either.  They seem to indicate this is optional.  I am not sure where it chooses to place the Em_EEPROM in the address space if you don't fix it.  Seems like I have it in a bas spot such that when I write to EEPROM I am overwriting a critical set of config registers.  Seem odd that I can brick the device.

I would experiment more, but I have bricked my only two devices.  I have to get a DigiKey order in and replace the parts on my boards to continue.

Thanks:

-Eric

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Eric-san,

> Looking over your example I can't say I see a fundamental difference between what you are doing and what I am doing.

That's right. I've just skimmed your PowerMeter Project, and I could not find any fundamental differences, either.

In your first post, I could not see the definition of your emEeprom[], I was suspecting it, but it turned out that you are doing it right, or at least similar to my sample.

> In the datasheet for Em_EEPROM they have a section on: "Placing EEPROM Storage at Fixed Address". 

> I did not do this, and from what I can see in your code you did not either.  They seem to indicate this is optional.

I have tried both fixed and "not fixed" but they both worked OK.

So as you understand, it is an option.

> Seems like I have it in a bas spot such that when I write to EEPROM I am overwriting a critical set of config registers. 

> Seem odd that I can brick the device.

I agree with you if we can assume that the Em_EEPROM function is triggering the problem.

But since your program can read the data back after reset, there may be a case that something else is causing the problem.

> I would experiment more, but I have bricked my only two devices. 

> I have to get a DigiKey order in and replace the parts on my boards to continue.

As I wrote above, may be you had better not trying more until you (and/or we) can figure out what was the problem

even if you receive new devices.

BTW, can you try using PSoC Programmer to erase all flash of the bricked device?

You can download it from the URL below. And please download and install the newest one.

https://www.cypress.com/documentation/software-and-drivers/psoc-programmer-archive

Best Regards,

9-Oct-2020

Motoo Tanaka

0 Likes
Rakshith
Moderator
Moderator
Moderator
250 likes received 1000 replies posted 750 replies posted

Hi Eric,

I tried importing your PSoC Creator project and changing the device but PSoC Creator was throwing an error. PSoC Creator is not able to modify the .cydwr file. Can you please re-archive the project and attach it to the thread? If you have any protection enabled, please disable the same and then archive the project.

Seems like I have it in a bas spot such that when I write to EEPROM I am overwriting a critical set of config registers.  Seem odd that I can brick the device.

As you are not providing the fixed address, it should not be affecting any config registers by default. It is unlikely that this might happen 😐

Are you still able to receive the UART logs in the devices that you used?

Also, please try out the PSoC Programmer suggestion and let us know your observations.

Thanks and Regards,

Rakshith M B

Thanks and Regards,
Rakshith M B
lock attach
Attachments are accessible only for community members.

Hello Rakshith,

Attached is another "bundle" of the project.  Hope this one is good.  You mentioned: "if I have any protection enabled, I should disable it"  Not sure what I should look for there?  Anymore detail on that incase I am doing something wrong might be good.  Regarding the debug UART output, I am attaching a couple of screen shots of the serial debug output of both the 1st and 2nd units as they operate now.

As you can see they still work correct in "application mode" and the reads/writes to Em_EEPROM still seem to occur.

Regarding the attempt at "Erase All" with the stand alone programmer.  I tried that with version 3.29 and it did not work.  See the thread with Motoo for more details.

Thanks:

-Eric

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

Hello Motoo-san,

  Thanks again for looking at this.  I downloaded the latest PSoC programmer (version 3.29.0).  The erase all does not work with this either.  Tried with both miniProg3 and a PioneerKit as the programming hardware.    See attached screen shot from trial with MiniProg3.  I should receive new chips on Saturday. I am going to replace the chip and attempt it with the Em_EEPROM memory at a fixed location.  Chips are cheap and I am pretty good with hot air re-work so not a problem to experiment a bit.  Thanks again for the help.

-Eric

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Eric-san,

> The erase all does not work with this either.

I'm sorry for hearing that.

Another thing I noticed from your screen shot is that you have a folder (directory) named

"PSoC Creator"

in your path to the project.

I think that path name should not have SPACE " ", or not-regular letters such as language specific letter and Kanji (16bit letter) etc.

So I recommend you to rename the folder to

"PSoC_Creator"

or

"PSoCCreator"

Also I would like to ask you to try the followings.

(1) I see that you selected "10p" for the connector, would you try "5p" instead?

(2) Check AutoDetection "Off" and specify the Device Family and Device in the left side panes.

(3) Try "Power Cycle"  for Programming Mode.

(4) Try slower "Clock Speed"

(5) Double Check the connections of SWD

(6) Double Check the check list in AN88619 below

https://www.cypress.com/file/141176/download

I especially would like to ask you to check chapters

4 Power

6 Reset

7 Programming and Debugging

Appendix C Schematic Checklist

> Chips are cheap and I am pretty good with hot air re-work so not a problem to experiment a bit.

I respect you!

Best Regards,

10-Oct-2020

Motoo Tanaka

Motoo-san,

  You rule!!   Thanks.  The combination of fixed Family/Device and Power Cycle instead of Reset for the programmer did the trick.  I can recover the chips.  I moved the code to fixed location using:

const uint8 emEeprom[Em_EEPROM_1_PHYSICAL_SIZE]

CY_SECTION(".my_emulated_eeprom") __ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};

and the the suggested modifications to the linker script outlined in the datasheet.  Even after that it gives me problems with programming the Reset/auto detect way.  But I don't really care. The Em_EEPROM is working and I have a method of programming the chips now.

Thanks again so much for your help.

-Eric