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