This is awesome!! I'm designing a board that uses an STM32H723 and (2X) W25Q128JV NOR Flash in a Dual Quad config using the OCTO-SPI. SO, my config will be a bit more complex, but I think I will be able to use these examples to get started on the large task. Thank you so much for sharing.
Hi @seemeridecom, interesting project. It would be interesting to know the performance of this architecture. Could it be interesting, in some cases (heavy data handling), to store program over OSPI keeping data on the internal flash?
@@bluewatThe project I'm building will be a larger HMI and I'm not 100% sure of the size of all the assets or code. The processor has 1MB of internal flash and I know I'll overrun that for sure. My plan is to put as much code in that internal flash and most all the assets (graphics/fonts) in the 32MB. I think with having them set up at Octo SPI, they should be pretty fast. Also, if I overrun the 32MB, I can always go larger. This will be a product that I want to release new firmware to my customers via download and they can install using a USB drive. I may also leverage an internal SD FLASH for custom user backgrounds and such.
uC calls the external loader having disabled all interrupts. So, systick also is disabled and functions like HAL_InitTick(), called in initialization, would hang. That's why they are redefined. That's explained somewhere in the ST documentation indicated in the video desctiption. Library (in some cases: for instance resetting and initializing flash chip) needs some delays: I left the library calling HAL_Delay() so, when it is normally used in a project, it will use the system timer. While I redefined it here, making it working with no systick.
hi, thanks for video. i followed steps you shows. i am using w25q64 chip. in program Flash_init sims to be working well but at Flash_chiperase goes into infinite loop it stuck in busy flag. what is the problem?
@@bluewat you are right but in the function Flash_WaitForWritingComplete(); ---> infinite loop at while (buffer[0]& SR1_BIT_BUSY ); . This buffer never receive S1 register value and causes a loop infinity
Hello Mauro, Very comprehensive and detailed video, thank you! I'm struggling with building an external loader for an SPI flash for the STM32WLE5, I have the CubeIDE project up and running based on the video but when I connect to the device with CubeProgrammer and try to use the stldr I built I get a message "Error: Data read failed". I tried to take the SPI out of the stldr and only test the init part with blinking a led on my target but I get the same error. When I run the same project in debug configuration from main.c the led is blinking. What could go wrong? Any way to debug it? Thanks
Hi...I have tried implementing this for issi 4MByte memory on stm32h750. It works fine until I tried to program a bin file > 100kByte. Cube programmer shows download failure at segment (0). Any idea what is wrong?
Is it possible to have my external flash memory via SPI having part of my program from the STM32CUBEIDE loaded like if it were the internal flash to carry a few variables?
In principle, yes. But: (1) what you mean referring to "a few variables"? They should be "a few constants". If so: external loader would program flash and, setting up an appropriate driver, "variable/constants" could be read regadless where they are stored: inside or outside uC. (2) Take in consideration the SPI flash speed: what said at point (1) is valid "in principle". External flash is a widely used to store data and software. But not and SPI one. I'm working on a "smaller footprint" version of the external loader. Much smaller. I'll try to set an example of this kind of handling also.
@@bluewatOh, great!! BTW my interest is basically do stuff with LCD Displays and for other projetcs, working with lookup tables. In this format, if i have a Lookup Table saved in the external memore like this: uint16_t Lookuptable[1000*60] __attribute__((section("ExtFlashSection"))); Can i address in the code calling like this: uint16_t data = Lookuptable[60]; To try to get the data from the Lookuptable[60] (in the pos 60) ? os do i need to get the pointer of the variable + the 60 positions and fetch from the Flash with the library functions?
No, you can't do that with an SPI flash. You have to setup a function handling flash/memory reading and than, using that function, you can forget if the data is stored intertnally or not in the rest of the program.
I was trying to make the external loader for the STM32G0B1CBT6 that has a RAM of 144K. It generates ok, but the issue is that when i try to open in the cube programmer, it shows as unknown and with address 0x0000000 and no name. Any idea of what could be the issue? (I've oppened an issue in the github as well with screenshots)@@bluewat
Hello!! Mauro, I have issues with CubeIDE, External Loader. In CubeProgrammer works great, but when i try use it on CubeIDE i cant write, so i dont know whats going on. Could you help me with.
CubeIDE and CubeProgrammer use THE SAME modules so you should easily detect the error: your EL is good (!), that's just a CubeIDE project problem. My 2 cents is: (first hypotesis) did you unselect "verify" in CubeIDE EL properties? If yes I see only (second one) a linker script problem. But it is not easy from here helping you much more than this.
I'm not sure, but it shouldn't be difficult to adapt the library to another type of communication. As you can see, Loader_Src.c makes calls to a library handling SPI communication through simple functions: Flash_Read(), Write(), Clear(),...
Hello sir, great video ! I am building a project on stm32 bluepill(f103CT8) and i require to store char arrays and for that i am using winbound flash chip , can give some steps to take care while writing the arrays in the memory and how to read them as i will require to read them mutiple times .
You should find, more or less, all information here in the video (how flash works and how it should be handled), in the related GitHub page (how to setup a project), and in the library function descriptions (how to use the single library functions). If the array is a "const" (written one time only, programming the system and read-only on project runtime) you could get to a very easy flash handling by mapping flash on the uC address space. Not described here until now. I'm working on a new video on this topic.
Hi, Thank you for the Video. I created the .stldr file. But Cube programmer doesn't show Memory Size, page size or Memory type. What could be the reason. I checked and rechecked every step mentioned in your video. Thanks in Advance My device is: STM32G0B0CET6
Hi, the easiest part of the answer is that you can be sure that there is something wrong. Not easy is to say what is wrong. That could be also just the structure in Dev_Inf.c. Maybe just a too long string as device name?
I don't understand why any writing or reading operation only works once (external loader functions). When I want to make a second transaction, I need to connect to stlink again. What could be the reason for this?
integrating an I2C eeprom, that's interesting: something I have in mind to test but I haven't yet done. F446re: ok, no problem with ram size. How you use I2C? In some my first tests (SPI) I had some problems with DMA. (Even considering disabled interrupts) Then I used only polling mode. But it was in my first tests: maybe now it could work. Even if I keep working only in polling mode on external loaders. Something else could be in the uC status left, after writing: changes something enabling/disabling "verify" after writing?
@@bluewat I did not use dma or interrupt. I did any delay part as you did. The functions already work stably on their own. The problem is that after performing any operation, I have to reconnect to stlink to perform a second operation. I experienced the same problem about six months ago when I tried to make an external loader with w25q32.
As you probably have already seen, TestAvailability just reads SFDP record from the flash. That record reports JEDEC information about device connected. Despite the memory size, the record starts with the string "SFDP". That is the only test done by TestAvailability function to see if a chip si connected and communicating. Now, I see only three possibilities: - (the absolutely most likely one) there is something wrong in the communication (SPI port setup and/or wiring). I noted that winbond SPI communication is quite weak (compared to other SPI devices). So, while prototyping over a breadboard, I keep a quite slow speed: below 2mbps. I rise it to higher speed (50mpbs and above) when I move the project over a PCB. Doublecheck wiring and CubeMX configuration - (it is possible, but only if you really belive communication is good) the flash could be damaged? can you test another chip? can you use current chip in another circuit? - (is it possible?) Winbond says that its devices follow Jedec standard since 2011 but not saying how was SFDP record before 2011. Is it possible you have a chip made before 2011?
@@kursadgulereem you are right this worked for me too, not I can program w25q64 using h723, now I want to figure out how to boot from that code.. I think I need to copy it to RAM.. then jump to RAM, right @bluewat?
Hello, great tutorial, but can You try this for STM32G0B0CET6 ? I got only blank name/board/mem size and device type: "UNKNOWN" in stm32CubeProgrammer.
@@pallavikadaam If I remember correctly, there is a problem with memory organization. In my case, an additional section was created in RAM before the loader functions. Solution: check the RAM structure with a memory analyzer. Delete the extra section. It worked for me.
Hello, great libray but I have some problems with creating external loader. I another project, libray works excellent (while testing communication with flash chip). But when I want create a external loader while debuging project the Flash_TestAvailability always return 0. I tried to set lower speed but without success (in another (test) project i was able to set max SPI speed and everythink works well. Regarding to debugging the loader project i found that HAL_SPI_Transmit(&FLASH_SPI_PORT , data, dataSize, HAL_MAX_DELAY) always return HAL status BUSY. Maybe someone knows why :)
I had a project having about 1MB loaded onto a flash without problems, I don't remember if sometimes I had something needing more than 1M. I checked that project right now: an F103@64MHz (a bluepill) with a w25q64 on spi1@2Mbps. If you like a help, you should provide at least some information: what's your system? How you say you can't write data over 128k? You mean you get an error? what's the error? ...
I guess you have an error READING/VERIFYING flash (via CubeProgrammer). If so your EL is ok, flash is (hopefully, if you haven't a mistake somewhere) correctly programmed, it is a limit of CubeProgrammer. Try to disable verify option (even on CubeIde), and see what happens. I'm close to publish a new video explaining (among other topics) even this case