Programming external CFI Flash on stm32f407vgt6

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Programming external CFI Flash on stm32f407vgt6

    I have external NOR Flash, CFI compliant connected to my STM32f407vgt6. It seems I can not download into
    the external flash. Is there any trick to it? What do I need to do to get it up and running?
    I am using IAR EWARM, but I would like to also use it with a GDB tool chain such as emBlocks, to which
    I would like to switch.
  • Hi Mike,

    We will try to squeeze this in for later today.
    We basically have the code available for this.
    We will provide a sample project for emIDE (emide.org, similar to em::Blocks, also Code::Blocks based) as well as for IAR EWARM
    which demonstrates debugging in external CFI flash on a STM32F4xx.


    Best regards
    Alex
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Mike,

    Sorry for the delay.

    In general:
    For more information about how to get up and running with J-Link flash download into external CFI flash:
    UM08001, chapter "Flash download" section "Setup for various debuggers (CFI flash)"

    Please find attached:
    A sample for emIDE (tested with emIDE V2.02a and J-Link DLL V4.68a)
    A sample for IAR EWARM V6.40.5 (tested with J-Link DLL V4.68a)

    The samples are made for the STM32407IE which is the smallest STM32F4 device. So they will work on all ones.
    They demonstrate flash download into internal + external CFI flash via J-Link.
    The Delay() function in main.c is placed in external CFI flash while the rest is placed in the internal flash.

    For emIDE: Init steps can be found at Project -> Properties -> Debugger
    For IAR: Init steps can be found in Setup\Init.mac

    Note that the projects expect the NOR flash at nCS0. If the NOR flash is connected to another chip select, the init must be adapted accordingly.
    In such cases you also need to adapt the CFI base address.
    emIDE: Project -> Properties -> Debugger & linker file
    IAR: settings\STM32F407IE_1x16bit_CFI_NOR_nCS0_Debug_FLASH.jlink & linker file


    Best regards
    Alex
    Files
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • This is an old thread, but it does exactly what I want to do.. program and debug an external CFI Flash ROM from an ST ARM.
    When I use JFash to talk to the board, I can erase and reprogram Flash without an issue.
    However when I debug from within IAR, the Flash seems to be recognised, compared and relevant sectors erased..
    but it then fails programming a few bytes in ('Programming 1 over 0').
    Setup sequence in the MAC file for the JLink seems identical to the equivalent setup in JFlash project file.
    Any ideas?
    PS
    CPU is STM32F429ZI, Flash is Spansion S29GL512S
  • Update on this issue - in fact I cannot program form JFlash either I get the same error.
    I CAN read the Flash array correctly.
    Flash is actually Spansion S29GL256S.
    Does this need custom RAM code to be written to support this device?
  • Hi,

    Does this need custom RAM code to be written to support this device?

    No. This device is supported by regular CFI flash programming.

    When I use JFash to talk to the board, I can erase and reprogram Flash without an issue.

    Update on this issue - in fact I cannot program form JFlash either I get the same error.

    One of these statements has to be incorrect...
    Maybe there is an issue in your init sequence?
    Maybe the nWP pin of the flash is LOW, so it can be read but not erased/programmed?
    Or the external memory interface of the STM is configured for read-only accesses to the flash?
    That would explain why other operations than reading fail.


    - Alex
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • Hi Alex
    Thanks for looking at this!
    This is my setup for the init sequence:

    __InitEBI() {
    __message "Macro file: Initializing external bus interface.";
    //
    // Initialize flash controller
    // Otherwise application will not run stand-alone and not after "reset" is clicked in debugger
    //
    // FSMC clock enable
    __writeMemory32(0x00000001, 0x40023838, "Memory");
    // GPIOD~G clock enable
    __writeMemory32(0x000001FF, 0x40023830, "Memory");
    // GPIOD config
    __writeMemory32(0xAAAAAA0A, 0x40020C00, "Memory");
    __writeMemory32(0xFFFFCF0F, 0x40020C08, "Memory");
    __writeMemory32(0xCCCC00CC, 0x40020C20, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40020C24, "Memory");
    // GPIOE config
    __writeMemory32(0xAAAAAAAA, 0x40021000, "Memory");
    __writeMemory32(0xFFFFFFFF, 0x40021008, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40021020, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40021024, "Memory");
    // GPIOF config
    __writeMemory32(0xAA000AAA, 0x40021400, "Memory");
    __writeMemory32(0xFF000FFF, 0x40021408, "Memory");
    __writeMemory32(0x00CCCCCC, 0x40021420, "Memory");
    __writeMemory32(0xCCCC0000, 0x40021424, "Memory");
    // GPIOG config
    // was: 0x02A80AAA
    // set Pin 9 as Output (Flash WP)
    __writeMemory32(0x28040AAA, 0x40021800, "Memory");
    // was: 0x03FC0FFF
    __writeMemory32(0x1CFC0FFF, 0x40021808, "Memory");
    __writeMemory32(0x00CCCCCC, 0x40021820, "Memory");
    // was: 0x000CCCC0
    __writeMemory32(0x0CC00000, 0x40021824, "Memory");

    // explicit write of 1 to GPIOG9 (Flash WP)
    __writeMemory32(0x00000200, 0x40021818, "Memory");

    // FSMC config
    __writeMemory32(0x00001059, 0xA0000000, "Memory");
    __writeMemory32(0x20000705, 0xA0000004, "Memory");
    __writeMemory32(0x20000705, 0xA0000104, "Memory");
    // Set DBGMCU_CR
    __writeMemory32(0xE0042004, 0x000000E7, "Memory");
    }

    My changes are in Port G setup. We use PG9 for WP, so want to hold that high. In the original script, PG13/PG14 were not set as FMC Alternate function - they are FMC_A24 and FMC_A25.
    I haven't checked the config values yet but as they were from the original example I assume they are Ok?
    Is it possible that you write to PG9 during Flash programming?
    Thanks!
  • Alex
    Ok I checked FSMC vs. FMC - it seems that ST have made them compatible for NOR Flash, the register bit definitions are the same for the first setup register. The only difference between my setting in the code (that does read Ok) is that I was using burst-mode access, when I disabled that bit patterns are identical (in first setup register).. so write access has been allowed.
    All I can think of is that WP and/or Reset may be getting set wrongly during the attempted write..
    For reference here is setup macro:
    __InitEBI() {
    __message "Macro file: Initializing external bus interface.";
    //
    // Initialize flash controller
    // Otherwise application will not run stand-alone and not after "reset" is clicked in debugger
    //
    // FSMC clock enable
    __writeMemory32(0x00000001, 0x40023838, "Memory");
    // GPIOD~G clock enable
    __writeMemory32(0x000001FF, 0x40023830, "Memory");
    // GPIOD config
    // was: 0xAAAAAA0A
    // set Pin 2 as Output (Flash Reset)
    __writeMemory32(0xAAAAAA1A, 0x40020C00, "Memory");
    __writeMemory32(0xFFFFCF0F, 0x40020C08, "Memory");
    __writeMemory32(0xCCCC00CC, 0x40020C20, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40020C24, "Memory");
    // GPIOE config
    __writeMemory32(0xAAAAAAAA, 0x40021000, "Memory");
    __writeMemory32(0xFFFFFFFF, 0x40021008, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40021020, "Memory");
    __writeMemory32(0xCCCCCCCC, 0x40021024, "Memory");
    // GPIOF config
    __writeMemory32(0xAA000AAA, 0x40021400, "Memory");
    __writeMemory32(0xFF000FFF, 0x40021408, "Memory");
    __writeMemory32(0x00CCCCCC, 0x40021420, "Memory");
    __writeMemory32(0xCCCC0000, 0x40021424, "Memory");
    // GPIOG config
    // was: 0x02A80AAA
    // set Pin 9 as Output (Flash WP)
    __writeMemory32(0x28040AAA, 0x40021800, "Memory");
    // was: 0x03FC0FFF
    __writeMemory32(0x1CFC0FFF, 0x40021808, "Memory");
    __writeMemory32(0x00CCCCCC, 0x40021820, "Memory");
    // was: 0x000CCCC0
    __writeMemory32(0x0CC00000, 0x40021824, "Memory");

    // explicit write of 1 to GPIOG9 (Flash WP)
    __writeMemory32(0x00000200, 0x40021818, "Memory");

    // FMC config
    __writeMemory32(0x00001059, 0xA0000000, "Memory");
    __writeMemory32(0x0453159C, 0xA0000004, "Memory");

    // explicit write of 1 to GPIOD2 (Flash Reset)
    __writeMemory32(0x00000004, 0x40020C18, "Memory");

    //__writeMemory32(0x00001059, 0xA0000000, "Memory");
    //__writeMemory32(0x20000705, 0xA0000004, "Memory");
    //__writeMemory32(0x20000705, 0xA0000104, "Memory");
    // Set DBGMCU_CR
    //__writeMemory32(0xE0042004, 0x000000E7, "Memory");
    }
  • Hi,

    See my answer in the new forum thread, which you created regarding this issue: Programming external NOR Flash on STM32F429.

    - Erik
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.