STM32F4xx HAL Documentation
Hardware Abstraction Layer for STM32F4 familiy
Loading...
Searching...
No Matches
stm32f4xx_hal_sai_ex.c
Go to the documentation of this file.
1
39/* Includes ------------------------------------------------------------------*/
40#include "stm32f4xx_hal.h"
41
51#ifdef HAL_SAI_MODULE_ENABLED
52
53#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
54 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || \
55 defined(STM32F423xx)
56
57/* Private typedef -----------------------------------------------------------*/
58/* Private define ------------------------------------------------------------*/
59/* SAI registers Masks */
60/* Private macro -------------------------------------------------------------*/
61/* Private variables ---------------------------------------------------------*/
62/* Private function prototypes -----------------------------------------------*/
63/* Private functions ---------------------------------------------------------*/
64
72/* Exported functions --------------------------------------------------------*/
99{
100 uint32_t tmpregisterGCR;
101
102#if defined(STM32F446xx)
103 /* This setting must be done with both audio block (A & B) disabled */
104 switch (hsai->Init.SynchroExt)
105 {
107 tmpregisterGCR = 0U;
108 break;
110 tmpregisterGCR = SAI_GCR_SYNCOUT_0;
111 break;
113 tmpregisterGCR = SAI_GCR_SYNCOUT_1;
114 break;
115 default:
116 tmpregisterGCR = 0U;
117 break;
118 }
119
121 {
122 tmpregisterGCR |= SAI_GCR_SYNCIN_0;
123 }
124
125 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
126 {
127 SAI1->GCR = tmpregisterGCR;
128 }
129 else
130 {
131 SAI2->GCR = tmpregisterGCR;
132 }
133#endif /* STM32F446xx */
134#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
135 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx)
136 /* This setting must be done with both audio block (A & B) disabled */
137 switch (hsai->Init.SynchroExt)
138 {
140 tmpregisterGCR = 0U;
141 break;
143 tmpregisterGCR = SAI_GCR_SYNCOUT_0;
144 break;
146 tmpregisterGCR = SAI_GCR_SYNCOUT_1;
147 break;
148 default:
149 tmpregisterGCR = 0U;
150 break;
151 }
152 SAI1->GCR = tmpregisterGCR;
153#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */
154}
162{
163 /* This variable used to store the SAI_CK_x (value in Hz) */
164 uint32_t saiclocksource = 0U;
165
166#if defined(STM32F446xx)
167 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
168 {
170 }
171 else /* SAI2_Block_A || SAI2_Block_B*/
172 {
174 }
175#endif /* STM32F446xx */
176#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
177 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx)
178 uint32_t vcoinput = 0U, tmpreg = 0U;
179
180 /* Check the SAI Block parameters */
182
183 /* SAI Block clock source selection */
184 if (hsai->Instance == SAI1_Block_A)
185 {
186 __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(hsai->Init.ClockSource);
187 }
188 else
189 {
190 __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG((uint32_t)(hsai->Init.ClockSource << 2U));
191 }
192
193 /* VCO Input Clock value calculation */
194 if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI)
195 {
196 /* In Case the PLL Source is HSI (Internal Clock) */
197 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
198 }
199 else
200 {
201 /* In Case the PLL Source is HSE (External Clock) */
202 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
203 }
204#if defined(STM32F413xx) || defined(STM32F423xx)
205 /* SAI_CLK_x : SAI Block Clock configuration for different clock sources selected */
206 if (hsai->Init.ClockSource == SAI_CLKSOURCE_PLLR)
207 {
208 /* Configure the PLLI2S division factor */
209 /* PLL_VCO Input = PLL_SOURCE/PLLM */
210 /* PLL_VCO Output = PLL_VCO Input * PLLN */
211 /* SAI_CLK(first level) = PLL_VCO Output/PLLR */
212 tmpreg = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U;
213 saiclocksource = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U)) / (tmpreg);
214
215 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */
216 tmpreg = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> 8U) + 1U);
217
218 saiclocksource = saiclocksource / (tmpreg);
219
220 }
221 else if (hsai->Init.ClockSource == SAI_CLKSOURCE_PLLI2S)
222 {
223 /* Configure the PLLI2S division factor */
224 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
225 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
226 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SR */
227 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U;
228 saiclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U)) / (tmpreg);
229
230 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */
231 tmpreg = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) + 1U);
232 saiclocksource = saiclocksource / (tmpreg);
233 }
234 else if (hsai->Init.ClockSource == SAI_CLKSOURCE_HS)
235 {
236 if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE)
237 {
238 /* Get the I2S source clock value */
239 saiclocksource = (uint32_t)(HSE_VALUE);
240 }
241 else
242 {
243 /* Get the I2S source clock value */
244 saiclocksource = (uint32_t)(HSI_VALUE);
245 }
246 }
247 else /* sConfig->ClockSource == SAI_CLKSource_Ext */
248 {
249 saiclocksource = EXTERNAL_CLOCK_VALUE;
250 }
251#else
252 /* SAI_CLK_x : SAI Block Clock configuration for different clock sources selected */
254 {
255 /* Configure the PLLI2S division factor */
256 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
257 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
258 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
259 tmpreg = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U;
260 saiclocksource = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U)) / (tmpreg);
261
262 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
263 tmpreg = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U);
264 saiclocksource = saiclocksource / (tmpreg);
265
266 }
267 else if (hsai->Init.ClockSource == SAI_CLKSOURCE_PLLI2S)
268 {
269 /* Configure the PLLI2S division factor */
270 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
271 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
272 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
273 tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U;
274 saiclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U)) / (tmpreg);
275
276 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
277 tmpreg = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U);
278 saiclocksource = saiclocksource / (tmpreg);
279 }
280 else /* sConfig->ClockSource == SAI_CLKSource_Ext */
281 {
282 /* Enable the External Clock selection */
283 __HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT);
284
285 saiclocksource = EXTERNAL_CLOCK_VALUE;
286 }
287#endif /* STM32F413xx || STM32F423xx */
288#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */
289 /* the return result is the value of SAI clock */
290 return saiclocksource;
291}
292
301#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */
302#endif /* HAL_SAI_MODULE_ENABLED */
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
Return the peripheral clock frequency for a given peripheral(SAI..)
#define RCC_PERIPHCLK_SAI2
#define RCC_PERIPHCLK_SAI1
#define RCC_PLLSOURCE_HSI
#define RCC_PLLSOURCE_HSE
void SAI_BlockSynchroConfig(const SAI_HandleTypeDef *hsai)
Configure SAI Block synchronization mode.
uint32_t SAI_GetInputClock(const SAI_HandleTypeDef *hsai)
Get SAI Input Clock based on SAI source clock selection.
#define IS_SAI_CLK_SOURCE(SOURCE)
#define SAI_SYNCEXT_DISABLE
#define SAI_SYNCEXT_OUTBLOCKA_ENABLE
#define SAI_SYNCEXT_OUTBLOCKB_ENABLE
#define SAI_SYNCHRONOUS_EXT_SAI2
#define SAI_CLKSOURCE_PLLI2S
#define SAI_CLKSOURCE_PLLSAI
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
#define EXTERNAL_CLOCK_VALUE
External clock source for I2S peripheral This value is used by the I2S HAL module to compute the I2S ...
#define HSI_VALUE
Internal High Speed oscillator (HSI) value. This value is used by the RCC HAL module to compute the s...
#define HSE_VALUE
Adjust the value of External High Speed oscillator (HSE) used in your application....
SAI_Block_TypeDef * Instance