1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_mdf.c
4   * @author  MCD Application Team
5   * @brief   This file provides firmware functions to manage the following
6   *          functionalities of the Multi-function Digital Filter (MDF)
7   *          peripheral:
8   *           + Initialization and de-initialization
9   *           + Acquisition
10   *           + Clock absence detection
11   *           + Short circuit detection
12   *           + Out-off limit detection
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2023 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   @verbatim
26   ==============================================================================
27                      ##### How to use this driver #####
28   ==============================================================================
29   [..]
30     *** Initialization and de-initialization ***
31     ============================================
32     [..]
33       (#) User has first to initialize MDF or ADF instance.
34       (#) As prerequisite, fill in the HAL_MDF_MspInit() :
35         (++) Enable MDFz or ADFz clock interface with __HAL_RCC_MDFz_CLK_ENABLE()
36              or __HAL_RCC_ADFz_CLK_ENABLE().
37         (++) Enable the clocks for the used GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
38         (++) Configure these pins in alternate mode using HAL_GPIO_Init().
39         (++) If interrupt mode is used, enable and configure MDFz_FLTx or ADFz
40              interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
41         (++) If DMA mode is used, initialize and configure DMA.
42       (#) Configure the common parameters (only for first MDF or ADF instance init),
43           serial interface parameters and filter bitstream selection by calling
44           HAL_MDF_Init() function.
45 
46     [..]
47       (#) User can de-initialize MDF or ADF instance with HAL_MDF_DeInit() function.
48 
49     *** Acquisition ***
50     ===================
51     [..]
52       (#) Configure filter parameters and start acquisition using HAL_MDF_AcqStart(),
53           HAL_MDF_AcqStart_IT() or HAL_MDF_AcqStart_DMA().
54       (#) In polling mode :
55             (++) Use HAL_MDF_PollForAcq() to detect the end of acquisition.
56                  Use HAL_MDF_GetAcqValue to get acquisition value.
57             (++) Only for MDF instance, use HAL_MDF_PollForSnapshotAcq() to detect
58                  the end of snapshot acquisition.
59                  Use HAL_MDF_GetSnapshotAcqValue to get snapshot acquisition value.
60             (++) Only for ADF instance, use HAL_MDF_PollForSndLvl() to detect and get
61                  new sound level value and ambient noise value.
62             (++) Only for ADF instance, use HAL_MDF_PollForSad() to detect sound activity.
63       (#) In interrupt mode :
64             (++) HAL_MDF_AcqCpltCallback() will be called at the end of acquisition.
65                  Use HAL_MDF_GetAcqValue to get acquisition value or use
66                  HAL_MDF_GetSnapshotAcqValue to get snapshot acquisition value.
67             (++) Only for ADF instance, HAL_MDF_SndLvlCallback() will be called when new
68                  sound level and ambient noise values are available.
69             (++) Only for ADF instance, HAL_MDF_SadCallback() will be called when
70                  sound activity detection occurs.
71             (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun or
72                  saturation occurs.
73                  Use HAL_MDF_GetErrorCode() to get the corresponding error.
74       (#) In DMA mode :
75             (++) HAL_MDF_AcqHalfCpltCallback() and HAL_MDF_AcqCpltCallback() will be called
76                  respectively at the half acquisition and at the acquisition complete.
77             (++) Only for ADF instance, HAL_MDF_SndLvlCallback() will be called when new
78                  sound level and ambient noise values are available.
79             (++) Only for ADF instance, HAL_MDF_SadCallback() will be called when
80                  sound activity detection occurs.
81             (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun,
82                  saturation or DMA error occurs.
83                  Use HAL_MDF_GetErrorCode() to get the corresponding error.
84       (#) Use HAL_MDF_GenerateTrgo() to generate pulse on TRGO signal.
85       (#) During acquisition, use HAL_MDF_SetDelay() and HAL_MDF_GetDelay() to respectively
86           set and get the delay on data source.
87       (#) During acquisition, use HAL_MDF_SetGain() and HAL_MDF_GetGain() to respectively
88           set and get the filter gain.
89       (#) During acquisition, use HAL_MDF_SetOffset() and HAL_MDF_GetOffset() to respectively
90           set and get the filter offset error compensation.
91       (#) During acquisition, only for MDF instance, use HAL_MDF_SetOffset() and HAL_MDF_GetOffset()
92           to respectively set and get the filter offset error compensation.
93       (#) Stop acquisition using HAL_MDF_AcqStop(), HAL_MDF_AcqStop_IT() or HAL_MDF_AcqStop_DMA().
94 
95     *** Clock absence detection ***
96     ===============================
97     [..]
98       (#) Clock absence detection is always enabled so no need to start clock absence detection
99           in polling mode.
100           Use HAL_MDF_CkabStart_IT() to start clock absence detection in interrupt mode.
101       (#) In polling mode, use HAL_MDF_PollForCkab() to detect the clock absence.
102       (#) In interrupt mode, HAL_MDF_ErrorCallback() will be called if clock absence detection
103           occurs.
104           Use HAL_MDF_GetErrorCode() to get the corresponding error.
105       (#) Stop clock absence detection in interrupt mode using HAL_MDF_CkabStop_IT().
106 
107     *** Short circuit detection ***
108     ===============================
109     [..]
110       (#) Only for MDF instance, start short circuit detection using HAL_MDF_ScdStart()
111           or HAL_MDF_ScdStart_IT().
112       (#) In polling mode, use HAL_MDF_PollForScd() to detect short circuit.
113       (#) In interrupt mode, HAL_MDF_ErrorCallback() will be called if short circuit detection
114           occurs.
115           Use HAL_MDF_GetErrorCode() to get the corresponding error.
116       (#) Stop short circuit detection using HAL_MDF_ScdStop() or HAL_MDF_ScdStop_IT().
117 
118     *** Out-off limit detection ***
119     ===============================
120     [..]
121       (#) Only for MDF instance, start out-off limit detection using HAL_MDF_OldStart()
122           or HAL_MDF_OldStart_IT().
123       (#) In polling mode, use HAL_MDF_PollForOld() to detect out-off limit and to get threshold
124           information.
125       (#) In interrupt mode, HAL_MDF_OldCallback() will be called if out-off limit detection occurs.
126       (#) Stop out-off limit detection using HAL_MDF_OldStop() or HAL_MDF_OldStop_IT().
127 
128     *** generic functions ***
129     =========================
130     [..]
131       (#) HAL_MDF_IRQHandler will be called when MDF or ADF interrupt occurs.
132       (#) HAL_MDF_ErrorCallback will be called when MDF or ADF error occurs.
133       (#) Use HAL_MDF_GetState() to get the current MDF or ADF instance state.
134       (#) Use HAL_MDF_GetErrorCode() to get the current MDF or ADF instance error code.
135 
136     *** Callback registration ***
137     =============================
138     [..]
139     The compilation define USE_HAL_MDF_REGISTER_CALLBACKS when set to 1
140     allows the user to configure dynamically the driver callbacks.
141     Use functions HAL_MDF_RegisterCallback(), HAL_MDF_RegisterOldCallback()
142     or HAL_MDF_RegisterSndLvlCallback() to register a user callback.
143 
144     [..]
145     Function HAL_MDF_RegisterCallback() allows to register following callbacks :
146       (+) AcqCpltCallback     : Acquisition complete callback.
147       (+) AcqHalfCpltCallback : Acquisition half complete callback.
148       (+) SadCallback         : Sound activity detection callback (only for ADF instance).
149       (+) ErrorCallback       : Error callback.
150       (+) MspInitCallback     : MSP init callback.
151       (+) MspDeInitCallback   : MSP de-init callback.
152     [..]
153     This function takes as parameters the HAL peripheral handle, the Callback ID
154     and a pointer to the user callback function.
155 
156     [..]
157     For MDF instance and for specific out-off limit detection callback use dedicated
158     register callback :
159     HAL_MDF_RegisterOldCallback().
160 
161     [..]
162     For ADF instance and for specific sound level callback use dedicated register callback :
163     HAL_MDF_RegisterSndLvlCallback().
164 
165     [..]
166     Use function HAL_MDF_UnRegisterCallback() to reset a callback to the default weak function.
167 
168     [..]
169     HAL_MDF_UnRegisterCallback() takes as parameters the HAL peripheral handle and the Callback ID.
170     [..]
171     This function allows to reset following callbacks :
172       (+) AcqCpltCallback     : Acquisition complete callback.
173       (+) AcqHalfCpltCallback : Acquisition half complete callback.
174       (+) SadCallback         : Sound activity detection callback (only for ADF instance).
175       (+) ErrorCallback       : Error callback.
176       (+) MspInitCallback     : MSP init callback.
177       (+) MspDeInitCallback   : MSP de-init callback.
178 
179     [..]
180     For MDF instance and for specific out-off limit detection callback use dedicated
181     unregister callback :
182     HAL_MDF_UnRegisterOldCallback().
183 
184     [..]
185     For ADF instance and for specific sound level callback use dedicated unregister callback :
186     HAL_MDF_UnRegisterSndLvlCallback().
187 
188     [..]
189     By default, after the call of init function and if the state is RESET
190     all callbacks are reset to the corresponding legacy weak functions :
191     examples HAL_MDF_AcqCpltCallback(), HAL_MDF_ErrorCallback().
192     Exception done for MspInit and MspDeInit callbacks that are respectively
193     reset to the legacy weak functions in the init and de-init only when these
194     callbacks are null (not registered beforehand).
195     If not, MspInit or MspDeInit are not null, the init and de-init keep and use
196     the user MspInit/MspDeInit callbacks (registered beforehand).
197 
198     [..]
199     Callbacks can be registered/unregistered in READY state only.
200     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
201     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
202     during the init/de-init.
203     In that case first register the MspInit/MspDeInit user callbacks using
204     HAL_MDF_RegisterCallback() before calling init or de-init function.
205 
206     [..]
207     When the compilation define USE_HAL_MDF_REGISTER_CALLBACKS is set to 0 or
208     not defined, the callback registering feature is not available
209     and weak callbacks are used.
210 
211     @endverbatim
212   */
213 
214 /* Includes ------------------------------------------------------------------*/
215 #include "stm32n6xx_hal.h"
216 
217 /** @addtogroup STM32N6xx_HAL_Driver
218   * @{
219   */
220 
221 /** @defgroup MDF MDF
222   * @brief MDF HAL module driver
223   * @{
224   */
225 
226 #ifdef HAL_MDF_MODULE_ENABLED
227 
228 /* Private typedef -----------------------------------------------------------*/
229 /** @defgroup MDF_Private_Typedefs  MDF Private Typedefs
230   * @{
231   */
232 /**
233   * @}
234   */
235 
236 /* Private define ------------------------------------------------------------*/
237 /** @defgroup MDF_Private_Constants  MDF Private Constants
238   * @{
239   */
240 #define MDF_INSTANCE_NUMBER 7U /* 6 instances for MDF1 and 1 instance for ADF1 */
241 /**
242   * @}
243   */
244 
245 /* Private macro -------------------------------------------------------------*/
246 /* Private variables ---------------------------------------------------------*/
247 /** @defgroup MDF_Private_Variables  MDF Private Variables
248   * @{
249   */
250 static uint32_t           v_mdf1InstanceCounter = 0U;
251 static uint32_t           v_adf1InstanceCounter = 0U;
252 static MDF_HandleTypeDef *a_mdfHandle[MDF_INSTANCE_NUMBER] = {NULL};
253 /**
254   * @}
255   */
256 
257 /* Private function prototypes -----------------------------------------------*/
258 /** @defgroup MDF_Private_Functions  MDF Private Functions
259   * @{
260   */
261 static uint32_t MDF_GetHandleNumberFromInstance(const MDF_Filter_TypeDef *const pInstance);
262 static void     MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig);
263 static void     MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma);
264 static void     MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma);
265 static void     MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma);
266 /**
267   * @}
268   */
269 
270 /* Exported functions ---------------------------------------------------------*/
271 /** @defgroup MDF_Exported_Functions  MDF Exported Functions
272   * @{
273   */
274 
275 /** @defgroup MDF_Exported_Functions_Group1  Initialization and de-initialization functions
276   * @brief    Initialization and de-initialization functions
277   *
278 @verbatim
279   ==============================================================================
280             ##### Initialization and de-initialization functions #####
281   ==============================================================================
282     [..]  This section provides functions allowing to :
283       (+) Initialize the MDF or ADF instance.
284       (+) De-initialize the MDF or ADF instance.
285       (+) Register and unregister callbacks.
286 @endverbatim
287   * @{
288   */
289 
290 /**
291   * @brief  Initialize the MDF instance according to the specified parameters
292   *         in the MDF_InitTypeDef structure and initialize the associated handle.
293   * @param  hmdf MDF handle.
294   * @retval HAL status.
295   */
HAL_MDF_Init(MDF_HandleTypeDef * hmdf)296 HAL_StatusTypeDef HAL_MDF_Init(MDF_HandleTypeDef *hmdf)
297 {
298   HAL_StatusTypeDef status = HAL_OK;
299 
300   /* Check MDF handle */
301   if (hmdf == NULL)
302   {
303     status = HAL_ERROR;
304   }
305   else
306   {
307     /* Check parameters */
308     assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance));
309     assert_param(IS_MDF_FILTER_BITSTREAM(hmdf->Init.FilterBistream));
310     assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.SerialInterface.Activation));
311 
312     /* Check that instance has not been already initialized */
313     if (a_mdfHandle[MDF_GetHandleNumberFromInstance(hmdf->Instance)] != NULL)
314     {
315       status = HAL_ERROR;
316     }
317     else
318     {
319 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
320       /* Reset callback pointers to the weak predefined callbacks */
321       if (IS_ADF_INSTANCE(hmdf->Instance))
322       {
323         hmdf->OldCallback   = NULL;
324         hmdf->SndLvCallback = HAL_MDF_SndLvlCallback;
325         hmdf->SadCallback   = HAL_MDF_SadCallback;
326       }
327       else /* MDF instance */
328       {
329         hmdf->OldCallback   = HAL_MDF_OldCallback;
330         hmdf->SndLvCallback = NULL;
331         hmdf->SadCallback   = NULL;
332       }
333       hmdf->AcqCpltCallback     = HAL_MDF_AcqCpltCallback;
334       hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback;
335       hmdf->ErrorCallback       = HAL_MDF_ErrorCallback;
336 
337       /* Call MDF MSP init function */
338       if (hmdf->MspInitCallback == NULL)
339       {
340         hmdf->MspInitCallback = HAL_MDF_MspInit;
341       }
342       hmdf->MspInitCallback(hmdf);
343 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
344       /* Call MDF MSP init function */
345       HAL_MDF_MspInit(hmdf);
346 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
347 
348       /* Configure common parameters only for first MDF or ADF instance */
349       if (((v_mdf1InstanceCounter == 0U) && IS_MDF_INSTANCE(hmdf->Instance)) ||
350           ((v_adf1InstanceCounter == 0U) && IS_ADF_INSTANCE(hmdf->Instance)))
351       {
352         MDF_TypeDef *mdfBase;
353         /* Get MDF base according instance */
354         mdfBase = (IS_ADF_INSTANCE(hmdf->Instance)) ? ADF1 : MDF1;
355 
356         /* Check clock generator status */
357         if ((mdfBase->CKGCR & MDF_CKGCR_CCKACTIVE) != 0U)
358         {
359           status = HAL_ERROR;
360         }
361         else
362         {
363           /* Configure number of interleaved filters for MDF instance */
364           if (IS_MDF_INSTANCE(hmdf->Instance))
365           {
366             assert_param(IS_MDF_INTERLEAVED_FILTERS(hmdf->Init.CommonParam.InterleavedFilters));
367             mdfBase->GCR &= ~(MDF_GCR_ILVNB);
368             mdfBase->GCR |= (hmdf->Init.CommonParam.InterleavedFilters << MDF_GCR_ILVNB_Pos);
369           }
370 
371           /* Configure processing clock divider, output clock divider,
372              output clock pins and output clock generation trigger */
373           assert_param(IS_MDF_PROC_CLOCK_DIVIDER(hmdf->Init.CommonParam.ProcClockDivider));
374           assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Activation));
375           mdfBase->CKGCR = 0U;
376           mdfBase->CKGCR |= ((hmdf->Init.CommonParam.ProcClockDivider - 1U) << MDF_CKGCR_PROCDIV_Pos);
377           if (hmdf->Init.CommonParam.OutputClock.Activation == ENABLE)
378           {
379             assert_param(IS_MDF_OUTPUT_CLOCK_PINS(hmdf->Init.CommonParam.OutputClock.Pins));
380             assert_param(IS_MDF_OUTPUT_CLOCK_DIVIDER(hmdf->Init.CommonParam.OutputClock.Divider));
381             assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Trigger.Activation));
382             mdfBase->CKGCR |= (((hmdf->Init.CommonParam.OutputClock.Divider - 1U) << MDF_CKGCR_CCKDIV_Pos) |
383                                hmdf->Init.CommonParam.OutputClock.Pins |
384                                (hmdf->Init.CommonParam.OutputClock.Pins >> 4U));
385             if (hmdf->Init.CommonParam.OutputClock.Trigger.Activation == ENABLE)
386             {
387               if (IS_MDF_INSTANCE(hmdf->Instance))
388               {
389                 assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_SOURCE(hmdf->Init.CommonParam.OutputClock.Trigger.Source));
390               }
391               else /* ADF instance */
392               {
393                 assert_param(IS_ADF_OUTPUT_CLOCK_TRIGGER_SOURCE(hmdf->Init.CommonParam.OutputClock.Trigger.Source));
394               }
395               assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_EDGE(hmdf->Init.CommonParam.OutputClock.Trigger.Edge));
396               mdfBase->CKGCR |= (hmdf->Init.CommonParam.OutputClock.Trigger.Source |
397                                  hmdf->Init.CommonParam.OutputClock.Trigger.Edge |
398                                  MDF_CKGCR_CKGMOD);
399             }
400           }
401 
402           /* Activate clock generator */
403           mdfBase->CKGCR |= MDF_CKGCR_CKDEN;
404         }
405       }
406 
407       /* Configure serial interface */
408       if ((status == HAL_OK) && (hmdf->Init.SerialInterface.Activation == ENABLE))
409       {
410         /* Check serial interface status */
411         if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U)
412         {
413           status = HAL_ERROR;
414         }
415         else
416         {
417           /* Configure mode, clock source and threshold */
418           assert_param(IS_MDF_SITF_MODE(hmdf->Init.SerialInterface.Mode));
419           assert_param(IS_MDF_SITF_CLOCK_SOURCE(hmdf->Init.SerialInterface.ClockSource));
420           assert_param(IS_MDF_SITF_THRESHOLD(hmdf->Init.SerialInterface.Threshold));
421           hmdf->Instance->SITFCR = 0U;
422           hmdf->Instance->SITFCR |= ((hmdf->Init.SerialInterface.Threshold << MDF_SITFCR_STH_Pos) |
423                                      hmdf->Init.SerialInterface.Mode | hmdf->Init.SerialInterface.ClockSource);
424 
425           /* Activate serial interface */
426           hmdf->Instance->SITFCR |= MDF_SITFCR_SITFEN;
427         }
428       }
429 
430       if (status == HAL_OK)
431       {
432         /* Configure filter bitstream */
433         hmdf->Instance->BSMXCR &= ~(MDF_BSMXCR_BSSEL);
434         hmdf->Instance->BSMXCR |= hmdf->Init.FilterBistream;
435 
436         /* Update instance counter and table */
437         if (IS_ADF_INSTANCE(hmdf->Instance))
438         {
439           v_adf1InstanceCounter++;
440         }
441         else /* MDF instance */
442         {
443           v_mdf1InstanceCounter++;
444         }
445         a_mdfHandle[MDF_GetHandleNumberFromInstance(hmdf->Instance)] = hmdf;
446 
447         /* Update error code and state */
448         hmdf->ErrorCode = MDF_ERROR_NONE;
449         hmdf->State     = HAL_MDF_STATE_READY;
450       }
451     }
452   }
453 
454   /* Return function status */
455   return status;
456 }
457 
458 /**
459   * @brief  De-initialize the MDF instance.
460   * @param  hmdf MDF handle.
461   * @retval HAL status.
462   */
HAL_MDF_DeInit(MDF_HandleTypeDef * hmdf)463 HAL_StatusTypeDef HAL_MDF_DeInit(MDF_HandleTypeDef *hmdf)
464 {
465   HAL_StatusTypeDef status = HAL_OK;
466 
467   /* Check MDF handle */
468   if (hmdf == NULL)
469   {
470     status = HAL_ERROR;
471   }
472   else
473   {
474     /* Check parameters */
475     assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance));
476 
477     /* Check that instance has not been already deinitialized */
478     if (a_mdfHandle[MDF_GetHandleNumberFromInstance(hmdf->Instance)] == NULL)
479     {
480       status = HAL_ERROR;
481     }
482     else
483     {
484       if (IS_MDF_INSTANCE(hmdf->Instance))
485       {
486         /* Disable short circuit detector if needed */
487         if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) != 0U)
488         {
489           hmdf->Instance->SCDCR &= ~(MDF_SCDCR_SCDEN);
490         }
491 
492         /* Disable out-off limit detector if needed */
493         if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != 0U)
494         {
495           hmdf->Instance->OLDCR &= ~(MDF_OLDCR_OLDEN);
496         }
497       }
498 
499       /* Disable sound activity detector if needed */
500       if (IS_ADF_INSTANCE(hmdf->Instance))
501       {
502         if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
503         {
504           hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
505         }
506       }
507 
508       /* Disable filter if needed */
509       if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
510       {
511         hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
512       }
513 
514       /* Disable serial interface if needed */
515       if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U)
516       {
517         hmdf->Instance->SITFCR &= ~(MDF_SITFCR_SITFEN);
518       }
519 
520       /* Disable all interrupts and clear all pending flags */
521       hmdf->Instance->DFLTIER = 0U;
522       hmdf->Instance->DFLTISR = 0xFFFFFFFFU;
523 
524       /* Disable clock generator only for last MDF or ADF instance deinitialization */
525       if (((v_mdf1InstanceCounter == 1U) && IS_MDF_INSTANCE(hmdf->Instance)) ||
526           ((v_adf1InstanceCounter == 1U) && IS_ADF_INSTANCE(hmdf->Instance)))
527       {
528         MDF_TypeDef *p_mdf_base;
529         /* Get MDF base according instance */
530         p_mdf_base = (IS_ADF_INSTANCE(hmdf->Instance)) ? ADF1 : MDF1;
531 
532         /* Disable clock generator */
533         p_mdf_base->CKGCR &= ~(MDF_CKGCR_CKDEN);
534       }
535 
536       /* Call MDF MSP deinit function */
537 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
538       if (hmdf->MspDeInitCallback == NULL)
539       {
540         hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
541       }
542       hmdf->MspDeInitCallback(hmdf);
543 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
544       HAL_MDF_MspDeInit(hmdf);
545 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
546 
547       /* Update instance counter and table */
548       if (IS_ADF_INSTANCE(hmdf->Instance))
549       {
550         v_adf1InstanceCounter--;
551       }
552       else /* MDF instance */
553       {
554         v_mdf1InstanceCounter--;
555       }
556       a_mdfHandle[MDF_GetHandleNumberFromInstance(hmdf->Instance)] = (MDF_HandleTypeDef *) NULL;
557 
558       /* Update state */
559       hmdf->State = HAL_MDF_STATE_RESET;
560     }
561   }
562 
563   /* Return function status */
564   return status;
565 }
566 
567 /**
568   * @brief  Initialize the MDF instance MSP.
569   * @param  hmdf MDF handle.
570   * @retval None.
571   */
HAL_MDF_MspInit(MDF_HandleTypeDef * hmdf)572 __weak void HAL_MDF_MspInit(MDF_HandleTypeDef *hmdf)
573 {
574   /* Prevent unused argument(s) compilation warning */
575   UNUSED(hmdf);
576 
577   /* NOTE : This function should not be modified, when the function is needed,
578             the HAL_MDF_MspInit could be implemented in the user file */
579 }
580 
581 /**
582   * @brief  De-initialize the MDF instance MSP.
583   * @param  hmdf MDF handle.
584   * @retval None.
585   */
HAL_MDF_MspDeInit(MDF_HandleTypeDef * hmdf)586 __weak void HAL_MDF_MspDeInit(MDF_HandleTypeDef *hmdf)
587 {
588   /* Prevent unused argument(s) compilation warning */
589   UNUSED(hmdf);
590 
591   /* NOTE : This function should not be modified, when the function is needed,
592             the HAL_MDF_MspDeInit could be implemented in the user file */
593 }
594 
595 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
596 /**
597   * @brief  Register a user MDF callback to be used instead of the weak predefined callback.
598   * @param  hmdf MDF handle.
599   * @param  CallbackID ID of the callback to be registered.
600   *         This parameter can be one of the following values:
601   *           @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID.
602   *           @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID.
603   *           @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance).
604   *           @arg @ref HAL_MDF_ERROR_CB_ID error callback ID.
605   *           @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID.
606   *           @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID.
607   * @param  pCallback pointer to the callback function.
608   * @retval HAL status.
609   */
HAL_MDF_RegisterCallback(MDF_HandleTypeDef * hmdf,HAL_MDF_CallbackIDTypeDef CallbackID,pMDF_CallbackTypeDef pCallback)610 HAL_StatusTypeDef HAL_MDF_RegisterCallback(MDF_HandleTypeDef        *hmdf,
611                                            HAL_MDF_CallbackIDTypeDef CallbackID,
612                                            pMDF_CallbackTypeDef      pCallback)
613 {
614   HAL_StatusTypeDef status = HAL_OK;
615 
616   /* Check parameters */
617   if (pCallback == NULL)
618   {
619     /* Update error code and status */
620     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
621     status = HAL_ERROR;
622   }
623   else
624   {
625     if (hmdf->State == HAL_MDF_STATE_READY)
626     {
627       switch (CallbackID)
628       {
629         case HAL_MDF_ACQ_COMPLETE_CB_ID :
630           hmdf->AcqCpltCallback = pCallback;
631           break;
632         case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID :
633           hmdf->AcqHalfCpltCallback = pCallback;
634           break;
635         case HAL_MDF_SAD_CB_ID :
636           hmdf->SadCallback = pCallback;
637           break;
638         case HAL_MDF_ERROR_CB_ID :
639           hmdf->ErrorCallback = pCallback;
640           break;
641         case HAL_MDF_MSPINIT_CB_ID :
642           hmdf->MspInitCallback = pCallback;
643           break;
644         case HAL_MDF_MSPDEINIT_CB_ID :
645           hmdf->MspDeInitCallback = pCallback;
646           break;
647         default :
648           /* Update error code and status */
649           hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
650           status = HAL_ERROR;
651           break;
652       }
653     }
654     else if (hmdf->State == HAL_MDF_STATE_RESET)
655     {
656       switch (CallbackID)
657       {
658         case HAL_MDF_MSPINIT_CB_ID :
659           hmdf->MspInitCallback = pCallback;
660           break;
661         case HAL_MDF_MSPDEINIT_CB_ID :
662           hmdf->MspDeInitCallback = pCallback;
663           break;
664         default :
665           /* Update error code and status */
666           hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
667           status = HAL_ERROR;
668           break;
669       }
670     }
671     else
672     {
673       /* Update error code and status */
674       hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
675       status = HAL_ERROR;
676     }
677   }
678 
679   /* Return function status */
680   return status;
681 }
682 
683 /**
684   * @brief  Unregister a user MDF callback.
685   *         MDF callback is redirected to the weak predefined callback.
686   * @param  hmdf MDF handle.
687   * @param  CallbackID ID of the callback to be unregistered.
688   *         This parameter can be one of the following values:
689   *           @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID.
690   *           @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID.
691   *           @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance).
692   *           @arg @ref HAL_MDF_ERROR_CB_ID error callback ID.
693   *           @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID.
694   *           @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID.
695   * @retval HAL status.
696   */
HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef * hmdf,HAL_MDF_CallbackIDTypeDef CallbackID)697 HAL_StatusTypeDef HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef        *hmdf,
698                                              HAL_MDF_CallbackIDTypeDef CallbackID)
699 {
700   HAL_StatusTypeDef status = HAL_OK;
701 
702   if (hmdf->State == HAL_MDF_STATE_READY)
703   {
704     switch (CallbackID)
705     {
706       case HAL_MDF_ACQ_COMPLETE_CB_ID :
707         hmdf->AcqCpltCallback = HAL_MDF_AcqCpltCallback;
708         break;
709       case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID :
710         hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback;
711         break;
712       case HAL_MDF_SAD_CB_ID :
713         hmdf->SadCallback = HAL_MDF_SadCallback;
714         break;
715       case HAL_MDF_ERROR_CB_ID :
716         hmdf->ErrorCallback = HAL_MDF_ErrorCallback;
717         break;
718       case HAL_MDF_MSPINIT_CB_ID :
719         hmdf->MspInitCallback = HAL_MDF_MspInit;
720         break;
721       case HAL_MDF_MSPDEINIT_CB_ID :
722         hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
723         break;
724       default :
725         /* Update error code and status */
726         hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
727         status = HAL_ERROR;
728         break;
729     }
730   }
731   else if (hmdf->State == HAL_MDF_STATE_RESET)
732   {
733     switch (CallbackID)
734     {
735       case HAL_MDF_MSPINIT_CB_ID :
736         hmdf->MspInitCallback = HAL_MDF_MspInit;
737         break;
738       case HAL_MDF_MSPDEINIT_CB_ID :
739         hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
740         break;
741       default :
742         /* Update error code and status */
743         hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
744         status = HAL_ERROR;
745         break;
746     }
747   }
748   else
749   {
750     /* Update error code and status */
751     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
752     status = HAL_ERROR;
753   }
754 
755   /* Return function status */
756   return status;
757 }
758 
759 /**
760   * @brief  Register specific MDF out-off limit detector callback
761   *         to be used instead of the weak predefined callback.
762   * @param  hmdf MDF handle.
763   * @param  pCallback pointer to the out-off limit detector callback function.
764   * @retval HAL status.
765   * @note   This function must not be used with ADF instance.
766   */
HAL_MDF_RegisterOldCallback(MDF_HandleTypeDef * hmdf,pMDF_OldCallbackTypeDef pCallback)767 HAL_StatusTypeDef HAL_MDF_RegisterOldCallback(MDF_HandleTypeDef      *hmdf,
768                                               pMDF_OldCallbackTypeDef pCallback)
769 {
770   HAL_StatusTypeDef status = HAL_OK;
771 
772   /* Check parameters */
773   if (pCallback == NULL)
774   {
775     /* Update error code and status */
776     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
777     status = HAL_ERROR;
778   }
779   else
780   {
781     if (hmdf->State == HAL_MDF_STATE_READY)
782     {
783       hmdf->OldCallback = pCallback;
784     }
785     else
786     {
787       /* Update error code and status */
788       hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
789       status = HAL_ERROR;
790     }
791   }
792 
793   /* Return function status */
794   return status;
795 }
796 
797 /**
798   * @brief  Unregister the specific MDF out-off limit detector callback.
799   *         MDF out-off limit detector callback is redirected to the weak predefined callback.
800   * @param  hmdf MDF handle.
801   * @retval HAL status.
802   * @note   This function must not be used with ADF instance.
803   */
HAL_MDF_UnRegisterOldCallback(MDF_HandleTypeDef * hmdf)804 HAL_StatusTypeDef HAL_MDF_UnRegisterOldCallback(MDF_HandleTypeDef *hmdf)
805 {
806   HAL_StatusTypeDef status = HAL_OK;
807 
808   if (hmdf->State == HAL_MDF_STATE_READY)
809   {
810     hmdf->OldCallback = HAL_MDF_OldCallback;
811   }
812   else
813   {
814     /* Update error code and status */
815     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
816     status = HAL_ERROR;
817   }
818 
819   /* Return function status */
820   return status;
821 }
822 
823 /**
824   * @brief  Register specific MDF sound level callback
825   *         to be used instead of the weak predefined callback.
826   * @param  hmdf MDF handle.
827   * @param  pCallback pointer to the sound level callback function.
828   * @retval HAL status.
829   * @note   This function must not be used with MDF instance.
830   */
HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef * hmdf,pMDF_SndLvlCallbackTypeDef pCallback)831 HAL_StatusTypeDef HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef         *hmdf,
832                                                  pMDF_SndLvlCallbackTypeDef pCallback)
833 {
834   HAL_StatusTypeDef status = HAL_OK;
835 
836   /* Check parameters */
837   if (pCallback == NULL)
838   {
839     /* Update error code and status */
840     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
841     status = HAL_ERROR;
842   }
843   else
844   {
845     if (hmdf->State == HAL_MDF_STATE_READY)
846     {
847       hmdf->SndLvCallback = pCallback;
848     }
849     else
850     {
851       /* Update error code and status */
852       hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
853       status = HAL_ERROR;
854     }
855   }
856 
857   /* Return function status */
858   return status;
859 }
860 
861 /**
862   * @brief  Unregister the specific MDF sound level callback.
863   *         MDF sound level callback is redirected to the weak predefined callback.
864   * @param  hmdf MDF handle.
865   * @retval HAL status.
866   * @note   This function must not be used with MDF instance.
867   */
HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef * hmdf)868 HAL_StatusTypeDef HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef *hmdf)
869 {
870   HAL_StatusTypeDef status = HAL_OK;
871 
872   if (hmdf->State == HAL_MDF_STATE_READY)
873   {
874     hmdf->SndLvCallback = HAL_MDF_SndLvlCallback;
875   }
876   else
877   {
878     /* Update error code and status */
879     hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
880     status = HAL_ERROR;
881   }
882 
883   /* Return function status */
884   return status;
885 }
886 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
887 
888 /**
889   * @}
890   */
891 
892 /** @defgroup MDF_Exported_Functions_Group2  Acquisition functions
893   * @brief    Acquisition functions
894   *
895 @verbatim
896   ==============================================================================
897                         ##### Acquisition functions #####
898   ==============================================================================
899     [..]  This section provides functions allowing to :
900       (+) Start and stop acquisition in polling, interrupt or DMA mode.
901       (+) Wait and get acquisition values.
902       (+) Generate pulse on TRGO signal.
903       (+) Modify and get some filter parameters during acquisition.
904       (+) Wait and get sound level values for ADF instance.
905       (+) Detect sound activity for ADF instance.
906 @endverbatim
907   * @{
908   */
909 
910 /**
911   * @brief  This function allows to start acquisition in polling mode.
912   * @param  hmdf MDF handle.
913   * @param  pFilterConfig Filter configuration parameters.
914   * @retval HAL status.
915   */
HAL_MDF_AcqStart(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig)916 HAL_StatusTypeDef HAL_MDF_AcqStart(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig)
917 {
918   HAL_StatusTypeDef status = HAL_OK;
919 
920   /* Check parameters */
921   if (pFilterConfig == NULL)
922   {
923     status = HAL_ERROR;
924   }
925   else
926   {
927     if (IS_ADF_INSTANCE(hmdf->Instance))
928     {
929       assert_param(IS_ADF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
930       assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
931     }
932     else
933     {
934       assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
935     }
936     if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE) &&
937         ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
938          (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
939          (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
940     {
941       status = HAL_ERROR;
942     }
943     /* Check state */
944     else if (hmdf->State != HAL_MDF_STATE_READY)
945     {
946       status = HAL_ERROR;
947     }
948     /* Check filter status */
949     else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
950     {
951       status = HAL_ERROR;
952     }
953     else
954     {
955       /* For ADF instance, check SAD status */
956       if (IS_ADF_INSTANCE(hmdf->Instance))
957       {
958         if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
959         {
960           status = HAL_ERROR;
961         }
962       }
963     }
964 
965     if (status == HAL_OK)
966     {
967       /* For MDF instance, check OLD status and main filter order */
968       assert_param(IS_MDF_CIC_MODE(pFilterConfig->CicMode));
969       if (IS_MDF_INSTANCE(hmdf->Instance))
970       {
971         if (((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != 0U) && (pFilterConfig->CicMode >= MDF_ONE_FILTER_SINC4))
972         {
973           status = HAL_ERROR;
974         }
975       }
976 
977       if (status == HAL_OK)
978       {
979         /* Configure filter and start acquisition */
980         hmdf->Instance->DFLTCR = 0U;
981         MDF_AcqStart(hmdf, pFilterConfig);
982       }
983     }
984   }
985 
986   /* Return function status */
987   return status;
988 }
989 
990 /**
991   * @brief  This function allows to poll for available acquisition value.
992   * @param  hmdf MDF handle.
993   * @param  Timeout Timeout value in milliseconds.
994   * @retval HAL status.
995   */
HAL_MDF_PollForAcq(MDF_HandleTypeDef * hmdf,uint32_t Timeout)996 HAL_StatusTypeDef HAL_MDF_PollForAcq(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
997 {
998   HAL_StatusTypeDef status = HAL_OK;
999 
1000   /* Check state */
1001   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1002   {
1003     status = HAL_ERROR;
1004   }
1005   else
1006   {
1007     uint32_t tickstart = HAL_GetTick();
1008 
1009     /* Wait for available acquisition value */
1010     while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_RXNEF) != MDF_DFLTISR_RXNEF) && (status == HAL_OK))
1011     {
1012       /* Check the timeout */
1013       if (Timeout != HAL_MAX_DELAY)
1014       {
1015         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1016         {
1017           status = HAL_TIMEOUT;
1018         }
1019       }
1020     }
1021 
1022     /* Check if data overflow, saturation or reshape filter occurs */
1023     uint32_t error_flags = (hmdf->Instance->DFLTISR & (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF));
1024     if (error_flags != 0U)
1025     {
1026       /* Update error code */
1027       if ((error_flags & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF)
1028       {
1029         hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
1030       }
1031       if ((error_flags & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF)
1032       {
1033         hmdf->ErrorCode |= MDF_ERROR_SATURATION;
1034       }
1035       if ((error_flags & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF)
1036       {
1037         hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN;
1038       }
1039 
1040       /* Clear corresponding flags */
1041       hmdf->Instance->DFLTISR |= error_flags;
1042 
1043       /* Call error callback */
1044 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1045       hmdf->ErrorCallback(hmdf);
1046 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1047       HAL_MDF_ErrorCallback(hmdf);
1048 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1049     }
1050 
1051     if (status == HAL_OK)
1052     {
1053       /* Update state only in asynchronous single shot mode */
1054       if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE)
1055       {
1056         hmdf->State = HAL_MDF_STATE_READY;
1057       }
1058     }
1059   }
1060 
1061   /* Return function status */
1062   return status;
1063 }
1064 
1065 /**
1066   * @brief  This function allows to poll for available snapshot acquisition value.
1067   * @param  hmdf MDF handle.
1068   * @param  Timeout Timeout value in milliseconds.
1069   * @retval HAL status.
1070   * @note   This function must not be used with ADF instance.
1071   */
HAL_MDF_PollForSnapshotAcq(MDF_HandleTypeDef * hmdf,uint32_t Timeout)1072 HAL_StatusTypeDef HAL_MDF_PollForSnapshotAcq(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
1073 {
1074   HAL_StatusTypeDef status = HAL_OK;
1075 
1076   /* Check state */
1077   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1078   {
1079     status = HAL_ERROR;
1080   }
1081   else
1082   {
1083     uint32_t tickstart = HAL_GetTick();
1084 
1085     /* Wait for available snapshot acquisition value */
1086     while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SSDRF) != MDF_DFLTISR_SSDRF) && (status == HAL_OK))
1087     {
1088       /* Check the timeout */
1089       if (Timeout != HAL_MAX_DELAY)
1090       {
1091         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1092         {
1093           status = HAL_TIMEOUT;
1094         }
1095       }
1096     }
1097 
1098     /* Check if snapshot overrun, saturation or reshape filter occurs */
1099     uint32_t error_flags = (hmdf->Instance->DFLTISR & (MDF_DFLTISR_SSOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF));
1100     if (error_flags != 0U)
1101     {
1102       /* Update error code */
1103       if ((error_flags & MDF_DFLTISR_SSOVRF) == MDF_DFLTISR_SSOVRF)
1104       {
1105         hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
1106       }
1107       if ((error_flags & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF)
1108       {
1109         hmdf->ErrorCode |= MDF_ERROR_SATURATION;
1110       }
1111       if ((error_flags & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF)
1112       {
1113         hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN;
1114       }
1115 
1116       /* Clear corresponding flags */
1117       hmdf->Instance->DFLTISR |= error_flags;
1118 
1119       /* Call error callback */
1120 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1121       hmdf->ErrorCallback(hmdf);
1122 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1123       HAL_MDF_ErrorCallback(hmdf);
1124 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1125     }
1126   }
1127 
1128   /* Return function status */
1129   return status;
1130 }
1131 
1132 /**
1133   * @brief  This function allows to get acquisition value.
1134   * @param  hmdf MDF handle.
1135   * @param  pValue Acquisition value on 24 MSB.
1136   * @retval HAL status.
1137   */
HAL_MDF_GetAcqValue(const MDF_HandleTypeDef * hmdf,int32_t * pValue)1138 HAL_StatusTypeDef HAL_MDF_GetAcqValue(const MDF_HandleTypeDef *hmdf, int32_t *pValue)
1139 {
1140   HAL_StatusTypeDef status = HAL_OK;
1141 
1142   /* Check parameters */
1143   if (pValue == NULL)
1144   {
1145     status = HAL_ERROR;
1146   }
1147   else
1148   {
1149     /* Check state */
1150     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1151     {
1152       if (hmdf->State != HAL_MDF_STATE_READY)
1153       {
1154         status = HAL_ERROR;
1155       }
1156     }
1157   }
1158 
1159   if (status == HAL_OK)
1160   {
1161     /* Get acquisition value */
1162     *pValue = (int32_t) hmdf->Instance->DFLTDR;
1163   }
1164 
1165   /* Return function status */
1166   return status;
1167 }
1168 
1169 /**
1170   * @brief  This function allows to get snapshot acquisition value.
1171   * @param  hmdf MDF handle.
1172   * @param  pSnapshotParam Snapshot parameters.
1173   * @retval HAL status.
1174   * @note   This function must not be used with ADF instance.
1175   */
HAL_MDF_GetSnapshotAcqValue(MDF_HandleTypeDef * hmdf,MDF_SnapshotParamTypeDef * pSnapshotParam)1176 HAL_StatusTypeDef HAL_MDF_GetSnapshotAcqValue(MDF_HandleTypeDef *hmdf, MDF_SnapshotParamTypeDef *pSnapshotParam)
1177 {
1178   HAL_StatusTypeDef status = HAL_OK;
1179 
1180   /* Check parameters */
1181   if (pSnapshotParam == NULL)
1182   {
1183     status = HAL_ERROR;
1184   }
1185   /* Check state */
1186   else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1187   {
1188     status = HAL_ERROR;
1189   }
1190   else
1191   {
1192     uint32_t snpsdr_value;
1193 
1194     /* Read value of snapshot data register */
1195     snpsdr_value = hmdf->Instance->SNPSDR;
1196 
1197     /* Clear snapshot data ready flag */
1198     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SSDRF;
1199 
1200     /* Store value of decimation counter in snapshot parameter structure */
1201     pSnapshotParam->DecimationCounter = (snpsdr_value & MDF_SNPSDR_MCICDC);
1202 
1203     /* Check snapshot format */
1204     if ((hmdf->Instance->DFLTCR & MDF_SNAPSHOT_16BITS) == MDF_SNAPSHOT_16BITS)
1205     {
1206       /* Store value of integrator counter in snapshot parameter structure */
1207       pSnapshotParam->IntegratorCounter = ((snpsdr_value & MDF_SNPSDR_EXTSDR) >> MDF_SNPSDR_EXTSDR_Pos);
1208 
1209       /* Store snapshot acquisition value (16MSB) in snapshot parameter structure */
1210       snpsdr_value &= 0xFFFF0000U;
1211       pSnapshotParam->Value = (int32_t) snpsdr_value;
1212     }
1213     else
1214     {
1215       /* Store snapshot acquisition value (23MSB) in snapshot parameter structure */
1216       snpsdr_value &= 0xFFFFFE00U;
1217       pSnapshotParam->Value = (int32_t) snpsdr_value;
1218     }
1219   }
1220 
1221   /* Return function status */
1222   return status;
1223 }
1224 
1225 /**
1226   * @brief  This function allows to stop acquisition in polling mode.
1227   * @param  hmdf MDF handle.
1228   * @retval HAL status.
1229   */
HAL_MDF_AcqStop(MDF_HandleTypeDef * hmdf)1230 HAL_StatusTypeDef HAL_MDF_AcqStop(MDF_HandleTypeDef *hmdf)
1231 {
1232   HAL_StatusTypeDef status = HAL_OK;
1233 
1234   /* Check state */
1235   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1236   {
1237     /* Check if state is ready and filter active */
1238     if (hmdf->State == HAL_MDF_STATE_READY)
1239     {
1240       if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
1241       {
1242         status = HAL_ERROR;
1243       }
1244     }
1245     else
1246     {
1247       status = HAL_ERROR;
1248     }
1249   }
1250   else
1251   {
1252     /* Disable sound activity detector if needed for ADF instance */
1253     if (IS_ADF_INSTANCE(hmdf->Instance))
1254     {
1255       if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1256       {
1257         hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
1258       }
1259     }
1260   }
1261 
1262   if (status == HAL_OK)
1263   {
1264     /* Disable filter */
1265     hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
1266 
1267     /* Clear all potential pending flags */
1268     if (IS_ADF_INSTANCE(hmdf->Instance))
1269     {
1270       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF |
1271                                   MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF);
1272     }
1273     else
1274     {
1275       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SSDRF | MDF_DFLTISR_SSOVRF |
1276                                   MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF);
1277     }
1278 
1279     /* Update state */
1280     hmdf->State = HAL_MDF_STATE_READY;
1281   }
1282 
1283   /* Return function status */
1284   return status;
1285 }
1286 
1287 /**
1288   * @brief  This function allows to start acquisition in interrupt mode.
1289   * @param  hmdf MDF handle.
1290   * @param  pFilterConfig Filter configuration parameters.
1291   * @retval HAL status.
1292   */
HAL_MDF_AcqStart_IT(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig)1293 HAL_StatusTypeDef HAL_MDF_AcqStart_IT(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig)
1294 {
1295   HAL_StatusTypeDef status = HAL_OK;
1296 
1297   /* Check parameters */
1298   if (pFilterConfig == NULL)
1299   {
1300     status = HAL_ERROR;
1301   }
1302   else
1303   {
1304     if (IS_ADF_INSTANCE(hmdf->Instance))
1305     {
1306       assert_param(IS_ADF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
1307       assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
1308     }
1309     else
1310     {
1311       assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
1312     }
1313     if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE) &&
1314         ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
1315          (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
1316          (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
1317     {
1318       status = HAL_ERROR;
1319     }
1320     /* Check state */
1321     else if (hmdf->State != HAL_MDF_STATE_READY)
1322     {
1323       status = HAL_ERROR;
1324     }
1325     /* Check filter status */
1326     else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
1327     {
1328       status = HAL_ERROR;
1329     }
1330     else
1331     {
1332       /* For ADF instance, check SAD status */
1333       if (IS_ADF_INSTANCE(hmdf->Instance))
1334       {
1335         if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1336         {
1337           status = HAL_ERROR;
1338         }
1339       }
1340     }
1341 
1342     if (status == HAL_OK)
1343     {
1344       /* For MDF instance, check OLD status and main filter order */
1345       assert_param(IS_MDF_CIC_MODE(pFilterConfig->CicMode));
1346       if (IS_MDF_INSTANCE(hmdf->Instance))
1347       {
1348         if (((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != 0U) && (pFilterConfig->CicMode >= MDF_ONE_FILTER_SINC4))
1349         {
1350           status = HAL_ERROR;
1351         }
1352       }
1353 
1354       if (status == HAL_OK)
1355       {
1356         if (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SNAPSHOT)
1357         {
1358           /* Enable snapshot overrun and data ready interrupts */
1359           hmdf->Instance->DFLTIER |= (MDF_DFLTIER_SSOVRIE | MDF_DFLTIER_SSDRIE);
1360         }
1361         else
1362         {
1363           if ((IS_MDF_INSTANCE(hmdf->Instance)) || (pFilterConfig->SoundActivity.Activation == DISABLE) ||
1364               (pFilterConfig->SoundActivity.DataMemoryTransfer != MDF_SAD_NO_MEMORY_TRANSFER))
1365           {
1366             /* Enable data overflow and fifo threshold interrupts */
1367             hmdf->Instance->DFLTIER |= (MDF_DFLTIER_DOVRIE | MDF_DFLTIER_FTHIE);
1368           }
1369         }
1370 
1371         if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
1372         {
1373           /* Enable reshape filter overrun interrupt */
1374           hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE;
1375         }
1376 
1377         /* Enable saturation interrupt */
1378         hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE;
1379 
1380         if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE))
1381         {
1382           /* Enable sound level value ready and sound activity detection interrupts */
1383           assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt));
1384           hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ?
1385                                      (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) :
1386                                      MDF_DFLTIER_SDDETIE;
1387         }
1388 
1389         /* Configure filter and start acquisition */
1390         hmdf->Instance->DFLTCR = 0U;
1391         MDF_AcqStart(hmdf, pFilterConfig);
1392       }
1393     }
1394   }
1395 
1396   /* Return function status */
1397   return status;
1398 }
1399 
1400 /**
1401   * @brief  This function allows to stop acquisition in interrupt mode.
1402   * @param  hmdf MDF handle.
1403   * @retval HAL status.
1404   */
HAL_MDF_AcqStop_IT(MDF_HandleTypeDef * hmdf)1405 HAL_StatusTypeDef HAL_MDF_AcqStop_IT(MDF_HandleTypeDef *hmdf)
1406 {
1407   HAL_StatusTypeDef status = HAL_OK;
1408 
1409   /* Check state */
1410   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1411   {
1412     /* Check if state is ready and filter active */
1413     if (hmdf->State == HAL_MDF_STATE_READY)
1414     {
1415       if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
1416       {
1417         status = HAL_ERROR;
1418       }
1419     }
1420     else
1421     {
1422       status = HAL_ERROR;
1423     }
1424   }
1425   else
1426   {
1427     /* Disable sound activity detector if needed for ADF instance */
1428     if (IS_ADF_INSTANCE(hmdf->Instance))
1429     {
1430       if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1431       {
1432         hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
1433       }
1434     }
1435   }
1436 
1437   if (status == HAL_OK)
1438   {
1439     /* Disable filter */
1440     hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
1441 
1442     /* Disable interrupts and clear all potential pending flags */
1443     if (IS_ADF_INSTANCE(hmdf->Instance))
1444     {
1445       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_FTHIE | MDF_DFLTIER_DOVRIE | MDF_DFLTIER_SATIE |
1446                                    MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE | MDF_DFLTIER_SDLVLIE);
1447       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF |
1448                                   MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF);
1449     }
1450     else
1451     {
1452       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_FTHIE | MDF_DFLTIER_DOVRIE | MDF_DFLTIER_SSDRIE |
1453                                    MDF_DFLTIER_SSOVRIE | MDF_DFLTIER_SATIE | MDF_DFLTIER_RFOVRIE);
1454       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SSDRF | MDF_DFLTISR_SSOVRF |
1455                                   MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF);
1456     }
1457 
1458     /* Update state */
1459     hmdf->State = HAL_MDF_STATE_READY;
1460   }
1461 
1462   /* Return function status */
1463   return status;
1464 }
1465 
1466 /**
1467   * @brief  This function allows to start acquisition in DMA mode.
1468   * @param  hmdf MDF handle.
1469   * @param  pFilterConfig Filter configuration parameters.
1470   * @param  pDmaConfig DMA configuration parameters.
1471   * @retval HAL status.
1472   */
HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig,const MDF_DmaConfigTypeDef * pDmaConfig)1473 HAL_StatusTypeDef HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig,
1474                                        const MDF_DmaConfigTypeDef *pDmaConfig)
1475 {
1476   HAL_StatusTypeDef status = HAL_OK;
1477 
1478   /* Check parameters */
1479   if ((pFilterConfig == NULL) || (pDmaConfig == NULL))
1480   {
1481     status = HAL_ERROR;
1482   }
1483   else
1484   {
1485     assert_param(IS_FUNCTIONAL_STATE(pDmaConfig->MsbOnly));
1486     if (IS_ADF_INSTANCE(hmdf->Instance))
1487     {
1488       assert_param(IS_ADF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
1489       assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
1490     }
1491     else
1492     {
1493       assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
1494     }
1495     if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE) &&
1496         ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
1497          (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
1498          (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
1499     {
1500       status = HAL_ERROR;
1501     }
1502     else if (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SNAPSHOT)
1503     {
1504       status = HAL_ERROR;
1505     }
1506     /* Check state */
1507     else if (hmdf->State != HAL_MDF_STATE_READY)
1508     {
1509       status = HAL_ERROR;
1510     }
1511     /* Check filter status */
1512     else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
1513     {
1514       status = HAL_ERROR;
1515     }
1516     else
1517     {
1518       /* For ADF instance, check SAD status */
1519       if (IS_ADF_INSTANCE(hmdf->Instance))
1520       {
1521         if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1522         {
1523           status = HAL_ERROR;
1524         }
1525       }
1526     }
1527 
1528     if (status == HAL_OK)
1529     {
1530       /* For MDF instance, check OLD status and main filter order */
1531       assert_param(IS_MDF_CIC_MODE(pFilterConfig->CicMode));
1532       if (IS_MDF_INSTANCE(hmdf->Instance))
1533       {
1534         if (((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != 0U) && (pFilterConfig->CicMode >= MDF_ONE_FILTER_SINC4))
1535         {
1536           status = HAL_ERROR;
1537         }
1538       }
1539 
1540       if (status == HAL_OK)
1541       {
1542         uint32_t SrcAddress;
1543 
1544         if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
1545         {
1546           /* Enable reshape filter overrun interrupt */
1547           hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE;
1548         }
1549 
1550         /* Enable saturation interrupt */
1551         hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE;
1552 
1553         if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE))
1554         {
1555           /* Enable sound level value ready and sound activity detection interrupts */
1556           assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt));
1557           hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ?
1558                                      (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) :
1559                                      MDF_DFLTIER_SDDETIE;
1560         }
1561 
1562         /* Enable MDF DMA requests */
1563         hmdf->Instance->DFLTCR = MDF_DFLTCR_DMAEN;
1564 
1565         /* Start DMA transfer */
1566         hmdf->hdma->XferCpltCallback     = MDF_DmaXferCpltCallback;
1567         hmdf->hdma->XferHalfCpltCallback = MDF_DmaXferHalfCpltCallback;
1568         hmdf->hdma->XferErrorCallback    = MDF_DmaErrorCallback;
1569         SrcAddress = (pDmaConfig->MsbOnly == ENABLE) ? (((uint32_t) &hmdf->Instance->DFLTDR) + 2U) :
1570                      (uint32_t) &hmdf->Instance->DFLTDR;
1571         if ((hmdf->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1572         {
1573           if (hmdf->hdma->LinkedListQueue != NULL)
1574           {
1575             hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = pDmaConfig->DataLength;
1576             hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = SrcAddress;
1577             hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pDmaConfig->Address;
1578 
1579             status = HAL_DMAEx_List_Start_IT(hmdf->hdma);
1580           }
1581           else
1582           {
1583             status = HAL_ERROR;
1584           }
1585         }
1586         else
1587         {
1588           status = HAL_DMA_Start_IT(hmdf->hdma, SrcAddress, pDmaConfig->Address, pDmaConfig->DataLength);
1589         }
1590         if (status != HAL_OK)
1591         {
1592           /* Update state */
1593           hmdf->State = HAL_MDF_STATE_ERROR;
1594           status = HAL_ERROR;
1595         }
1596         else
1597         {
1598           /* Configure filter and start acquisition */
1599           MDF_AcqStart(hmdf, pFilterConfig);
1600         }
1601       }
1602     }
1603   }
1604 
1605   /* Return function status */
1606   return status;
1607 }
1608 
1609 /**
1610   * @brief  This function allows to stop acquisition in DMA mode.
1611   * @param  hmdf MDF handle.
1612   * @retval HAL status.
1613   */
HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef * hmdf)1614 HAL_StatusTypeDef HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef *hmdf)
1615 {
1616   HAL_StatusTypeDef status = HAL_OK;
1617 
1618   /* Check if state is ready and filter active */
1619   if (hmdf->State == HAL_MDF_STATE_READY)
1620   {
1621     if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
1622     {
1623       status = HAL_ERROR;
1624     }
1625   }
1626   else
1627   {
1628     /* Check state */
1629     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1630     {
1631       status = HAL_ERROR;
1632     }
1633     else
1634     {
1635       /* Stop the DMA transfer */
1636       if (HAL_DMA_Abort(hmdf->hdma) != HAL_OK)
1637       {
1638         /* Update state */
1639         hmdf->State = HAL_MDF_STATE_ERROR;
1640         status = HAL_ERROR;
1641       }
1642     }
1643   }
1644 
1645   if (status == HAL_OK)
1646   {
1647     /* Disable sound activity detector if needed for ADF instance */
1648     if (IS_ADF_INSTANCE(hmdf->Instance))
1649     {
1650       if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1651       {
1652         hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
1653       }
1654     }
1655 
1656     /* Disable filter */
1657     hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
1658 
1659     /* Disable interrupts and clear all potential pending flags */
1660     if (IS_ADF_INSTANCE(hmdf->Instance))
1661     {
1662       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_SATIE | MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE |
1663                                    MDF_DFLTIER_SDLVLIE);
1664       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF | MDF_DFLTISR_SDDETF |
1665                                   MDF_DFLTISR_SDLVLF);
1666     }
1667     else
1668     {
1669       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_SATIE | MDF_DFLTIER_RFOVRIE);
1670       hmdf->Instance->DFLTISR |= (MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF);
1671     }
1672 
1673     /* Disable MDF DMA requests */
1674     hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DMAEN);
1675 
1676     /* Update state */
1677     hmdf->State = HAL_MDF_STATE_READY;
1678   }
1679 
1680   /* Return function status */
1681   return status;
1682 }
1683 
1684 /**
1685   * @brief  This function allows to generate pulse on TRGO signal.
1686   * @param  hmdf MDF handle.
1687   * @retval HAL status.
1688   */
HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef * hmdf)1689 HAL_StatusTypeDef HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef *hmdf)
1690 {
1691   HAL_StatusTypeDef status = HAL_OK;
1692 
1693   /* Check state */
1694   if (hmdf->State != HAL_MDF_STATE_READY)
1695   {
1696     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1697     {
1698       status = HAL_ERROR;
1699     }
1700   }
1701 
1702   if (status == HAL_OK)
1703   {
1704     MDF_TypeDef *p_mdf_base;
1705 
1706     /* Get MDF base according instance */
1707     p_mdf_base = (IS_ADF_INSTANCE(hmdf->Instance)) ? ADF1 : MDF1;
1708 
1709     /* Check if trigger output control is already active */
1710     if ((p_mdf_base->GCR & MDF_GCR_TRGO) == MDF_GCR_TRGO)
1711     {
1712       status = HAL_ERROR;
1713     }
1714     else
1715     {
1716       /* Generate pulse on trigger output control signal */
1717       p_mdf_base->GCR |= MDF_GCR_TRGO;
1718     }
1719   }
1720 
1721   /* Return function status */
1722   return status;
1723 }
1724 
1725 /**
1726   * @brief  This function allows to set delay to apply on data source in number of samples.
1727   * @param  hmdf MDF handle.
1728   * @param  Delay Delay to apply on data source in number of samples.
1729   *         This parameter must be a number between Min_Data = 0 and Max_Data = 127.
1730   * @retval HAL status.
1731   */
HAL_MDF_SetDelay(MDF_HandleTypeDef * hmdf,uint32_t Delay)1732 HAL_StatusTypeDef HAL_MDF_SetDelay(MDF_HandleTypeDef *hmdf, uint32_t Delay)
1733 {
1734   HAL_StatusTypeDef status = HAL_OK;
1735 
1736   /* Check parameters */
1737   assert_param(IS_MDF_DELAY(Delay));
1738 
1739   /* Check state */
1740   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1741   {
1742     status = HAL_ERROR;
1743   }
1744   else
1745   {
1746     /* Check if bitstream delay is already active */
1747     if ((hmdf->Instance->DLYCR & MDF_DLYCR_SKPBF) == MDF_DLYCR_SKPBF)
1748     {
1749       status = HAL_ERROR;
1750     }
1751     else
1752     {
1753       /* Configure bitstream delay */
1754       hmdf->Instance->DLYCR |= Delay;
1755     }
1756   }
1757 
1758   /* Return function status */
1759   return status;
1760 }
1761 
1762 /**
1763   * @brief  This function allows to get current delay applied on data source in number of samples.
1764   * @param  hmdf MDF handle.
1765   * @param  pDelay Current delay applied on data source in number of samples.
1766   *         This value is between Min_Data = 0 and Max_Data = 127.
1767   * @retval HAL status.
1768   */
HAL_MDF_GetDelay(const MDF_HandleTypeDef * hmdf,uint32_t * pDelay)1769 HAL_StatusTypeDef HAL_MDF_GetDelay(const MDF_HandleTypeDef *hmdf, uint32_t *pDelay)
1770 {
1771   HAL_StatusTypeDef status = HAL_OK;
1772 
1773   /* Check parameters */
1774   if (pDelay == NULL)
1775   {
1776     status = HAL_ERROR;
1777   }
1778   /* Check state */
1779   else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1780   {
1781     status = HAL_ERROR;
1782   }
1783   else
1784   {
1785     /* Get current bitstream delay */
1786     *pDelay = (hmdf->Instance->DLYCR & MDF_DLYCR_SKPDLY);
1787   }
1788 
1789   /* Return function status */
1790   return status;
1791 }
1792 
1793 /**
1794   * @brief  This function allows to set filter gain.
1795   * @param  hmdf MDF handle.
1796   * @param  Gain Filter gain in step of around 3db (from -48db to 72dB).
1797   *         This parameter must be a number between Min_Data = -16 and Max_Data = 24.
1798   * @retval HAL status.
1799   */
HAL_MDF_SetGain(MDF_HandleTypeDef * hmdf,int32_t Gain)1800 HAL_StatusTypeDef HAL_MDF_SetGain(MDF_HandleTypeDef *hmdf, int32_t Gain)
1801 {
1802   HAL_StatusTypeDef status = HAL_OK;
1803 
1804   /* Check parameters */
1805   assert_param(IS_MDF_GAIN(Gain));
1806 
1807   /* Check state */
1808   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1809   {
1810     status = HAL_ERROR;
1811   }
1812   else
1813   {
1814     uint32_t register_gain_value;
1815     uint32_t tmp_register;
1816 
1817     if (Gain < 0)
1818     {
1819       int32_t adjust_gain;
1820 
1821       /* adjust gain value to set on register for negative value (offset of -16) */
1822       adjust_gain = Gain - 16;
1823       register_gain_value = ((uint32_t) adjust_gain & 0x3FU);
1824     }
1825     else
1826     {
1827       /* for positive value, no offset to apply */
1828       register_gain_value = (uint32_t) Gain;
1829     }
1830     /* Set gain */
1831     tmp_register = (hmdf->Instance->DFLTCICR & ~(MDF_DFLTCICR_SCALE));
1832     hmdf->Instance->DFLTCICR = (tmp_register | (register_gain_value << MDF_DFLTCICR_SCALE_Pos));
1833   }
1834 
1835   /* Return function status */
1836   return status;
1837 }
1838 
1839 /**
1840   * @brief  This function allows to get filter gain.
1841   * @param  hmdf MDF handle.
1842   * @param  pGain Filter gain in step of around 3db (from -48db to 72dB).
1843   *         This parameter is between Min_Data = -16 and Max_Data = 24.
1844   * @retval HAL status.
1845   */
HAL_MDF_GetGain(const MDF_HandleTypeDef * hmdf,int32_t * pGain)1846 HAL_StatusTypeDef HAL_MDF_GetGain(const MDF_HandleTypeDef *hmdf, int32_t *pGain)
1847 {
1848   HAL_StatusTypeDef status = HAL_OK;
1849 
1850   /* Check parameters */
1851   if (pGain == NULL)
1852   {
1853     status = HAL_ERROR;
1854   }
1855   /* Check state */
1856   else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1857   {
1858     status = HAL_ERROR;
1859   }
1860   else
1861   {
1862     uint32_t register_gain_value;
1863 
1864     /* Get current gain */
1865     register_gain_value = ((hmdf->Instance->DFLTCICR & MDF_DFLTCICR_SCALE) >> MDF_DFLTCICR_SCALE_Pos);
1866     if (register_gain_value > 31U)
1867     {
1868       /* adjust gain value to set on register for negative value (offset of +16) */
1869       register_gain_value |= 0xFFFFFFC0U;
1870       *pGain = (int32_t) register_gain_value + 16;
1871     }
1872     else
1873     {
1874       /* for positive value, no offset to apply */
1875       *pGain = (int32_t) register_gain_value;
1876     }
1877   }
1878 
1879   /* Return function status */
1880   return status;
1881 }
1882 
1883 /**
1884   * @brief  This function allows to set filter offset error compensation.
1885   * @param  hmdf MDF handle.
1886   * @param  Offset Filter offset error compensation.
1887   *         This parameter must be a number between Min_Data = -33554432 and Max_Data = 33554431.
1888   * @retval HAL status.
1889   * @note   This function must not be used with ADF instance.
1890   */
HAL_MDF_SetOffset(MDF_HandleTypeDef * hmdf,int32_t Offset)1891 HAL_StatusTypeDef HAL_MDF_SetOffset(MDF_HandleTypeDef *hmdf, int32_t Offset)
1892 {
1893   HAL_StatusTypeDef status = HAL_OK;
1894 
1895   /* Check parameters */
1896   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
1897   assert_param(IS_MDF_OFFSET(Offset));
1898 
1899   /* Check state */
1900   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1901   {
1902     status = HAL_ERROR;
1903   }
1904   else
1905   {
1906     /* Set offset */
1907     hmdf->Instance->OECCR = (uint32_t) Offset;
1908   }
1909 
1910   /* Return function status */
1911   return status;
1912 }
1913 
1914 /**
1915   * @brief  This function allows to get filter offset error compensation.
1916   * @param  hmdf MDF handle.
1917   * @param  pOffset Filter offset error compensation.
1918   *         This value is between Min_Data = -33554432 and Max_Data = 33554431.
1919   * @retval HAL status.
1920   * @note   This function must not be used with ADF instance.
1921   */
HAL_MDF_GetOffset(const MDF_HandleTypeDef * hmdf,int32_t * pOffset)1922 HAL_StatusTypeDef HAL_MDF_GetOffset(const MDF_HandleTypeDef *hmdf, int32_t *pOffset)
1923 {
1924   HAL_StatusTypeDef status = HAL_OK;
1925 
1926   /* Check parameters */
1927   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
1928   if (pOffset == NULL)
1929   {
1930     status = HAL_ERROR;
1931   }
1932   /* Check state */
1933   else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1934   {
1935     status = HAL_ERROR;
1936   }
1937   else
1938   {
1939     uint32_t register_offset_value;
1940 
1941     /* Get current offset */
1942     register_offset_value = hmdf->Instance->OECCR;
1943     if (register_offset_value > 33554431U)
1944     {
1945       /* Negative value */
1946       register_offset_value |= 0xFC000000U;
1947       *pOffset = (int32_t) register_offset_value;
1948     }
1949     else
1950     {
1951       /* Positive value */
1952       *pOffset = (int32_t) register_offset_value;
1953     }
1954   }
1955 
1956   /* Return function status */
1957   return status;
1958 }
1959 
1960 /**
1961   * @brief  This function allows to poll for sound level data.
1962   * @param  hmdf MDF handle.
1963   * @param  Timeout Timeout value in milliseconds.
1964   * @param  pSoundLevel Sound level.
1965             This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1966   * @param  pAmbientNoise Ambient noise.
1967             This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1968   * @retval HAL status.
1969   * @note   This function must not be used with MDF instance.
1970   */
HAL_MDF_PollForSndLvl(MDF_HandleTypeDef * hmdf,uint32_t Timeout,uint32_t * pSoundLevel,uint32_t * pAmbientNoise)1971 HAL_StatusTypeDef HAL_MDF_PollForSndLvl(MDF_HandleTypeDef *hmdf, uint32_t Timeout, uint32_t *pSoundLevel,
1972                                         uint32_t *pAmbientNoise)
1973 {
1974   HAL_StatusTypeDef status = HAL_OK;
1975 
1976   /* Check parameters */
1977   assert_param(IS_ADF_INSTANCE(hmdf->Instance));
1978   if ((pSoundLevel == NULL) || (pAmbientNoise == NULL))
1979   {
1980     status = HAL_ERROR;
1981   }
1982   /* Check state */
1983   else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1984   {
1985     status = HAL_ERROR;
1986   }
1987   /* Check SAD status */
1988   else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U)
1989   {
1990     status = HAL_ERROR;
1991   }
1992   else
1993   {
1994     uint32_t tickstart = HAL_GetTick();
1995 
1996     /* Wait for available sound level data */
1997     while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDLVLF) != MDF_DFLTISR_SDLVLF) && (status == HAL_OK))
1998     {
1999       /* Check the timeout */
2000       if (Timeout != HAL_MAX_DELAY)
2001       {
2002         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2003         {
2004           status = HAL_TIMEOUT;
2005         }
2006       }
2007     }
2008 
2009     if (status == HAL_OK)
2010     {
2011       /* Get sound level */
2012       *pSoundLevel = hmdf->Instance->SADSDLVR;
2013 
2014       /* Get ambient noise */
2015       *pAmbientNoise = hmdf->Instance->SADANLVR;
2016 
2017       /* Clear sound level ready flag */
2018       hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF;
2019     }
2020   }
2021 
2022   /* Return function status */
2023   return status;
2024 }
2025 
2026 /**
2027   * @brief  This function allows to poll for sound activity detection.
2028   * @param  hmdf MDF handle.
2029   * @param  Timeout Timeout value in milliseconds.
2030   * @retval HAL status.
2031   * @note   This function must not be used with MDF instance.
2032   */
HAL_MDF_PollForSad(MDF_HandleTypeDef * hmdf,uint32_t Timeout)2033 HAL_StatusTypeDef HAL_MDF_PollForSad(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
2034 {
2035   HAL_StatusTypeDef status = HAL_OK;
2036 
2037   /* Check parameters */
2038   assert_param(IS_ADF_INSTANCE(hmdf->Instance));
2039 
2040   /* Check state */
2041   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2042   {
2043     status = HAL_ERROR;
2044   }
2045   /* Check SAD status */
2046   else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U)
2047   {
2048     status = HAL_ERROR;
2049   }
2050   else
2051   {
2052     uint32_t tickstart = HAL_GetTick();
2053 
2054     /* Wait for sound activity detection */
2055     while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDDETF) != MDF_DFLTISR_SDDETF) && (status == HAL_OK))
2056     {
2057       /* Check the timeout */
2058       if (Timeout != HAL_MAX_DELAY)
2059       {
2060         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2061         {
2062           status = HAL_TIMEOUT;
2063         }
2064       }
2065     }
2066 
2067     if (status == HAL_OK)
2068     {
2069       /* Clear sound activity detection flag */
2070       hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF;
2071     }
2072   }
2073 
2074   /* Return function status */
2075   return status;
2076 }
2077 
2078 /**
2079   * @brief  MDF acquisition complete callback.
2080   * @param  hmdf MDF handle.
2081   * @retval None.
2082   */
HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef * hmdf)2083 __weak void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf)
2084 {
2085   /* Prevent unused argument(s) compilation warning */
2086   UNUSED(hmdf);
2087 
2088   /* NOTE : This function should not be modified, when the function is needed,
2089             the HAL_MDF_AcqCpltCallback could be implemented in the user file */
2090 }
2091 
2092 /**
2093   * @brief  MDF acquisition half complete callback.
2094   * @param  hmdf MDF handle.
2095   * @retval None.
2096   */
HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef * hmdf)2097 __weak void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf)
2098 {
2099   /* Prevent unused argument(s) compilation warning */
2100   UNUSED(hmdf);
2101 
2102   /* NOTE : This function should not be modified, when the function is needed,
2103             the HAL_MDF_AcqHalfCpltCallback could be implemented in the user file */
2104 }
2105 
2106 /**
2107   * @brief  MDF sound level callback.
2108   * @param  hmdf MDF handle.
2109   * @param  SoundLevel Sound level value computed by sound activity detector.
2110   *         This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
2111   * @param  AmbientNoise Ambient noise value computed by sound activity detector.
2112   *         This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
2113   * @retval None.
2114   */
HAL_MDF_SndLvlCallback(MDF_HandleTypeDef * hmdf,uint32_t SoundLevel,uint32_t AmbientNoise)2115 __weak void HAL_MDF_SndLvlCallback(MDF_HandleTypeDef *hmdf, uint32_t SoundLevel, uint32_t AmbientNoise)
2116 {
2117   /* Prevent unused argument(s) compilation warning */
2118   UNUSED(hmdf);
2119   UNUSED(SoundLevel);
2120   UNUSED(AmbientNoise);
2121 
2122   /* NOTE : This function should not be modified, when the function is needed,
2123             the HAL_MDF_SndLvlCallback could be implemented in the user file */
2124 }
2125 
2126 /**
2127   * @brief  MDF sound activity detector callback.
2128   * @param  hmdf MDF handle.
2129   * @retval None.
2130   */
HAL_MDF_SadCallback(MDF_HandleTypeDef * hmdf)2131 __weak void HAL_MDF_SadCallback(MDF_HandleTypeDef *hmdf)
2132 {
2133   /* Prevent unused argument(s) compilation warning */
2134   UNUSED(hmdf);
2135 
2136   /* NOTE : This function should not be modified, when the function is needed,
2137             the HAL_MDF_SadCallback could be implemented in the user file */
2138 }
2139 
2140 /**
2141   * @}
2142   */
2143 
2144 /** @defgroup MDF_Exported_Functions_Group3  Clock absence detection functions
2145   * @brief    Clock absence detection functions
2146   *
2147 @verbatim
2148   ==============================================================================
2149                   ##### Clock absence detection functions #####
2150   ==============================================================================
2151     [..]  This section provides functions allowing to :
2152       (+) Start and stop clock absence detection in interrupt mode.
2153       (+) Detect clock absence.
2154 @endverbatim
2155   * @{
2156   */
2157 
2158 /**
2159   * @brief  This function allows to poll for the clock absence detection.
2160   * @param  hmdf MDF handle.
2161   * @param  Timeout Timeout value in milliseconds.
2162   * @retval HAL status.
2163   */
HAL_MDF_PollForCkab(MDF_HandleTypeDef * hmdf,uint32_t Timeout)2164 HAL_StatusTypeDef HAL_MDF_PollForCkab(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
2165 {
2166   HAL_StatusTypeDef status = HAL_OK;
2167 
2168   /* Check state */
2169   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2170   {
2171     if (hmdf->State != HAL_MDF_STATE_READY)
2172     {
2173       status = HAL_ERROR;
2174     }
2175   }
2176 
2177   if (status == HAL_OK)
2178   {
2179     /* Check serial interface status and mode */
2180     if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
2181     {
2182       status = HAL_ERROR;
2183     }
2184     else
2185     {
2186       if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
2187       {
2188         status = HAL_ERROR;
2189       }
2190     }
2191   }
2192 
2193   if (status == HAL_OK)
2194   {
2195     uint32_t tickstart = HAL_GetTick();
2196 
2197     /* Wait for clock absence detection */
2198     while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) != MDF_DFLTISR_CKABF) && (status == HAL_OK))
2199     {
2200       /* Check the timeout */
2201       if (Timeout != HAL_MAX_DELAY)
2202       {
2203         if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2204         {
2205           status = HAL_TIMEOUT;
2206         }
2207       }
2208     }
2209 
2210     if (status == HAL_OK)
2211     {
2212       /* Clear clock absence detection flag */
2213       hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
2214     }
2215   }
2216 
2217   /* Return function status */
2218   return status;
2219 }
2220 
2221 /**
2222   * @brief  This function allows to start clock absence detection in interrupt mode.
2223   * @param  hmdf MDF handle.
2224   * @retval HAL status.
2225   */
HAL_MDF_CkabStart_IT(MDF_HandleTypeDef * hmdf)2226 HAL_StatusTypeDef HAL_MDF_CkabStart_IT(MDF_HandleTypeDef *hmdf)
2227 {
2228   HAL_StatusTypeDef status = HAL_OK;
2229 
2230   /* Check state */
2231   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2232   {
2233     if (hmdf->State != HAL_MDF_STATE_READY)
2234     {
2235       status = HAL_ERROR;
2236     }
2237   }
2238 
2239   if (status == HAL_OK)
2240   {
2241     /* Check serial interface status and mode */
2242     if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
2243     {
2244       status = HAL_ERROR;
2245     }
2246     else
2247     {
2248       if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
2249       {
2250         status = HAL_ERROR;
2251       }
2252     }
2253   }
2254 
2255   if (status == HAL_OK)
2256   {
2257     /* Clear clock absence detection flag */
2258     hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
2259 
2260     /* Check clock absence detection flag */
2261     if ((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF)
2262     {
2263       status = HAL_ERROR;
2264     }
2265     else
2266     {
2267       /* Enable clock absence detection interrupt */
2268       hmdf->Instance->DFLTIER |= MDF_DFLTIER_CKABIE;
2269     }
2270   }
2271 
2272   /* Return function status */
2273   return status;
2274 }
2275 
2276 /**
2277   * @brief  This function allows to stop clock absence detection in interrupt mode.
2278   * @param  hmdf MDF handle.
2279   * @retval HAL status.
2280   */
HAL_MDF_CkabStop_IT(MDF_HandleTypeDef * hmdf)2281 HAL_StatusTypeDef HAL_MDF_CkabStop_IT(MDF_HandleTypeDef *hmdf)
2282 {
2283   HAL_StatusTypeDef status = HAL_OK;
2284 
2285   /* Check state */
2286   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2287   {
2288     if (hmdf->State != HAL_MDF_STATE_READY)
2289     {
2290       status = HAL_ERROR;
2291     }
2292   }
2293 
2294   if (status == HAL_OK)
2295   {
2296     /* Check serial interface status and mode */
2297     if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
2298     {
2299       status = HAL_ERROR;
2300     }
2301     else
2302     {
2303       if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
2304       {
2305         status = HAL_ERROR;
2306       }
2307     }
2308   }
2309 
2310   if (status == HAL_OK)
2311   {
2312     /* Disable clock absence detection interrupt */
2313     hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_CKABIE);
2314 
2315     /* Clear potential pending clock absence detection flag */
2316     hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
2317   }
2318 
2319   /* Return function status */
2320   return status;
2321 }
2322 
2323 /**
2324   * @}
2325   */
2326 
2327 /** @defgroup MDF_Exported_Functions_Group4  Short circuit detection functions
2328   * @brief    Short circuit detection functions
2329   *
2330 @verbatim
2331   ==============================================================================
2332                   ##### Short circuit detection functions #####
2333   ==============================================================================
2334     [..]  This section provides functions available only for MDF instance
2335           allowing to :
2336       (+) Start and stop short circuit detection in polling and interrupt mode.
2337       (+) Detect short circuit.
2338 @endverbatim
2339   * @{
2340   */
2341 
2342 /**
2343   * @brief  This function allows to start short-circuit detection in polling mode.
2344   * @param  hmdf MDF handle.
2345   * @param  pScdConfig Short-circuit detector configuration parameters.
2346   * @retval HAL status.
2347   * @note   This function must not be used with ADF instance.
2348   */
HAL_MDF_ScdStart(MDF_HandleTypeDef * hmdf,const MDF_ScdConfigTypeDef * pScdConfig)2349 HAL_StatusTypeDef HAL_MDF_ScdStart(MDF_HandleTypeDef *hmdf, const MDF_ScdConfigTypeDef *pScdConfig)
2350 {
2351   HAL_StatusTypeDef status = HAL_OK;
2352 
2353   /* Check parameters */
2354   if (pScdConfig == NULL)
2355   {
2356     status = HAL_ERROR;
2357   }
2358   else
2359   {
2360     assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2361     assert_param(IS_MDF_SCD_THRESHOLD(pScdConfig->Threshold));
2362     assert_param(IS_MDF_BREAK_SIGNAL(pScdConfig->BreakSignal));
2363 
2364     /* Check state */
2365     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2366     {
2367       if (hmdf->State != HAL_MDF_STATE_READY)
2368       {
2369         status = HAL_ERROR;
2370       }
2371     }
2372 
2373     if (status == HAL_OK)
2374     {
2375       /* Check short-circuit detector status */
2376       if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) == MDF_SCDCR_SCDACTIVE)
2377       {
2378         status = HAL_ERROR;
2379       }
2380       else
2381       {
2382         /* Configure threshold and break signal */
2383         hmdf->Instance->SCDCR = (((pScdConfig->Threshold - 1U) << MDF_SCDCR_SCDT_Pos) |
2384                                  (pScdConfig->BreakSignal << MDF_SCDCR_BKSCD_Pos));
2385 
2386         /* Enable short-circuit detector */
2387         hmdf->Instance->SCDCR |= MDF_SCDCR_SCDEN;
2388       }
2389     }
2390   }
2391 
2392   /* Return function status */
2393   return status;
2394 }
2395 
2396 /**
2397   * @brief  This function allows to poll for the short-circuit detection.
2398   * @param  hmdf MDF handle.
2399   * @param  Timeout Timeout value in milliseconds.
2400   * @retval HAL status.
2401   * @note   This function must not be used with ADF instance.
2402   */
HAL_MDF_PollForScd(MDF_HandleTypeDef * hmdf,uint32_t Timeout)2403 HAL_StatusTypeDef HAL_MDF_PollForScd(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
2404 {
2405   HAL_StatusTypeDef status = HAL_OK;
2406 
2407   /* Check parameters */
2408   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2409 
2410   /* Check state */
2411   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2412   {
2413     if (hmdf->State != HAL_MDF_STATE_READY)
2414     {
2415       status = HAL_ERROR;
2416     }
2417   }
2418 
2419   if (status == HAL_OK)
2420   {
2421     /* Check short-circuit detector status */
2422     if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) != MDF_SCDCR_SCDACTIVE)
2423     {
2424       status = HAL_ERROR;
2425     }
2426     else
2427     {
2428       uint32_t tickstart = HAL_GetTick();
2429 
2430       /* Wait for short-circuit detection */
2431       while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SCDF) != MDF_DFLTISR_SCDF) && (status == HAL_OK))
2432       {
2433         /* Check the timeout */
2434         if (Timeout != HAL_MAX_DELAY)
2435         {
2436           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2437           {
2438             status = HAL_TIMEOUT;
2439           }
2440         }
2441       }
2442 
2443       if (status == HAL_OK)
2444       {
2445         /* Clear short-circuit detection flag */
2446         hmdf->Instance->DFLTISR |= MDF_DFLTISR_SCDF;
2447       }
2448     }
2449   }
2450 
2451   /* Return function status */
2452   return status;
2453 }
2454 
2455 /**
2456   * @brief  This function allows to stop short-circuit detection in polling mode.
2457   * @param  hmdf MDF handle.
2458   * @retval HAL status.
2459   * @note   This function must not be used with ADF instance.
2460   */
HAL_MDF_ScdStop(MDF_HandleTypeDef * hmdf)2461 HAL_StatusTypeDef HAL_MDF_ScdStop(MDF_HandleTypeDef *hmdf)
2462 {
2463   HAL_StatusTypeDef status = HAL_OK;
2464 
2465   /* Check parameters */
2466   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2467 
2468   /* Check state */
2469   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2470   {
2471     if (hmdf->State != HAL_MDF_STATE_READY)
2472     {
2473       status = HAL_ERROR;
2474     }
2475   }
2476 
2477   if (status == HAL_OK)
2478   {
2479     /* Check short-circuit detector status */
2480     if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) != MDF_SCDCR_SCDACTIVE)
2481     {
2482       status = HAL_ERROR;
2483     }
2484     else
2485     {
2486       /* Disable short-circuit detection */
2487       hmdf->Instance->SCDCR &= ~(MDF_SCDCR_SCDEN);
2488 
2489       /* Clear potential pending short-circuit detection flag */
2490       hmdf->Instance->DFLTISR |= MDF_DFLTISR_SCDF;
2491     }
2492   }
2493 
2494   /* Return function status */
2495   return status;
2496 }
2497 
2498 /**
2499   * @brief  This function allows to start short-circuit detection in interrupt mode.
2500   * @param  hmdf MDF handle.
2501   * @param  pScdConfig Short-circuit detector configuration parameters.
2502   * @retval HAL status.
2503   * @note   This function must not be used with ADF instance.
2504   */
HAL_MDF_ScdStart_IT(MDF_HandleTypeDef * hmdf,const MDF_ScdConfigTypeDef * pScdConfig)2505 HAL_StatusTypeDef HAL_MDF_ScdStart_IT(MDF_HandleTypeDef *hmdf, const MDF_ScdConfigTypeDef *pScdConfig)
2506 {
2507   HAL_StatusTypeDef status = HAL_OK;
2508 
2509   /* Check parameters */
2510   if (pScdConfig == NULL)
2511   {
2512     status = HAL_ERROR;
2513   }
2514   else
2515   {
2516     assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2517     assert_param(IS_MDF_SCD_THRESHOLD(pScdConfig->Threshold));
2518     assert_param(IS_MDF_BREAK_SIGNAL(pScdConfig->BreakSignal));
2519 
2520     /* Check state */
2521     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2522     {
2523       if (hmdf->State != HAL_MDF_STATE_READY)
2524       {
2525         status = HAL_ERROR;
2526       }
2527     }
2528 
2529     if (status == HAL_OK)
2530     {
2531       /* Check short-circuit detector status */
2532       if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) == MDF_SCDCR_SCDACTIVE)
2533       {
2534         status = HAL_ERROR;
2535       }
2536       else
2537       {
2538         /* Configure threshold and break signal */
2539         hmdf->Instance->SCDCR = (((pScdConfig->Threshold - 1U) << MDF_SCDCR_SCDT_Pos) |
2540                                  (pScdConfig->BreakSignal << MDF_SCDCR_BKSCD_Pos));
2541 
2542         /* Enable short-circuit detector interrupt */
2543         hmdf->Instance->DFLTIER |= MDF_DFLTIER_SCDIE;
2544 
2545         /* Enable short-circuit detector */
2546         hmdf->Instance->SCDCR |= MDF_SCDCR_SCDEN;
2547       }
2548     }
2549   }
2550 
2551   /* Return function status */
2552   return status;
2553 }
2554 
2555 /**
2556   * @brief  This function allows to stop short-circuit detection in interrupt mode.
2557   * @param  hmdf MDF handle.
2558   * @retval HAL status.
2559   * @note   This function must not be used with ADF instance.
2560   */
HAL_MDF_ScdStop_IT(MDF_HandleTypeDef * hmdf)2561 HAL_StatusTypeDef HAL_MDF_ScdStop_IT(MDF_HandleTypeDef *hmdf)
2562 {
2563   HAL_StatusTypeDef status = HAL_OK;
2564 
2565   /* Check parameters */
2566   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2567 
2568   /* Check state */
2569   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2570   {
2571     if (hmdf->State != HAL_MDF_STATE_READY)
2572     {
2573       status = HAL_ERROR;
2574     }
2575   }
2576 
2577   if (status == HAL_OK)
2578   {
2579     /* Check short-circuit detector status */
2580     if ((hmdf->Instance->SCDCR & MDF_SCDCR_SCDACTIVE) != MDF_SCDCR_SCDACTIVE)
2581     {
2582       status = HAL_ERROR;
2583     }
2584     else
2585     {
2586       /* Disable short-circuit detection */
2587       hmdf->Instance->SCDCR &= ~(MDF_SCDCR_SCDEN);
2588 
2589       /* Disable short-circuit detection interrupt */
2590       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_SCDIE);
2591 
2592       /* Clear potential pending short-circuit detection flag */
2593       hmdf->Instance->DFLTISR |= MDF_DFLTISR_SCDF;
2594     }
2595   }
2596 
2597   /* Return function status */
2598   return status;
2599 }
2600 
2601 /**
2602   * @}
2603   */
2604 
2605 /** @defgroup MDF_Exported_Functions_Group5  Out-off limit detection functions
2606   * @brief    Out-off limit detection functions
2607   *
2608 @verbatim
2609   ==============================================================================
2610                   ##### Out-off limit detection functions #####
2611   ==============================================================================
2612     [..]  This section provides functions available only for MDF instance
2613           allowing to :
2614       (+) Start and stop out-off limit detection in polling and interrupt mode.
2615       (+) Detect short circuit and get threshold information.
2616 @endverbatim
2617   * @{
2618   */
2619 
2620 /**
2621   * @brief  This function allows to start out-off limit detection in polling mode.
2622   * @param  hmdf MDF handle.
2623   * @param  pOldConfig Out-off limit detector configuration parameters.
2624   * @retval HAL status.
2625   * @note   This function must not be used with ADF instance.
2626   */
HAL_MDF_OldStart(MDF_HandleTypeDef * hmdf,const MDF_OldConfigTypeDef * pOldConfig)2627 HAL_StatusTypeDef HAL_MDF_OldStart(MDF_HandleTypeDef *hmdf, const MDF_OldConfigTypeDef *pOldConfig)
2628 {
2629   HAL_StatusTypeDef status = HAL_OK;
2630 
2631   /* Check parameters */
2632   if (pOldConfig == NULL)
2633   {
2634     status = HAL_ERROR;
2635   }
2636   else
2637   {
2638     assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2639     assert_param(IS_MDF_OLD_CIC_MODE(pOldConfig->OldCicMode));
2640     assert_param(IS_MDF_OLD_DECIMATION_RATIO(pOldConfig->OldDecimationRatio));
2641     assert_param(IS_MDF_OLD_THRESHOLD(pOldConfig->HighThreshold));
2642     assert_param(IS_MDF_OLD_THRESHOLD(pOldConfig->LowThreshold));
2643     assert_param(IS_MDF_OLD_EVENT_CONFIG(pOldConfig->OldEventConfig));
2644     assert_param(IS_MDF_BREAK_SIGNAL(pOldConfig->BreakSignal));
2645     if (pOldConfig->LowThreshold >= pOldConfig->HighThreshold)
2646     {
2647       status = HAL_ERROR;
2648     }
2649     else
2650     {
2651       /* Check state */
2652       if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2653       {
2654         if (hmdf->State != HAL_MDF_STATE_READY)
2655         {
2656           status = HAL_ERROR;
2657         }
2658       }
2659     }
2660 
2661     if (status == HAL_OK)
2662     {
2663       /* Check out-off limit detector status */
2664       if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) == MDF_OLDCR_OLDACTIVE)
2665       {
2666         status = HAL_ERROR;
2667       }
2668       else
2669       {
2670         /* Check filter status */
2671         if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) == MDF_DFLTCR_DFLTACTIVE)
2672         {
2673           /* Check main filter order */
2674           if ((hmdf->Instance->DFLTCICR & MDF_DFLTCICR_CICMOD) >= MDF_ONE_FILTER_SINC4)
2675           {
2676             status = HAL_ERROR;
2677           }
2678         }
2679         else
2680         {
2681           /* Reset main filter order */
2682           hmdf->Instance->DFLTCICR &= ~(MDF_DFLTCICR_CICMOD);
2683         }
2684 
2685         if (status == HAL_OK)
2686         {
2687           /* Configure OLD CIC mode, decimation ratio, event and break signal */
2688           hmdf->Instance->OLDCR = (pOldConfig->OldCicMode | pOldConfig->OldEventConfig |
2689                                    ((pOldConfig->OldDecimationRatio - 1U) << MDF_OLDCR_ACICD_Pos) |
2690                                    (pOldConfig->BreakSignal << MDF_OLDCR_BKOLD_Pos));
2691 
2692           /* Configure low and high thresholds */
2693           hmdf->Instance->OLDTHLR = (uint32_t) pOldConfig->LowThreshold;
2694           hmdf->Instance->OLDTHHR = (uint32_t) pOldConfig->HighThreshold;
2695 
2696           /* Enable out-off limit detector */
2697           hmdf->Instance->OLDCR |= MDF_OLDCR_OLDEN;
2698         }
2699       }
2700     }
2701   }
2702 
2703   /* Return function status */
2704   return status;
2705 }
2706 
2707 /**
2708   * @brief  This function allows to poll for the out-off limit detection.
2709   * @param  hmdf MDF handle.
2710   * @param  Timeout Timeout value in milliseconds.
2711   * @param  pThresholdInfo Threshold information of out-off limit detection.
2712   *         This parameter can be a value of @ref MDF_OldThresholdInfo.
2713   * @retval HAL status.
2714   * @note   This function must not be used with ADF instance.
2715   */
HAL_MDF_PollForOld(MDF_HandleTypeDef * hmdf,uint32_t Timeout,uint32_t * pThresholdInfo)2716 HAL_StatusTypeDef HAL_MDF_PollForOld(MDF_HandleTypeDef *hmdf, uint32_t Timeout, uint32_t *pThresholdInfo)
2717 {
2718   HAL_StatusTypeDef status = HAL_OK;
2719 
2720   /* Check parameters */
2721   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2722   if (pThresholdInfo == NULL)
2723   {
2724     status = HAL_ERROR;
2725   }
2726   else
2727   {
2728     /* Check state */
2729     if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2730     {
2731       if (hmdf->State != HAL_MDF_STATE_READY)
2732       {
2733         status = HAL_ERROR;
2734       }
2735     }
2736   }
2737 
2738   if (status == HAL_OK)
2739   {
2740     /* Check out-off limit detector status */
2741     if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != MDF_OLDCR_OLDACTIVE)
2742     {
2743       status = HAL_ERROR;
2744     }
2745     else
2746     {
2747       uint32_t tickstart = HAL_GetTick();
2748 
2749       /* Wait for out-off limit detection */
2750       while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_OLDF) != MDF_DFLTISR_OLDF) && (status == HAL_OK))
2751       {
2752         /* Check the timeout */
2753         if (Timeout != HAL_MAX_DELAY)
2754         {
2755           if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
2756           {
2757             status = HAL_TIMEOUT;
2758           }
2759         }
2760       }
2761 
2762       if (status == HAL_OK)
2763       {
2764         /* Get threshold information */
2765         if ((hmdf->Instance->DFLTISR & (MDF_DFLTISR_THLF | MDF_DFLTISR_THHF)) == 0U)
2766         {
2767           *pThresholdInfo = MDF_OLD_IN_THRESHOLDS;
2768         }
2769         else if ((hmdf->Instance->DFLTISR & MDF_DFLTISR_THLF) == MDF_DFLTISR_THLF)
2770         {
2771           *pThresholdInfo = MDF_OLD_LOW_THRESHOLD;
2772         }
2773         else
2774         {
2775           *pThresholdInfo = MDF_OLD_HIGH_THRESHOLD;
2776         }
2777 
2778         /* Clear out-off limit detection flags */
2779         hmdf->Instance->DFLTISR |= MDF_DFLTISR_OLDF;
2780       }
2781     }
2782   }
2783 
2784   /* Return function status */
2785   return status;
2786 }
2787 
2788 /**
2789   * @brief  This function allows to stop out-off limit detection in polling mode.
2790   * @param  hmdf MDF handle.
2791   * @retval HAL status.
2792   * @note   This function must not be used with ADF instance.
2793   */
HAL_MDF_OldStop(MDF_HandleTypeDef * hmdf)2794 HAL_StatusTypeDef HAL_MDF_OldStop(MDF_HandleTypeDef *hmdf)
2795 {
2796   HAL_StatusTypeDef status = HAL_OK;
2797 
2798   /* Check parameters */
2799   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2800 
2801   /* Check state */
2802   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2803   {
2804     if (hmdf->State != HAL_MDF_STATE_READY)
2805     {
2806       status = HAL_ERROR;
2807     }
2808   }
2809 
2810   if (status == HAL_OK)
2811   {
2812     /* Check out-off limit detector status */
2813     if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != MDF_OLDCR_OLDACTIVE)
2814     {
2815       status = HAL_ERROR;
2816     }
2817     else
2818     {
2819       /* Disable out-off limit detection */
2820       hmdf->Instance->OLDCR &= ~(MDF_OLDCR_OLDEN);
2821 
2822       /* Clear potential pending out-off limit detection flags */
2823       hmdf->Instance->DFLTISR |= MDF_DFLTISR_OLDF;
2824     }
2825   }
2826 
2827   /* Return function status */
2828   return status;
2829 }
2830 
2831 /**
2832   * @brief  This function allows to start out-off limit detection in interrupt mode.
2833   * @param  hmdf MDF handle.
2834   * @param  pOldConfig Out-off limit detector configuration parameters.
2835   * @retval HAL status.
2836   * @note   This function must not be used with ADF instance.
2837   */
HAL_MDF_OldStart_IT(MDF_HandleTypeDef * hmdf,const MDF_OldConfigTypeDef * pOldConfig)2838 HAL_StatusTypeDef HAL_MDF_OldStart_IT(MDF_HandleTypeDef *hmdf, const MDF_OldConfigTypeDef *pOldConfig)
2839 {
2840   HAL_StatusTypeDef status = HAL_OK;
2841 
2842   /* Check parameters */
2843   if (pOldConfig == NULL)
2844   {
2845     status = HAL_ERROR;
2846   }
2847   else
2848   {
2849     assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2850     assert_param(IS_MDF_OLD_CIC_MODE(pOldConfig->OldCicMode));
2851     assert_param(IS_MDF_OLD_DECIMATION_RATIO(pOldConfig->OldDecimationRatio));
2852     assert_param(IS_MDF_OLD_THRESHOLD(pOldConfig->HighThreshold));
2853     assert_param(IS_MDF_OLD_THRESHOLD(pOldConfig->LowThreshold));
2854     assert_param(IS_MDF_OLD_EVENT_CONFIG(pOldConfig->OldEventConfig));
2855     assert_param(IS_MDF_BREAK_SIGNAL(pOldConfig->BreakSignal));
2856     if (pOldConfig->LowThreshold >= pOldConfig->HighThreshold)
2857     {
2858       status = HAL_ERROR;
2859     }
2860     else
2861     {
2862       /* Check state */
2863       if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2864       {
2865         if (hmdf->State != HAL_MDF_STATE_READY)
2866         {
2867           status = HAL_ERROR;
2868         }
2869       }
2870     }
2871 
2872     if (status == HAL_OK)
2873     {
2874       /* Check out-off limit detector status */
2875       if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) == MDF_OLDCR_OLDACTIVE)
2876       {
2877         status = HAL_ERROR;
2878       }
2879       else
2880       {
2881         /* Check filter status */
2882         if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) == MDF_DFLTCR_DFLTACTIVE)
2883         {
2884           /* Check main filter order */
2885           if ((hmdf->Instance->DFLTCICR & MDF_DFLTCICR_CICMOD) >= MDF_ONE_FILTER_SINC4)
2886           {
2887             status = HAL_ERROR;
2888           }
2889         }
2890         else
2891         {
2892           /* Reset main filter order */
2893           hmdf->Instance->DFLTCICR &= ~(MDF_DFLTCICR_CICMOD);
2894         }
2895 
2896         if (status == HAL_OK)
2897         {
2898           /* Configure OLD CIC mode, decimation ratio, event and break signal */
2899           hmdf->Instance->OLDCR = (pOldConfig->OldCicMode | pOldConfig->OldEventConfig |
2900                                    ((pOldConfig->OldDecimationRatio - 1U) << MDF_OLDCR_ACICD_Pos) |
2901                                    (pOldConfig->BreakSignal << MDF_OLDCR_BKOLD_Pos));
2902 
2903           /* Configure low and high thresholds */
2904           hmdf->Instance->OLDTHLR = (uint32_t) pOldConfig->LowThreshold;
2905           hmdf->Instance->OLDTHHR = (uint32_t) pOldConfig->HighThreshold;
2906 
2907           /* Enable out-off limit detector interrupt */
2908           hmdf->Instance->DFLTIER |= MDF_DFLTIER_OLDIE;
2909 
2910           /* Enable out-off limit detector */
2911           hmdf->Instance->OLDCR |= MDF_OLDCR_OLDEN;
2912         }
2913       }
2914     }
2915   }
2916 
2917   /* Return function status */
2918   return status;
2919 }
2920 
2921 /**
2922   * @brief  This function allows to stop out-off limit detection in interrupt mode.
2923   * @param  hmdf MDF handle.
2924   * @retval HAL status.
2925   * @note   This function must not be used with ADF instance.
2926   */
HAL_MDF_OldStop_IT(MDF_HandleTypeDef * hmdf)2927 HAL_StatusTypeDef HAL_MDF_OldStop_IT(MDF_HandleTypeDef *hmdf)
2928 {
2929   HAL_StatusTypeDef status = HAL_OK;
2930 
2931   /* Check parameters */
2932   assert_param(IS_MDF_INSTANCE(hmdf->Instance));
2933 
2934   /* Check state */
2935   if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
2936   {
2937     if (hmdf->State != HAL_MDF_STATE_READY)
2938     {
2939       status = HAL_ERROR;
2940     }
2941   }
2942 
2943   if (status == HAL_OK)
2944   {
2945     /* Check out-off limit detector status */
2946     if ((hmdf->Instance->OLDCR & MDF_OLDCR_OLDACTIVE) != MDF_OLDCR_OLDACTIVE)
2947     {
2948       status = HAL_ERROR;
2949     }
2950     else
2951     {
2952       /* Disable out-off limit detection */
2953       hmdf->Instance->OLDCR &= ~(MDF_OLDCR_OLDEN);
2954 
2955       /* Disable out-off limit detector interrupt */
2956       hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_OLDIE);
2957 
2958       /* Clear potential pending out-off limit detection flags */
2959       hmdf->Instance->DFLTISR |= MDF_DFLTISR_OLDF;
2960     }
2961   }
2962 
2963   /* Return function status */
2964   return status;
2965 }
2966 
2967 /**
2968   * @brief  MDF out-off limit detector callback.
2969   * @param  hmdf MDF handle.
2970   * @param  ThresholdInfo Threshold information of out-off limit detection.
2971   *         This parameter can be a value of @ref MDF_OldThresholdInfo.
2972   * @retval None.
2973   */
HAL_MDF_OldCallback(MDF_HandleTypeDef * hmdf,uint32_t ThresholdInfo)2974 __weak void HAL_MDF_OldCallback(MDF_HandleTypeDef *hmdf, uint32_t ThresholdInfo)
2975 {
2976   /* Prevent unused argument(s) compilation warning */
2977   UNUSED(hmdf);
2978   UNUSED(ThresholdInfo);
2979 
2980   /* NOTE : This function should not be modified, when the function is needed,
2981             the HAL_MDF_OldCallback could be implemented in the user file */
2982 }
2983 
2984 /**
2985   * @}
2986   */
2987 
2988 /** @defgroup MDF_Exported_Functions_Group6  Generic functions
2989   * @brief    Generic functions
2990   *
2991 @verbatim
2992   ==============================================================================
2993                           ##### Generic functions #####
2994   ==============================================================================
2995     [..]  This section provides functions allowing to :
2996       (+) Handle MDF interrupt.
2997       (+) Inform user that error occurs.
2998       (+) Get the current MDF instance state.
2999       (+) Get the current MDF instance error code.
3000 @endverbatim
3001   * @{
3002   */
3003 
3004 /**
3005   * @brief  This function handles the MDF interrupts.
3006   * @param  hmdf MDF handle.
3007   * @retval None.
3008   */
HAL_MDF_IRQHandler(MDF_HandleTypeDef * hmdf)3009 void HAL_MDF_IRQHandler(MDF_HandleTypeDef *hmdf)
3010 {
3011   uint32_t tmp_reg1;
3012   uint32_t tmp_reg2;
3013   uint32_t interrupts;
3014 
3015   /* Read current flags and interrupts and determine which ones occur */
3016   tmp_reg1 = hmdf->Instance->DFLTIER;
3017   tmp_reg2 = hmdf->Instance->DFLTISR;
3018   interrupts = (tmp_reg1 & tmp_reg2);
3019 
3020   /* Check if data overflow occurs */
3021   if ((interrupts & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF)
3022   {
3023     /* Clear data overflow flag */
3024     hmdf->Instance->DFLTISR |= MDF_DFLTISR_DOVRF;
3025 
3026     /* Update error code */
3027     hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
3028 
3029     /* Call error callback */
3030 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3031     hmdf->ErrorCallback(hmdf);
3032 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3033     HAL_MDF_ErrorCallback(hmdf);
3034 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3035   }
3036   /* Check if snapshot overrun occurs */
3037   else if ((interrupts & MDF_DFLTISR_SSOVRF) == MDF_DFLTISR_SSOVRF)
3038   {
3039     /* Clear snapshot overrun flag */
3040     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SSOVRF;
3041 
3042     /* Update error code */
3043     hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
3044 
3045     /* Call error callback */
3046 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3047     hmdf->ErrorCallback(hmdf);
3048 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3049     HAL_MDF_ErrorCallback(hmdf);
3050 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3051   }
3052   /* Check if RXFIFO threshold occurs */
3053   else if ((interrupts & MDF_DFLTISR_FTHF) == MDF_DFLTISR_FTHF)
3054   {
3055     /* Call acquisition complete callback */
3056 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3057     hmdf->AcqCpltCallback(hmdf);
3058 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3059     HAL_MDF_AcqCpltCallback(hmdf);
3060 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3061 
3062     /* Update state only in asynchronous single shot mode */
3063     if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE)
3064     {
3065       hmdf->State = HAL_MDF_STATE_READY;
3066     }
3067   }
3068   /* Check if snapshot data ready occurs */
3069   else if ((interrupts & MDF_DFLTISR_SSDRF) == MDF_DFLTISR_SSDRF)
3070   {
3071     /* Clear snapshot data ready flag */
3072     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SSDRF;
3073 
3074     /* Call acquisition complete callback */
3075 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3076     hmdf->AcqCpltCallback(hmdf);
3077 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3078     HAL_MDF_AcqCpltCallback(hmdf);
3079 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3080   }
3081   /* Check if reshape filter overrun occurs */
3082   else if ((interrupts & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF)
3083   {
3084     /* Clear reshape filter overrun flag */
3085     hmdf->Instance->DFLTISR |= MDF_DFLTISR_RFOVRF;
3086 
3087     /* Update error code */
3088     hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN;
3089 
3090     /* Call error callback */
3091 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3092     hmdf->ErrorCallback(hmdf);
3093 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3094     HAL_MDF_ErrorCallback(hmdf);
3095 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3096   }
3097   /* Check if clock absence detection occurs */
3098   else if ((interrupts & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF)
3099   {
3100     /* Clear clock absence detection flag */
3101     hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
3102 
3103     /* Update error code */
3104     hmdf->ErrorCode |= MDF_ERROR_CLOCK_ABSENCE;
3105 
3106     /* Call error callback */
3107 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3108     hmdf->ErrorCallback(hmdf);
3109 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3110     HAL_MDF_ErrorCallback(hmdf);
3111 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3112   }
3113   /* Check if saturation occurs */
3114   else if ((interrupts & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF)
3115   {
3116     /* Clear saturation flag */
3117     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SATF;
3118 
3119     /* Update error code */
3120     hmdf->ErrorCode |= MDF_ERROR_SATURATION;
3121 
3122     /* Call error callback */
3123 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3124     hmdf->ErrorCallback(hmdf);
3125 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3126     HAL_MDF_ErrorCallback(hmdf);
3127 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3128   }
3129   /* Check if short-circuit detection occurs */
3130   else if ((interrupts & MDF_DFLTISR_SCDF) == MDF_DFLTISR_SCDF)
3131   {
3132     /* Clear short-circuit detection flag */
3133     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SCDF;
3134 
3135     /* Update error code */
3136     hmdf->ErrorCode |= MDF_ERROR_SHORT_CIRCUIT;
3137 
3138     /* Call error callback */
3139 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3140     hmdf->ErrorCallback(hmdf);
3141 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3142     HAL_MDF_ErrorCallback(hmdf);
3143 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3144   }
3145   /* Check if out-off limit detection occurs */
3146   else if ((interrupts & MDF_DFLTISR_OLDF) == MDF_DFLTISR_OLDF)
3147   {
3148     uint32_t threshold_info;
3149 
3150     /* Get threshold information */
3151     if ((hmdf->Instance->DFLTISR & (MDF_DFLTISR_THLF | MDF_DFLTISR_THHF)) == 0U)
3152     {
3153       threshold_info = MDF_OLD_IN_THRESHOLDS;
3154     }
3155     else if ((hmdf->Instance->DFLTISR & MDF_DFLTISR_THLF) == MDF_DFLTISR_THLF)
3156     {
3157       threshold_info = MDF_OLD_LOW_THRESHOLD;
3158     }
3159     else
3160     {
3161       threshold_info = MDF_OLD_HIGH_THRESHOLD;
3162     }
3163 
3164     /* Clear out-off limit detection flag */
3165     hmdf->Instance->DFLTISR |= MDF_DFLTISR_OLDF;
3166 
3167     /* Update error code */
3168     hmdf->ErrorCode |= MDF_ERROR_OUT_OFF_LIMIT;
3169 
3170     /* Call out-off limit detection callback */
3171 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3172     hmdf->OldCallback(hmdf, threshold_info);
3173 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3174     HAL_MDF_OldCallback(hmdf, threshold_info);
3175 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3176   }
3177   /* Check if sound activity detection occurs */
3178   else if ((interrupts & MDF_DFLTISR_SDDETF) == MDF_DFLTISR_SDDETF)
3179   {
3180     /* Clear sound activity detection flag */
3181     hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF;
3182 
3183     /* Call sound activity detection callback */
3184 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3185     hmdf->SadCallback(hmdf);
3186 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3187     HAL_MDF_SadCallback(hmdf);
3188 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3189   }
3190   else
3191   {
3192     /* Check if sound level ready occurs */
3193     if ((interrupts & MDF_DFLTISR_SDLVLF) == MDF_DFLTISR_SDLVLF)
3194     {
3195       uint32_t sound_level;
3196       uint32_t ambient_noise;
3197 
3198       /* Get sound level */
3199       sound_level = hmdf->Instance->SADSDLVR;
3200 
3201       /* Get ambient noise */
3202       ambient_noise = hmdf->Instance->SADANLVR;
3203 
3204       /* Clear sound level ready flag */
3205       hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF;
3206 
3207       /* Call sound level callback */
3208 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3209       hmdf->SndLvCallback(hmdf, sound_level, ambient_noise);
3210 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3211       HAL_MDF_SndLvlCallback(hmdf, sound_level, ambient_noise);
3212 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3213     }
3214   }
3215 }
3216 
3217 /**
3218   * @brief  MDF error callback.
3219   * @param  hmdf MDF handle.
3220   * @retval None.
3221   */
HAL_MDF_ErrorCallback(MDF_HandleTypeDef * hmdf)3222 __weak void HAL_MDF_ErrorCallback(MDF_HandleTypeDef *hmdf)
3223 {
3224   /* Prevent unused argument(s) compilation warning */
3225   UNUSED(hmdf);
3226 
3227   /* NOTE : This function should not be modified, when the function is needed,
3228             the HAL_MDF_ErrorCallback could be implemented in the user file */
3229 }
3230 
3231 /**
3232   * @brief  This function allows to get the current MDF state.
3233   * @param  hmdf MDF handle.
3234   * @retval MDF state.
3235   */
HAL_MDF_GetState(const MDF_HandleTypeDef * hmdf)3236 HAL_MDF_StateTypeDef HAL_MDF_GetState(const MDF_HandleTypeDef *hmdf)
3237 {
3238   /* Return MDF state */
3239   return hmdf->State;
3240 }
3241 
3242 /**
3243   * @brief  This function allows to get the current MDF error.
3244   * @param  hmdf MDF handle.
3245   * @retval MDF error code.
3246   */
HAL_MDF_GetError(const MDF_HandleTypeDef * hmdf)3247 uint32_t HAL_MDF_GetError(const MDF_HandleTypeDef *hmdf)
3248 {
3249   /* Return MDF error code */
3250   return hmdf->ErrorCode;
3251 }
3252 
3253 /**
3254   * @}
3255   */
3256 
3257 /**
3258   * @}
3259   */
3260 
3261 /** @addtogroup MDF_Private_Functions
3262   * @brief      Private functions
3263   * @{
3264   */
3265 
3266 /**
3267   * @brief  This function allows to get the handle number from instance.
3268   * @param  pInstance MDF instance.
3269   * @retval Instance number.
3270   */
MDF_GetHandleNumberFromInstance(const MDF_Filter_TypeDef * const pInstance)3271 static uint32_t MDF_GetHandleNumberFromInstance(const MDF_Filter_TypeDef *const pInstance)
3272 {
3273   uint32_t handle_number;
3274 
3275   /* Get handle number from instance */
3276   if (pInstance == MDF1_Filter0)
3277   {
3278     handle_number = 0U;
3279   }
3280   else if (pInstance == MDF1_Filter1)
3281   {
3282     handle_number = 1U;
3283   }
3284   else if (pInstance == MDF1_Filter2)
3285   {
3286     handle_number = 2U;
3287   }
3288   else if (pInstance == MDF1_Filter3)
3289   {
3290     handle_number = 3U;
3291   }
3292   else if (pInstance == MDF1_Filter4)
3293   {
3294     handle_number = 4U;
3295   }
3296   else if (pInstance == MDF1_Filter5)
3297   {
3298     handle_number = 5U;
3299   }
3300   else /* ADF1_Filter0 */
3301   {
3302     handle_number = 6U;
3303   }
3304 
3305   return handle_number;
3306 }
3307 
3308 /**
3309   * @brief  This function allows to configure filter and start acquisition.
3310   * @param  hmdf MDF handle.
3311   * @param  pFilterConfig Filter configuration parameters.
3312   * @retval None.
3313   */
MDF_AcqStart(MDF_HandleTypeDef * const hmdf,const MDF_FilterConfigTypeDef * const pFilterConfig)3314 static void MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig)
3315 {
3316   uint32_t register_gain_value;
3317 
3318   /* Configure acquisition mode, discard samples, trigger and fifo threshold */
3319   assert_param(IS_MDF_DISCARD_SAMPLES(pFilterConfig->DiscardSamples));
3320   assert_param(IS_MDF_FIFO_THRESHOLD(pFilterConfig->FifoThreshold));
3321   if ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_CONT) ||
3322       (pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE))
3323   {
3324     /* Trigger parameters are not used */
3325     hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold |
3326                                (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos));
3327   }
3328   else
3329   {
3330     /* Trigger parameters are used */
3331     if (IS_ADF_INSTANCE(hmdf->Instance))
3332     {
3333       assert_param(IS_ADF_TRIGGER_SOURCE(pFilterConfig->Trigger.Source));
3334     }
3335     else
3336     {
3337       assert_param(IS_MDF_TRIGGER_SOURCE(pFilterConfig->Trigger.Source));
3338     }
3339     assert_param(IS_MDF_TRIGGER_EDGE(pFilterConfig->Trigger.Edge));
3340     hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold |
3341                                pFilterConfig->Trigger.Source | pFilterConfig->Trigger.Edge |
3342                                (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos));
3343   }
3344 
3345   /* Configure if needed snapshot format only for MDF instance */
3346   if (IS_MDF_INSTANCE(hmdf->Instance) && (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SNAPSHOT))
3347   {
3348     assert_param(IS_MDF_SNAPSHOT_FORMAT(pFilterConfig->SnapshotFormat));
3349     hmdf->Instance->DFLTCR |= pFilterConfig->SnapshotFormat;
3350   }
3351 
3352   /* Configure data source, CIC mode, decimation ratio and gain */
3353   if (IS_ADF_INSTANCE(hmdf->Instance))
3354   {
3355     assert_param(IS_ADF_DATA_SOURCE(pFilterConfig->DataSource));
3356     assert_param(IS_ADF_CIC_MODE(pFilterConfig->CicMode));
3357   }
3358   else
3359   {
3360     assert_param(IS_MDF_DATA_SOURCE(pFilterConfig->DataSource));
3361   }
3362   assert_param(IS_MDF_DECIMATION_RATIO(pFilterConfig->DecimationRatio));
3363   assert_param(IS_MDF_GAIN(pFilterConfig->Gain));
3364   if (pFilterConfig->Gain < 0)
3365   {
3366     int32_t adjust_gain;
3367 
3368     /* adjust gain value to set on register for negative value (offset of -16) */
3369     adjust_gain = pFilterConfig->Gain - 16;
3370     register_gain_value = ((uint32_t) adjust_gain & 0x3FU);
3371   }
3372   else
3373   {
3374     /* for positive value, no offset to apply */
3375     register_gain_value = (uint32_t) pFilterConfig->Gain;
3376   }
3377   hmdf->Instance->DFLTCICR = (pFilterConfig->DataSource | pFilterConfig->CicMode |
3378                               ((pFilterConfig->DecimationRatio - 1U) << MDF_DFLTCICR_MCICD_Pos) |
3379                               (register_gain_value << MDF_DFLTCICR_SCALE_Pos));
3380 
3381   /* Configure bitstream delay */
3382   assert_param(IS_MDF_DELAY(pFilterConfig->Delay));
3383   hmdf->Instance->DLYCR = pFilterConfig->Delay;
3384 
3385   /* Configure offset compensation only for MDF instance */
3386   if (IS_MDF_INSTANCE(hmdf->Instance))
3387   {
3388     assert_param(IS_MDF_OFFSET(pFilterConfig->Offset));
3389     hmdf->Instance->OECCR = (uint32_t) pFilterConfig->Offset;
3390   }
3391 
3392   /* Configure reshape filter */
3393   assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->ReshapeFilter.Activation));
3394   hmdf->Instance->DFLTRSFR = 0U;
3395   if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
3396   {
3397     /* Configure reshape filter decimation ratio */
3398     assert_param(IS_MDF_RSF_DECIMATION_RATIO(pFilterConfig->ReshapeFilter.DecimationRatio));
3399     hmdf->Instance->DFLTRSFR |= pFilterConfig->ReshapeFilter.DecimationRatio;
3400   }
3401   else
3402   {
3403     /* Bypass reshape filter */
3404     hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_RSFLTBYP;
3405   }
3406 
3407   /* Configure high-pass filter */
3408   assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->HighPassFilter.Activation));
3409   if (pFilterConfig->HighPassFilter.Activation == ENABLE)
3410   {
3411     /* Configure high-pass filter cut-off frequency */
3412     assert_param(IS_MDF_HPF_CUTOFF_FREQ(pFilterConfig->HighPassFilter.CutOffFrequency));
3413     hmdf->Instance->DFLTRSFR |= pFilterConfig->HighPassFilter.CutOffFrequency;
3414   }
3415   else
3416   {
3417     /* Bypass high-pass filter */
3418     hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_HPFBYP;
3419   }
3420 
3421   /* Configure integrator only for MDF instance */
3422   if (IS_MDF_INSTANCE(hmdf->Instance))
3423   {
3424     assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->Integrator.Activation));
3425     if (pFilterConfig->Integrator.Activation == ENABLE)
3426     {
3427       /* Configure integrator value and output division */
3428       assert_param(IS_MDF_INTEGRATOR_VALUE(pFilterConfig->Integrator.Value));
3429       assert_param(IS_MDF_INTEGRATOR_OUTPUT_DIV(pFilterConfig->Integrator.OutputDivision));
3430       hmdf->Instance->DFLTINTR = (((pFilterConfig->Integrator.Value - 1U) << MDF_DFLTINTR_INTVAL_Pos) |
3431                                   pFilterConfig->Integrator.OutputDivision);
3432     }
3433     else
3434     {
3435       /* Bypass integrator */
3436       hmdf->Instance->DFLTINTR = 0U;
3437     }
3438   }
3439 
3440   if (IS_ADF_INSTANCE(hmdf->Instance))
3441   {
3442     assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
3443     if (pFilterConfig->SoundActivity.Activation == ENABLE)
3444     {
3445       /* Configure SAD mode, frame size, hysteresis, sound trigger event
3446          and data memory transfer only for ADF instance */
3447       assert_param(IS_MDF_SAD_MODE(pFilterConfig->SoundActivity.Mode));
3448       assert_param(IS_MDF_SAD_FRAME_SIZE(pFilterConfig->SoundActivity.FrameSize));
3449       if (pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR)
3450       {
3451         assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Hysteresis));
3452       }
3453       assert_param(IS_MDF_SAD_SOUND_TRIGGER(pFilterConfig->SoundActivity.SoundTriggerEvent));
3454       assert_param(IS_MDF_SAD_DATA_MEMORY_TRANSFER(pFilterConfig->SoundActivity.DataMemoryTransfer));
3455       if ((pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR) &&
3456           (pFilterConfig->SoundActivity.Hysteresis == ENABLE))
3457       {
3458         hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize |
3459                                  MDF_SADCR_HYSTEN | pFilterConfig->SoundActivity.SoundTriggerEvent |
3460                                  pFilterConfig->SoundActivity.DataMemoryTransfer);
3461       }
3462       else
3463       {
3464         hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize |
3465                                  pFilterConfig->SoundActivity.SoundTriggerEvent |
3466                                  pFilterConfig->SoundActivity.DataMemoryTransfer);
3467       }
3468 
3469       /* Configure SAD minimum noise level, hangover window, learning frames,
3470          ambient noise slope control and signal noise threshold only for ADF instance */
3471       assert_param(IS_MDF_SAD_MIN_NOISE_LEVEL(pFilterConfig->SoundActivity.MinNoiseLevel));
3472       assert_param(IS_MDF_SAD_HANGOVER_WINDOW(pFilterConfig->SoundActivity.HangoverWindow));
3473       assert_param(IS_MDF_SAD_LEARNING_FRAMES(pFilterConfig->SoundActivity.LearningFrames));
3474       assert_param(IS_MDF_SAD_SIGNAL_NOISE_THRESHOLD(pFilterConfig->SoundActivity.SignalNoiseThreshold));
3475       if (pFilterConfig->SoundActivity.Mode != MDF_SAD_SOUND_DETECTOR)
3476       {
3477         assert_param(IS_MDF_SAD_AMBIENT_NOISE_SLOPE(pFilterConfig->SoundActivity.AmbientNoiseSlope));
3478         hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) |
3479                                    pFilterConfig->SoundActivity.HangoverWindow |
3480                                    pFilterConfig->SoundActivity.LearningFrames |
3481                                    (pFilterConfig->SoundActivity.AmbientNoiseSlope << MDF_SADCFGR_ANSLP_Pos) |
3482                                    pFilterConfig->SoundActivity.SignalNoiseThreshold);
3483       }
3484       else
3485       {
3486         hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) |
3487                                    pFilterConfig->SoundActivity.HangoverWindow |
3488                                    pFilterConfig->SoundActivity.LearningFrames |
3489                                    pFilterConfig->SoundActivity.SignalNoiseThreshold);
3490       }
3491     }
3492     else
3493     {
3494       /* SAD is not used */
3495       hmdf->Instance->SADCR = 0U;
3496       hmdf->Instance->SADCFGR = 0U;
3497     }
3498   }
3499 
3500   /* Update instance state */
3501   hmdf->State = HAL_MDF_STATE_ACQUISITION;
3502 
3503   /* Enable sound activity detector if needed only for ADF instance */
3504   if ((IS_ADF_INSTANCE(hmdf->Instance)) && (pFilterConfig->SoundActivity.Activation == ENABLE))
3505   {
3506     hmdf->Instance->SADCR |= MDF_SADCR_SADEN;
3507   }
3508 
3509   /* Enable filter */
3510   hmdf->Instance->DFLTCR |= MDF_DFLTCR_DFLTEN;
3511 }
3512 
3513 /**
3514   * @brief  This function handles DMA transfer complete callback.
3515   * @param  hdma DMA handle.
3516   * @retval None.
3517   */
MDF_DmaXferCpltCallback(DMA_HandleTypeDef * hdma)3518 static void MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma)
3519 {
3520   MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3521 
3522   /* Check if DMA in circular mode */
3523   if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
3524   {
3525     hmdf->State = HAL_MDF_STATE_READY;
3526   }
3527 
3528 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3529   hmdf->AcqCpltCallback(hmdf);
3530 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3531   HAL_MDF_AcqCpltCallback(hmdf);
3532 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3533 }
3534 
3535 /**
3536   * @brief  This function handles DMA half transfer complete callback.
3537   * @param  hdma DMA handle.
3538   * @retval None.
3539   */
MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef * hdma)3540 static void MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma)
3541 {
3542   MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3543 
3544 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3545   hmdf->AcqHalfCpltCallback(hmdf);
3546 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3547   HAL_MDF_AcqHalfCpltCallback(hmdf);
3548 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3549 }
3550 
3551 /**
3552   * @brief  This function handles DMA error callback.
3553   * @param  hdma DMA handle.
3554   * @retval None.
3555   */
MDF_DmaErrorCallback(DMA_HandleTypeDef * hdma)3556 static void MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma)
3557 {
3558   MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
3559 
3560   /* Update error code */
3561   hmdf->ErrorCode |= MDF_ERROR_DMA;
3562 
3563 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
3564   hmdf->ErrorCallback(hmdf);
3565 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
3566   HAL_MDF_ErrorCallback(hmdf);
3567 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
3568 }
3569 
3570 /**
3571   * @}
3572   */
3573 
3574 #endif /* HAL_MDF_MODULE_ENABLED */
3575 
3576 /**
3577   * @}
3578   */
3579 
3580 /**
3581   * @}
3582   */
3583