/** * @brief Get SAI Input Clock based on SAI source clock selection * @param hsai: pointer to a SAI_HandleTypeDef structure that contains * the configuration information for SAI module. * @retval SAI Clock Input */ uint32_t SAI_GetInputClock(SAI_HandleTypeDef *hsai) { /* This variable used to store the SAI_CK_x (value in Hz) */ uint32_t saiclocksource = 0; if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B)) { saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1); } else { /* SAI2_Block_A || SAI2_Block_B*/ saiclocksource = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2); } /* the return result is the value of SAI clock */ return saiclocksource; }
/** * @brief Perform an ADC automatic self-calibration * Calibration prerequisite: ADC must be disabled (execute this * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). * During calibration process, ADC is enabled. ADC is let enabled at * the completion of this function. * @param hadc: ADC handle * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; uint32_t tickstart; __IO uint32_t wait_loop_index = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* 1. Calibration prerequisite: */ /* - ADC must be disabled for at least two ADC clock cycles in disable */ /* mode before ADC enable */ /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ tmp_hal_status = ADC_ConversionStop_Disable(hadc); /* Check if ADC is effectively disabled */ if (tmp_hal_status != HAL_ERROR) { /* Hardware prerequisite: delay before starting the calibration. */ /* - Computation of CPU clock cycles corresponding to ADC clock cycles. */ /* - Wait for the expected ADC clock cycles delay */ wait_loop_index = ((SystemCoreClock / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES ); while(wait_loop_index != 0) { wait_loop_index--; } /* 2. Enable the ADC peripheral */ ADC_Enable(hadc); /* 3. Resets ADC calibration registers */ SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL); tickstart = HAL_GetTick(); /* Wait for calibration reset completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } /* 4. Start ADC calibration */ SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL); tickstart = HAL_GetTick(); /* Wait for calibration completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Wait for injected group conversion to be completed. * @param hadc: ADC handle * @param Timeout: Timeout value in millisecond. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) { uint32_t tickstart; /* Variables for polling in case of scan mode enabled and polling for each */ /* conversion. */ __IO uint32_t Conversion_Timeout_CPU_cycles = 0; uint32_t Conversion_Timeout_CPU_cycles_max = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Get timeout */ tickstart = HAL_GetTick(); /* Polling for end of conversion: differentiation if single/sequence */ /* conversion. */ /* For injected group, flag JEOC is set only at the end of the sequence, */ /* not for each conversion within the sequence. */ /* - If single conversion for injected group (scan mode disabled or */ /* InjectedNbrOfConversion ==1), flag jEOC is used to determine the */ /* conversion completion. */ /* - If sequence conversion for injected group (scan mode enabled and */ /* InjectedNbrOfConversion >=2), flag JEOC is set only at the end of the */ /* sequence. */ /* To poll for each conversion, the maximum conversion time is computed */ /* from ADC conversion time (selected sampling time + conversion time of */ /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */ /* settings, conversion time range can be from 28 to 32256 CPU cycles). */ if ((hadc->Instance->JSQR & ADC_JSQR_JL) == RESET) { /* Wait until End of Conversion flag is raised */ while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC)) { /* Check if timeout is disabled (set to infinite wait) */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart ) > Timeout)) { /* Update ADC state machine to timeout */ hadc->State = HAL_ADC_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } } } else { /* Poll with maximum conversion time */ /* - Computation of CPU clock cycles corresponding to ADC clock cycles */ /* and ADC maximum conversion cycles on all channels. */ /* - Wait for the expected ADC clock cycles delay */ Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) * ADC_CONVCYCLES_MAX_RANGE(hadc) ); while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max) { /* Check if timeout is disabled (set to infinite wait) */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) { /* Update ADC state machine to timeout */ hadc->State = HAL_ADC_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } Conversion_Timeout_CPU_cycles ++; } } /* Clear injected group conversion flag (and regular conversion flag raised */ /* simultaneously) */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC | ADC_FLAG_EOC); /* Update state machine on conversion status if not in error state */ if(hadc->State != HAL_ADC_STATE_ERROR) { /* Update ADC state machine */ if(hadc->State != HAL_ADC_STATE_EOC_INJ_REG) { if(hadc->State == HAL_ADC_STATE_EOC_REG) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ; } } } /* Return ADC state */ return HAL_OK; }
/** * @brief Initializes the I2S according to the specified parameters * in the I2S_InitTypeDef and create the associated handle. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s) { uint32_t i2sdiv = 2, i2sodd = 0, packetlength = 1; uint32_t tmp = 0, i2sclk = 0; /* Check the I2S handle allocation */ if(hi2s == NULL) { return HAL_ERROR; } /* Check the I2S parameters */ assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance)); assert_param(IS_I2S_MODE(hi2s->Init.Mode)); assert_param(IS_I2S_STANDARD(hi2s->Init.Standard)); assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat)); assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput)); assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq)); assert_param(IS_I2S_CPOL(hi2s->Init.CPOL)); if(hi2s->State == HAL_I2S_STATE_RESET) { /* Allocate lock resource and initialize it */ hi2s-> Lock = HAL_UNLOCKED; /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ HAL_I2S_MspInit(hi2s); } hi2s->State = HAL_I2S_STATE_BUSY; /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/ if(hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT) { i2sodd = (uint32_t)0; i2sdiv = (uint32_t)2; } /* If the requested audio frequency is not the default, compute the prescaler */ else { /* Check the frame length (For the Prescaler computing) *******************/ if(hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) { /* Packet length is 16 bits */ packetlength = 1; } else { /* Packet length is 32 bits */ packetlength = 2; } if(hi2s->Instance == SPI2) { /* Get the source clock value: based on SPI2 Instance */ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S2); } else if(hi2s->Instance == SPI3) { /* Get the source clock value: based on SPI3 Instance */ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S3); } else { /* Get the source clock value: based on System Clock value */ i2sclk = HAL_RCC_GetSysClockFreq(); } if(i2sclk == 0) { return HAL_ERROR; } /* Compute the Real divider depending on the MCLK output state, with a floating point */ if(hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) { /* MCLK output is enabled */ tmp = (uint32_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5); } else { /* MCLK output is disabled */ tmp = (uint32_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5); } /* Remove the flatting point */ tmp = tmp / 10; /* Check the parity of the divider */ i2sodd = (uint32_t)(tmp & (uint32_t)1); /* Compute the i2sdiv prescaler */ i2sdiv = (uint32_t)((tmp - i2sodd) / 2); /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */ i2sodd = (uint32_t) (i2sodd << 8); } /* Test if the divider is 1 or 0 or greater than 0xFF */ if((i2sdiv < 2) || (i2sdiv > 0xFF)) { /* Set the default values */ i2sdiv = 2; i2sodd = 0; } /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */ /* And configure the I2S with the I2S_InitStruct values */ MODIFY_REG( hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN |\ SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD |\ SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG |\ SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD),\ (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode |\ hi2s->Init.Standard | hi2s->Init.DataFormat |\ hi2s->Init.CPOL)); /* Write to SPIx I2SPR register the computed value */ hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput)); hi2s->ErrorCode = HAL_I2S_ERROR_NONE; hi2s->State= HAL_I2S_STATE_READY; return HAL_OK; }