Advertisement
bremenpl

qspi.c

Mar 15th, 2018
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 36.22 KB | None | 0 0
  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32l496g_discovery_qspi.c
  4.   * @author  MCD Application Team
  5.   * @version V1.0.0
  6.   * @date    17-February-2017
  7.   * @brief   This file includes a standard driver for the MX25R6435F QSPI
  8.   *          memory mounted on STM32L496G-Discovery board.
  9.   @verbatim
  10.   ==============================================================================
  11.                      ##### How to use this driver #####
  12.   ==============================================================================  
  13.   [..]
  14.    (#) This driver is used to drive the MX25R6435F QSPI external
  15.        memory mounted on STM32L496G-DISCO evaluation board.
  16.        
  17.    (#) This driver need a specific component driver (MX25R6435F) to be included with.
  18.  
  19.    (#) Initialization steps:
  20.        (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
  21.             function includes the MSP layer hardware resources initialization and the
  22.             QSPI interface with the external memory. The BSP_QSPI_DeInit() can be used
  23.             to deactivate the QSPI interface.
  24.  
  25.    (#) QSPI memory operations
  26.        (++) QSPI memory can be accessed with read/write operations once it is
  27.             initialized.
  28.             Read/write operation can be performed with AHB access using the functions
  29.             BSP_QSPI_Read()/BSP_QSPI_Write().
  30.        (++) The function to the QSPI memory in memory-mapped mode is possible after
  31.             the call of the function BSP_QSPI_EnableMemoryMappedMode().
  32.        (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
  33.             (see the QSPI memory data sheet)
  34.        (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
  35.             specifying the block address. You can perform an erase operation of the whole
  36.             chip by calling the function BSP_QSPI_Erase_Chip().
  37.        (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
  38.             (see the QSPI memory data sheet)
  39.        (++) Perform erase sector operation using the function BSP_QSPI_Erase_Sector()
  40.             which is not blocking. So the function BSP_QSPI_GetStatus() should be used
  41.             to check if the memory is busy, and the functions BSP_QSPI_SuspendErase()/
  42.             BSP_QSPI_ResumeErase() can be used to perform other operations during the
  43.             sector erase.
  44.        (++) Deep power down of the QSPI memory is managed with the call of the functions
  45.             BSP_QSPI_EnterDeepPowerDown()/BSP_QSPI_LeaveDeepPowerDown()
  46.   @endverbatim
  47.   ******************************************************************************
  48.   * @attention
  49.   *
  50.   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  51.   *
  52.   * Redistribution and use in source and binary forms, with or without modification,
  53.   * are permitted provided that the following conditions are met:
  54.   *   1. Redistributions of source code must retain the above copyright notice,
  55.   *      this list of conditions and the following disclaimer.
  56.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  57.   *      this list of conditions and the following disclaimer in the documentation
  58.   *      and/or other materials provided with the distribution.
  59.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  60.   *      may be used to endorse or promote products derived from this software
  61.   *      without specific prior written permission.
  62.   *
  63.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  64.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  65.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  67.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  68.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  69.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  70.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  71.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  72.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73.   *
  74.   ******************************************************************************
  75.   */
  76.  
  77. /* Includes ------------------------------------------------------------------*/
  78. #include "stm32l496g_discovery_qspi.h"
  79.  
  80. /** @addtogroup BSP
  81.   * @{
  82.   */
  83.  
  84. /** @addtogroup STM32L496G_DISCOVERY
  85.   * @{
  86.   */
  87.  
  88. /** @defgroup STM32L496G_DISCOVERY_QSPI STM32L496G-DISCOVERY QSPI
  89.   * @{
  90.   */
  91.  
  92. /* Private constants --------------------------------------------------------*/
  93. /** @defgroup STM32L496G_DISCOVERY_QSPI_Private_Constants Private Constants
  94.   * @{
  95.   */
  96. #define QSPI_QUAD_DISABLE       0x0
  97. #define QSPI_QUAD_ENABLE        0x1
  98.  
  99. #define QSPI_HIGH_PERF_DISABLE  0x0
  100. #define QSPI_HIGH_PERF_ENABLE   0x1
  101. /**
  102.   * @}
  103.   */
  104. /* Private variables ---------------------------------------------------------*/
  105.  
  106. /** @defgroup STM32L496G_DISCOVERY_QSPI_Private_Variables Private Variables
  107.   * @{
  108.   */
  109. QSPI_HandleTypeDef QSPIHandle;
  110.  
  111. /**
  112.   * @}
  113.   */
  114.  
  115.  
  116. /* Private functions ---------------------------------------------------------*/
  117.  
  118. /** @defgroup STM32L496G_DISCOVERY_QSPI_Private_Functions Private Functions
  119.   * @{
  120.   */
  121. static void    QSPI_MspInit            (void);
  122. static void    QSPI_MspDeInit          (void);
  123. static uint8_t QSPI_ResetMemory        (QSPI_HandleTypeDef *hqspi);
  124. static uint8_t QSPI_WriteEnable        (QSPI_HandleTypeDef *hqspi);
  125. static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
  126. static uint8_t QSPI_QuadMode           (QSPI_HandleTypeDef *hqspi, uint8_t Operation);
  127. static uint8_t QSPI_HighPerfMode       (QSPI_HandleTypeDef *hqspi, uint8_t Operation);
  128.  
  129. /**
  130.   * @}
  131.   */
  132.  
  133. /* Exported functions ---------------------------------------------------------*/
  134.  
  135. /** @addtogroup STM32L496G_DISCOVERY_QSPI_Exported_Functions
  136.   * @{
  137.   */
  138.  
  139. /**
  140.   * @brief  Initializes the QSPI interface.
  141.   * @retval QSPI memory status
  142.   */
  143. uint8_t BSP_QSPI_Init(void)
  144. {
  145.   QSPIHandle.Instance = QUADSPI;
  146.  
  147.   /* Call the DeInit function to reset the driver */
  148.   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
  149.   {
  150.     return QSPI_ERROR;
  151.   }
  152.        
  153.   /* System level initialization */
  154.   QSPI_MspInit();
  155.  
  156.   /* QSPI initialization */
  157.   QSPIHandle.Init.ClockPrescaler     = 2; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 26.67MHz */
  158.   QSPIHandle.Init.FifoThreshold      = 4;
  159.   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_NONE;
  160.   QSPIHandle.Init.FlashSize          = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1;
  161.   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
  162.   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
  163.  
  164.   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  165.   {
  166.     return QSPI_ERROR;
  167.   }
  168.  
  169.   /* QSPI memory reset */
  170.   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
  171.   {
  172.     return QSPI_NOT_SUPPORTED;
  173.   }
  174.  
  175.   /* QSPI quad enable */
  176.   if (QSPI_QuadMode(&QSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK)
  177.   {
  178.     return QSPI_ERROR;
  179.   }
  180.  
  181.   /* High performance mode enable */
  182.   if (QSPI_HighPerfMode(&QSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK)
  183.   {
  184.     return QSPI_ERROR;
  185.   }
  186.  
  187.   /* Re-configure the clock for the high performance mode */
  188.   QSPIHandle.Init.ClockPrescaler = 1; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 40MHz */
  189.  
  190.   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
  191.   {
  192.     return QSPI_ERROR;
  193.   }
  194.  
  195.   return QSPI_OK;
  196. }
  197.  
  198. /**
  199.   * @brief  De-Initializes the QSPI interface.
  200.   * @retval QSPI memory status
  201.   */
  202. uint8_t BSP_QSPI_DeInit(void)
  203. {
  204.   QSPIHandle.Instance = QUADSPI;
  205.  
  206.   /* Call the DeInit function to reset the driver */
  207.   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
  208.   {
  209.     return QSPI_ERROR;
  210.   }
  211.  
  212.   /* System level De-initialization */
  213.   QSPI_MspDeInit();
  214.  
  215.     return QSPI_OK;
  216. }
  217.  
  218. /**
  219.   * @brief  Reads an amount of data from the QSPI memory.
  220.   * @param  pData    : Pointer to data to be read
  221.   * @param  ReadAddr : Read start address
  222.   * @param  Size     : Size of data to read    
  223.   * @retval QSPI memory status
  224.   */
  225. uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
  226. {
  227.   QSPI_CommandTypeDef sCommand;
  228.  
  229.   /* Initialize the read command */
  230.   sCommand.InstructionMode    = QSPI_INSTRUCTION_1_LINE;
  231.   sCommand.Instruction        = QUAD_INOUT_READ_CMD;
  232.   sCommand.AddressMode        = QSPI_ADDRESS_4_LINES;
  233.   sCommand.AddressSize        = QSPI_ADDRESS_24_BITS;
  234.   sCommand.Address            = ReadAddr;
  235.   sCommand.AlternateByteMode  = QSPI_ALTERNATE_BYTES_4_LINES;
  236.   sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
  237.   sCommand.AlternateBytes     = MX25R6435F_ALT_BYTES_NO_PE_MODE;
  238.   sCommand.DataMode           = QSPI_DATA_4_LINES;
  239.   sCommand.DummyCycles        = MX25R6435F_DUMMY_CYCLES_READ_QUAD;
  240.   sCommand.NbData             = Size;
  241.   sCommand.DdrMode            = QSPI_DDR_MODE_DISABLE;
  242.   sCommand.DdrHoldHalfCycle   = QSPI_DDR_HHC_ANALOG_DELAY;
  243.   sCommand.SIOOMode           = QSPI_SIOO_INST_EVERY_CMD;
  244.  
  245.   /* Configure the command */
  246.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  247.   {
  248.     return QSPI_ERROR;
  249.   }
  250.  
  251.   /* Reception of the data */
  252.   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  253.   {
  254.     return QSPI_ERROR;
  255.   }
  256.  
  257.   return QSPI_OK;
  258. }
  259.  
  260. /**
  261.   * @brief  Writes an amount of data to the QSPI memory.
  262.   * @param  pData     : Pointer to data to be written
  263.   * @param  WriteAddr : Write start address
  264.   * @param  Size      : Size of data to write    
  265.   * @retval QSPI memory status
  266.   */
  267. uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
  268. {
  269.   QSPI_CommandTypeDef sCommand;
  270.   uint32_t end_addr, current_size, current_addr;
  271.  
  272.   /* Calculation of the size between the write address and the end of the page */
  273.   current_size = MX25R6435F_PAGE_SIZE - (WriteAddr % MX25R6435F_PAGE_SIZE);
  274.  
  275.   /* Check if the size of the data is less than the remaining place in the page */
  276.   if (current_size > Size)
  277.   {
  278.     current_size = Size;
  279.   }
  280.  
  281.   /* Initialize the adress variables */
  282.   current_addr = WriteAddr;
  283.   end_addr = WriteAddr + Size;
  284.  
  285.   /* Initialize the program command */
  286.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  287.   sCommand.Instruction       = QUAD_PAGE_PROG_CMD;
  288.   sCommand.AddressMode       = QSPI_ADDRESS_4_LINES;
  289.   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  290.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  291.   sCommand.DataMode          = QSPI_DATA_4_LINES;
  292.   sCommand.DummyCycles       = 0;
  293.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  294.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  295.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  296.  
  297.   /* Perform the write page by page */
  298.   do
  299.   {
  300.     sCommand.Address = current_addr;
  301.     sCommand.NbData  = current_size;
  302.  
  303.     /* Enable write operations */
  304.     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  305.     {
  306.       return QSPI_ERROR;
  307.     }
  308.    
  309.     /* Configure the command */
  310.     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  311.     {
  312.       return QSPI_ERROR;
  313.     }
  314.    
  315.     /* Transmission of the data */
  316.     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  317.     {
  318.       return QSPI_ERROR;
  319.     }
  320.    
  321.     /* Configure automatic polling mode to wait for end of program */  
  322.     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
  323.     {
  324.       return QSPI_ERROR;
  325.     }
  326.    
  327.     /* Update the address and size variables for next page programming */
  328.     current_addr += current_size;
  329.     pData += current_size;
  330.     current_size = ((current_addr + MX25R6435F_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25R6435F_PAGE_SIZE;
  331.   } while (current_addr < end_addr);
  332.  
  333.   return QSPI_OK;
  334. }
  335.  
  336. /**
  337.   * @brief  Erases the specified block of the QSPI memory.
  338.   * @param  BlockAddress : Block address to erase  
  339.   * @retval QSPI memory status
  340.   */
  341. uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
  342. {
  343.   QSPI_CommandTypeDef sCommand;
  344.  
  345.   /* Initialize the erase command */
  346.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  347.   sCommand.Instruction       = BLOCK_ERASE_CMD;
  348.   sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
  349.   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  350.   sCommand.Address           = BlockAddress;
  351.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  352.   sCommand.DataMode          = QSPI_DATA_NONE;
  353.   sCommand.DummyCycles       = 0;
  354.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  355.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  356.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  357.  
  358.   /* Enable write operations */
  359.   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  360.   {
  361.     return QSPI_ERROR;
  362.   }
  363.  
  364.   /* Send the command */
  365.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  366.   {
  367.     return QSPI_ERROR;
  368.   }
  369.  
  370.   /* Configure automatic polling mode to wait for end of erase */  
  371.   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK)
  372.   {
  373.     return QSPI_ERROR;
  374.   }
  375.  
  376.   return QSPI_OK;
  377. }
  378.  
  379. /**
  380.   * @brief  Erases the specified sector of the QSPI memory.
  381.   * @param  Sector : Sector address to erase (0 to 255)
  382.   * @retval QSPI memory status
  383.   * @note This function is non blocking meaning that sector erase
  384.   *       operation is started but not completed when the function
  385.   *       returns. Application has to call BSP_QSPI_GetStatus()
  386.   *       to know when the device is available again (i.e. erase operation
  387.   *       completed).
  388.   */
  389. uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector)
  390. {
  391.   QSPI_CommandTypeDef sCommand;
  392.  
  393.   if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE))
  394.   {
  395.     return QSPI_ERROR;
  396.   }
  397.  
  398.   /* Initialize the erase command */
  399.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  400.   sCommand.Instruction       = SECTOR_ERASE_CMD;
  401.   sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
  402.   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
  403.   sCommand.Address           = (Sector * MX25R6435F_SECTOR_SIZE);
  404.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  405.   sCommand.DataMode          = QSPI_DATA_NONE;
  406.   sCommand.DummyCycles       = 0;
  407.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  408.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  409.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  410.  
  411.   /* Enable write operations */
  412.   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  413.   {
  414.     return QSPI_ERROR;
  415.   }
  416.  
  417.   /* Send the command */
  418.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  419.   {
  420.     return QSPI_ERROR;
  421.   }
  422.  
  423.   return QSPI_OK;
  424. }
  425.  
  426. /**
  427.   * @brief  Erases the entire QSPI memory.
  428.   * @retval QSPI memory status
  429.   */
  430. uint8_t BSP_QSPI_Erase_Chip(void)
  431. {
  432.   QSPI_CommandTypeDef sCommand;
  433.  
  434.   /* Initialize the erase command */
  435.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  436.   sCommand.Instruction       = CHIP_ERASE_CMD;
  437.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  438.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  439.   sCommand.DataMode          = QSPI_DATA_NONE;
  440.   sCommand.DummyCycles       = 0;
  441.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  442.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  443.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  444.  
  445.   /* Enable write operations */
  446.   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  447.   {
  448.     return QSPI_ERROR;
  449.   }
  450.  
  451.   /* Send the command */
  452.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  453.   {
  454.     return QSPI_ERROR;
  455.   }
  456.  
  457.   /* Configure automatic polling mode to wait for end of erase */  
  458.   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK)
  459.   {
  460.     return QSPI_ERROR;
  461.   }
  462.  
  463.   return QSPI_OK;
  464. }
  465.  
  466. /**
  467.   * @brief  Reads current status of the QSPI memory.
  468.   * @retval QSPI memory status
  469.   */
  470. uint8_t BSP_QSPI_GetStatus(void)
  471. {
  472.   QSPI_CommandTypeDef sCommand;
  473.   uint8_t reg;
  474.  
  475.   /* Initialize the read security register command */
  476.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  477.   sCommand.Instruction       = READ_SEC_REG_CMD;
  478.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  479.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  480.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  481.   sCommand.DummyCycles       = 0;
  482.   sCommand.NbData            = 1;
  483.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  484.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  485.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  486.  
  487.   /* Configure the command */
  488.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  489.   {
  490.     return QSPI_ERROR;
  491.   }
  492.  
  493.   /* Reception of the data */
  494.   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  495.   {
  496.     return QSPI_ERROR;
  497.   }
  498.  
  499.   /* Check the value of the register */
  500.   if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0)
  501.   {
  502.     return QSPI_ERROR;
  503.   }
  504.   else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0)
  505.   {
  506.     return QSPI_SUSPENDED;
  507.   }
  508.  
  509.   /* Initialize the read status register command */
  510.   sCommand.Instruction       = READ_STATUS_REG_CMD;
  511.  
  512.   /* Configure the command */
  513.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  514.   {
  515.     return QSPI_ERROR;
  516.   }
  517.  
  518.   /* Reception of the data */
  519.   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  520.   {
  521.     return QSPI_ERROR;
  522.   }
  523.  
  524.   /* Check the value of the register */
  525.   if ((reg & MX25R6435F_SR_WIP) != 0)
  526.   {
  527.     return QSPI_BUSY;
  528.   }
  529.   else
  530.   {
  531.     return QSPI_OK;
  532.   }
  533. }
  534.  
  535. /**
  536.   * @brief  Return the configuration of the QSPI memory.
  537.   * @param  pInfo : pointer on the configuration structure  
  538.   * @retval QSPI memory status
  539.   */
  540. uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
  541. {
  542.   /* Configure the structure with the memory configuration */
  543.   pInfo->FlashSize          = MX25R6435F_FLASH_SIZE;
  544.   pInfo->EraseSectorSize    = MX25R6435F_SECTOR_SIZE;
  545.   pInfo->EraseSectorsNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE);
  546.   pInfo->ProgPageSize       = MX25R6435F_PAGE_SIZE;
  547.   pInfo->ProgPagesNumber    = (MX25R6435F_FLASH_SIZE/MX25R6435F_PAGE_SIZE);
  548.  
  549.   return QSPI_OK;
  550. }
  551.  
  552. /**
  553.   * @brief  Configure the QSPI in memory-mapped mode
  554.   * @retval QSPI memory status
  555.   */
  556. uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
  557. {
  558.   QSPI_CommandTypeDef      sCommand;
  559.   QSPI_MemoryMappedTypeDef sMemMappedCfg;
  560.  
  561.   /* Configure the command for the read instruction */
  562.   sCommand.InstructionMode    = QSPI_INSTRUCTION_1_LINE;
  563.   sCommand.Instruction        = QUAD_INOUT_READ_CMD;
  564.   sCommand.AddressMode        = QSPI_ADDRESS_4_LINES;
  565.   sCommand.AddressSize        = QSPI_ADDRESS_24_BITS;
  566.   sCommand.AlternateByteMode  = QSPI_ALTERNATE_BYTES_4_LINES;
  567.   sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
  568.   sCommand.AlternateBytes     = MX25R6435F_ALT_BYTES_NO_PE_MODE;
  569.   sCommand.DataMode           = QSPI_DATA_4_LINES;
  570.   sCommand.DummyCycles        = MX25R6435F_DUMMY_CYCLES_READ_QUAD;
  571.   sCommand.DdrMode            = QSPI_DDR_MODE_DISABLE;
  572.   sCommand.DdrHoldHalfCycle   = QSPI_DDR_HHC_ANALOG_DELAY;
  573.   sCommand.SIOOMode           = QSPI_SIOO_INST_EVERY_CMD;
  574.  
  575.   /* Configure the memory mapped mode */
  576.   sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
  577.  
  578.   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
  579.   {
  580.     return QSPI_ERROR;
  581.   }
  582.  
  583.   return QSPI_OK;
  584. }
  585.  
  586. /**
  587.   * @brief  This function suspends an ongoing erase command.
  588.   * @retval QSPI memory status
  589.   */
  590. uint8_t BSP_QSPI_SuspendErase(void)
  591. {
  592.   QSPI_CommandTypeDef sCommand;
  593.  
  594.   /* Check whether the device is busy (erase operation is
  595.   in progress).
  596.   */
  597.   if (BSP_QSPI_GetStatus() == QSPI_BUSY)
  598.   {
  599.     /* Initialize the erase command */
  600.     sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  601.     sCommand.Instruction       = PROG_ERASE_SUSPEND_CMD;
  602.     sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  603.     sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  604.     sCommand.DataMode          = QSPI_DATA_NONE;
  605.     sCommand.DummyCycles       = 0;
  606.     sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  607.     sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  608.     sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  609.    
  610.     /* Send the command */
  611.     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  612.     {
  613.       return QSPI_ERROR;
  614.     }
  615.    
  616.     if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
  617.     {
  618.       return QSPI_OK;
  619.     }
  620.    
  621.     return QSPI_ERROR;
  622.   }
  623.  
  624.   return QSPI_OK;
  625. }
  626.  
  627. /**
  628.   * @brief  This function resumes a paused erase command.
  629.   * @retval QSPI memory status
  630.   */
  631. uint8_t BSP_QSPI_ResumeErase(void)
  632. {
  633.   QSPI_CommandTypeDef sCommand;
  634.  
  635.   /* Check whether the device is in suspended state */
  636.   if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
  637.   {
  638.     /* Initialize the erase command */
  639.     sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  640.     sCommand.Instruction       = PROG_ERASE_RESUME_CMD;
  641.     sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  642.     sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  643.     sCommand.DataMode          = QSPI_DATA_NONE;
  644.     sCommand.DummyCycles       = 0;
  645.     sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  646.     sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  647.     sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  648.    
  649.     /* Send the command */
  650.     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  651.     {
  652.       return QSPI_ERROR;
  653.     }
  654.    
  655.     /*
  656.     When this command is executed, the status register write in progress bit is set to 1, and
  657.     the flag status register program erase controller bit is set to 0. This command is ignored
  658.     if the device is not in a suspended state.
  659.     */
  660.    
  661.     if (BSP_QSPI_GetStatus() == QSPI_BUSY)
  662.     {
  663.       return QSPI_OK;
  664.     }
  665.    
  666.     return QSPI_ERROR;
  667.   }
  668.  
  669.   return QSPI_OK;
  670. }
  671.  
  672. /**
  673.   * @brief  This function enter the QSPI memory in deep power down mode.
  674.   * @retval QSPI memory status
  675.   */
  676. uint8_t BSP_QSPI_EnterDeepPowerDown(void)
  677. {
  678.   QSPI_CommandTypeDef sCommand;
  679.  
  680.   /* Initialize the deep power down command */
  681.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  682.   sCommand.Instruction       = DEEP_POWER_DOWN_CMD;
  683.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  684.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  685.   sCommand.DataMode          = QSPI_DATA_NONE;
  686.   sCommand.DummyCycles       = 0;
  687.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  688.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  689.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  690.    
  691.   /* Send the command */
  692.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  693.   {
  694.     return QSPI_ERROR;
  695.   }
  696.  
  697.   /* ---          Memory takes 10us max to enter deep power down          --- */
  698.   /* --- At least 30us should be respected before leaving deep power down --- */
  699.  
  700.   return QSPI_OK;
  701. }
  702.  
  703. /**
  704.   * @brief  This function leave the QSPI memory from deep power down mode.
  705.   * @retval QSPI memory status
  706.   */
  707. uint8_t BSP_QSPI_LeaveDeepPowerDown(void)
  708. {
  709.   QSPI_CommandTypeDef sCommand;
  710.  
  711.   /* Initialize the erase command */
  712.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  713.   sCommand.Instruction       = NO_OPERATION_CMD;
  714.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  715.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  716.   sCommand.DataMode          = QSPI_DATA_NONE;
  717.   sCommand.DummyCycles       = 0;
  718.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  719.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  720.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  721.    
  722.   /* Send the command */
  723.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  724.   {
  725.     return QSPI_ERROR;
  726.   }
  727.  
  728.   /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */
  729.   /* ---                  Memory takes 35us min to leave deep power down                  --- */
  730.  
  731.   return QSPI_OK;
  732. }
  733. /**
  734.   * @}
  735.   */
  736.  
  737. /** @addtogroup STM32L496G_DISCOVERY_QSPI_Private_Functions
  738.   * @{
  739.   */
  740.  
  741. /**
  742.   * @brief  Initializes the QSPI MSP.
  743.   * @retval None
  744.   */
  745. static void QSPI_MspInit(void)
  746. {
  747.   GPIO_InitTypeDef GPIO_InitStruct;
  748.  
  749.   /* Enable the QuadSPI memory interface clock */
  750.   __HAL_RCC_QSPI_CLK_ENABLE();
  751.  
  752.   /* Reset the QuadSPI memory interface */
  753.   __HAL_RCC_QSPI_FORCE_RESET();
  754.   __HAL_RCC_QSPI_RELEASE_RESET();
  755.  
  756.   /* Enable GPIO clocks */
  757.   __HAL_RCC_GPIOA_CLK_ENABLE();
  758.   __HAL_RCC_GPIOB_CLK_ENABLE();
  759.  
  760.   /* QSPI CS GPIO pin configuration  */
  761.   GPIO_InitStruct.Pin       = GPIO_PIN_11;
  762.   GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  763.   GPIO_InitStruct.Pull      = GPIO_PULLUP;
  764.   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  765.   GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
  766.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  767.  
  768.   /* QSPI CLK, D0, D1, D2 and D3 GPIO pins configuration  */
  769.   GPIO_InitStruct.Pin       = (GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7);
  770.   GPIO_InitStruct.Pull      = GPIO_NOPULL;
  771.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  772.  
  773.   GPIO_InitStruct.Pin       = (GPIO_PIN_0 | GPIO_PIN_1);
  774.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  775. }
  776.  
  777. /**
  778.   * @brief  De-Initializes the QSPI MSP.
  779.   * @retval None
  780.   */
  781. static void QSPI_MspDeInit(void)
  782. {
  783.   GPIO_InitTypeDef GPIO_InitStruct;
  784.  
  785.   /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration  */
  786.  
  787.   __HAL_RCC_GPIOA_CLK_ENABLE();
  788.   __HAL_RCC_GPIOB_CLK_ENABLE();
  789.  
  790.   HAL_GPIO_DeInit(GPIOA, (GPIO_PIN_6 | GPIO_PIN_7));
  791.   HAL_GPIO_DeInit(GPIOB, (GPIO_PIN_0 | GPIO_PIN_1));
  792.  
  793.   /* Set GPIOB pin 11 in pull up mode (optimum default setting) */
  794.   GPIO_InitStruct.Mode      = GPIO_MODE_INPUT;
  795.   GPIO_InitStruct.Pin       = GPIO_PIN_11;
  796.   GPIO_InitStruct.Pull      = GPIO_NOPULL;
  797.   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_LOW;
  798.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  799.  
  800.   /* Set GPIOA pin 3 in no pull, low state (optimum default setting) */
  801.   GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP  ;
  802.   GPIO_InitStruct.Pull      = GPIO_NOPULL;
  803.   GPIO_InitStruct.Pin       = GPIO_PIN_3;
  804.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  805.   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
  806.    
  807.   /* Reset the QuadSPI memory interface */
  808.   __HAL_RCC_QSPI_FORCE_RESET();
  809.   __HAL_RCC_QSPI_RELEASE_RESET();
  810.  
  811.   /* Disable the QuadSPI memory interface clock */
  812.   __HAL_RCC_QSPI_CLK_DISABLE();
  813. }
  814.  
  815. /**
  816.   * @brief  This function reset the QSPI memory.
  817.   * @param  hqspi : QSPI handle
  818.   * @retval None
  819.   */
  820. static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
  821. {
  822.   QSPI_CommandTypeDef sCommand;
  823.  
  824.   /* Initialize the reset enable command */
  825.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  826.   sCommand.Instruction       = RESET_ENABLE_CMD;
  827.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  828.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  829.   sCommand.DataMode          = QSPI_DATA_NONE;
  830.   sCommand.DummyCycles       = 0;
  831.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  832.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  833.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  834.  
  835.   /* Send the command */
  836.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  837.   {
  838.     return QSPI_ERROR;
  839.   }
  840.  
  841.   /* Send the reset memory command */
  842.   sCommand.Instruction = RESET_MEMORY_CMD;
  843.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  844.   {
  845.     return QSPI_ERROR;
  846.   }
  847.  
  848.   /* Configure automatic polling mode to wait the memory is ready */  
  849.   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
  850.   {
  851.     return QSPI_ERROR;
  852.   }
  853.  
  854.   return QSPI_OK;
  855. }
  856.  
  857. /**
  858.   * @brief  This function send a Write Enable and wait it is effective.
  859.   * @param  hqspi : QSPI handle
  860.   * @retval None
  861.   */
  862. static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
  863. {
  864.   QSPI_CommandTypeDef     sCommand;
  865.   QSPI_AutoPollingTypeDef sConfig;
  866.  
  867.   /* Enable write operations */
  868.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  869.   sCommand.Instruction       = WRITE_ENABLE_CMD;
  870.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  871.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  872.   sCommand.DataMode          = QSPI_DATA_NONE;
  873.   sCommand.DummyCycles       = 0;
  874.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  875.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  876.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  877.  
  878.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  879.   {
  880.     return QSPI_ERROR;
  881.   }
  882.  
  883.   /* Configure automatic polling mode to wait for write enabling */  
  884.   sConfig.Match           = MX25R6435F_SR_WEL;
  885.   sConfig.Mask            = MX25R6435F_SR_WEL;
  886.   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
  887.   sConfig.StatusBytesSize = 1;
  888.   sConfig.Interval        = 0x10;
  889.   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
  890.  
  891.   sCommand.Instruction    = READ_STATUS_REG_CMD;
  892.   sCommand.DataMode       = QSPI_DATA_1_LINE;
  893.  
  894.   if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  895.   {
  896.     return QSPI_ERROR;
  897.   }
  898.  
  899.   return QSPI_OK;
  900. }
  901.  
  902. /**
  903.   * @brief  This function read the SR of the memory and wait the EOP.
  904.   * @param  hqspi   : QSPI handle
  905.   * @param  Timeout : Timeout for auto-polling
  906.   * @retval None
  907.   */
  908. static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
  909. {
  910.   QSPI_CommandTypeDef     sCommand;
  911.   QSPI_AutoPollingTypeDef sConfig;
  912.  
  913.   /* Configure automatic polling mode to wait for memory ready */  
  914.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  915.   sCommand.Instruction       = READ_STATUS_REG_CMD;
  916.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  917.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  918.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  919.   sCommand.DummyCycles       = 0;
  920.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  921.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  922.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  923.  
  924.   sConfig.Match           = 0;
  925.   sConfig.Mask            = MX25R6435F_SR_WIP;
  926.   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
  927.   sConfig.StatusBytesSize = 1;
  928.   sConfig.Interval        = 0x10;
  929.   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
  930.  
  931.   if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK)
  932.   {
  933.     return QSPI_ERROR;
  934.   }
  935.  
  936.   return QSPI_OK;
  937. }
  938.  
  939. /**
  940.   * @brief  This function enables/disables the Quad mode of the memory.
  941.   * @param  hqspi     : QSPI handle
  942.   * @param  Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode  
  943.   * @retval None
  944.   */
  945. static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation)
  946. {
  947.   QSPI_CommandTypeDef sCommand;
  948.   uint8_t reg;
  949.  
  950.   /* Read status register */
  951.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  952.   sCommand.Instruction       = READ_STATUS_REG_CMD;
  953.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  954.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  955.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  956.   sCommand.DummyCycles       = 0;
  957.   sCommand.NbData            = 1;
  958.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  959.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  960.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  961.  
  962.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  963.   {
  964.     return QSPI_ERROR;
  965.   }
  966.  
  967.   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  968.   {
  969.     return QSPI_ERROR;
  970.   }
  971.  
  972.   /* Enable write operations */
  973.   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  974.   {
  975.     return QSPI_ERROR;
  976.   }
  977.  
  978.   /* Activate/deactivate the Quad mode */
  979.   if (Operation == QSPI_QUAD_ENABLE)
  980.   {
  981.     SET_BIT(reg, MX25R6435F_SR_QE);
  982.   }
  983.   else
  984.   {
  985.     CLEAR_BIT(reg, MX25R6435F_SR_QE);
  986.   }
  987.  
  988.   sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD;
  989.  
  990.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  991.   {
  992.     return QSPI_ERROR;
  993.   }
  994.  
  995.   if (HAL_QSPI_Transmit(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  996.   {
  997.     return QSPI_ERROR;
  998.   }
  999.  
  1000.   /* Wait that memory is ready */  
  1001.   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
  1002.   {
  1003.     return QSPI_ERROR;
  1004.   }
  1005.  
  1006.   /* Check the configuration has been correctly done */
  1007.   sCommand.Instruction = READ_STATUS_REG_CMD;
  1008.  
  1009.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1010.   {
  1011.     return QSPI_ERROR;
  1012.   }
  1013.  
  1014.   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1015.   {
  1016.     return QSPI_ERROR;
  1017.   }
  1018.  
  1019.   if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) ||
  1020.       (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE)))
  1021.   {
  1022.     return QSPI_ERROR;
  1023.   }
  1024.  
  1025.   return QSPI_OK;
  1026. }
  1027.  
  1028. /**
  1029.   * @brief  This function enables/disables the high performance mode of the memory.
  1030.   * @param  hqspi     : QSPI handle
  1031.   * @param  Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode    
  1032.   * @retval None
  1033.   */
  1034. static uint8_t QSPI_HighPerfMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation)
  1035. {
  1036.   QSPI_CommandTypeDef sCommand;
  1037.   uint8_t reg[3];
  1038.  
  1039.   /* Read status register */
  1040.   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
  1041.   sCommand.Instruction       = READ_STATUS_REG_CMD;
  1042.   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
  1043.   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
  1044.   sCommand.DataMode          = QSPI_DATA_1_LINE;
  1045.   sCommand.DummyCycles       = 0;
  1046.   sCommand.NbData            = 1;
  1047.   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
  1048.   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
  1049.   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
  1050.  
  1051.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1052.   {
  1053.     return QSPI_ERROR;
  1054.   }
  1055.  
  1056.   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1057.   {
  1058.     return QSPI_ERROR;
  1059.   }
  1060.  
  1061.   /* Read configuration registers */
  1062.   sCommand.Instruction = READ_CFG_REG_CMD;
  1063.   sCommand.NbData      = 2;
  1064.  
  1065.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1066.   {
  1067.     return QSPI_ERROR;
  1068.   }
  1069.  
  1070.   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1071.   {
  1072.     return QSPI_ERROR;
  1073.   }
  1074.  
  1075.   /* Enable write operations */
  1076.   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
  1077.   {
  1078.     return QSPI_ERROR;
  1079.   }
  1080.  
  1081.   /* Activate/deactivate the Quad mode */
  1082.   if (Operation == QSPI_HIGH_PERF_ENABLE)
  1083.   {
  1084.     SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH);
  1085.   }
  1086.   else
  1087.   {
  1088.     CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH);
  1089.   }
  1090.  
  1091.   sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD;
  1092.   sCommand.NbData      = 3;
  1093.  
  1094.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1095.   {
  1096.     return QSPI_ERROR;
  1097.   }
  1098.  
  1099.   if (HAL_QSPI_Transmit(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1100.   {
  1101.     return QSPI_ERROR;
  1102.   }
  1103.  
  1104.   /* Wait that memory is ready */  
  1105.   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
  1106.   {
  1107.     return QSPI_ERROR;
  1108.   }
  1109.  
  1110.   /* Check the configuration has been correctly done */
  1111.   sCommand.Instruction = READ_CFG_REG_CMD;
  1112.   sCommand.NbData      = 2;
  1113.  
  1114.   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1115.   {
  1116.     return QSPI_ERROR;
  1117.   }
  1118.  
  1119.   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  1120.   {
  1121.     return QSPI_ERROR;
  1122.   }
  1123.  
  1124.   if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) ||
  1125.       (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE)))
  1126.   {
  1127.     return QSPI_ERROR;
  1128.   }
  1129.  
  1130.   return QSPI_OK;
  1131. }
  1132.  
  1133. /**
  1134.   * @}
  1135.   */
  1136.  
  1137. /**
  1138.   * @}
  1139.   */
  1140.  
  1141. /**
  1142.   * @}
  1143.   */
  1144.  
  1145. /**
  1146.   * @}
  1147.   */
  1148.  
  1149. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement