xref: /btstack/port/stm32-f4discovery-usb/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c (revision a8f7f3fcbcd51f8d2e92aca076b6a9f812db358c)
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_hal_sdram.c
4   * @author  MCD Application Team
5   * @brief   SDRAM HAL module driver.
6   *          This file provides a generic firmware to drive SDRAM memories mounted
7   *          as external device.
8   *
9   @verbatim
10   ==============================================================================
11                        ##### How to use this driver #####
12   ==============================================================================
13   [..]
14     This driver is a generic layered driver which contains a set of APIs used to
15     control SDRAM memories. It uses the FMC layer functions to interface
16     with SDRAM devices.
17     The following sequence should be followed to configure the FMC to interface
18     with SDRAM memories:
19 
20    (#) Declare a SDRAM_HandleTypeDef handle structure, for example:
21           SDRAM_HandleTypeDef  hdsram
22 
23        (++) Fill the SDRAM_HandleTypeDef handle "Init" field with the allowed
24             values of the structure member.
25 
26        (++) Fill the SDRAM_HandleTypeDef handle "Instance" field with a predefined
27             base register instance for NOR or SDRAM device
28 
29    (#) Declare a FMC_SDRAM_TimingTypeDef structure; for example:
30           FMC_SDRAM_TimingTypeDef  Timing;
31       and fill its fields with the allowed values of the structure member.
32 
33    (#) Initialize the SDRAM Controller by calling the function HAL_SDRAM_Init(). This function
34        performs the following sequence:
35 
36        (##) MSP hardware layer configuration using the function HAL_SDRAM_MspInit()
37        (##) Control register configuration using the FMC SDRAM interface function
38             FMC_SDRAM_Init()
39        (##) Timing register configuration using the FMC SDRAM interface function
40             FMC_SDRAM_Timing_Init()
41        (##) Program the SDRAM external device by applying its initialization sequence
42             according to the device plugged in your hardware. This step is mandatory
43             for accessing the SDRAM device.
44 
45    (#) At this stage you can perform read/write accesses from/to the memory connected
46        to the SDRAM Bank. You can perform either polling or DMA transfer using the
47        following APIs:
48        (++) HAL_SDRAM_Read()/HAL_SDRAM_Write() for polling read/write access
49        (++) HAL_SDRAM_Read_DMA()/HAL_SDRAM_Write_DMA() for DMA read/write transfer
50 
51    (#) You can also control the SDRAM device by calling the control APIs HAL_SDRAM_WriteOperation_Enable()/
52        HAL_SDRAM_WriteOperation_Disable() to respectively enable/disable the SDRAM write operation or
53        the function HAL_SDRAM_SendCommand() to send a specified command to the SDRAM
54        device. The command to be sent must be configured with the FMC_SDRAM_CommandTypeDef
55        structure.
56 
57    (#) You can continuously monitor the SDRAM device HAL state by calling the function
58        HAL_SDRAM_GetState()
59 
60    *** Callback registration ***
61     =============================================
62     [..]
63       The compilation define  USE_HAL_SDRAM_REGISTER_CALLBACKS when set to 1
64       allows the user to configure dynamically the driver callbacks.
65 
66       Use Functions @ref HAL_SDRAM_RegisterCallback() to register a user callback,
67       it allows to register following callbacks:
68         (+) MspInitCallback    : SDRAM MspInit.
69         (+) MspDeInitCallback  : SDRAM MspDeInit.
70       This function takes as parameters the HAL peripheral handle, the Callback ID
71       and a pointer to the user callback function.
72 
73       Use function @ref HAL_SDRAM_UnRegisterCallback() to reset a callback to the default
74       weak (surcharged) function. It allows to reset following callbacks:
75         (+) MspInitCallback    : SDRAM MspInit.
76         (+) MspDeInitCallback  : SDRAM MspDeInit.
77       This function) takes as parameters the HAL peripheral handle and the Callback ID.
78 
79       By default, after the @ref HAL_SDRAM_Init and if the state is HAL_SDRAM_STATE_RESET
80       all callbacks are reset to the corresponding legacy weak (surcharged) functions.
81       Exception done for MspInit and MspDeInit callbacks that are respectively
82       reset to the legacy weak (surcharged) functions in the @ref HAL_SDRAM_Init
83       and @ref  HAL_SDRAM_DeInit only when these callbacks are null (not registered beforehand).
84       If not, MspInit or MspDeInit are not null, the @ref HAL_SDRAM_Init and @ref HAL_SDRAM_DeInit
85       keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
86 
87       Callbacks can be registered/unregistered in READY state only.
88       Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
89       in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
90       during the Init/DeInit.
91       In that case first register the MspInit/MspDeInit user callbacks
92       using @ref HAL_SDRAM_RegisterCallback before calling @ref HAL_SDRAM_DeInit
93       or @ref HAL_SDRAM_Init function.
94 
95       When The compilation define USE_HAL_SDRAM_REGISTER_CALLBACKS is set to 0 or
96       not defined, the callback registering feature is not available
97       and weak (surcharged) callbacks are used.
98 
99   @endverbatim
100   ******************************************************************************
101   * @attention
102   *
103   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
104   * All rights reserved.</center></h2>
105   *
106   * This software component is licensed by ST under BSD 3-Clause license,
107   * the "License"; You may not use this file except in compliance with the
108   * License. You may obtain a copy of the License at:
109   *                        opensource.org/licenses/BSD-3-Clause
110   *
111   ******************************************************************************
112   */
113 
114 /* Includes ------------------------------------------------------------------*/
115 #include "stm32f4xx_hal.h"
116 
117 /** @addtogroup STM32F4xx_HAL_Driver
118   * @{
119   */
120 
121 /** @defgroup SDRAM SDRAM
122   * @brief SDRAM driver modules
123   * @{
124   */
125 #ifdef HAL_SDRAM_MODULE_ENABLED
126 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
127     defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
128 
129 /* Private typedef -----------------------------------------------------------*/
130 /* Private define ------------------------------------------------------------*/
131 /* Private macro -------------------------------------------------------------*/
132 /* Private variables ---------------------------------------------------------*/
133 /* Private functions ---------------------------------------------------------*/
134 /* Exported functions --------------------------------------------------------*/
135 /** @defgroup SDRAM_Exported_Functions SDRAM Exported Functions
136   * @{
137   */
138 
139 /** @defgroup SDRAM_Exported_Functions_Group1 Initialization and de-initialization functions
140   * @brief    Initialization and Configuration functions
141   *
142   @verbatim
143   ==============================================================================
144            ##### SDRAM Initialization and de_initialization functions #####
145   ==============================================================================
146   [..]
147     This section provides functions allowing to initialize/de-initialize
148     the SDRAM memory
149 
150 @endverbatim
151   * @{
152   */
153 
154 /**
155   * @brief  Performs the SDRAM device initialization sequence.
156   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
157   *                the configuration information for SDRAM module.
158   * @param  Timing Pointer to SDRAM control timing structure
159   * @retval HAL status
160   */
HAL_SDRAM_Init(SDRAM_HandleTypeDef * hsdram,FMC_SDRAM_TimingTypeDef * Timing)161 HAL_StatusTypeDef HAL_SDRAM_Init(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_TimingTypeDef *Timing)
162 {
163   /* Check the SDRAM handle parameter */
164   if(hsdram == NULL)
165   {
166     return HAL_ERROR;
167   }
168 
169   if(hsdram->State == HAL_SDRAM_STATE_RESET)
170   {
171     /* Allocate lock resource and initialize it */
172     hsdram->Lock = HAL_UNLOCKED;
173 #if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
174     if(hsdram->MspInitCallback == NULL)
175     {
176       hsdram->MspInitCallback = HAL_SDRAM_MspInit;
177     }
178     hsdram->RefreshErrorCallback = HAL_SDRAM_RefreshErrorCallback;
179     hsdram->DmaXferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback;
180     hsdram->DmaXferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback;
181 
182     /* Init the low level hardware */
183     hsdram->MspInitCallback(hsdram);
184 #else
185     /* Initialize the low level hardware (MSP) */
186     HAL_SDRAM_MspInit(hsdram);
187 #endif
188   }
189 
190   /* Initialize the SDRAM controller state */
191   hsdram->State = HAL_SDRAM_STATE_BUSY;
192 
193   /* Initialize SDRAM control Interface */
194   FMC_SDRAM_Init(hsdram->Instance, &(hsdram->Init));
195 
196   /* Initialize SDRAM timing Interface */
197   FMC_SDRAM_Timing_Init(hsdram->Instance, Timing, hsdram->Init.SDBank);
198 
199   /* Update the SDRAM controller state */
200   hsdram->State = HAL_SDRAM_STATE_READY;
201 
202   return HAL_OK;
203 }
204 
205 /**
206   * @brief  Perform the SDRAM device initialization sequence.
207   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
208   *                the configuration information for SDRAM module.
209   * @retval HAL status
210   */
HAL_SDRAM_DeInit(SDRAM_HandleTypeDef * hsdram)211 HAL_StatusTypeDef HAL_SDRAM_DeInit(SDRAM_HandleTypeDef *hsdram)
212 {
213 #if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
214   if(hsdram->MspDeInitCallback == NULL)
215   {
216     hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit;
217   }
218 
219   /* DeInit the low level hardware */
220   hsdram->MspDeInitCallback(hsdram);
221 #else
222   /* Initialize the low level hardware (MSP) */
223   HAL_SDRAM_MspDeInit(hsdram);
224 #endif
225 
226   /* Configure the SDRAM registers with their reset values */
227   FMC_SDRAM_DeInit(hsdram->Instance, hsdram->Init.SDBank);
228 
229   /* Reset the SDRAM controller state */
230   hsdram->State = HAL_SDRAM_STATE_RESET;
231 
232   /* Release Lock */
233   __HAL_UNLOCK(hsdram);
234 
235   return HAL_OK;
236 }
237 
238 /**
239   * @brief  SDRAM MSP Init.
240   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
241   *                the configuration information for SDRAM module.
242   * @retval None
243   */
HAL_SDRAM_MspInit(SDRAM_HandleTypeDef * hsdram)244 __weak void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram)
245 {
246   /* Prevent unused argument(s) compilation warning */
247   UNUSED(hsdram);
248   /* NOTE: This function Should not be modified, when the callback is needed,
249             the HAL_SDRAM_MspInit could be implemented in the user file
250    */
251 }
252 
253 /**
254   * @brief  SDRAM MSP DeInit.
255   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
256   *                the configuration information for SDRAM module.
257   * @retval None
258   */
HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef * hsdram)259 __weak void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram)
260 {
261   /* Prevent unused argument(s) compilation warning */
262   UNUSED(hsdram);
263   /* NOTE: This function Should not be modified, when the callback is needed,
264             the HAL_SDRAM_MspDeInit could be implemented in the user file
265    */
266 }
267 
268 /**
269   * @brief  This function handles SDRAM refresh error interrupt request.
270   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
271   *                the configuration information for SDRAM module.
272   * @retval HAL status
273 */
HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef * hsdram)274 void HAL_SDRAM_IRQHandler(SDRAM_HandleTypeDef *hsdram)
275 {
276   /* Check SDRAM interrupt Rising edge flag */
277   if(__FMC_SDRAM_GET_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_IT))
278   {
279     /* SDRAM refresh error interrupt callback */
280 #if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
281     hsdram->RefreshErrorCallback(hsdram);
282 #else
283     HAL_SDRAM_RefreshErrorCallback(hsdram);
284 #endif
285 
286     /* Clear SDRAM refresh error interrupt pending bit */
287     __FMC_SDRAM_CLEAR_FLAG(hsdram->Instance, FMC_SDRAM_FLAG_REFRESH_ERROR);
288   }
289 }
290 
291 /**
292   * @brief  SDRAM Refresh error callback.
293   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
294   *                the configuration information for SDRAM module.
295   * @retval None
296   */
HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef * hsdram)297 __weak void HAL_SDRAM_RefreshErrorCallback(SDRAM_HandleTypeDef *hsdram)
298 {
299   /* Prevent unused argument(s) compilation warning */
300   UNUSED(hsdram);
301   /* NOTE: This function Should not be modified, when the callback is needed,
302             the HAL_SDRAM_RefreshErrorCallback could be implemented in the user file
303    */
304 }
305 
306 /**
307   * @brief  DMA transfer complete callback.
308   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
309   *                the configuration information for the specified DMA module.
310   * @retval None
311   */
HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef * hdma)312 __weak void HAL_SDRAM_DMA_XferCpltCallback(DMA_HandleTypeDef *hdma)
313 {
314   /* Prevent unused argument(s) compilation warning */
315   UNUSED(hdma);
316   /* NOTE: This function Should not be modified, when the callback is needed,
317             the HAL_SDRAM_DMA_XferCpltCallback could be implemented in the user file
318    */
319 }
320 
321 /**
322   * @brief  DMA transfer complete error callback.
323   * @param  hdma DMA handle
324   * @retval None
325   */
HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef * hdma)326 __weak void HAL_SDRAM_DMA_XferErrorCallback(DMA_HandleTypeDef *hdma)
327 {
328   /* Prevent unused argument(s) compilation warning */
329   UNUSED(hdma);
330   /* NOTE: This function Should not be modified, when the callback is needed,
331             the HAL_SDRAM_DMA_XferErrorCallback could be implemented in the user file
332    */
333 }
334 /**
335   * @}
336   */
337 
338 /** @defgroup SDRAM_Exported_Functions_Group2 Input and Output functions
339   * @brief    Input Output and memory control functions
340   *
341   @verbatim
342   ==============================================================================
343                     ##### SDRAM Input and Output functions #####
344   ==============================================================================
345   [..]
346     This section provides functions allowing to use and control the SDRAM memory
347 
348 @endverbatim
349   * @{
350   */
351 
352 /**
353   * @brief  Reads 8-bit data buffer from the SDRAM memory.
354   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
355   *                the configuration information for SDRAM module.
356   * @param  pAddress Pointer to read start address
357   * @param  pDstBuffer Pointer to destination buffer
358   * @param  BufferSize Size of the buffer to read from memory
359   * @retval HAL status
360   */
HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint8_t * pDstBuffer,uint32_t BufferSize)361 HAL_StatusTypeDef HAL_SDRAM_Read_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pDstBuffer, uint32_t BufferSize)
362 {
363   __IO uint8_t *pSdramAddress = (uint8_t *)pAddress;
364 
365   /* Process Locked */
366   __HAL_LOCK(hsdram);
367 
368   /* Check the SDRAM controller state */
369   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
370   {
371     return HAL_BUSY;
372   }
373   else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED)
374   {
375     return  HAL_ERROR;
376   }
377 
378   /* Read data from source */
379   for(; BufferSize != 0U; BufferSize--)
380   {
381     *pDstBuffer = *(__IO uint8_t *)pSdramAddress;
382     pDstBuffer++;
383     pSdramAddress++;
384   }
385 
386   /* Process Unlocked */
387   __HAL_UNLOCK(hsdram);
388 
389   return HAL_OK;
390 }
391 
392 /**
393   * @brief  Writes 8-bit data buffer to SDRAM memory.
394   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
395   *                the configuration information for SDRAM module.
396   * @param  pAddress Pointer to write start address
397   * @param  pSrcBuffer Pointer to source buffer to write
398   * @param  BufferSize Size of the buffer to write to memory
399   * @retval HAL status
400   */
HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint8_t * pSrcBuffer,uint32_t BufferSize)401 HAL_StatusTypeDef HAL_SDRAM_Write_8b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint8_t *pSrcBuffer, uint32_t BufferSize)
402 {
403   __IO uint8_t *pSdramAddress = (uint8_t *)pAddress;
404   uint32_t tmp = 0U;
405 
406   /* Process Locked */
407   __HAL_LOCK(hsdram);
408 
409   /* Check the SDRAM controller state */
410   tmp = hsdram->State;
411 
412   if(tmp == HAL_SDRAM_STATE_BUSY)
413   {
414     return HAL_BUSY;
415   }
416   else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED))
417   {
418     return  HAL_ERROR;
419   }
420 
421   /* Write data to memory */
422   for(; BufferSize != 0U; BufferSize--)
423   {
424     *(__IO uint8_t *)pSdramAddress = *pSrcBuffer;
425     pSrcBuffer++;
426     pSdramAddress++;
427   }
428 
429   /* Process Unlocked */
430   __HAL_UNLOCK(hsdram);
431 
432   return HAL_OK;
433 }
434 
435 /**
436   * @brief  Reads 16-bit data buffer from the SDRAM memory.
437   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
438   *                the configuration information for SDRAM 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_SDRAM_Read_16b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint16_t * pDstBuffer,uint32_t BufferSize)444 HAL_StatusTypeDef HAL_SDRAM_Read_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pDstBuffer, uint32_t BufferSize)
445 {
446   __IO uint16_t *pSdramAddress = (uint16_t *)pAddress;
447 
448   /* Process Locked */
449   __HAL_LOCK(hsdram);
450 
451   /* Check the SDRAM controller state */
452   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
453   {
454     return HAL_BUSY;
455   }
456   else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED)
457   {
458     return  HAL_ERROR;
459   }
460 
461   /* Read data from source */
462   for(; BufferSize != 0U; BufferSize--)
463   {
464     *pDstBuffer = *(__IO uint16_t *)pSdramAddress;
465     pDstBuffer++;
466     pSdramAddress++;
467   }
468 
469   /* Process Unlocked */
470   __HAL_UNLOCK(hsdram);
471 
472   return HAL_OK;
473 }
474 
475 /**
476   * @brief  Writes 16-bit data buffer to SDRAM memory.
477   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
478   *                the configuration information for SDRAM module.
479   * @param  pAddress Pointer to write start address
480   * @param  pSrcBuffer Pointer to source buffer to write
481   * @param  BufferSize Size of the buffer to write to memory
482   * @retval HAL status
483   */
HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint16_t * pSrcBuffer,uint32_t BufferSize)484 HAL_StatusTypeDef HAL_SDRAM_Write_16b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint16_t *pSrcBuffer, uint32_t BufferSize)
485 {
486   __IO uint16_t *pSdramAddress = (uint16_t *)pAddress;
487   uint32_t tmp = 0U;
488 
489   /* Process Locked */
490   __HAL_LOCK(hsdram);
491 
492   /* Check the SDRAM controller state */
493   tmp = hsdram->State;
494 
495   if(tmp == HAL_SDRAM_STATE_BUSY)
496   {
497     return HAL_BUSY;
498   }
499   else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED))
500   {
501     return  HAL_ERROR;
502   }
503 
504   /* Write data to memory */
505   for(; BufferSize != 0U; BufferSize--)
506   {
507     *(__IO uint16_t *)pSdramAddress = *pSrcBuffer;
508     pSrcBuffer++;
509     pSdramAddress++;
510   }
511 
512   /* Process Unlocked */
513   __HAL_UNLOCK(hsdram);
514 
515   return HAL_OK;
516 }
517 
518 /**
519   * @brief  Reads 32-bit data buffer from the SDRAM memory.
520   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
521   *                the configuration information for SDRAM module.
522   * @param  pAddress Pointer to read start address
523   * @param  pDstBuffer Pointer to destination buffer
524   * @param  BufferSize Size of the buffer to read from memory
525   * @retval HAL status
526   */
HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint32_t * pDstBuffer,uint32_t BufferSize)527 HAL_StatusTypeDef HAL_SDRAM_Read_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
528 {
529   __IO uint32_t *pSdramAddress = (uint32_t *)pAddress;
530 
531   /* Process Locked */
532   __HAL_LOCK(hsdram);
533 
534   /* Check the SDRAM controller state */
535   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
536   {
537     return HAL_BUSY;
538   }
539   else if(hsdram->State == HAL_SDRAM_STATE_PRECHARGED)
540   {
541     return  HAL_ERROR;
542   }
543 
544   /* Read data from source */
545   for(; BufferSize != 0U; BufferSize--)
546   {
547     *pDstBuffer = *(__IO uint32_t *)pSdramAddress;
548     pDstBuffer++;
549     pSdramAddress++;
550   }
551 
552   /* Process Unlocked */
553   __HAL_UNLOCK(hsdram);
554 
555   return HAL_OK;
556 }
557 
558 /**
559   * @brief  Writes 32-bit data buffer to SDRAM memory.
560   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
561   *                the configuration information for SDRAM module.
562   * @param  pAddress Pointer to write start address
563   * @param  pSrcBuffer Pointer to source buffer to write
564   * @param  BufferSize Size of the buffer to write to memory
565   * @retval HAL status
566   */
HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint32_t * pSrcBuffer,uint32_t BufferSize)567 HAL_StatusTypeDef HAL_SDRAM_Write_32b(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
568 {
569   __IO uint32_t *pSdramAddress = (uint32_t *)pAddress;
570   uint32_t tmp = 0U;
571 
572   /* Process Locked */
573   __HAL_LOCK(hsdram);
574 
575   /* Check the SDRAM controller state */
576   tmp = hsdram->State;
577 
578   if(tmp == HAL_SDRAM_STATE_BUSY)
579   {
580     return HAL_BUSY;
581   }
582   else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED))
583   {
584     return  HAL_ERROR;
585   }
586 
587   /* Write data to memory */
588   for(; BufferSize != 0U; BufferSize--)
589   {
590     *(__IO uint32_t *)pSdramAddress = *pSrcBuffer;
591     pSrcBuffer++;
592     pSdramAddress++;
593   }
594 
595   /* Process Unlocked */
596   __HAL_UNLOCK(hsdram);
597 
598   return HAL_OK;
599 }
600 
601 /**
602   * @brief  Reads a Words data from the SDRAM memory using DMA transfer.
603   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
604   *                the configuration information for SDRAM module.
605   * @param  pAddress Pointer to read start address
606   * @param  pDstBuffer Pointer to destination buffer
607   * @param  BufferSize Size of the buffer to read from memory
608   * @retval HAL status
609   */
HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint32_t * pDstBuffer,uint32_t BufferSize)610 HAL_StatusTypeDef HAL_SDRAM_Read_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)
611 {
612   uint32_t tmp = 0U;
613 
614   /* Process Locked */
615   __HAL_LOCK(hsdram);
616 
617   /* Check the SDRAM controller state */
618   tmp = hsdram->State;
619 
620   if(tmp == HAL_SDRAM_STATE_BUSY)
621   {
622     return HAL_BUSY;
623   }
624   else if(tmp == HAL_SDRAM_STATE_PRECHARGED)
625   {
626     return  HAL_ERROR;
627   }
628 
629   /* Configure DMA user callbacks */
630   hsdram->hdma->XferCpltCallback  = HAL_SDRAM_DMA_XferCpltCallback;
631   hsdram->hdma->XferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback;
632 
633   /* Enable the DMA Stream */
634   HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pAddress, (uint32_t)pDstBuffer, (uint32_t)BufferSize);
635 
636   /* Process Unlocked */
637   __HAL_UNLOCK(hsdram);
638 
639   return HAL_OK;
640 }
641 
642 /**
643   * @brief  Writes a Words data buffer to SDRAM memory using DMA transfer.
644   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
645   *                the configuration information for SDRAM module.
646   * @param  pAddress Pointer to write start address
647   * @param  pSrcBuffer Pointer to source buffer to write
648   * @param  BufferSize Size of the buffer to write to memory
649   * @retval HAL status
650   */
HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef * hsdram,uint32_t * pAddress,uint32_t * pSrcBuffer,uint32_t BufferSize)651 HAL_StatusTypeDef HAL_SDRAM_Write_DMA(SDRAM_HandleTypeDef *hsdram, uint32_t *pAddress, uint32_t *pSrcBuffer, uint32_t BufferSize)
652 {
653   uint32_t tmp = 0U;
654 
655   /* Process Locked */
656   __HAL_LOCK(hsdram);
657 
658   /* Check the SDRAM controller state */
659   tmp = hsdram->State;
660 
661   if(tmp == HAL_SDRAM_STATE_BUSY)
662   {
663     return HAL_BUSY;
664   }
665   else if((tmp == HAL_SDRAM_STATE_PRECHARGED) || (tmp == HAL_SDRAM_STATE_WRITE_PROTECTED))
666   {
667     return  HAL_ERROR;
668   }
669 
670   /* Configure DMA user callbacks */
671   hsdram->hdma->XferCpltCallback  = HAL_SDRAM_DMA_XferCpltCallback;
672   hsdram->hdma->XferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback;
673 
674   /* Enable the DMA Stream */
675   HAL_DMA_Start_IT(hsdram->hdma, (uint32_t)pSrcBuffer, (uint32_t)pAddress, (uint32_t)BufferSize);
676 
677   /* Process Unlocked */
678   __HAL_UNLOCK(hsdram);
679 
680   return HAL_OK;
681 }
682 
683 #if (USE_HAL_SDRAM_REGISTER_CALLBACKS == 1)
684 /**
685   * @brief  Register a User SDRAM Callback
686   *         To be used instead of the weak (surcharged) predefined callback
687   * @param hsdram : SDRAM handle
688   * @param CallbackId : ID of the callback to be registered
689   *        This parameter can be one of the following values:
690   *          @arg @ref HAL_SDRAM_MSP_INIT_CB_ID       SDRAM MspInit callback ID
691   *          @arg @ref HAL_SDRAM_MSP_DEINIT_CB_ID     SDRAM MspDeInit callback ID
692   *          @arg @ref HAL_SDRAM_REFRESH_ERR_CB_ID    SDRAM Refresh Error callback ID
693   * @param pCallback : pointer to the Callback function
694   * @retval status
695   */
HAL_SDRAM_RegisterCallback(SDRAM_HandleTypeDef * hsdram,HAL_SDRAM_CallbackIDTypeDef CallbackId,pSDRAM_CallbackTypeDef pCallback)696 HAL_StatusTypeDef HAL_SDRAM_RegisterCallback (SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, pSDRAM_CallbackTypeDef pCallback)
697 {
698   HAL_StatusTypeDef status = HAL_OK;
699   HAL_SDRAM_StateTypeDef state;
700 
701   if(pCallback == NULL)
702   {
703     return HAL_ERROR;
704   }
705 
706   /* Process locked */
707   __HAL_LOCK(hsdram);
708 
709   state = hsdram->State;
710   if((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED))
711   {
712     switch (CallbackId)
713     {
714     case HAL_SDRAM_MSP_INIT_CB_ID :
715       hsdram->MspInitCallback = pCallback;
716       break;
717     case HAL_SDRAM_MSP_DEINIT_CB_ID :
718       hsdram->MspDeInitCallback = pCallback;
719       break;
720     case HAL_SDRAM_REFRESH_ERR_CB_ID :
721       hsdram->RefreshErrorCallback = pCallback;
722       break;
723     default :
724       /* update return status */
725       status =  HAL_ERROR;
726       break;
727     }
728   }
729   else if(hsdram->State == HAL_SDRAM_STATE_RESET)
730   {
731     switch (CallbackId)
732     {
733     case HAL_SDRAM_MSP_INIT_CB_ID :
734       hsdram->MspInitCallback = pCallback;
735       break;
736     case HAL_SDRAM_MSP_DEINIT_CB_ID :
737       hsdram->MspDeInitCallback = pCallback;
738       break;
739     default :
740       /* update return status */
741       status =  HAL_ERROR;
742       break;
743     }
744   }
745   else
746   {
747     /* update return status */
748     status =  HAL_ERROR;
749   }
750 
751   /* Release Lock */
752   __HAL_UNLOCK(hsdram);
753   return status;
754 }
755 
756 /**
757   * @brief  Unregister a User SDRAM Callback
758   *         SDRAM Callback is redirected to the weak (surcharged) predefined callback
759   * @param hsdram : SDRAM handle
760   * @param CallbackId : ID of the callback to be unregistered
761   *        This parameter can be one of the following values:
762   *          @arg @ref HAL_SDRAM_MSP_INIT_CB_ID       SDRAM MspInit callback ID
763   *          @arg @ref HAL_SDRAM_MSP_DEINIT_CB_ID     SDRAM MspDeInit callback ID
764   *          @arg @ref HAL_SDRAM_REFRESH_ERR_CB_ID    SDRAM Refresh Error callback ID
765   *          @arg @ref HAL_SDRAM_DMA_XFER_CPLT_CB_ID  SDRAM DMA Xfer Complete callback ID
766   *          @arg @ref HAL_SDRAM_DMA_XFER_ERR_CB_ID   SDRAM DMA Xfer Error callback ID
767   * @retval status
768   */
HAL_SDRAM_UnRegisterCallback(SDRAM_HandleTypeDef * hsdram,HAL_SDRAM_CallbackIDTypeDef CallbackId)769 HAL_StatusTypeDef HAL_SDRAM_UnRegisterCallback (SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId)
770 {
771   HAL_StatusTypeDef status = HAL_OK;
772   HAL_SDRAM_StateTypeDef state;
773 
774   /* Process locked */
775   __HAL_LOCK(hsdram);
776 
777   state = hsdram->State;
778   if((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED))
779   {
780     switch (CallbackId)
781     {
782     case HAL_SDRAM_MSP_INIT_CB_ID :
783       hsdram->MspInitCallback = HAL_SDRAM_MspInit;
784       break;
785     case HAL_SDRAM_MSP_DEINIT_CB_ID :
786       hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit;
787       break;
788     case HAL_SDRAM_REFRESH_ERR_CB_ID :
789       hsdram->RefreshErrorCallback = HAL_SDRAM_RefreshErrorCallback;
790       break;
791     case HAL_SDRAM_DMA_XFER_CPLT_CB_ID :
792       hsdram->DmaXferCpltCallback = HAL_SDRAM_DMA_XferCpltCallback;
793       break;
794     case HAL_SDRAM_DMA_XFER_ERR_CB_ID :
795       hsdram->DmaXferErrorCallback = HAL_SDRAM_DMA_XferErrorCallback;
796       break;
797     default :
798       /* update return status */
799       status =  HAL_ERROR;
800       break;
801     }
802   }
803   else if(hsdram->State == HAL_SDRAM_STATE_RESET)
804   {
805     switch (CallbackId)
806     {
807     case HAL_SDRAM_MSP_INIT_CB_ID :
808       hsdram->MspInitCallback = HAL_SDRAM_MspInit;
809       break;
810     case HAL_SDRAM_MSP_DEINIT_CB_ID :
811       hsdram->MspDeInitCallback = HAL_SDRAM_MspDeInit;
812       break;
813     default :
814       /* update return status */
815       status =  HAL_ERROR;
816       break;
817     }
818   }
819   else
820   {
821     /* update return status */
822     status =  HAL_ERROR;
823   }
824 
825   /* Release Lock */
826   __HAL_UNLOCK(hsdram);
827   return status;
828 }
829 
830 /**
831   * @brief  Register a User SDRAM Callback for DMA transfers
832   *         To be used instead of the weak (surcharged) predefined callback
833   * @param hsdram : SDRAM handle
834   * @param CallbackId : ID of the callback to be registered
835   *        This parameter can be one of the following values:
836   *          @arg @ref HAL_SDRAM_DMA_XFER_CPLT_CB_ID  SDRAM DMA Xfer Complete callback ID
837   *          @arg @ref HAL_SDRAM_DMA_XFER_ERR_CB_ID   SDRAM DMA Xfer Error callback ID
838   * @param pCallback : pointer to the Callback function
839   * @retval status
840   */
HAL_SDRAM_RegisterDmaCallback(SDRAM_HandleTypeDef * hsdram,HAL_SDRAM_CallbackIDTypeDef CallbackId,pSDRAM_DmaCallbackTypeDef pCallback)841 HAL_StatusTypeDef HAL_SDRAM_RegisterDmaCallback(SDRAM_HandleTypeDef *hsdram, HAL_SDRAM_CallbackIDTypeDef CallbackId, pSDRAM_DmaCallbackTypeDef pCallback)
842 {
843   HAL_StatusTypeDef status = HAL_OK;
844   HAL_SDRAM_StateTypeDef state;
845 
846   if(pCallback == NULL)
847   {
848     return HAL_ERROR;
849   }
850 
851   /* Process locked */
852   __HAL_LOCK(hsdram);
853 
854   state = hsdram->State;
855   if((state == HAL_SDRAM_STATE_READY) || (state == HAL_SDRAM_STATE_WRITE_PROTECTED))
856   {
857     switch (CallbackId)
858     {
859     case HAL_SDRAM_DMA_XFER_CPLT_CB_ID :
860       hsdram->DmaXferCpltCallback = pCallback;
861       break;
862     case HAL_SDRAM_DMA_XFER_ERR_CB_ID :
863       hsdram->DmaXferErrorCallback = pCallback;
864       break;
865     default :
866       /* update return status */
867       status =  HAL_ERROR;
868       break;
869     }
870   }
871   else
872   {
873     /* update return status */
874     status =  HAL_ERROR;
875   }
876 
877   /* Release Lock */
878   __HAL_UNLOCK(hsdram);
879   return status;
880 }
881 #endif
882 
883 /**
884   * @}
885   */
886 
887 /** @defgroup SDRAM_Exported_Functions_Group3 Control functions
888  *  @brief   management functions
889  *
890 @verbatim
891   ==============================================================================
892                          ##### SDRAM Control functions #####
893   ==============================================================================
894   [..]
895     This subsection provides a set of functions allowing to control dynamically
896     the SDRAM interface.
897 
898 @endverbatim
899   * @{
900   */
901 
902 /**
903   * @brief  Enables dynamically SDRAM write protection.
904   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
905   *                the configuration information for SDRAM module.
906   * @retval HAL status
907   */
HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef * hsdram)908 HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Enable(SDRAM_HandleTypeDef *hsdram)
909 {
910   /* Check the SDRAM controller state */
911   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
912   {
913     return HAL_BUSY;
914   }
915 
916   /* Update the SDRAM state */
917   hsdram->State = HAL_SDRAM_STATE_BUSY;
918 
919   /* Enable write protection */
920   FMC_SDRAM_WriteProtection_Enable(hsdram->Instance, hsdram->Init.SDBank);
921 
922   /* Update the SDRAM state */
923   hsdram->State = HAL_SDRAM_STATE_WRITE_PROTECTED;
924 
925   return HAL_OK;
926 }
927 
928 /**
929   * @brief  Disables dynamically SDRAM write protection.
930   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
931   *                the configuration information for SDRAM module.
932   * @retval HAL status
933   */
HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef * hsdram)934 HAL_StatusTypeDef HAL_SDRAM_WriteProtection_Disable(SDRAM_HandleTypeDef *hsdram)
935 {
936   /* Check the SDRAM controller state */
937   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
938   {
939     return HAL_BUSY;
940   }
941 
942   /* Update the SDRAM state */
943   hsdram->State = HAL_SDRAM_STATE_BUSY;
944 
945   /* Disable write protection */
946   FMC_SDRAM_WriteProtection_Disable(hsdram->Instance, hsdram->Init.SDBank);
947 
948   /* Update the SDRAM state */
949   hsdram->State = HAL_SDRAM_STATE_READY;
950 
951   return HAL_OK;
952 }
953 
954 /**
955   * @brief  Sends Command to the SDRAM bank.
956   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
957   *                the configuration information for SDRAM module.
958   * @param  Command SDRAM command structure
959   * @param  Timeout Timeout duration
960   * @retval HAL status
961   */
HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef * hsdram,FMC_SDRAM_CommandTypeDef * Command,uint32_t Timeout)962 HAL_StatusTypeDef HAL_SDRAM_SendCommand(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout)
963 {
964   /* Check the SDRAM controller state */
965   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
966   {
967     return HAL_BUSY;
968   }
969 
970   /* Update the SDRAM state */
971   hsdram->State = HAL_SDRAM_STATE_BUSY;
972 
973   /* Send SDRAM command */
974   FMC_SDRAM_SendCommand(hsdram->Instance, Command, Timeout);
975 
976   /* Update the SDRAM controller state */
977   if(Command->CommandMode == FMC_SDRAM_CMD_PALL)
978   {
979     hsdram->State = HAL_SDRAM_STATE_PRECHARGED;
980   }
981   else
982   {
983     hsdram->State = HAL_SDRAM_STATE_READY;
984   }
985 
986   return HAL_OK;
987 }
988 
989 /**
990   * @brief  Programs the SDRAM Memory Refresh rate.
991   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
992   *                the configuration information for SDRAM module.
993   * @param  RefreshRate The SDRAM refresh rate value
994   * @retval HAL status
995   */
HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef * hsdram,uint32_t RefreshRate)996 HAL_StatusTypeDef HAL_SDRAM_ProgramRefreshRate(SDRAM_HandleTypeDef *hsdram, uint32_t RefreshRate)
997 {
998   /* Check the SDRAM controller state */
999   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
1000   {
1001     return HAL_BUSY;
1002   }
1003 
1004   /* Update the SDRAM state */
1005   hsdram->State = HAL_SDRAM_STATE_BUSY;
1006 
1007   /* Program the refresh rate */
1008   FMC_SDRAM_ProgramRefreshRate(hsdram->Instance ,RefreshRate);
1009 
1010   /* Update the SDRAM state */
1011   hsdram->State = HAL_SDRAM_STATE_READY;
1012 
1013   return HAL_OK;
1014 }
1015 
1016 /**
1017   * @brief  Sets the Number of consecutive SDRAM Memory auto Refresh commands.
1018   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
1019   *                the configuration information for SDRAM module.
1020   * @param  AutoRefreshNumber The SDRAM auto Refresh number
1021   * @retval HAL status
1022   */
HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef * hsdram,uint32_t AutoRefreshNumber)1023 HAL_StatusTypeDef HAL_SDRAM_SetAutoRefreshNumber(SDRAM_HandleTypeDef *hsdram, uint32_t AutoRefreshNumber)
1024 {
1025   /* Check the SDRAM controller state */
1026   if(hsdram->State == HAL_SDRAM_STATE_BUSY)
1027   {
1028     return HAL_BUSY;
1029   }
1030 
1031   /* Update the SDRAM state */
1032   hsdram->State = HAL_SDRAM_STATE_BUSY;
1033 
1034   /* Set the Auto-Refresh number */
1035   FMC_SDRAM_SetAutoRefreshNumber(hsdram->Instance ,AutoRefreshNumber);
1036 
1037   /* Update the SDRAM state */
1038   hsdram->State = HAL_SDRAM_STATE_READY;
1039 
1040   return HAL_OK;
1041 }
1042 
1043 /**
1044   * @brief  Returns the SDRAM memory current mode.
1045   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
1046   *                the configuration information for SDRAM module.
1047   * @retval The SDRAM memory mode.
1048   */
HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef * hsdram)1049 uint32_t HAL_SDRAM_GetModeStatus(SDRAM_HandleTypeDef *hsdram)
1050 {
1051   /* Return the SDRAM memory current mode */
1052   return(FMC_SDRAM_GetModeStatus(hsdram->Instance, hsdram->Init.SDBank));
1053 }
1054 
1055 /**
1056   * @}
1057   */
1058 
1059 /** @defgroup SDRAM_Exported_Functions_Group4 State functions
1060  *  @brief   Peripheral State functions
1061  *
1062 @verbatim
1063   ==============================================================================
1064                       ##### SDRAM State functions #####
1065   ==============================================================================
1066   [..]
1067     This subsection permits to get in run-time the status of the SDRAM controller
1068     and the data flow.
1069 
1070 @endverbatim
1071   * @{
1072   */
1073 
1074 /**
1075   * @brief  Returns the SDRAM state.
1076   * @param  hsdram pointer to a SDRAM_HandleTypeDef structure that contains
1077   *                the configuration information for SDRAM module.
1078   * @retval HAL state
1079   */
HAL_SDRAM_GetState(SDRAM_HandleTypeDef * hsdram)1080 HAL_SDRAM_StateTypeDef HAL_SDRAM_GetState(SDRAM_HandleTypeDef *hsdram)
1081 {
1082   return hsdram->State;
1083 }
1084 
1085 /**
1086   * @}
1087   */
1088 
1089 /**
1090   * @}
1091   */
1092 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
1093 #endif /* HAL_SDRAM_MODULE_ENABLED */
1094 /**
1095   * @}
1096   */
1097 
1098 /**
1099   * @}
1100   */
1101 
1102 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1103