2020-12-28 12:53 AM
In the last weeks, I was working on running W25Q256 nor flash chip from vendor Winbond with STM32F746 MCU on a custom board. My guideline in this road is ST's how to run QSPI flash video tutorial (5-part video) and of course some genius guys in the community who's helped me a lot to rewrite the functions of QSPI flash (Init, Erase, Write, Memory-mapped). So far functions tested in the Main.c and I can read the pre-written data on the memory. The next step is to generate (.stldr) external loader file and modify Flash.ld file.
according to the video tutorial, I added Loader_Src.c, dev_inf.c, and dev_inf.h files to the workspace but there is a little confusion about flash.ld file that contains memory definitions and all other data and text stuff to assign to specific memory (>FLASH, >RAM, >QUADSPI).
for the point of concern, I use STM32F746 with IS42S32400F SD-RAM connected with 2-banks to MCU and of-course W25Q256 NOR-FLASH.
here I uploaded relevant files for check
STM32F746BGTX_FLASH.ld
/**
******************************************************************************
* @file LinkerScript.ld
* @author Auto-generated by STM32CubeIDE
* @brief Linker script for STM32F746BGTx Device from STM32F7 series
* 1024Kbytes FLASH
* 320Kbytes RAM
*
* Set heap size, stack size and stack location according
* to application requirements.
*
* Set memory bank area and size if external memory is used
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200 ; /* required amount of heap */
_Min_Stack_Size = 0x400 ; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}
/* Sections */
SECTIONS
{
/* The startup code into "FLASH" Rom type memory */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/* The program code and other data into "FLASH" Rom type memory */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH
/* Constant data into "FLASH" Rom type memory */
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
.ARM.extab : {
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*)
. = ALIGN(4);
} >FLASH
.ARM : {
. = ALIGN(4);
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
. = ALIGN(4);
} >FLASH
.preinit_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
} >FLASH
.init_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
} >FLASH
.fini_array :
{
. = ALIGN(4);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
} >FLASH
/* Used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* Initialized data sections into "RAM" Ram type memory */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section into "RAM" Ram type memory */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* Remove information from the compiler libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
.ARM.attributes 0 : { *(.ARM.attributes) }
}
Dev_inf.c
/*
* Dev_Inf.c
*
*/
#include "Dev_Inf.h"
#include "quadspi.h"
/* This structure contains information used by ST-LINK Utility to program and erase the device */
#if defined (__ICCARM__)
__root struct StorageInfo const StorageInfo = {
#else
struct StorageInfo const StorageInfo = {
#endif
"QSPI_flashloader_CSP", // Device Name + version number
NOR_FLASH, // Device Type
0x90000000, // Device Start Address
MEMORY_FLASH_SIZE, // Device Size in Bytes
MEMORY_PAGE_SIZE, // Programming Page Size
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
{ {
(MEMORY_FLASH_SIZE / MEMORY_SECTOR_SIZE), // Sector Numbers,
(uint32_t) MEMORY_SECTOR_SIZE
}, //Sector Size
{ 0x00000000, 0x00000000 }
}
};
Solved! Go to Solution.
2021-07-27 11:40 PM
@Community member Thank you very much and sorry for the late response I was out of office , unfortunately my pin configuration is :
PB2,PB10,PC9,Pc10,PD13,PE2 which is not mentioned on your github files. I would find the source much more usefull though as I am not only in need of a flash loader but also a driver. About my current bsp I have copied this project which is very similar to mine https://github.com/uraetech/STM32H750-Development-Board/tree/master/H750%20QSPI%20W25Q128 and change some register definitions for compatibility between JV and FV variants with no success I can only read the flash,read the manufacturers Id but not erase or write
Thanks again Spyros M.
2021-07-28 07:57 AM
There are so many pin combinations.
These particular ones are coded in assembler, with a table driven pin initialization list. Really don't furnish source for these as it involves more tools and support than I can afford to provide.
Writing and Erasing can't occur concurrently with Memory Mapped Read
2021-07-28 08:00 AM
Current STLDR and FLM (Keil) forks for these now live here
https://github.com/cturvey/stm32extldr/tree/main/f7_w25q256
2021-07-29 03:45 AM
@Community member Thank you very much.
Unfortunately this doesn't work.Probably because of the different register bits between W25Q128JV and W25Q128FV , cube programmer stucks at erasing sector 0 for a minute and then it throws errors . I am aware that Writing and Erasing can't occur concurrently with Memory Mapped Read but I want the full driver in my use case for the reason below:
My product will store some bitmaps on the flash ,also my product will have a bootloader and probably many updates will occur.On the updates the bitmaps will probably change so the bootloader responsible for the updates will have to do what a flash loader does but without a jtag and with a usb for more user friendliness . And that's why I need to implement a whole driver and not only the memory mapped part.Thanks for the effort , it is bad that I didn't achieve what I wanted but I guess there are no shortcuts in my case.
Here are my logs by the way
EDIT :
@Community member Thank you very much.
oof I had a hardware problem , I was nor reading neither writing to flash IO3 due to a hardware error , my pin configuration is
PB2-> Clock
PB10-> CS
PC9 -> IO0
PD12 -> IO1
PD13-> IO2
PE2-> IO3
I am very sorry for the trouble!
2021-07-29 04:27 AM
The things are relatively easy to modify at this point.
PE2 should be D2/IO2
PD13 should be D3/IO3
It you have these switch we might need to use DUAL mode rather than QUAD
What's the key difference of the JV vs FV in your experiments?
Can you should schematic section for this as built?
This is my pin cheat sheet (although I think the AF mapping is slightly different for OSPI)
https://github.com/cturvey/stm32extldr/blob/main/h7pins.txt
Winbond parts to hand : W25Q128BVFG W25Q64BVFIG W25Q256FVFG W25Q512JVFQ
2021-07-29 06:47 AM
Not currently supporting DTR/DDR modes, loader doesn't really benefit from them. Also can't find readily available JVF(I)M parts in the SOP/SOIC-16 300mil form-factor currently. If someone has a few pieces they can send me, drop me an email.
W25Q128JVFIQ
W25Q128JVFIM (DTR)
2021-08-17 05:10 AM
The screen I made with Touchgfx works just fine. But Flash Memory is at 82% and will be full soon. So I need to implement QSPI. I have W25Q128JVSQ Flash and 176 pin STM32H743IITx board. Could you please prepare an MX file (with .ioc extension) for me? I work in a company that carries out an R&D project and I need to finish this job as soon as possible. Otherwise it won't be good for me.
2021-08-17 05:14 AM
2021-08-17 05:16 AM
These (4 pictures) are the images of the product, can you please help me urgently?
2021-08-17 05:17 AM