Skip to main content
yldzmuhammed
Associate III
September 3, 2019
Question

STM32F7 QSPI Flash External Flash Loader

  • September 3, 2019
  • 36 replies
  • 5771 views

Hello to everyone.

I am currently developing a project using STM32F750N8 and W25Q128. As you can guess, the project has an LCD. So the project is too big to fit into the internal memory. That's why I need an external memory integrated programming.

I develop the software with Keil and use the Jlink programmer.

I know that i need to the External Flash Loader for this operation. That's why I developed one.

But it doesn't work as it should. I also added UART for debug purposes. It works quite unstable.

Sometimes Init function doesn't work, sometimes the sector erase fails, sometimes the full chip erase fails, sometimes everything works, but the verification fails. Verification is never successful, though.

I have developed an application that runs on the internal memory, and I can sector/full chip erase and write any data in the external memory.

I also monitored the voltage from the flash chip ic from VCC pin using an oscilloscope. 3.3V. Just as it should be. When wiping, writing, reading, the voltage is exactly as it should be. But I didn't get a stable result.

I have prepared the attached project.

Can someone take a hand?

This topic has been closed for replies.

36 replies

AVI-crak
Senior
September 4, 2019

Externally managing exact memory addresses is a very bad idea. After some time, you may change the design of the breadboard, at this point you will have to rewrite two programs - for the breadboard and for the big machine.

However, if the recording algorithm is made easier, then its reliability will increase.

You need to transfer data blocks of an acceptable size from a large machine, so that the correction of transmission errors does not freeze data transmission for a long time. The data block is located after the data packet level.

Data blocks must be collected up to the level of one physical data block of flash memory (not a whole sector !!!). Here you can have three blocks of physical size: the first is assembled, the second is a buffer, the third is written to flash memory. Three blocks allow you to perform data transfer and write operations - completely asynchronously, without waiting cycles.

Clearing flash memory from data, and checking for 0xFF - can be done on the machine, without exact addresses.

To verify data through direct reading, you already have part of the algorithm.

Feedback is not always needed as much as you want. Too detailed a report will only be annoying. It makes sense a detailed report in the failure mode, once.

I propose the option of writing a data block without controlling the sector address. If you change a little, it will work with any flash memory chip.

https://bitbucket.org/AVI-crak/system_f746/src/default/qspi_driver_S25FL256S/qspi_rw.c

yldzmuhammed
Associate III
September 4, 2019

Hello @AVI-crak​ 

I did not get your point. Sorry. Are you talking about (mainly) road map? Did you see any wrong part in my code?

AVI-crak
Senior
September 4, 2019

I looked at your code, it is based on HAL functions. I see address management but cannot see the contents of HAL functions. To do this, you must run your code on physical debugging - not available to me.

Address management is a mistake. You must hide address management behind the physical driver.

The transition between direct and indirect addressing is the operation "address & 0x0FFFFFFF". It does not matter the location of the memory bank and its size - there is no access above the address 0x0FFFFFFF.

AVI-crak
Senior
September 4, 2019

Additionally.

About writing a block to flash memory.

The internal external memory machine does not allow the clock to stop during a write operation. This means that the data must come in one piece, without pauses !!! This mode can only provide a working DMA. In the event of a failure, the write operation will be performed, but with errors. Errors are read through the state registers of the external flash memory.

In case of using DMA - a protective timer is not required. Because there are no external physical dependencies, everything is done inside the microprocessor.

Look at my code, there is a hardware check for state flags. There are no errors reading flags, I just check the contents of the memory by direct reading.

All modern flash memory chips already have a hardware anti-freeze timer. It resets the last operation and sets error flags on internal registers. The software protection timer is required only for debugging the program algorithm, after which it must be deleted.

yldzmuhammed
Associate III
September 4, 2019

By address management you mean:

#define SRAM_ADDRESS1	((uint32_t *)(SRAM2_BASE + 4))
#define SRAM_ADDRESS2	((uint32_t *)(SRAM2_BASE + 8))
 
/* Private macro -------------------------------------------------------------*/
#define M8(adr) 		(*((volatile uint8_t *) (adr)))
#define M16(adr) 		(*((volatile uint16_t *) (adr)))
#define M32(adr) 		(*((volatile uint32_t *) (adr)))
 
 
 
 
	M32(SRAM_ADDRESS1)++;
	M32(SRAM_ADDRESS2) += (uint32_t)sz;

If it is, they just keep some variables.

Can you explain with more details?

AVI-crak
Senior
September 4, 2019

I have a line

#define SDRAM __attribute __ ((section (". qsdram")))

You can write like this

#define QSPIROM __attribute __ ((section (". qspirom")))

