Skip to main content
Ehill.16
Senior
September 13, 2020
Question

Writing and reading QSPI Flash on STM32F746G DISCO

  • September 13, 2020
  • 2 replies
  • 3630 views

I created my application using the CubeMX. Here are my read and write routines, my QSPI initialization routine, and while loop. I am using the USB to display what is read from the QSPI flash memory. I am writing a string to the memory, but when I read it back, read buffer is empty. I initial this buffer with "Empty", so it is doing something. Been working on since yesterday. Can anyone help me. The address I am sending is 0x90000000.

Here are my code snippets of the write function, the read function, the QSPI initialization function, and the main function loop.

 uint8_t QspiWriteData(uint32_t address, uint32_t size, uint8_t *pData) {

QSPI_CommandTypeDef s_command;

printf("Ft813QspiReadData8(%ld, %d, pData)\n", address, size);

/* Initialize the read command */

s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;

s_command.Instruction = EXT_QUAD_IN_FAST_PROG_CMD;

s_command.AddressMode = QSPI_ADDRESS_4_LINES;

s_command.AddressSize = QSPI_ADDRESS_32_BITS;

s_command.Address = address;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.AlternateBytes = 0;

s_command.DataMode = QSPI_DATA_4_LINES;

s_command.DummyCycles = 0;

s_command.NbData = size;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

/* Configure the command */

printf("HAL_QSPI_Command\n");

if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)

!= HAL_OK) {

printf("HAL_ERROR\n");

return HAL_ERROR;

}

/* Reception of the data */

printf("HAL_QSPI_Transmit\n");

if (HAL_QSPI_Transmit(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)

!= HAL_OK) {

printf("HAL_ERROR\n");

return HAL_ERROR;

}

return HAL_OK;

}

uint8_t QspiReadData(uint32_t address, uint32_t size, uint8_t *pData) {

QSPI_CommandTypeDef s_command;

QSPI_AutoPollingTypeDef s_config;

/* Initialize the read command */

s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;

s_command.Instruction = QUAD_INOUT_FAST_READ_CMD;

s_command.AddressMode = QSPI_ADDRESS_4_LINES;

s_command.AddressSize = QSPI_ADDRESS_32_BITS;

s_command.Address = address;

s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;

s_command.AlternateBytes = 0;

s_command.AlternateBytesSize = 0;

s_command.DataMode = QSPI_DATA_4_LINES; // QSPI_DATA_4_LINES

s_command.DummyCycles = 0;

s_command.NbData = size;

s_command.DdrMode = QSPI_DDR_MODE_DISABLE;

s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;

/* Configure the command */

printf("HAL_QSPI_Command\n");

if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)

!= HAL_OK) {

printf("HAL_ERROR\n");

return HAL_ERROR;

}

/* Reception of the data */

printf("HAL_QSPI_Receive\n");

if (HAL_QSPI_Receive(&hqspi, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE)

!= HAL_OK) {

printf("HAL_ERROR\n"); // Timeout after 5000mS

return HAL_ERROR;

}

return HAL_OK;

}

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 = 1;

hqspi.Init.FifoThreshold = 1;

hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;

hqspi.Init.FlashSize = 31;

hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE;

hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;

hqspi.Init.FlashID = QSPI_FLASH_ID_1;

hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;

if (HAL_QSPI_Init(&hqspi) != HAL_OK) {

Error_Handler();

}

/* USER CODE BEGIN QUADSPI_Init 2 */

/* USER CODE END QUADSPI_Init 2 */

}

while (1) {

if (VCP_retrieveInputData(buffer, 1) != 0) { // check to see if data arrived on USB

switch (buffer[0]) {

case 'A': // if 'A' command ( command to invoke sending of a 140KB of data to the host PC ) //

QspiWriteData(QSPI_FLASH_ADR, sizeof(qspidata), qspidata);

//BSP_QSPI_Write(qspidata, address, sizeof(qspidata));

CDC_Transmit_FS(qspiSent, sizeof(qspiSent));

HAL_Delay(1000);

break;

case 'B':

//BSP_QSPI_Read(data_packet_rx, address, sizeof(data_packet_rx));

QspiReadData(QSPI_FLASH_ADR, sizeof(data_packet_rx),

data_packet_rx);

CDC_Transmit_FS(data_packet_rx, sizeof(data_packet_rx));

break;

}

}

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

This topic has been closed for replies.

2 replies

Tesla DeLorean
Guru
September 13, 2020

Address sent to the QSPI device should be masked, it is not the ARM memory buffer address, but the offset into the QSPI device.

Should use/test with the BSP code.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Ehill.16
Ehill.16Author
Senior
September 15, 2020

clive1, is the offset the page number, 0 to 65535? What is the largest about of bytes you can write with BSP_QSPI_Write. It worked fine when I wrote a short string to the qspi flash memory. But when I tried to send something larger a couple of different pages, it wouldn't work. And now when I try to write a short string it doesn't write it. I don't know what happened. I erased the whole memory with the ST-Link thinking maybe this would help. It didn't.

Ehill.16
Ehill.16Author
Senior
September 14, 2020

Thanks Clive1. I got it work with the BSP code. I see that the BSP read and write functions use HAL anyways.

I have another question. I set up the QSPI flash memory to use DMA. So my question is, is the DMA used to read and write the QSPI flash memory?

Tesla DeLorean
Guru
September 14, 2020

In memory mapped mode you should be able to use DMA ​reads to move out large blocks of data.

I​ wouldn't bother with writing using DMA as the process is slow and you need to check and wait on the flash to complete internal processes. Memory also needs to be erased, which can take minutes or seconds depending on the scope of the operation.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Ehill.16
Ehill.16Author
Senior
September 14, 2020

Thanks again for the fast reply and this info.

The QSPI flash memory manufacturer claims transfers speeds of up 50 MB/s if the processor is running at 216MHz. I am sure this an exaggerated claim.