Skip to main content
yldzmuhammed
Associate III
August 21, 2019
Question

STM32F7 External Flash loader using QuadSPI

  • August 21, 2019
  • 3 replies
  • 1049 views

I have a problem same as on here https://community.st.com/s/profile/0050X000007vtAYQAY?t=1566392175765 but different mcu (STM32F750N8) and same flash chip.

I used the code that published there. But i cant get it done.

When i compile my code, i can see clk on the qspi chip. But it is not solid.

Here is my init code (uart for debugging):

/*
 * Initialize Flash Programming Functions
 * Parameter: adr: Device Base Address
 * clk: Clock Frequency (Hz)
 * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
 * Return Value: 0 - OK, 1 - Failed
 */
int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
{
	SystemInit();
 SystemClock_Config();
	
	__HAL_RCC_GPIOI_CLK_ENABLE();
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_3;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
	
	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
	GPIOI->BSRR = (uint32_t)GPIO_PIN_3 << 16;
 
 __HAL_RCC_USART1_CLK_ENABLE();
 
 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**USART1 GPIO Configuration 
 PA10 ------> USART1_RX
 PA9 ------> USART1_TX 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	HAL_UART_Init(&huart1);
	
	
	
	SYSInit();
	BSP_QSPI_Init();
	
//	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
// QSPI_ResetMemory();
 
//	BSP_QSPI_MemoryMappedMode();
	
	return (0);
}
//

Here is my subsector erase code:

/*
 * Erase Sector in Flash Memory
 * Parameter: adr: Sector Address
 * Return Value: 0 - OK, 1 - Failed
 */
int EraseSector (unsigned long adr)
{
	HAL_UART_Transmit(&huart1, (uint8_t *)"Sector erase", sizeof("Sector erase"), 1);
	GPIOI->BSRR = GPIO_PIN_0;
	BSP_QSPI_Erase_Block(adr - base_adr);
	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
	
	return 0;
}
//

Here is my sector erase (full chip) code:

/*
 * Erase complete Flash Memory
 * Return Value: 0 - OK, 1 - Failed
 */
int EraseChip (void)
{
	HAL_UART_Transmit(&huart1, (uint8_t *)"Full chip erase", sizeof("Full chip erase"), 1);
	GPIOI->BSRR = GPIO_PIN_3;
	BSP_QSPI_Erase_Chip();
	GPIOI->BSRR = (uint32_t)GPIO_PIN_3 << 16;
	
	return 0;
}
//

I tried so many thing but still no progress. It is not rigid. Can some one give me a hand?

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
August 21, 2019

The call syntax here looks to be for the Keil flash loader, presumably you're using the STM32 Cube Programmer, or ST-LINK Utilities.

Have you tested the code within your own application?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
yldzmuhammed
Associate III
August 21, 2019

No, I am not using STM32Cube Programmer or ST-Link. In fact i can't. But not important. I am using Jlink.

Yes, i am testing it now. All day..

Some times, when i erase flash (Flash->Erase menu), it calls EraseChip function, and some times EraseSector function.

When i try to program (Load) it says that Flash Timeout. Reset the Target and try it again.

But i added to the flash loader code and in the init function

	SystemInit();
 SystemClock_Config();
	
	__HAL_RCC_GPIOI_CLK_ENABLE();
 
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_3;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
	HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
	
	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
	GPIOI->BSRR = (uint32_t)GPIO_PIN_3 << 16;
 
 __HAL_RCC_USART1_CLK_ENABLE();
 
 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**USART1 GPIO Configuration 
 PA10 ------> USART1_RX
 PA9 ------> USART1_TX 
 */
 GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	huart1.Instance = USART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart1.Init.OverSampling = UART_OVERSAMPLING_16;
	huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
	huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	HAL_UART_Init(&huart1);
	
	sprintf((char*)buffer, "Init->adr: 0x%00000000lX clk: 0x%00000000lX fnc: 0x%00000000lX\r\n", adr, clk, fnc);
	HAL_UART_Transmit(&huart1, buffer, strlen((const char*)buffer), 1);
	
	SYSInit();
	BSP_QSPI_Init();
	
//	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
// QSPI_ResetMemory();
 
//	BSP_QSPI_MemoryMappedMode();
	
	return (0);

printed Init->adr: 0x90000000 clk: 0xBEBC200 fnc: 0x1

In the erase functions

/*
 * Erase complete Flash Memory
 * Return Value: 0 - OK, 1 - Failed
 */
int EraseChip (void)
{
	HAL_UART_Transmit(&huart1, (uint8_t *)"Full chip erase\r\n", sizeof("Full chip erase\r\n"), 1);
	
//	GPIOI->BSRR = GPIO_PIN_3;
	uint8_t response = BSP_QSPI_Erase_Chip();
//	GPIOI->BSRR = (uint32_t)GPIO_PIN_3 << 16;
	
	return response;
}
//
 
/*
 * Erase Sector in Flash Memory
 * Parameter: adr: Sector Address
 * Return Value: 0 - OK, 1 - Failed
 */
int EraseSector (unsigned long adr)
{
	sprintf((char*)buffer, "EraseSector->adr: 0x%00000000lX\r\n", adr);
	HAL_UART_Transmit(&huart1, buffer, strlen((const char*)buffer), 1);
	
//	GPIOI->BSRR = GPIO_PIN_0;
	uint8_t response = BSP_QSPI_Erase_Block(adr - base_adr);
//	GPIOI->BSRR = (uint32_t)GPIO_PIN_0 << 16;
	
	return response;
}
//

prints nothing. And some times i can succesfully erase program (via fully erase) and mostly not.

I can not program btw.

Tesla DeLorean
Guru
August 21, 2019

>>Yes, i am testing it now. All day..

By "tested", I mean that you have a stand-alone application or test program, that is able to use the flash memory, exercise it (read, write, erase, execute-in-place) and works flawlessly, prior to integrating into a loader application.

One of the QSPI parts I've been using has a Mass Erase time of 80-90 seconds. You'd want to confirm actual run times for completion before setting timeouts, and those should perhaps provide some 10-15% margin.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
yldzmuhammed
Associate III
August 21, 2019

Hi,

I have solved the problem but Verify function. Now i can program all the flash memory area.

Have should i write the verify function for keil api?

Edit: I will publish on github this, when i complite.

yldzmuhammed
Associate III
August 21, 2019

I can not see any problem to let it occur. But somehow, functions not returning back (i think so). I atteched my external loader project.