/** ****************************************************************************** * @file DFSDM/DFSDM_PulseSkipper/Src/pulse_skipper.c * @author MCD Application Team * @brief This file provides a set of firmware functions to pulse skipper. ****************************************************************************** * @attention * * Copyright (c) 2017 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "pulse_skipper.h" /** @addtogroup STM32F4xx_HAL_Examples * @{ */ /** @addtogroup DFSDM_PulseSkipper * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define NB_BITSTREAM_CLOCK_PERIOD 4 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Timer3 handler declaration for DFSDM2 */ TIM_HandleTypeDef TimDfsdm2Handle; /* Timer4 handler declaration for DFSDM1 */ TIM_HandleTypeDef TimDfsdm1Handle; /* Private function prototypes -----------------------------------------------*/ static void Skipper_MspInit(void); /* Private functions ---------------------------------------------------------*/ /** * @brief Enable Multi Channel clock Delay for DFSDM1 and DFSDM2 . * @param None * @retval None */ void Pulse_Skipper_Init(void) { /* Configure TIM3 and TIM4 */ Skipper_MspInit(); /* Enable delay clock gating */ HAL_DFSDM_EnableDelayClock(HAL_MCHDLY_CLOCK_DFSDM1); HAL_DFSDM_EnableDelayClock(HAL_MCHDLY_CLOCK_DFSDM2); } /** * @brief Inject DFSDM2 audio clock as clock source for the bitstream clock * @param None * @retval None */ void Pulse_Skipper_Bitstream_Start(void) { HAL_DFSDM_BitstreamClock_Start(); } /** * @brief Stop DFSDM2 audio clock as clock source for the bitstream clock. * @param None * @retval None */ void Pulse_Skipper_Bitstream_Stop(void) { HAL_DFSDM_BitstreamClock_Stop(); } /** * @brief Generate Pulse skipper on selected channel * @param skipperstruct: Structure for channel * @retval None */ void Pulse_Skipper_Generate_Pulse(PulseSkipper_InitTypeDef* skipperstruct) { /*****************DFSDM1 Pulse Skipper Channel Generation ********************/ if (skipperstruct->DFSDM1PulseSkipperCh == DFSDM1_PULSE_SKIPPER_CH02) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm1Handle.Instance, DFSDM1_TIM4_OC2, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm1Handle.Instance, DFSDM1_TIM4_OC2, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm1Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm1Handle); } else if (skipperstruct->DFSDM1PulseSkipperCh == DFSDM1_PULSE_SKIPPER_CH13) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm1Handle.Instance, DFSDM1_TIM4_OC1, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm1Handle.Instance, DFSDM1_TIM4_OC1, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm1Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm1Handle); } /*****************DFSDM2 Pulse Skipper Channel Generation ********************/ if (skipperstruct->DFSDM2PulseSkipperCh == DFSDM2_PULSE_SKIPPER_CH04) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC4, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC4, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm2Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm2Handle); } else if (skipperstruct->DFSDM2PulseSkipperCh == DFSDM2_PULSE_SKIPPER_CH15) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC3, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC3, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm2Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm2Handle); } else if (skipperstruct->DFSDM2PulseSkipperCh == DFSDM2_PULSE_SKIPPER_CH26) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC2, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC2, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm2Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm2Handle); } else if (skipperstruct->DFSDM2PulseSkipperCh == DFSDM2_PULSE_SKIPPER_CH37) { /* Disable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC1, TIM_CCx_DISABLE); /* Enable the Capture compare channel */ TIM_CCxChannelCmd(TimDfsdm2Handle.Instance, DFSDM2_TIM3_OC1, TIM_CCx_ENABLE); /* Use TIM_Base in order to get interrupt once pulse ended */ /* Enable the TIM Update interrupt */ __HAL_TIM_ENABLE_IT(&TimDfsdm2Handle, TIM_IT_UPDATE); /* Enable the Peripheral */ __HAL_TIM_ENABLE(&TimDfsdm2Handle); } } /** * @brief Turns selected LED Off. * @param Led: LED to be set off * This parameter can be one of the following values: * @arg LED5 * @arg LED8 * @retval None */ static void Skipper_MspInit(void) { /* Output compare structure */ TIM_OC_InitTypeDef sOCConfig; /* Slave configuration structure */ TIM_SlaveConfigTypeDef sSlaveConfig; /* Timers Configuration */ TimDfsdm2Handle.Instance = TIM3; TimDfsdm1Handle.Instance = TIM4; /*====================== TIM3 configuration =======================*/ /* Initialize TIM3 peripheral in PWM mode */ TimDfsdm2Handle.Init.Period = NB_BITSTREAM_CLOCK_PERIOD ; TimDfsdm2Handle.Init.Prescaler = 0; TimDfsdm2Handle.Init.ClockDivision = 0; TimDfsdm2Handle.Init.CounterMode = TIM_COUNTERMODE_UP; TimDfsdm2Handle.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_Init(&TimDfsdm2Handle) != HAL_OK) { /* Initialization Error */ while(1); } /* Configure the OPM Mode */ HAL_TIM_OnePulse_Init(&TimDfsdm2Handle, TIM_OPMODE_SINGLE); /* Configure the PWM_channel_1 */ sOCConfig.OCMode = TIM_OCMODE_PWM1; sOCConfig.OCPolarity = TIM_OCPOLARITY_LOW; sOCConfig.Pulse = 1; sOCConfig.OCFastMode = TIM_OCFAST_DISABLE ; if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm2Handle, &sOCConfig, TIM_CHANNEL_1) != HAL_OK) { /* Initialization Error */ while(1); } if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm2Handle, &sOCConfig, TIM_CHANNEL_2) != HAL_OK) { /* Initialization Error */ while(1); } if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm2Handle, &sOCConfig, TIM_CHANNEL_3) != HAL_OK) { /* Initialization Error */ while(1);; } if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm2Handle, &sOCConfig, TIM_CHANNEL_4) != HAL_OK) { /* Initialization Error */ while(1); } /* Configure TIM3 in Gated slave mode & use the Internal Trigger 0 (ITR1) as trigger source */ sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; sSlaveConfig.InputTrigger = TIM_TS_ETRF; sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED; sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; sSlaveConfig.TriggerFilter = 0; if (HAL_TIM_SlaveConfigSynchronization(&TimDfsdm2Handle, &sSlaveConfig) != HAL_OK) { /* Initialization Error */ while(1); } /*====================== TIM4 configuration =======================*/ /* Initialize TIM4 peripheral in PWM mode */ TimDfsdm1Handle.Init.Period = NB_BITSTREAM_CLOCK_PERIOD; TimDfsdm1Handle.Init.Prescaler = 0; TimDfsdm1Handle.Init.ClockDivision = 0; TimDfsdm1Handle.Init.CounterMode = TIM_COUNTERMODE_UP; TimDfsdm1Handle.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_Init(&TimDfsdm1Handle) != HAL_OK) { /* Initialization Error */ while(1); } /* Configure the OPM Mode */ HAL_TIM_OnePulse_Init(&TimDfsdm1Handle, TIM_OPMODE_SINGLE); /* Configure the PWM_channel_1 */ sOCConfig.OCMode = TIM_OCMODE_PWM1; sOCConfig.OCPolarity = TIM_OCPOLARITY_LOW; sOCConfig.Pulse = 1; sOCConfig.OCFastMode = TIM_OCFAST_DISABLE ; if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm1Handle, &sOCConfig, TIM_CHANNEL_1) != HAL_OK) { /* Initialization Error */ while(1); } if (HAL_TIM_PWM_ConfigChannel(&TimDfsdm1Handle, &sOCConfig, TIM_CHANNEL_2) != HAL_OK) { /* Initialization Error */ while(1); } /* Configure TIM4 in Gated slave mode & use the Internal Trigger 0 (ITR1) as trigger source */ sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; sSlaveConfig.InputTrigger = TIM_TS_ETRF; sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_NONINVERTED; sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; sSlaveConfig.TriggerFilter = 0; if (HAL_TIM_SlaveConfigSynchronization(&TimDfsdm1Handle, &sSlaveConfig) != HAL_OK) { /* Initialization Error */ while(1); } } /** * @brief TIM MSP Initialization * This function configures the hardware resources used in this example: * - Peripheral's clock enable * - Peripheral's GPIO Configuration * @param htim: TIM handle pointer * @retval None */ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_InitStruct; /* Enable TIM4, TIM3 clocks */ __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_TIM4_CLK_ENABLE(); /* Enable GPIOB, GPIOD clocks */ __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; /* Configure PB.04 (TIM3_Channel1): pin D12 from CN6 */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; GPIO_InitStruct.Pin = GPIO_PIN_4; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PB.05 (TIM3_Channel2): pin D11 from CN6 */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; GPIO_InitStruct.Pin = GPIO_PIN_5; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PB.00 (TIM3_Channel3): pin D6 from CN8 */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; GPIO_InitStruct.Pin = GPIO_PIN_0; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PB.01 (TIM3_Channel4): pin A4 from CN9 */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; GPIO_InitStruct.Pin = GPIO_PIN_1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PB.06 (TIM4_Channel1) : pin D4 from CN8 */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; GPIO_InitStruct.Pin = GPIO_PIN_6; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Configure PD.13 (TIM4_Channel2) */ GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; GPIO_InitStruct.Pin = GPIO_PIN_13; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM3_IRQn); HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM4_IRQn); } /** * @} */ /** * @} */ /** * @} */ /** * @} */