STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_sai_ex.c 00004 * @author MCD Application Team 00005 * @brief SAI Extension HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of SAI extension peripheral: 00008 * + Extension features functions 00009 * 00010 @verbatim 00011 ============================================================================== 00012 ##### SAI peripheral extension features ##### 00013 ============================================================================== 00014 00015 [..] Comparing to other previous devices, the SAI interface for STM32F446xx 00016 devices contains the following additional features : 00017 00018 (+) Possibility to be clocked from PLLR 00019 00020 ##### How to use this driver ##### 00021 ============================================================================== 00022 [..] This driver provides functions to manage several sources to clock SAI 00023 00024 @endverbatim 00025 ****************************************************************************** 00026 * @attention 00027 * 00028 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00029 * 00030 * Redistribution and use in source and binary forms, with or without modification, 00031 * are permitted provided that the following conditions are met: 00032 * 1. Redistributions of source code must retain the above copyright notice, 00033 * this list of conditions and the following disclaimer. 00034 * 2. Redistributions in binary form must reproduce the above copyright notice, 00035 * this list of conditions and the following disclaimer in the documentation 00036 * and/or other materials provided with the distribution. 00037 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00038 * may be used to endorse or promote products derived from this software 00039 * without specific prior written permission. 00040 * 00041 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00042 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00043 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00044 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00045 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00046 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00047 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00048 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00049 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00050 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00051 * 00052 ****************************************************************************** 00053 */ 00054 00055 /* Includes ------------------------------------------------------------------*/ 00056 #include "stm32f4xx_hal.h" 00057 00058 /** @addtogroup STM32F4xx_HAL_Driver 00059 * @{ 00060 */ 00061 00062 /** @defgroup SAIEx SAIEx 00063 * @brief SAI Extension HAL module driver 00064 * @{ 00065 */ 00066 00067 #ifdef HAL_SAI_MODULE_ENABLED 00068 00069 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00070 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || \ 00071 defined(STM32F423xx) 00072 00073 /* Private typedef -----------------------------------------------------------*/ 00074 /* Private define ------------------------------------------------------------*/ 00075 /* SAI registers Masks */ 00076 /* Private macro -------------------------------------------------------------*/ 00077 /* Private variables ---------------------------------------------------------*/ 00078 /* Private function prototypes -----------------------------------------------*/ 00079 /* Private functions ---------------------------------------------------------*/ 00080 00081 /** @defgroup SAI_Private_Functions SAI Private Functions 00082 * @{ 00083 */ 00084 /** 00085 * @} 00086 */ 00087 00088 /* Exported functions --------------------------------------------------------*/ 00089 /** @defgroup SAIEx_Exported_Functions SAI Extended Exported Functions 00090 * @{ 00091 */ 00092 00093 /** @defgroup SAIEx_Exported_Functions_Group1 Extension features functions 00094 * @brief Extension features functions 00095 * 00096 @verbatim 00097 =============================================================================== 00098 ##### Extension features Functions ##### 00099 =============================================================================== 00100 [..] 00101 This subsection provides a set of functions allowing to manage the possible 00102 SAI clock sources. 00103 00104 @endverbatim 00105 * @{ 00106 */ 00107 00108 /** 00109 * @brief Configure SAI Block synchronization mode 00110 * @param hsai pointer to a SAI_HandleTypeDef structure that contains 00111 * the configuration information for SAI module. 00112 * @retval SAI Clock Input 00113 */ 00114 void SAI_BlockSynchroConfig(SAI_HandleTypeDef *hsai) 00115 { 00116 uint32_t tmpregisterGCR = 0U; 00117 00118 #if defined(STM32F446xx) 00119 /* This setting must be done with both audio block (A & B) disabled */ 00120 switch(hsai->Init.SynchroExt) 00121 { 00122 case SAI_SYNCEXT_DISABLE : 00123 tmpregisterGCR = 0U; 00124 break; 00125 case SAI_SYNCEXT_OUTBLOCKA_ENABLE : 00126 tmpregisterGCR = SAI_GCR_SYNCOUT_0; 00127 break; 00128 case SAI_SYNCEXT_OUTBLOCKB_ENABLE : 00129 tmpregisterGCR = SAI_GCR_SYNCOUT_1; 00130 break; 00131 default: 00132 break; 00133 } 00134 00135 if((hsai->Init.Synchro) == SAI_SYNCHRONOUS_EXT_SAI2) 00136 { 00137 tmpregisterGCR |= SAI_GCR_SYNCIN_0; 00138 } 00139 00140 if((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) 00141 { 00142 SAI1->GCR = tmpregisterGCR; 00143 } 00144 else 00145 { 00146 SAI2->GCR = tmpregisterGCR; 00147 } 00148 #endif /* STM32F446xx */ 00149 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00150 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) 00151 /* This setting must be done with both audio block (A & B) disabled */ 00152 switch(hsai->Init.SynchroExt) 00153 { 00154 case SAI_SYNCEXT_DISABLE : 00155 tmpregisterGCR = 0U; 00156 break; 00157 case SAI_SYNCEXT_OUTBLOCKA_ENABLE : 00158 tmpregisterGCR = SAI_GCR_SYNCOUT_0; 00159 break; 00160 case SAI_SYNCEXT_OUTBLOCKB_ENABLE : 00161 tmpregisterGCR = SAI_GCR_SYNCOUT_1; 00162 break; 00163 default: 00164 break; 00165 } 00166 SAI1->GCR = tmpregisterGCR; 00167 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */ 00168 } 00169 /** 00170 * @brief Get SAI Input Clock based on SAI source clock selection 00171 * @param hsai pointer to a SAI_HandleTypeDef structure that contains 00172 * the configuration information for SAI module. 00173 * @retval SAI Clock Input 00174 */ 00175 uint32_t SAI_GetInputClock(SAI_HandleTypeDef *hsai) 00176 { 00177 /* This variable used to store the SAI_CK_x (value in Hz) */ 00178 uint32_t saiclocksource = 0U; 00179 00180 #if defined(STM32F446xx) 00181 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) 00182 { 00183 saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1); 00184 } 00185 else /* SAI2_Block_A || SAI2_Block_B*/ 00186 { 00187 saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2); 00188 } 00189 #endif /* STM32F446xx */ 00190 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00191 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) 00192 uint32_t vcoinput = 0U, tmpreg = 0U; 00193 00194 /* Check the SAI Block parameters */ 00195 assert_param(IS_SAI_CLK_SOURCE(hsai->Init.ClockSource)); 00196 00197 /* SAI Block clock source selection */ 00198 if(hsai->Instance == SAI1_Block_A) 00199 { 00200 __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(hsai->Init.ClockSource); 00201 } 00202 else 00203 { 00204 __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG((uint32_t)(hsai->Init.ClockSource << 2U)); 00205 } 00206 00207 /* VCO Input Clock value calculation */ 00208 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) 00209 { 00210 /* In Case the PLL Source is HSI (Internal Clock) */ 00211 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); 00212 } 00213 else 00214 { 00215 /* In Case the PLL Source is HSE (External Clock) */ 00216 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM))); 00217 } 00218 #if defined(STM32F413xx) || defined(STM32F423xx) 00219 /* SAI_CLK_x : SAI Block Clock configuration for different clock sources selected */ 00220 if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLR) 00221 { 00222 /* Configure the PLLI2S division factor */ 00223 /* PLL_VCO Input = PLL_SOURCE/PLLM */ 00224 /* PLL_VCO Output = PLL_VCO Input * PLLN */ 00225 /* SAI_CLK(first level) = PLL_VCO Output/PLLR */ 00226 tmpreg = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U; 00227 saiclocksource = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg); 00228 00229 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */ 00230 tmpreg = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> 8U) + 1U); 00231 00232 saiclocksource = saiclocksource/(tmpreg); 00233 00234 } 00235 else if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLI2S) 00236 { 00237 /* Configure the PLLI2S division factor */ 00238 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 00239 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00240 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SR */ 00241 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U; 00242 saiclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg); 00243 00244 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */ 00245 tmpreg = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) + 1U); 00246 saiclocksource = saiclocksource/(tmpreg); 00247 } 00248 else if(hsai->Init.ClockSource == SAI_CLKSOURCE_HS) 00249 { 00250 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) 00251 { 00252 /* Get the I2S source clock value */ 00253 saiclocksource = (uint32_t)(HSE_VALUE); 00254 } 00255 else 00256 { 00257 /* Get the I2S source clock value */ 00258 saiclocksource = (uint32_t)(HSI_VALUE); 00259 } 00260 } 00261 else /* sConfig->ClockSource == SAI_CLKSource_Ext */ 00262 { 00263 saiclocksource = EXTERNAL_CLOCK_VALUE; 00264 } 00265 #else 00266 /* SAI_CLK_x : SAI Block Clock configuration for different clock sources selected */ 00267 if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLSAI) 00268 { 00269 /* Configure the PLLI2S division factor */ 00270 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ 00271 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ 00272 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ 00273 tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U; 00274 saiclocksource = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg); 00275 00276 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ 00277 tmpreg = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U); 00278 saiclocksource = saiclocksource/(tmpreg); 00279 00280 } 00281 else if(hsai->Init.ClockSource == SAI_CLKSOURCE_PLLI2S) 00282 { 00283 /* Configure the PLLI2S division factor */ 00284 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ 00285 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ 00286 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ 00287 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U; 00288 saiclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg); 00289 00290 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ 00291 tmpreg = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U); 00292 saiclocksource = saiclocksource/(tmpreg); 00293 } 00294 else /* sConfig->ClockSource == SAI_CLKSource_Ext */ 00295 { 00296 /* Enable the External Clock selection */ 00297 __HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT); 00298 00299 saiclocksource = EXTERNAL_CLOCK_VALUE; 00300 } 00301 #endif /* STM32F413xx || STM32F423xx */ 00302 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */ 00303 /* the return result is the value of SAI clock */ 00304 return saiclocksource; 00305 } 00306 00307 /** 00308 * @} 00309 */ 00310 00311 /** 00312 * @} 00313 */ 00314 00315 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */ 00316 #endif /* HAL_SAI_MODULE_ENABLED */ 00317 /** 00318 * @} 00319 */ 00320 00321 /** 00322 * @} 00323 */ 00324 00325 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/