1 /**
2   ******************************************************************************
3   * @file    stm32l562e_discovery_ospi.c
4   * @author  MCD Application Team
5   * @brief   This file includes a standard driver for the MX25LM51245G OSPI
6   *          memory mounted on STM32L562E-DK board.
7   @verbatim
8   ==============================================================================
9                      ##### How to use this driver #####
10   ==============================================================================
11   [..]
12    (#) This driver is used to drive the MX25LM51245G Octal NOR
13        external memory mounted on STM32L562E-DK discovery board.
14 
15    (#) This driver need specific component driver (MX25LM51245G) to be included with.
16 
17    (#) MX25LM51245G Initialization steps:
18        (++) Initialize the OPSI external memory using the BSP_OSPI_NOR_Init() function. This
19             function includes the MSP layer hardware resources initialization and the
20             OSPI interface with the external memory.
21 
22    (#) MX25LM51245G Octal NOR memory operations
23        (++) OSPI memory can be accessed with read/write operations once it is
24             initialized.
25             Read/write operation can be performed with AHB access using the functions
26             BSP_OSPI_NOR_Read()/BSP_OSPI_NOR_Write().
27        (++) The function BSP_OSPI_NOR_GetInfo() returns the configuration of the OSPI memory.
28             (see the OSPI memory data sheet)
29        (++) Perform erase block operation using the function BSP_OSPI_NOR_Erase_Block() and by
30             specifying the block address. You can perform an erase operation of the whole
31             chip by calling the function BSP_OSPI_NOR_Erase_Chip().
32        (++) The function BSP_OSPI_NOR_GetStatus() returns the current status of the OSPI memory.
33             (see the OSPI memory data sheet)
34        (++) The memory access can be configured in memory-mapped mode with the call of
35             function BSP_OSPI_NOR_EnableMemoryMapped(). To go back in indirect mode, the
36             function BSP_OSPI_NOR_DisableMemoryMapped() should be used.
37        (++) The erase operation can be suspend and resume with using functions
38             BSP_OSPI_NOR_SuspendErase() and BSP_OSPI_NOR_ResumeErase()
39        (++) It is possible to put the memory in deep power-down mode to reduce its consumption.
40             For this, the function BSP_OSPI_NOR_EnterDeepPowerDown() should be called. To leave
41             the deep power-down mode, the function BSP_OSPI_NOR_LeaveDeepPowerDown() should be called.
42        (++) The function BSP_OSPI_NOR_ReadID() returns the identifier of the memory
43             (see the OSPI memory data sheet)
44        (++) The configuration of the interface between peripheral and memory is done by
45             the function BSP_OSPI_NOR_ConfigFlash(), three modes are possible :
46             - SPI : instruction, address and data on one line
47             - STR OPI : instruction, address and data on eight lines with sampling on one edge of clock
48             - DTR OPI : instruction, address and data on eight lines with sampling on both edgaes of clock
49 
50   @endverbatim
51   ******************************************************************************
52   * @attention
53   *
54   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
55   * All rights reserved.</center></h2>
56   *
57   * This software component is licensed by ST under BSD 3-Clause license,
58   * the "License"; You may not use this file except in compliance with the
59   * License. You may obtain a copy of the License at:
60   *                        opensource.org/licenses/BSD-3-Clause
61   *
62   ******************************************************************************
63   */
64 
65 /* Includes ------------------------------------------------------------------*/
66 #include "stm32l562e_discovery_ospi.h"
67 
68 /** @addtogroup BSP
69   * @{
70   */
71 
72 /** @addtogroup STM32L562E-DK
73   * @{
74   */
75 
76 /** @defgroup STM32L562E-DK_OSPI STM32L562E-DK OSPI
77   * @{
78   */
79 
80 /* Exported variables --------------------------------------------------------*/
81 /** @addtogroup STM32L562E-DK_OSPI_NOR_Exported_Variables
82   * @{
83   */
84 OSPI_HandleTypeDef hospi_nor[OSPI_NOR_INSTANCES_NUMBER] = {0};
85 OSPI_NOR_Ctx_t Ospi_Nor_Ctx[OSPI_NOR_INSTANCES_NUMBER] = {{OSPI_ACCESS_NONE,
86                                                            MX25LM51245G_SPI_MODE,
87                                                            MX25LM51245G_STR_TRANSFER}};
88 /**
89   * @}
90   */
91 
92 /* Private constants --------------------------------------------------------*/
93 /* Private variables ---------------------------------------------------------*/
94 /** @defgroup STM32L552E_EVAL_OSPI_NOR_Private_Variables NOR Private Variables
95   * @{
96   */
97 #if (USE_HAL_OSPI_REGISTER_CALLBACKS == 1)
98 static uint32_t OspiNor_IsMspCbValid[OSPI_NOR_INSTANCES_NUMBER] = {0};
99 #endif /* USE_HAL_OSPI_REGISTER_CALLBACKS */
100 /**
101   * @}
102   */
103 
104 /* Private functions ---------------------------------------------------------*/
105 
106 /** @defgroup STM32L562E-DK_OSPI_NOR_Private_Functions STM32L562E-DK OSPI_NOR Private Functions
107   * @{
108   */
109 static void    OSPI_NOR_MspInit      (OSPI_HandleTypeDef *hospi);
110 static void    OSPI_NOR_MspDeInit    (OSPI_HandleTypeDef *hospi);
111 static int32_t OSPI_NOR_ResetMemory  (uint32_t Instance);
112 static int32_t OSPI_NOR_EnterDOPIMode(uint32_t Instance);
113 static int32_t OSPI_NOR_EnterSOPIMode(uint32_t Instance);
114 static int32_t OSPI_NOR_ExitOPIMode  (uint32_t Instance);
115 /**
116   * @}
117   */
118 
119 /* Exported functions ---------------------------------------------------------*/
120 
121 /** @addtogroup STM32L562E-DK_OSPI_NOR_Exported_Functions
122   * @{
123   */
124 
125 /**
126   * @brief  Initializes the OSPI interface.
127   * @param  Instance   OSPI Instance
128   * @param  Init       OSPI Init structure
129   * @retval BSP status
130   */
BSP_OSPI_NOR_Init(uint32_t Instance,BSP_OSPI_NOR_Init_t * Init)131 int32_t BSP_OSPI_NOR_Init(uint32_t Instance, BSP_OSPI_NOR_Init_t *Init)
132 {
133   int32_t ret;
134   BSP_OSPI_NOR_Info_t pInfo;
135   MX_OSPI_InitTypeDef ospi_init;
136 
137   /* Check if the instance is supported */
138   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
139   {
140     ret = BSP_ERROR_WRONG_PARAM;
141   }
142   else
143   {
144     /* Check if the instance is already initialized */
145     if (Ospi_Nor_Ctx[Instance].IsInitialized == OSPI_ACCESS_NONE)
146     {
147 #if (USE_HAL_OSPI_REGISTER_CALLBACKS == 0)
148       /* Msp OSPI initialization */
149       OSPI_NOR_MspInit(&hospi_nor[Instance]);
150 #else
151       /* Register the OSPI MSP Callbacks */
152       if(OspiNor_IsMspCbValid[Instance] == 0UL)
153       {
154         if(BSP_OSPI_NOR_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE)
155         {
156           return BSP_ERROR_PERIPH_FAILURE;
157         }
158       }
159 #endif /* USE_HAL_OSPI_REGISTER_CALLBACKS */
160 
161       /* Get Flash information of one memory */
162       (void)MX25LM51245G_GetFlashInfo(&pInfo);
163 
164       /* Fill config structure */
165       ospi_init.ClockPrescaler = 3; /* OctoSPI clock = 120MHz / ClockPrescaler = 40MHz */
166       ospi_init.MemorySize     = (uint32_t)POSITION_VAL((uint32_t)pInfo.FlashSize);
167       ospi_init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
168       ospi_init.TransferRate   = (uint32_t) Init->TransferRate;
169 
170       /* STM32 OSPI interface initialization */
171       if (MX_OSPI_NOR_Init(&hospi_nor[Instance], &ospi_init) != HAL_OK)
172       {
173         ret = BSP_ERROR_PERIPH_FAILURE;
174       }
175       /* OSPI memory reset */
176       else if (OSPI_NOR_ResetMemory(Instance) != BSP_ERROR_NONE)
177       {
178         ret = BSP_ERROR_COMPONENT_FAILURE;
179       }
180       /* Check if memory is ready */
181       else if (MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
182       {
183         ret = BSP_ERROR_COMPONENT_FAILURE;
184       }
185       /* Configure the memory */
186       else if (BSP_OSPI_NOR_ConfigFlash(Instance, Init->InterfaceMode, Init->TransferRate) != BSP_ERROR_NONE)
187       {
188         ret = BSP_ERROR_COMPONENT_FAILURE;
189       }
190       else
191       {
192         ret = BSP_ERROR_NONE;
193       }
194     }
195     else
196     {
197       ret = BSP_ERROR_NONE;
198     }
199   }
200 
201   /* Return BSP status */
202   return ret;
203 }
204 
205 /**
206   * @brief  De-Initializes the OSPI interface.
207   * @param  Instance   OSPI Instance
208   * @retval BSP status
209   */
BSP_OSPI_NOR_DeInit(uint32_t Instance)210 int32_t BSP_OSPI_NOR_DeInit(uint32_t Instance)
211 {
212   int32_t ret = BSP_ERROR_NONE;
213 
214   /* Check if the instance is supported */
215   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
216   {
217     ret = BSP_ERROR_WRONG_PARAM;
218   }
219   else
220   {
221     /* Check if the instance is already initialized */
222     if (Ospi_Nor_Ctx[Instance].IsInitialized != OSPI_ACCESS_NONE)
223     {
224       /* Disable Memory mapped mode */
225       if(Ospi_Nor_Ctx[Instance].IsInitialized == OSPI_ACCESS_MMP)
226       {
227         if(BSP_OSPI_NOR_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE)
228         {
229           return BSP_ERROR_COMPONENT_FAILURE;
230         }
231       }
232 
233       /* Set default Ospi_Nor_Ctx values */
234       Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_NONE;
235       Ospi_Nor_Ctx[Instance].InterfaceMode = BSP_OSPI_NOR_SPI_MODE;
236       Ospi_Nor_Ctx[Instance].TransferRate  = BSP_OSPI_NOR_STR_TRANSFER;
237 
238 #if (USE_HAL_OSPI_REGISTER_CALLBACKS == 0)
239       OSPI_NOR_MspDeInit(&hospi_nor[Instance]);
240 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS == 0) */
241 
242       /* Call the DeInit function to reset the driver */
243       if (HAL_OSPI_DeInit(&hospi_nor[Instance]) != HAL_OK)
244       {
245         ret = BSP_ERROR_PERIPH_FAILURE;
246       }
247     }
248   }
249 
250   /* Return BSP status */
251   return ret;
252 }
253 
254 /**
255   * @brief  Initializes the OSPI interface.
256   * @param  hospi          OSPI handle
257   * @param  Init           OSPI config structure
258   * @retval BSP status
259   */
MX_OSPI_NOR_Init(OSPI_HandleTypeDef * hospi,MX_OSPI_InitTypeDef * Init)260 __weak HAL_StatusTypeDef MX_OSPI_NOR_Init(OSPI_HandleTypeDef *hospi, MX_OSPI_InitTypeDef *Init)
261 {
262     /* OctoSPI initialization */
263   hospi->Instance = OCTOSPI1;
264 
265   hospi->Init.FifoThreshold      = 4;
266   hospi->Init.DualQuad           = HAL_OSPI_DUALQUAD_DISABLE;
267   hospi->Init.DeviceSize         = Init->MemorySize; /* 512 MBits */
268   hospi->Init.ChipSelectHighTime = 2;
269   hospi->Init.FreeRunningClock   = HAL_OSPI_FREERUNCLK_DISABLE;
270   hospi->Init.ClockMode          = HAL_OSPI_CLOCK_MODE_0;
271   hospi->Init.WrapSize           = HAL_OSPI_WRAP_NOT_SUPPORTED;
272   hospi->Init.ClockPrescaler     = Init->ClockPrescaler;
273   hospi->Init.SampleShifting     = Init->SampleShifting;
274   hospi->Init.ChipSelectBoundary = 0;
275 
276   if (Init->TransferRate == (uint32_t) BSP_OSPI_NOR_DTR_TRANSFER)
277   {
278     hospi->Init.MemoryType            = HAL_OSPI_MEMTYPE_MACRONIX;
279     hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
280   }
281   else
282   {
283     hospi->Init.MemoryType            = HAL_OSPI_MEMTYPE_MICRON;
284     hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
285   }
286 
287   return HAL_OSPI_Init(hospi);
288 }
289 
290 #if (USE_HAL_OSPI_REGISTER_CALLBACKS == 1)
291 /**
292   * @brief Default BSP OSPI Msp Callbacks
293   * @param Instance      OSPI Instance
294   * @retval BSP status
295   */
BSP_OSPI_NOR_RegisterDefaultMspCallbacks(uint32_t Instance)296 int32_t BSP_OSPI_NOR_RegisterDefaultMspCallbacks (uint32_t Instance)
297 {
298   int32_t ret = BSP_ERROR_NONE;
299 
300   /* Check if the instance is supported */
301   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
302   {
303     ret = BSP_ERROR_WRONG_PARAM;
304   }
305   else
306   {
307     /* Register MspInit/MspDeInit Callbacks */
308     if(HAL_OSPI_RegisterCallback(&hospi_nor[Instance], HAL_OSPI_MSP_INIT_CB_ID, OSPI_NOR_MspInit) != HAL_OK)
309     {
310       ret = BSP_ERROR_PERIPH_FAILURE;
311     }
312     else if(HAL_OSPI_RegisterCallback(&hospi_nor[Instance], HAL_OSPI_MSP_DEINIT_CB_ID, OSPI_NOR_MspDeInit) != HAL_OK)
313     {
314       ret = BSP_ERROR_PERIPH_FAILURE;
315     }
316     else
317     {
318       OspiNor_IsMspCbValid[Instance] = 1U;
319     }
320   }
321 
322   /* Return BSP status */
323   return ret;
324 }
325 
326 /**
327   * @brief BSP OSPI Msp Callback registering
328   * @param Instance     OSPI Instance
329   * @param CallBacks    pointer to MspInit/MspDeInit callbacks functions
330   * @retval BSP status
331   */
BSP_OSPI_NOR_RegisterMspCallbacks(uint32_t Instance,BSP_OSPI_Cb_t * CallBacks)332 int32_t BSP_OSPI_NOR_RegisterMspCallbacks (uint32_t Instance, BSP_OSPI_Cb_t *CallBacks)
333 {
334   int32_t ret = BSP_ERROR_NONE;
335 
336   /* Check if the instance is supported */
337   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
338   {
339     ret = BSP_ERROR_WRONG_PARAM;
340   }
341   else
342   {
343     /* Register MspInit/MspDeInit Callbacks */
344     if(HAL_OSPI_RegisterCallback(&hospi_nor[Instance], HAL_OSPI_MSP_INIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK)
345     {
346       ret = BSP_ERROR_PERIPH_FAILURE;
347     }
348     else if(HAL_OSPI_RegisterCallback(&hospi_nor[Instance], HAL_OSPI_MSP_DEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK)
349     {
350       ret = BSP_ERROR_PERIPH_FAILURE;
351     }
352     else
353     {
354       OspiNor_IsMspCbValid[Instance] = 1U;
355     }
356   }
357 
358   /* Return BSP status */
359   return ret;
360 }
361 #endif /* (USE_HAL_OSPI_REGISTER_CALLBACKS == 1) */
362 
363 /**
364   * @brief  Reads an amount of data from the OSPI memory.
365   * @param  Instance  OSPI instance
366   * @param  pData     Pointer to data to be read
367   * @param  ReadAddr  Read start address
368   * @param  Size      Size of data to read
369   * @retval BSP status
370   */
BSP_OSPI_NOR_Read(uint32_t Instance,uint8_t * pData,uint32_t ReadAddr,uint32_t Size)371 int32_t BSP_OSPI_NOR_Read(uint32_t Instance, uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
372 {
373   int32_t ret;
374 
375   /* Check if the instance is supported */
376   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
377   {
378     ret = BSP_ERROR_WRONG_PARAM;
379   }
380   else
381   {
382     if(Ospi_Nor_Ctx[Instance].TransferRate == BSP_OSPI_NOR_STR_TRANSFER)
383     {
384       if(MX25LM51245G_ReadSTR(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, MX25LM51245G_4BYTES_SIZE, pData, ReadAddr, Size) != MX25LM51245G_OK)
385       {
386         ret = BSP_ERROR_COMPONENT_FAILURE;
387       }
388       else
389       {
390         ret = BSP_ERROR_NONE;
391       }
392     }
393     else
394     {
395       if(MX25LM51245G_ReadDTR(&hospi_nor[Instance], pData, ReadAddr, Size) != MX25LM51245G_OK)
396       {
397         ret = BSP_ERROR_COMPONENT_FAILURE;
398       }
399       else
400       {
401         ret = BSP_ERROR_NONE;
402       }
403     }
404   }
405 
406   /* Return BSP status */
407   return ret;
408 }
409 
410 /**
411   * @brief  Writes an amount of data to the OSPI memory.
412   * @param  Instance  OSPI instance
413   * @param  pData     Pointer to data to be written
414   * @param  WriteAddr Write start address
415   * @param  Size      Size of data to write
416   * @retval BSP status
417   */
BSP_OSPI_NOR_Write(uint32_t Instance,uint8_t * pData,uint32_t WriteAddr,uint32_t Size)418 int32_t BSP_OSPI_NOR_Write(uint32_t Instance, uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
419 {
420   int32_t ret = BSP_ERROR_NONE;
421   uint32_t end_addr, current_size, current_addr;
422   uint32_t data_addr;
423 
424   /* Check if the instance is supported */
425   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
426   {
427     ret = BSP_ERROR_WRONG_PARAM;
428   }
429   else
430   {
431     /* Calculation of the size between the write address and the end of the page */
432     current_size = MX25LM51245G_PAGE_SIZE - (WriteAddr % MX25LM51245G_PAGE_SIZE);
433 
434     /* Check if the size of the data is less than the remaining place in the page */
435     if (current_size > Size)
436     {
437       current_size = Size;
438     }
439 
440     /* Initialize the address variables */
441     current_addr = WriteAddr;
442     end_addr = WriteAddr + Size;
443     data_addr = (uint32_t)pData;
444 
445     /* Perform the write page by page */
446     do
447     {
448       /* Check if Flash busy ? */
449       if(MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
450       {
451         ret = BSP_ERROR_COMPONENT_FAILURE;
452       }/* Enable write operations */
453       else if(MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
454       {
455         ret = BSP_ERROR_COMPONENT_FAILURE;
456       }
457       else
458       {
459         if(Ospi_Nor_Ctx[Instance].TransferRate == BSP_OSPI_NOR_STR_TRANSFER)
460         {
461           /* Issue page program command */
462           if(MX25LM51245G_PageProgram(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, MX25LM51245G_4BYTES_SIZE, (uint8_t*)data_addr, current_addr, current_size) != MX25LM51245G_OK)
463           {
464             ret = BSP_ERROR_COMPONENT_FAILURE;
465           }
466         }
467         else
468         {
469           /* Issue page program command */
470           if(MX25LM51245G_PageProgramDTR(&hospi_nor[Instance], (uint8_t*)data_addr, current_addr, current_size) != MX25LM51245G_OK)
471           {
472             ret = BSP_ERROR_COMPONENT_FAILURE;
473           }
474         }
475 
476         if (ret == BSP_ERROR_NONE)
477         {
478           /* Configure automatic polling mode to wait for end of program */
479           if (MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
480           {
481             ret = BSP_ERROR_COMPONENT_FAILURE;
482           }
483           else
484           {
485             /* Update the address and size variables for next page programming */
486             current_addr += current_size;
487             data_addr += current_size;
488             current_size = ((current_addr + MX25LM51245G_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25LM51245G_PAGE_SIZE;
489           }
490         }
491       }
492     } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE));
493   }
494 
495   /* Return BSP status */
496   return ret;
497 }
498 
499 /**
500   * @brief  Erases the specified block of the OSPI memory.
501   * @param  Instance     OSPI instance
502   * @param  BlockAddress Block address to erase
503   * @param  BlockSize    Erase Block size
504   * @retval BSP status
505   */
BSP_OSPI_NOR_Erase_Block(uint32_t Instance,uint32_t BlockAddress,BSP_OSPI_NOR_Erase_t BlockSize)506 int32_t BSP_OSPI_NOR_Erase_Block(uint32_t Instance, uint32_t BlockAddress, BSP_OSPI_NOR_Erase_t BlockSize)
507 {
508   int32_t ret;
509 
510   /* Check if the instance is supported */
511   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
512   {
513     ret = BSP_ERROR_WRONG_PARAM;
514   }
515   else
516   {
517     /* Check Flash busy ? */
518     if(MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
519     {
520       ret = BSP_ERROR_COMPONENT_FAILURE;
521     }/* Enable write operations */
522     else if(MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
523     {
524       ret = BSP_ERROR_COMPONENT_FAILURE;
525     }/* Issue Block Erase command */
526     else if(MX25LM51245G_BlockErase(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_4BYTES_SIZE, BlockAddress, BlockSize) != MX25LM51245G_OK)
527     {
528       ret = BSP_ERROR_COMPONENT_FAILURE;
529     }
530     else
531     {
532       ret = BSP_ERROR_NONE;
533     }
534   }
535 
536   /* Return BSP status */
537   return ret;
538 }
539 
540 /**
541   * @brief  Erases the entire OSPI memory.
542   * @param  Instance  QSPI instance
543   * @retval BSP status
544   */
BSP_OSPI_NOR_Erase_Chip(uint32_t Instance)545 int32_t BSP_OSPI_NOR_Erase_Chip(uint32_t Instance)
546 {
547   int32_t ret;
548 
549   /* Check if the instance is supported */
550   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
551   {
552     ret = BSP_ERROR_WRONG_PARAM;
553   }
554   else
555   {
556     /* Check Flash busy ? */
557     if(MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
558     {
559       ret = BSP_ERROR_COMPONENT_FAILURE;
560     }/* Enable write operations */
561     else if(MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
562     {
563       ret = BSP_ERROR_COMPONENT_FAILURE;
564     }/* Issue Chip erase command */
565     else if(MX25LM51245G_ChipErase(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
566     {
567       ret = BSP_ERROR_COMPONENT_FAILURE;
568     }
569     else
570     {
571       ret = BSP_ERROR_NONE;
572     }
573   }
574 
575   /* Return BSP status */
576   return ret;
577 }
578 
579 /**
580   * @brief  Reads current status of the OSPI memory.
581   * @param  Instance  QSPI instance
582   * @retval OSPI memory status: whether busy or not
583   */
BSP_OSPI_NOR_GetStatus(uint32_t Instance)584 int32_t BSP_OSPI_NOR_GetStatus(uint32_t Instance)
585 {
586   static uint8_t reg[2];
587   int32_t ret;
588 
589   /* Check if the instance is supported */
590   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
591   {
592     ret = BSP_ERROR_WRONG_PARAM;
593   }
594   else
595   {
596     if(MX25LM51245G_ReadSecurityRegister(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, reg) != MX25LM51245G_OK)
597     {
598       ret = BSP_ERROR_COMPONENT_FAILURE;
599     }/* Check the value of the register */
600     else if ((reg[0] & (MX25LM51245G_SECR_P_FAIL | MX25LM51245G_SECR_E_FAIL)) != 0U)
601     {
602       ret = BSP_ERROR_COMPONENT_FAILURE;
603     }
604     else if ((reg[0] & (MX25LM51245G_SECR_PSB | MX25LM51245G_SECR_ESB)) != 0U)
605     {
606       ret = BSP_ERROR_OSPI_SUSPENDED;
607     }
608     else if(MX25LM51245G_ReadStatusRegister(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, reg) != MX25LM51245G_OK)
609     {
610       ret = BSP_ERROR_COMPONENT_FAILURE;
611     }/* Check the value of the register */
612     else if ((reg[0] & MX25LM51245G_SR_WIP) != 0U)
613     {
614       ret = BSP_ERROR_BUSY;
615     }
616     else
617     {
618       ret = BSP_ERROR_NONE;
619     }
620   }
621 
622   /* Return BSP status */
623   return ret;
624 }
625 
626 /**
627   * @brief  Return the configuration of the OSPI memory.
628   * @param  Instance  OSPI instance
629   * @param  pInfo     pointer on the configuration structure
630   * @retval BSP status
631   */
BSP_OSPI_NOR_GetInfo(uint32_t Instance,BSP_OSPI_NOR_Info_t * pInfo)632 int32_t BSP_OSPI_NOR_GetInfo(uint32_t Instance, BSP_OSPI_NOR_Info_t* pInfo)
633 {
634   int32_t ret = BSP_ERROR_NONE;
635 
636   /* Check if the instance is supported */
637   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
638   {
639     ret = BSP_ERROR_WRONG_PARAM;
640   }
641   else
642   {
643     (void)MX25LM51245G_GetFlashInfo(pInfo);
644   }
645 
646   /* Return BSP status */
647   return ret;
648 }
649 
650 /**
651   * @brief  Configure the OSPI in memory-mapped mode
652   * @param  Instance  OSPI instance
653   * @retval BSP status
654   */
BSP_OSPI_NOR_EnableMemoryMappedMode(uint32_t Instance)655 int32_t BSP_OSPI_NOR_EnableMemoryMappedMode(uint32_t Instance)
656 {
657   int32_t ret = BSP_ERROR_NONE;
658 
659   /* Check if the instance is supported */
660   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
661   {
662     ret = BSP_ERROR_WRONG_PARAM;
663   }
664   else
665   {
666     if(Ospi_Nor_Ctx[Instance].TransferRate == BSP_OSPI_NOR_STR_TRANSFER)
667     {
668       if(MX25LM51245G_EnableMemoryMappedModeSTR(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, MX25LM51245G_4BYTES_SIZE) != MX25LM51245G_OK)
669       {
670         ret = BSP_ERROR_COMPONENT_FAILURE;
671       }
672       else /* Update OSPI context if all operations are well done */
673       {
674         Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_MMP;
675       }
676     }
677     else
678     {
679       if(MX25LM51245G_EnableMemoryMappedModeDTR(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode) != MX25LM51245G_OK)
680       {
681         ret = BSP_ERROR_COMPONENT_FAILURE;
682       }
683       else /* Update OSPI context if all operations are well done */
684       {
685         Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_MMP;
686       }
687     }
688   }
689 
690   /* Return BSP status */
691   return ret;
692 }
693 
694 /**
695   * @brief  Exit form memory-mapped mode
696   *         Only 1 Instance can running MMP mode. And it will lock system at this mode.
697   * @param  Instance  OSPI instance
698   * @retval BSP status
699   */
BSP_OSPI_NOR_DisableMemoryMappedMode(uint32_t Instance)700 int32_t BSP_OSPI_NOR_DisableMemoryMappedMode(uint32_t Instance)
701 {
702   int32_t ret = BSP_ERROR_NONE;
703 
704   /* Check if the instance is supported */
705   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
706   {
707     ret = BSP_ERROR_WRONG_PARAM;
708   }
709   else
710   {
711     if(Ospi_Nor_Ctx[Instance].IsInitialized != OSPI_ACCESS_MMP)
712     {
713       ret = BSP_ERROR_OSPI_MMP_UNLOCK_FAILURE;
714     }/* Abort MMP back to indirect mode */
715     else if(HAL_OSPI_Abort(&hospi_nor[Instance]) != HAL_OK)
716     {
717       ret = BSP_ERROR_PERIPH_FAILURE;
718     }
719     else /* Update OSPI NOR context if all operations are well done */
720     {
721       Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_INDIRECT;
722     }
723   }
724 
725   /* Return BSP status */
726   return ret;
727 }
728 
729 /**
730   * @brief  Get flash ID 3 Bytes:
731   *         Manufacturer ID, Memory type, Memory density
732   * @param  Instance  OSPI instance
733   * @param  Id Pointer to flash ID bytes
734   * @retval BSP status
735   */
BSP_OSPI_NOR_ReadID(uint32_t Instance,uint8_t * Id)736 int32_t BSP_OSPI_NOR_ReadID(uint32_t Instance, uint8_t *Id)
737 {
738   int32_t ret;
739 
740   /* Check if the instance is supported */
741   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
742   {
743     ret = BSP_ERROR_WRONG_PARAM;
744   }
745   else if(MX25LM51245G_ReadID(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, Id) != MX25LM51245G_OK)
746   {
747     ret = BSP_ERROR_COMPONENT_FAILURE;
748   }
749   else
750   {
751     ret = BSP_ERROR_NONE;
752   }
753 
754   /* Return BSP status */
755   return ret;
756 }
757 
758 /**
759   * @brief  Set Flash to desired Interface mode. And this instance becomes current instance.
760   *         If current instance running at MMP mode then this function doesn't work.
761   *         Indirect -> Indirect
762   * @param  Instance  OSPI instance
763   * @param  Mode      OSPI mode
764   * @param  Rate      OSPI transfer rate
765   * @retval BSP status
766   */
BSP_OSPI_NOR_ConfigFlash(uint32_t Instance,BSP_OSPI_NOR_Interface_t Mode,BSP_OSPI_NOR_Transfer_t Rate)767 int32_t BSP_OSPI_NOR_ConfigFlash(uint32_t Instance, BSP_OSPI_NOR_Interface_t Mode, BSP_OSPI_NOR_Transfer_t Rate)
768 {
769   int32_t ret = BSP_ERROR_NONE;
770 
771   /* Check if the instance is supported */
772   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
773   {
774     ret = BSP_ERROR_WRONG_PARAM;
775   }
776   else
777   {
778     /* Check if MMP mode locked ************************************************/
779     if(Ospi_Nor_Ctx[Instance].IsInitialized == OSPI_ACCESS_MMP)
780     {
781       ret = BSP_ERROR_OSPI_MMP_LOCK_FAILURE;
782     }
783     else
784     {
785       /* Setup Flash interface ***************************************************/
786       switch(Ospi_Nor_Ctx[Instance].InterfaceMode)
787       {
788       case BSP_OSPI_NOR_OPI_MODE :  /* 8-8-8 commands */
789         if((Mode != BSP_OSPI_NOR_OPI_MODE) || (Rate != Ospi_Nor_Ctx[Instance].TransferRate))
790         {
791           /* Exit OPI mode */
792           ret = OSPI_NOR_ExitOPIMode(Instance);
793 
794           if ((ret == BSP_ERROR_NONE) && (Mode == BSP_OSPI_NOR_OPI_MODE))
795           {
796 
797             if (Ospi_Nor_Ctx[Instance].TransferRate == BSP_OSPI_NOR_STR_TRANSFER)
798             {
799               /* Enter DTR OPI mode */
800               ret = OSPI_NOR_EnterDOPIMode(Instance);
801             }
802             else
803             {
804               /* Enter STR OPI mode */
805               ret = OSPI_NOR_EnterSOPIMode(Instance);
806             }
807           }
808         }
809         break;
810 
811       case BSP_OSPI_NOR_SPI_MODE :  /* 1-1-1 commands, Power on H/W default setting */
812       default :
813         if(Mode == BSP_OSPI_NOR_OPI_MODE)
814         {
815           if(Rate == BSP_OSPI_NOR_STR_TRANSFER)
816           {
817             /* Enter STR OPI mode */
818             ret = OSPI_NOR_EnterSOPIMode(Instance);
819           }
820           else
821           {
822             /* Enter DTR OPI mode */
823             ret = OSPI_NOR_EnterDOPIMode(Instance);
824           }
825         }
826         break;
827       }
828 
829       /* Update OSPI context if all operations are well done */
830       if(ret == BSP_ERROR_NONE)
831       {
832         /* Update current status parameter *****************************************/
833         Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_INDIRECT;
834         Ospi_Nor_Ctx[Instance].InterfaceMode = Mode;
835         Ospi_Nor_Ctx[Instance].TransferRate  = Rate;
836       }
837     }
838   }
839 
840   /* Return BSP status */
841   return ret;
842 }
843 
844 /**
845   * @brief  This function suspends an ongoing erase command.
846   * @param  Instance  QSPI instance
847   * @retval BSP status
848   */
BSP_OSPI_NOR_SuspendErase(uint32_t Instance)849 int32_t BSP_OSPI_NOR_SuspendErase(uint32_t Instance)
850 {
851   int32_t ret;
852 
853   /* Check if the instance is supported */
854   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
855   {
856     ret = BSP_ERROR_WRONG_PARAM;
857   }
858   /* Check whether the device is busy (erase operation is in progress). */
859   else if (BSP_OSPI_NOR_GetStatus(Instance) != BSP_ERROR_BUSY)
860   {
861     ret = BSP_ERROR_COMPONENT_FAILURE;
862   }
863   else if(MX25LM51245G_Suspend(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
864   {
865     ret = BSP_ERROR_COMPONENT_FAILURE;
866   }
867   else if (BSP_OSPI_NOR_GetStatus(Instance) != BSP_ERROR_OSPI_SUSPENDED)
868   {
869     ret = BSP_ERROR_COMPONENT_FAILURE;
870   }
871   else
872   {
873     ret = BSP_ERROR_NONE;
874   }
875 
876   /* Return BSP status */
877   return ret;
878 }
879 
880 /**
881   * @brief  This function resumes a paused erase command.
882   * @param  Instance  QSPI instance
883   * @retval BSP status
884   */
BSP_OSPI_NOR_ResumeErase(uint32_t Instance)885 int32_t BSP_OSPI_NOR_ResumeErase(uint32_t Instance)
886 {
887   int32_t ret;
888 
889   /* Check if the instance is supported */
890   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
891   {
892     ret = BSP_ERROR_WRONG_PARAM;
893   }
894   /* Check whether the device is busy (erase operation is in progress). */
895   else if (BSP_OSPI_NOR_GetStatus(Instance) != BSP_ERROR_OSPI_SUSPENDED)
896   {
897     ret = BSP_ERROR_COMPONENT_FAILURE;
898   }
899   else if(MX25LM51245G_Resume(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
900   {
901     ret = BSP_ERROR_COMPONENT_FAILURE;
902   }
903   /*
904   When this command is executed, the status register write in progress bit is set to 1, and
905   the flag status register program erase controller bit is set to 0. This command is ignored
906   if the device is not in a suspended state.
907   */
908   else if (BSP_OSPI_NOR_GetStatus(Instance) != BSP_ERROR_BUSY)
909   {
910     ret = BSP_ERROR_COMPONENT_FAILURE;
911   }
912   else
913   {
914     ret = BSP_ERROR_NONE;
915   }
916 
917   /* Return BSP status */
918   return ret;
919 }
920 
921 /**
922   * @brief  This function enter the OSPI memory in deep power down mode.
923   * @param  Instance  QSPI instance
924   * @retval BSP status
925   */
BSP_OSPI_NOR_EnterDeepPowerDown(uint32_t Instance)926 int32_t BSP_OSPI_NOR_EnterDeepPowerDown(uint32_t Instance)
927 {
928   int32_t ret;
929 
930   /* Check if the instance is supported */
931   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
932   {
933     ret = BSP_ERROR_WRONG_PARAM;
934   }
935   else if(MX25LM51245G_EnterPowerDown(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
936   {
937     ret = BSP_ERROR_COMPONENT_FAILURE;
938   }
939   else
940   {
941     ret = BSP_ERROR_NONE;
942   }
943 
944   /* ---          Memory takes 10us max to enter deep power down          --- */
945 
946   /* Return BSP status */
947   return ret;
948 }
949 
950 /**
951   * @brief  This function leave the OSPI memory from deep power down mode.
952   * @param  Instance  QSPI instance
953   * @retval BSP status
954   */
BSP_OSPI_NOR_LeaveDeepPowerDown(uint32_t Instance)955 int32_t BSP_OSPI_NOR_LeaveDeepPowerDown(uint32_t Instance)
956 {
957   int32_t ret;
958 
959   /* Check if the instance is supported */
960   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
961   {
962     ret = BSP_ERROR_WRONG_PARAM;
963   }
964   else if(MX25LM51245G_NoOperation(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
965   {
966     ret = BSP_ERROR_COMPONENT_FAILURE;
967   }
968   else
969   {
970     ret = BSP_ERROR_NONE;
971   }
972 
973   /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */
974   /* ---                  Memory takes 30us min to leave deep power down                  --- */
975 
976   /* Return BSP status */
977   return ret;
978 }
979 /**
980   * @}
981   */
982 
983 /** @addtogroup STM32L562E-DK_OSPI_NOR_Private_Functions
984   * @{
985   */
986 
987 /**
988   * @brief  Initializes the OSPI MSP.
989   * @param  hospi OSPI handle
990   * @retval None
991   */
OSPI_NOR_MspInit(OSPI_HandleTypeDef * hospi)992 static void OSPI_NOR_MspInit(OSPI_HandleTypeDef *hospi)
993 {
994   GPIO_InitTypeDef GPIO_InitStruct;
995 
996   /* hospi unused argument(s) compilation warning */
997   UNUSED(hospi);
998 
999   /* Enable the OctoSPI memory interface clock */
1000   OSPI_CLK_ENABLE();
1001 
1002   /* Reset the OctoSPI memory interface */
1003   OSPI_FORCE_RESET();
1004   OSPI_RELEASE_RESET();
1005 
1006   /* Enable GPIO clocks */
1007   OSPI_CLK_GPIO_CLK_ENABLE();
1008   OSPI_DQS_GPIO_CLK_ENABLE();
1009   OSPI_CS_GPIO_CLK_ENABLE();
1010   OSPI_D0_GPIO_CLK_ENABLE();
1011   OSPI_D1_GPIO_CLK_ENABLE();
1012   OSPI_D2_GPIO_CLK_ENABLE();
1013   OSPI_D3_GPIO_CLK_ENABLE();
1014   OSPI_D4_GPIO_CLK_ENABLE();
1015   OSPI_D5_GPIO_CLK_ENABLE();
1016   OSPI_D6_GPIO_CLK_ENABLE();
1017   OSPI_D7_GPIO_CLK_ENABLE();
1018 
1019   /* OctoSPI CS GPIO pin configuration  */
1020   GPIO_InitStruct.Pin       = OSPI_CS_PIN;
1021   GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
1022   GPIO_InitStruct.Pull      = GPIO_PULLUP;
1023   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
1024   GPIO_InitStruct.Alternate = OSPI_CS_PIN_AF;
1025   HAL_GPIO_Init(OSPI_CS_GPIO_PORT, &GPIO_InitStruct);
1026 
1027   /* OctoSPI DQS GPIO pin configuration  */
1028   GPIO_InitStruct.Pin       = OSPI_DQS_PIN;
1029   GPIO_InitStruct.Alternate = OSPI_DQS_PIN_AF;
1030   HAL_GPIO_Init(OSPI_DQS_GPIO_PORT, &GPIO_InitStruct);
1031 
1032   /* OctoSPI CLK GPIO pin configuration  */
1033   GPIO_InitStruct.Pin       = OSPI_CLK_PIN;
1034   GPIO_InitStruct.Pull      = GPIO_NOPULL;
1035   GPIO_InitStruct.Alternate = OSPI_CLK_PIN_AF;
1036   HAL_GPIO_Init(OSPI_CLK_GPIO_PORT, &GPIO_InitStruct);
1037 
1038   /* OctoSPI D0 GPIO pin configuration  */
1039   GPIO_InitStruct.Pin       = OSPI_D0_PIN;
1040   GPIO_InitStruct.Alternate = OSPI_D0_PIN_AF;
1041   HAL_GPIO_Init(OSPI_D0_GPIO_PORT, &GPIO_InitStruct);
1042 
1043   /* OctoSPI D1 GPIO pin configuration  */
1044   GPIO_InitStruct.Pin       = OSPI_D1_PIN;
1045   GPIO_InitStruct.Alternate = OSPI_D1_PIN_AF;
1046   HAL_GPIO_Init(OSPI_D1_GPIO_PORT, &GPIO_InitStruct);
1047 
1048   /* OctoSPI D2 GPIO pin configuration  */
1049   GPIO_InitStruct.Pin       = OSPI_D2_PIN;
1050   GPIO_InitStruct.Alternate = OSPI_D2_PIN_AF;
1051   HAL_GPIO_Init(OSPI_D2_GPIO_PORT, &GPIO_InitStruct);
1052 
1053   /* OctoSPI D3 GPIO pin configuration  */
1054   GPIO_InitStruct.Pin       = OSPI_D3_PIN;
1055   GPIO_InitStruct.Alternate = OSPI_D3_PIN_AF;
1056   HAL_GPIO_Init(OSPI_D3_GPIO_PORT, &GPIO_InitStruct);
1057 
1058   /* OctoSPI D4 GPIO pin configuration  */
1059   GPIO_InitStruct.Pin       = OSPI_D4_PIN;
1060   GPIO_InitStruct.Alternate = OSPI_D4_PIN_AF;
1061   HAL_GPIO_Init(OSPI_D4_GPIO_PORT, &GPIO_InitStruct);
1062 
1063   /* OctoSPI D5 GPIO pin configuration  */
1064   GPIO_InitStruct.Pin       = OSPI_D5_PIN;
1065   GPIO_InitStruct.Alternate = OSPI_D5_PIN_AF;
1066   HAL_GPIO_Init(OSPI_D5_GPIO_PORT, &GPIO_InitStruct);
1067 
1068   /* OctoSPI D6 GPIO pin configuration  */
1069   GPIO_InitStruct.Pin       = OSPI_D6_PIN;
1070   GPIO_InitStruct.Alternate = OSPI_D6_PIN_AF;
1071   HAL_GPIO_Init(OSPI_D6_GPIO_PORT, &GPIO_InitStruct);
1072 
1073   /* OctoSPI D7 GPIO pin configuration  */
1074   GPIO_InitStruct.Pin       = OSPI_D7_PIN;
1075   GPIO_InitStruct.Alternate = OSPI_D7_PIN_AF;
1076   HAL_GPIO_Init(OSPI_D7_GPIO_PORT, &GPIO_InitStruct);
1077 }
1078 
1079 /**
1080   * @brief  De-Initializes the OSPI MSP.
1081   * @param  hospi OSPI handle
1082   * @retval None
1083   */
OSPI_NOR_MspDeInit(OSPI_HandleTypeDef * hospi)1084 static void OSPI_NOR_MspDeInit(OSPI_HandleTypeDef *hospi)
1085 {
1086   /* hospi unused argument(s) compilation warning */
1087   UNUSED(hospi);
1088 
1089   /* OctoSPI GPIO pins de-configuration  */
1090   HAL_GPIO_DeInit(OSPI_CLK_GPIO_PORT, OSPI_CLK_PIN);
1091   HAL_GPIO_DeInit(OSPI_DQS_GPIO_PORT, OSPI_DQS_PIN);
1092   HAL_GPIO_DeInit(OSPI_CS_GPIO_PORT, OSPI_CS_PIN);
1093   HAL_GPIO_DeInit(OSPI_D0_GPIO_PORT, OSPI_D0_PIN);
1094   HAL_GPIO_DeInit(OSPI_D1_GPIO_PORT, OSPI_D1_PIN);
1095   HAL_GPIO_DeInit(OSPI_D2_GPIO_PORT, OSPI_D2_PIN);
1096   HAL_GPIO_DeInit(OSPI_D3_GPIO_PORT, OSPI_D3_PIN);
1097   HAL_GPIO_DeInit(OSPI_D4_GPIO_PORT, OSPI_D4_PIN);
1098   HAL_GPIO_DeInit(OSPI_D5_GPIO_PORT, OSPI_D5_PIN);
1099   HAL_GPIO_DeInit(OSPI_D6_GPIO_PORT, OSPI_D6_PIN);
1100   HAL_GPIO_DeInit(OSPI_D7_GPIO_PORT, OSPI_D7_PIN);
1101 
1102   /* Reset the OctoSPI memory interface */
1103   OSPI_FORCE_RESET();
1104   OSPI_RELEASE_RESET();
1105 
1106   /* Disable the OctoSPI memory interface clock */
1107   OSPI_CLK_DISABLE();
1108 }
1109 
1110 /**
1111   * @brief  This function reset the OSPI memory.
1112   * @param  Instance  OSPI instance
1113   * @retval BSP status
1114   */
OSPI_NOR_ResetMemory(uint32_t Instance)1115 static int32_t OSPI_NOR_ResetMemory (uint32_t Instance)
1116 {
1117   int32_t ret = BSP_ERROR_NONE;
1118 
1119   /* Check if the instance is supported */
1120   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
1121   {
1122     ret = BSP_ERROR_WRONG_PARAM;
1123   }
1124   else if(MX25LM51245G_ResetEnable(&hospi_nor[Instance], BSP_OSPI_NOR_SPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1125   {
1126     ret = BSP_ERROR_COMPONENT_FAILURE;
1127   }
1128   else if(MX25LM51245G_ResetMemory(&hospi_nor[Instance], BSP_OSPI_NOR_SPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1129   {
1130     ret = BSP_ERROR_COMPONENT_FAILURE;
1131   }
1132   else if(MX25LM51245G_ResetEnable(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1133   {
1134     ret = BSP_ERROR_COMPONENT_FAILURE;
1135   }
1136   else if(MX25LM51245G_ResetMemory(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1137   {
1138     ret = BSP_ERROR_COMPONENT_FAILURE;
1139   }
1140   else if(MX25LM51245G_ResetEnable(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_DTR_TRANSFER) != MX25LM51245G_OK)
1141   {
1142     ret = BSP_ERROR_COMPONENT_FAILURE;
1143   }
1144   else if(MX25LM51245G_ResetMemory(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_DTR_TRANSFER) != MX25LM51245G_OK)
1145   {
1146     ret = BSP_ERROR_COMPONENT_FAILURE;
1147   }
1148   else
1149   {
1150     Ospi_Nor_Ctx[Instance].IsInitialized = OSPI_ACCESS_INDIRECT;      /* After reset S/W setting to indirect access   */
1151     Ospi_Nor_Ctx[Instance].InterfaceMode = BSP_OSPI_NOR_SPI_MODE;         /* After reset H/W back to SPI mode by default  */
1152     Ospi_Nor_Ctx[Instance].TransferRate  = BSP_OSPI_NOR_STR_TRANSFER;     /* After reset S/W setting to STR mode          */
1153 
1154     /* After SWreset CMD, wait in case SWReset occurred during erase operation */
1155     HAL_Delay(MX25LM51245G_RESET_MAX_TIME);
1156   }
1157 
1158   /* Return BSP status */
1159   return ret;
1160 }
1161 
1162 /**
1163   * @brief  This function enables the octal DTR mode of the memory.
1164   * @param  Instance  OSPI instance
1165   * @retval BSP status
1166   */
OSPI_NOR_EnterDOPIMode(uint32_t Instance)1167 static int32_t OSPI_NOR_EnterDOPIMode(uint32_t Instance)
1168 {
1169   int32_t ret;
1170   uint8_t reg[2];
1171 
1172   /* Check if the instance is supported */
1173   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
1174   {
1175     ret = BSP_ERROR_WRONG_PARAM;
1176   }
1177   /* Enable write operations */
1178   else if (MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
1179   {
1180     ret = BSP_ERROR_COMPONENT_FAILURE;
1181   }
1182   /* Write Configuration register 2 (with new dummy cycles) */
1183   else if (MX25LM51245G_WriteCfg2Register(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_CR2_REG3_ADDR, MX25LM51245G_CR2_DC_6_CYCLES) != MX25LM51245G_OK)
1184   {
1185     ret = BSP_ERROR_COMPONENT_FAILURE;
1186   }
1187   /* Enable write operations */
1188   else if (MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
1189   {
1190     ret = BSP_ERROR_COMPONENT_FAILURE;
1191   }
1192   /* Write Configuration register 2 (with Octal I/O SPI protocol) */
1193   else if (MX25LM51245G_WriteCfg2Register(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_CR2_REG1_ADDR, MX25LM51245G_CR2_DOPI) != MX25LM51245G_OK)
1194   {
1195     ret = BSP_ERROR_COMPONENT_FAILURE;
1196   }
1197   else
1198   {
1199     /* Wait that the configuration is effective and check that memory is ready */
1200     HAL_Delay(MX25LM51245G_WRITE_REG_MAX_TIME);
1201 
1202     /* Reconfigure the memory type of the peripheral */
1203     hospi_nor[Instance].Init.MemoryType            = HAL_OSPI_MEMTYPE_MACRONIX;
1204     hospi_nor[Instance].Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
1205     if (HAL_OSPI_Init(&hospi_nor[Instance]) != HAL_OK)
1206     {
1207       ret = BSP_ERROR_PERIPH_FAILURE;
1208     }
1209     /* Check Flash busy ? */
1210     else if (MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_DTR_TRANSFER) != MX25LM51245G_OK)
1211     {
1212       ret = BSP_ERROR_COMPONENT_FAILURE;
1213     }
1214     /* Check the configuration has been correctly done */
1215     else if (MX25LM51245G_ReadCfg2Register(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_DTR_TRANSFER, MX25LM51245G_CR2_REG1_ADDR, reg) != MX25LM51245G_OK)
1216     {
1217       ret = BSP_ERROR_COMPONENT_FAILURE;
1218     }
1219     else if (reg[0] != MX25LM51245G_CR2_DOPI)
1220     {
1221       ret = BSP_ERROR_COMPONENT_FAILURE;
1222     }
1223     else
1224     {
1225       ret = BSP_ERROR_NONE;
1226     }
1227   }
1228 
1229   /* Return BSP status */
1230   return ret;
1231 }
1232 
1233 /**
1234   * @brief  This function enables the octal STR mode of the memory.
1235   * @param  Instance  OSPI instance
1236   * @retval BSP status
1237   */
OSPI_NOR_EnterSOPIMode(uint32_t Instance)1238 static int32_t OSPI_NOR_EnterSOPIMode(uint32_t Instance)
1239 {
1240   int32_t ret;
1241   uint8_t reg[2];
1242 
1243   /* Check if the instance is supported */
1244   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
1245   {
1246     ret = BSP_ERROR_WRONG_PARAM;
1247   }
1248   /* Enable write operations */
1249   else if (MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
1250   {
1251     ret = BSP_ERROR_COMPONENT_FAILURE;
1252   }
1253   /* Write Configuration register 2 (with new dummy cycles) */
1254   else if (MX25LM51245G_WriteCfg2Register(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_CR2_REG3_ADDR, MX25LM51245G_CR2_DC_6_CYCLES) != MX25LM51245G_OK)
1255   {
1256     ret = BSP_ERROR_COMPONENT_FAILURE;
1257   }
1258   /* Enable write operations */
1259   else if (MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
1260   {
1261     ret = BSP_ERROR_COMPONENT_FAILURE;
1262   }
1263   /* Write Configuration register 2 (with Octal I/O SPI protocol) */
1264   else if (MX25LM51245G_WriteCfg2Register(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_CR2_REG1_ADDR, MX25LM51245G_CR2_SOPI) != MX25LM51245G_OK)
1265   {
1266     ret = BSP_ERROR_COMPONENT_FAILURE;
1267   }
1268   else
1269   {
1270     /* Wait that the configuration is effective and check that memory is ready */
1271     HAL_Delay(MX25LM51245G_WRITE_REG_MAX_TIME);
1272 
1273     /* Check Flash busy ? */
1274     if (MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1275     {
1276       ret = BSP_ERROR_COMPONENT_FAILURE;
1277     }
1278     /* Check the configuration has been correctly done */
1279     else if (MX25LM51245G_ReadCfg2Register(&hospi_nor[Instance], BSP_OSPI_NOR_OPI_MODE, BSP_OSPI_NOR_STR_TRANSFER, MX25LM51245G_CR2_REG1_ADDR, reg) != MX25LM51245G_OK)
1280     {
1281       ret = BSP_ERROR_COMPONENT_FAILURE;
1282     }
1283     else if (reg[0] != MX25LM51245G_CR2_SOPI)
1284     {
1285       ret = BSP_ERROR_COMPONENT_FAILURE;
1286     }
1287     else
1288     {
1289       ret = BSP_ERROR_NONE;
1290     }
1291   }
1292 
1293   /* Return BSP status */
1294   return ret;
1295 }
1296 
1297 /**
1298   * @brief  This function disables the octal DTR or STR mode of the memory.
1299   * @param  Instance  OSPI instance
1300   * @retval BSP status
1301   */
OSPI_NOR_ExitOPIMode(uint32_t Instance)1302 static int32_t OSPI_NOR_ExitOPIMode (uint32_t Instance)
1303 {
1304   int32_t ret = BSP_ERROR_NONE;
1305   uint8_t reg[2];
1306 
1307   /* Check if the instance is supported */
1308   if(Instance >= OSPI_NOR_INSTANCES_NUMBER)
1309   {
1310     ret = BSP_ERROR_WRONG_PARAM;
1311   }
1312   /* Enable write operations */
1313   else if (MX25LM51245G_WriteEnable(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate) != MX25LM51245G_OK)
1314   {
1315     ret = BSP_ERROR_COMPONENT_FAILURE;
1316   }
1317   else
1318   {
1319     /* Write Configuration register 2 (with SPI protocol) */
1320     reg[0] = 0;
1321     reg[1] = 0;
1322     if (MX25LM51245G_WriteCfg2Register(&hospi_nor[Instance], Ospi_Nor_Ctx[Instance].InterfaceMode, Ospi_Nor_Ctx[Instance].TransferRate, MX25LM51245G_CR2_REG1_ADDR, reg[0]) != MX25LM51245G_OK)
1323     {
1324       ret = BSP_ERROR_COMPONENT_FAILURE;
1325     }
1326     else
1327     {
1328       /* Wait that the configuration is effective and check that memory is ready */
1329       HAL_Delay(MX25LM51245G_WRITE_REG_MAX_TIME);
1330 
1331       if (Ospi_Nor_Ctx[Instance].TransferRate == BSP_OSPI_NOR_DTR_TRANSFER)
1332       {
1333         /* Reconfigure the memory type of the peripheral */
1334         hospi_nor[Instance].Init.MemoryType            = HAL_OSPI_MEMTYPE_MICRON;
1335         hospi_nor[Instance].Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
1336         if (HAL_OSPI_Init(&hospi_nor[Instance]) != HAL_OK)
1337         {
1338           ret = BSP_ERROR_PERIPH_FAILURE;
1339         }
1340       }
1341 
1342       if (ret == BSP_ERROR_NONE)
1343       {
1344         /* Check Flash busy ? */
1345         if (MX25LM51245G_AutoPollingMemReady(&hospi_nor[Instance], BSP_OSPI_NOR_SPI_MODE, BSP_OSPI_NOR_STR_TRANSFER) != MX25LM51245G_OK)
1346         {
1347           ret = BSP_ERROR_COMPONENT_FAILURE;
1348         }
1349         /* Check the configuration has been correctly done */
1350         else if (MX25LM51245G_ReadCfg2Register(&hospi_nor[Instance], BSP_OSPI_NOR_SPI_MODE, BSP_OSPI_NOR_STR_TRANSFER, MX25LM51245G_CR2_REG1_ADDR, reg) != MX25LM51245G_OK)
1351         {
1352           ret = BSP_ERROR_COMPONENT_FAILURE;
1353         }
1354         else if (reg[0] != 0U)
1355         {
1356           ret = BSP_ERROR_COMPONENT_FAILURE;
1357         }
1358         else
1359         {
1360           /* Nothing to do */
1361         }
1362       }
1363     }
1364   }
1365 
1366   /* Return BSP status */
1367   return ret;
1368 }
1369 
1370 /**
1371   * @}
1372   */
1373 
1374 /**
1375   * @}
1376   */
1377 
1378 /**
1379   * @}
1380   */
1381 
1382 /**
1383   * @}
1384   */
1385 
1386 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1387 
1388