cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H747I-DISCO QSPI not working with BSP

nathan_s
Associate

I am trying to read and write to the MT25TL01G on the STM32H747I-DISCO board via the QSPI interface during runtime. I followed https://community.st.com/t5/stm32-mcus/how-to-add-a-bsp-to-an-stm32cubeide-project/ta-p/49812 to add the BSP to my project, using the QSPI files instead of the LCD files, and using the MT25TL01G component instead of the devices specified in that post. The program successfully compiles and runs, but data is not successfully written/read from the mt25.
The code I have written is below, and should function as a basic test of QSPI read/write functionality.
The program loops as intended, and does not get stuck anywhere. However, the result buffer always remains filled with 0s and never matches the data buffer as intended.
Using ST-Link, I have confirmed that the program successfully fills the address specified with 0s, but does not successfully write data values.
Please let me know what I'm missing 🙂


My init function:

/**
* @brief QUADSPI Initialization Function
* @PAram None
* @retval None
*/
static void MX_QUADSPI_Init(void)
{

/* USER CODE BEGIN QUADSPI_Init 0 */

/* USER CODE END QUADSPI_Init 0 */

/* USER CODE BEGIN QUADSPI_Init 1 */

/* USER CODE END QUADSPI_Init 1 */
/* QUADSPI parameter configuration*/
hqspi.Instance = QUADSPI;
hqspi.Init.ClockPrescaler = 255;
hqspi.Init.FifoThreshold = 1;
hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
hqspi.Init.FlashSize = 1;
hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
hqspi.Init.DualFlash = QSPI_DUALFLASH_ENABLE;
if (HAL_QSPI_Init(&hqspi) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN QUADSPI_Init 2 */
BSP_QSPI_Init_t init;
init.InterfaceMode = MT25TL01G_QPI_MODE;
init.TransferRate = MT25TL01G_DTR_TRANSFER;
init.DualFlashMode = MT25TL01G_DUALFLASH_DISABLE;
if (BSP_QSPI_Init(0, &init) != BSP_ERROR_NONE)
{
Error_Handler();
}
/* USER CODE END QUADSPI_Init 2 */

}

My main function:

/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* USER CODE BEGIN Boot_Mode_Sequence_1 */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/* Activate HSEM notification for Cortex-M4*/
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));
/*
Domain D2 goes to STOP mode (Cortex-M4 in deep-sleep) waiting for Cortex-M7 to
perform system initialization (system clock config, external memory configuration.. )
*/
HAL_PWREx_ClearPendingEvent();
HAL_PWREx_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFE, PWR_D2_DOMAIN);
/* Clear HSEM flag */
__HAL_HSEM_CLEAR_FLAG(__HAL_HSEM_SEMID_TO_MASK(HSEM_ID_0));

/* USER CODE END Boot_Mode_Sequence_1 */
/* MCU Configuration--------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC3_Init();
MX_ETH_Init();
MX_FMC_Init();
MX_HDMI_CEC_Init();
MX_QUADSPI_Init();
MX_RTC_Init();
MX_SAI1_Init();
//MX_SDMMC1_SD_Init();
MX_SPDIFRX1_Init();
MX_SPI2_Init();
MX_SPI5_Init();
MX_TIM8_Init();
MX_TIM13_Init();
MX_UART8_Init();
MX_USB_OTG_HS_PCD_Init();
/* USER CODE BEGIN 2 */
const uint32_t TEST_ADDRESS = 0x00050000;
const uint32_t TEST_SIZE = 128;
uint8_t clear[TEST_SIZE];
for (uint32_t i = 0; i < TEST_SIZE; i++)
clear[i] = 0;
uint8_t data[TEST_SIZE];
for (uint32_t i = 0; i < TEST_SIZE; i++)
data[i] = i;
uint8_t result[TEST_SIZE];
for (uint32_t i = 0; i < TEST_SIZE; i++)
result[i] = 0;


/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
BSP_QSPI_Write(0, clear, TEST_ADDRESS, TEST_SIZE);
BSP_QSPI_Read(0, result, TEST_ADDRESS, TEST_SIZE);
BSP_QSPI_Write(0, data, TEST_ADDRESS, TEST_SIZE);
BSP_QSPI_Read(0, result, TEST_ADDRESS, TEST_SIZE);
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

1 ACCEPTED SOLUTION

Accepted Solutions

I would definitely recommend reading the MT25TL01G data sheet, and acquainting yourself as to how NOR Flash works.

The memory needs to be erased first, and you get one shot at knocking ONE bits down to ZERO. It does not behave like RAM or EEPROM

You DON'T write a page of zeros to it. Erase the sector(s) usually a minimum of 4KB, and then Write the content you want, 256 bytes at a time, on 256 byte boundaries. Both Write and Erase operation expect you to wait of completion, by polling BUSY/READY status of the array.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

3 REPLIES 3
Imen.D
ST Employee

Hello @nathan_s and welcome to the Community 🙂

You can get inspired from the examples and update your configuration according to your needs:

STM32Cube_FW_H7_V1.11.0\Projects\STM32H747I-EVAL\Examples\QSPI\

STM32Cube_FW_H7_V1.11.0\Projects\STM32H747I-DISCO\Examples\BSP\readme.txt

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
raptorhal2
Lead

Try smaller steps to get there:

   Read status and ID registers first.

   Read memory. Its a NOR memory, so that should return 255 for each byte after an erase.

   Page Program, then read memory. Check the code to ensure Page Program is sending a Write Enable before writing.

This flash memory is a very capable, complicated device. Read the data sheet thoroughly to troubleshoot.

I would definitely recommend reading the MT25TL01G data sheet, and acquainting yourself as to how NOR Flash works.

The memory needs to be erased first, and you get one shot at knocking ONE bits down to ZERO. It does not behave like RAM or EEPROM

You DON'T write a page of zeros to it. Erase the sector(s) usually a minimum of 4KB, and then Write the content you want, 256 bytes at a time, on 256 byte boundaries. Both Write and Erase operation expect you to wait of completion, by polling BUSY/READY status of the array.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..