2
votes

I am trying to use an external flash memory (TC58CVG1S3HxAIx) with NUCLEO-L476RG board. I can’t get the QSPI to work. I used STM32CubeMx to configure QSPI:

void MX_QUADSPI_Init(void)
{

  hqspi.Instance = QUADSPI;
  hqspi.Init.ClockPrescaler = 255;
  hqspi.Init.FifoThreshold = 1;
  hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
  hqspi.Init.FlashSize = 30;
  hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
  hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
  if (HAL_QSPI_Init(&hqspi) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(qspiHandle->Instance==QUADSPI)
  {
  /* USER CODE BEGIN QUADSPI_MspInit 0 */

  /* USER CODE END QUADSPI_MspInit 0 */
    /* QUADSPI clock enable */
    __HAL_RCC_QSPI_CLK_ENABLE();


    /**QUADSPI GPIO Configuration    
    PA6     ------> QUADSPI_BK1_IO3
    PA7     ------> QUADSPI_BK1_IO2
    PB0     ------> QUADSPI_BK1_IO1
    PB1     ------> QUADSPI_BK1_IO0
    PB10     ------> QUADSPI_CLK
    PB11     ------> QUADSPI_NCS 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN QUADSPI_MspInit 1 */

  /* USER CODE END QUADSPI_MspInit 1 */
  }
}

And I wrote a simple program to get id from the flash memory:

#include "main.h"
#include "stm32l4xx_hal.h"
#include "quadspi.h"
#include "gpio.h"

uint8_t ReadAddr = 0x9F;
uint8_t pBuffer[3];

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_QUADSPI_Init();

  while (1)
  {
  HAL_QSPI_Transmit(&hqspi, &ReadAddr, 5);
  HAL_QSPI_Receive(&hqspi, pBuffer, 5);
  }
}

The qspi clock doesn’t work. I checked on the oscilloscope and all I see is a straight line. If I change the qspi clock mode to high the problem is still there, but I see the line on 3V not 0V. The CS signal works, on the oscilloscope I can clearly see the time when uC should transmit and receive.

I checked AHB3ENR register and it is properly initialized. I have no idea what else could be wrong.

Could somebody help me?

1
Have you tried debug mode? It is SUPER useful because you can view the values of all the registers in the device. You can also change the values of the registers in run time without having to re-upload code. Verify that the options in the QSPI registers seem normal according to the Reference Manual for your specific STM32 chipGeorge Troulis
Yes, I tried debug mode. All the QSPI register values seem fine to me but it’s my first time using QSPI so I might be missing something.awyzlin

1 Answers

1
votes

It looks like incorrect using of HAL driver.

QSPI is more sophisticated peripheral, than conventional SPI module.

Communication through QSPI consists several phases (instruction, address and data), as described in reference manual.

Length of these phases should be written in data length and communication configuration registers.

It should be done by calling HAL_QSPI_Command(), if you still using HAL drivers.

You can find examples in HAL external memory driver (for example, stm32h743i_eval_qspi.c, but i don't know, is there an analog for STM32L476's HAL).

Also read the very helpful document AN4760 Application note Quad-SPI (QSPI) interface on STM32 microcontrollers