1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_sram.c
4   * @author  MCD Application Team
5   * @brief   SRAM HAL module driver.
6   *          This file provides a generic firmware to drive SRAM memories
7   *          mounted as external device.
8   *
9   ******************************************************************************
10   * @attention
11   *
12   * Copyright (c) 2021 STMicroelectronics.
13   * All rights reserved.
14   *
15   * This software is licensed under terms that can be found in the LICENSE file
16   * in the root directory of this software component.
17   * If no LICENSE file comes with this software, it is provided AS-IS.
18   *
19   ******************************************************************************
20   @verbatim
21   ==============================================================================
22                           ##### How to use this driver #####
23   ==============================================================================
24   [..]
25     This driver is a generic layered driver which contains a set of APIs used to
26     control SRAM memories. It uses the FMC layer functions to interface
27     with SRAM devices.
28     The following sequence should be followed to configure the FMC to interface
29     with SRAM/PSRAM memories:
30 
31    (#) Declare a SRAM_HandleTypeDef handle structure, for example:
32           SRAM_HandleTypeDef  hsram; and:
33 
34        (++) Fill the SRAM_HandleTypeDef handle "Init" field with the allowed
35             values of the structure member.
36 
37        (++) Fill the SRAM_HandleTypeDef handle "Instance" field with a predefined
38             base register instance for NOR or SRAM device
39 
40        (++) Fill the SRAM_HandleTypeDef handle "Extended" field with a predefined
41             base register instance for NOR or SRAM extended mode
42 
43    (#) Declare two FMC_NORSRAM_TimingTypeDef structures, for both normal and extended
44        mode timings; for example:
45           FMC_NORSRAM_TimingTypeDef  Timing and FMC_NORSRAM_TimingTypeDef  ExTiming;
46       and fill its fields with the allowed values of the structure member.
47 
48    (#) Initialize the SRAM Controller by calling the function HAL_SRAM_Init(). This function
49        performs the following sequence:
50 
51        (##) MSP hardware layer configuration using the function HAL_SRAM_MspInit()
52        (##) Control register configuration using the FMC NORSRAM interface function
53             FMC_NORSRAM_Init()
54        (##) Timing register configuration using the FMC NORSRAM interface function
55             FMC_NORSRAM_Timing_Init()
56        (##) Extended mode Timing register configuration using the FMC NORSRAM interface function
57             FMC_NORSRAM_Extended_Timing_Init()
58        (##) Enable the SRAM device using the macro __FMC_NORSRAM_ENABLE()
59 
60    (#) At this stage you can perform read/write accesses from/to the memory connected
61        to the NOR/SRAM Bank. You can perform either polling or DMA transfer using the
62        following APIs:
63        (++) HAL_SRAM_Read()/HAL_SRAM_Write() for polling read/write access
64        (++) HAL_SRAM_Read_DMA()/HAL_SRAM_Write_DMA() for DMA read/write transfer
65 
66    (#) You can also control the SRAM device by calling the control APIs HAL_SRAM_WriteOperation_Enable()/
67        HAL_SRAM_WriteOperation_Disable() to respectively enable/disable the SRAM write operation
68 
69    (#) You can continuously monitor the SRAM device HAL state by calling the function
70        HAL_SRAM_GetState()
71 
72        *** Callback registration ***
73     =============================================
74     [..]
75       The compilation define  USE_HAL_SRAM_REGISTER_CALLBACKS when set to 1
76       allows the user to configure dynamically the driver callbacks.
77 
78       Use Functions HAL_SRAM_RegisterCallback() to register a user callback,
79       it allows to register following callbacks:
80         (+) MspInitCallback    : SRAM MspInit.
81         (+) MspDeInitCallback  : SRAM MspDeInit.
82       This function takes as parameters the HAL peripheral handle, the Callback ID
83       and a pointer to the user callback function.
84 
85       Use function HAL_SRAM_UnRegisterCallback() to reset a callback to the default
86       weak (overridden) function. It allows to reset following callbacks:
87         (+) MspInitCallback    : SRAM MspInit.
88         (+) MspDeInitCallback  : SRAM MspDeInit.
89       This function) takes as parameters the HAL peripheral handle and the Callback ID.
90 
91       By default, after the HAL_SRAM_Init and if the state is HAL_SRAM_STATE_RESET
92       all callbacks are reset to the corresponding legacy weak (overridden) functions.
93       Exception done for MspInit and MspDeInit callbacks that are respectively
94       reset to the legacy weak (overridden) functions in the HAL_SRAM_Init
95       and  HAL_SRAM_DeInit only when these callbacks are null (not registered beforehand).
96       If not, MspInit or MspDeInit are not null, the HAL_SRAM_Init and HAL_SRAM_DeInit
97       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
98 
99       Callbacks can be registered/unregistered in READY state only.
100       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
101       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
102       during the Init/DeInit.
103       In that case first register the MspInit/MspDeInit user callbacks
104       using HAL_SRAM_RegisterCallback before calling HAL_SRAM_DeInit
105       or HAL_SRAM_Init function.
106 
107       When The compilation define USE_HAL_SRAM_REGISTER_CALLBACKS is set to 0 or
108       not defined, the callback registering feature is not available
109       and weak (overridden) callbacks are used.
110 
111   @endverbatim
112   ******************************************************************************
113   */
114 
115 /* Includes ------------------------------------------------------------------*/
116 #include "stm32u5xx_hal.h"
117 
118 
119 /** @addtogroup STM32U5xx_HAL_Driver
120   * @{
121   */
122 
123 #ifdef HAL_SRAM_MODULE_ENABLED
124 
125 /** @defgroup SRAM SRAM
126   * @brief SRAM driver modules
127   * @{
128   */
129 
130 /* Private typedef -----------------------------------------------------------*/
131 /* Private define ------------------------------------------------------------*/
132 /* Private macro -------------------------------------------------------------*/
133 /* Private variables ---------------------------------------------------------*/
134 /* Private function prototypes -----------------------------------------------*/
135 /** @addtogroup SRAM_Private_Functions SRAM Private Functions
136   * @{
137   */
138 static void SRAM_DMACplt(DMA_HandleTypeDef *hdma);
139 static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma);
140 static void SRAM_DMAError(DMA_HandleTypeDef *hdma);
141 /**
142   * @}
143   */
144 
145 /* Exported functions --------------------------------------------------------*/
146 
147 /** @defgroup SRAM_Exported_Functions SRAM Exported Functions
148   * @{
149   */
150 
151 /** @defgroup SRAM_Exported_Functions_Group1 Initialization and de-initialization functions
152   * @brief    Initialization and Configuration functions.
153   *
154   @verbatim
155   ==============================================================================
156            ##### SRAM Initialization and de_initialization functions #####
157   ==============================================================================
158     [..]  This section provides functions allowing to initialize/de-initialize
159           the SRAM memory
160 
161 @endverbatim
162   * @{
163   */
164 
165 /**
166   * @brief  Performs the SRAM device initialization sequence
167   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
168   *                the configuration information for SRAM module.
169   * @param  Timing Pointer to SRAM control timing structure
170   * @param  ExtTiming Pointer to SRAM extended mode timing structure
171   * @retval HAL status
172   */
HAL_SRAM_Init(SRAM_HandleTypeDef * hsram,FMC_NORSRAM_TimingTypeDef * Timing,FMC_NORSRAM_TimingTypeDef * ExtTiming)173 HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram, FMC_NORSRAM_TimingTypeDef *Timing,
174                                 FMC_NORSRAM_TimingTypeDef *ExtTiming)
175 {
176   /* Check the SRAM handle parameter */
177   if (hsram == NULL)
178   {
179     return HAL_ERROR;
180   }
181 
182   if (hsram->State == HAL_SRAM_STATE_RESET)
183   {
184     /* Allocate lock resource and initialize it */
185     hsram->Lock = HAL_UNLOCKED;
186 
187 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
188     if (hsram->MspInitCallback == NULL)
189     {
190       hsram->MspInitCallback = HAL_SRAM_MspInit;
191     }
192     hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
193     hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
194 
195     /* Init the low level hardware */
196     hsram->MspInitCallback(hsram);
197 #else
198     /* Initialize the low level hardware (MSP) */
199     HAL_SRAM_MspInit(hsram);
200 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
201   }
202 
203   /* Initialize SRAM control Interface */
204   (void)FMC_NORSRAM_Init(hsram->Instance, &(hsram->Init));
205 
206   /* Initialize SRAM timing Interface */
207   (void)FMC_NORSRAM_Timing_Init(hsram->Instance, Timing, hsram->Init.NSBank);
208 
209   /* Initialize SRAM extended mode timing Interface */
210   (void)FMC_NORSRAM_Extended_Timing_Init(hsram->Extended, ExtTiming, hsram->Init.NSBank,
211                                          hsram->Init.ExtendedMode);
212 
213   /* Enable the NORSRAM device */
214   __FMC_NORSRAM_ENABLE(hsram->Instance, hsram->Init.NSBank);
215 
216   /* Enable FMC Peripheral */
217   __FMC_ENABLE();
218 
219   /* Initialize the SRAM controller state */
220   hsram->State = HAL_SRAM_STATE_READY;
221 
222   return HAL_OK;
223 }
224 
225 /**
226   * @brief  Performs the SRAM device De-initialization sequence.
227   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
228   *                the configuration information for SRAM module.
229   * @retval HAL status
230   */
HAL_SRAM_DeInit(SRAM_HandleTypeDef * hsram)231 HAL_StatusTypeDef HAL_SRAM_DeInit(SRAM_HandleTypeDef *hsram)
232 {
233 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
234   if (hsram->MspDeInitCallback == NULL)
235   {
236     hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
237   }
238 
239   /* DeInit the low level hardware */
240   hsram->MspDeInitCallback(hsram);
241 #else
242   /* De-Initialize the low level hardware (MSP) */
243   HAL_SRAM_MspDeInit(hsram);
244 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
245 
246   /* Configure the SRAM registers with their reset values */
247   (void)FMC_NORSRAM_DeInit(hsram->Instance, hsram->Extended, hsram->Init.NSBank);
248 
249   /* Reset the SRAM controller state */
250   hsram->State = HAL_SRAM_STATE_RESET;
251 
252   /* Release Lock */
253   __HAL_UNLOCK(hsram);
254 
255   return HAL_OK;
256 }
257 
258 /**
259   * @brief  SRAM MSP Init.
260   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
261   *                the configuration information for SRAM module.
262   * @retval None
263   */
HAL_SRAM_MspInit(SRAM_HandleTypeDef * hsram)264 __weak void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
265 {
266   /* Prevent unused argument(s) compilation warning */
267   UNUSED(hsram);
268 
269   /* NOTE : This function Should not be modified, when the callback is needed,
270             the HAL_SRAM_MspInit could be implemented in the user file
271    */
272 }
273 
274 /**
275   * @brief  SRAM MSP DeInit.
276   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
277   *                the configuration information for SRAM module.
278   * @retval None
279   */
HAL_SRAM_MspDeInit(SRAM_HandleTypeDef * hsram)280 __weak void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef *hsram)
281 {
282   /* Prevent unused argument(s) compilation warning */
283   UNUSED(hsram);
284 
285   /* NOTE : This function Should not be modified, when the callback is needed,
286             the HAL_SRAM_MspDeInit could be implemented in the user file
287    */
288 }
289 
290 /**
291   * @brief  DMA transfer complete callback.
292   * @param  hdma pointer to a SRAM_HandleTypeDef structure that contains
293   *                the configuration information for SRAM module.
294   * @retval None
295   */
HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef * hdma)296 __weak void HAL_SRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
297 {
298   /* Prevent unused argument(s) compilation warning */
299   UNUSED(hdma);
300 
301   /* NOTE : This function Should not be modified, when the callback is needed,
302             the HAL_SRAM_DMA_XferCpltCallback could be implemented in the user file
303    */
304 }
305 
306 /**
307   * @brief  DMA transfer complete error callback.
308   * @param  hdma pointer to a SRAM_HandleTypeDef structure that contains
309   *                the configuration information for SRAM module.
310   * @retval None
311   */
HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef * hdma)312 __weak void HAL_SRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
313 {
314   /* Prevent unused argument(s) compilation warning */
315   UNUSED(hdma);
316 
317   /* NOTE : This function Should not be modified, when the callback is needed,
318             the HAL_SRAM_DMA_XferErrorCallback could be implemented in the user file
319    */
320 }
321 
322 /**
323   * @}
324   */
325 
326 /** @defgroup SRAM_Exported_Functions_Group2 Input Output and memory control functions
327   * @brief    Input Output and memory control functions
328   *
329   @verbatim
330   ==============================================================================
331                   ##### SRAM Input and Output functions #####
332   ==============================================================================
333   [..]
334     This section provides functions allowing to use and control the SRAM memory
335 
336 @endverbatim
337   * @{
338   */
339 
340 /**
341   * @brief  Reads 8-bit buffer from SRAM memory.
342   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
343   *                the configuration information for SRAM module.
344   * @param  pAddress Pointer to read start address
345   * @param  pDstBuffer Pointer to destination buffer
346   * @param  BufferSize Size of the buffer to read from memory
347   * @retval HAL status
348   */
HAL_SRAM_Read_8b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint8_t * pDstBuffer,uint32_t BufferSize)349 HAL_StatusTypeDef HAL_SRAM_Read_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pDstBuffer,
350                                    uint32_t BufferSize)
351 {
352   uint32_t size;
353   __IO uint8_t *psramaddress = (uint8_t *)pAddress;
354   uint8_t *pdestbuff = pDstBuffer;
355   HAL_SRAM_StateTypeDef state = hsram->State;
356 
357   /* Check the SRAM controller state */
358   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
359   {
360     /* Process Locked */
361     __HAL_LOCK(hsram);
362 
363     /* Update the SRAM controller state */
364     hsram->State = HAL_SRAM_STATE_BUSY;
365 
366     /* Read data from memory */
367     for (size = BufferSize; size != 0U; size--)
368     {
369       *pdestbuff = *psramaddress;
370       pdestbuff++;
371       psramaddress++;
372     }
373 
374     /* Update the SRAM controller state */
375     hsram->State = state;
376 
377     /* Process unlocked */
378     __HAL_UNLOCK(hsram);
379   }
380   else
381   {
382     return HAL_ERROR;
383   }
384 
385   return HAL_OK;
386 }
387 
388 /**
389   * @brief  Writes 8-bit buffer to SRAM memory.
390   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
391   *                the configuration information for SRAM module.
392   * @param  pAddress Pointer to write start address
393   * @param  pSrcBuffer Pointer to source buffer to write
394   * @param  BufferSize Size of the buffer to write to memory
395   * @retval HAL status
396   */
HAL_SRAM_Write_8b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint8_t * pSrcBuffer,uint32_t BufferSize)397 HAL_StatusTypeDef HAL_SRAM_Write_8b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint8_t *pSrcBuffer,
398                                     uint32_t BufferSize)
399 {
400   uint32_t size;
401   __IO uint8_t *psramaddress = (uint8_t *)pAddress;
402   uint8_t *psrcbuff = pSrcBuffer;
403 
404   /* Check the SRAM controller state */
405   if (hsram->State == HAL_SRAM_STATE_READY)
406   {
407     /* Process Locked */
408     __HAL_LOCK(hsram);
409 
410     /* Update the SRAM controller state */
411     hsram->State = HAL_SRAM_STATE_BUSY;
412 
413     /* Write data to memory */
414     for (size = BufferSize; size != 0U; size--)
415     {
416       *psramaddress = *psrcbuff;
417       psrcbuff++;
418       psramaddress++;
419     }
420 
421     /* Update the SRAM controller state */
422     hsram->State = HAL_SRAM_STATE_READY;
423 
424     /* Process unlocked */
425     __HAL_UNLOCK(hsram);
426   }
427   else
428   {
429     return HAL_ERROR;
430   }
431 
432   return HAL_OK;
433 }
434 
435 /**
436   * @brief  Reads 16-bit buffer from SRAM memory.
437   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
438   *                the configuration information for SRAM module.
439   * @param  pAddress Pointer to read start address
440   * @param  pDstBuffer Pointer to destination buffer
441   * @param  BufferSize Size of the buffer to read from memory
442   * @retval HAL status
443   */
HAL_SRAM_Read_16b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint16_t * pDstBuffer,uint32_t BufferSize)444 HAL_StatusTypeDef HAL_SRAM_Read_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pDstBuffer,
445                                     uint32_t BufferSize)
446 {
447   uint32_t size;
448   __IO uint32_t *psramaddress = pAddress;
449   uint16_t *pdestbuff = pDstBuffer;
450   uint8_t limit;
451   HAL_SRAM_StateTypeDef state = hsram->State;
452 
453   /* Check the SRAM controller state */
454   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
455   {
456     /* Process Locked */
457     __HAL_LOCK(hsram);
458 
459     /* Update the SRAM controller state */
460     hsram->State = HAL_SRAM_STATE_BUSY;
461 
462     /* Check if the size is a 32-bits multiple */
463     limit = (((BufferSize % 2U) != 0U) ? 1U : 0U);
464 
465     /* Read data from memory */
466     for (size = BufferSize; size != limit; size -= 2U)
467     {
468       *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU);
469       pdestbuff++;
470       *pdestbuff = (uint16_t)(((*psramaddress) & 0xFFFF0000U) >> 16U);
471       pdestbuff++;
472       psramaddress++;
473     }
474 
475     /* Read last 16-bits if size is not 32-bits multiple */
476     if (limit != 0U)
477     {
478       *pdestbuff = (uint16_t)((*psramaddress) & 0x0000FFFFU);
479     }
480 
481     /* Update the SRAM controller state */
482     hsram->State = state;
483 
484     /* Process unlocked */
485     __HAL_UNLOCK(hsram);
486   }
487   else
488   {
489     return HAL_ERROR;
490   }
491 
492   return HAL_OK;
493 }
494 
495 /**
496   * @brief  Writes 16-bit buffer to SRAM memory.
497   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
498   *                the configuration information for SRAM module.
499   * @param  pAddress Pointer to write start address
500   * @param  pSrcBuffer Pointer to source buffer to write
501   * @param  BufferSize Size of the buffer to write to memory
502   * @retval HAL status
503   */
HAL_SRAM_Write_16b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint16_t * pSrcBuffer,uint32_t BufferSize)504 HAL_StatusTypeDef HAL_SRAM_Write_16b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint16_t *pSrcBuffer,
505                                      uint32_t BufferSize)
506 {
507   uint32_t size;
508   __IO uint32_t *psramaddress = pAddress;
509   uint16_t *psrcbuff = pSrcBuffer;
510   uint8_t limit;
511 
512   /* Check the SRAM controller state */
513   if (hsram->State == HAL_SRAM_STATE_READY)
514   {
515     /* Process Locked */
516     __HAL_LOCK(hsram);
517 
518     /* Update the SRAM controller state */
519     hsram->State = HAL_SRAM_STATE_BUSY;
520 
521     /* Check if the size is a 32-bits multiple */
522     limit = (((BufferSize % 2U) != 0U) ? 1U : 0U);
523 
524     /* Write data to memory */
525     for (size = BufferSize; size != limit; size -= 2U)
526     {
527       *psramaddress = (uint32_t)(*psrcbuff);
528       psrcbuff++;
529       *psramaddress |= ((uint32_t)(*psrcbuff) << 16U);
530       psrcbuff++;
531       psramaddress++;
532     }
533 
534     /* Write last 16-bits if size is not 32-bits multiple */
535     if (limit != 0U)
536     {
537       *psramaddress = ((uint32_t)(*psrcbuff) & 0x0000FFFFU) | ((*psramaddress) & 0xFFFF0000U);
538     }
539 
540     /* Update the SRAM controller state */
541     hsram->State = HAL_SRAM_STATE_READY;
542 
543     /* Process unlocked */
544     __HAL_UNLOCK(hsram);
545   }
546   else
547   {
548     return HAL_ERROR;
549   }
550 
551   return HAL_OK;
552 }
553 
554 /**
555   * @brief  Reads 32-bit buffer from SRAM memory.
556   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
557   *                the configuration information for SRAM module.
558   * @param  pAddress Pointer to read start address
559   * @param  pDstBuffer Pointer to destination buffer
560   * @param  BufferSize Size of the buffer to read from memory
561   * @retval HAL status
562   */
HAL_SRAM_Read_32b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint32_t * pDstBuffer,uint32_t BufferSize)563 HAL_StatusTypeDef HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
564                                     uint32_t BufferSize)
565 {
566   uint32_t size;
567   __IO uint32_t *psramaddress = pAddress;
568   uint32_t *pdestbuff = pDstBuffer;
569   HAL_SRAM_StateTypeDef state = hsram->State;
570 
571   /* Check the SRAM controller state */
572   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
573   {
574     /* Process Locked */
575     __HAL_LOCK(hsram);
576 
577     /* Update the SRAM controller state */
578     hsram->State = HAL_SRAM_STATE_BUSY;
579 
580     /* Read data from memory */
581     for (size = BufferSize; size != 0U; size--)
582     {
583       *pdestbuff = *psramaddress;
584       pdestbuff++;
585       psramaddress++;
586     }
587 
588     /* Update the SRAM controller state */
589     hsram->State = state;
590 
591     /* Process unlocked */
592     __HAL_UNLOCK(hsram);
593   }
594   else
595   {
596     return HAL_ERROR;
597   }
598 
599   return HAL_OK;
600 }
601 
602 /**
603   * @brief  Writes 32-bit buffer to SRAM memory.
604   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
605   *                the configuration information for SRAM module.
606   * @param  pAddress Pointer to write start address
607   * @param  pSrcBuffer Pointer to source buffer to write
608   * @param  BufferSize Size of the buffer to write to memory
609   * @retval HAL status
610   */
HAL_SRAM_Write_32b(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint32_t * pSrcBuffer,uint32_t BufferSize)611 HAL_StatusTypeDef HAL_SRAM_Write_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
612                                      uint32_t BufferSize)
613 {
614   uint32_t size;
615   __IO uint32_t *psramaddress = pAddress;
616   uint32_t *psrcbuff = pSrcBuffer;
617 
618   /* Check the SRAM controller state */
619   if (hsram->State == HAL_SRAM_STATE_READY)
620   {
621     /* Process Locked */
622     __HAL_LOCK(hsram);
623 
624     /* Update the SRAM controller state */
625     hsram->State = HAL_SRAM_STATE_BUSY;
626 
627     /* Write data to memory */
628     for (size = BufferSize; size != 0U; size--)
629     {
630       *psramaddress = *psrcbuff;
631       psrcbuff++;
632       psramaddress++;
633     }
634 
635     /* Update the SRAM controller state */
636     hsram->State = HAL_SRAM_STATE_READY;
637 
638     /* Process unlocked */
639     __HAL_UNLOCK(hsram);
640   }
641   else
642   {
643     return HAL_ERROR;
644   }
645 
646   return HAL_OK;
647 }
648 
649 /**
650   * @brief  Reads a Words data from the SRAM memory using DMA transfer.
651   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
652   *                the configuration information for SRAM module.
653   * @param  pAddress Pointer to read start address
654   * @param  pDstBuffer Pointer to destination buffer
655   * @param  BufferSize Size of the buffer to read from memory
656   * @retval HAL status
657   */
HAL_SRAM_Read_DMA(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint32_t * pDstBuffer,uint32_t BufferSize)658 HAL_StatusTypeDef HAL_SRAM_Read_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer,
659                                     uint32_t BufferSize)
660 {
661   HAL_StatusTypeDef status;
662   HAL_SRAM_StateTypeDef state = hsram->State;
663   uint32_t size;
664   uint32_t data_width;
665 
666   /* Check the SRAM controller state */
667   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
668   {
669     /* Process Locked */
670     __HAL_LOCK(hsram);
671 
672     /* Update the SRAM controller state */
673     hsram->State = HAL_SRAM_STATE_BUSY;
674 
675     /* Configure DMA user callbacks */
676     if (state == HAL_SRAM_STATE_READY)
677     {
678       hsram->hdma->XferCpltCallback = SRAM_DMACplt;
679     }
680     else
681     {
682       hsram->hdma->XferCpltCallback = SRAM_DMACpltProt;
683     }
684     hsram->hdma->XferErrorCallback = SRAM_DMAError;
685 
686     if ((hsram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
687     {
688       if ((hsram->hdma->LinkedListQueue != 0U) && (hsram->hdma->LinkedListQueue->Head != 0U))
689       {
690         /* Check destination data width and set the size to be transferred */
691         data_width = hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
692 
693         if (data_width == DMA_DEST_DATAWIDTH_WORD)
694         {
695           size = (BufferSize * 4U);
696         }
697         else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
698         {
699           size = (BufferSize * 2U);
700         }
701         else
702         {
703           size = (BufferSize);
704         }
705         /* Set Source , destination , buffer size */
706         /* Set DMA data size */
707         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size;
708         /* Set DMA source address */
709         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pAddress;
710         /* Set DMA destination address */
711         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pDstBuffer;
712 
713         /* Enable the DMA Stream */
714         status = HAL_DMAEx_List_Start_IT(hsram->hdma);
715       }
716       else
717       {
718         /* Change SRAM state */
719         hsram->State = HAL_SRAM_STATE_READY;
720 
721         __HAL_UNLOCK(hsram);
722 
723         status = HAL_ERROR;
724       }
725     }
726     else
727     {
728       /* Check destination data width and set the size to be transferred */
729       data_width = hsram->hdma->Init.DestDataWidth;
730 
731       if (data_width == DMA_DEST_DATAWIDTH_WORD)
732       {
733         size = (BufferSize * 4U);
734       }
735       else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
736       {
737         size = (BufferSize * 2U);
738       }
739       else
740       {
741         size = (BufferSize);
742       }
743 
744       /* Enable the DMA Stream */
745       status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, size);
746     }
747 
748     /* Process unlocked */
749     __HAL_UNLOCK(hsram);
750   }
751   else
752   {
753     status = HAL_ERROR;
754   }
755 
756   return status;
757 }
758 
759 /**
760   * @brief  Writes a Words data buffer to SRAM memory using DMA transfer.
761   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
762   *                the configuration information for SRAM module.
763   * @param  pAddress Pointer to write start address
764   * @param  pSrcBuffer Pointer to source buffer to write
765   * @param  BufferSize Size of the buffer to write to memory
766   * @retval HAL status
767   */
HAL_SRAM_Write_DMA(SRAM_HandleTypeDef * hsram,uint32_t * pAddress,uint32_t * pSrcBuffer,uint32_t BufferSize)768 HAL_StatusTypeDef HAL_SRAM_Write_DMA(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pSrcBuffer,
769                                      uint32_t BufferSize)
770 {
771   HAL_StatusTypeDef status;
772   uint32_t size;
773   uint32_t data_width;
774 
775   /* Check the SRAM controller state */
776   if (hsram->State == HAL_SRAM_STATE_READY)
777   {
778     /* Process Locked */
779     __HAL_LOCK(hsram);
780 
781     /* Update the SRAM controller state */
782     hsram->State = HAL_SRAM_STATE_BUSY;
783 
784     /* Configure DMA user callbacks */
785     hsram->hdma->XferCpltCallback = SRAM_DMACplt;
786     hsram->hdma->XferErrorCallback = SRAM_DMAError;
787 
788     if ((hsram->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
789     {
790       if ((hsram->hdma->LinkedListQueue != 0U) && (hsram->hdma->LinkedListQueue->Head != 0U))
791       {
792         /* Check destination data width and set the size to be transferred */
793         data_width = hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CTR1_DEFAULT_OFFSET] & DMA_CTR1_DDW_LOG2;
794 
795         if (data_width == DMA_DEST_DATAWIDTH_WORD)
796         {
797           size = (BufferSize * 4U);
798         }
799         else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
800         {
801           size = (BufferSize * 2U);
802         }
803         else
804         {
805           size = (BufferSize);
806         }
807         /* Set Source , destination , buffer size */
808         /* Set DMA data size */
809         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = size;
810         /* Set DMA source address */
811         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = (uint32_t)pSrcBuffer;
812         /* Set DMA destination address */
813         hsram->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = (uint32_t)pAddress;
814         /* Enable the DMA Stream */
815         status = HAL_DMAEx_List_Start_IT(hsram->hdma);
816       }
817       else
818       {
819         /* Change SRAM state */
820         hsram->State = HAL_SRAM_STATE_READY;
821 
822         __HAL_UNLOCK(hsram);
823 
824         status = HAL_ERROR;
825       }
826     }
827     else
828     {
829       /* Check destination data width and set the size to be transferred */
830       data_width = hsram->hdma->Init.DestDataWidth;
831 
832       if (data_width == DMA_DEST_DATAWIDTH_WORD)
833       {
834         size = (BufferSize * 4U);
835       }
836       else if (data_width == DMA_DEST_DATAWIDTH_HALFWORD)
837       {
838         size = (BufferSize * 2U);
839       }
840       else
841       {
842         size = (BufferSize);
843       }
844 
845       /* Enable the DMA Stream */
846       status = HAL_DMA_Start_IT(hsram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, size);
847     }
848 
849     /* Process unlocked */
850     __HAL_UNLOCK(hsram);
851   }
852   else
853   {
854     status = HAL_ERROR;
855   }
856 
857   return status;
858 }
859 
860 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
861 /**
862   * @brief  Register a User SRAM Callback
863   *         To be used to override the weak predefined callback
864   * @param hsram : SRAM handle
865   * @param CallbackId : ID of the callback to be registered
866   *        This parameter can be one of the following values:
867   *          @arg @ref HAL_SRAM_MSP_INIT_CB_ID       SRAM MspInit callback ID
868   *          @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID     SRAM MspDeInit callback ID
869   * @param pCallback : pointer to the Callback function
870   * @retval status
871   */
HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef * hsram,HAL_SRAM_CallbackIDTypeDef CallbackId,pSRAM_CallbackTypeDef pCallback)872 HAL_StatusTypeDef HAL_SRAM_RegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
873                                             pSRAM_CallbackTypeDef pCallback)
874 {
875   HAL_StatusTypeDef status = HAL_OK;
876   HAL_SRAM_StateTypeDef state;
877 
878   if (pCallback == NULL)
879   {
880     return HAL_ERROR;
881   }
882 
883   state = hsram->State;
884   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_RESET) || (state == HAL_SRAM_STATE_PROTECTED))
885   {
886     switch (CallbackId)
887     {
888       case HAL_SRAM_MSP_INIT_CB_ID :
889         hsram->MspInitCallback = pCallback;
890         break;
891       case HAL_SRAM_MSP_DEINIT_CB_ID :
892         hsram->MspDeInitCallback = pCallback;
893         break;
894       default :
895         /* update return status */
896         status =  HAL_ERROR;
897         break;
898     }
899   }
900   else
901   {
902     /* update return status */
903     status =  HAL_ERROR;
904   }
905 
906   return status;
907 }
908 
909 /**
910   * @brief  Unregister a User SRAM Callback
911   *         SRAM Callback is redirected to the weak predefined callback
912   * @param hsram : SRAM handle
913   * @param CallbackId : ID of the callback to be unregistered
914   *        This parameter can be one of the following values:
915   *          @arg @ref HAL_SRAM_MSP_INIT_CB_ID       SRAM MspInit callback ID
916   *          @arg @ref HAL_SRAM_MSP_DEINIT_CB_ID     SRAM MspDeInit callback ID
917   *          @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID  SRAM DMA Xfer Complete callback ID
918   *          @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID   SRAM DMA Xfer Error callback ID
919   * @retval status
920   */
HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef * hsram,HAL_SRAM_CallbackIDTypeDef CallbackId)921 HAL_StatusTypeDef HAL_SRAM_UnRegisterCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId)
922 {
923   HAL_StatusTypeDef status = HAL_OK;
924   HAL_SRAM_StateTypeDef state;
925 
926   state = hsram->State;
927   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
928   {
929     switch (CallbackId)
930     {
931       case HAL_SRAM_MSP_INIT_CB_ID :
932         hsram->MspInitCallback = HAL_SRAM_MspInit;
933         break;
934       case HAL_SRAM_MSP_DEINIT_CB_ID :
935         hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
936         break;
937       case HAL_SRAM_DMA_XFER_CPLT_CB_ID :
938         hsram->DmaXferCpltCallback = HAL_SRAM_DMA_XferCpltCallback;
939         break;
940       case HAL_SRAM_DMA_XFER_ERR_CB_ID :
941         hsram->DmaXferErrorCallback = HAL_SRAM_DMA_XferErrorCallback;
942         break;
943       default :
944         /* update return status */
945         status =  HAL_ERROR;
946         break;
947     }
948   }
949   else if (state == HAL_SRAM_STATE_RESET)
950   {
951     switch (CallbackId)
952     {
953       case HAL_SRAM_MSP_INIT_CB_ID :
954         hsram->MspInitCallback = HAL_SRAM_MspInit;
955         break;
956       case HAL_SRAM_MSP_DEINIT_CB_ID :
957         hsram->MspDeInitCallback = HAL_SRAM_MspDeInit;
958         break;
959       default :
960         /* update return status */
961         status =  HAL_ERROR;
962         break;
963     }
964   }
965   else
966   {
967     /* update return status */
968     status =  HAL_ERROR;
969   }
970 
971   return status;
972 }
973 
974 /**
975   * @brief  Register a User SRAM Callback for DMA transfers
976   *         To be used to override the weak predefined callback
977   * @param hsram : SRAM handle
978   * @param CallbackId : ID of the callback to be registered
979   *        This parameter can be one of the following values:
980   *          @arg @ref HAL_SRAM_DMA_XFER_CPLT_CB_ID  SRAM DMA Xfer Complete callback ID
981   *          @arg @ref HAL_SRAM_DMA_XFER_ERR_CB_ID   SRAM DMA Xfer Error callback ID
982   * @param pCallback : pointer to the Callback function
983   * @retval status
984   */
HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef * hsram,HAL_SRAM_CallbackIDTypeDef CallbackId,pSRAM_DmaCallbackTypeDef pCallback)985 HAL_StatusTypeDef HAL_SRAM_RegisterDmaCallback(SRAM_HandleTypeDef *hsram, HAL_SRAM_CallbackIDTypeDef CallbackId,
986                                                pSRAM_DmaCallbackTypeDef pCallback)
987 {
988   HAL_StatusTypeDef status = HAL_OK;
989   HAL_SRAM_StateTypeDef state;
990 
991   if (pCallback == NULL)
992   {
993     return HAL_ERROR;
994   }
995 
996   /* Process locked */
997   __HAL_LOCK(hsram);
998 
999   state = hsram->State;
1000   if ((state == HAL_SRAM_STATE_READY) || (state == HAL_SRAM_STATE_PROTECTED))
1001   {
1002     switch (CallbackId)
1003     {
1004       case HAL_SRAM_DMA_XFER_CPLT_CB_ID :
1005         hsram->DmaXferCpltCallback = pCallback;
1006         break;
1007       case HAL_SRAM_DMA_XFER_ERR_CB_ID :
1008         hsram->DmaXferErrorCallback = pCallback;
1009         break;
1010       default :
1011         /* update return status */
1012         status =  HAL_ERROR;
1013         break;
1014     }
1015   }
1016   else
1017   {
1018     /* update return status */
1019     status =  HAL_ERROR;
1020   }
1021 
1022   /* Release Lock */
1023   __HAL_UNLOCK(hsram);
1024   return status;
1025 }
1026 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
1027 
1028 /**
1029   * @}
1030   */
1031 
1032 /** @defgroup SRAM_Exported_Functions_Group3 Control functions
1033   *  @brief   Control functions
1034   *
1035 @verbatim
1036   ==============================================================================
1037                         ##### SRAM Control functions #####
1038   ==============================================================================
1039   [..]
1040     This subsection provides a set of functions allowing to control dynamically
1041     the SRAM interface.
1042 
1043 @endverbatim
1044   * @{
1045   */
1046 
1047 /**
1048   * @brief  Enables dynamically SRAM write operation.
1049   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
1050   *                the configuration information for SRAM module.
1051   * @retval HAL status
1052   */
HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef * hsram)1053 HAL_StatusTypeDef HAL_SRAM_WriteOperation_Enable(SRAM_HandleTypeDef *hsram)
1054 {
1055   /* Check the SRAM controller state */
1056   if (hsram->State == HAL_SRAM_STATE_PROTECTED)
1057   {
1058     /* Process Locked */
1059     __HAL_LOCK(hsram);
1060 
1061     /* Update the SRAM controller state */
1062     hsram->State = HAL_SRAM_STATE_BUSY;
1063 
1064     /* Enable write operation */
1065     (void)FMC_NORSRAM_WriteOperation_Enable(hsram->Instance, hsram->Init.NSBank);
1066 
1067     /* Update the SRAM controller state */
1068     hsram->State = HAL_SRAM_STATE_READY;
1069 
1070     /* Process unlocked */
1071     __HAL_UNLOCK(hsram);
1072   }
1073   else
1074   {
1075     return HAL_ERROR;
1076   }
1077 
1078   return HAL_OK;
1079 }
1080 
1081 /**
1082   * @brief  Disables dynamically SRAM write operation.
1083   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
1084   *                the configuration information for SRAM module.
1085   * @retval HAL status
1086   */
HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef * hsram)1087 HAL_StatusTypeDef HAL_SRAM_WriteOperation_Disable(SRAM_HandleTypeDef *hsram)
1088 {
1089   /* Check the SRAM controller state */
1090   if (hsram->State == HAL_SRAM_STATE_READY)
1091   {
1092     /* Process Locked */
1093     __HAL_LOCK(hsram);
1094 
1095     /* Update the SRAM controller state */
1096     hsram->State = HAL_SRAM_STATE_BUSY;
1097 
1098     /* Disable write operation */
1099     (void)FMC_NORSRAM_WriteOperation_Disable(hsram->Instance, hsram->Init.NSBank);
1100 
1101     /* Update the SRAM controller state */
1102     hsram->State = HAL_SRAM_STATE_PROTECTED;
1103 
1104     /* Process unlocked */
1105     __HAL_UNLOCK(hsram);
1106   }
1107   else
1108   {
1109     return HAL_ERROR;
1110   }
1111 
1112   return HAL_OK;
1113 }
1114 
1115 /**
1116   * @}
1117   */
1118 
1119 /** @defgroup SRAM_Exported_Functions_Group4 Peripheral State functions
1120   *  @brief   Peripheral State functions
1121   *
1122 @verbatim
1123   ==============================================================================
1124                       ##### SRAM State functions #####
1125   ==============================================================================
1126   [..]
1127     This subsection permits to get in run-time the status of the SRAM controller
1128     and the data flow.
1129 
1130 @endverbatim
1131   * @{
1132   */
1133 
1134 /**
1135   * @brief  Returns the SRAM controller state
1136   * @param  hsram pointer to a SRAM_HandleTypeDef structure that contains
1137   *                the configuration information for SRAM module.
1138   * @retval HAL state
1139   */
HAL_SRAM_GetState(const SRAM_HandleTypeDef * hsram)1140 HAL_SRAM_StateTypeDef HAL_SRAM_GetState(const SRAM_HandleTypeDef *hsram)
1141 {
1142   return hsram->State;
1143 }
1144 
1145 /**
1146   * @}
1147   */
1148 
1149 /**
1150   * @}
1151   */
1152 
1153 /** @addtogroup SRAM_Private_Functions SRAM Private Functions
1154   * @{
1155   */
1156 
1157 /**
1158   * @brief  DMA SRAM process complete callback.
1159   * @param  hdma : DMA handle
1160   * @retval None
1161   */
SRAM_DMACplt(DMA_HandleTypeDef * hdma)1162 static void SRAM_DMACplt(DMA_HandleTypeDef *hdma)
1163 {
1164   SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
1165 
1166   /* Disable the DMA channel */
1167   __HAL_DMA_DISABLE(hdma);
1168 
1169   /* Update the SRAM controller state */
1170   hsram->State = HAL_SRAM_STATE_READY;
1171 
1172 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
1173   hsram->DmaXferCpltCallback(hdma);
1174 #else
1175   HAL_SRAM_DMA_XferCpltCallback(hdma);
1176 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
1177 }
1178 
1179 /**
1180   * @brief  DMA SRAM process complete callback.
1181   * @param  hdma : DMA handle
1182   * @retval None
1183   */
SRAM_DMACpltProt(DMA_HandleTypeDef * hdma)1184 static void SRAM_DMACpltProt(DMA_HandleTypeDef *hdma)
1185 {
1186   SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
1187 
1188   /* Disable the DMA channel */
1189   __HAL_DMA_DISABLE(hdma);
1190 
1191   /* Update the SRAM controller state */
1192   hsram->State = HAL_SRAM_STATE_PROTECTED;
1193 
1194 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
1195   hsram->DmaXferCpltCallback(hdma);
1196 #else
1197   HAL_SRAM_DMA_XferCpltCallback(hdma);
1198 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
1199 }
1200 
1201 /**
1202   * @brief  DMA SRAM error callback.
1203   * @param  hdma : DMA handle
1204   * @retval None
1205   */
SRAM_DMAError(DMA_HandleTypeDef * hdma)1206 static void SRAM_DMAError(DMA_HandleTypeDef *hdma)
1207 {
1208   SRAM_HandleTypeDef *hsram = (SRAM_HandleTypeDef *)(hdma->Parent);
1209 
1210   /* Disable the DMA channel */
1211   __HAL_DMA_DISABLE(hdma);
1212 
1213   /* Update the SRAM controller state */
1214   hsram->State = HAL_SRAM_STATE_ERROR;
1215 
1216 #if (USE_HAL_SRAM_REGISTER_CALLBACKS == 1)
1217   hsram->DmaXferErrorCallback(hdma);
1218 #else
1219   HAL_SRAM_DMA_XferErrorCallback(hdma);
1220 #endif /* USE_HAL_SRAM_REGISTER_CALLBACKS */
1221 }
1222 
1223 /**
1224   * @}
1225   */
1226 
1227 /**
1228   * @}
1229   */
1230 
1231 #endif /* HAL_SRAM_MODULE_ENABLED */
1232 
1233 /**
1234   * @}
1235   */
1236 
1237