awyzlin
awyzlin

Reputation: 73

Communication problem with SPI NAND flash memory (STM32L4, QSPI)

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?

Upvotes: 2

Views: 2047

Answers (1)

Alexey Esaulenko
Alexey Esaulenko

Reputation: 549

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

Upvotes: 1

Related Questions