Skip to main content
Visitor II
August 5, 2024
Question

W25Q80DV QSPI with STM32F412VET3 - Strange things I don't understand.

  • August 5, 2024
  • 1 reply
  • 1491 views

Hi everyone.

So I have W25Q80DV QSPI with STM32F412VET, I would like to use it to store some data. As per datasheet for W25Q80DV its flash is 8mbit and so I have the following initialization code : 

hqspi.Instance = QUADSPI;

hqspi.Init.ClockPrescaler = 2;

hqspi.Init.FifoThreshold = 1;

hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;

hqspi.Init.FlashSize = 19;

hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;

hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;

hqspi.Init.FlashID = QSPI_FLASH_ID_2;

hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;

HAL_StatusTypeDef status = HAL_QSPI_Init(&hqspi);


According to the datasheet, FlashSize should be 19, since the flash size is 8mbit. But with flashsize being 19, the write operations (particlarly when I call HAL_Transmit) times out.
If I set the FlashSize to 31, it works as expected which I find odd.

Additionally my code for writing :


static
HAL_StatusTypeDef QSPI_PageProgram(uint32_t addr, uint8_t *txBuf) {
QSPI_CommandTypeDef s_command = {0};

s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;

s_command.Instruction = PAGE_PROGRAM_CMD;

s_command.AddressMode = QSPI_ADDRESS_1_LINE;

s_command.AddressSize = QSPI_ADDRESS_24_BITS; // 24-Bit-Adresse

s_command.Address = addr;

s_command.DataMode = QSPI_DATA_1_LINE;

s_command.DummyCycles = 0;

s_command.NbData = 4;

s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;




HAL_StatusTypeDef status = HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);

if (status != HAL_OK) {

return status;

}




status = HAL_QSPI_Transmit(&hqspi, txBuf, HAL_QSPI_TIMEOUT_DEFAULT_VALUE); //TIMEOUT here with flashsize = 19




return status;

}



One more question : Since I am new to embedded stuff I don't fully understand how the external flash memory actually works. If I would like to use the QSPI I assume I need to flash it somehow using CubeProgrammer, probably by using an external loader. Because when I debug using the IDE, it works as expected (despite difficulty to debug - I guess I need to enable memory mapping mode).

but it is not clear to me how to do this, there are some external loaders available in CubeProgrammer but not for my board

Thanks!

 

    This topic has been closed for replies.

    1 reply

    Graduate II
    August 5, 2024

    How are the pins configured on your board?

    The write page methods support writing up to 256 bytes, at a 256-byte aligned address. You can write anywhere in the page, but the total will drop as you move into the the page.

    The bit width of the address shouldn't be an issue with an 8mbit / 1MB NOR FLASH

    For write you'd need to use write-enable, and then wait for completion of the write. It shouldn't be taking over a few dozen milliseconds. The erase can run to seconds depending on the part and the erase size.

    LqAuthor
    Visitor II
    August 6, 2024

    Hi, thanks for the answer.

    Here's the pin configuration : 

    HAL_GPIO_WritePin(GPIOE, EN_M5_Pin|EN_M4_Pin, GPIO_PIN_RESET);


    HAL_GPIO_WritePin(GPIOC, Motor_All_Sleep_Pin|LED2_Pin|LED1_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(UART_TX_ENABLE_GPIO_Port, UART_TX_ENABLE_Pin, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, EN_M2_Pin|EN_M3_Pin|EN_M1_Pin, GPIO_PIN_RESET);


    HAL_GPIO_WritePin(EN_M0_GPIO_Port, EN_M0_Pin, GPIO_PIN_RESET);


    PEPin PEPin */

    GPIO_InitStruct.Pin = SW3_Pin|SW4_Pin|SW5_Pin|SW6_Pin

    |SW1_Pin|SW2_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = EN_M5_Pin|EN_M4_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);




    /*Configure GPIO pins : PCPin PCPin PCPin */

    GPIO_InitStruct.Pin = Motor_All_Sleep_Pin|LED2_Pin|LED1_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = GPIO_PIN_1;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = UART_TX_ENABLE_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(UART_TX_ENABLE_GPIO_Port, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = EN_M2_Pin|EN_M3_Pin|EN_M1_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = EN_M0_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(EN_M0_GPIO_Port, &GPIO_InitStruct);







    PDPin PDPin PDPin PDPin

    PDPin PDPin PDPin */

    GPIO_InitStruct.Pin = EndStop_M3_D09_Pin|EndStop_M3_D10_Pin|EndStop_M2_D11_Pin|EndStop_M2_D13_Pin

    |EndStop_M1_D14_Pin|EndStop_M4_D02_Pin|EndStop_M4_D03_Pin|EndStop_M5_D04_Pin

    |EndStop_M5_D05_Pin|EndStop_M6_D06_Pin|EndStop_M6_D07_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);







    GPIO_InitStruct.Pin = EndStop_M1_D15_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(EndStop_M1_D15_GPIO_Port, &GPIO_InitStruct);







    HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(EXTI2_IRQn);




    HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(EXTI3_IRQn);




    HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(EXTI4_IRQn);




    HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);




    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

    I do write-enable before page programming. I think the process of that shouldn't be an issue, since It works as expected if hqspi.Init.FlashSize = 31. Which is odd, I have no clue why it has to be 31, as per datasheet it actually should be 19. As soon as I use 19, then any HAL_QSPI_Transmit/ HAL_QSPI_Receive operation times out unless the AddressMode of the command is set to QSPI_ADDRESS_NONE.

    Thanks.

    Graduate II
    August 6, 2024

    Not sure I'm going to be able mine anything useful there.

    Perhaps you have the MSP code initializing the QSPI pins/clocks?