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>© 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