1 /**
2 ******************************************************************************
3 * @file stm32h7rsxx_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 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2022 STMicroelectronics.
16 * All rights reserved.
17 *
18 * This software is licensed under terms that can be found in the LICENSE file
19 * in the root directory of this software component.
20 * If no LICENSE file comes with this software, it is provided AS-IS.
21 *
22 ******************************************************************************
23 @verbatim
24 ==============================================================================
25 ##### How to use this driver #####
26 ==============================================================================
27 [..]
28 *** Initialization and de-initialization ***
29 ============================================
30 [..]
31 (#) User has first to initialize ADF instance.
32 (#) As prerequisite, fill in the HAL_MDF_MspInit() :
33 (++) Enable ADFz clock interface with __HAL_RCC_ADFz_CLK_ENABLE().
34 (++) Enable the clocks for the used GPIOS with __HAL_RCC_GPIOx_CLK_ENABLE().
35 (++) Configure these pins in alternate mode using HAL_GPIO_Init().
36 (++) If interrupt mode is used, enable and configure ADFz_FLTx
37 interrupt with HAL_NVIC_SetPriority() and HAL_NVIC_EnableIRQ().
38 (++) If DMA mode is used, initialize and configure DMA.
39 (#) Configure the common parameters, serial interface parameters and
40 filter bitstream selection by calling HAL_MDF_Init() function.
41
42 [..]
43 (#) User can de-initialize ADF instance with HAL_MDF_DeInit() function.
44
45 *** Acquisition ***
46 ===================
47 [..]
48 (#) Configure filter parameters and start acquisition using HAL_MDF_AcqStart(),
49 HAL_MDF_AcqStart_IT() or HAL_MDF_AcqStart_DMA().
50 (#) In polling mode :
51 (++) Use HAL_MDF_PollForAcq() to detect the end of acquisition.
52 Use HAL_MDF_GetAcqValue to get acquisition value.
53 (++) Use HAL_MDF_PollForSndLvl() to detect and get
54 new sound level value and ambient noise value.
55 (++) Use HAL_MDF_PollForSad() to detect sound activity.
56 (#) In interrupt mode :
57 (++) HAL_MDF_AcqCpltCallback() will be called at the end of acquisition.
58 Use HAL_MDF_GetAcqValue to get acquisition value.
59 (++) HAL_MDF_SndLvlCallback() will be called when new
60 sound level and ambient noise values are available.
61 (++) HAL_MDF_SadCallback() will be called when
62 sound activity detection occurs.
63 (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun or
64 saturation occurs.
65 Use HAL_MDF_GetErrorCode() to get the corresponding error.
66 (#) In DMA mode :
67 (++) HAL_MDF_AcqHalfCpltCallback() and HAL_MDF_AcqCpltCallback() will be called
68 respectively at the half acquisition and at the acquisition complete.
69 (++) HAL_MDF_SndLvlCallback() will be called when new
70 sound level and ambient noise values are available.
71 (++) HAL_MDF_SadCallback() will be called when
72 sound activity detection occurs.
73 (++) HAL_MDF_ErrorCallback() will be called if overflow, filter overrun,
74 saturation or DMA error occurs.
75 Use HAL_MDF_GetErrorCode() to get the corresponding error.
76 (#) Use HAL_MDF_GenerateTrgo() to generate pulse on TRGO signal.
77 (#) During acquisition, use HAL_MDF_SetDelay() and HAL_MDF_GetDelay() to respectively
78 set and get the delay on data source.
79 (#) During acquisition, use HAL_MDF_SetGain() and HAL_MDF_GetGain() to respectively
80 set and get the filter gain.
81 (#) Stop acquisition using HAL_MDF_AcqStop(), HAL_MDF_AcqStop_IT() or HAL_MDF_AcqStop_DMA().
82
83 *** Clock absence detection ***
84 ===============================
85 [..]
86 (#) Clock absence detection is always enabled so no need to start clock absence detection
87 in polling mode.
88 Use HAL_MDF_CkabStart_IT() to start clock absence detection in interrupt mode.
89 (#) In polling mode, use HAL_MDF_PollForCkab() to detect the clock absence.
90 (#) In interrupt mode, HAL_MDF_ErrorCallback() will be called if clock absence detection
91 occurs.
92 Use HAL_MDF_GetErrorCode() to get the corresponding error.
93 (#) Stop clock absence detection in interrupt mode using HAL_MDF_CkabStop_IT().
94
95 *** generic functions ***
96 =========================
97 [..]
98 (#) HAL_MDF_IRQHandler will be called when ADF interrupt occurs.
99 (#) HAL_MDF_ErrorCallback will be called when ADF error occurs.
100 (#) Use HAL_MDF_GetState() to get the current ADF instance state.
101 (#) Use HAL_MDF_GetErrorCode() to get the current ADF instance error code.
102
103 *** Callback registration ***
104 =============================
105 [..]
106 The compilation define USE_HAL_MDF_REGISTER_CALLBACKS when set to 1
107 allows the user to configure dynamically the driver callbacks.
108 Use functions HAL_MDF_RegisterCallback(), HAL_MDF_RegisterOldCallback()
109 or HAL_MDF_RegisterSndLvlCallback() to register a user callback.
110
111 [..]
112 Function HAL_MDF_RegisterCallback() allows to register following callbacks :
113 (+) AcqCpltCallback : Acquisition complete callback.
114 (+) AcqHalfCpltCallback : Acquisition half complete callback.
115 (+) SadCallback : Sound activity detection callback (only for ADF instance).
116 (+) ErrorCallback : Error callback.
117 (+) MspInitCallback : MSP init callback.
118 (+) MspDeInitCallback : MSP de-init callback.
119 [..]
120 This function takes as parameters the HAL peripheral handle, the Callback ID
121 and a pointer to the user callback function.
122
123 [..]
124 For specific sound level callback use dedicated register callback :
125 HAL_MDF_RegisterSndLvlCallback().
126
127 [..]
128 Use function HAL_MDF_UnRegisterCallback() to reset a callback to the default weak function.
129
130 [..]
131 HAL_MDF_UnRegisterCallback() takes as parameters the HAL peripheral handle and the Callback ID.
132 [..]
133 This function allows to reset following callbacks :
134 (+) AcqCpltCallback : Acquisition complete callback.
135 (+) AcqHalfCpltCallback : Acquisition half complete callback.
136 (+) SadCallback : Sound activity detection callback (only for ADF instance).
137 (+) ErrorCallback : Error callback.
138 (+) MspInitCallback : MSP init callback.
139 (+) MspDeInitCallback : MSP de-init callback.
140
141 [..]
142 For specific sound level callback use dedicated unregister callback :
143 HAL_MDF_UnRegisterSndLvlCallback().
144
145 [..]
146 By default, after the call of init function and if the state is RESET
147 all callbacks are reset to the corresponding legacy weak functions :
148 examples HAL_MDF_AcqCpltCallback(), HAL_MDF_ErrorCallback().
149 Exception done for MspInit and MspDeInit callbacks that are respectively
150 reset to the legacy weak functions in the init and de-init only when these
151 callbacks are null (not registered beforehand).
152 If not, MspInit or MspDeInit are not null, the init and de-init keep and use
153 the user MspInit/MspDeInit callbacks (registered beforehand).
154
155 [..]
156 Callbacks can be registered/unregistered in READY state only.
157 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
158 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
159 during the init/de-init.
160 In that case first register the MspInit/MspDeInit user callbacks using
161 HAL_MDF_RegisterCallback() before calling init or de-init function.
162
163 [..]
164 When the compilation define USE_HAL_MDF_REGISTER_CALLBACKS is set to 0 or
165 not defined, the callback registering feature is not available
166 and weak callbacks are used.
167
168 @endverbatim
169 */
170
171 /* Includes ------------------------------------------------------------------*/
172 #include "stm32h7rsxx_hal.h"
173
174 /** @addtogroup STM32H7RSxx_HAL_Driver
175 * @{
176 */
177
178 /** @defgroup MDF MDF
179 * @brief MDF HAL module driver
180 * @{
181 */
182
183 #ifdef HAL_MDF_MODULE_ENABLED
184
185 /* Private typedef -----------------------------------------------------------*/
186 /** @defgroup MDF_Private_Typedefs MDF Private Typedefs
187 * @{
188 */
189 /**
190 * @}
191 */
192
193 /* Private define ------------------------------------------------------------*/
194 /** @defgroup MDF_Private_Constants MDF Private Constants
195 * @{
196 */
197 /**
198 * @}
199 */
200
201 /* Private macro -------------------------------------------------------------*/
202 /* Private variables ---------------------------------------------------------*/
203 /** @defgroup MDF_Private_Variables MDF Private Variables
204 * @{
205 */
206 static MDF_HandleTypeDef *v_mdfHandle = NULL;
207 /**
208 * @}
209 */
210
211 /* Private function prototypes -----------------------------------------------*/
212 /** @defgroup MDF_Private_Functions MDF Private Functions
213 * @{
214 */
215 static void MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig);
216 static void MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma);
217 static void MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma);
218 static void MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma);
219 /**
220 * @}
221 */
222
223 /* Exported functions ---------------------------------------------------------*/
224 /** @defgroup MDF_Exported_Functions MDF Exported Functions
225 * @{
226 */
227
228 /** @defgroup MDF_Exported_Functions_Group1 Initialization and de-initialization functions
229 * @brief Initialization and de-initialization functions
230 *
231 @verbatim
232 ==============================================================================
233 ##### Initialization and de-initialization functions #####
234 ==============================================================================
235 [..] This section provides functions allowing to :
236 (+) Initialize the ADF instance.
237 (+) De-initialize the ADF instance.
238 (+) Register and unregister callbacks.
239 @endverbatim
240 * @{
241 */
242
243 /**
244 * @brief Initialize the MDF instance according to the specified parameters
245 * in the MDF_InitTypeDef structure and initialize the associated handle.
246 * @param hmdf MDF handle.
247 * @retval HAL status.
248 */
HAL_MDF_Init(MDF_HandleTypeDef * hmdf)249 HAL_StatusTypeDef HAL_MDF_Init(MDF_HandleTypeDef *hmdf)
250 {
251 HAL_StatusTypeDef status = HAL_OK;
252
253 /* Check MDF handle */
254 if (hmdf == NULL)
255 {
256 status = HAL_ERROR;
257 }
258 else
259 {
260 /* Check parameters */
261 assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance));
262 assert_param(IS_MDF_FILTER_BITSTREAM(hmdf->Init.FilterBistream));
263 assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.SerialInterface.Activation));
264
265 /* Check that instance has not been already initialized */
266 if (v_mdfHandle != NULL)
267 {
268 status = HAL_ERROR;
269 }
270 else
271 {
272 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
273 /* Reset callback pointers to the weak predefined callbacks */
274 hmdf->SndLvCallback = HAL_MDF_SndLvlCallback;
275 hmdf->SadCallback = HAL_MDF_SadCallback;
276 hmdf->AcqCpltCallback = HAL_MDF_AcqCpltCallback;
277 hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback;
278 hmdf->ErrorCallback = HAL_MDF_ErrorCallback;
279
280 /* Call MDF MSP init function */
281 if (hmdf->MspInitCallback == NULL)
282 {
283 hmdf->MspInitCallback = HAL_MDF_MspInit;
284 }
285 hmdf->MspInitCallback(hmdf);
286 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
287 /* Call MDF MSP init function */
288 HAL_MDF_MspInit(hmdf);
289 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
290
291 /* Configure common parameters */
292 /* Check clock generator status */
293 if ((ADF1->CKGCR & MDF_CKGCR_CKGACTIVE) != 0U)
294 {
295 status = HAL_ERROR;
296 }
297 else
298 {
299 /* Configure processing clock divider, output clock divider,
300 output clock pins and output clock generation trigger */
301 assert_param(IS_MDF_PROC_CLOCK_DIVIDER(hmdf->Init.CommonParam.ProcClockDivider));
302 assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Activation));
303 ADF1->CKGCR = 0U;
304 ADF1->CKGCR |= ((hmdf->Init.CommonParam.ProcClockDivider - 1U) << MDF_CKGCR_PROCDIV_Pos);
305 if (hmdf->Init.CommonParam.OutputClock.Activation == ENABLE)
306 {
307 assert_param(IS_MDF_OUTPUT_CLOCK_PINS(hmdf->Init.CommonParam.OutputClock.Pins));
308 assert_param(IS_MDF_OUTPUT_CLOCK_DIVIDER(hmdf->Init.CommonParam.OutputClock.Divider));
309 assert_param(IS_FUNCTIONAL_STATE(hmdf->Init.CommonParam.OutputClock.Trigger.Activation));
310 ADF1->CKGCR |= (((hmdf->Init.CommonParam.OutputClock.Divider - 1U) << MDF_CKGCR_CCKDIV_Pos) |
311 hmdf->Init.CommonParam.OutputClock.Pins |
312 (hmdf->Init.CommonParam.OutputClock.Pins >> 4U));
313 if (hmdf->Init.CommonParam.OutputClock.Trigger.Activation == ENABLE)
314 {
315 assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_SOURCE(hmdf->Init.CommonParam.OutputClock.Trigger.Source));
316 assert_param(IS_MDF_OUTPUT_CLOCK_TRIGGER_EDGE(hmdf->Init.CommonParam.OutputClock.Trigger.Edge));
317 ADF1->CKGCR |= (hmdf->Init.CommonParam.OutputClock.Trigger.Source |
318 hmdf->Init.CommonParam.OutputClock.Trigger.Edge |
319 MDF_CKGCR_CKGMOD);
320 }
321 }
322
323 /* Activate clock generator */
324 ADF1->CKGCR |= MDF_CKGCR_CKGDEN;
325 }
326
327 /* Configure serial interface */
328 if ((status == HAL_OK) && (hmdf->Init.SerialInterface.Activation == ENABLE))
329 {
330 /* Check serial interface status */
331 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U)
332 {
333 status = HAL_ERROR;
334 }
335 else
336 {
337 /* Configure mode, clock source and threshold */
338 assert_param(IS_MDF_SITF_MODE(hmdf->Init.SerialInterface.Mode));
339 assert_param(IS_MDF_SITF_CLOCK_SOURCE(hmdf->Init.SerialInterface.ClockSource));
340 assert_param(IS_MDF_SITF_THRESHOLD(hmdf->Init.SerialInterface.Threshold));
341 hmdf->Instance->SITFCR = 0U;
342 hmdf->Instance->SITFCR |= ((hmdf->Init.SerialInterface.Threshold << MDF_SITFCR_STH_Pos) |
343 hmdf->Init.SerialInterface.Mode | hmdf->Init.SerialInterface.ClockSource);
344
345 /* Activate serial interface */
346 hmdf->Instance->SITFCR |= MDF_SITFCR_SITFEN;
347 }
348 }
349
350 if (status == HAL_OK)
351 {
352 /* Configure filter bitstream */
353 hmdf->Instance->BSMXCR &= ~(MDF_BSMXCR_BSSEL);
354 hmdf->Instance->BSMXCR |= hmdf->Init.FilterBistream;
355
356 /* Update instance pointer */
357 v_mdfHandle = hmdf;
358
359 /* Update error code and state */
360 hmdf->ErrorCode = MDF_ERROR_NONE;
361 hmdf->State = HAL_MDF_STATE_READY;
362 }
363 }
364 }
365
366 /* Return function status */
367 return status;
368 }
369
370 /**
371 * @brief De-initialize the MDF instance.
372 * @param hmdf MDF handle.
373 * @retval HAL status.
374 */
HAL_MDF_DeInit(MDF_HandleTypeDef * hmdf)375 HAL_StatusTypeDef HAL_MDF_DeInit(MDF_HandleTypeDef *hmdf)
376 {
377 HAL_StatusTypeDef status = HAL_OK;
378
379 /* Check MDF handle */
380 if (hmdf == NULL)
381 {
382 status = HAL_ERROR;
383 }
384 else
385 {
386 /* Check parameters */
387 assert_param(IS_MDF_ALL_INSTANCE(hmdf->Instance));
388
389 /* Check that instance has not been already deinitialized */
390 if (v_mdfHandle == NULL)
391 {
392 status = HAL_ERROR;
393 }
394 else
395 {
396 /* Disable sound activity detector if needed */
397 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
398 {
399 hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
400 }
401
402 /* Disable filter if needed */
403 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
404 {
405 hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
406 }
407
408 /* Disable serial interface if needed */
409 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) != 0U)
410 {
411 hmdf->Instance->SITFCR &= ~(MDF_SITFCR_SITFEN);
412 }
413
414 /* Disable all interrupts and clear all pending flags */
415 hmdf->Instance->DFLTIER = 0U;
416 hmdf->Instance->DFLTISR = 0xFFFFFFFFU;
417
418 /* Disable clock generator */
419 ADF1->CKGCR &= ~(MDF_CKGCR_CKGDEN);
420
421 /* Call MDF MSP deinit function */
422 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
423 if (hmdf->MspDeInitCallback == NULL)
424 {
425 hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
426 }
427 hmdf->MspDeInitCallback(hmdf);
428 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
429 HAL_MDF_MspDeInit(hmdf);
430 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
431
432 /* Update instance pointer */
433 v_mdfHandle = (MDF_HandleTypeDef *) NULL;
434
435 /* Update state */
436 hmdf->State = HAL_MDF_STATE_RESET;
437 }
438 }
439
440 /* Return function status */
441 return status;
442 }
443
444 /**
445 * @brief Initialize the MDF instance MSP.
446 * @param hmdf MDF handle.
447 * @retval None.
448 */
HAL_MDF_MspInit(MDF_HandleTypeDef * hmdf)449 __weak void HAL_MDF_MspInit(MDF_HandleTypeDef *hmdf)
450 {
451 /* Prevent unused argument(s) compilation warning */
452 UNUSED(hmdf);
453
454 /* NOTE : This function should not be modified, when the function is needed,
455 the HAL_MDF_MspInit could be implemented in the user file */
456 }
457
458 /**
459 * @brief De-initialize the MDF instance MSP.
460 * @param hmdf MDF handle.
461 * @retval None.
462 */
HAL_MDF_MspDeInit(MDF_HandleTypeDef * hmdf)463 __weak void HAL_MDF_MspDeInit(MDF_HandleTypeDef *hmdf)
464 {
465 /* Prevent unused argument(s) compilation warning */
466 UNUSED(hmdf);
467
468 /* NOTE : This function should not be modified, when the function is needed,
469 the HAL_MDF_MspDeInit could be implemented in the user file */
470 }
471
472 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
473 /**
474 * @brief Register a user MDF callback to be used instead of the weak predefined callback.
475 * @param hmdf MDF handle.
476 * @param CallbackID ID of the callback to be registered.
477 * This parameter can be one of the following values:
478 * @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID.
479 * @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID.
480 * @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance).
481 * @arg @ref HAL_MDF_ERROR_CB_ID error callback ID.
482 * @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID.
483 * @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID.
484 * @param pCallback pointer to the callback function.
485 * @retval HAL status.
486 */
HAL_MDF_RegisterCallback(MDF_HandleTypeDef * hmdf,HAL_MDF_CallbackIDTypeDef CallbackID,pMDF_CallbackTypeDef pCallback)487 HAL_StatusTypeDef HAL_MDF_RegisterCallback(MDF_HandleTypeDef *hmdf,
488 HAL_MDF_CallbackIDTypeDef CallbackID,
489 pMDF_CallbackTypeDef pCallback)
490 {
491 HAL_StatusTypeDef status = HAL_OK;
492
493 /* Check parameters */
494 if (pCallback == NULL)
495 {
496 /* Update error code and status */
497 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
498 status = HAL_ERROR;
499 }
500 else
501 {
502 if (hmdf->State == HAL_MDF_STATE_READY)
503 {
504 switch (CallbackID)
505 {
506 case HAL_MDF_ACQ_COMPLETE_CB_ID :
507 hmdf->AcqCpltCallback = pCallback;
508 break;
509 case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID :
510 hmdf->AcqHalfCpltCallback = pCallback;
511 break;
512 case HAL_MDF_SAD_CB_ID :
513 hmdf->SadCallback = pCallback;
514 break;
515 case HAL_MDF_ERROR_CB_ID :
516 hmdf->ErrorCallback = pCallback;
517 break;
518 case HAL_MDF_MSPINIT_CB_ID :
519 hmdf->MspInitCallback = pCallback;
520 break;
521 case HAL_MDF_MSPDEINIT_CB_ID :
522 hmdf->MspDeInitCallback = pCallback;
523 break;
524 default :
525 /* Update error code and status */
526 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
527 status = HAL_ERROR;
528 break;
529 }
530 }
531 else if (hmdf->State == HAL_MDF_STATE_RESET)
532 {
533 switch (CallbackID)
534 {
535 case HAL_MDF_MSPINIT_CB_ID :
536 hmdf->MspInitCallback = pCallback;
537 break;
538 case HAL_MDF_MSPDEINIT_CB_ID :
539 hmdf->MspDeInitCallback = pCallback;
540 break;
541 default :
542 /* Update error code and status */
543 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
544 status = HAL_ERROR;
545 break;
546 }
547 }
548 else
549 {
550 /* Update error code and status */
551 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
552 status = HAL_ERROR;
553 }
554 }
555
556 /* Return function status */
557 return status;
558 }
559
560 /**
561 * @brief Unregister a user MDF callback.
562 * MDF callback is redirected to the weak predefined callback.
563 * @param hmdf MDF handle.
564 * @param CallbackID ID of the callback to be unregistered.
565 * This parameter can be one of the following values:
566 * @arg @ref HAL_MDF_ACQ_COMPLETE_CB_ID acquisition complete callback ID.
567 * @arg @ref HAL_MDF_ACQ_HALFCOMPLETE_CB_ID acquisition half complete callback ID.
568 * @arg @ref HAL_MDF_SAD_CB_ID sound activity detector callback ID (only for ADF instance).
569 * @arg @ref HAL_MDF_ERROR_CB_ID error callback ID.
570 * @arg @ref HAL_MDF_MSPINIT_CB_ID MSP init callback ID.
571 * @arg @ref HAL_MDF_MSPDEINIT_CB_ID MSP de-init callback ID.
572 * @retval HAL status.
573 */
HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef * hmdf,HAL_MDF_CallbackIDTypeDef CallbackID)574 HAL_StatusTypeDef HAL_MDF_UnRegisterCallback(MDF_HandleTypeDef *hmdf,
575 HAL_MDF_CallbackIDTypeDef CallbackID)
576 {
577 HAL_StatusTypeDef status = HAL_OK;
578
579 if (hmdf->State == HAL_MDF_STATE_READY)
580 {
581 switch (CallbackID)
582 {
583 case HAL_MDF_ACQ_COMPLETE_CB_ID :
584 hmdf->AcqCpltCallback = HAL_MDF_AcqCpltCallback;
585 break;
586 case HAL_MDF_ACQ_HALFCOMPLETE_CB_ID :
587 hmdf->AcqHalfCpltCallback = HAL_MDF_AcqHalfCpltCallback;
588 break;
589 case HAL_MDF_SAD_CB_ID :
590 hmdf->SadCallback = HAL_MDF_SadCallback;
591 break;
592 case HAL_MDF_ERROR_CB_ID :
593 hmdf->ErrorCallback = HAL_MDF_ErrorCallback;
594 break;
595 case HAL_MDF_MSPINIT_CB_ID :
596 hmdf->MspInitCallback = HAL_MDF_MspInit;
597 break;
598 case HAL_MDF_MSPDEINIT_CB_ID :
599 hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
600 break;
601 default :
602 /* Update error code and status */
603 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
604 status = HAL_ERROR;
605 break;
606 }
607 }
608 else if (hmdf->State == HAL_MDF_STATE_RESET)
609 {
610 switch (CallbackID)
611 {
612 case HAL_MDF_MSPINIT_CB_ID :
613 hmdf->MspInitCallback = HAL_MDF_MspInit;
614 break;
615 case HAL_MDF_MSPDEINIT_CB_ID :
616 hmdf->MspDeInitCallback = HAL_MDF_MspDeInit;
617 break;
618 default :
619 /* Update error code and status */
620 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
621 status = HAL_ERROR;
622 break;
623 }
624 }
625 else
626 {
627 /* Update error code and status */
628 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
629 status = HAL_ERROR;
630 }
631
632 /* Return function status */
633 return status;
634 }
635
636 /**
637 * @brief Register specific MDF sound level callback
638 * to be used instead of the weak predefined callback.
639 * @param hmdf MDF handle.
640 * @param pCallback pointer to the sound level callback function.
641 * @retval HAL status.
642 */
HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef * hmdf,pMDF_SndLvlCallbackTypeDef pCallback)643 HAL_StatusTypeDef HAL_MDF_RegisterSndLvlCallback(MDF_HandleTypeDef *hmdf,
644 pMDF_SndLvlCallbackTypeDef pCallback)
645 {
646 HAL_StatusTypeDef status = HAL_OK;
647
648 /* Check parameters */
649 if (pCallback == NULL)
650 {
651 /* Update error code and status */
652 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
653 status = HAL_ERROR;
654 }
655 else
656 {
657 if (hmdf->State == HAL_MDF_STATE_READY)
658 {
659 hmdf->SndLvCallback = pCallback;
660 }
661 else
662 {
663 /* Update error code and status */
664 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
665 status = HAL_ERROR;
666 }
667 }
668
669 /* Return function status */
670 return status;
671 }
672
673 /**
674 * @brief Unregister the specific MDF sound level callback.
675 * MDF sound level callback is redirected to the weak predefined callback.
676 * @param hmdf MDF handle.
677 * @retval HAL status.
678 */
HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef * hmdf)679 HAL_StatusTypeDef HAL_MDF_UnRegisterSndLvlCallback(MDF_HandleTypeDef *hmdf)
680 {
681 HAL_StatusTypeDef status = HAL_OK;
682
683 if (hmdf->State == HAL_MDF_STATE_READY)
684 {
685 hmdf->SndLvCallback = HAL_MDF_SndLvlCallback;
686 }
687 else
688 {
689 /* Update error code and status */
690 hmdf->ErrorCode |= MDF_ERROR_INVALID_CALLBACK;
691 status = HAL_ERROR;
692 }
693
694 /* Return function status */
695 return status;
696 }
697 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
698
699 /**
700 * @}
701 */
702
703 /** @defgroup MDF_Exported_Functions_Group2 Acquisition functions
704 * @brief Acquisition functions
705 *
706 @verbatim
707 ==============================================================================
708 ##### Acquisition functions #####
709 ==============================================================================
710 [..] This section provides functions allowing to :
711 (+) Start and stop acquisition in polling, interrupt or DMA mode.
712 (+) Wait and get acquisition values.
713 (+) Generate pulse on TRGO signal.
714 (+) Modify and get some filter parameters during acquisition.
715 (+) Wait and get sound level values.
716 (+) Detect sound activity.
717 @endverbatim
718 * @{
719 */
720
721 /**
722 * @brief This function allows to start acquisition in polling mode.
723 * @param hmdf MDF handle.
724 * @param pFilterConfig Filter configuration parameters.
725 * @retval HAL status.
726 */
HAL_MDF_AcqStart(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig)727 HAL_StatusTypeDef HAL_MDF_AcqStart(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig)
728 {
729 HAL_StatusTypeDef status = HAL_OK;
730
731 /* Check parameters */
732 if (pFilterConfig == NULL)
733 {
734 status = HAL_ERROR;
735 }
736 else
737 {
738 assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
739 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
740 if ((pFilterConfig->SoundActivity.Activation == ENABLE) &&
741 ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
742 (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
743 (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
744 {
745 status = HAL_ERROR;
746 }
747 /* Check state */
748 else if (hmdf->State != HAL_MDF_STATE_READY)
749 {
750 status = HAL_ERROR;
751 }
752 /* Check filter status */
753 else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
754 {
755 status = HAL_ERROR;
756 }
757 else
758 {
759 /* Check SAD status */
760 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
761 {
762 status = HAL_ERROR;
763 }
764 }
765
766 if (status == HAL_OK)
767 {
768 /* Configure filter and start acquisition */
769 hmdf->Instance->DFLTCR = 0U;
770 MDF_AcqStart(hmdf, pFilterConfig);
771 }
772 }
773
774 /* Return function status */
775 return status;
776 }
777
778 /**
779 * @brief This function allows to poll for available acquisition value.
780 * @param hmdf MDF handle.
781 * @param Timeout Timeout value in milliseconds.
782 * @retval HAL status.
783 */
HAL_MDF_PollForAcq(MDF_HandleTypeDef * hmdf,uint32_t Timeout)784 HAL_StatusTypeDef HAL_MDF_PollForAcq(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
785 {
786 HAL_StatusTypeDef status = HAL_OK;
787
788 /* Check state */
789 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
790 {
791 status = HAL_ERROR;
792 }
793 else
794 {
795 uint32_t tickstart = HAL_GetTick();
796
797 /* Wait for available acquisition value */
798 while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_RXNEF) != MDF_DFLTISR_RXNEF) && (status == HAL_OK))
799 {
800 /* Check the timeout */
801 if (Timeout != HAL_MAX_DELAY)
802 {
803 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
804 {
805 status = HAL_TIMEOUT;
806 }
807 }
808 }
809
810 /* Check if data overflow, saturation or reshape filter occurs */
811 uint32_t error_flags = (hmdf->Instance->DFLTISR & (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF));
812 if (error_flags != 0U)
813 {
814 /* Update error code */
815 if ((error_flags & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF)
816 {
817 hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
818 }
819 if ((error_flags & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF)
820 {
821 hmdf->ErrorCode |= MDF_ERROR_SATURATION;
822 }
823 if ((error_flags & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF)
824 {
825 hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN;
826 }
827
828 /* Clear corresponding flags */
829 hmdf->Instance->DFLTISR |= error_flags;
830
831 /* Call error callback */
832 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
833 hmdf->ErrorCallback(hmdf);
834 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
835 HAL_MDF_ErrorCallback(hmdf);
836 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
837 }
838
839 if (status == HAL_OK)
840 {
841 /* Update state only in asynchronous single shot mode */
842 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE)
843 {
844 hmdf->State = HAL_MDF_STATE_READY;
845 }
846 }
847 }
848
849 /* Return function status */
850 return status;
851 }
852
853 /**
854 * @brief This function allows to get acquisition value.
855 * @param hmdf MDF handle.
856 * @param pValue Acquisition value on 24 MSB.
857 * @retval HAL status.
858 */
HAL_MDF_GetAcqValue(const MDF_HandleTypeDef * hmdf,int32_t * pValue)859 HAL_StatusTypeDef HAL_MDF_GetAcqValue(const MDF_HandleTypeDef *hmdf, int32_t *pValue)
860 {
861 HAL_StatusTypeDef status = HAL_OK;
862
863 /* Check parameters */
864 if (pValue == NULL)
865 {
866 status = HAL_ERROR;
867 }
868 else
869 {
870 /* Check state */
871 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
872 {
873 if (hmdf->State != HAL_MDF_STATE_READY)
874 {
875 status = HAL_ERROR;
876 }
877 }
878 }
879
880 if (status == HAL_OK)
881 {
882 /* Get acquisition value */
883 *pValue = (int32_t) hmdf->Instance->DFLTDR;
884 }
885
886 /* Return function status */
887 return status;
888 }
889
890 /**
891 * @brief This function allows to stop acquisition in polling mode.
892 * @param hmdf MDF handle.
893 * @retval HAL status.
894 */
HAL_MDF_AcqStop(MDF_HandleTypeDef * hmdf)895 HAL_StatusTypeDef HAL_MDF_AcqStop(MDF_HandleTypeDef *hmdf)
896 {
897 HAL_StatusTypeDef status = HAL_OK;
898
899 /* Check state */
900 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
901 {
902 /* Check if state is ready and filter active */
903 if (hmdf->State == HAL_MDF_STATE_READY)
904 {
905 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
906 {
907 status = HAL_ERROR;
908 }
909 }
910 else
911 {
912 status = HAL_ERROR;
913 }
914 }
915 else
916 {
917 /* Disable sound activity detector if needed */
918 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
919 {
920 hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
921 }
922 }
923
924 if (status == HAL_OK)
925 {
926 /* Disable filter */
927 hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
928
929 /* Clear all potential pending flags */
930 hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF |
931 MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF);
932
933 /* Update state */
934 hmdf->State = HAL_MDF_STATE_READY;
935 }
936
937 /* Return function status */
938 return status;
939 }
940
941 /**
942 * @brief This function allows to start acquisition in interrupt mode.
943 * @param hmdf MDF handle.
944 * @param pFilterConfig Filter configuration parameters.
945 * @retval HAL status.
946 */
HAL_MDF_AcqStart_IT(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig)947 HAL_StatusTypeDef HAL_MDF_AcqStart_IT(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig)
948 {
949 HAL_StatusTypeDef status = HAL_OK;
950
951 /* Check parameters */
952 if (pFilterConfig == NULL)
953 {
954 status = HAL_ERROR;
955 }
956 else
957 {
958 assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
959 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
960 if ((pFilterConfig->SoundActivity.Activation == ENABLE) &&
961 ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
962 (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
963 (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
964 {
965 status = HAL_ERROR;
966 }
967 /* Check state */
968 else if (hmdf->State != HAL_MDF_STATE_READY)
969 {
970 status = HAL_ERROR;
971 }
972 /* Check filter status */
973 else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
974 {
975 status = HAL_ERROR;
976 }
977 else
978 {
979 /* Check SAD status */
980 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
981 {
982 status = HAL_ERROR;
983 }
984 }
985
986 if (status == HAL_OK)
987 {
988 if ((pFilterConfig->SoundActivity.Activation == DISABLE) ||
989 (pFilterConfig->SoundActivity.DataMemoryTransfer != MDF_SAD_NO_MEMORY_TRANSFER))
990 {
991 /* Enable data overflow and fifo threshold interrupts */
992 hmdf->Instance->DFLTIER |= (MDF_DFLTIER_DOVRIE | MDF_DFLTIER_FTHIE);
993 }
994
995 if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
996 {
997 /* Enable reshape filter overrun interrupt */
998 hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE;
999 }
1000
1001 /* Enable saturation interrupt */
1002 hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE;
1003
1004 if (pFilterConfig->SoundActivity.Activation == ENABLE)
1005 {
1006 /* Enable sound level value ready and sound activity detection interrupts */
1007 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt));
1008 hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ?
1009 (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) :
1010 MDF_DFLTIER_SDDETIE;
1011 }
1012
1013 /* Configure filter and start acquisition */
1014 hmdf->Instance->DFLTCR = 0U;
1015 MDF_AcqStart(hmdf, pFilterConfig);
1016 }
1017 }
1018
1019 /* Return function status */
1020 return status;
1021 }
1022
1023 /**
1024 * @brief This function allows to stop acquisition in interrupt mode.
1025 * @param hmdf MDF handle.
1026 * @retval HAL status.
1027 */
HAL_MDF_AcqStop_IT(MDF_HandleTypeDef * hmdf)1028 HAL_StatusTypeDef HAL_MDF_AcqStop_IT(MDF_HandleTypeDef *hmdf)
1029 {
1030 HAL_StatusTypeDef status = HAL_OK;
1031
1032 /* Check state */
1033 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1034 {
1035 /* Check if state is ready and filter active */
1036 if (hmdf->State == HAL_MDF_STATE_READY)
1037 {
1038 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
1039 {
1040 status = HAL_ERROR;
1041 }
1042 }
1043 else
1044 {
1045 status = HAL_ERROR;
1046 }
1047 }
1048 else
1049 {
1050 /* Disable sound activity detector if needed */
1051 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1052 {
1053 hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
1054 }
1055 }
1056
1057 if (status == HAL_OK)
1058 {
1059 /* Disable filter */
1060 hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
1061
1062 /* Disable interrupts and clear all potential pending flags */
1063 hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_FTHIE | MDF_DFLTIER_DOVRIE | MDF_DFLTIER_SATIE |
1064 MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE | MDF_DFLTIER_SDLVLIE);
1065 hmdf->Instance->DFLTISR |= (MDF_DFLTISR_DOVRF | MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF |
1066 MDF_DFLTISR_SDDETF | MDF_DFLTISR_SDLVLF);
1067
1068 /* Update state */
1069 hmdf->State = HAL_MDF_STATE_READY;
1070 }
1071
1072 /* Return function status */
1073 return status;
1074 }
1075
1076 /**
1077 * @brief This function allows to start acquisition in DMA mode.
1078 * @param hmdf MDF handle.
1079 * @param pFilterConfig Filter configuration parameters.
1080 * @param pDmaConfig DMA configuration parameters.
1081 * @retval HAL status.
1082 */
HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef * hmdf,const MDF_FilterConfigTypeDef * pFilterConfig,const MDF_DmaConfigTypeDef * pDmaConfig)1083 HAL_StatusTypeDef HAL_MDF_AcqStart_DMA(MDF_HandleTypeDef *hmdf, const MDF_FilterConfigTypeDef *pFilterConfig,
1084 const MDF_DmaConfigTypeDef *pDmaConfig)
1085 {
1086 HAL_StatusTypeDef status = HAL_OK;
1087
1088 /* Check parameters */
1089 if ((pFilterConfig == NULL) || (pDmaConfig == NULL))
1090 {
1091 status = HAL_ERROR;
1092 }
1093 else
1094 {
1095 assert_param(IS_FUNCTIONAL_STATE(pDmaConfig->MsbOnly));
1096 assert_param(IS_MDF_ACQUISITION_MODE(pFilterConfig->AcquisitionMode));
1097 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
1098 if ((pFilterConfig->SoundActivity.Activation == ENABLE) &&
1099 ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE) ||
1100 (pFilterConfig->AcquisitionMode == MDF_MODE_SYNC_SINGLE) ||
1101 (pFilterConfig->AcquisitionMode == MDF_MODE_WINDOW_CONT)))
1102 {
1103 status = HAL_ERROR;
1104 }
1105 /* Check state */
1106 else if (hmdf->State != HAL_MDF_STATE_READY)
1107 {
1108 status = HAL_ERROR;
1109 }
1110 /* Check filter status */
1111 else if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != 0U)
1112 {
1113 status = HAL_ERROR;
1114 }
1115 else
1116 {
1117 /* Check SAD status */
1118 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1119 {
1120 status = HAL_ERROR;
1121 }
1122 }
1123
1124 if (status == HAL_OK)
1125 {
1126 uint32_t SrcAddress;
1127
1128 if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
1129 {
1130 /* Enable reshape filter overrun interrupt */
1131 hmdf->Instance->DFLTIER |= MDF_DFLTIER_RFOVRIE;
1132 }
1133
1134 /* Enable saturation interrupt */
1135 hmdf->Instance->DFLTIER |= MDF_DFLTIER_SATIE;
1136
1137 if (pFilterConfig->SoundActivity.Activation == ENABLE)
1138 {
1139 /* Enable sound level value ready and sound activity detection interrupts */
1140 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.SoundLevelInterrupt));
1141 hmdf->Instance->DFLTIER |= (pFilterConfig->SoundActivity.SoundLevelInterrupt == ENABLE) ?
1142 (MDF_DFLTIER_SDLVLIE | MDF_DFLTIER_SDDETIE) :
1143 MDF_DFLTIER_SDDETIE;
1144 }
1145
1146 /* Enable MDF DMA requests */
1147 hmdf->Instance->DFLTCR = MDF_DFLTCR_DMAEN;
1148
1149 /* Start DMA transfer */
1150 hmdf->hdma->XferCpltCallback = MDF_DmaXferCpltCallback;
1151 hmdf->hdma->XferHalfCpltCallback = MDF_DmaXferHalfCpltCallback;
1152 hmdf->hdma->XferErrorCallback = MDF_DmaErrorCallback;
1153 SrcAddress = (pDmaConfig->MsbOnly == ENABLE) ? (((uint32_t) &hmdf->Instance->DFLTDR) + 2U) :
1154 (uint32_t) &hmdf->Instance->DFLTDR;
1155 if ((hmdf->hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1156 {
1157 if (hmdf->hdma->LinkedListQueue != NULL)
1158 {
1159 hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] = pDmaConfig->DataLength;
1160 hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] = SrcAddress;
1161 hmdf->hdma->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] = pDmaConfig->Address;
1162
1163 status = HAL_DMAEx_List_Start_IT(hmdf->hdma);
1164 }
1165 else
1166 {
1167 status = HAL_ERROR;
1168 }
1169 }
1170 else
1171 {
1172 status = HAL_DMA_Start_IT(hmdf->hdma, SrcAddress, pDmaConfig->Address, pDmaConfig->DataLength);
1173 }
1174 if (status != HAL_OK)
1175 {
1176 /* Update state */
1177 hmdf->State = HAL_MDF_STATE_ERROR;
1178 status = HAL_ERROR;
1179 }
1180 else
1181 {
1182 /* Configure filter and start acquisition */
1183 MDF_AcqStart(hmdf, pFilterConfig);
1184 }
1185 }
1186 }
1187
1188 /* Return function status */
1189 return status;
1190 }
1191
1192 /**
1193 * @brief This function allows to stop acquisition in DMA mode.
1194 * @param hmdf MDF handle.
1195 * @retval HAL status.
1196 */
HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef * hmdf)1197 HAL_StatusTypeDef HAL_MDF_AcqStop_DMA(MDF_HandleTypeDef *hmdf)
1198 {
1199 HAL_StatusTypeDef status = HAL_OK;
1200
1201 /* Check if state is ready and filter active */
1202 if (hmdf->State == HAL_MDF_STATE_READY)
1203 {
1204 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_DFLTACTIVE) != MDF_DFLTCR_DFLTACTIVE)
1205 {
1206 status = HAL_ERROR;
1207 }
1208 }
1209 else
1210 {
1211 /* Check state */
1212 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1213 {
1214 status = HAL_ERROR;
1215 }
1216 else
1217 {
1218 /* Stop the DMA transfer */
1219 if (HAL_DMA_Abort(hmdf->hdma) != HAL_OK)
1220 {
1221 /* Update state */
1222 hmdf->State = HAL_MDF_STATE_ERROR;
1223 status = HAL_ERROR;
1224 }
1225 }
1226 }
1227
1228 if (status == HAL_OK)
1229 {
1230 /* Disable sound activity detector if needed */
1231 if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) != 0U)
1232 {
1233 hmdf->Instance->SADCR &= ~(MDF_SADCR_SADEN);
1234 }
1235
1236 /* Disable filter */
1237 hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DFLTEN);
1238
1239 /* Disable interrupts and clear all potential pending flags */
1240 hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_SATIE | MDF_DFLTIER_RFOVRIE | MDF_DFLTIER_SDDETIE |
1241 MDF_DFLTIER_SDLVLIE);
1242 hmdf->Instance->DFLTISR |= (MDF_DFLTISR_SATF | MDF_DFLTISR_RFOVRF | MDF_DFLTISR_SDDETF |
1243 MDF_DFLTISR_SDLVLF);
1244
1245 /* Disable MDF DMA requests */
1246 hmdf->Instance->DFLTCR &= ~(MDF_DFLTCR_DMAEN);
1247
1248 /* Update state */
1249 hmdf->State = HAL_MDF_STATE_READY;
1250 }
1251
1252 /* Return function status */
1253 return status;
1254 }
1255
1256 /**
1257 * @brief This function allows to generate pulse on TRGO signal.
1258 * @param hmdf MDF handle.
1259 * @retval HAL status.
1260 */
HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef * hmdf)1261 HAL_StatusTypeDef HAL_MDF_GenerateTrgo(const MDF_HandleTypeDef *hmdf)
1262 {
1263 HAL_StatusTypeDef status = HAL_OK;
1264
1265 /* Check state */
1266 if (hmdf->State != HAL_MDF_STATE_READY)
1267 {
1268 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1269 {
1270 status = HAL_ERROR;
1271 }
1272 }
1273
1274 if (status == HAL_OK)
1275 {
1276 /* Check if trigger output control is already active */
1277 if ((ADF1->GCR & MDF_GCR_TRGO) == MDF_GCR_TRGO)
1278 {
1279 status = HAL_ERROR;
1280 }
1281 else
1282 {
1283 /* Generate pulse on trigger output control signal */
1284 ADF1->GCR |= MDF_GCR_TRGO;
1285 }
1286 }
1287
1288 /* Return function status */
1289 return status;
1290 }
1291
1292 /**
1293 * @brief This function allows to set delay to apply on data source in number of samples.
1294 * @param hmdf MDF handle.
1295 * @param Delay Delay to apply on data source in number of samples.
1296 * This parameter must be a number between Min_Data = 0 and Max_Data = 127.
1297 * @retval HAL status.
1298 */
HAL_MDF_SetDelay(MDF_HandleTypeDef * hmdf,uint32_t Delay)1299 HAL_StatusTypeDef HAL_MDF_SetDelay(MDF_HandleTypeDef *hmdf, uint32_t Delay)
1300 {
1301 HAL_StatusTypeDef status = HAL_OK;
1302
1303 /* Check parameters */
1304 assert_param(IS_MDF_DELAY(Delay));
1305
1306 /* Check state */
1307 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1308 {
1309 status = HAL_ERROR;
1310 }
1311 else
1312 {
1313 /* Check if bitstream delay is already active */
1314 if ((hmdf->Instance->DLYCR & MDF_DLYCR_SKPBF) == MDF_DLYCR_SKPBF)
1315 {
1316 status = HAL_ERROR;
1317 }
1318 else
1319 {
1320 /* Configure bitstream delay */
1321 hmdf->Instance->DLYCR |= Delay;
1322 }
1323 }
1324
1325 /* Return function status */
1326 return status;
1327 }
1328
1329 /**
1330 * @brief This function allows to get current delay applied on data source in number of samples.
1331 * @param hmdf MDF handle.
1332 * @param pDelay Current delay applied on data source in number of samples.
1333 * This value is between Min_Data = 0 and Max_Data = 127.
1334 * @retval HAL status.
1335 */
HAL_MDF_GetDelay(const MDF_HandleTypeDef * hmdf,uint32_t * pDelay)1336 HAL_StatusTypeDef HAL_MDF_GetDelay(const MDF_HandleTypeDef *hmdf, uint32_t *pDelay)
1337 {
1338 HAL_StatusTypeDef status = HAL_OK;
1339
1340 /* Check parameters */
1341 if (pDelay == NULL)
1342 {
1343 status = HAL_ERROR;
1344 }
1345 /* Check state */
1346 else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1347 {
1348 status = HAL_ERROR;
1349 }
1350 else
1351 {
1352 /* Get current bitstream delay */
1353 *pDelay = (hmdf->Instance->DLYCR & MDF_DLYCR_SKPDLY);
1354 }
1355
1356 /* Return function status */
1357 return status;
1358 }
1359
1360 /**
1361 * @brief This function allows to set filter gain.
1362 * @param hmdf MDF handle.
1363 * @param Gain Filter gain in step of around 3db (from -48db to 72dB).
1364 * This parameter must be a number between Min_Data = -16 and Max_Data = 24.
1365 * @retval HAL status.
1366 */
HAL_MDF_SetGain(MDF_HandleTypeDef * hmdf,int32_t Gain)1367 HAL_StatusTypeDef HAL_MDF_SetGain(MDF_HandleTypeDef *hmdf, int32_t Gain)
1368 {
1369 HAL_StatusTypeDef status = HAL_OK;
1370
1371 /* Check parameters */
1372 assert_param(IS_MDF_GAIN(Gain));
1373
1374 /* Check state */
1375 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1376 {
1377 status = HAL_ERROR;
1378 }
1379 else
1380 {
1381 uint32_t register_gain_value;
1382 uint32_t tmp_register;
1383
1384 if (Gain < 0)
1385 {
1386 int32_t adjust_gain;
1387
1388 /* adjust gain value to set on register for negative value (offset of -16) */
1389 adjust_gain = Gain - 16;
1390 register_gain_value = ((uint32_t) adjust_gain & 0x3FU);
1391 }
1392 else
1393 {
1394 /* for positive value, no offset to apply */
1395 register_gain_value = (uint32_t) Gain;
1396 }
1397 /* Set gain */
1398 tmp_register = (hmdf->Instance->DFLTCICR & ~(MDF_DFLTCICR_SCALE));
1399 hmdf->Instance->DFLTCICR = (tmp_register | (register_gain_value << MDF_DFLTCICR_SCALE_Pos));
1400 }
1401
1402 /* Return function status */
1403 return status;
1404 }
1405
1406 /**
1407 * @brief This function allows to get filter gain.
1408 * @param hmdf MDF handle.
1409 * @param pGain Filter gain in step of around 3db (from -48db to 72dB).
1410 * This parameter is between Min_Data = -16 and Max_Data = 24.
1411 * @retval HAL status.
1412 */
HAL_MDF_GetGain(const MDF_HandleTypeDef * hmdf,int32_t * pGain)1413 HAL_StatusTypeDef HAL_MDF_GetGain(const MDF_HandleTypeDef *hmdf, int32_t *pGain)
1414 {
1415 HAL_StatusTypeDef status = HAL_OK;
1416
1417 /* Check parameters */
1418 if (pGain == NULL)
1419 {
1420 status = HAL_ERROR;
1421 }
1422 /* Check state */
1423 else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1424 {
1425 status = HAL_ERROR;
1426 }
1427 else
1428 {
1429 uint32_t register_gain_value;
1430
1431 /* Get current gain */
1432 register_gain_value = ((hmdf->Instance->DFLTCICR & MDF_DFLTCICR_SCALE) >> MDF_DFLTCICR_SCALE_Pos);
1433 if (register_gain_value > 31U)
1434 {
1435 /* adjust gain value to set on register for negative value (offset of +16) */
1436 register_gain_value |= 0xFFFFFFC0U;
1437 *pGain = (int32_t) register_gain_value + 16;
1438 }
1439 else
1440 {
1441 /* for positive value, no offset to apply */
1442 *pGain = (int32_t) register_gain_value;
1443 }
1444 }
1445
1446 /* Return function status */
1447 return status;
1448 }
1449
1450 /**
1451 * @brief This function allows to poll for sound level data.
1452 * @param hmdf MDF handle.
1453 * @param Timeout Timeout value in milliseconds.
1454 * @param pSoundLevel Sound level.
1455 This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1456 * @param pAmbientNoise Ambient noise.
1457 This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1458 * @retval HAL status.
1459 */
HAL_MDF_PollForSndLvl(MDF_HandleTypeDef * hmdf,uint32_t Timeout,uint32_t * pSoundLevel,uint32_t * pAmbientNoise)1460 HAL_StatusTypeDef HAL_MDF_PollForSndLvl(MDF_HandleTypeDef *hmdf, uint32_t Timeout, uint32_t *pSoundLevel,
1461 uint32_t *pAmbientNoise)
1462 {
1463 HAL_StatusTypeDef status = HAL_OK;
1464
1465 /* Check parameters */
1466 if ((pSoundLevel == NULL) || (pAmbientNoise == NULL))
1467 {
1468 status = HAL_ERROR;
1469 }
1470 /* Check state */
1471 else if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1472 {
1473 status = HAL_ERROR;
1474 }
1475 /* Check SAD status */
1476 else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U)
1477 {
1478 status = HAL_ERROR;
1479 }
1480 else
1481 {
1482 uint32_t tickstart = HAL_GetTick();
1483
1484 /* Wait for available sound level data */
1485 while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDLVLF) != MDF_DFLTISR_SDLVLF) && (status == HAL_OK))
1486 {
1487 /* Check the timeout */
1488 if (Timeout != HAL_MAX_DELAY)
1489 {
1490 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1491 {
1492 status = HAL_TIMEOUT;
1493 }
1494 }
1495 }
1496
1497 if (status == HAL_OK)
1498 {
1499 /* Get sound level */
1500 *pSoundLevel = hmdf->Instance->SADSDLVR;
1501
1502 /* Get ambient noise */
1503 *pAmbientNoise = hmdf->Instance->SADANLVR;
1504
1505 /* Clear sound level ready flag */
1506 hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF;
1507 }
1508 }
1509
1510 /* Return function status */
1511 return status;
1512 }
1513
1514 /**
1515 * @brief This function allows to poll for sound activity detection.
1516 * @param hmdf MDF handle.
1517 * @param Timeout Timeout value in milliseconds.
1518 * @retval HAL status.
1519 */
HAL_MDF_PollForSad(MDF_HandleTypeDef * hmdf,uint32_t Timeout)1520 HAL_StatusTypeDef HAL_MDF_PollForSad(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
1521 {
1522 HAL_StatusTypeDef status = HAL_OK;
1523
1524 /* Check state */
1525 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1526 {
1527 status = HAL_ERROR;
1528 }
1529 /* Check SAD status */
1530 else if ((hmdf->Instance->SADCR & MDF_SADCR_SADACTIVE) == 0U)
1531 {
1532 status = HAL_ERROR;
1533 }
1534 else
1535 {
1536 uint32_t tickstart = HAL_GetTick();
1537
1538 /* Wait for sound activity detection */
1539 while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_SDDETF) != MDF_DFLTISR_SDDETF) && (status == HAL_OK))
1540 {
1541 /* Check the timeout */
1542 if (Timeout != HAL_MAX_DELAY)
1543 {
1544 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1545 {
1546 status = HAL_TIMEOUT;
1547 }
1548 }
1549 }
1550
1551 if (status == HAL_OK)
1552 {
1553 /* Clear sound activity detection flag */
1554 hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF;
1555 }
1556 }
1557
1558 /* Return function status */
1559 return status;
1560 }
1561
1562 /**
1563 * @brief MDF acquisition complete callback.
1564 * @param hmdf MDF handle.
1565 * @retval None.
1566 */
HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef * hmdf)1567 __weak void HAL_MDF_AcqCpltCallback(MDF_HandleTypeDef *hmdf)
1568 {
1569 /* Prevent unused argument(s) compilation warning */
1570 UNUSED(hmdf);
1571
1572 /* NOTE : This function should not be modified, when the function is needed,
1573 the HAL_MDF_AcqCpltCallback could be implemented in the user file */
1574 }
1575
1576 /**
1577 * @brief MDF acquisition half complete callback.
1578 * @param hmdf MDF handle.
1579 * @retval None.
1580 */
HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef * hmdf)1581 __weak void HAL_MDF_AcqHalfCpltCallback(MDF_HandleTypeDef *hmdf)
1582 {
1583 /* Prevent unused argument(s) compilation warning */
1584 UNUSED(hmdf);
1585
1586 /* NOTE : This function should not be modified, when the function is needed,
1587 the HAL_MDF_AcqHalfCpltCallback could be implemented in the user file */
1588 }
1589
1590 /**
1591 * @brief MDF sound level callback.
1592 * @param hmdf MDF handle.
1593 * @param SoundLevel Sound level value computed by sound activity detector.
1594 * This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1595 * @param AmbientNoise Ambient noise value computed by sound activity detector.
1596 * This parameter can be a value between Min_Data = 0 and Max_Data = 32767.
1597 * @retval None.
1598 */
HAL_MDF_SndLvlCallback(MDF_HandleTypeDef * hmdf,uint32_t SoundLevel,uint32_t AmbientNoise)1599 __weak void HAL_MDF_SndLvlCallback(MDF_HandleTypeDef *hmdf, uint32_t SoundLevel, uint32_t AmbientNoise)
1600 {
1601 /* Prevent unused argument(s) compilation warning */
1602 UNUSED(hmdf);
1603 UNUSED(SoundLevel);
1604 UNUSED(AmbientNoise);
1605
1606 /* NOTE : This function should not be modified, when the function is needed,
1607 the HAL_MDF_SndLvlCallback could be implemented in the user file */
1608 }
1609
1610 /**
1611 * @brief MDF sound activity detector callback.
1612 * @param hmdf MDF handle.
1613 * @retval None.
1614 */
HAL_MDF_SadCallback(MDF_HandleTypeDef * hmdf)1615 __weak void HAL_MDF_SadCallback(MDF_HandleTypeDef *hmdf)
1616 {
1617 /* Prevent unused argument(s) compilation warning */
1618 UNUSED(hmdf);
1619
1620 /* NOTE : This function should not be modified, when the function is needed,
1621 the HAL_MDF_SadCallback could be implemented in the user file */
1622 }
1623
1624 /**
1625 * @}
1626 */
1627
1628 /** @defgroup MDF_Exported_Functions_Group3 Clock absence detection functions
1629 * @brief Clock absence detection functions
1630 *
1631 @verbatim
1632 ==============================================================================
1633 ##### Clock absence detection functions #####
1634 ==============================================================================
1635 [..] This section provides functions allowing to :
1636 (+) Start and stop clock absence detection in interrupt mode.
1637 (+) Detect clock absence.
1638 @endverbatim
1639 * @{
1640 */
1641
1642 /**
1643 * @brief This function allows to poll for the clock absence detection.
1644 * @param hmdf MDF handle.
1645 * @param Timeout Timeout value in milliseconds.
1646 * @retval HAL status.
1647 */
HAL_MDF_PollForCkab(MDF_HandleTypeDef * hmdf,uint32_t Timeout)1648 HAL_StatusTypeDef HAL_MDF_PollForCkab(MDF_HandleTypeDef *hmdf, uint32_t Timeout)
1649 {
1650 HAL_StatusTypeDef status = HAL_OK;
1651
1652 /* Check state */
1653 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1654 {
1655 if (hmdf->State != HAL_MDF_STATE_READY)
1656 {
1657 status = HAL_ERROR;
1658 }
1659 }
1660
1661 if (status == HAL_OK)
1662 {
1663 /* Check serial interface status and mode */
1664 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
1665 {
1666 status = HAL_ERROR;
1667 }
1668 else
1669 {
1670 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
1671 {
1672 status = HAL_ERROR;
1673 }
1674 }
1675 }
1676
1677 if (status == HAL_OK)
1678 {
1679 uint32_t tickstart = HAL_GetTick();
1680
1681 /* Wait for clock absence detection */
1682 while (((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) != MDF_DFLTISR_CKABF) && (status == HAL_OK))
1683 {
1684 /* Check the timeout */
1685 if (Timeout != HAL_MAX_DELAY)
1686 {
1687 if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
1688 {
1689 status = HAL_TIMEOUT;
1690 }
1691 }
1692 }
1693
1694 if (status == HAL_OK)
1695 {
1696 /* Clear clock absence detection flag */
1697 hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
1698 }
1699 }
1700
1701 /* Return function status */
1702 return status;
1703 }
1704
1705 /**
1706 * @brief This function allows to start clock absence detection in interrupt mode.
1707 * @param hmdf MDF handle.
1708 * @retval HAL status.
1709 */
HAL_MDF_CkabStart_IT(MDF_HandleTypeDef * hmdf)1710 HAL_StatusTypeDef HAL_MDF_CkabStart_IT(MDF_HandleTypeDef *hmdf)
1711 {
1712 HAL_StatusTypeDef status = HAL_OK;
1713
1714 /* Check state */
1715 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1716 {
1717 if (hmdf->State != HAL_MDF_STATE_READY)
1718 {
1719 status = HAL_ERROR;
1720 }
1721 }
1722
1723 if (status == HAL_OK)
1724 {
1725 /* Check serial interface status and mode */
1726 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
1727 {
1728 status = HAL_ERROR;
1729 }
1730 else
1731 {
1732 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
1733 {
1734 status = HAL_ERROR;
1735 }
1736 }
1737 }
1738
1739 if (status == HAL_OK)
1740 {
1741 /* Clear clock absence detection flag */
1742 hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
1743
1744 /* Check clock absence detection flag */
1745 if ((hmdf->Instance->DFLTISR & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF)
1746 {
1747 status = HAL_ERROR;
1748 }
1749 else
1750 {
1751 /* Enable clock absence detection interrupt */
1752 hmdf->Instance->DFLTIER |= MDF_DFLTIER_CKABIE;
1753 }
1754 }
1755
1756 /* Return function status */
1757 return status;
1758 }
1759
1760 /**
1761 * @brief This function allows to stop clock absence detection in interrupt mode.
1762 * @param hmdf MDF handle.
1763 * @retval HAL status.
1764 */
HAL_MDF_CkabStop_IT(MDF_HandleTypeDef * hmdf)1765 HAL_StatusTypeDef HAL_MDF_CkabStop_IT(MDF_HandleTypeDef *hmdf)
1766 {
1767 HAL_StatusTypeDef status = HAL_OK;
1768
1769 /* Check state */
1770 if (hmdf->State != HAL_MDF_STATE_ACQUISITION)
1771 {
1772 if (hmdf->State != HAL_MDF_STATE_READY)
1773 {
1774 status = HAL_ERROR;
1775 }
1776 }
1777
1778 if (status == HAL_OK)
1779 {
1780 /* Check serial interface status and mode */
1781 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFACTIVE) == 0U)
1782 {
1783 status = HAL_ERROR;
1784 }
1785 else
1786 {
1787 if ((hmdf->Instance->SITFCR & MDF_SITFCR_SITFMOD) != MDF_SITF_NORMAL_SPI_MODE)
1788 {
1789 status = HAL_ERROR;
1790 }
1791 }
1792 }
1793
1794 if (status == HAL_OK)
1795 {
1796 /* Disable clock absence detection interrupt */
1797 hmdf->Instance->DFLTIER &= ~(MDF_DFLTIER_CKABIE);
1798
1799 /* Clear potential pending clock absence detection flag */
1800 hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
1801 }
1802
1803 /* Return function status */
1804 return status;
1805 }
1806
1807 /**
1808 * @}
1809 */
1810
1811 /** @defgroup MDF_Exported_Functions_Group4 Generic functions
1812 * @brief Generic functions
1813 *
1814 @verbatim
1815 ==============================================================================
1816 ##### Generic functions #####
1817 ==============================================================================
1818 [..] This section provides functions allowing to :
1819 (+) Handle MDF interrupt.
1820 (+) Inform user that error occurs.
1821 (+) Get the current MDF instance state.
1822 (+) Get the current MDF instance error code.
1823 @endverbatim
1824 * @{
1825 */
1826
1827 /**
1828 * @brief This function handles the MDF interrupts.
1829 * @param hmdf MDF handle.
1830 * @retval None.
1831 */
HAL_MDF_IRQHandler(MDF_HandleTypeDef * hmdf)1832 void HAL_MDF_IRQHandler(MDF_HandleTypeDef *hmdf)
1833 {
1834 uint32_t tmp_reg1;
1835 uint32_t tmp_reg2;
1836 uint32_t interrupts;
1837
1838 /* Read current flags and interrupts and determine which ones occur */
1839 tmp_reg1 = hmdf->Instance->DFLTIER;
1840 tmp_reg2 = hmdf->Instance->DFLTISR;
1841 interrupts = (tmp_reg1 & tmp_reg2);
1842
1843 /* Check if data overflow occurs */
1844 if ((interrupts & MDF_DFLTISR_DOVRF) == MDF_DFLTISR_DOVRF)
1845 {
1846 /* Clear data overflow flag */
1847 hmdf->Instance->DFLTISR |= MDF_DFLTISR_DOVRF;
1848
1849 /* Update error code */
1850 hmdf->ErrorCode |= MDF_ERROR_ACQUISITION_OVERFLOW;
1851
1852 /* Call error callback */
1853 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1854 hmdf->ErrorCallback(hmdf);
1855 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1856 HAL_MDF_ErrorCallback(hmdf);
1857 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1858 }
1859 /* Check if RXFIFO threshold occurs */
1860 else if ((interrupts & MDF_DFLTISR_FTHF) == MDF_DFLTISR_FTHF)
1861 {
1862 /* Call acquisition complete callback */
1863 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1864 hmdf->AcqCpltCallback(hmdf);
1865 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1866 HAL_MDF_AcqCpltCallback(hmdf);
1867 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1868
1869 /* Update state only in asynchronous single shot mode */
1870 if ((hmdf->Instance->DFLTCR & MDF_DFLTCR_ACQMOD) == MDF_MODE_ASYNC_SINGLE)
1871 {
1872 hmdf->State = HAL_MDF_STATE_READY;
1873 }
1874 }
1875 /* Check if reshape filter overrun occurs */
1876 else if ((interrupts & MDF_DFLTISR_RFOVRF) == MDF_DFLTISR_RFOVRF)
1877 {
1878 /* Clear reshape filter overrun flag */
1879 hmdf->Instance->DFLTISR |= MDF_DFLTISR_RFOVRF;
1880
1881 /* Update error code */
1882 hmdf->ErrorCode |= MDF_ERROR_RSF_OVERRUN;
1883
1884 /* Call error callback */
1885 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1886 hmdf->ErrorCallback(hmdf);
1887 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1888 HAL_MDF_ErrorCallback(hmdf);
1889 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1890 }
1891 /* Check if clock absence detection occurs */
1892 else if ((interrupts & MDF_DFLTISR_CKABF) == MDF_DFLTISR_CKABF)
1893 {
1894 /* Clear clock absence detection flag */
1895 hmdf->Instance->DFLTISR |= MDF_DFLTISR_CKABF;
1896
1897 /* Update error code */
1898 hmdf->ErrorCode |= MDF_ERROR_CLOCK_ABSENCE;
1899
1900 /* Call error callback */
1901 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1902 hmdf->ErrorCallback(hmdf);
1903 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1904 HAL_MDF_ErrorCallback(hmdf);
1905 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1906 }
1907 /* Check if saturation occurs */
1908 else if ((interrupts & MDF_DFLTISR_SATF) == MDF_DFLTISR_SATF)
1909 {
1910 /* Clear saturation flag */
1911 hmdf->Instance->DFLTISR |= MDF_DFLTISR_SATF;
1912
1913 /* Update error code */
1914 hmdf->ErrorCode |= MDF_ERROR_SATURATION;
1915
1916 /* Call error callback */
1917 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1918 hmdf->ErrorCallback(hmdf);
1919 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1920 HAL_MDF_ErrorCallback(hmdf);
1921 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1922 }
1923 /* Check if sound activity detection occurs */
1924 else if ((interrupts & MDF_DFLTISR_SDDETF) == MDF_DFLTISR_SDDETF)
1925 {
1926 /* Clear sound activity detection flag */
1927 hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDDETF;
1928
1929 /* Call sound activity detection callback */
1930 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1931 hmdf->SadCallback(hmdf);
1932 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1933 HAL_MDF_SadCallback(hmdf);
1934 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1935 }
1936 else
1937 {
1938 /* Check if sound level ready occurs */
1939 if ((interrupts & MDF_DFLTISR_SDLVLF) == MDF_DFLTISR_SDLVLF)
1940 {
1941 uint32_t sound_level;
1942 uint32_t ambient_noise;
1943
1944 /* Get sound level */
1945 sound_level = hmdf->Instance->SADSDLVR;
1946
1947 /* Get ambient noise */
1948 ambient_noise = hmdf->Instance->SADANLVR;
1949
1950 /* Clear sound level ready flag */
1951 hmdf->Instance->DFLTISR |= MDF_DFLTISR_SDLVLF;
1952
1953 /* Call sound level callback */
1954 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
1955 hmdf->SndLvCallback(hmdf, sound_level, ambient_noise);
1956 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
1957 HAL_MDF_SndLvlCallback(hmdf, sound_level, ambient_noise);
1958 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
1959 }
1960 }
1961 }
1962
1963 /**
1964 * @brief MDF error callback.
1965 * @param hmdf MDF handle.
1966 * @retval None.
1967 */
HAL_MDF_ErrorCallback(MDF_HandleTypeDef * hmdf)1968 __weak void HAL_MDF_ErrorCallback(MDF_HandleTypeDef *hmdf)
1969 {
1970 /* Prevent unused argument(s) compilation warning */
1971 UNUSED(hmdf);
1972
1973 /* NOTE : This function should not be modified, when the function is needed,
1974 the HAL_MDF_ErrorCallback could be implemented in the user file */
1975 }
1976
1977 /**
1978 * @brief This function allows to get the current MDF state.
1979 * @param hmdf MDF handle.
1980 * @retval MDF state.
1981 */
HAL_MDF_GetState(const MDF_HandleTypeDef * hmdf)1982 HAL_MDF_StateTypeDef HAL_MDF_GetState(const MDF_HandleTypeDef *hmdf)
1983 {
1984 /* Return MDF state */
1985 return hmdf->State;
1986 }
1987
1988 /**
1989 * @brief This function allows to get the current MDF error.
1990 * @param hmdf MDF handle.
1991 * @retval MDF error code.
1992 */
HAL_MDF_GetError(const MDF_HandleTypeDef * hmdf)1993 uint32_t HAL_MDF_GetError(const MDF_HandleTypeDef *hmdf)
1994 {
1995 /* Return MDF error code */
1996 return hmdf->ErrorCode;
1997 }
1998
1999 /**
2000 * @}
2001 */
2002
2003 /**
2004 * @}
2005 */
2006
2007 /** @addtogroup MDF_Private_Functions
2008 * @brief Private functions
2009 * @{
2010 */
2011
2012 /**
2013 * @brief This function allows to configure filter and start acquisition.
2014 * @param hmdf MDF handle.
2015 * @param pFilterConfig Filter configuration parameters.
2016 * @retval None.
2017 */
MDF_AcqStart(MDF_HandleTypeDef * const hmdf,const MDF_FilterConfigTypeDef * const pFilterConfig)2018 static void MDF_AcqStart(MDF_HandleTypeDef *const hmdf, const MDF_FilterConfigTypeDef *const pFilterConfig)
2019 {
2020 uint32_t register_gain_value;
2021
2022 /* Configure acquisition mode, discard samples, trigger and fifo threshold */
2023 assert_param(IS_MDF_DISCARD_SAMPLES(pFilterConfig->DiscardSamples));
2024 assert_param(IS_MDF_FIFO_THRESHOLD(pFilterConfig->FifoThreshold));
2025 if ((pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_CONT) ||
2026 (pFilterConfig->AcquisitionMode == MDF_MODE_ASYNC_SINGLE))
2027 {
2028 /* Trigger parameters are not used */
2029 hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold |
2030 (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos));
2031 }
2032 else
2033 {
2034 /* Trigger parameters are used */
2035 assert_param(IS_MDF_TRIGGER_SOURCE(pFilterConfig->Trigger.Source));
2036 assert_param(IS_MDF_TRIGGER_EDGE(pFilterConfig->Trigger.Edge));
2037 hmdf->Instance->DFLTCR |= (pFilterConfig->AcquisitionMode | pFilterConfig->FifoThreshold |
2038 pFilterConfig->Trigger.Source | pFilterConfig->Trigger.Edge |
2039 (pFilterConfig->DiscardSamples << MDF_DFLTCR_NBDIS_Pos));
2040 }
2041
2042 /* Configure data source, CIC mode, decimation ratio and gain */
2043 assert_param(IS_MDF_DATA_SOURCE(pFilterConfig->DataSource));
2044 assert_param(IS_MDF_CIC_MODE(pFilterConfig->CicMode));
2045 assert_param(IS_MDF_DECIMATION_RATIO(pFilterConfig->DecimationRatio));
2046 assert_param(IS_MDF_GAIN(pFilterConfig->Gain));
2047 if (pFilterConfig->Gain < 0)
2048 {
2049 int32_t adjust_gain;
2050
2051 /* adjust gain value to set on register for negative value (offset of -16) */
2052 adjust_gain = pFilterConfig->Gain - 16;
2053 register_gain_value = ((uint32_t) adjust_gain & 0x3FU);
2054 }
2055 else
2056 {
2057 /* for positive value, no offset to apply */
2058 register_gain_value = (uint32_t) pFilterConfig->Gain;
2059 }
2060 hmdf->Instance->DFLTCICR = (pFilterConfig->DataSource | pFilterConfig->CicMode |
2061 ((pFilterConfig->DecimationRatio - 1U) << MDF_DFLTCICR_MCICD_Pos) |
2062 (register_gain_value << MDF_DFLTCICR_SCALE_Pos));
2063
2064 /* Configure bitstream delay */
2065 assert_param(IS_MDF_DELAY(pFilterConfig->Delay));
2066 hmdf->Instance->DLYCR = pFilterConfig->Delay;
2067
2068 /* Configure reshape filter */
2069 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->ReshapeFilter.Activation));
2070 hmdf->Instance->DFLTRSFR = 0U;
2071 if (pFilterConfig->ReshapeFilter.Activation == ENABLE)
2072 {
2073 /* Configure reshape filter decimation ratio */
2074 assert_param(IS_MDF_RSF_DECIMATION_RATIO(pFilterConfig->ReshapeFilter.DecimationRatio));
2075 hmdf->Instance->DFLTRSFR |= pFilterConfig->ReshapeFilter.DecimationRatio;
2076 }
2077 else
2078 {
2079 /* Bypass reshape filter */
2080 hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_RSFLTBYP;
2081 }
2082
2083 /* Configure high-pass filter */
2084 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->HighPassFilter.Activation));
2085 if (pFilterConfig->HighPassFilter.Activation == ENABLE)
2086 {
2087 /* Configure high-pass filter cut-off frequency */
2088 assert_param(IS_MDF_HPF_CUTOFF_FREQ(pFilterConfig->HighPassFilter.CutOffFrequency));
2089 hmdf->Instance->DFLTRSFR |= pFilterConfig->HighPassFilter.CutOffFrequency;
2090 }
2091 else
2092 {
2093 /* Bypass high-pass filter */
2094 hmdf->Instance->DFLTRSFR |= MDF_DFLTRSFR_HPFBYP;
2095 }
2096
2097 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Activation));
2098 if (pFilterConfig->SoundActivity.Activation == ENABLE)
2099 {
2100 /* Configure SAD mode, frame size, hysteresis, sound trigger event
2101 and data memory transfer only for ADF instance */
2102 assert_param(IS_MDF_SAD_MODE(pFilterConfig->SoundActivity.Mode));
2103 assert_param(IS_MDF_SAD_FRAME_SIZE(pFilterConfig->SoundActivity.FrameSize));
2104 if (pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR)
2105 {
2106 assert_param(IS_FUNCTIONAL_STATE(pFilterConfig->SoundActivity.Hysteresis));
2107 }
2108 assert_param(IS_MDF_SAD_SOUND_TRIGGER(pFilterConfig->SoundActivity.SoundTriggerEvent));
2109 assert_param(IS_MDF_SAD_DATA_MEMORY_TRANSFER(pFilterConfig->SoundActivity.DataMemoryTransfer));
2110 if ((pFilterConfig->SoundActivity.Mode != MDF_SAD_AMBIENT_NOISE_DETECTOR) &&
2111 (pFilterConfig->SoundActivity.Hysteresis == ENABLE))
2112 {
2113 hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize |
2114 MDF_SADCR_HYSTEN | pFilterConfig->SoundActivity.SoundTriggerEvent |
2115 pFilterConfig->SoundActivity.DataMemoryTransfer);
2116 }
2117 else
2118 {
2119 hmdf->Instance->SADCR = (pFilterConfig->SoundActivity.Mode | pFilterConfig->SoundActivity.FrameSize |
2120 pFilterConfig->SoundActivity.SoundTriggerEvent |
2121 pFilterConfig->SoundActivity.DataMemoryTransfer);
2122 }
2123
2124 /* Configure SAD minimum noise level, hangover window, learning frames,
2125 ambient noise slope control and signal noise threshold only for ADF instance */
2126 assert_param(IS_MDF_SAD_MIN_NOISE_LEVEL(pFilterConfig->SoundActivity.MinNoiseLevel));
2127 assert_param(IS_MDF_SAD_HANGOVER_WINDOW(pFilterConfig->SoundActivity.HangoverWindow));
2128 assert_param(IS_MDF_SAD_LEARNING_FRAMES(pFilterConfig->SoundActivity.LearningFrames));
2129 assert_param(IS_MDF_SAD_SIGNAL_NOISE_THRESHOLD(pFilterConfig->SoundActivity.SignalNoiseThreshold));
2130 if (pFilterConfig->SoundActivity.Mode != MDF_SAD_SOUND_DETECTOR)
2131 {
2132 assert_param(IS_MDF_SAD_AMBIENT_NOISE_SLOPE(pFilterConfig->SoundActivity.AmbientNoiseSlope));
2133 hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) |
2134 pFilterConfig->SoundActivity.HangoverWindow |
2135 pFilterConfig->SoundActivity.LearningFrames |
2136 (pFilterConfig->SoundActivity.AmbientNoiseSlope << MDF_SADCFGR_ANSLP_Pos) |
2137 pFilterConfig->SoundActivity.SignalNoiseThreshold);
2138 }
2139 else
2140 {
2141 hmdf->Instance->SADCFGR = ((pFilterConfig->SoundActivity.MinNoiseLevel << MDF_SADCFGR_ANMIN_Pos) |
2142 pFilterConfig->SoundActivity.HangoverWindow |
2143 pFilterConfig->SoundActivity.LearningFrames |
2144 pFilterConfig->SoundActivity.SignalNoiseThreshold);
2145 }
2146 }
2147 else
2148 {
2149 /* SAD is not used */
2150 hmdf->Instance->SADCR = 0U;
2151 hmdf->Instance->SADCFGR = 0U;
2152 }
2153
2154 /* Update instance state */
2155 hmdf->State = HAL_MDF_STATE_ACQUISITION;
2156
2157 /* Enable sound activity detector if needed */
2158 if (pFilterConfig->SoundActivity.Activation == ENABLE)
2159 {
2160 hmdf->Instance->SADCR |= MDF_SADCR_SADEN;
2161 }
2162
2163 /* Enable filter */
2164 hmdf->Instance->DFLTCR |= MDF_DFLTCR_DFLTEN;
2165 }
2166
2167 /**
2168 * @brief This function handles DMA transfer complete callback.
2169 * @param hdma DMA handle.
2170 * @retval None.
2171 */
MDF_DmaXferCpltCallback(DMA_HandleTypeDef * hdma)2172 static void MDF_DmaXferCpltCallback(DMA_HandleTypeDef *hdma)
2173 {
2174 MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2175
2176 /* Check if DMA in circular mode */
2177 if (hdma->Mode != DMA_LINKEDLIST_CIRCULAR)
2178 {
2179 hmdf->State = HAL_MDF_STATE_READY;
2180 }
2181
2182 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
2183 hmdf->AcqCpltCallback(hmdf);
2184 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
2185 HAL_MDF_AcqCpltCallback(hmdf);
2186 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
2187 }
2188
2189 /**
2190 * @brief This function handles DMA half transfer complete callback.
2191 * @param hdma DMA handle.
2192 * @retval None.
2193 */
MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef * hdma)2194 static void MDF_DmaXferHalfCpltCallback(DMA_HandleTypeDef *hdma)
2195 {
2196 MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2197
2198 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
2199 hmdf->AcqHalfCpltCallback(hmdf);
2200 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
2201 HAL_MDF_AcqHalfCpltCallback(hmdf);
2202 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
2203 }
2204
2205 /**
2206 * @brief This function handles DMA error callback.
2207 * @param hdma DMA handle.
2208 * @retval None.
2209 */
MDF_DmaErrorCallback(DMA_HandleTypeDef * hdma)2210 static void MDF_DmaErrorCallback(DMA_HandleTypeDef *hdma)
2211 {
2212 MDF_HandleTypeDef *hmdf = (MDF_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2213
2214 /* Update error code */
2215 hmdf->ErrorCode |= MDF_ERROR_DMA;
2216
2217 #if (USE_HAL_MDF_REGISTER_CALLBACKS == 1)
2218 hmdf->ErrorCallback(hmdf);
2219 #else /* USE_HAL_MDF_REGISTER_CALLBACKS */
2220 HAL_MDF_ErrorCallback(hmdf);
2221 #endif /* USE_HAL_MDF_REGISTER_CALLBACKS */
2222 }
2223
2224 /**
2225 * @}
2226 */
2227
2228 #endif /* HAL_MDF_MODULE_ENABLED */
2229
2230 /**
2231 * @}
2232 */
2233
2234 /**
2235 * @}
2236 */
2237