stm32h7xx_hal_mdma.c 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_hal_mdma.c
  4. * @author MCD Application Team
  5. * @version V1.0.0
  6. * @date 21-April-2017
  7. * @brief This file provides firmware functions to manage the following
  8. * functionalities of the Master Direct Memory Access (MDMA) peripheral:
  9. * + Initialization/de-initialization functions
  10. * + I/O operation functions
  11. * + Peripheral State and errors functions
  12. @verbatim
  13. ==============================================================================
  14. ##### How to use this driver #####
  15. ==============================================================================
  16. [..]
  17. (#) Enable and configure the peripheral to be connected to the MDMA Channel
  18. (except for internal SRAM/FLASH memories: no initialization is
  19. necessary) please refer to Reference manual for connection between peripherals
  20. and MDMA requests.
  21. (#)
  22. For a given Channel use HAL_MDMA_Init function to program the required configuration through the following parameters:
  23. transfer request , channel priority, data endianness, Source increment, destination increment ,
  24. source data size, destination data size, data alignment, source Burst, destination Burst ,
  25. buffer Transfer Length, Transfer Trigger Mode (buffer transfer, block transfer, repeated block transfer
  26. or full transfer) source and destination block address offset, mask address and data.
  27. If using the MDMA in linked list mode then use function HAL_MDMA_LinkedList_CreateNode to fill a transfer node.
  28. Note that parameters given to the function HAL_MDMA_Init corresponds always to the node zero.
  29. Use function HAL_MDMA_LinkedList_AddNode to connect the created node to the linked list at a given position.
  30. User can make a linked list circular using function HAL_MDMA_LinkedList_EnableCircularMode , this function will automatically connect the
  31. last node of the list to the first one in order to make the list circular.
  32. In this case the linked list will loop on node 1 : first node connected after the initial transfer defined by the HAL_MDMA_Init
  33. -@- The initial transfer itself (node 0 corresponding to the Init).
  34. User can disable the circular mode using function HAL_MDMA_LinkedList_DisableCircularMode, this function will then remove
  35. the connection between last node and first one.
  36. Function HAL_MDMA_LinkedList_RemoveNode can be used to remove (disconnect) a node from the transfer linked list.
  37. When a linked list is circular (last node connected to first one), if removing node1 (node where the linked list loops),
  38. the linked list remains circular and node 2 becomes the first one.
  39. Note that if the linked list is made circular the transfer will loop infinitely (or until aborted by the user).
  40. [..]
  41. (+) User can select the transfer trigger mode (parameter TransferTriggerMode) to define the amount of data to be
  42. transfer upon a request :
  43. (++) MDMA_BUFFER_TRANSFER : each request triggers a transfer of BufferTransferLength data
  44. with BufferTransferLength defined within the HAL_MDMA_Init.
  45. (++) MDMA_BLOCK_TRANSFER : each request triggers a transfer of a block
  46. with block size defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT
  47. or within the current linked list node parameters.
  48. (++) MDMA_REPEAT_BLOCK_TRANSFER : each request triggers a transfer of a number of blocks
  49. with block size and number of blocks defined within the function HAL_MDMA_Start/HAL_MDMA_Start_IT
  50. or within the current linked list node parameters.
  51. (++) MDMA_FULL_TRANSFER : each request triggers a full transfer
  52. all blocks and all nodes(if a linked list has been created using HAL_MDMA_LinkedList_CreateNode \ HAL_MDMA_LinkedList_AddNode).
  53. *** Polling mode IO operation ***
  54. =================================
  55. [..]
  56. (+) Use HAL_MDMA_Start() to start MDMA transfer after the configuration of Source
  57. address and destination address and the Length of data to be transferred.
  58. (+) Use HAL_MDMA_PollForTransfer() to poll for the end of current transfer or a transfer level
  59. In this case a fixed Timeout can be configured by User depending from his application.
  60. (+) Use HAL_MDMA_Abort() function to abort the current transfer : blocking method this API returns
  61. when the abort ends or timeout (should not be called from an interrupt service routine).
  62. *** Interrupt mode IO operation ***
  63. ===================================
  64. [..]
  65. (+) Configure the MDMA interrupt priority using HAL_NVIC_SetPriority()
  66. (+) Enable the MDMA IRQ handler using HAL_NVIC_EnableIRQ()
  67. (+) Use HAL_MDMA_Start_IT() to start MDMA transfer after the configuration of
  68. Source address and destination address and the Length of data to be transferred. In this
  69. case the MDMA interrupt is configured.
  70. (+) Use HAL_MDMA_IRQHandler() called under MDMA_IRQHandler() Interrupt subroutine
  71. (+) At the end of data transfer HAL_MDMA_IRQHandler() function is executed and user can
  72. add his own function by customization of function pointer XferCpltCallback and
  73. XferErrorCallback (i.e a member of MDMA handle structure).
  74. (+) Use HAL_MDMA_Abort_IT() function to abort the current transfer : non-blocking method. This API returns immediately
  75. then the callback XferAbortCallback (if specified by the user) is asserted once the MDMA channel hase effectively aborted.
  76. (could be called from an interrupt service routine).
  77. (+) Use functions HAL_MDMA_RegisterCallback and HAL_MDMA_UnRegisterCallback respectevely to register unregister user callbacks
  78. from the following list :
  79. (++) XferCpltCallback : transfer complete callback.
  80. (++) XferBufferCpltCallback : buffer transfer complete callback.
  81. (++) XferBlockCpltCallback : block transfer complete callback.
  82. (++) XferRepeatBlockCpltCallback : repeated block transfer complete callback.
  83. (++) XferErrorCallback : transfer error callback.
  84. (++) XferAbortCallback : transfer abort complete callback.
  85. [..]
  86. (+) If the transfer Request corresponds to SW request (MDMA_REQUEST_SW) User can use function HAL_MDMA_GenerateSWRequest to
  87. trigger requests manually. Function HAL_MDMA_GenerateSWRequest must be used with the following precautions:
  88. (++) This function returns an error if used while the Transfer hase ends or not started.
  89. (++) If used while the current request hase not been served yet (current request transfer on going)
  90. this function returns an error and the new request is ignored.
  91. Generally this function should be used in conjunctions with the MDMA callbacks:
  92. (++) example 1:
  93. (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BUFFER_TRANSFER
  94. (+++) Register a callback for buffer transfer complete (using callback ID set to HAL_MDMA_XFER_BUFFERCPLT_CB_ID)
  95. (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first BufferTransferLength data.
  96. (+++) When the buffer transfer complete callback is asserted first buffer hase been transferred and user can ask for a new buffer transfer
  97. request using HAL_MDMA_GenerateSWRequest.
  98. (++) example 2:
  99. (+++) Configure a transfer with request set to MDMA_REQUEST_SW and trigger mode set to MDMA_BLOCK_TRANSFER
  100. (+++) Register a callback for block transfer complete (using callback ID HAL_MDMA_XFER_BLOCKCPLT_CB_ID)
  101. (+++) After calling HAL_MDMA_Start_IT the MDMA will issue the transfer of a first block of data.
  102. (+++) When the block transfer complete callback is asserted the fisrt block hase been transferred and user can ask
  103. for a new block transfer request using HAL_MDMA_GenerateSWRequest.
  104. [..] Use HAL_MDMA_GetState() function to return the MDMA state and HAL_MDMA_GetError() in case of error detection.
  105. *** MDMA HAL driver macros list ***
  106. =============================================
  107. [..]
  108. Below the list of most used macros in MDMA HAL driver.
  109. (+) __HAL_MDMA_ENABLE: Enable the specified MDMA Stream.
  110. (+) __HAL_MDMA_DISABLE: Disable the specified MDMA Stream.
  111. (+) __HAL_MDMA_GET_FLAG: Get the MDMA Stream pending flags.
  112. (+) __HAL_MDMA_CLEAR_FLAG: Clear the MDMA Stream pending flags.
  113. (+) __HAL_MDMA_ENABLE_IT: Enable the specified MDMA Stream interrupts.
  114. (+) __HAL_MDMA_DISABLE_IT: Disable the specified MDMA Stream interrupts.
  115. (+) __HAL_MDMA_GET_IT_SOURCE: Check whether the specified MDMA Stream interrupt has occurred or not.
  116. [..]
  117. (@) You can refer to the header file of the MDMA HAL driver for more useful macros.
  118. [..]
  119. @endverbatim
  120. ******************************************************************************
  121. * @attention
  122. *
  123. * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
  124. *
  125. * Redistribution and use in source and binary forms, with or without modification,
  126. * are permitted provided that the following conditions are met:
  127. * 1. Redistributions of source code must retain the above copyright notice,
  128. * this list of conditions and the following disclaimer.
  129. * 2. Redistributions in binary form must reproduce the above copyright notice,
  130. * this list of conditions and the following disclaimer in the documentation
  131. * and/or other materials provided with the distribution.
  132. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  133. * may be used to endorse or promote products derived from this software
  134. * without specific prior written permission.
  135. *
  136. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  137. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  138. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  139. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  140. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  141. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  142. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  143. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  144. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  145. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  146. *
  147. ******************************************************************************
  148. */
  149. /* Includes ------------------------------------------------------------------*/
  150. #include "stm32h7xx_hal.h"
  151. /** @addtogroup STM32H7xx_HAL_Driver
  152. * @{
  153. */
  154. /** @defgroup MDMA MDMA
  155. * @brief MDMA HAL module driver
  156. * @{
  157. */
  158. #ifdef HAL_MDMA_MODULE_ENABLED
  159. /* Private typedef -----------------------------------------------------------*/
  160. /* Private constants ---------------------------------------------------------*/
  161. /** @addtogroup MDMA_Private_Constants
  162. * @{
  163. */
  164. #define HAL_TIMEOUT_MDMA_ABORT ((uint32_t)5U) /* 5 ms */
  165. #define HAL_MDMA_CHANNEL_SIZE ((uint32_t)0x40U) /* an MDMA instance channel size is 64 byte */
  166. /**
  167. * @}
  168. */
  169. /* Private macro -------------------------------------------------------------*/
  170. /* Private variables ---------------------------------------------------------*/
  171. /* Private function prototypes -----------------------------------------------*/
  172. /** @addtogroup MDMA_Private_Functions_Prototypes
  173. * @{
  174. */
  175. static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount);
  176. static void MDMA_Init(MDMA_HandleTypeDef *hmdma);
  177. /**
  178. * @}
  179. */
  180. /** @addtogroup MDMA_Exported_Functions MDMA Exported Functions
  181. * @{
  182. */
  183. /** @addtogroup MDMA_Exported_Functions_Group1
  184. *
  185. @verbatim
  186. ===============================================================================
  187. ##### Initialization and de-initialization functions #####
  188. ===============================================================================
  189. [..]
  190. This section provides functions allowing to :
  191. Initialize and de-initialize the MDMA channel.
  192. Register and Unregister MDMA callbacks
  193. [..]
  194. The HAL_MDMA_Init() function follows the MDMA channel configuration procedures as described in
  195. reference manual.
  196. The HAL_MDMA_DeInit function allows to deinitialize the MDMA channel.
  197. HAL_MDMA_RegisterCallback and HAL_MDMA_UnRegisterCallback functions allows
  198. respectevely to register/unregister an MDMA callback function.
  199. @endverbatim
  200. * @{
  201. */
  202. /**
  203. * @brief Initializes the MDMA according to the specified
  204. * parameters in the MDMA_InitTypeDef and create the associated handle.
  205. * @param hmdma: Pointer to a MDMA_HandleTypeDef structure that contains
  206. * the configuration information for the specified MDMA Stream.
  207. * @retval HAL status
  208. */
  209. HAL_StatusTypeDef HAL_MDMA_Init(MDMA_HandleTypeDef *hmdma)
  210. {
  211. uint32_t tickstart = HAL_GetTick();
  212. /* Check the MDMA peripheral handle */
  213. if(hmdma == NULL)
  214. {
  215. return HAL_ERROR;
  216. }
  217. /* Check the parameters */
  218. assert_param(IS_MDMA_STREAM_ALL_INSTANCE(hmdma->Instance));
  219. assert_param(IS_MDMA_PRIORITY(hmdma->Init.Priority));
  220. assert_param(IS_MDMA_ENDIANNESS_MODE(hmdma->Init.Endianness));
  221. assert_param(IS_MDMA_REQUEST(hmdma->Init.Request));
  222. assert_param(IS_MDMA_SOURCE_INC(hmdma->Init.SourceInc));
  223. assert_param(IS_MDMA_DESTINATION_INC(hmdma->Init.DestinationInc));
  224. assert_param(IS_MDMA_SOURCE_DATASIZE(hmdma->Init.SourceDataSize));
  225. assert_param(IS_MDMA_DESTINATION_DATASIZE(hmdma->Init.DestDataSize));
  226. assert_param(IS_MDMA_DATA_ALIGNMENT(hmdma->Init.DataAlignment));
  227. assert_param(IS_MDMA_SOURCE_BURST(hmdma->Init.SourceBurst));
  228. assert_param(IS_MDMA_DESTINATION_BURST(hmdma->Init.DestBurst));
  229. assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(hmdma->Init.BufferTransferLength));
  230. assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(hmdma->Init.TransferTriggerMode));
  231. assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.SourceBlockAddressOffset));
  232. assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(hmdma->Init.DestBlockAddressOffset));
  233. /* Allocate lock resource */
  234. __HAL_UNLOCK(hmdma);
  235. /* Change MDMA peripheral state */
  236. hmdma->State = HAL_MDMA_STATE_BUSY;
  237. /* Disable the MDMA channel */
  238. __HAL_MDMA_DISABLE(hmdma);
  239. /* Check if the MDMA channel is effectively disabled */
  240. while((hmdma->Instance->CCR & MDMA_CCR_EN) != RESET)
  241. {
  242. /* Check for the Timeout */
  243. if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_MDMA_ABORT)
  244. {
  245. /* Update error code */
  246. hmdma->ErrorCode = HAL_MDMA_ERROR_TIMEOUT;
  247. /* Change the MDMA state */
  248. hmdma->State = HAL_MDMA_STATE_ERROR;
  249. return HAL_ERROR;
  250. }
  251. }
  252. /* Init MDMA channel registers */
  253. MDMA_Init(hmdma);
  254. /* Reset the MDMA first/last linkedlist node addresses and node counter */
  255. hmdma->FirstLinkedListNodeAddress = 0;
  256. hmdma->LastLinkedListNodeAddress = 0;
  257. hmdma->LinkedListNodeCounter = 0;
  258. /* Initialise the error code */
  259. hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
  260. /* Initialize the MDMA state */
  261. hmdma->State = HAL_MDMA_STATE_READY;
  262. return HAL_OK;
  263. }
  264. /**
  265. * @brief DeInitializes the MDMA peripheral
  266. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  267. * the configuration information for the specified MDMA Stream.
  268. * @retval HAL status
  269. */
  270. HAL_StatusTypeDef HAL_MDMA_DeInit(MDMA_HandleTypeDef *hmdma)
  271. {
  272. /* Check the MDMA peripheral handle */
  273. if(hmdma == NULL)
  274. {
  275. return HAL_ERROR;
  276. }
  277. /* Check the MDMA peripheral state */
  278. if(hmdma->State == HAL_MDMA_STATE_BUSY)
  279. {
  280. hmdma->ErrorCode = HAL_MDMA_ERROR_BUSY;
  281. return HAL_ERROR;
  282. }
  283. /* Disable the selected MDMA Channelx */
  284. __HAL_MDMA_DISABLE(hmdma);
  285. /* Reset MDMA Channel control register */
  286. hmdma->Instance->CCR = 0;
  287. hmdma->Instance->CTCR = 0;
  288. hmdma->Instance->CBNDTR = 0;
  289. hmdma->Instance->CSAR = 0;
  290. hmdma->Instance->CDAR = 0;
  291. hmdma->Instance->CBRUR = 0;
  292. hmdma->Instance->CLAR = 0;
  293. hmdma->Instance->CTBR = 0;
  294. hmdma->Instance->CMAR = 0;
  295. hmdma->Instance->CMDR = 0;
  296. /* Clear all flags */
  297. __HAL_MDMA_CLEAR_FLAG(hmdma,(MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC));
  298. /* Reset the MDMA first/last linkedlist node addresses and node counter */
  299. hmdma->FirstLinkedListNodeAddress = 0;
  300. hmdma->LastLinkedListNodeAddress = 0;
  301. hmdma->LinkedListNodeCounter = 0;
  302. /* Initialise the error code */
  303. hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
  304. /* Initialize the MDMA state */
  305. hmdma->State = HAL_MDMA_STATE_RESET;
  306. /* Release Lock */
  307. __HAL_UNLOCK(hmdma);
  308. return HAL_OK;
  309. }
  310. /**
  311. * @brief Config the Post request Mask address and Mask data
  312. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  313. * the configuration information for the specified MDMA Channel.
  314. * @param MaskAddress: specifies the address to be updated (written) with MaskData after a request is served.
  315. * @param MaskData: specifies the value to be written to MaskAddress after a request is served.
  316. * MaskAddress and MaskData could be used to automatically clear a peripheral flag when the request is served.
  317. * @retval HAL status
  318. */
  319. HAL_StatusTypeDef HAL_MDMA_ConfigPostRequestMask(MDMA_HandleTypeDef *hmdma, uint32_t MaskAddress, uint32_t MaskData)
  320. {
  321. HAL_StatusTypeDef status = HAL_OK;
  322. /* Check the MDMA peripheral handle */
  323. if(hmdma == NULL)
  324. {
  325. return HAL_ERROR;
  326. }
  327. /* Process locked */
  328. __HAL_LOCK(hmdma);
  329. if(HAL_MDMA_STATE_READY == hmdma->State)
  330. {
  331. /* if HW request set Post Request MaskAddress and MaskData, */
  332. if((hmdma->Instance->CTCR & MDMA_CTCR_SWRM) == 0)
  333. {
  334. /* Set the HW request clear Mask and Data */
  335. hmdma->Instance->CMAR = MaskAddress;
  336. hmdma->Instance->CMDR = MaskData;
  337. /*
  338. -If the request is done by SW : BWM could be set to 1 or 0.
  339. -If the request is done by a peripheral :
  340. If mask address not set (0) => BWM must be set to 0
  341. If mask address set (different than 0) => BWM could be set to 1 or 0
  342. */
  343. if(MaskAddress == 0)
  344. {
  345. hmdma->Instance->CTCR &= ~MDMA_CTCR_BWM;
  346. }
  347. else
  348. {
  349. hmdma->Instance->CTCR |= MDMA_CTCR_BWM;
  350. }
  351. }
  352. else
  353. {
  354. /* Return error status */
  355. status = HAL_ERROR;
  356. }
  357. }
  358. else
  359. {
  360. /* Return error status */
  361. status = HAL_ERROR;
  362. }
  363. /* Release Lock */
  364. __HAL_UNLOCK(hmdma);
  365. return status;
  366. }
  367. /**
  368. * @brief Register callbacks
  369. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  370. * the configuration information for the specified MDMA Channel.
  371. * @param CallbackID: User Callback identifier
  372. * @param pCallback: pointer to callbacsk function.
  373. * @retval HAL status
  374. */
  375. HAL_StatusTypeDef HAL_MDMA_RegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID, void (* pCallback)(MDMA_HandleTypeDef *_hmdma))
  376. {
  377. HAL_StatusTypeDef status = HAL_OK;
  378. /* Check the MDMA peripheral handle */
  379. if(hmdma == NULL)
  380. {
  381. return HAL_ERROR;
  382. }
  383. /* Process locked */
  384. __HAL_LOCK(hmdma);
  385. if(HAL_MDMA_STATE_READY == hmdma->State)
  386. {
  387. switch (CallbackID)
  388. {
  389. case HAL_MDMA_XFER_CPLT_CB_ID:
  390. hmdma->XferCpltCallback = pCallback;
  391. break;
  392. case HAL_MDMA_XFER_BUFFERCPLT_CB_ID:
  393. hmdma->XferBufferCpltCallback = pCallback;
  394. break;
  395. case HAL_MDMA_XFER_BLOCKCPLT_CB_ID:
  396. hmdma->XferBlockCpltCallback = pCallback;
  397. break;
  398. case HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID:
  399. hmdma->XferRepeatBlockCpltCallback = pCallback;
  400. break;
  401. case HAL_MDMA_XFER_ERROR_CB_ID:
  402. hmdma->XferErrorCallback = pCallback;
  403. break;
  404. case HAL_MDMA_XFER_ABORT_CB_ID:
  405. hmdma->XferAbortCallback = pCallback;
  406. break;
  407. default:
  408. break;
  409. }
  410. }
  411. else
  412. {
  413. /* Return error status */
  414. status = HAL_ERROR;
  415. }
  416. /* Release Lock */
  417. __HAL_UNLOCK(hmdma);
  418. return status;
  419. }
  420. /**
  421. * @brief UnRegister callbacks
  422. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  423. * the configuration information for the specified MDMA Channel.
  424. * @param CallbackID: User Callback identifier
  425. * a HAL_MDMA_CallbackIDTypeDef ENUM as parameter.
  426. * @retval HAL status
  427. */
  428. HAL_StatusTypeDef HAL_MDMA_UnRegisterCallback(MDMA_HandleTypeDef *hmdma, HAL_MDMA_CallbackIDTypeDef CallbackID)
  429. {
  430. HAL_StatusTypeDef status = HAL_OK;
  431. /* Check the MDMA peripheral handle */
  432. if(hmdma == NULL)
  433. {
  434. return HAL_ERROR;
  435. }
  436. /* Process locked */
  437. __HAL_LOCK(hmdma);
  438. if(HAL_MDMA_STATE_READY == hmdma->State)
  439. {
  440. switch (CallbackID)
  441. {
  442. case HAL_MDMA_XFER_CPLT_CB_ID:
  443. hmdma->XferCpltCallback = NULL;
  444. break;
  445. case HAL_MDMA_XFER_BUFFERCPLT_CB_ID:
  446. hmdma->XferBufferCpltCallback = NULL;
  447. break;
  448. case HAL_MDMA_XFER_BLOCKCPLT_CB_ID:
  449. hmdma->XferBlockCpltCallback = NULL;
  450. break;
  451. case HAL_MDMA_XFER_REPBLOCKCPLT_CB_ID:
  452. hmdma->XferRepeatBlockCpltCallback = NULL;
  453. break;
  454. case HAL_MDMA_XFER_ERROR_CB_ID:
  455. hmdma->XferErrorCallback = NULL;
  456. break;
  457. case HAL_MDMA_XFER_ABORT_CB_ID:
  458. hmdma->XferAbortCallback = NULL;
  459. break;
  460. case HAL_MDMA_XFER_ALL_CB_ID:
  461. hmdma->XferCpltCallback = NULL;
  462. hmdma->XferBufferCpltCallback = NULL;
  463. hmdma->XferBlockCpltCallback = NULL;
  464. hmdma->XferRepeatBlockCpltCallback = NULL;
  465. hmdma->XferErrorCallback = NULL;
  466. hmdma->XferAbortCallback = NULL;
  467. break;
  468. default:
  469. status = HAL_ERROR;
  470. break;
  471. }
  472. }
  473. else
  474. {
  475. status = HAL_ERROR;
  476. }
  477. /* Release Lock */
  478. __HAL_UNLOCK(hmdma);
  479. return status;
  480. }
  481. /**
  482. * @}
  483. */
  484. /** @addtogroup MDMA_Exported_Functions_Group2
  485. *
  486. @verbatim
  487. ===============================================================================
  488. ##### Linked list operation functions #####
  489. ===============================================================================
  490. [..] This section provides functions allowing to:
  491. (+) Create a linked list node
  492. (+) Add a node to the MDMA linked list
  493. (+) Remove a node from the MDMA linked list
  494. (+) Enable/Disable linked list circular mode
  495. @endverbatim
  496. * @{
  497. */
  498. /**
  499. * @brief Initializes an MDMA Link Node according to the specified
  500. * parameters in the pMDMA_LinkedListNodeConfig .
  501. * @param pNode: Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
  502. * registers configurations.
  503. * @param pNodeConfig: Pointer to a MDMA_LinkNodeConfTypeDef structure that contains
  504. * the configuration information for the specified MDMA Linked List Node.
  505. * @retval HAL status
  506. */
  507. HAL_StatusTypeDef HAL_MDMA_LinkedList_CreateNode(MDMA_LinkNodeTypeDef *pNode, MDMA_LinkNodeConfTypeDef *pNodeConfig)
  508. {
  509. uint32_t addressMask = 0;
  510. uint32_t blockoffset = 0;
  511. /* Check the MDMA peripheral state */
  512. if((pNode == NULL) || (pNodeConfig == NULL))
  513. {
  514. return HAL_ERROR;
  515. }
  516. /* Check the parameters */
  517. assert_param(IS_MDMA_PRIORITY(pNodeConfig->Init.Priority));
  518. assert_param(IS_MDMA_ENDIANNESS_MODE(pNodeConfig->Init.Endianness));
  519. assert_param(IS_MDMA_REQUEST(pNodeConfig->Init.Request));
  520. assert_param(IS_MDMA_SOURCE_INC(pNodeConfig->Init.SourceInc));
  521. assert_param(IS_MDMA_DESTINATION_INC(pNodeConfig->Init.DestinationInc));
  522. assert_param(IS_MDMA_SOURCE_DATASIZE(pNodeConfig->Init.SourceDataSize));
  523. assert_param(IS_MDMA_DESTINATION_DATASIZE(pNodeConfig->Init.DestDataSize));
  524. assert_param(IS_MDMA_DATA_ALIGNMENT(pNodeConfig->Init.DataAlignment));
  525. assert_param(IS_MDMA_SOURCE_BURST(pNodeConfig->Init.SourceBurst));
  526. assert_param(IS_MDMA_DESTINATION_BURST(pNodeConfig->Init.DestBurst));
  527. assert_param(IS_MDMA_BUFFER_TRANSFER_LENGTH(pNodeConfig->Init.BufferTransferLength));
  528. assert_param(IS_MDMA_TRANSFER_TRIGGER_MODE(pNodeConfig->Init.TransferTriggerMode));
  529. assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.SourceBlockAddressOffset));
  530. assert_param(IS_MDMA_BLOCK_ADDR_OFFSET(pNodeConfig->Init.DestBlockAddressOffset));
  531. assert_param(IS_MDMA_TRANSFER_LENGTH(pNodeConfig->BlockDataLength));
  532. assert_param(IS_MDMA_BLOCK_COUNT(pNodeConfig->BlockCount));
  533. /*configure next Link node Address Register to zero */
  534. pNode->CLAR = 0;
  535. /*Configure the Link Node registers*/
  536. pNode->CTBR = 0;
  537. pNode->CMAR = 0;
  538. pNode->CMDR = 0;
  539. pNode->Reserved = 0;
  540. /* write new CTCR Register value */
  541. pNode->CTCR = pNodeConfig->Init.SourceInc | pNodeConfig->Init.DestinationInc | \
  542. pNodeConfig->Init.SourceDataSize | pNodeConfig->Init.DestDataSize | \
  543. pNodeConfig->Init.DataAlignment| pNodeConfig->Init.SourceBurst | \
  544. pNodeConfig->Init.DestBurst | \
  545. ((pNodeConfig->Init.BufferTransferLength - 1) << POSITION_VAL(MDMA_CTCR_TLEN)) | \
  546. pNodeConfig->Init.TransferTriggerMode;
  547. /* If SW request set the CTCR register to SW Request Mode*/
  548. if(pNodeConfig->Init.Request == MDMA_REQUEST_SW)
  549. {
  550. pNode->CTCR |= MDMA_CTCR_SWRM;
  551. }
  552. /*
  553. -If the request is done by SW : BWM could be set to 1 or 0.
  554. -If the request is done by a peripheral :
  555. If mask address not set (0) => BWM must be set to 0
  556. If mask address set (different than 0) => BWM could be set to 1 or 0
  557. */
  558. if((pNodeConfig->Init.Request == MDMA_REQUEST_SW) || (pNodeConfig->PostRequestMaskAddress != 0))
  559. {
  560. pNode->CTCR |= MDMA_CTCR_BWM;
  561. }
  562. /* Set the new CBNDTR Register value */
  563. pNode->CBNDTR = ((pNodeConfig->BlockCount - 1) << POSITION_VAL(MDMA_CBNDTR_BRC)) & MDMA_CBNDTR_BRC;
  564. /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */
  565. if(pNodeConfig->Init.SourceBlockAddressOffset < 0)
  566. {
  567. pNode->CBNDTR |= MDMA_CBNDTR_BRSUM;
  568. /*write new CBRUR Register value : source repeat block offset */
  569. blockoffset = (-1 * pNodeConfig->Init.SourceBlockAddressOffset);
  570. pNode->CBRUR = blockoffset & 0x0000FFFFU;
  571. }
  572. else
  573. {
  574. /*write new CBRUR Register value : source repeat block offset */
  575. pNode->CBRUR = (((uint32_t) pNodeConfig->Init.SourceBlockAddressOffset) & 0x0000FFFFU);
  576. }
  577. /* if block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */
  578. if(pNodeConfig->Init.DestBlockAddressOffset < 0)
  579. {
  580. pNode->CBNDTR |= MDMA_CBNDTR_BRDUM;
  581. /*write new CBRUR Register value : destination repeat block offset */
  582. blockoffset = (-1 * pNodeConfig->Init.DestBlockAddressOffset);
  583. pNode->CBRUR |= ((blockoffset & 0x0000FFFFU) << POSITION_VAL(MDMA_CBRUR_DUV));
  584. }
  585. else
  586. {
  587. /*write new CBRUR Register value : destination repeat block offset */
  588. pNode->CBRUR |= (((uint32_t)pNodeConfig->Init.DestBlockAddressOffset) & 0x0000FFFFU) << POSITION_VAL(MDMA_CBRUR_DUV);
  589. }
  590. /* Configure MDMA Link Node data length */
  591. pNode->CBNDTR |= pNodeConfig->BlockDataLength;
  592. /* Configure MDMA Link Node destination address */
  593. pNode->CDAR = pNodeConfig->DstAddress;
  594. /* Configure MDMA Link Node Source address */
  595. pNode->CSAR = pNodeConfig->SrcAddress;
  596. /* if HW request set the HW request and the requet CleraMask and ClearData MaskData, */
  597. if(pNodeConfig->Init.Request != MDMA_REQUEST_SW)
  598. {
  599. /* Set the HW request in CTBR register */
  600. pNode->CTBR = pNodeConfig->Init.Request & MDMA_CTBR_TSEL;
  601. /* Set the HW request clear Mask and Data */
  602. pNode->CMAR = pNodeConfig->PostRequestMaskAddress;
  603. pNode->CMDR = pNodeConfig->PostRequestMaskData;
  604. }
  605. addressMask = pNodeConfig->SrcAddress & 0xFF000000U;
  606. if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
  607. {
  608. /*The AHBSbus is used as source (read operation) on channel x */
  609. pNode->CTBR |= MDMA_CTBR_SBUS;
  610. }
  611. addressMask = pNodeConfig->DstAddress & 0xFF000000U;
  612. if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
  613. {
  614. /*The AHB bus is used as destination (write operation) on channel x */
  615. pNode->CTBR |= MDMA_CTBR_DBUS;
  616. }
  617. return HAL_OK;
  618. }
  619. /**
  620. * @brief Connect a node to the linked list.
  621. * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
  622. * the configuration information for the specified MDMA Channel.
  623. * @param pNewNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
  624. * to be add to the list.
  625. * @param pPrevNode : Pointer to the new node position in the linked list or zero to insert the new node
  626. * at the end of the list
  627. *
  628. * @retval HAL status
  629. */
  630. HAL_StatusTypeDef HAL_MDMA_LinkedList_AddNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNewNode, MDMA_LinkNodeTypeDef *pPrevNode)
  631. {
  632. MDMA_LinkNodeTypeDef *pNode = 0;
  633. uint32_t counter = 0, nodeInserted = 0;
  634. HAL_StatusTypeDef hal_status = HAL_OK;
  635. /* Check the MDMA peripheral handle */
  636. if((hmdma == NULL) || (pNewNode == NULL))
  637. {
  638. return HAL_ERROR;
  639. }
  640. /* Process locked */
  641. __HAL_LOCK(hmdma);
  642. if(HAL_MDMA_STATE_READY == hmdma->State)
  643. {
  644. /* Change MDMA peripheral state */
  645. hmdma->State = HAL_MDMA_STATE_BUSY;
  646. /* Check if this is the first node (after the Inititlization node) */
  647. if((uint32_t)hmdma->FirstLinkedListNodeAddress == 0)
  648. {
  649. if(pPrevNode == NULL)
  650. {
  651. /* if this is the first node after the initialization
  652. connect this node to the node 0 by updating
  653. the MDMA channel CLAR register to this node address */
  654. hmdma->Instance->CLAR = (uint32_t)pNewNode;
  655. /* Set the MDMA handle First linked List node*/
  656. hmdma->FirstLinkedListNodeAddress = pNewNode;
  657. /*reset New node link */
  658. pNewNode->CLAR = 0;
  659. /* Update the Handle last node address */
  660. hmdma->LastLinkedListNodeAddress = pNewNode;
  661. hmdma->LinkedListNodeCounter = 1;
  662. }
  663. else
  664. {
  665. hal_status = HAL_ERROR;
  666. }
  667. }
  668. else if(hmdma->FirstLinkedListNodeAddress != pNewNode)
  669. {
  670. /* Check if the node to insert already exists*/
  671. pNode = hmdma->FirstLinkedListNodeAddress;
  672. while((counter < hmdma->LinkedListNodeCounter) && (hal_status == HAL_OK))
  673. {
  674. if(pNode->CLAR == (uint32_t)pNewNode)
  675. {
  676. hal_status = HAL_ERROR; /* error this node already exist in the linked list and it is not first node */
  677. }
  678. pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
  679. counter++;
  680. }
  681. if(hal_status == HAL_OK)
  682. {
  683. /* Check if the previous node is the last one in the current list or zero */
  684. if((pPrevNode == hmdma->LastLinkedListNodeAddress) || (pPrevNode == 0))
  685. {
  686. /* insert the new node at the end of the list. */
  687. pNewNode->CLAR = hmdma->LastLinkedListNodeAddress->CLAR;
  688. hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)pNewNode;
  689. /* Update the Handle last node address */
  690. hmdma->LastLinkedListNodeAddress = pNewNode;
  691. /* Increment the linked list node counter */
  692. hmdma->LinkedListNodeCounter++;
  693. }
  694. else
  695. {
  696. /*insert the new node after the pPreviousNode node */
  697. pNode = hmdma->FirstLinkedListNodeAddress;
  698. counter = 0;
  699. while((counter < hmdma->LinkedListNodeCounter) && (nodeInserted == 0))
  700. {
  701. counter++;
  702. if(pNode == pPrevNode)
  703. {
  704. /*Insert the new node after the previous one */
  705. pNewNode->CLAR = pNode->CLAR;
  706. pNode->CLAR = (uint32_t)pNewNode;
  707. /* Increment the linked list node counter */
  708. hmdma->LinkedListNodeCounter++;
  709. nodeInserted = 1;
  710. }
  711. else
  712. {
  713. pNode = (MDMA_LinkNodeTypeDef *)pNode->CLAR;
  714. }
  715. }
  716. if(nodeInserted == 0)
  717. {
  718. hal_status = HAL_ERROR;
  719. }
  720. }
  721. }
  722. }
  723. else
  724. {
  725. hal_status = HAL_ERROR;
  726. }
  727. /* Process unlocked */
  728. __HAL_UNLOCK(hmdma);
  729. hmdma->State = HAL_MDMA_STATE_READY;
  730. return hal_status;
  731. }
  732. else
  733. {
  734. /* Process unlocked */
  735. __HAL_UNLOCK(hmdma);
  736. /* Return error status */
  737. return HAL_BUSY;
  738. }
  739. }
  740. /**
  741. * @brief Disconnect/Remove a node from the transfer linked list.
  742. * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
  743. * the configuration information for the specified MDMA Channel.
  744. * @param pNode : Pointer to a MDMA_LinkNodeTypeDef structure that contains Linked list node
  745. * to be removed from the list.
  746. *
  747. * @retval HAL status
  748. */
  749. HAL_StatusTypeDef HAL_MDMA_LinkedList_RemoveNode(MDMA_HandleTypeDef *hmdma, MDMA_LinkNodeTypeDef *pNode)
  750. {
  751. MDMA_LinkNodeTypeDef *ptmpNode = 0;
  752. uint32_t counter = 0, nodeDeleted = 0;
  753. HAL_StatusTypeDef hal_status = HAL_OK;
  754. /* Check the MDMA peripheral handle */
  755. if((hmdma == NULL) || (pNode == NULL))
  756. {
  757. return HAL_ERROR;
  758. }
  759. /* Process locked */
  760. __HAL_LOCK(hmdma);
  761. if(HAL_MDMA_STATE_READY == hmdma->State)
  762. {
  763. /* Change MDMA peripheral state */
  764. hmdma->State = HAL_MDMA_STATE_BUSY;
  765. /* If first and last node are null (no nodes in the list) : return error*/
  766. if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0) || (hmdma->LinkedListNodeCounter == 0))
  767. {
  768. hal_status = HAL_ERROR;
  769. }
  770. else if(hmdma->FirstLinkedListNodeAddress == pNode) /* Deleting first node */
  771. {
  772. /* Delete 1st node */
  773. if(hmdma->LastLinkedListNodeAddress == pNode)
  774. {
  775. /*if the last node is at the same time the first one (1 single node after the init node 0)
  776. then update the last node too */
  777. hmdma->FirstLinkedListNodeAddress = 0;
  778. hmdma->LastLinkedListNodeAddress = 0;
  779. hmdma->LinkedListNodeCounter = 0;
  780. hmdma->Instance->CLAR = 0;
  781. }
  782. else
  783. {
  784. if((uint32_t)hmdma->FirstLinkedListNodeAddress == hmdma->LastLinkedListNodeAddress->CLAR)
  785. {
  786. /* if last node is looping to first (circular list) one update the last node connection */
  787. hmdma->LastLinkedListNodeAddress->CLAR = pNode->CLAR;
  788. }
  789. /* if deleting the first node after the initialization
  790. connect the next node to the node 0 by updating
  791. the MDMA channel CLAR register to this node address */
  792. hmdma->Instance->CLAR = pNode->CLAR;
  793. hmdma->FirstLinkedListNodeAddress = (MDMA_LinkNodeTypeDef *)hmdma->Instance->CLAR;
  794. /* Update the Handle node counter */
  795. hmdma->LinkedListNodeCounter--;
  796. }
  797. }
  798. else /* Deleting any other node */
  799. {
  800. /*Deleted node is not the first one : find it */
  801. ptmpNode = hmdma->FirstLinkedListNodeAddress;
  802. while((counter < hmdma->LinkedListNodeCounter) && (nodeDeleted == 0))
  803. {
  804. counter++;
  805. if(ptmpNode->CLAR == ((uint32_t)pNode))
  806. {
  807. /* if deleting the last node */
  808. if(pNode == hmdma->LastLinkedListNodeAddress)
  809. {
  810. /*Update the linked list last node address in the handle*/
  811. hmdma->LastLinkedListNodeAddress = ptmpNode;
  812. }
  813. /* update the next node link after deleting pMDMA_LinkedListNode */
  814. ptmpNode->CLAR = pNode->CLAR;
  815. nodeDeleted = 1;
  816. /* Update the Handle node counter */
  817. hmdma->LinkedListNodeCounter--;
  818. }
  819. else
  820. {
  821. ptmpNode = (MDMA_LinkNodeTypeDef *)ptmpNode->CLAR;
  822. }
  823. }
  824. if(nodeDeleted == 0)
  825. {
  826. /* last node reashed without finding the node to delete : return error */
  827. hal_status = HAL_ERROR;
  828. }
  829. }
  830. /* Process unlocked */
  831. __HAL_UNLOCK(hmdma);
  832. hmdma->State = HAL_MDMA_STATE_READY;
  833. return hal_status;
  834. }
  835. else
  836. {
  837. /* Process unlocked */
  838. __HAL_UNLOCK(hmdma);
  839. /* Return error status */
  840. return HAL_BUSY;
  841. }
  842. }
  843. /**
  844. * @brief Make the linked list circular by connecting the last node to the first.
  845. * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
  846. * the configuration information for the specified MDMA Channel.
  847. * @retval HAL status
  848. */
  849. HAL_StatusTypeDef HAL_MDMA_LinkedList_EnableCircularMode(MDMA_HandleTypeDef *hmdma)
  850. {
  851. HAL_StatusTypeDef hal_status = HAL_OK;
  852. /* Check the MDMA peripheral handle */
  853. if(hmdma == NULL)
  854. {
  855. return HAL_ERROR;
  856. }
  857. /* Process locked */
  858. __HAL_LOCK(hmdma);
  859. if(HAL_MDMA_STATE_READY == hmdma->State)
  860. {
  861. /* Change MDMA peripheral state */
  862. hmdma->State = HAL_MDMA_STATE_BUSY;
  863. /* If first and last node are null (no nodes in the list) : return error*/
  864. if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0) || (hmdma->LinkedListNodeCounter == 0))
  865. {
  866. hal_status = HAL_ERROR;
  867. }
  868. else
  869. {
  870. /* to enable circular mode Last Node should be connected to first node */
  871. hmdma->LastLinkedListNodeAddress->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress;
  872. }
  873. }
  874. /* Process unlocked */
  875. __HAL_UNLOCK(hmdma);
  876. hmdma->State = HAL_MDMA_STATE_READY;
  877. return hal_status;
  878. }
  879. /**
  880. * @brief Disable the linked list circular mode by setting the last node connection to null
  881. * @param hmdma : Pointer to a MDMA_HandleTypeDef structure that contains
  882. * the configuration information for the specified MDMA Channel.
  883. * @retval HAL status
  884. */
  885. HAL_StatusTypeDef HAL_MDMA_LinkedList_DisableCircularMode(MDMA_HandleTypeDef *hmdma)
  886. {
  887. HAL_StatusTypeDef hal_status = HAL_OK;
  888. /* Check the MDMA peripheral handle */
  889. if(hmdma == NULL)
  890. {
  891. return HAL_ERROR;
  892. }
  893. /* Process locked */
  894. __HAL_LOCK(hmdma);
  895. if(HAL_MDMA_STATE_READY == hmdma->State)
  896. {
  897. /* Change MDMA peripheral state */
  898. hmdma->State = HAL_MDMA_STATE_BUSY;
  899. /* If first and last node are null (no nodes in the list) : return error*/
  900. if(((uint32_t)hmdma->FirstLinkedListNodeAddress == 0) || ((uint32_t)hmdma->LastLinkedListNodeAddress == 0) || (hmdma->LinkedListNodeCounter == 0))
  901. {
  902. hal_status = HAL_ERROR;
  903. }
  904. else
  905. {
  906. /* to disable circular mode Last Node should be connected to NULL */
  907. hmdma->LastLinkedListNodeAddress->CLAR = 0;
  908. }
  909. }
  910. /* Process unlocked */
  911. __HAL_UNLOCK(hmdma);
  912. hmdma->State = HAL_MDMA_STATE_READY;
  913. return hal_status;
  914. }
  915. /**
  916. * @}
  917. */
  918. /** @addtogroup MDMA_Exported_Functions_Group3
  919. *
  920. @verbatim
  921. ===============================================================================
  922. ##### IO operation functions #####
  923. ===============================================================================
  924. [..] This section provides functions allowing to:
  925. (+) Configure the source, destination address and data length and Start MDMA transfer
  926. (+) Configure the source, destination address and data length and
  927. Start MDMA transfer with interrupt
  928. (+) Abort MDMA transfer
  929. (+) Poll for transfer complete
  930. (+) Generate a SW request (when Request is set to MDMA_REQUEST_SW)
  931. (+) Handle MDMA interrupt request
  932. @endverbatim
  933. * @{
  934. */
  935. /**
  936. * @brief Starts the MDMA Transfer.
  937. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  938. * the configuration information for the specified MDMA Stream.
  939. * @param SrcAddress : The source memory Buffer address
  940. * @param DstAddress : The destination memory Buffer address
  941. * @param BlockDataLength : The length of a block transfer in bytes
  942. * @param BlockCount : The number of a blocks to be transfer
  943. * @retval HAL status
  944. */
  945. HAL_StatusTypeDef HAL_MDMA_Start (MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
  946. {
  947. /* Check the parameters */
  948. assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength));
  949. assert_param(IS_MDMA_BLOCK_COUNT(BlockCount));
  950. /* Check the MDMA peripheral handle */
  951. if(hmdma == NULL)
  952. {
  953. return HAL_ERROR;
  954. }
  955. /* Process locked */
  956. __HAL_LOCK(hmdma);
  957. if(HAL_MDMA_STATE_READY == hmdma->State)
  958. {
  959. /* Change MDMA peripheral state */
  960. hmdma->State = HAL_MDMA_STATE_BUSY;
  961. /* Initialize the error code */
  962. hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
  963. /* Disable the peripheral */
  964. __HAL_MDMA_DISABLE(hmdma);
  965. /* Configure the source, destination address and the data length */
  966. MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount);
  967. /* Enable the Peripheral */
  968. __HAL_MDMA_ENABLE(hmdma);
  969. if(hmdma->Init.Request == MDMA_REQUEST_SW)
  970. {
  971. /* activate If SW request mode*/
  972. hmdma->Instance->CCR |= MDMA_CCR_SWRQ;
  973. }
  974. }
  975. else
  976. {
  977. /* Process unlocked */
  978. __HAL_UNLOCK(hmdma);
  979. /* Return error status */
  980. return HAL_BUSY;
  981. }
  982. return HAL_OK;
  983. }
  984. /**
  985. * @brief Starts the MDMA Transfer with interrupts enabled.
  986. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  987. * the configuration information for the specified MDMA Stream.
  988. * @param SrcAddress : The source memory Buffer address
  989. * @param DstAddress : The destination memory Buffer address
  990. * @param BlockDataLength : The length of a block transfer in bytes
  991. * @param BlockCount : The number of a blocks to be transfer
  992. * @retval HAL status
  993. */
  994. HAL_StatusTypeDef HAL_MDMA_Start_IT(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
  995. {
  996. /* Check the parameters */
  997. assert_param(IS_MDMA_TRANSFER_LENGTH(BlockDataLength));
  998. assert_param(IS_MDMA_BLOCK_COUNT(BlockCount));
  999. /* Check the MDMA peripheral handle */
  1000. if(hmdma == NULL)
  1001. {
  1002. return HAL_ERROR;
  1003. }
  1004. /* Process locked */
  1005. __HAL_LOCK(hmdma);
  1006. if(HAL_MDMA_STATE_READY == hmdma->State)
  1007. {
  1008. /* Change MDMA peripheral state */
  1009. hmdma->State = HAL_MDMA_STATE_BUSY;
  1010. /* Initialize the error code */
  1011. hmdma->ErrorCode = HAL_MDMA_ERROR_NONE;
  1012. /* Disable the peripheral */
  1013. __HAL_MDMA_DISABLE(hmdma);
  1014. /* Configure the source, destination address and the data length */
  1015. MDMA_SetConfig(hmdma, SrcAddress, DstAddress, BlockDataLength, BlockCount);
  1016. /* Enable Common interrupts i.e Transfer Error IT and Channel Transfer Complete IT*/
  1017. __HAL_MDMA_ENABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC));
  1018. if(hmdma->XferBlockCpltCallback != NULL)
  1019. {
  1020. /* if Block transfer complete Callback is set enable the corresponding IT*/
  1021. __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BT);
  1022. }
  1023. if(hmdma->XferRepeatBlockCpltCallback != NULL)
  1024. {
  1025. /* if Repeated Block transfer complete Callback is set enable the corresponding IT*/
  1026. __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BRT);
  1027. }
  1028. if(hmdma->XferBufferCpltCallback != NULL)
  1029. {
  1030. /* if buffer transfer complete Callback is set enable the corresponding IT*/
  1031. __HAL_MDMA_ENABLE_IT(hmdma, MDMA_IT_BFTC);
  1032. }
  1033. /* Enable the Peripheral */
  1034. __HAL_MDMA_ENABLE(hmdma);
  1035. if(hmdma->Init.Request == MDMA_REQUEST_SW)
  1036. {
  1037. /* activate If SW request mode*/
  1038. hmdma->Instance->CCR |= MDMA_CCR_SWRQ;
  1039. }
  1040. }
  1041. else
  1042. {
  1043. /* Process unlocked */
  1044. __HAL_UNLOCK(hmdma);
  1045. /* Return error status */
  1046. return HAL_BUSY;
  1047. }
  1048. return HAL_OK;
  1049. }
  1050. /**
  1051. * @brief Aborts the MDMA Transfer.
  1052. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  1053. * the configuration information for the specified MDMA Channel.
  1054. *
  1055. * @note After disabling a MDMA Stream, a check for wait until the MDMA Channel is
  1056. * effectively disabled is added. If a Stream is disabled
  1057. * while a data transfer is ongoing, the current data will be transferred
  1058. * and the Stream will be effectively disabled only after the transfer of
  1059. * this single data is finished.
  1060. * @retval HAL status
  1061. */
  1062. HAL_StatusTypeDef HAL_MDMA_Abort(MDMA_HandleTypeDef *hmdma)
  1063. {
  1064. uint32_t tickstart = HAL_GetTick();
  1065. /* Check the MDMA peripheral handle */
  1066. if(hmdma == NULL)
  1067. {
  1068. return HAL_ERROR;
  1069. }
  1070. if(HAL_MDMA_STATE_BUSY != hmdma->State)
  1071. {
  1072. hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
  1073. /* Process Unlocked */
  1074. __HAL_UNLOCK(hmdma);
  1075. return HAL_ERROR;
  1076. }
  1077. else
  1078. {
  1079. /* Disable all the transfer interrupts */
  1080. __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC));
  1081. /* Disable the channel */
  1082. __HAL_MDMA_DISABLE(hmdma);
  1083. /* Check if the MDMA Channel is effectively disabled */
  1084. while((hmdma->Instance->CCR & MDMA_CCR_EN) != 0)
  1085. {
  1086. /* Check for the Timeout */
  1087. if( (HAL_GetTick() - tickstart ) > HAL_TIMEOUT_MDMA_ABORT)
  1088. {
  1089. /* Update error code */
  1090. hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT;
  1091. /* Process Unlocked */
  1092. __HAL_UNLOCK(hmdma);
  1093. /* Change the MDMA state */
  1094. hmdma->State = HAL_MDMA_STATE_ERROR;
  1095. return HAL_ERROR;
  1096. }
  1097. }
  1098. /* Clear all interrupt flags */
  1099. __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_FLAG_BT | MDMA_FLAG_BRT | MDMA_FLAG_BFTC));
  1100. /* Process Unlocked */
  1101. __HAL_UNLOCK(hmdma);
  1102. /* Change the MDMA state*/
  1103. hmdma->State = HAL_MDMA_STATE_READY;
  1104. }
  1105. return HAL_OK;
  1106. }
  1107. /**
  1108. * @brief Aborts the MDMA Transfer in Interrupt mode.
  1109. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  1110. * the configuration information for the specified MDMA Channel.
  1111. * @retval HAL status
  1112. */
  1113. HAL_StatusTypeDef HAL_MDMA_Abort_IT(MDMA_HandleTypeDef *hmdma)
  1114. {
  1115. /* Check the MDMA peripheral handle */
  1116. if(hmdma == NULL)
  1117. {
  1118. return HAL_ERROR;
  1119. }
  1120. if(HAL_MDMA_STATE_BUSY != hmdma->State)
  1121. {
  1122. hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
  1123. return HAL_ERROR;
  1124. }
  1125. else
  1126. {
  1127. /* Set Abort State */
  1128. hmdma->State = HAL_MDMA_STATE_ABORT;
  1129. /* Disable the stream */
  1130. __HAL_MDMA_DISABLE(hmdma);
  1131. }
  1132. return HAL_OK;
  1133. }
  1134. /**
  1135. * @brief Polling for transfer complete.
  1136. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  1137. * the configuration information for the specified MDMA Channel.
  1138. * @param CompleteLevel: Specifies the MDMA level complete.
  1139. * @param Timeout: Timeout duration.
  1140. * @retval HAL status
  1141. */
  1142. HAL_StatusTypeDef HAL_MDMA_PollForTransfer(MDMA_HandleTypeDef *hmdma, uint32_t CompleteLevel, uint32_t Timeout)
  1143. {
  1144. uint32_t levelFlag = 0, errorFlag = 0;
  1145. uint32_t tickstart = 0;
  1146. /* Check the parameters */
  1147. assert_param(IS_MDMA_LEVEL_COMPLETE(CompleteLevel));
  1148. /* Check the MDMA peripheral handle */
  1149. if(hmdma == NULL)
  1150. {
  1151. return HAL_ERROR;
  1152. }
  1153. if(HAL_MDMA_STATE_BUSY != hmdma->State)
  1154. {
  1155. /* No transfer ongoing */
  1156. hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
  1157. return HAL_ERROR;
  1158. }
  1159. /* Get the level transfer complete flag */
  1160. levelFlag = ((CompleteLevel == HAL_MDMA_FULL_TRANSFER) ? MDMA_FLAG_CTC :\
  1161. (CompleteLevel == HAL_MDMA_BUFFER_TRANSFER)? MDMA_FLAG_BFTC :\
  1162. (CompleteLevel == HAL_MDMA_BLOCK_TRANSFER) ? MDMA_FLAG_BT :\
  1163. MDMA_FLAG_BRT);
  1164. /* Get timeout */
  1165. tickstart = HAL_GetTick();
  1166. while(__HAL_MDMA_GET_FLAG(hmdma, levelFlag) == RESET)
  1167. {
  1168. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != RESET))
  1169. {
  1170. /* Get the transfer error source flag */
  1171. errorFlag = hmdma->Instance->CESR;
  1172. if((errorFlag & MDMA_CESR_TED) == 0)
  1173. {
  1174. /* Update error code : Read Transfer error */
  1175. hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER;
  1176. }
  1177. else
  1178. {
  1179. /* Update error code : Write Transfer error */
  1180. hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER;
  1181. }
  1182. if((errorFlag & MDMA_CESR_TEMD) != 0)
  1183. {
  1184. /* Update error code : Error Mask Data */
  1185. hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA;
  1186. }
  1187. if((errorFlag & MDMA_CESR_TELD) != 0)
  1188. {
  1189. /* Update error code : Error Linked list */
  1190. hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST;
  1191. }
  1192. if((errorFlag & MDMA_CESR_ASE) != 0)
  1193. {
  1194. /* Update error code : Address/Size alignment error */
  1195. hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT;
  1196. }
  1197. if((errorFlag & MDMA_CESR_BSE) != 0)
  1198. {
  1199. /* Update error code : Block Size error */
  1200. hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE;
  1201. }
  1202. HAL_MDMA_Abort(hmdma); /* if error then abort the current transfer */
  1203. /*
  1204. Note that the Abort function will
  1205. - Clear the transfer error flags
  1206. - Unlock
  1207. - Set the State
  1208. */
  1209. return HAL_ERROR;
  1210. }
  1211. /* Check for the Timeout */
  1212. if(Timeout != HAL_MAX_DELAY)
  1213. {
  1214. if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
  1215. {
  1216. /* Update error code */
  1217. hmdma->ErrorCode |= HAL_MDMA_ERROR_TIMEOUT;
  1218. HAL_MDMA_Abort(hmdma); /* if timeout then abort the current transfer */
  1219. /*
  1220. Note that the Abort function will
  1221. - Clear the transfer error flags
  1222. - Unlock
  1223. - Set the State
  1224. */
  1225. return HAL_ERROR;
  1226. }
  1227. }
  1228. }
  1229. /* Clear the transfer level flag */
  1230. if(CompleteLevel == HAL_MDMA_BUFFER_TRANSFER)
  1231. {
  1232. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC);
  1233. }
  1234. else if(CompleteLevel == HAL_MDMA_BLOCK_TRANSFER)
  1235. {
  1236. __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT));
  1237. }
  1238. else if(CompleteLevel == HAL_MDMA_REPEAT_BLOCK_TRANSFER)
  1239. {
  1240. __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BFTC | MDMA_FLAG_BT | MDMA_FLAG_BRT));
  1241. }
  1242. else if(CompleteLevel == HAL_MDMA_FULL_TRANSFER)
  1243. {
  1244. __HAL_MDMA_CLEAR_FLAG(hmdma, (MDMA_FLAG_BRT | MDMA_FLAG_BT | MDMA_FLAG_BFTC | MDMA_FLAG_CTC));
  1245. /* Process unlocked */
  1246. __HAL_UNLOCK(hmdma);
  1247. hmdma->State = HAL_MDMA_STATE_READY;
  1248. }
  1249. return HAL_OK;
  1250. }
  1251. /**
  1252. * @brief Generate an MDMA SW request trigger to activate the request on the given Channel.
  1253. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  1254. * the configuration information for the specified MDMA Stream.
  1255. * @retval HAL status
  1256. */
  1257. HAL_StatusTypeDef HAL_MDMA_GenerateSWRequest(MDMA_HandleTypeDef *hmdma)
  1258. {
  1259. /* Check the MDMA peripheral handle */
  1260. if(hmdma == NULL)
  1261. {
  1262. return HAL_ERROR;
  1263. }
  1264. if((hmdma->Instance->CCR & MDMA_CCR_EN) == RESET)
  1265. {
  1266. /* if no Transfer on going (MDMA enable bit not set) retrun error */
  1267. hmdma->ErrorCode = HAL_MDMA_ERROR_NO_XFER;
  1268. return HAL_ERROR;
  1269. }
  1270. else if(((hmdma->Instance->CISR & MDMA_CISR_CRQA) != RESET) || ((hmdma->Instance->CTCR & MDMA_CTCR_SWRM) == RESET))
  1271. {
  1272. /* if an MDMA ongoing request hase not yet ends or if request mode is not SW request retrun error */
  1273. hmdma->ErrorCode = HAL_MDMA_ERROR_BUSY;
  1274. return HAL_ERROR;
  1275. }
  1276. else
  1277. {
  1278. /* Set the SW request bit to activate the request on the Channel */
  1279. hmdma->Instance->CCR |= MDMA_CCR_SWRQ;
  1280. return HAL_OK;
  1281. }
  1282. }
  1283. /**
  1284. * @brief Handles MDMA interrupt request.
  1285. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  1286. * the configuration information for the specified MDMA Stream.
  1287. * @retval None
  1288. */
  1289. void HAL_MDMA_IRQHandler(MDMA_HandleTypeDef *hmdma)
  1290. {
  1291. __IO uint32_t count = 0;
  1292. uint32_t timeout = SystemCoreClock / 9600;
  1293. uint32_t generalIntFlag, errorFlag;
  1294. /* General Interrupt Flag management ****************************************/
  1295. generalIntFlag = 1 << (((uint32_t)hmdma->Instance - (uint32_t)(MDMA_Channel0))/HAL_MDMA_CHANNEL_SIZE);
  1296. if((MDMA->GISR0 & generalIntFlag) == RESET)
  1297. {
  1298. return; /* the General interrupt flag for the current channel is down , nothing to do */
  1299. }
  1300. /* Transfer Error Interrupt management ***************************************/
  1301. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_TE) != RESET))
  1302. {
  1303. if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_TE) != RESET)
  1304. {
  1305. /* Disable the transfer error interrupt */
  1306. __HAL_MDMA_DISABLE_IT(hmdma, MDMA_IT_TE);
  1307. /* Get the transfer error source flag */
  1308. errorFlag = hmdma->Instance->CESR;
  1309. if((errorFlag & MDMA_CESR_TED) == 0)
  1310. {
  1311. /* Update error code : Read Transfer error */
  1312. hmdma->ErrorCode |= HAL_MDMA_ERROR_READ_XFER;
  1313. }
  1314. else
  1315. {
  1316. /* Update error code : Write Transfer error */
  1317. hmdma->ErrorCode |= HAL_MDMA_ERROR_WRITE_XFER;
  1318. }
  1319. if((errorFlag & MDMA_CESR_TEMD) != 0)
  1320. {
  1321. /* Update error code : Error Mask Data */
  1322. hmdma->ErrorCode |= HAL_MDMA_ERROR_MASK_DATA;
  1323. }
  1324. if((errorFlag & MDMA_CESR_TELD) != 0)
  1325. {
  1326. /* Update error code : Error Linked list */
  1327. hmdma->ErrorCode |= HAL_MDMA_ERROR_LINKED_LIST;
  1328. }
  1329. if((errorFlag & MDMA_CESR_ASE) != 0)
  1330. {
  1331. /* Update error code : Address/Size alignment error */
  1332. hmdma->ErrorCode |= HAL_MDMA_ERROR_ALIGNMENT;
  1333. }
  1334. if((errorFlag & MDMA_CESR_BSE) != 0)
  1335. {
  1336. /* Update error code : Block Size error error */
  1337. hmdma->ErrorCode |= HAL_MDMA_ERROR_BLOCK_SIZE;
  1338. }
  1339. /* Clear the transfer error flags */
  1340. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE);
  1341. }
  1342. }
  1343. /* Buffer Transfer Complete Interrupt management ******************************/
  1344. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BFTC) != RESET))
  1345. {
  1346. if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BFTC) != RESET)
  1347. {
  1348. /* Clear the buffer transfer complete flag */
  1349. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BFTC);
  1350. if(hmdma->XferBufferCpltCallback != NULL)
  1351. {
  1352. /* Buffer transfer callback */
  1353. hmdma->XferBufferCpltCallback(hmdma);
  1354. }
  1355. }
  1356. }
  1357. /* Block Transfer Complete Interrupt management ******************************/
  1358. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BT) != RESET))
  1359. {
  1360. if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BT) != RESET)
  1361. {
  1362. /* Clear the block transfer complete flag */
  1363. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BT);
  1364. if(hmdma->XferBlockCpltCallback != NULL)
  1365. {
  1366. /* Block transfer callback */
  1367. hmdma->XferBlockCpltCallback(hmdma);
  1368. }
  1369. }
  1370. }
  1371. /* Repeated Block Transfer Complete Interrupt management ******************************/
  1372. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_BRT) != RESET))
  1373. {
  1374. if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_BRT) != RESET)
  1375. {
  1376. /* Clear the repeat block transfer complete flag */
  1377. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_BRT);
  1378. if(hmdma->XferRepeatBlockCpltCallback != NULL)
  1379. {
  1380. /* Repeated Block transfer callback */
  1381. hmdma->XferRepeatBlockCpltCallback(hmdma);
  1382. }
  1383. }
  1384. }
  1385. /* Channel Transfer Complete Interrupt management ***********************************/
  1386. if((__HAL_MDMA_GET_FLAG(hmdma, MDMA_FLAG_CTC) != RESET))
  1387. {
  1388. if(__HAL_MDMA_GET_IT_SOURCE(hmdma, MDMA_IT_CTC) != RESET)
  1389. {
  1390. /* Disable all the transfer interrupts */
  1391. __HAL_MDMA_DISABLE_IT(hmdma, (MDMA_IT_TE | MDMA_IT_CTC | MDMA_IT_BT | MDMA_IT_BRT | MDMA_IT_BFTC));
  1392. if(HAL_MDMA_STATE_ABORT == hmdma->State)
  1393. {
  1394. /* Process Unlocked */
  1395. __HAL_UNLOCK(hmdma);
  1396. /* Change the DMA state */
  1397. hmdma->State = HAL_MDMA_STATE_READY;
  1398. if(hmdma->XferAbortCallback != NULL)
  1399. {
  1400. hmdma->XferAbortCallback(hmdma);
  1401. }
  1402. return;
  1403. }
  1404. /* Clear the Channel Transfer Complete flag */
  1405. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_CTC);
  1406. /* Process Unlocked */
  1407. __HAL_UNLOCK(hmdma);
  1408. /* Change MDMA peripheral state */
  1409. hmdma->State = HAL_MDMA_STATE_READY;
  1410. if(hmdma->XferCpltCallback != NULL)
  1411. {
  1412. /* Channel Transfer Complete callback */
  1413. hmdma->XferCpltCallback(hmdma);
  1414. }
  1415. }
  1416. }
  1417. /* manage error case */
  1418. if(hmdma->ErrorCode != HAL_MDMA_ERROR_NONE)
  1419. {
  1420. hmdma->State = HAL_MDMA_STATE_ABORT;
  1421. /* Disable the channel */
  1422. __HAL_MDMA_DISABLE(hmdma);
  1423. do
  1424. {
  1425. if (++count > timeout)
  1426. {
  1427. break;
  1428. }
  1429. }
  1430. while((hmdma->Instance->CCR & MDMA_CCR_EN) != RESET);
  1431. /* Process Unlocked */
  1432. __HAL_UNLOCK(hmdma);
  1433. if((hmdma->Instance->CCR & MDMA_CCR_EN) != RESET)
  1434. {
  1435. /* Change the MDMA state to error if MDMA disable fails */
  1436. hmdma->State = HAL_MDMA_STATE_ERROR;
  1437. }
  1438. else
  1439. {
  1440. /* Change the MDMA state to Ready if MDMA disable success */
  1441. hmdma->State = HAL_MDMA_STATE_READY;
  1442. }
  1443. if (hmdma->XferErrorCallback != NULL)
  1444. {
  1445. /* Transfer error callback */
  1446. hmdma->XferErrorCallback(hmdma);
  1447. }
  1448. }
  1449. }
  1450. /**
  1451. * @}
  1452. */
  1453. /** @addtogroup MDMA_Exported_Functions_Group4
  1454. *
  1455. @verbatim
  1456. ===============================================================================
  1457. ##### State and Errors functions #####
  1458. ===============================================================================
  1459. [..]
  1460. This subsection provides functions allowing to
  1461. (+) Check the MDMA state
  1462. (+) Get error code
  1463. @endverbatim
  1464. * @{
  1465. */
  1466. /**
  1467. * @brief Returns the MDMA state.
  1468. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  1469. * the configuration information for the specified MDMA Stream.
  1470. * @retval HAL state
  1471. */
  1472. HAL_MDMA_StateTypeDef HAL_MDMA_GetState(MDMA_HandleTypeDef *hmdma)
  1473. {
  1474. return hmdma->State;
  1475. }
  1476. /**
  1477. * @brief Return the MDMA error code
  1478. * @param hmdma : pointer to a MDMA_HandleTypeDef structure that contains
  1479. * the configuration information for the specified MDMA Stream.
  1480. * @retval MDMA Error Code
  1481. */
  1482. uint32_t HAL_MDMA_GetError(MDMA_HandleTypeDef *hmdma)
  1483. {
  1484. return hmdma->ErrorCode;
  1485. }
  1486. /**
  1487. * @}
  1488. */
  1489. /**
  1490. * @}
  1491. */
  1492. /** @addtogroup JPEG_Private_Functions
  1493. * @{
  1494. */
  1495. /**
  1496. * @brief Sets the MDMA Transfer parameter.
  1497. * @param hmdma: pointer to a MDMA_HandleTypeDef structure that contains
  1498. * the configuration information for the specified MDMA Stream.
  1499. * @param SrcAddress: The source memory Buffer address
  1500. * @param DstAddress: The destination memory Buffer address
  1501. * @param BlockDataLength : The length of a block transfer in bytes
  1502. * @param BlockCount: The number of a blocks to be transfer
  1503. * @retval HAL status
  1504. */
  1505. static void MDMA_SetConfig(MDMA_HandleTypeDef *hmdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t BlockDataLength, uint32_t BlockCount)
  1506. {
  1507. uint32_t addressMask;
  1508. /* Configure MDMA Channel data length */
  1509. MODIFY_REG(hmdma->Instance->CBNDTR ,MDMA_CBNDTR_BNDT, (BlockDataLength & MDMA_CBNDTR_BNDT));
  1510. /*Configure the MDMA block repeat count*/
  1511. MODIFY_REG( hmdma->Instance->CBNDTR , MDMA_CBNDTR_BRC , ((BlockCount - 1) << POSITION_VAL(MDMA_CBNDTR_BRC)) & MDMA_CBNDTR_BRC);
  1512. /* Clear all interrupt flags */
  1513. __HAL_MDMA_CLEAR_FLAG(hmdma, MDMA_FLAG_TE | MDMA_FLAG_CTC | MDMA_CISR_BRTIF | MDMA_CISR_BTIF | MDMA_CISR_TCIF);
  1514. /* Configure MDMA Channel destination address */
  1515. hmdma->Instance->CDAR = DstAddress;
  1516. /* Configure MDMA Channel Source address */
  1517. hmdma->Instance->CSAR = SrcAddress;
  1518. addressMask = SrcAddress & 0xFF000000U;
  1519. if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
  1520. {
  1521. /*The AHBSbus is used as source (read operation) on channel x */
  1522. hmdma->Instance->CTBR |= MDMA_CTBR_SBUS;
  1523. }
  1524. else
  1525. {
  1526. /*The AXI bus is used as source (read operation) on channel x */
  1527. hmdma->Instance->CTBR &= (~MDMA_CTBR_SBUS);
  1528. }
  1529. addressMask = DstAddress & 0xFF000000U;
  1530. if((addressMask == 0x20000000U) || (addressMask == 0x00000000U))
  1531. {
  1532. /*The AHB bus is used as destination (write operation) on channel x */
  1533. hmdma->Instance->CTBR |= MDMA_CTBR_DBUS;
  1534. }
  1535. else
  1536. {
  1537. /*The AXI bus is used as destination (write operation) on channel x */
  1538. hmdma->Instance->CTBR &= (~MDMA_CTBR_DBUS);
  1539. }
  1540. /* Set the linked list rgeitser to the first node of the list */
  1541. hmdma->Instance->CLAR = (uint32_t)hmdma->FirstLinkedListNodeAddress;
  1542. }
  1543. static void MDMA_Init(MDMA_HandleTypeDef *hmdma)
  1544. {
  1545. uint32_t blockoffset = 0;
  1546. /* Prepare the MDMA Channel configuration */
  1547. hmdma->Instance->CCR = hmdma->Init.Priority | hmdma->Init.Endianness;
  1548. /* write new CTCR Register value */
  1549. hmdma->Instance->CTCR = hmdma->Init.SourceInc | hmdma->Init.DestinationInc | \
  1550. hmdma->Init.SourceDataSize | hmdma->Init.DestDataSize | \
  1551. hmdma->Init.DataAlignment | hmdma->Init.SourceBurst | \
  1552. hmdma->Init.DestBurst | \
  1553. ((hmdma->Init.BufferTransferLength - 1) << POSITION_VAL(MDMA_CTCR_TLEN)) | \
  1554. hmdma->Init.TransferTriggerMode;
  1555. /* If SW request set the CTCR register to SW Request Mode*/
  1556. if(hmdma->Init.Request == MDMA_REQUEST_SW)
  1557. {
  1558. /*
  1559. -If the request is done by SW : BWM could be set to 1 or 0.
  1560. -If the request is done by a peripheral :
  1561. If mask address not set (0) => BWM must be set to 0
  1562. If mask address set (different than 0) => BWM could be set to 1 or 0
  1563. */
  1564. hmdma->Instance->CTCR |= (MDMA_CTCR_SWRM | MDMA_CTCR_BWM);
  1565. }
  1566. /* Reset CBNDTR Register */
  1567. hmdma->Instance->CBNDTR = 0;
  1568. /* if block source address offset is negative set the Block Repeat Source address Update Mode to decrement */
  1569. if(hmdma->Init.SourceBlockAddressOffset < 0)
  1570. {
  1571. hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRSUM;
  1572. /*write new CBRUR Register value : source repeat block offset */
  1573. blockoffset = (-1 * hmdma->Init.SourceBlockAddressOffset);
  1574. hmdma->Instance->CBRUR = (blockoffset & 0x0000FFFFU);
  1575. }
  1576. else
  1577. {
  1578. /*write new CBRUR Register value : source repeat block offset */
  1579. hmdma->Instance->CBRUR = (((uint32_t)hmdma->Init.SourceBlockAddressOffset) & 0x0000FFFFU);
  1580. }
  1581. /* if block destination address offset is negative set the Block Repeat destination address Update Mode to decrement */
  1582. if(hmdma->Init.DestBlockAddressOffset < 0)
  1583. {
  1584. hmdma->Instance->CBNDTR |= MDMA_CBNDTR_BRDUM;
  1585. /*write new CBRUR Register value : destination repeat block offset */
  1586. blockoffset = (-1 * hmdma->Init.DestBlockAddressOffset);
  1587. hmdma->Instance->CBRUR |= ((blockoffset & 0x0000FFFFU) << POSITION_VAL(MDMA_CBRUR_DUV));
  1588. }
  1589. else
  1590. {
  1591. /*write new CBRUR Register value : destination repeat block offset */
  1592. hmdma->Instance->CBRUR |= (((uint32_t)hmdma->Init.DestBlockAddressOffset) & 0x0000FFFFU) << POSITION_VAL(MDMA_CBRUR_DUV);
  1593. }
  1594. /* if HW request set the HW request and the requet CleraMask and ClearData MaskData, */
  1595. if(hmdma->Init.Request != MDMA_REQUEST_SW)
  1596. {
  1597. /* Set the HW request in CTRB register */
  1598. hmdma->Instance->CTBR = hmdma->Init.Request & MDMA_CTBR_TSEL;
  1599. }
  1600. else /* SW request : reset the CTBR register */
  1601. {
  1602. hmdma->Instance->CTBR = 0;
  1603. }
  1604. /*Write Link Address Register*/
  1605. hmdma->Instance->CLAR = 0;
  1606. }
  1607. /**
  1608. * @}
  1609. */
  1610. #endif /* HAL_MDMA_MODULE_ENABLED */
  1611. /**
  1612. * @}
  1613. */
  1614. /**
  1615. * @}
  1616. */
  1617. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/