This means the declared name section in the linker, where all the necessary data is placed. There is no need to accurately calculate the address; the machine will do this.

I do not know how your data is indicated in the external flash memory. I make the notation through the structure

#ifdef __cplusplus
 extern "C" {
#endif /* __cplusplus */
 
#ifndef image_h
#define graphics_package 0
 
#if (graphics_package == 1U)
#define QSPIROM __attribute__((section(".qspirom")))
QSPIROM static const struct
{
 uint16_t image01[0x25800];
 uint16_t image02[0x25800];
...
 
}grafik={
 #include "image0_1.h"
 #include "image0_2.h"
...
} ;
#else
 
 
typedef struct
{
 uint16_t image01[0x25800];
 uint16_t image02[0x25800];
...
}grafik_TypeDef;
#define grafik ((grafik_TypeDef*) (0x90000000))
 
#endif
 
#endif /* image_h */
#define image_h
 
#ifdef __cplusplus
}
#endif /* __cplusplus */ 

yldzmuhammed
Associate III
September 4, 2019

Firts of all, thanks alot for your support.

Secondly, i dont think this will help me to write firmware or anything to the flash memory with jlink. Am i correct?

AVI-crak
Senior
September 4, 2019

Look at my example, there is no exact binding to addresses. The compiler collects all the firmware at one time, tens of hundreds of separate pieces of data with a symbolic name in the addresses of external flash memory. This is a long time, but only once.

After that, the memory dump can be flashed with an external programmer, or with a separate project - using flash memory as a data storage device.

A symbolic name is much easier to use than exact addresses - which are very easy to get confused about.

If you need to add new data, just add it to the project under the write operation to your symbolic name. As a rule, these are small pieces of data that easily fit into the RAM memory in debug mode.

There is an option to use the file system, but this adds overhead when reading. And it almost completely prohibits the creation of one whole memory dump. This is convenient for the slow development of the project, and a huge crutch when replicating finished devices.

yldzmuhammed
Associate III
September 4, 2019

Dear @AVI-crak​ please forgive me.But i still don get that how to write external flash memory?i want to write all my firmware to the my external flash memory. How am i going to do that? That is all i need for now.

Thanks.

AVI-crak
Senior
September 4, 2019

Suppose grafik.image01 [] already exists, and grafik.image02 [] needs to be added

We are creating a new project for debugging in memory: with the initialization of the clock, functions for writing to flash memory, a data file for writing, and nothing more.

void main(void)
{
volatile uint32_t temp; temp = 0;
 
//qspi_data_wire ( uint8_t* data, uint32_t data_size, uint32_t flash_adres)
qspi_data_wire (image02_in[0] , (0x25800 * 2), &grafik.image02[0]);
while(1)
temp++;
;
}; 

We are waiting for the debugger to get to line number 8.

All new data is recorded.

Now you can delete this code.

The recording function itself checks the addresses of sectors of flash memory, with full overlap. If part of the data is located in the upper or lower part of the physical sector of the flash memory, then the entire physical flash sector is first read into the temporary buffer, then part of the data is replaced by new ones, after which the entire data sector is physically erased and written in a new cycle from the temporary buffer.

If the data completely covers several physical sectors of the external flash memory: then a little useless work is observed - the data is first read and then completely overwritten. I’m just too lazy to write processing conditions, everything works like that.

The size of the temporary buffer should be equal to the size of the physical sector of the external flash memory. There are chips with sector sizes 4k, 16k, 64k, 256k, 512k, and even 4M !!! This imposes restrictions on the breadboard; in some cases, the use of an external sdram is required.

In the case when the data for recording is large, then the only way out is to use an SD card. This is the easiest and fastest way to transfer data. Use the Jlink debugger for this purpose - a waste of time (more than two hours !!!).

I apologize, perhaps the reason for poor communication is the use of an online translator.

AVI-crak
Senior
September 4, 2019

I forgot, for the correct work with external flash memory in the indirect addressing mode - you must use the MPU settings. Allow this memory area to use, allow reading, allow code execution, enable data cache.

lexabps
Associate
September 16, 2019

Does your external flash downloader work?

yldzmuhammed
Associate III
September 16, 2019

Some times yes, mostly not working. Why did you asked?

lexabps
Associate
September 16, 2019

I need an external QSPI flashloader for STM32F746IGTx + w25q128fv

yldzmuhammed
Associate III
September 16, 2019

Which pins do you use for your board (i assume your board is custom. different from disco)? Have you ever test my code or did you write your own yet?

lexabps
Associate
September 16, 2019
yldzmuhammed
Associate III
September 16, 2019

Did they share any external loader?

lexabps
Associate
September 16, 2019

I do not know. I have not found.