cancel
Showing results for 
Search instead for 
Did you mean: 

Writing and reading QSPI Flash on STM32F746G DISCO

Ehill.16
Senior

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 */

}

8 REPLIES 8

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
Ehill.16
Senior

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?

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 Venmo
Up vote any posts that you find helpful, it shows what's working..

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.

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.

They are optimized for burst read operation, should be able to get close.

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

clive1, is the offset the page number, 0 to 65535? What is the largest amount of bytes that 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.

Disregard this, it is working now. I was using MX_QUADSPI_Init() to initialize the QSPI memory. when I changed to using BSP_QSPI_Init, it started working. I guess what happened was when I regenerated code from CubeMX, it changed the clockprescaler.