| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722 |
- /**
- **********************************************************************************************************************
- * @file stm32h5xx_hal_dma.c
- * @author MCD Application Team
- * @brief This file provides firmware functions to manage the following functionalities of the Direct Memory Access
- * (DMA) peripheral:
- * + Initialization/De-Initialization Functions
- * + I/O Operation Functions
- * + State and Errors Functions
- * + DMA Attributes Functions
- *
- **********************************************************************************************************************
- * @attention
- *
- * Copyright (c) 2023 STMicroelectronics.
- * All rights reserved.
- *
- * This software is licensed under terms that can be found in the LICENSE file
- * in the root directory of this software component.
- * If no LICENSE file comes with this software, it is provided AS-IS.
- *
- **********************************************************************************************************************
- @verbatim
- ======================================================================================================================
- ##### How to use this driver #####
- ======================================================================================================================
- [..]
- DMA transfer modes are divided to 2 major categories :
- (+) Normal transfers (legacy)
- (+) Linked-list transfers
- [..]
- Normal transfers mode is initialized via the standard module and linked-list mode is configured via the extended
- module.
- [..]
- Additionally to linked-list capability, all advanced DMA features are managed and configured via the extended
- module as extensions to normal mode.
- Advanced features are :
- (+) Repeated block feature.
- (+) Trigger feature.
- (+) Data handling feature.
- [..]
- DMA Legacy circular transfer, is replaced by circular linked-list configuration.
- *** Initialization and De-Initialization ***
- ============================================
- [..]
- For a given channel, enable and configure the peripheral to be connected to the DMA Channel (except for internal
- SRAM/FLASH memories: no initialization is necessary) please refer to Reference manual for connection between
- peripherals and DMA requests.
- [..]
- For a given channel, use HAL_DMA_Init function to program the required configuration for normal transfer through
- the following parameters:
- (+) Request : Specifies the DMA channel request
- Request parameters :
- (++) can be a value of DMA_Request_Selection
- (+) BlkHWRequest : Specifies the Block hardware request mode for DMA channel
- (++) can be a value of DMA_Block_Request
- (+) Direction : Specifies the transfer direction for DMA channel
- (++) can be a value of DMA_Transfer_Direction
- (+) SrcInc : Specifies the source increment mode for the DMA channel
- (++) can be a value of DMA_Source_Increment_Mode
- (+) DestInc : Specifies the destination increment mode for the DMA channel
- (++) can be a value of DMA_Destination_Increment_Mode
- (+) SrcDataWidth : Specifies the source data width for the DMA channel
- (++) can be a value of DMA_Source_Data_Width
- (+) DestDataWidth : Specifies the destination data width for the DMA channel
- (++) can be a value of DMA_Destination_Data_Width
- (+) Priority : Specifies the priority for the DMA channel
- (++) can be a value of DMA_Priority_Level
- (+) SrcBurstLength : Specifies the source burst length (number of beats) for the DMA channel
- (++) can be a value of between 1 and 64
- (+) DestBurstLength : Specifies the destination burst length (number of beats) for the DMA channel
- (++) can be a value of between 1 and 64
- (+) TransferAllocatedPort : Specifies the source and destination allocated ports
- (++) can be a value of DMA_Transfer_Allocated_Port
- (+) TransferEventMode : Specifies the transfer event mode for the DMA channel
- (++) can be a value of DMA_Transfer_Event_Mode
- (+) Mode : Specifies the transfer mode for the DMA channel
- (++) can be one of the following modes :
- (+++) DMA_NORMAL : Normal Mode
- (+++) DMA_PFCTRL : Peripheral Flow Control (peripheral early termination) Mode
- *** Polling mode IO operation ***
- =================================
- [..]
- (+) Use HAL_DMA_Start() to start a DMA normal transfer after the configuration of source address, destination
- address and the size of data to be transferred.
- (+) Use HAL_DMA_PollForTransfer() to poll for selected transfer level. In this case a fixed Timeout can be
- configured by User depending on his application.
- Transfer level can be :
- (++) HAL_DMA_HALF_TRANSFER
- (++) HAL_DMA_FULL_TRANSFER
- For circular transfer, this API returns an HAL_ERROR with HAL_DMA_ERROR_NOT_SUPPORTED error code.
- (+) Use HAL_DMA_Abort() function to abort any ongoing DMA transfer in blocking mode.
- This API returns HAL_ERROR when there is no ongoing transfer or timeout is reached when disabling the DMA
- channel. (This API should not be called from an interrupt service routine)
- *** Interrupt mode IO operation ***
- ===================================
- [..]
- (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
- (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
- (+) Use HAL_DMA_RegisterCallback() function to register user callbacks from the following list :
- (++) XferCpltCallback : transfer complete callback.
- (++) XferHalfCpltCallback : half transfer complete callback.
- (++) XferErrorCallback : transfer error callback.
- (++) XferAbortCallback : transfer abort complete callback.
- (++) XferSuspendCallback : transfer suspend complete callback.
- (+) Use HAL_DMA_Start_IT() to start the DMA transfer after the enable of DMA interrupts and the configuration
- of source address,destination address and the size of data to be transferred.
- (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() interrupt subroutine to handle any DMA interrupt.
- (+) Use HAL_DMA_Abort_IT() function to abort any on-going DMA transfer in non-blocking mode.
- This API will suspend immediately the DMA channel execution. When the transfer is effectively suspended,
- an interrupt is generated and HAL_DMA_IRQHandler() will reset the channel and execute the callback
- XferAbortCallback. (This API could be called from an interrupt service routine)
- *** State and errors ***
- ========================
- [..]
- (+) Use HAL_DMA_GetState() function to get the DMA state.
- (+) Use HAL_DMA_GetError() function to get the DMA error code.
- *** Security and privilege attributes ***
- =========================================
- [..]
- (+) Use HAL_DMA_ConfigChannelAttributes() function to configure DMA channel security and privilege attributes.
- (++) Security : at channel level, at source level and at destination level.
- (++) Privilege : at channel level.
- (+) Use HAL_DMA_GetConfigChannelAttributes() function to get the DMA channel attributes.
- (+) Use HAL_DMA_LockChannelAttributes() function to lock the DMA channel security and privilege attributes
- configuration. This API can be called once after each system boot.
- If called again, HAL_DMA_ConfigChannelAttributes() API has no effect.
- Unlock is done either by a system boot or a by an RCC reset.
- (+) Use HAL_DMA_GetLockChannelAttributes() function to get the attributes lock status.
- *** DMA HAL driver macros list ***
- ==================================
- [..]
- Below the list of most used macros in DMA HAL driver.
- (+) __HAL_DMA_ENABLE : Enable the specified DMA Channel.
- (+) __HAL_DMA_DISABLE : Disable the specified DMA Channel.
- (+) __HAL_DMA_GET_FLAG : Get the DMA Channel pending flags.
- (+) __HAL_DMA_CLEAR_FLAG : Clear the DMA Channel pending flags.
- (+) __HAL_DMA_ENABLE_IT : Enable the specified DMA Channel interrupts.
- (+) __HAL_DMA_DISABLE_IT : Disable the specified DMA Channel interrupts.
- (+) __HAL_DMA_GET_IT_SOURCE : Check whether the specified DMA Channel interrupt has occurred or not.
- [..]
- (@) You can refer to the header file of the DMA HAL driver for more useful macros.
- @endverbatim
- **********************************************************************************************************************
- */
- /* Includes ----------------------------------------------------------------------------------------------------------*/
- #include "stm32h5xx_hal.h"
- /** @addtogroup STM32H5xx_HAL_Driver
- * @{
- */
- /** @defgroup DMA DMA
- * @brief DMA HAL module driver
- * @{
- */
- #ifdef HAL_DMA_MODULE_ENABLED
- /* Private typedef ---------------------------------------------------------------------------------------------------*/
- /* Private constants -------------------------------------------------------------------------------------------------*/
- /* Private macro -----------------------------------------------------------------------------------------------------*/
- /* Private variables -------------------------------------------------------------------------------------------------*/
- /* Private function prototypes ---------------------------------------------------------------------------------------*/
- static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
- uint32_t SrcAddress,
- uint32_t DstAddress,
- uint32_t SrcDataSize);
- static void DMA_Init(DMA_HandleTypeDef const *const hdma);
- /* Exported functions ------------------------------------------------------------------------------------------------*/
- /** @addtogroup DMA_Exported_Functions DMA Exported Functions
- * @{
- */
- /** @addtogroup DMA_Exported_Functions_Group1
- *
- @verbatim
- ======================================================================================================================
- ##### Initialization and de-initialization functions #####
- ======================================================================================================================
- [..]
- This section provides functions allowing to initialize and de-initialize the DMA channel in normal mode.
- [..]
- (+) The HAL_DMA_Init() function follows the DMA channel configuration procedures as described in reference manual.
- (+) The HAL_DMA_DeInit() function allows to de-initialize the DMA channel.
- @endverbatim
- * @{
- */
- /**
- * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef and
- * create the associated handle.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *const hdma)
- {
- /* Get tick number */
- uint32_t tickstart = HAL_GetTick();
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
- assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
- if (hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
- {
- assert_param(IS_DMA_REQUEST(hdma->Init.Request));
- }
- assert_param(IS_DMA_BLOCK_HW_REQUEST(hdma->Init.BlkHWRequest));
- assert_param(IS_DMA_SOURCE_INC(hdma->Init.SrcInc));
- assert_param(IS_DMA_DESTINATION_INC(hdma->Init.DestInc));
- assert_param(IS_DMA_SOURCE_DATA_WIDTH(hdma->Init.SrcDataWidth));
- assert_param(IS_DMA_DESTINATION_DATA_WIDTH(hdma->Init.DestDataWidth));
- assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
- assert_param(IS_DMA_TCEM_EVENT_MODE(hdma->Init.TransferEventMode));
- assert_param(IS_DMA_MODE(hdma->Init.Mode));
- if (hdma->Init.Mode == DMA_PFCTRL)
- {
- assert_param(IS_DMA_PFREQ_INSTANCE(hdma->Instance));
- }
- /* Check DMA channel instance */
- if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
- {
- assert_param(IS_DMA_BURST_LENGTH(hdma->Init.SrcBurstLength));
- assert_param(IS_DMA_BURST_LENGTH(hdma->Init.DestBurstLength));
- assert_param(IS_DMA_TRANSFER_ALLOCATED_PORT(hdma->Init.TransferAllocatedPort));
- }
- /* Allocate lock resource */
- __HAL_UNLOCK(hdma);
- /* Initialize the callbacks */
- if (hdma->State == HAL_DMA_STATE_RESET)
- {
- /* Clean all callbacks */
- hdma->XferCpltCallback = NULL;
- hdma->XferHalfCpltCallback = NULL;
- hdma->XferErrorCallback = NULL;
- hdma->XferAbortCallback = NULL;
- hdma->XferSuspendCallback = NULL;
- }
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_BUSY;
- /* Disable the DMA channel */
- __HAL_DMA_DISABLE(hdma);
- /* Check if the DMA channel is effectively disabled */
- while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_ERROR;
- return HAL_ERROR;
- }
- }
- /* Initialize the DMA channel registers */
- DMA_Init(hdma);
- /* Update DMA channel operation mode */
- hdma->Mode = hdma->Init.Mode;
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- return HAL_OK;
- }
- /**
- * @brief DeInitialize the DMA channel when it is configured in normal mode.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *const hdma)
- {
- DMA_TypeDef *p_dma_instance;
- uint32_t tickstart = HAL_GetTick();
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
- /* Get DMA instance */
- p_dma_instance = GET_DMA_INSTANCE(hdma);
- /* Disable the selected DMA Channel */
- __HAL_DMA_DISABLE(hdma);
- /* Check if the DMA channel is effectively disabled */
- while ((hdma->Instance->CCR & DMA_CCR_EN) != 0U)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_ERROR;
- return HAL_ERROR;
- }
- }
- /* Reset DMA Channel registers */
- hdma->Instance->CLBAR = 0U;
- hdma->Instance->CCR = 0U;
- hdma->Instance->CTR1 = 0U;
- hdma->Instance->CTR2 = 0U;
- hdma->Instance->CBR1 = 0U;
- hdma->Instance->CSAR = 0U;
- hdma->Instance->CDAR = 0U;
- hdma->Instance->CLLR = 0U;
- /* Reset 2D Addressing registers */
- if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
- {
- hdma->Instance->CTR3 = 0U;
- hdma->Instance->CBR2 = 0U;
- }
- /* Clear privilege attribute */
- CLEAR_BIT(p_dma_instance->PRIVCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
- #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
- /* Clear secure attribute */
- CLEAR_BIT(p_dma_instance->SECCFGR, (1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU)));
- #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
- /* Clear all flags */
- __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
- DMA_FLAG_TO));
- /* Clean all callbacks */
- hdma->XferCpltCallback = NULL;
- hdma->XferHalfCpltCallback = NULL;
- hdma->XferErrorCallback = NULL;
- hdma->XferAbortCallback = NULL;
- hdma->XferSuspendCallback = NULL;
- /* Clean DMA queue */
- hdma->LinkedListQueue = NULL;
- /* Clean DMA parent */
- if (hdma->Parent != NULL)
- {
- hdma->Parent = NULL;
- }
- /* Update DMA channel operation mode */
- hdma->Mode = DMA_NORMAL;
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_RESET;
- /* Release Lock */
- __HAL_UNLOCK(hdma);
- return HAL_OK;
- }
- /**
- * @}
- */
- /** @addtogroup DMA_Exported_Functions_Group2
- *
- @verbatim
- ======================================================================================================================
- ##### IO operation functions #####
- ======================================================================================================================
- [..]
- This section provides functions allowing to :
- (+) Configure the source, destination address and data size and Start DMA transfer in normal mode
- (+) Abort DMA transfer
- (+) Poll for transfer complete
- (+) Handle DMA interrupt request
- (+) Register and Unregister DMA callbacks
- [..]
- (+) The HAL_DMA_Start() function allows to start the DMA channel transfer in normal mode (Blocking mode).
- (+) The HAL_DMA_Start_IT() function allows to start the DMA channel transfer in normal mode (Non-blocking mode).
- (+) The HAL_DMA_Abort() function allows to abort any on-going transfer (Blocking mode).
- (+) The HAL_DMA_Abort_IT() function allows to abort any on-going transfer (Non-blocking mode).
- (+) The HAL_DMA_PollForTransfer() function allows to poll on half transfer and transfer complete (Blocking mode).
- This API cannot be used for circular transfers.
- (+) The HAL_DMA_IRQHandler() function allows to handle any DMA channel interrupt (Non-blocking mode).
- (+) The HAL_DMA_RegisterCallback() and HAL_DMA_UnRegisterCallback() functions allow respectively to register and
- unregister user customized callbacks.
- User callbacks are called under HAL_DMA_IRQHandler().
- @endverbatim
- * @{
- */
- /**
- * @brief Start the DMA channel transfer in normal mode (Blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
- * the specified DMA Channel.
- * @param SrcAddress : The source data address.
- * @param DstAddress : The destination data address.
- * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *const hdma,
- uint32_t SrcAddress,
- uint32_t DstAddress,
- uint32_t SrcDataSize)
- {
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the DMA Mode is DMA_NORMAL */
- if (hdma->Mode != DMA_NORMAL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
- /* Process locked */
- __HAL_LOCK(hdma);
- /* Check DMA channel state */
- if (hdma->State == HAL_DMA_STATE_READY)
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_BUSY;
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
- /* Configure the source address, destination address, the data size and clear flags */
- DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
- /* Enable DMA channel */
- __HAL_DMA_ENABLE(hdma);
- }
- else
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
- /* Process unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- return HAL_OK;
- }
- /**
- * @brief Starts the DMA channel transfer in normal mode with interrupts enabled (Non-blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param SrcAddress : The source data address.
- * @param DstAddress : The destination data address.
- * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *const hdma,
- uint32_t SrcAddress,
- uint32_t DstAddress,
- uint32_t SrcDataSize)
- {
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the DMA Mode is DMA_NORMAL */
- if (hdma->Mode != DMA_NORMAL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_BLOCK_SIZE(SrcDataSize));
- /* Process locked */
- __HAL_LOCK(hdma);
- /* Check DMA channel state */
- if (hdma->State == HAL_DMA_STATE_READY)
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_BUSY;
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NONE;
- /* Configure the source address, destination address, the data size and clear flags */
- DMA_SetConfig(hdma, SrcAddress, DstAddress, SrcDataSize);
- /* Enable common interrupts: Transfer Complete and Transfer Errors ITs */
- __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_DTE | DMA_IT_ULE | DMA_IT_USE | DMA_IT_TO));
- /* Check half transfer complete callback */
- if (hdma->XferHalfCpltCallback != NULL)
- {
- /* If Half Transfer complete callback is set, enable the corresponding IT */
- __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
- }
- /* Check Half suspend callback */
- if (hdma->XferSuspendCallback != NULL)
- {
- /* If Transfer suspend callback is set, enable the corresponding IT */
- __HAL_DMA_ENABLE_IT(hdma, DMA_IT_SUSP);
- }
- /* Enable DMA channel */
- __HAL_DMA_ENABLE(hdma);
- }
- else
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
- /* Process unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- return HAL_OK;
- }
- /**
- * @brief Abort any on-going DMA channel transfer (Blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @note After suspending a DMA channel, a wait until the DMA channel is effectively stopped is added. If a channel
- * is suspended while a data transfer is on-going, the current data will be transferred and the channel will be
- * effectively suspended only after the transfer of any on-going data is finished.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *const hdma)
- {
- /* Get tick number */
- uint32_t tickstart = HAL_GetTick();
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check DMA channel state */
- if (hdma->State != HAL_DMA_STATE_BUSY)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- else
- {
- /* Suspend the channel */
- hdma->Instance->CCR |= DMA_CCR_SUSP;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_SUSPEND;
- /* Check if the DMA Channel is suspended */
- while ((hdma->Instance->CSR & DMA_CSR_SUSPF) == 0U)
- {
- /* Check for the Timeout */
- if ((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_ERROR;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- }
- /* Reset the channel */
- hdma->Instance->CCR |= DMA_CCR_RESET;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_ABORT;
- /* Clear all status flags */
- __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
- DMA_FLAG_TO));
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- /* Clear remaining data size to ensure loading linked-list from memory next start */
- hdma->Instance->CBR1 = 0U;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- }
- return HAL_OK;
- }
- /**
- * @brief Abort any on-going DMA channel transfer in interrupt mode (Non-blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *const hdma)
- {
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check DMA channel state */
- if (hdma->State != HAL_DMA_STATE_BUSY)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
- return HAL_ERROR;
- }
- else
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_ABORT;
- /* Suspend the channel and activate suspend interrupt */
- hdma->Instance->CCR |= (DMA_CCR_SUSP | DMA_CCR_SUSPIE);
- }
- return HAL_OK;
- }
- /**
- * @brief Polling for transfer status (Blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param CompleteLevel : Specifies the DMA level complete.
- * @param Timeout : Timeout duration.
- * @retval HAL status
- */
- HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *const hdma,
- HAL_DMA_LevelCompleteTypeDef CompleteLevel,
- uint32_t Timeout)
- {
- /* Get tick number */
- uint32_t tickstart = HAL_GetTick();
- uint32_t level_flag;
- uint32_t tmp_csr;
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_LEVEL_COMPLETE(CompleteLevel));
- /* Check DMA channel state */
- if (hdma->State != HAL_DMA_STATE_BUSY)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- /* Polling mode is not supported in circular mode */
- if ((hdma->Mode & DMA_LINKEDLIST_CIRCULAR) == DMA_LINKEDLIST_CIRCULAR)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
- return HAL_ERROR;
- }
- /* Get the level transfer complete flag */
- level_flag = ((CompleteLevel == HAL_DMA_FULL_TRANSFER) ? DMA_FLAG_IDLE : DMA_FLAG_HT);
- /* Get DMA channel status */
- tmp_csr = hdma->Instance->CSR;
- while ((tmp_csr & level_flag) == 0U)
- {
- /* Check for the timeout */
- if (Timeout != HAL_MAX_DELAY)
- {
- if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;
- /*
- If timeout, abort the current transfer.
- Note that the Abort function will
- - Clear all transfer flags.
- - Unlock.
- - Set the State.
- */
- (void)HAL_DMA_Abort(hdma);
- return HAL_ERROR;
- }
- }
- /* Get a newer CSR register value */
- tmp_csr = hdma->Instance->CSR;
- }
- /* Check trigger overrun flag */
- if ((tmp_csr & DMA_FLAG_TO) != 0U)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_TO;
- /* Clear the error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
- }
- /* Check error flags */
- if ((tmp_csr & (DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE)) != 0U)
- {
- /* Check the data transfer error flag */
- if ((tmp_csr & DMA_FLAG_DTE) != 0U)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
- /* Clear the error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
- }
- /* Check the update link error flag */
- if ((tmp_csr & DMA_FLAG_ULE) != 0U)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
- /* Clear the error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
- }
- /* Check the user setting error flag */
- if ((tmp_csr & DMA_FLAG_USE) != 0U)
- {
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_USE;
- /* Clear the error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
- }
- /* Reset the channel */
- hdma->Instance->CCR |= DMA_CCR_RESET;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- return HAL_ERROR;
- }
- /* Clear the transfer level flag */
- if (CompleteLevel == HAL_DMA_HALF_TRANSFER)
- {
- /* Clear the Half Transfer flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
- }
- else if (CompleteLevel == HAL_DMA_FULL_TRANSFER)
- {
- /* Clear the transfer flags */
- __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- }
- /* Process unlocked */
- __HAL_UNLOCK(hdma);
- }
- else
- {
- return HAL_ERROR;
- }
- return HAL_OK;
- }
- /**
- * @brief Handle DMA interrupt request (Non-blocking mode).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval None.
- */
- void HAL_DMA_IRQHandler(DMA_HandleTypeDef *const hdma)
- {
- const DMA_TypeDef *p_dma_instance = GET_DMA_INSTANCE(hdma);
- uint32_t global_it_flag = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
- uint32_t global_active_flag_ns = IS_DMA_GLOBAL_ACTIVE_FLAG_NS(p_dma_instance, global_it_flag);
- #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
- uint32_t global_active_flag_s = IS_DMA_GLOBAL_ACTIVE_FLAG_S(p_dma_instance, global_it_flag);
- #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
- /* Global Interrupt Flag management *********************************************************************************/
- #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
- if ((global_active_flag_s == 0U) && (global_active_flag_ns == 0U))
- #else
- if (global_active_flag_ns == 0U)
- #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
- {
- return; /* the global interrupt flag for the current channel is down , nothing to do */
- }
- /* Data Transfer Error Interrupt management *************************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_DTE) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DTE) != 0U)
- {
- /* Clear the transfer error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_DTE);
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_DTE;
- }
- }
- /* Update Linked-list Error Interrupt management ********************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_ULE) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_ULE) != 0U)
- {
- /* Clear the update linked-list error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_ULE);
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_ULE;
- }
- }
- /* User Setting Error Interrupt management **************************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_USE) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_USE) != 0U)
- {
- /* Clear the user setting error flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_USE);
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_USE;
- }
- }
- /* Trigger Overrun Interrupt management *****************************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TO) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TO) != 0U)
- {
- /* Clear the trigger overrun flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TO);
- /* Update the DMA channel error code */
- hdma->ErrorCode |= HAL_DMA_ERROR_TO;
- }
- }
- /* Half Transfer Complete Interrupt management **********************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_HT) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
- {
- /* Clear the half transfer flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_HT);
- /* Check half transfer complete callback */
- if (hdma->XferHalfCpltCallback != NULL)
- {
- /* Half transfer callback */
- hdma->XferHalfCpltCallback(hdma);
- }
- }
- }
- /* Suspend Transfer Interrupt management ****************************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_SUSP) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_SUSP) != 0U)
- {
- /* Clear the block transfer complete flag */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_SUSP);
- /* Check DMA channel state */
- if (hdma->State == HAL_DMA_STATE_ABORT)
- {
- /* Disable the suspend transfer interrupt */
- __HAL_DMA_DISABLE_IT(hdma, DMA_IT_SUSP);
- /* Reset the channel internal state and reset the FIFO */
- hdma->Instance->CCR |= DMA_CCR_RESET;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- /* Clear remaining data size to ensure loading linked-list from memory next start */
- hdma->Instance->CBR1 = 0U;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- /* Check transfer abort callback */
- if (hdma->XferAbortCallback != NULL)
- {
- /* Transfer abort callback */
- hdma->XferAbortCallback(hdma);
- }
- return;
- }
- else
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_SUSPEND;
- /* Check transfer suspend callback */
- if (hdma->XferSuspendCallback != NULL)
- {
- /* Transfer suspend callback */
- hdma->XferSuspendCallback(hdma);
- }
- }
- }
- }
- /* Transfer Complete Interrupt management ***************************************************************************/
- if (__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U)
- {
- /* Check if interrupt source is enabled */
- if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
- {
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* If linked-list transfer */
- if (hdma->Instance->CLLR == 0U)
- {
- if (hdma->Instance->CBR1 == 0U)
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- }
- }
- }
- else
- {
- /* If normal transfer */
- if (hdma->Instance->CBR1 == 0U)
- {
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- }
- }
- /* Clear TC and HT transfer flags */
- __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- /* Check transfer complete callback */
- if (hdma->XferCpltCallback != NULL)
- {
- /* Channel Transfer Complete callback */
- hdma->XferCpltCallback(hdma);
- }
- }
- }
- /* Manage error case ************************************************************************************************/
- if (hdma->ErrorCode != HAL_DMA_ERROR_NONE)
- {
- /* Reset the channel internal state and reset the FIFO */
- hdma->Instance->CCR |= DMA_CCR_RESET;
- /* Update the DMA channel state */
- hdma->State = HAL_DMA_STATE_READY;
- /* Check DMA channel transfer mode */
- if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
- {
- /* Update the linked-list queue state */
- hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
- }
- /* Process Unlocked */
- __HAL_UNLOCK(hdma);
- /* Check transfer error callback */
- if (hdma->XferErrorCallback != NULL)
- {
- /* Transfer error callback */
- hdma->XferErrorCallback(hdma);
- }
- }
- }
- /**
- * @brief Register callback according to specified ID.
- * @note The HAL_DMA_RegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
- * to register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enumeration.
- * @param pCallback : Pointer to private callback function.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *const hdma,
- HAL_DMA_CallbackIDTypeDef CallbackID,
- void (*const pCallback)(DMA_HandleTypeDef *const _hdma))
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check DMA channel state */
- if (hdma->State == HAL_DMA_STATE_READY)
- {
- /* Check callback ID */
- switch (CallbackID)
- {
- case HAL_DMA_XFER_CPLT_CB_ID:
- {
- /* Register transfer complete callback */
- hdma->XferCpltCallback = pCallback;
- break;
- }
- case HAL_DMA_XFER_HALFCPLT_CB_ID:
- {
- /* Register half transfer callback */
- hdma->XferHalfCpltCallback = pCallback;
- break;
- }
- case HAL_DMA_XFER_ERROR_CB_ID:
- {
- /* Register transfer error callback */
- hdma->XferErrorCallback = pCallback;
- break;
- }
- case HAL_DMA_XFER_ABORT_CB_ID:
- {
- /* Register abort callback */
- hdma->XferAbortCallback = pCallback;
- break;
- }
- case HAL_DMA_XFER_SUSPEND_CB_ID:
- {
- /* Register suspend callback */
- hdma->XferSuspendCallback = pCallback;
- break;
- }
- default:
- {
- /* Update error status */
- status = HAL_ERROR;
- break;
- }
- }
- }
- else
- {
- /* Update error status */
- status = HAL_ERROR;
- }
- return status;
- }
- /**
- * @brief Unregister callback according to specified ID.
- * @note The HAL_DMA_UnRegisterCallback() may be called before HAL_DMA_Init() in HAL_DMA_STATE_RESET
- * to un-register callbacks for HAL_DMA_MSPINIT_CB_ID and HAL_DMA_MSPDEINIT_CB_ID.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param CallbackID : User Callback identifier which could be a value of HAL_DMA_CallbackIDTypeDef enum.
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *const hdma,
- HAL_DMA_CallbackIDTypeDef CallbackID)
- {
- HAL_StatusTypeDef status = HAL_OK;
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check DMA channel state */
- if (hdma->State == HAL_DMA_STATE_READY)
- {
- /* Check callback ID */
- switch (CallbackID)
- {
- case HAL_DMA_XFER_CPLT_CB_ID:
- {
- /* UnRegister transfer complete callback */
- hdma->XferCpltCallback = NULL;
- break;
- }
- case HAL_DMA_XFER_HALFCPLT_CB_ID:
- {
- /* UnRegister half transfer callback */
- hdma->XferHalfCpltCallback = NULL;
- break;
- }
- case HAL_DMA_XFER_ERROR_CB_ID:
- {
- /* UnRegister transfer error callback */
- hdma->XferErrorCallback = NULL;
- break;
- }
- case HAL_DMA_XFER_ABORT_CB_ID:
- {
- /* UnRegister abort callback */
- hdma->XferAbortCallback = NULL;
- break;
- }
- case HAL_DMA_XFER_SUSPEND_CB_ID:
- {
- /* UnRegister suspend callback */
- hdma->XferSuspendCallback = NULL;
- break;
- }
- case HAL_DMA_XFER_ALL_CB_ID:
- {
- /* UnRegister all available callbacks */
- hdma->XferCpltCallback = NULL;
- hdma->XferHalfCpltCallback = NULL;
- hdma->XferErrorCallback = NULL;
- hdma->XferAbortCallback = NULL;
- hdma->XferSuspendCallback = NULL;
- break;
- }
- default:
- {
- /* Update error status */
- status = HAL_ERROR;
- break;
- }
- }
- }
- else
- {
- /* Update error status */
- status = HAL_ERROR;
- }
- return status;
- }
- /**
- * @}
- */
- /** @addtogroup DMA_Exported_Functions_Group3
- *
- @verbatim
- ======================================================================================================================
- ##### State and Errors functions #####
- ======================================================================================================================
- [..]
- This section provides functions allowing to :
- (+) Check the DMA state
- (+) Get error code
- [..]
- (+) The HAL_DMA_GetState() function allows to get the DMA channel state.
- (+) The HAL_DMA_DeInit() function allows to get the DMA channel error code.
- @endverbatim
- * @{
- */
- /**
- * @brief Returns the DMA channel state.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval DMA state.
- */
- HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef const *const hdma)
- {
- /* Return the DMA channel state */
- return hdma->State;
- }
- /**
- * @brief Return the DMA channel error code.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval DMA Error Code.
- */
- uint32_t HAL_DMA_GetError(DMA_HandleTypeDef const *const hdma)
- {
- /* Return the DMA channel error code */
- return hdma->ErrorCode;
- }
- /**
- * @}
- */
- /** @addtogroup DMA_Exported_Functions_Group4
- *
- @verbatim
- ======================================================================================================================
- ##### DMA Attributes functions #####
- ======================================================================================================================
- [..]
- This section provides functions allowing to :
- (+) Configure DMA channel secure and privilege attributes.
- (+) Get DMA channel secure and privilege attributes.
- (+) Lock DMA channel secure and privilege attributes configuration.
- (+) Check whether DMA channel secure and privilege attributes configuration is locked or not.
- [..]
- (+) The HAL_DMA_ConfigChannelAttributes() function allows to configure DMA channel security and privilege
- attributes.
- (+) The HAL_DMA_GetConfigChannelAttributes() function allows to get DMA channel security and privilege attributes
- configuration.
- (+) The HAL_DMA_LockChannelAttributes() function allows to lock the DMA channel security and privilege attributes.
- (+) The HAL_DMA_GetLockChannelAttributes() function allows to get the DMA channel security and privilege
- attributes lock status.
- @endverbatim
- * @{
- */
- /**
- * @brief Configure the DMA channel security and privilege attribute(s).
- * @note These attributes cannot be modified when the corresponding lock state is enabled.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for
- * the specified DMA Channel.
- * @param ChannelAttributes : Specifies the DMA channel secure/privilege attributes.
- * This parameter can be a one or a combination of @ref DMA_Channel_Attributes.
- * @retval HAL Status.
- */
- HAL_StatusTypeDef HAL_DMA_ConfigChannelAttributes(DMA_HandleTypeDef *const hdma, uint32_t ChannelAttributes)
- {
- DMA_TypeDef *p_dma_instance;
- uint32_t channel_idx;
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Check the parameters */
- assert_param(IS_DMA_ATTRIBUTES(ChannelAttributes));
- /* Get DMA instance */
- p_dma_instance = GET_DMA_INSTANCE(hdma);
- /* Get channel index */
- channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
- /* Check DMA channel privilege attribute management */
- if ((ChannelAttributes & DMA_CHANNEL_ATTR_PRIV_MASK) == DMA_CHANNEL_ATTR_PRIV_MASK)
- {
- /* Configure DMA channel privilege attribute */
- if ((ChannelAttributes & DMA_CHANNEL_PRIV) == DMA_CHANNEL_PRIV)
- {
- p_dma_instance->PRIVCFGR |= channel_idx;
- }
- else
- {
- p_dma_instance->PRIVCFGR &= (~channel_idx);
- }
- }
- #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
- /* Check DMA channel security attribute management */
- if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_MASK) == DMA_CHANNEL_ATTR_SEC_MASK)
- {
- /* Configure DMA channel security attribute */
- if ((ChannelAttributes & DMA_CHANNEL_SEC) == DMA_CHANNEL_SEC)
- {
- p_dma_instance->SECCFGR |= channel_idx;
- }
- else
- {
- p_dma_instance->SECCFGR &= (~channel_idx);
- }
- }
- /* Channel source security attribute management */
- if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_SRC_MASK) == DMA_CHANNEL_ATTR_SEC_SRC_MASK)
- {
- /* Configure DMA channel source security attribute */
- if ((ChannelAttributes & DMA_CHANNEL_SRC_SEC) == DMA_CHANNEL_SRC_SEC)
- {
- hdma->Instance->CTR1 |= DMA_CTR1_SSEC;
- }
- else
- {
- hdma->Instance->CTR1 &= (~DMA_CTR1_SSEC);
- }
- }
- /* Channel destination security attribute management */
- if ((ChannelAttributes & DMA_CHANNEL_ATTR_SEC_DEST_MASK) == DMA_CHANNEL_ATTR_SEC_DEST_MASK)
- {
- /* Configure DMA channel destination security attribute */
- if ((ChannelAttributes & DMA_CHANNEL_DEST_SEC) == DMA_CHANNEL_DEST_SEC)
- {
- hdma->Instance->CTR1 |= DMA_CTR1_DSEC;
- }
- else
- {
- hdma->Instance->CTR1 &= (~DMA_CTR1_DSEC);
- }
- }
- #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
- return HAL_OK;
- }
- /**
- * @brief Get the DMA channel security and privilege attributes.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information
- * for the specified DMA Channel.
- * @param pChannelAttributes : Pointer to the returned attributes.
- * @retval HAL Status.
- */
- HAL_StatusTypeDef HAL_DMA_GetConfigChannelAttributes(DMA_HandleTypeDef const *const hdma,
- uint32_t *const pChannelAttributes)
- {
- const DMA_TypeDef *p_dma_instance;
- uint32_t attributes;
- uint32_t channel_idx;
- /* Check the DMA peripheral handle and channel attributes parameters */
- if ((hdma == NULL) || (pChannelAttributes == NULL))
- {
- return HAL_ERROR;
- }
- /* Get DMA instance */
- p_dma_instance = GET_DMA_INSTANCE(hdma);
- /* Get channel index */
- channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
- /* Get DMA channel privilege attribute */
- attributes = ((p_dma_instance->PRIVCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NPRIV : DMA_CHANNEL_PRIV;
- #if defined (DMA_SECCFGR_SEC0)
- /* Get DMA channel security attribute */
- attributes |= ((p_dma_instance->SECCFGR & channel_idx) == 0U) ? DMA_CHANNEL_NSEC : DMA_CHANNEL_SEC;
- /* Get DMA channel source security attribute */
- attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_SSEC) == 0U) ? DMA_CHANNEL_SRC_NSEC : DMA_CHANNEL_SRC_SEC;
- /* Get DMA channel destination security attribute */
- attributes |= ((hdma->Instance->CTR1 & DMA_CTR1_DSEC) == 0U) ? DMA_CHANNEL_DEST_NSEC : DMA_CHANNEL_DEST_SEC;
- #endif /* DMA_SECCFGR_SEC0 */
- /* return value */
- *pChannelAttributes = attributes;
- return HAL_OK;
- }
- #if defined (DMA_RCFGLOCKR_LOCK0)
- #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
- /**
- * @brief Lock the DMA channel security and privilege attribute(s).
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval HAL Status.
- */
- HAL_StatusTypeDef HAL_DMA_LockChannelAttributes(DMA_HandleTypeDef const *const hdma)
- {
- DMA_TypeDef *p_dma_instance;
- uint32_t channel_idx;
- /* Check the DMA peripheral handle parameter */
- if (hdma == NULL)
- {
- return HAL_ERROR;
- }
- /* Get DMA instance */
- p_dma_instance = GET_DMA_INSTANCE(hdma);
- /* Get channel index */
- channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
- /* Lock the DMA channel privilege and security attributes */
- p_dma_instance->RCFGLOCKR |= channel_idx;
- return HAL_OK;
- }
- #endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
- /**
- * @brief Get the security and privilege attribute lock state of a DMA channel.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param pLockState : Pointer to lock state (returned value can be DMA_CHANNEL_ATTRIBUTE_UNLOCKED or
- * DMA_CHANNEL_ATTRIBUTE_LOCKED).
- * @retval HAL status.
- */
- HAL_StatusTypeDef HAL_DMA_GetLockChannelAttributes(DMA_HandleTypeDef const *const hdma, uint32_t *const pLockState)
- {
- const DMA_TypeDef *p_dma_instance;
- uint32_t channel_idx;
- /* Check the DMA peripheral handle and lock state parameters */
- if ((hdma == NULL) || (pLockState == NULL))
- {
- return HAL_ERROR;
- }
- /* Get DMA instance */
- p_dma_instance = GET_DMA_INSTANCE(hdma);
- /* Get channel index */
- channel_idx = 1UL << (GET_DMA_CHANNEL(hdma) & 0x1FU);
- /* Get channel lock attribute state */
- *pLockState = ((p_dma_instance->RCFGLOCKR & channel_idx) == 0U) ? DMA_CHANNEL_ATTRIBUTE_UNLOCKED : \
- DMA_CHANNEL_ATTRIBUTE_LOCKED;
- return HAL_OK;
- }
- #endif /* DMA_RCFGLOCKR_LOCK0 */
- /**
- * @}
- */
- /**
- * @}
- */
- /* Private functions -------------------------------------------------------------------------------------------------*/
- /** @defgroup DMA_Private_Functions DMA Private Functions
- * @brief DMA Private Functions
- * @{
- */
- /**
- * @brief Set the DMA channel normal transfer parameters.
- * @param hdma : Pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @param SrcAddress : The source data address.
- * @param DstAddress : The destination data address.
- * @param SrcDataSize : The length of data to be transferred from source to destination in bytes.
- * @retval None.
- */
- static void DMA_SetConfig(DMA_HandleTypeDef const *const hdma,
- uint32_t SrcAddress,
- uint32_t DstAddress,
- uint32_t SrcDataSize)
- {
- /* Configure the DMA channel data size */
- MODIFY_REG(hdma->Instance->CBR1, DMA_CBR1_BNDT, (SrcDataSize & DMA_CBR1_BNDT));
- /* Clear all interrupt flags */
- __HAL_DMA_CLEAR_FLAG(hdma, DMA_FLAG_TC | DMA_FLAG_HT | DMA_FLAG_DTE | DMA_FLAG_ULE | DMA_FLAG_USE | DMA_FLAG_SUSP |
- DMA_FLAG_TO);
- /* Configure DMA channel source address */
- hdma->Instance->CSAR = SrcAddress;
- /* Configure DMA channel destination address */
- hdma->Instance->CDAR = DstAddress;
- }
- /**
- * @brief Initialize the DMA channel in normal mode according to the specified parameters in the DMA_InitTypeDef.
- * @param hdma : pointer to a DMA_HandleTypeDef structure that contains the configuration information for the
- * specified DMA Channel.
- * @retval None.
- */
- static void DMA_Init(DMA_HandleTypeDef const *const hdma)
- {
- uint32_t tmpreg;
- /* Prepare DMA Channel Control Register (CCR) value *****************************************************************/
- tmpreg = hdma->Init.Priority;
- /* Write DMA Channel Control Register (CCR) */
- MODIFY_REG(hdma->Instance->CCR, DMA_CCR_PRIO | DMA_CCR_LAP | DMA_CCR_LSM, tmpreg);
- /* Prepare DMA Channel Transfer Register (CTR1) value ***************************************************************/
- tmpreg = hdma->Init.DestInc | hdma->Init.DestDataWidth | hdma->Init.SrcInc | hdma->Init.SrcDataWidth;
- /* Add parameters specific to GPDMA */
- if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
- {
- tmpreg |= (hdma->Init.TransferAllocatedPort |
- (((hdma->Init.DestBurstLength - 1U) << DMA_CTR1_DBL_1_Pos) & DMA_CTR1_DBL_1) |
- (((hdma->Init.SrcBurstLength - 1U) << DMA_CTR1_SBL_1_Pos) & DMA_CTR1_SBL_1));
- }
- /* Write DMA Channel Transfer Register 1 (CTR1) */
- #if defined (DMA_CTR1_SSEC)
- MODIFY_REG(hdma->Instance->CTR1, ~(DMA_CTR1_SSEC | DMA_CTR1_DSEC), tmpreg);
- #else
- WRITE_REG(hdma->Instance->CTR1, tmpreg);
- #endif /* DMA_CTR1_SSEC */
- /* Prepare DMA Channel Transfer Register 2 (CTR2) value *************************************************************/
- tmpreg = hdma->Init.BlkHWRequest | (hdma->Init.Request & DMA_CTR2_REQSEL) | hdma->Init.TransferEventMode;
- /* Memory to Peripheral Transfer */
- if ((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
- {
- if (IS_GPDMA_INSTANCE(hdma->Instance) != 0U)
- {
- tmpreg |= DMA_CTR2_DREQ;
- }
- }
- /* Memory to Memory Transfer */
- else if ((hdma->Init.Direction) == DMA_MEMORY_TO_MEMORY)
- {
- tmpreg |= DMA_CTR2_SWREQ;
- }
- else
- {
- /* Nothing to do */
- }
- /* Set DMA channel operation mode */
- tmpreg |= hdma->Init.Mode;
- /* Write DMA Channel Transfer Register 2 (CTR2) */
- MODIFY_REG(hdma->Instance->CTR2, (DMA_CTR2_TCEM | DMA_CTR2_TRIGPOL | DMA_CTR2_TRIGSEL | DMA_CTR2_TRIGM |
- DMA_CTR2_PFREQ | DMA_CTR2_BREQ | DMA_CTR2_DREQ | DMA_CTR2_SWREQ |
- DMA_CTR2_REQSEL), tmpreg);
- /* Write DMA Channel Block Register 1 (CBR1) ************************************************************************/
- WRITE_REG(hdma->Instance->CBR1, 0U);
- /* If 2D Addressing is supported by current channel */
- if (IS_DMA_2D_ADDRESSING_INSTANCE(hdma->Instance) != 0U)
- {
- /* Write DMA Channel Transfer Register 3 (CTR3) *******************************************************************/
- WRITE_REG(hdma->Instance->CTR3, 0U);
- /* Write DMA Channel Block Register 2 (CBR2) **********************************************************************/
- WRITE_REG(hdma->Instance->CBR2, 0U);
- }
- /* Write DMA Channel linked-list address register (CLLR) ************************************************************/
- WRITE_REG(hdma->Instance->CLLR, 0U);
- }
- /**
- * @}
- */
- #endif /* HAL_DMA_MODULE_ENABLED */
- /**
- * @}
- */
- /**
- * @}
- */
|