QuadSPI Flash отобразил память на stm32l4s9zi - PullRequest
0 голосов
/ 11 июня 2019

Я пытаюсь выяснить, как создать флэш-память, отображаемую через quadSPI. Я использую микроконтроллер STM32L4S9ZI с памятью Winbond W25Q32JVSSIQ QuadSPI.

MCU поддерживает OctoSPI, а не QuadSPI. Но в справочном руководстве написано, что OctoSPI для этого конкретного MCU можно использовать в режиме QuadSPI.

Я уже пытался использовать тот же MCU с флэш-памятью OctoSPI, и все работало правильно. Но с QuadSPI он вообще не работает. Проблема в том, что каждый раз, когда я посылаю команду, ничего не получается в качестве ответа. Я уже пытался использовать осциллограф, но сигналы выглядят странно (точно периодические импульсы на IO1, IO2, CLK и CS все время малы). Сейчас я просто пытаюсь прочитать идентификатор производителя чипа флэш-памяти, не более того. Я использовал тот же код с OctoSPI Flash, и он работает.

void HAL_OSPI_MspInit(OSPI_HandleTypeDef *hospi)
{
    if (hospi->Instance == OCTOSPI1)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
        OSPIM_CfgTypeDef OSPIM_Cfg_Struct;

        /*##-1- Enable peripherals and GPIO Clocks #################################*/
        /* Enable the OctoSPI memory interface clocks */
        __HAL_RCC_OSPI1_CLK_ENABLE();
        __HAL_RCC_OSPIM_CLK_ENABLE();
        /* Reset the OctoSPI memory interface */
        __HAL_RCC_OSPI1_FORCE_RESET();
        __HAL_RCC_OSPI1_RELEASE_RESET();
        /* Enable GPIO clocks */
        /* IOSV bit MUST be set to access GPIO port G[2:15] */
        __HAL_RCC_PWR_CLK_ENABLE();
        SET_BIT(PWR->CR2, PWR_CR2_IOSV);

        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();

        /*##-2- Configure peripheral GPIO ##########################################*/
        /* OSPI CS GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_2;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPIM_P1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* OSPI CLK GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_3;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* OSPI D0 GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

        /* OSPI D1 GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_0;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

        /* OSPI D2 GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_7;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /* OSPI D3 GPIO pin configuration  */
        GPIO_InitStruct.Pin       = GPIO_PIN_6;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        /*##-3- Configure the NVIC for OSPI #########################################*/
        /* NVIC configuration for OSPI interrupt */
        HAL_NVIC_SetPriority(OCTOSPI1_IRQn, 0x0F, 0);
        HAL_NVIC_EnableIRQ(OCTOSPI1_IRQn);

        /*##-4- Configure the OctoSPI IO Manager ####################################*/
        OSPIM_Cfg_Struct.ClkPort    = 1;
        OSPIM_Cfg_Struct.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
        OSPIM_Cfg_Struct.IOLowPort  = HAL_OSPIM_IOPORT_1_LOW;
        OSPIM_Cfg_Struct.NCSPort    = 1;

        if (HAL_OSPIM_Config(hospi, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
        {
            /* User may add here some code to deal with this error */
            while(1)
            {
            }
        }
    }
}
//  /* Initialize OctoSPI ----------------------------------------------------- */
    OSPIHandle.Instance = OCTOSPI1;
    HAL_OSPI_DeInit(&OSPIHandle);

    OSPIHandle.Init.FifoThreshold         = 1;
    OSPIHandle.Init.DualQuad              = HAL_OSPI_DUALQUAD_DISABLE;
    OSPIHandle.Init.MemoryType            = HAL_OSPI_MEMTYPE_MICRON;
    OSPIHandle.Init.DeviceSize            = OSPI_FLASH_SIZE;
    OSPIHandle.Init.ChipSelectHighTime    = 2;
    OSPIHandle.Init.FreeRunningClock      = HAL_OSPI_FREERUNCLK_DISABLE;
    OSPIHandle.Init.ClockMode             = HAL_OSPI_CLOCK_MODE_0;
    OSPIHandle.Init.WrapSize              = HAL_OSPI_WRAP_NOT_SUPPORTED;
    OSPIHandle.Init.ClockPrescaler        = 2; /* OctoSPI clock = 120MHz / ClockPrescaler = 60MHz */
    OSPIHandle.Init.SampleShifting        = HAL_OSPI_SAMPLE_SHIFTING_NONE;
    OSPIHandle.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
    OSPIHandle.Init.ChipSelectBoundary    = 0;

    if (HAL_OSPI_Init(&OSPIHandle) != HAL_OK)
    {
        printf("%s %d\r\n", __FILE__, __LINE__);
        error_handler();
    }
//
//  printf("%s %d\r\n", __FILE__, __LINE__);
//
//  /* Device ID ---- */
      sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
      sCommand.Instruction = 0x94;
      sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
      sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
      sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
      sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

      sCommand.Address = 0x000000;
      sCommand.AddressMode = HAL_OSPI_ADDRESS_4_LINES;
      sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
      sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;

      sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES;
      sCommand.AlternateBytes = 0xF;
      sCommand.AlternateBytesSize = 1;

      sCommand.DataMode = HAL_OSPI_DATA_4_LINES;
      sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
      sCommand.DummyCycles = 4;
      sCommand.NbData = 2;
      sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;


    uint8_t reg[2];
    printf("%s %d\r\n", __FILE__, __LINE__);
    if (HAL_OSPI_Command(&OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        printf("%s %d\r\n", __FILE__, __LINE__);
        error_handler();
    }
    printf("%s %d\r\n", __FILE__, __LINE__);

    if (HAL_OSPI_Receive(&OSPIHandle, reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
    {
        printf("%s %d error: %d 0x%08x 0x%08x\r\n", __FILE__, __LINE__, OSPIHandle.ErrorCode, reg[0], reg[1]);
        error_handler();
    }
    printf("%s %d\r\n", __FILE__, __LINE__);

Я действительно надеюсь, что смогу выяснить, как инициализируется память QuadSPI на устройстве OctoSPI.

Не могли бы вы помочь с периферийным устройством QuadSPI при инициализации OctoSPI? Есть что-то, что я пропускаю? Спасибо

...