Hello, I'm working on a STM32F429ZI board and S29GL128S External NOR Flash in order to save some code (images among others). I'm trying to configure the project, but I do something wrong because the KEIL finds errors. In order to generate an .FML file, I copied the project S29GL064Nx2 from C:\Keil\ARM\Flash and adapt it according to S29GL128S memory. In this project (S29GL128S), I have some doubts:
1) Is the Device of the "Options for Target" configuration STM32F429ZI? 2) Is important the Read/Only Memory Areas configuration? 3) The *.Lin file I put the same as S29GL064Nx2 project. Is it correct?
The address of flash starts 0x0000000 and its size is 0x1000000 (16MB). According to Reference Manual of STM32F429 (RM0090), the address to NOR flash, is from 0x60000000 to 0x6FFFFFFF. On STM32F429 project, I've selected in "tions for Target" > Debug > Settings > Flash Download the *.FLM file from S29GL128S.
i.imgsafe.org/0fee591383.png
The files which I want to save in the NOR flash, I've selected in "Options for file" ROM1 as a Memory Assigment.
i.imgsafe.org/0feddb3759.jpg
But, I have a Flash timeout error, can you help me about what is produced this error?
i.imgsafe.org/0fec83e876.jpg
Is there any tutorial which explains step by step how I have to configure?
Thanks in advance
Hi Brian,
thank you again for your comments,
I made a debug application for ST-Link Utility's external loader but when I'm debugging I can read, program and erase done but if I build such as an external loader I can't program/erase. Maybe there is a bad initialization when it works such as an external loader, I 'm still investigating. The important thing is I have a program that can read, program and erase and this a verification that the hardware works.
In Keil, I found the S29GLxxx flash programming with the legacity suport v4 and you can set the S29GL128P target which is similar our memory flash S29GL128S. Using this flash programming I can't program/erase any projecte from keil. I've been looking closely the S29GLxxx and there is never initialized any peripheral like FSMC or RCC. This initialization must be embedded in the code or throught a debug init file? If only I load a projecte without debugging is needed a init file?
I'm glad you were able to verify hardware functionality - that should make for much easier debugging now that there's absolute confidence that it's "just" a firmware issue!
I believe you need to use a debug init file for what you're trying to do. Here's an old thread with someone that was in a similar situation: http://www.keil.com/forum/60124/
Also, check out app note AN2784 from ST regarding executing code from external NOR flash (specifically page 15, which points at an example application running out of flash): www.st.com/.../cd00200423.pdf
There's typically a NOR execute example included in the Std Peripheral Lib package downloadable from ST, which might also be a good reference, although it probably won't provde any help with an INI file you'd need for the debugger.
Post back with any further progress, I'd like to hear about it - you guys are definitely on the right track.
Here are some additional hints for the debugger INI from Keil: http://www.keil.com/support/docs/3146.htm
Hi Brian
thank you for your fast replies!
In the Std Peripheral Library I found a NOR_codeExecute example (STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\FSMC\NOR_CodeExecute) whitch I try to follow the same steps. I made my own init file, configuring the FSMC and the GPIOs. Using this file such a debug init file I have the same result and I can't program/erase. Perhaps is missing the RCC's init for external clock becase the board is made with a external xtal.
FUNC void Setup(void) { // RCC _WDWORD(0x40021014, 0x00000114); // FSMC clock enable _WDWORD(0x40021018, 0x000001FD); // GPIOB~G clock enable // GPIOB (5,6) _WDWORD(0x40020400, 0x00002A80); // GPIOB MODE _WDWORD(0x40020408, 0x00003CC0); // GPIOB OSPEEDR _WDWORD(0x4002040C, 0x00000100); // GPIOB PUPDR _WDWORD(0x40020420, 0x0CC00000); // GPIOB AFRL _WDWORD(0x40020424, 0x00000000); // GPIOB AFRH // GPIOC (0) _WDWORD(0x40020800, 0x00000002); // GPIOC MODE _WDWORD(0x40020808, 0x00000003); // GPIOC OSPEEDR _WDWORD(0x4002080C, 0x00000000); // GPIOC PUPDR _WDWORD(0x40020820, 0x0000000C); // GPIOC AFRL _WDWORD(0x40020824, 0x00000000); // GPIOC AFRH // GPIOD (0, 1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15) _WDWORD(0x40020C00, 0xAAAA8A0A); // GPIOD MODE _WDWORD(0x40020C08, 0xFFFFCF0F); // GPIOD OSPEEDR _WDWORD(0x40020C0C, 0x00000000); // GPIOD PUPDR _WDWORD(0x40020C20, 0xC0CC00CC); // GPIOD AFRL _WDWORD(0x40020C24, 0xCCCCCCCC); // GPIOD AFRH // GPIOE (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) _WDWORD(0x40021000, 0xAAAAAA80); // GPIOE MODE _WDWORD(0x40021008, 0xFFFFFFC0); // GPIOE OSPEEDR _WDWORD(0x4002100C, 0x00000000); // GPIOE PUPDR _WDWORD(0x40021020, 0xCCCCC000); // GPIOE AFRL _WDWORD(0x40021024, 0xCCCCCCCC); // GPIOE AFRH // GPIOF (0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15) _WDWORD(0x40021400, 0xAAA00AAA); // GPIOF MODE _WDWORD(0x40021408, 0xFFC00FFF); // GPIOF OSPEEDR _WDWORD(0x4002140C, 0x00000000); // GPIOF PUPDR _WDWORD(0x40021420, 0x00CCCCCC); // GPIOF AFRL _WDWORD(0x40021424, 0xCCCCCE00); // GPIOF AFRH // GPIOG (0, 1, 2, 3, 4, 5, 8, 15) _WDWORD(0x40021800, 0x82A2AAAA); // GPIOG MODE _WDWORD(0x40021808, 0xC0030FFF); // GPIOG OSPEEDR _WDWORD(0x4002180C, 0x00000000); // GPIOG PUPDR _WDWORD(0x40021820, 0xEECCCCCC); // GPIOG AFRL _WDWORD(0x40021824, 0xC009E90C); // GPIOG AFRH // FSMC _WDWORD(0xA0000000, 0x000050D9); // FSMC_BCR1 _WDWORD(0xA0000004, 0x1FFFFFF9); // FSMC_BTR1 _WDWORD(0xA0000104, 0x1FFFFFF9); // FSMC_BWTR1 } Setup();
The final idea is do the same that says the app note AN2784: load our project in the external flash and have a minimal program in the internal flash where you can erase/write and jump the external flash memory.
I keep you updated
Best regards
I found some bugs in the debug ini file (wrong address RCC registers). After fixing it, I have been able to erase and program the external flash (the first time!) but I haven't been able to debug my project, it shows a dialog error with the message "This target device does not support all the defined breakpoints!Please reduce the number of breakpoints and start again". I checked there's no breakpoint enabled and the dialog still apears. I followed the steps noted in the discusion forum "Creating Dynamic Library" but the same results.
After doing a hardreset (unpluging the power of my board), now I can't erase and program. I catch the message error "Could non stop Cortex-M device! Please check the JTAG cable".My debug is configured to work with SW's port. I'm trying changing the options Connect & Reset Options without success.
Is there some wrong configuration or something is missing?
Hi Jordi,
That's mixed news if I've ever heard any. You're certainly closer now. . . Any time I've had errors regarding JTAG programming, it was usually an issue with a reset line, or one of the GPIO pins got remapped and was no longer dedicated to JTAG.
The ST Link V2 programmer only supports a handful of breakpoints - go to "Debug->Disable All Breakpoints" and then verify no breakpoints are set in the "Debug->Breakpoints" window.
Double check the last two messages in the previous forum thread 60124 regarding debug, it sounds like you're having similar issues - theirs was resolved by simply unchecking "load application at startup"
after checking the connection of my connector there was a problem with the SWD connector. Now is solved.
Now the scenario is:
-Now I can erase and program with Keil. The flashed project is verified, thus, the content of the memory is consistent.
-I made 2 init file, one is used on Init File field in "Options for Target > Utilities" and the other is used on Initialization File field in "Options for Target > Debug". This files inicializes the RCC, GPIOs and FMC but in case the second file is added a jump application to the external address (0x60000000).
FUNC void Setup(void) { // RCC_APB1ENR // - PWR EN = 1 _WDWORD(0x40023840, 0x10000000); // PWR_CR // - VOS = Scale 1 mode _WDWORD(0x40007000, (_RDWORD(0x40007000) | 0x0000C000) ); // RCC_PLLCFGR // - PLLQ = 7 // - PLLSRC = 1 // - PLLP = 2 // - PLLN = 336 // - PLLM = 8 _WDWORD(0x40023804, 0x07405408); // RCC_CFGR // PPRE2 = 4 (Div 2) // PPRE1 = 5 (Div 4) // HPRE = 0 (Div 1) // SW = 2 (PLLCLK) _WDWORD(0x40023808, 0x00009402); // RCC_CR // - PLLSAION = 1 // - PLLON = 1 // - HSEON = 1 _WDWORD(0x40023800, 0x11010083); // RCC_AHB1ENR // - GPIOBEN = 1 // - GPIOCEN = 1 // - GPIODEN = 1 // - GPIOEEN = 1 // - GPIODFN = 1 // - GPIODGN = 1 _WDWORD(0x40023830, 0x0010007E); // RCC_AHB3ENR // - FMCEN = 1 _WDWORD(0x40023838, 0x00000001); // GPIOB (5,6) _WDWORD(0x40020400, 0x00002A80); // GPIOB MODE _WDWORD(0x40020408, 0x00003CC0); // GPIOB OSPEEDR _WDWORD(0x4002040C, 0x00000100); // GPIOB PUPDR _WDWORD(0x40020420, 0x0CC00000); // GPIOB AFRL _WDWORD(0x40020424, 0x00000000); // GPIOB AFRH // GPIOC (0) _WDWORD(0x40020800, 0x00000002); // GPIOC MODE _WDWORD(0x40020808, 0x00000003); // GPIOC OSPEEDR _WDWORD(0x4002080C, 0x00000000); // GPIOC PUPDR _WDWORD(0x40020820, 0x0000000C); // GPIOC AFRL _WDWORD(0x40020824, 0x00000000); // GPIOC AFRH // GPIOD (0, 1, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15) _WDWORD(0x40020C00, 0xAAAA8A0A); // GPIOD MODE _WDWORD(0x40020C08, 0xFFFFCF0F); // GPIOD OSPEEDR _WDWORD(0x40020C0C, 0x00000000); // GPIOD PUPDR _WDWORD(0x40020C20, 0xC0CC00CC); // GPIOD AFRL _WDWORD(0x40020C24, 0xCCCCCCCC); // GPIOD AFRH // GPIOE (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) _WDWORD(0x40021000, 0xAAAAAA80); // GPIOE MODE _WDWORD(0x40021008, 0xFFFFFFC0); // GPIOE OSPEEDR _WDWORD(0x4002100C, 0x00000000); // GPIOE PUPDR _WDWORD(0x40021020, 0xCCCCC000); // GPIOE AFRL _WDWORD(0x40021024, 0xCCCCCCCC); // GPIOE AFRH // GPIOF (0, 1, 2, 3, 4, 5, 11, 12, 13, 14, 15) _WDWORD(0x40021400, 0xAAA00AAA); // GPIOF MODE _WDWORD(0x40021408, 0xFFC00FFF); // GPIOF OSPEEDR _WDWORD(0x4002140C, 0x00000000); // GPIOF PUPDR _WDWORD(0x40021420, 0x00CCCCCC); // GPIOF AFRL _WDWORD(0x40021424, 0xCCCCCE00); // GPIOF AFRH // GPIOG (0, 1, 2, 3, 4, 5, 8, 15) _WDWORD(0x40021800, 0x82A2AAAA); // GPIOG MODE _WDWORD(0x40021808, 0xC0030FFF); // GPIOG OSPEEDR _WDWORD(0x4002180C, 0x00000000); // GPIOG PUPDR _WDWORD(0x40021820, 0xEECCCCCC); // GPIOG AFRL _WDWORD(0x40021824, 0xC009E90C); // GPIOG AFRH // FSMC _WDWORD(0xA0000000, 0x000050D9); // FSMC_BCR1 _WDWORD(0xA0000004, 0x1FFFFFF9); // FSMC_BTR1 _WDWORD(0xA0000104, 0x1FFFFFF9); // FSMC_BWTR1 } Setup(); //--Only for debug init file-- LOAD %L INCREMENTAL SP = _RDWORD(0x60000000); // Setup Stack Pointer PC = _RDWORD(0x60000004); // Setup Prog Counter _WDWORD(0xE000ED08,0x60000000) // Offset Vector Reset //----------------------------
-Before use the external flash was made a project with STemWin libray that works fine with the internal memory but there isn't enought size to allocate more images. Now If I try debug this project in the external memory it starts in Reset_Handler and after called SystemInit and calling __main always is showed the same dialog of "This target device does not support all the defined breakpoints". The execution continues but I'm not sure what is run (LCD alsways is in white). To do it more easy to debug, I changed the main function which prints a "Hello World" throught the ITM port, but there's nothing printed in the Debug Viewer and in the bottom bar shows the message "Trace: Communication Error". The printf function worked fine when the project was allocated in the internal memory.
I'm wondering is there any limitation running an application in the external memory. I believe the simple main with printf should run without problems. Is missing any configuration in the compiler or linker?
Thank you for your support
I don't believe there's a limitation for executing code form external flash, other than possibly slower execution. That being said, I've never personally done it. There are several configuration registers for the FSMC, so you might want to double check these against your IC's datasheet (making sure both the Init functions in code and debug INI file are consistent)
You've managed to get very far, but are still hung up on executing out of external flash. One possible work-around (if you only need to store images in external flash) would be to locate just the images in external flash. You should be able to do this by group or per file: * right click on the group or file you'd like to move * click Options for <Group/File> * Under "Memory Assignment", choose your external flash address range from the Code/Const field.
This should get the linker to automatically load the images (or groups of images) you've selected into external flash, freeing up internal flash for code execution, only referencing external flash when an image is needed.
Jordi/Rouse
How has this progressed - have you guys managed to get your code executing out of external NOR flash, or did you successfully fall back to simply storing images there?
finally we found a workaround, flashing the images as bitmap (either DAT format) to the external flash. Also I found in the StemWin Library, the widget Image has two type of functions: One to load images from memory and the other to load from the external memory. Testing the second type of functions I catched HardFault_Handler's exception. I think it could be insufficient stack or heap size. I will investigate.
Thank you very mutch