4 Replies Latest reply on Jul 3, 2020 12:37 AM by HolgerW_56

    FM0+ Flash routines

    Chva_1477726

      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

        • 2. Re: FM0+ Flash routines
          Chva_1477726

          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

          • 3. Re: FM0+ Flash routines
            Chva_1477726

            Hi

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

             

            Regards

            • 4. Re: FM0+ Flash routines
              HolgerW_56

              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