/** * @brief Enables the selected ADC software start conversion of the injected channels. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc) { __IO uint32_t counter = 0; uint32_t tmp1 = 0, tmp2 = 0; /* Process locked */ __HAL_LOCK(hadc); /* Check if a regular conversion is ongoing */ if (hadc->State == HAL_ADC_STATE_BUSY_REG) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ; } /* Check if ADC peripheral is disabled in order to enable it and wait during Tstab time the ADC's stabilization */ if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) { /* Enable the Peripheral */ __HAL_ADC_ENABLE(hadc); /* Delay for temperature sensor stabilization time */ /* Compute number of CPU cycles to wait for */ counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); while (counter != 0) { counter--; } } /* Check if Multimode enabled */ if (HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if (tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } else { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if ((hadc->Instance == ADC1) && tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Poll for injected conversion complete * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param Timeout: Timeout value in millisecond. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) { uint32_t tickstart = 0U; /* Get tick */ tickstart = HAL_GetTick(); /* Check End of conversion flag */ while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC))) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) { hadc->State= HAL_ADC_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_TIMEOUT; } } } /* Clear injected group conversion flag */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC); /* Update ADC state machine */ SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); /* Determine whether any further conversion upcoming on group injected */ /* by external trigger, continuous mode or scan sequence on going. */ /* Note: On STM32F4, there is no independent flag of end of sequence. */ /* The test of scan sequence on going is done either with scan */ /* sequence disabled or with end of conversion flag set to */ /* of end of sequence. */ if(ADC_IS_SOFTWARE_START_INJECTED(hadc) && (HAL_IS_BIT_CLR(hadc->Instance->JSQR, ADC_JSQR_JL) || HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) && (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) && (ADC_IS_SOFTWARE_START_REGULAR(hadc) && (hadc->Init.ContinuousConvMode == DISABLE) ) ) ) { /* Set ADC state */ CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) { SET_BIT(hadc->State, HAL_ADC_STATE_READY); } } /* Return ADC state */ return HAL_OK; }
/** * @brief Stop conversion of injected channels, disable interruption of * end-of-conversion. Disable ADC peripheral if no regular conversion * is on going. * @note If ADC must be disabled and if conversion is on going on * regular group, function HAL_ADC_Stop must be used to stop both * injected and regular groups, and disable the ADC. * @note If injected group mode auto-injection is enabled, * function HAL_ADC_Stop must be used. * @param hadc: ADC handle * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion and disable ADC peripheral */ /* Conditioned to: */ /* - No conversion on the other group (regular group) is intended to */ /* continue (injected and regular groups stop conversion and ADC disable */ /* are common) */ /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) { /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ __HAL_ADC_DISABLE(hadc); /* Check if ADC is effectively disabled */ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) { /* Disable ADC end of conversion interrupt for injected channels */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY); } } else { /* Update ADC state machine to error */ SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); tmp_hal_status = HAL_ERROR; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Resumes the audio stream playing from the Media. * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s) { /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_BUSY_TX) { /* Enable the I2S DMA Tx request */ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); } else if(hi2s->State == HAL_I2S_STATE_BUSY_RX) { /* Enable the I2S DMA Rx request */ SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); } /* If the I2S peripheral is still not enabled, enable it */ if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; }
/** * @brief Returns the last ADC Master&Slave regular conversions results data * in the selected multi mode. * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) * @retval The converted data value. */ uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc) { uint32_t tmpDR = 0; /* Check the parameters */ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Note: EOC flag is not cleared here by software because automatically */ /* cleared by hardware when reading register DR. */ /* On STM32F1 devices, ADC1 data register DR contains ADC2 conversions */ /* only if ADC1 DMA mode is enabled. */ tmpDR = hadc->Instance->DR; if (HAL_IS_BIT_CLR(ADC1->CR2, ADC_CR2_DMA)) { tmpDR |= (ADC2->DR << 16); } /* Return ADC converted value */ return tmpDR; }
/** * @brief Enables ADC, starts conversion of injected group with interruption. * - JEOC (end of conversion of injected group) * Each of these interruptions has its dedicated callback function. * @param hadc: ADC handle * @retval HAL status. */ HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Enable the ADC peripheral */ tmp_hal_status = ADC_Enable(hadc); /* Start conversion if ADC is effectively enabled */ if (tmp_hal_status != HAL_ERROR) { /* Check if a regular conversion is ongoing */ if(hadc->State == HAL_ADC_STATE_BUSY_REG) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ; } /* Process unlocked */ /* Unlock before starting ADC conversions: in case of potential */ /* interruption, to let the process to ADC IRQ Handler. */ __HAL_UNLOCK(hadc); /* Set ADC error code to none */ ADC_CLEAR_ERRORCODE(hadc); /* Clear injected group conversion flag */ /* (To ensure of no unknown state from potential previous ADC operations) */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); /* Enable end of conversion interrupt for injected channels */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); /* Enable conversion of injected group. */ /* If software start has been selected, conversion starts immediately. */ /* If external trigger has been selected, conversion will start at next */ /* trigger event. */ /* If automatic injected conversion is enabled, conversion will start */ /* after next regular group conversion. */ if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) { /* Enable ADC software conversion for injected channels */ SET_BIT(hadc->Instance->CR2, ADC_CR2_JSWSTART); } } /* Return function status */ return tmp_hal_status; }
/** * @brief DMA transfer complete callback. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void ADC_MultiModeDMAConvCplt(DMA_HandleTypeDef *hdma) { /* Retrieve ADC handle corresponding to current DMA handle */ ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* Update state machine on conversion status if not in error state */ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) { /* Update ADC state machine */ SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); /* Determine whether any further conversion upcoming on group regular */ /* by external trigger, continuous mode or scan sequence on going. */ /* Note: On STM32F4, there is no independent flag of end of sequence. */ /* The test of scan sequence on going is done either with scan */ /* sequence disabled or with end of conversion flag set to */ /* of end of sequence. */ if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && (hadc->Init.ContinuousConvMode == DISABLE) && (HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) || HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_EOCS) ) ) { /* Disable ADC end of single conversion interrupt on group regular */ /* Note: Overrun interrupt was enabled with EOC interrupt in */ /* HAL_ADC_Start_IT(), but is not disabled here because can be used */ /* by overrun IRQ process below. */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* Set ADC state */ CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) { SET_BIT(hadc->State, HAL_ADC_STATE_READY); } } /* Conversion complete callback */ HAL_ADC_ConvCpltCallback(hadc); } else { /* Call DMA error callback */ hadc->DMA_Handle->XferErrorCallback(hdma); } }
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_ADC_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ char ch; ch = 'x'; HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100); sprintf(strbuf,"Hello\n"); uint32_t adcvals[5]; HAL_ADC_Start(&hadc); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_ADC_Start(&hadc); for (int i=0;i<3;i++){ while(HAL_IS_BIT_CLR(hadc.Instance->ISR, (ADC_FLAG_EOC|ADC_FLAG_EOS))){} adcvals[i] = hadc.Instance->DR; } for (int i=0;i<5;i++){ sprintf(strbuf,"i:%d,adc:%4d ",i,adcvals[i]); HAL_UART_Transmit(&huart1,strbuf,strlen(strbuf),1000); } sprintf(strbuf,"\n"); HAL_UART_Transmit(&huart1,strbuf,strlen(strbuf),1000); HAL_Delay(1000); } /* USER CODE END 3 */ }
/** * @brief Enables ADC and starts conversion of the regular channels. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) { __IO uint32_t counter = 0; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge)); /* Process locked */ __HAL_LOCK(hadc); /* Check if an injected conversion is ongoing */ if (hadc->State == HAL_ADC_STATE_BUSY_INJ) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_REG; } /* Check if ADC peripheral is disabled in order to enable it and wait during Tstab time the ADC's stabilization */ if ((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) { /* Enable the Peripheral */ __HAL_ADC_ENABLE(hadc); /* Delay for ADC stabilization time */ /* Compute number of CPU cycles to wait for */ counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000)); while (counter != 0) { counter--; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Check if Multimode enabled */ if (HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { /* if no external trigger present enable software conversion of regular channels */ if ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET) { /* Enable the selected ADC software conversion for regular group */ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; } } else { /* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */ if ((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) { /* Enable the selected ADC software conversion for regular group */ hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART; } } /* Return function status */ return HAL_OK; }
/** * @brief DMA I2S receive process complete callback * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma) { I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; if(HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC)) { /* Disable Rx DMA Request */ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); hi2s->RxXferCount = 0; hi2s->State = HAL_I2S_STATE_READY; } HAL_I2S_RxCpltCallback(hi2s); }
/** * @brief Stop conversion of injected channels. Disable ADC peripheral if * no regular conversion is on going. * @note If ADC must be disabled with this function and if regular conversion * is on going, function HAL_ADC_Stop must be used preliminarily. * @note In case of auto-injection mode, HAL_ADC_Stop must be used. * @param hadc: ADC handle * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmpHALStatus = HAL_OK; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion and disable ADC peripheral */ /* Conditioned to: */ /* - No conversion on the other group (regular group) is intended to */ /* continue (injected and regular groups stop conversion and ADC disable */ /* are common) */ /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ if((hadc->State != HAL_ADC_STATE_BUSY_REG) && (hadc->State != HAL_ADC_STATE_BUSY_INJ_REG) && HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) { /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ tmpHALStatus = ADC_ConversionStop_Disable(hadc); /* Check if ADC is effectively disabled */ if (tmpHALStatus != HAL_ERROR) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_READY; } } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmpHALStatus = HAL_ERROR; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmpHALStatus; }
/** * @brief Disables ADC DMA (multi-ADC mode) and disables ADC peripheral * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; ADC_Common_TypeDef *tmpADC_Common; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ __HAL_ADC_DISABLE(hadc); /* Pointer to the common control register to which is belonging hadc */ /* (Depending on STM32F4 product, there may be up to 3 ADC and 1 common */ /* control register) */ tmpADC_Common = ADC_COMMON_REGISTER(hadc); /* Check if ADC is effectively disabled */ if(HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_ADON)) { /* Disable the selected ADC DMA mode for multimode */ tmpADC_Common->CCR &= ~ADC_CCR_DDS; /* Disable the DMA channel (in case of DMA in circular mode or stop while */ /* DMA transfer is on going) */ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); /* Disable ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); /* Set ADC state */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, HAL_ADC_STATE_READY); } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief DMA IRDA receive process complete callback. * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode */ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { hirda->RxXferCount = 0; /* Disable the DMA transfer for the receiver request by resetting the DMAR bit in the IRDA CR3 register */ hirda->Instance->CR3 &= ~(USART_CR3_DMAR); /* At end of Rx process, restore hirda->RxState to Ready */ hirda->RxState = HAL_IRDA_STATE_READY; } HAL_IRDA_RxCpltCallback(hirda); }
/** * @brief Enables the buffer of temperature sensor for the ADC, required when device is in mode low-power (low-power run, low-power sleep or stop mode) * This function must be called before function HAL_ADC_Init() * (in case of previous ADC operations: function HAL_ADC_DeInit() must be called first) * For more details on procedure and buffer current consumption, refer to device reference manual. * @note This is functional only if the LOCK is not set. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_EnableVREFINTTempSensor(void) { uint32_t tickstart = 0; /* Enable the Buffer for the ADC by setting EN_VREFINT bit and the ENBUF_SENSOR_ADC in the CFGR3 register */ SET_BIT(SYSCFG->CFGR3, (SYSCFG_CFGR3_ENBUF_SENSOR_ADC | SYSCFG_CFGR3_EN_VREFINT)); /* Wait for Vrefint buffer effectively enabled */ /* Get tick count */ tickstart = HAL_GetTick(); while(HAL_IS_BIT_CLR(SYSCFG->CFGR3, SYSCFG_CFGR3_VREFINT_ADC_RDYF)) { if((HAL_GetTick() - tickstart) > SYSCFG_BUF_TEMPSENSOR_ENABLE_TIMEOUT) { return HAL_ERROR; } } return HAL_OK; }
/** * @brief DMA IRDA transmit process complete callback. * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode */ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { hirda->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the IRDA CR3 register */ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT); /* Enable the IRDA Transmit Complete Interrupt */ __HAL_IRDA_ENABLE_IT(hirda, IRDA_IT_TC); } /* DMA Circular mode */ else { HAL_IRDA_TxCpltCallback(hirda); } }
/** * @brief DMA IRDA receive process complete callback. * @param hdma: Pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode */ if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) ) { hirda->RxXferCount = 0; /* Disable the DMA transfer for the receiver request by setting the DMAR bit in the IRDA CR3 register */ CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR); if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_TX; } else { hirda->State = HAL_IRDA_STATE_READY; } } HAL_IRDA_RxCpltCallback(hirda); }
/** * @brief Handles ADC interrupt request * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @retval None */ void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) { uint32_t tmp1 = 0, tmp2 = 0; /* Check the parameters */ assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); assert_param(IS_ADC_REGULAR_LENGTH(hadc->Init.NbrOfConversion)); assert_param(IS_ADC_EOCSelection(hadc->Init.EOCSelection)); tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC); /* Check End of conversion flag for regular channels */ if(tmp1 && tmp2) { /* Check if an injected conversion is ready */ if(hadc->State == HAL_ADC_STATE_EOC_INJ) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_EOC_REG; } if((hadc->Init.ContinuousConvMode == DISABLE) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET)) { if(hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV) { /* DISABLE the ADC end of conversion interrupt for regular group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* DISABLE the ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); } else { if (hadc->NbrOfCurrentConversionRank == 0) { hadc->NbrOfCurrentConversionRank = hadc->Init.NbrOfConversion; } /* Decrement the number of conversion when an interrupt occurs */ hadc->NbrOfCurrentConversionRank--; /* Check if all conversions are finished */ if(hadc->NbrOfCurrentConversionRank == 0) { /* DISABLE the ADC end of conversion interrupt for regular group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); /* DISABLE the ADC overrun interrupt */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR); } } } /* Conversion complete callback */ HAL_ADC_ConvCpltCallback(hadc); /* Clear the ADCx flag for regular end of conversion */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_EOC); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_JEOC); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_JEOC); /* Check End of conversion flag for injected channels */ if(tmp1 && tmp2) { /* Check if a regular conversion is ready */ 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; } tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); if(((hadc->Init.ContinuousConvMode == DISABLE) || tmp1) && tmp2) { /* DISABLE the ADC end of conversion interrupt for injected group */ __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); } /* Conversion complete callback */ HAL_ADCEx_InjectedConvCpltCallback(hadc); /* Clear the ADCx flag for injected end of conversion */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_JEOC); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD); /* Check Analog watchdog flag */ if(tmp1 && tmp2) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_AWD; /* Clear the ADCx's Analog watchdog flag */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_AWD); /* Level out of window callback */ HAL_ADC_LevelOutOfWindowCallback(hadc); } tmp1 = __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR); tmp2 = __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_OVR); /* Check Overrun flag */ if(tmp1 && tmp2) { /* Change ADC state to overrun state */ hadc->State = HAL_ADC_STATE_ERROR; /* Set ADC error code to overrun */ hadc->ErrorCode |= HAL_ADC_ERROR_OVR; /* Clear the Overrun flag */ __HAL_ADC_CLEAR_FLAG(hadc,ADC_FLAG_OVR); /* Error callback */ HAL_ADC_ErrorCallback(hadc); } }
/** * @brief Transmit and Receive an amount of data in non-blocking mode with DMA * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @param pTxData: a 16-bit pointer to the Transmit data buffer. * @param pRxData: a 16-bit pointer to the Receive data buffer. * @param Size: number of frames to be sent. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @retval HAL status */ HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size) { /* Check Mode parameter */ assert_param(IS_I2S_FD_MODE(hi2s->Init.Mode)); if((pTxData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { hi2s->pTxBuffPtr = pTxData; hi2s->pRxBuffPtr = pRxData; hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\ ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) { hi2s->TxXferSize = (Size << 1U); hi2s->TxXferCount = (Size << 1U); hi2s->RxXferSize = (Size << 1U); hi2s->RxXferCount = (Size << 1U); } else { hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; } /* Set the I2S Rx DMA Half transfert complete callback */ hi2s->hdmarx->XferHalfCpltCallback = I2SEx_DMATxRxHalfCplt; /* Set the I2S Rx DMA transfert complete callback */ hi2s->hdmarx->XferCpltCallback = I2SEx_DMATxRxCplt; /* Set the DMA error callback */ hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError; /* Enable the Rx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->RXDR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize); /* Check if the I2S Rx requests are already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN)) { /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Enable Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_RXDMAEN); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } } /* Set the I2S Tx DMA transfer callbacks as NULL because the communication closing is performed in DMA reception callbacks */ hi2s->hdmatx->XferHalfCpltCallback = NULL; hi2s->hdmatx->XferCpltCallback = NULL; hi2s->hdmatx->XferErrorCallback = NULL; /* Enable the Tx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->TXDR, hi2s->TxXferSize); /* Check if the I2S Tx requests are already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN)) { /* Check if the SPI2S is disabled to edit CFG1 register */ if ((hi2s->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) { /* Enable Tx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); } else { /* Disable SPI peripheral */ __HAL_I2S_DISABLE(hi2s); /* Enable Tx/Rx DMA Request */ SET_BIT(hi2s->Instance->CFG1, SPI_CFG1_TXDMAEN); /* Enable SPI peripheral */ __HAL_I2S_ENABLE(hi2s); } } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief AES CCM Authentication TAG generation. * @param hcryp: pointer to a CRYP_HandleTypeDef structure that contains * the configuration information for CRYP module * @param AuthTag: Pointer to the authentication buffer * @param Timeout: Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_CRYPEx_AESCCM_GenerateAuthTAG(CRYP_HandleTypeDef *hcryp, uint32_t *AuthTag, uint32_t Timeout) { uint32_t tagaddr = (uint32_t)AuthTag; uint32_t ctr0 [4]={0}; uint32_t ctr0addr = (uint32_t)ctr0; uint32_t tickstart = 0U; if(hcryp->State == HAL_CRYP_STATE_READY) { /* Process locked */ __HAL_LOCK(hcryp); /* Change the CRYP peripheral state */ hcryp->State = HAL_CRYP_STATE_BUSY; /* Check if initialization phase has already been performed */ if(hcryp->Phase == CRYPEx_PHASE_PROCESS) { /* Change the CRYP phase */ hcryp->Phase = CRYPEx_PHASE_FINAL; } else /* Initialization phase has not been performed*/ { /* Disable the peripheral */ __HAL_CRYP_DISABLE(hcryp); /* Sequence error code field */ hcryp->ErrorCode |= HAL_CRYP_ERROR_AUTH_TAG_SEQUENCE; /* Change the CRYP peripheral state */ hcryp->State = HAL_CRYP_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hcryp); return HAL_ERROR; } /* Disable CRYP to start the final phase */ __HAL_CRYP_DISABLE(hcryp); /* Select final phase & ALGODIR bit must be set to ‘0’. */ MODIFY_REG(hcryp->Instance->CR, CRYP_CR_GCM_CCMPH|CRYP_CR_ALGODIR, CRYP_PHASE_FINAL|CRYP_OPERATINGMODE_ENCRYPT); /* Enable the CRYP peripheral */ __HAL_CRYP_ENABLE(hcryp); /* Write the counter block in the IN FIFO, CTR0 information from B0 data has to be swapped according to the DATATYPE*/ ctr0[0]=(hcryp->Init.B0[0]) & CRYP_CCM_CTR0_0; ctr0[1]=hcryp->Init.B0[1]; ctr0[2]=hcryp->Init.B0[2]; ctr0[3]=hcryp->Init.B0[3] & CRYP_CCM_CTR0_3; if(hcryp->Init.DataType == CRYP_DATATYPE_8B) { hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __REV(*(uint32_t*)(ctr0addr)); } else if(hcryp->Init.DataType == CRYP_DATATYPE_16B) { hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U); ctr0addr+=4; hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U); ctr0addr+=4; hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U); ctr0addr+=4; hcryp->Instance->DIN = __ROR(*(uint32_t*)(ctr0addr), 16U); } else if(hcryp->Init.DataType == CRYP_DATATYPE_1B) { hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr)); ctr0addr+=4; hcryp->Instance->DIN = __RBIT(*(uint32_t*)(ctr0addr)); } else { hcryp->Instance->DIN = *(uint32_t*)(ctr0addr); ctr0addr+=4; hcryp->Instance->DIN = *(uint32_t*)(ctr0addr); ctr0addr+=4; hcryp->Instance->DIN = *(uint32_t*)(ctr0addr); ctr0addr+=4; hcryp->Instance->DIN = *(uint32_t*)(ctr0addr);; } /* Wait for OFNE flag to be raised */ tickstart = HAL_GetTick(); while(HAL_IS_BIT_CLR(hcryp->Instance->SR, CRYP_FLAG_OFNE)) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) { /* Disable the CRYP peripheral Clock */ __HAL_CRYP_DISABLE(hcryp); /* Change state */ hcryp->ErrorCode |= HAL_CRYP_ERROR_TIMEOUT; hcryp->State = HAL_CRYP_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hcryp); return HAL_ERROR; } } } /* Read the Auth TAG in the IN FIFO */ *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; tagaddr+=4U; *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; tagaddr+=4U; *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; tagaddr+=4U; *(uint32_t*)(tagaddr) = hcryp->Instance->DOUT; /* Change the CRYP peripheral state */ hcryp->State = HAL_CRYP_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hcryp); /* Disable CRYP */ __HAL_CRYP_DISABLE(hcryp); } else { /* Busy error code field */ hcryp->ErrorCode = HAL_CRYP_ERROR_BUSY; return HAL_ERROR; } /* Return function status */ return HAL_OK; }
/** * @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 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. */ /* Note: Variable "conversion_timeout_cpu_cycles" set to offset 28 CPU */ /* cycles to compensate number of CPU cycles for processing of variable */ /* "conversion_timeout_cpu_cycles_max" */ uint32_t conversion_timeout_cpu_cycles = 28; 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 setting "EOCSelection" is set to poll for each single conversion, */ /* management of polling depends on setting of injected group sequencer: */ /* - 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 ADC clock cycles) and APB2/ADC clock prescalers (depending on */ /* settings, conversion time range can vary from 8 to several thousands */ /* of CPU cycles). */ /* Note: On STM32L1, setting "EOCSelection" is related to regular group */ /* only, by hardware. For compatibility with other STM32 devices, */ /* this setting is related also to injected group by software. */ if (((hadc->Instance->JSQR & ADC_JSQR_JL) == RESET) || (hadc->Init.EOCSelection != EOC_SINGLE_CONV) ) { /* 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 { /* Computation of CPU cycles corresponding to ADC conversion cycles. */ /* Retrieve ADC clock prescaler and ADC maximum conversion cycles on all */ /* channels. */ conversion_timeout_cpu_cycles_max = __ADC_GET_CLOCK_PRESCALER_DECIMAL(hadc); conversion_timeout_cpu_cycles_max *= __ADC_CONVCYCLES_MAX_RANGE(hadc); /* Poll with maximum conversion time */ 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 end of conversion flag of injected group if low power feature */ /* "Auto Wait" is disabled, to not interfere with this feature until data */ /* register is read using function HAL_ADCEx_InjectedGetValue(). */ if (hadc->Init.LowPowerAutoWait == DISABLE) { /* Clear injected group conversion flag */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC); } /* 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 Enables the interrupt and starts ADC conversion of injected channels. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * * @retval HAL status. */ HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc) { __IO uint32_t counter = 0U; uint32_t tmp1 = 0U, tmp2 = 0U; /* Process locked */ __HAL_LOCK(hadc); /* Enable the ADC peripheral */ /* Check if ADC peripheral is disabled in order to enable it and wait during Tstab time the ADC's stabilization */ if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) { /* Enable the Peripheral */ __HAL_ADC_ENABLE(hadc); /* Delay for ADC stabilization time */ /* Compute number of CPU cycles to wait for */ counter = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); while(counter != 0U) { counter--; } } /* Start conversion if ADC is effectively enabled */ if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_ADON)) { /* Set ADC state */ /* - Clear state bitfield related to injected group conversion results */ /* - Set state bitfield related to injected operation */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); /* Check if a regular conversion is ongoing */ /* Note: On this device, there is no ADC error code fields related to */ /* conversions on group injected only. In case of conversion on */ /* going on group regular, no error code is reset. */ if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) { /* Reset ADC all error code fields */ ADC_CLEAR_ERRORCODE(hadc); } /* Process unlocked */ /* Unlock before starting ADC conversions: in case of potential */ /* interruption, to let the process to ADC IRQ Handler. */ __HAL_UNLOCK(hadc); /* Clear injected group conversion flag */ /* (To ensure of no unknown state from potential previous ADC operations) */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); /* Enable end of conversion interrupt for injected channels */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); /* Check if Multimode enabled */ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if(tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } else { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if((hadc->Instance == ADC1) && tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } } /* Return function status */ return HAL_OK; }
/** * @brief Receive data in blocking mode. * @param hcec: CEC handle * @param pData: pointer to received data buffer. * @param Timeout: Timeout duration. * @note The received data size is not known beforehand, the latter is known * when the reception is complete and is stored in hcec->RxXferSize. * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max). * If only a header is received, hcec->RxXferSize = 0 * @retval HAL status */ HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout) { uint32_t temp = 0; uint32_t tickstart = 0; if(hcec->State == HAL_CEC_STATE_READY) { if(pData == NULL) { return HAL_ERROR; } /* When a ping is received, RxXferSize is 0*/ /* When a message is received, RxXferSize contains the number of received bytes */ hcec->RxXferSize = CEC_RXXFERSIZE_INITIALIZE; /* Process Locked */ __HAL_LOCK(hcec); hcec->ErrorCode = HAL_CEC_ERROR_NONE; /* Continue the reception until the End Of Message is received (CEC_FLAG_REOM) */ do { /* Timeout handling */ tickstart = HAL_GetTick(); /* Wait for next byte to be received */ while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_RBTF)) { /* Timeout handling */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } /* Check if an error occured during the reception */ if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR)) { /* Copy ESR for error handling purposes */ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* Keep the value of CSR register as the register is cleared during reception process */ temp = hcec->Instance->CSR; /* Read received data */ *pData++ = hcec->Instance->RXD; /* Acknowledge received byte by writing 0x00 */ CLEAR_BIT(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK); /* Increment the number of received data */ if(hcec->RxXferSize == CEC_RXXFERSIZE_INITIALIZE) { hcec->RxXferSize = 0; } else { hcec->RxXferSize++; } }while (HAL_IS_BIT_CLR(temp, CEC_FLAG_REOM)); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); if(IS_CEC_MSGSIZE(hcec->RxXferSize)) { return HAL_OK; } else { return HAL_ERROR; } } else { return HAL_BUSY; } }
/** * @brief Receive an amount of data in non-blocking mode with DMA * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @param pData: a 16-bit pointer to the Receive data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { hi2s->pRxBuffPtr = pData; hi2s->State = HAL_I2S_STATE_BUSY_RX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\ ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) { hi2s->RxXferSize = (Size << 1); hi2s->RxXferCount = (Size << 1); } else { hi2s->RxXferSize = Size; hi2s->RxXferCount = Size; } /* Set the I2S Rx DMA Half transfert complete callback */ hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt; /* Set the I2S Rx DMA transfert complete callback */ hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt; /* Set the DMA error callback */ hi2s->hdmarx->XferErrorCallback = I2S_DMAError; /* Check if Master Receiver mode is selected */ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) { /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read access to the SPI_SR register. */ __HAL_I2S_CLEAR_OVRFLAG(hi2s); } /* Enable the Rx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize); /* Check if the I2S is already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Check if the I2S Rx request is already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN)) { /* Enable Rx DMA Request */ SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN); } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief Transmit an amount of data in non-blocking mode with DMA * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @param pData: a 16-bit pointer to the Transmit data buffer. * @param Size: number of data sample to be sent: * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S * configuration phase, the Size parameter means the number of 16-bit data length * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected * the Size parameter means the number of 16-bit data length. * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization * between Master and Slave(example: audio streaming). * @retval HAL status */ HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { hi2s->pTxBuffPtr = pData; hi2s->State = HAL_I2S_STATE_BUSY_TX; hi2s->ErrorCode = HAL_I2S_ERROR_NONE; if(((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\ ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) { hi2s->TxXferSize = (Size << 1); hi2s->TxXferCount = (Size << 1); } else { hi2s->TxXferSize = Size; hi2s->TxXferCount = Size; } /* Set the I2S Tx DMA Half transfert complete callback */ hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt; /* Set the I2S Tx DMA transfert complete callback */ hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt; /* Set the DMA error callback */ hi2s->hdmatx->XferErrorCallback = I2S_DMAError; /* Enable the Tx DMA Channel */ HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize); /* Check if the I2S is already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Check if the I2S Tx request is already enabled */ if(HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN)) { /* Enable Tx DMA Request */ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN); } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief Enables the interrupt and starts ADC conversion of injected channels. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * * @retval HAL status. */ HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc) { uint32_t i = 0, tmp1 = 0, tmp2 =0; /* Process locked */ __HAL_LOCK(hadc); /* Check if a regular conversion is ongoing */ if(hadc->State == HAL_ADC_STATE_BUSY_REG) { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ_REG; } else { /* Change ADC state */ hadc->State = HAL_ADC_STATE_BUSY_INJ; } /* Set ADC error code to none */ hadc->ErrorCode = HAL_ADC_ERROR_NONE; /* Check if ADC peripheral is disabled in order to enable it and wait during Tstab time the ADC's stabilization */ if((hadc->Instance->CR2 & ADC_CR2_ADON) != ADC_CR2_ADON) { /* Enable the Peripheral */ __HAL_ADC_ENABLE(hadc); /* Delay inserted to wait during Tstab time the ADC's stabilazation */ for(; i <= 540; i++) { __NOP(); } } /* Enable the ADC end of conversion interrupt for injected group */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); /* Enable the ADC overrun interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); /* Check if Multimode enabled */ if(HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI)) { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if(tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } else { tmp1 = HAL_IS_BIT_CLR(hadc->Instance->CR2, ADC_CR2_JEXTEN); tmp2 = HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO); if((hadc->Instance == ADC1) && tmp1 && tmp2) { /* Enable the selected ADC software conversion for injected group */ hadc->Instance->CR2 |= ADC_CR2_JSWSTART; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Send data in blocking mode * @param hcec: CEC handle * @param DestinationAddress: destination logical address * @param pData: pointer to input byte data buffer * @param Size: amount of data to be sent in bytes (without counting the header). * 0 means only the header is sent (ping operation). * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout) { uint8_t temp = 0; uint32_t tempisr = 0; uint32_t tickstart = 0; if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) { hcec->ErrorCode = HAL_CEC_ERROR_NONE; if((pData == NULL ) && (Size > 0)) { hcec->State = HAL_CEC_STATE_ERROR; return HAL_ERROR; } assert_param(IS_CEC_ADDRESS(DestinationAddress)); assert_param(IS_CEC_MSGSIZE(Size)); /* Process Locked */ __HAL_LOCK(hcec); hcec->State = HAL_CEC_STATE_BUSY_TX; hcec->TxXferCount = Size; /* case no data to be sent, sender is only pinging the system */ if (Size == 0) { /* Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); } /* send header block */ temp = ((uint32_t)hcec->Init.InitiatorAddress << CEC_INITIATOR_LSB_POS) | DestinationAddress; hcec->Instance->TXDR = temp; /* Set TX Start of Message (TXSOM) bit */ __HAL_CEC_FIRST_BYTE_TX_SET(hcec); while (hcec->TxXferCount > 0) { hcec->TxXferCount--; tickstart = HAL_GetTick(); while(HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_TXBR)) { if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } /* check whether error occurred while waiting for TXBR to be set: * has Tx underrun occurred ? * has Tx error occurred ? * has Tx Missing Acknowledge error occurred ? * has Arbitration Loss error occurred ? */ tempisr = hcec->Instance->ISR; if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)); hcec->State = HAL_CEC_STATE_ERROR; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* TXBR to clear BEFORE writing TXDR register */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXBR); if (hcec->TxXferCount == 0) { /* if last byte transmission, set TX End of Message (TXEOM) bit */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); } hcec->Instance->TXDR = *pData++; /* error check after TX byte write up */ tempisr = hcec->Instance->ISR; if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)); hcec->State = HAL_CEC_STATE_ERROR; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* end while (while (hcec->TxXferCount > 0)) */ /* if no error up to this point, check that transmission is * complete, that is wait until TXEOM is reset */ tickstart = HAL_GetTick(); while (HAL_IS_BIT_SET(hcec->Instance->CR, CEC_CR_TXEOM)) { if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_ERROR; __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } } /* Final error check once all bytes have been transmitted */ tempisr = hcec->Instance->ISR; if ((tempisr & (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)); hcec->State = HAL_CEC_STATE_ERROR; __HAL_UNLOCK(hcec); return HAL_ERROR; } hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Send data in blocking mode * @param hcec: CEC handle * @param DestinationAddress: destination logical address * @param pData: pointer to input byte data buffer * @param Size: amount of data to be sent in bytes (without counting the header). * 0 means only the header is sent (ping operation). * Maximum TX size is 15 bytes (1 opcode and up to 14 operands). * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_CEC_Transmit(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size, uint32_t Timeout) { uint8_t temp = 0; uint32_t tickstart = 0; /* If the IP is ready */ if((hcec->State == HAL_CEC_STATE_READY) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) { /* Basic check on pData pointer */ if(((pData == NULL) && (Size > 0)) || (! IS_CEC_MSGSIZE(Size))) { return HAL_ERROR; } assert_param(IS_CEC_ADDRESS(DestinationAddress)); /* Process Locked */ __HAL_LOCK(hcec); /* Enter the transmit mode */ hcec->State = HAL_CEC_STATE_BUSY_TX; hcec->ErrorCode = HAL_CEC_ERROR_NONE; /* Initialize the number of bytes to send, * 0 means only one header is sent (ping operation) */ hcec->TxXferCount = Size; /* Send header block */ temp = (uint8_t)((uint32_t)(hcec->Init.InitiatorAddress) << CEC_INITIATOR_LSB_POS) | DestinationAddress; hcec->Instance->TXD = temp; /* In case no data to be sent, sender is only pinging the system */ if (Size != 0) { /* Set TX Start of Message (TXSOM) bit */ hcec->Instance->CSR = CEC_FLAG_TSOM; } else { /* Send a ping command */ hcec->Instance->CSR = CEC_FLAG_TEOM|CEC_FLAG_TSOM; } /* Polling TBTRF bit with timeout handling*/ while (hcec->TxXferCount > 0) { /* Decreasing of the number of remaining data to receive */ hcec->TxXferCount--; /* Timeout handling */ tickstart = HAL_GetTick(); /* Waiting for the next data transmission */ while(HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF)) { /* Timeout handling */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } /* Check if an error occured */ if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR)) { /* Copy ESR for error handling purposes */ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR); __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* Write the next data to TX buffer */ hcec->Instance->TXD = *pData++; /* If this is the last byte of the ongoing transmission */ if (hcec->TxXferCount == 0) { /* Acknowledge byte request and signal end of message */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, CEC_FLAG_TEOM); } else { /* Acknowledge byte request by writing 0x00 */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00); } } /* Timeout handling */ tickstart = HAL_GetTick(); /* Wait for message transmission completion (TBTRF is set) */ while (HAL_IS_BIT_CLR(hcec->Instance->CSR, CEC_FLAG_TBTRF)) { /* Timeout handling */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } /* Check of error during transmission of the last byte */ if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR)) { /* Copy ESR for error handling purposes */ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR); __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* Check of error after the last byte transmission */ if(HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_TERR) || HAL_IS_BIT_SET(hcec->Instance->CSR, CEC_FLAG_RERR)) { /* Copy ESR for error handling purposes */ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR); __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_ERROR; } /* Acknowledge successful completion by writing 0x00 */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Receive data in blocking mode. Must be invoked when RXBR has been set. * @param hcec: CEC handle * @param pData: pointer to received data buffer. * @param Timeout: Timeout duration. * Note that the received data size is not known beforehand, the latter is known * when the reception is complete and is stored in hcec->RxXferSize. * hcec->RxXferSize is the sum of opcodes + operands (0 to 14 operands max). * If only a header is received, hcec->RxXferSize = 0 * @retval HAL status */ HAL_StatusTypeDef HAL_CEC_Receive(CEC_HandleTypeDef *hcec, uint8_t *pData, uint32_t Timeout) { uint32_t temp; uint32_t tickstart = 0; if (hcec->State == HAL_CEC_STATE_READY) { hcec->ErrorCode = HAL_CEC_ERROR_NONE; if (pData == NULL ) { hcec->State = HAL_CEC_STATE_ERROR; return HAL_ERROR; } hcec->RxXferSize = 0; /* Process Locked */ __HAL_LOCK(hcec); /* Rx loop until CEC_ISR_RXEND is set */ while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXEND)) { tickstart = HAL_GetTick(); /* Wait for next byte to be received */ while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_FLAG_RXBR)) { if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { hcec->State = HAL_CEC_STATE_TIMEOUT; __HAL_UNLOCK(hcec); return HAL_TIMEOUT; } } /* any error so far ? * has Rx Missing Acknowledge occurred ? * has Rx Long Bit Period error occurred ? * has Rx Short Bit Period error occurred ? * has Rx Bit Rising error occurred ? * has Rx Overrun error occurred ? */ temp = (uint32_t) (hcec->Instance->ISR); if ((temp & (CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = temp; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec,(CEC_FLAG_RXACKE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|CEC_FLAG_BRE|CEC_FLAG_RXOVR)); hcec->State = HAL_CEC_STATE_ERROR; __HAL_UNLOCK(hcec); return HAL_ERROR; } } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXBR)) */ /* read received data */ *pData++ = hcec->Instance->RXDR; temp = (uint32_t) (hcec->Instance->ISR); /* end of message ? */ if ((temp & CEC_ISR_RXEND) != 0) { assert_param(IS_CEC_MSGSIZE(hcec->RxXferSize)); __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXEND); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_OK; } /* clear Rx-Byte Received flag */ __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_RXBR); /* increment payload byte counter */ hcec->RxXferSize++; } /* while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND)) */ /* if the instructions below are executed, it means RXEND was set when RXBR was * set for the first time: * the code within the "while (HAL_IS_BIT_CLR(hcec->Instance->ISR, CEC_ISR_RXEND))" * loop has not been executed and this means a single byte has been sent */ *pData++ = hcec->Instance->RXDR; /* only one header is received: RxXferSize is set to 0 (no operand, no opcode) */ hcec->RxXferSize = 0; __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND); hcec->State = HAL_CEC_STATE_READY; __HAL_UNLOCK(hcec); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief This function handles FLASH interrupt request. * @retval None */ void HAL_FLASH_IRQHandler(void) { uint32_t addresstmp = 0; /* Check FLASH operation error flags */ #if defined(FLASH_BANK2_END) if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \ (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))) #else if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR)) #endif /* FLASH_BANK2_END */ { /*return the faulty address*/ addresstmp = pFlash.Address; /* Reset address */ pFlash.Address = 0xFFFFFFFF; /*Save the Error code*/ FLASH_SetErrorCode(); /* FLASH error interrupt user callback */ HAL_FLASH_OperationErrorCallback(addresstmp); /* Stop the procedure ongoing*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } /* Check FLASH End of Operation flag */ #if defined(FLASH_BANK2_END) if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1); #else if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) { /* Clear FLASH End of Operation pending bit */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); #endif /* FLASH_BANK2_END */ /* Process can continue only if no error detected */ if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE) { if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE) { /* Nb of pages to erased can be decreased */ pFlash.DataRemaining--; /* Check if there are still pages to erase*/ if(pFlash.DataRemaining != 0) { addresstmp = pFlash.Address; /*Indicate user which sector has been erased*/ HAL_FLASH_EndOfOperationCallback(addresstmp); /*Increment sector number*/ addresstmp = pFlash.Address + FLASH_PAGE_SIZE; pFlash.Address = addresstmp; /* If the erase operation is completed, disable the PER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PER); FLASH_PageErase(addresstmp); } else { /*No more pages to Erase, user callback can be called.*/ /*Reset Sector and stop Erase pages procedure*/ pFlash.Address = addresstmp = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(addresstmp); } } else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) { /* Operation is completed, disable the MER Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_MER); #if defined(FLASH_BANK2_END) /* Stop Mass Erase procedure if no pending mass erase on other bank */ if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER)) { #endif /* FLASH_BANK2_END */ /* MassErase ended. Return the selected bank*/ /* FLASH EOP interrupt user callback */ HAL_FLASH_EndOfOperationCallback(0); /* Stop Mass Erase procedure*/ pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } #if defined(FLASH_BANK2_END) } #endif /* FLASH_BANK2_END */ else { /* Nb of 16-bit data to program can be decreased */ pFlash.DataRemaining--; /* Check if there are still 16-bit data to program */ if(pFlash.DataRemaining != 0) { /* Increment address to 16-bit */ pFlash.Address += 2; addresstmp = pFlash.Address; /* Shift to have next 16-bit data */ pFlash.Data = (pFlash.Data >> 16); /* Operation is completed, disable the PG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); /*Program halfword (16-bit) at a specified address.*/ FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data); } else { /*Program ended. Return the selected address*/ /* FLASH EOP interrupt user callback */ if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD) { HAL_FLASH_EndOfOperationCallback(pFlash.Address); } else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD) { HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2); } else { HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6); } /* Reset Address and stop Program procedure*/ pFlash.Address = 0xFFFFFFFF; pFlash.ProcedureOnGoing = FLASH_PROC_NONE; } } } }