FM0+ Flash routines

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

cross mob
Chva_1477726
Level 4
Level 4
25 sign-ins 10 sign-ins First solution authored

Hi

I need to save calibration parameters and since the MCU does not have EEPROM, I need to use flash to save them.

I am experiencing  serious issues with the mainflash routines in PDL2.1.

  1. The MFlash_SectorErase function erases the sector, but he MCU "hangs" and need a reset to work again. This is a big issue as you need to clear the sector before you can write again to that area.
  2. the MFlash_WriteData32Bit function writes one 32bit word and "hang" the MCU, requiring a reset.
  3. The MFlash_WriteData16Bit works only if you write one 16bit halfword. If you try to write more than one halfword, the MCU "hang" end require a reset.
  4. The MFlash_WriteData16Bit routine requires a 16bit address, which means you cannot write to an address above 64K on the 88K and 128K MCU's

Not related to the PDL, I cannot seem to find the sector size in any of the documentation.

I managed to get 3) to work with multiple writes by changing the PDL routine, but it writes at word boundaries, not halfword boundaries.

I have lost a lot of development time tracking down some of the issues and is really disappointed that the provided library functions does not work as advertised.

Any assistance to get this resolved will be appreciated.

Best regards

Chris

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

I had a look to the mainflash.c provided by PDL 2.1.0, and figured out, it only may work when using the IAR compiler.

PSoC Creator uses GCC.

Flash routines for FM0+ need to me executed within the RAM area, so the mainflash.c must be copied and linked to RAM area, what is done for IDE by the directive __ramfunc

Workaround/solution:

1) goto c:\Users\<your login>\Documents\Cypress\PDL\2.1.0\drivers\flash\

2) make a backup copy of existing mainflash.c

3) Copy the attached mainflash.c here.

4) Clean and build your project

Note: There will one warning, what is okay:

M0121:ignoring changed section attributes for .data

Additionally I have attached my test project (S6E1A1_MFlash.cyprj.Archive02.zip)

Next, you might prefer to use on of the smaller FLASH sectors, what is in the 'middle' of the complete FLASH.

Honestly the GCC (at least what I found) is not such comfortable like e.g. IAR.

Here my 'solution', see again attached example:

The 'problem' is, that the 'EEPROM' must be located within the FLASH-ROM area, in other words, the FLASH-ROM area must be spilt, what the GCC linker does not like.

Do as follow: on .\s6e1a12_rom.ld

MEMORY

{

  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 16K

  ROM1 (rx) : ORIGIN = 0x00006000, LENGTH = 64K

  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 6K

}

As you can see, SA2 (0x4000-0x3FFF) is not mentioned, as we will address it by pointers, no code must be linked.

You can add this area as well, if you like to map parameters from your code initially.

The Problem is, that your code per default is mapped to ROM, but this area is just 16K. If your code gets bigger, than you have to name it as ROM1 (or whatever name you like) see my dummycode.c, using __attribute__((section(".sectionROM1")))

Within the linker skript, I have added

  .sectionROM1 :

  {

  KEEP (*(.sectionROM1))

  } > ROM1

The 'disadvantage', you must split your code manually if it gets > 16KB, and you have to add __attribute__((section(".sectionROM1"))) to those additonal modules.

Regards,

Holger

View solution in original post

0 Likes
4 Replies
Roy_Liu
Moderator
Moderator
Moderator
5 comments on KBA First comment on KBA 10 questions asked

I don't have much experience with usage of FMx MCUs, but I hope the following stuffs could help you more or less.

The Flash Programming Manual has sector organization info:

https://www.cypress.com/documentation/programming-specifications/fm0-family-s6e1a1-series-flash-prog...

https://www.cypress.com/documentation/programming-specifications/s6e1c1c3-series-32-bit-microcontrol...

A code example:

https://www.cypress.com/documentation/software-and-drivers/s6e1a1-flash-uart

Roy Liu
0 Likes

Hi

Thanks for this info, I will go into it in detail. Looking at the sector structure, there are only 5 sectors and they are 8k and 32k in size (for the 88k chips). I cannot afford to "waste" 32k of flash at the end of the application for a few bytes of parameters.

Is there a way I can reserve the second 8k block at the beginning of the flash and get the application to fit around it? I am thinking along the lines of placing all initialization code in the first 8k flash sector and then start the application in the third block but need some guidance as to how to do this.

Any help will be appreciated. I have never changed the standard memory assignments of the compiler. I use PSoC Creator as IDE.

Regards

Chris

0 Likes

Hi

I tried the sector erase routine in the flash UART example and it still hang the MCU.

Regards

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

I had a look to the mainflash.c provided by PDL 2.1.0, and figured out, it only may work when using the IAR compiler.

PSoC Creator uses GCC.

Flash routines for FM0+ need to me executed within the RAM area, so the mainflash.c must be copied and linked to RAM area, what is done for IDE by the directive __ramfunc

Workaround/solution:

1) goto c:\Users\<your login>\Documents\Cypress\PDL\2.1.0\drivers\flash\

2) make a backup copy of existing mainflash.c

3) Copy the attached mainflash.c here.

4) Clean and build your project

Note: There will one warning, what is okay:

M0121:ignoring changed section attributes for .data

Additionally I have attached my test project (S6E1A1_MFlash.cyprj.Archive02.zip)

Next, you might prefer to use on of the smaller FLASH sectors, what is in the 'middle' of the complete FLASH.

Honestly the GCC (at least what I found) is not such comfortable like e.g. IAR.

Here my 'solution', see again attached example:

The 'problem' is, that the 'EEPROM' must be located within the FLASH-ROM area, in other words, the FLASH-ROM area must be spilt, what the GCC linker does not like.

Do as follow: on .\s6e1a12_rom.ld

MEMORY

{

  ROM (rx) : ORIGIN = 0x00000000, LENGTH = 16K

  ROM1 (rx) : ORIGIN = 0x00006000, LENGTH = 64K

  RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 6K

}

As you can see, SA2 (0x4000-0x3FFF) is not mentioned, as we will address it by pointers, no code must be linked.

You can add this area as well, if you like to map parameters from your code initially.

The Problem is, that your code per default is mapped to ROM, but this area is just 16K. If your code gets bigger, than you have to name it as ROM1 (or whatever name you like) see my dummycode.c, using __attribute__((section(".sectionROM1")))

Within the linker skript, I have added

  .sectionROM1 :

  {

  KEEP (*(.sectionROM1))

  } > ROM1

The 'disadvantage', you must split your code manually if it gets > 16KB, and you have to add __attribute__((section(".sectionROM1"))) to those additonal modules.

Regards,

Holger

0 Likes