/** * @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); /* Start conversion of injected group if software start has been selected */ /* and if automatic injected conversion is disabled. */ /* 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 (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)) { if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) ) { /* Start ADC conversion on injected group with SW start */ SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG)); } else { /* Start ADC conversion on injected group with external trigger */ SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG); } } } else { /* Process unlocked */ __HAL_UNLOCK(hadc); } /* Return function status */ return tmp_hal_status; }
/** * @brief Enables ADC DMA request after last transfer (Multi-ADC mode) and enables ADC peripheral * * @note Caution: This function must be used only with the ADC master. * * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param pData: Pointer to buffer in which transferred from ADC peripheral to memory will be stored. * @param Length: The length of data to be transferred from ADC peripheral to memory. * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) { __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)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests)); /* Process locked */ __HAL_LOCK(hadc); /* 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--; } } /* 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 regular group conversion results */ /* - Set state bitfield related to regular group operation */ ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR, HAL_ADC_STATE_REG_BUSY); /* If conversions on group regular are also triggering group injected, */ /* update ADC state. */ if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) { ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); } /* State machine update: Check if an injected conversion is ongoing */ if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) { /* Reset ADC error code fields related to conversions on group regular */ CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); } else { /* 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); /* Set the DMA transfer complete callback */ hadc->DMA_Handle->XferCpltCallback = ADC_MultiModeDMAConvCplt; /* Set the DMA half transfer complete callback */ hadc->DMA_Handle->XferHalfCpltCallback = ADC_MultiModeDMAHalfConvCplt; /* Set the DMA error callback */ hadc->DMA_Handle->XferErrorCallback = ADC_MultiModeDMAError ; /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ /* start (in case of SW start): */ /* Clear regular group conversion flag and overrun flag */ /* (To ensure of no unknown state from potential previous ADC operations) */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); /* Enable ADC overrun interrupt */ __HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR); if (hadc->Init.DMAContinuousRequests != DISABLE) { /* Enable the selected ADC DMA request after last transfer */ ADC->CCR |= ADC_CCR_DDS; } else { /* Disable the selected ADC EOC rising on each regular channel conversion */ ADC->CCR &= ~ADC_CCR_DDS; } /* Enable the DMA Stream */ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&ADC->CDR, (uint32_t)pData, Length); /* 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; } } /* Return function status */ return HAL_OK; }
/** * @brief Writes a half-word buffer to the NOR memory. This function must be used only with S29GL128P NOR memory. * @param hnor: pointer to the NOR handle * @param uwAddress: NOR memory internal start write address * @param pData: pointer to source data buffer. * @param uwBufferSize: Size of the buffer to write * @retval HAL status */ HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) { uint16_t * p_currentaddress = (uint16_t *)NULL; uint16_t * p_endaddress = (uint16_t *)NULL; uint32_t lastloadedaddress = 0, deviceaddress = 0; /* Process Locked */ __HAL_LOCK(hnor); /* Check the NOR controller state */ if(hnor->State == HAL_NOR_STATE_BUSY) { return HAL_BUSY; } /* Select the NOR device address */ if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) { deviceaddress = NOR_MEMORY_ADRESS1; } else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) { deviceaddress = NOR_MEMORY_ADRESS2; } else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) { deviceaddress = NOR_MEMORY_ADRESS3; } else /* FMC_NORSRAM_BANK4 */ { deviceaddress = NOR_MEMORY_ADRESS4; } /* Update the NOR controller state */ hnor->State = HAL_NOR_STATE_BUSY; /* Initialize variables */ p_currentaddress = (uint16_t*)((uint32_t)(uwAddress)); p_endaddress = p_currentaddress + (uwBufferSize-1); lastloadedaddress = (uint32_t)(uwAddress); /* Issue unlock command sequence */ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); /* Write Buffer Load Command */ NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG); NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, NOR_MEMORY_8B, uwAddress), (uwBufferSize - 1)); /* Load Data into NOR Buffer */ while(p_currentaddress <= p_endaddress) { /* Store last loaded address & data value (for polling) */ lastloadedaddress = (uint32_t)p_currentaddress; NOR_WRITE(p_currentaddress, *pData++); p_currentaddress ++; } NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM); /* Check the NOR controller state */ hnor->State = HAL_NOR_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hnor); return HAL_OK; }
/** * @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((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Check if the I2S Tx request is already enabled */ if((hi2s->Instance->CR2 & SPI_CR2_TXDMAEN) != SPI_CR2_TXDMAEN) { /* Enable Tx DMA Request */ hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN; } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief Initializes the LCD peripheral according to the specified parameters * in the LCD_InitStruct. * @note This function can be used only when the LCD is disabled. * The LCD HighDrive can be enabled/disabled using related macros up to user. * @param hlcd: LCD handle * @retval None */ HAL_StatusTypeDef HAL_LCD_Init(LCD_HandleTypeDef *hlcd) { uint32_t tickstart = 0x00; uint8_t counter = 0; /* Check the LCD handle allocation */ if(hlcd == NULL) { return HAL_ERROR; } /* Check function parameters */ assert_param(IS_LCD_ALL_INSTANCE(hlcd->Instance)); assert_param(IS_LCD_PRESCALER(hlcd->Init.Prescaler)); assert_param(IS_LCD_DIVIDER(hlcd->Init.Divider)); assert_param(IS_LCD_DUTY(hlcd->Init.Duty)); assert_param(IS_LCD_BIAS(hlcd->Init.Bias)); assert_param(IS_LCD_VOLTAGE_SOURCE(hlcd->Init.VoltageSource)); assert_param(IS_LCD_PULSE_ON_DURATION(hlcd->Init.PulseOnDuration)); assert_param(IS_LCD_HIGHDRIVE(hlcd->Init.HighDrive)); assert_param(IS_LCD_DEAD_TIME(hlcd->Init.DeadTime)); assert_param(IS_LCD_CONTRAST(hlcd->Init.Contrast)); assert_param(IS_LCD_BLINK_FREQUENCY(hlcd->Init.BlinkFrequency)); assert_param(IS_LCD_BLINK_MODE(hlcd->Init.BlinkMode)); assert_param(IS_LCD_MUXSEGMENT(hlcd->Init.MuxSegment)); if(hlcd->State == HAL_LCD_STATE_RESET) { /* Allocate lock resource and initialize it */ __HAL_UNLOCK(hlcd); /* Initialize the low level hardware (MSP) */ HAL_LCD_MspInit(hlcd); } hlcd->State = HAL_LCD_STATE_BUSY; /* Disable the peripheral */ __HAL_LCD_DISABLE(hlcd); /* Clear the LCD_RAM registers and enable the display request by setting the UDR bit in the LCD_SR register */ for(counter = LCD_RAM_REGISTER0; counter <= LCD_RAM_REGISTER15; counter++) { hlcd->Instance->RAM[counter] = 0; } /* Enable the display request */ SET_BIT(hlcd->Instance->SR, LCD_SR_UDR); /* Configure the LCD Prescaler, Divider, Blink mode and Blink Frequency: Set PS[3:0] bits according to hlcd->Init.Prescaler value Set DIV[3:0] bits according to hlcd->Init.Divider value Set BLINK[1:0] bits according to hlcd->Init.BlinkMode value Set BLINKF[2:0] bits according to hlcd->Init.BlinkFrequency value Set DEAD[2:0] bits according to hlcd->Init.DeadTime value Set PON[2:0] bits according to hlcd->Init.PulseOnDuration value Set CC[2:0] bits according to hlcd->Init.Contrast value Set HD[0] bit according to hlcd->Init.HighDrive value*/ MODIFY_REG(hlcd->Instance->FCR, \ (LCD_FCR_PS | LCD_FCR_DIV | LCD_FCR_BLINK| LCD_FCR_BLINKF | \ LCD_FCR_DEAD | LCD_FCR_PON | LCD_FCR_CC), \ (hlcd->Init.Prescaler | hlcd->Init.Divider | hlcd->Init.BlinkMode | hlcd->Init.BlinkFrequency | \ hlcd->Init.DeadTime | hlcd->Init.PulseOnDuration | hlcd->Init.Contrast | hlcd->Init.HighDrive)); /* Wait until LCD Frame Control Register Synchronization flag (FCRSF) is set in the LCD_SR register This bit is set by hardware each time the LCD_FCR register is updated in the LCDCLK domain. It is cleared by hardware when writing to the LCD_FCR register.*/ LCD_WaitForSynchro(hlcd); /* Configure the LCD Duty, Bias, Voltage Source, Dead Time: Set DUTY[2:0] bits according to hlcd->Init.Duty value Set BIAS[1:0] bits according to hlcd->Init.Bias value Set VSEL bit according to hlcd->Init.VoltageSource value Set MUX_SEG bit according to hlcd->Init.MuxSegment value */ MODIFY_REG(hlcd->Instance->CR, \ (LCD_CR_DUTY | LCD_CR_BIAS | LCD_CR_VSEL | LCD_CR_MUX_SEG), \ (hlcd->Init.Duty | hlcd->Init.Bias | hlcd->Init.VoltageSource | hlcd->Init.MuxSegment)); /* Enable the peripheral */ __HAL_LCD_ENABLE(hlcd); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait Until the LCD is enabled */ while(__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_ENS) == RESET) { if((HAL_GetTick() - tickstart ) > LCD_TIMEOUT_VALUE) { hlcd->ErrorCode = HAL_LCD_ERROR_ENS; return HAL_TIMEOUT; } } /* Get timeout */ tickstart = HAL_GetTick(); /*!< Wait Until the LCD Booster is ready */ while(__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_RDY) == RESET) { if((HAL_GetTick() - tickstart ) > LCD_TIMEOUT_VALUE) { hlcd->ErrorCode = HAL_LCD_ERROR_RDY; return HAL_TIMEOUT; } } /* Initialize the LCD state */ hlcd->ErrorCode = HAL_LCD_ERROR_NONE; hlcd->State= HAL_LCD_STATE_READY; return HAL_OK; }
/** * @brief Open and configure an endpoint * @param hpcd: PCD handle * @param ep_addr: endpoint address * @param ep_mps: endpoint max packert size * @param ep_type: endpoint type * @retval HAL status */ HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type) { HAL_StatusTypeDef ret = HAL_OK; PCD_EPTypeDef *ep; if ((ep_addr & 0x80) == 0x80) { ep = &hpcd->IN_ep[ep_addr & 0x7F]; } else { ep = &hpcd->OUT_ep[ep_addr & 0x7F]; } ep->num = ep_addr & 0x7F; ep->is_in = (0x80 & ep_addr) != 0; ep->maxpacket = ep_mps; ep->type = ep_type; __HAL_LOCK(hpcd); /* initialize Endpoint */ switch (ep->type) { case PCD_EP_TYPE_CTRL: PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_CONTROL); break; case PCD_EP_TYPE_BULK: PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_BULK); break; case PCD_EP_TYPE_INTR: PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_INTERRUPT); break; case PCD_EP_TYPE_ISOC: PCD_SET_EPTYPE(hpcd->Instance, ep->num, USB_EP_ISOCHRONOUS); break; } PCD_SET_EP_ADDRESS(hpcd->Instance, ep->num, ep->num); if (ep->doublebuffer == 0) { if (ep->is_in) { /*Set the endpoint Transmit buffer address */ PCD_SET_EP_TX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress); PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); /* Configure NAK status for the Endpoint*/ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_NAK); } else { /*Set the endpoint Receive buffer address */ PCD_SET_EP_RX_ADDRESS(hpcd->Instance, ep->num, ep->pmaadress); /*Set the endpoint Receive buffer counter*/ PCD_SET_EP_RX_CNT(hpcd->Instance, ep->num, ep->maxpacket); PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); /* Configure VALID status for the Endpoint*/ PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID); } } /*Double Buffer*/ else { /*Set the endpoint as double buffered*/ PCD_SET_EP_DBUF(hpcd->Instance, ep->num); /*Set buffer address for double buffered mode*/ PCD_SET_EP_DBUF_ADDR(hpcd->Instance, ep->num,ep->pmaaddr0, ep->pmaaddr1); if (ep->is_in==0) { /* Clear the data toggle bits for the endpoint IN/OUT*/ PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); /* Reset value of the data toggle bits for the endpoint out*/ PCD_TX_DTOG(hpcd->Instance, ep->num); PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_VALID); PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS); } else { /* Clear the data toggle bits for the endpoint IN/OUT*/ PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); PCD_RX_DTOG(hpcd->Instance, ep->num); /* Configure DISABLE status for the Endpoint*/ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS); PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS); } } __HAL_UNLOCK(hpcd); return ret; }
/** * @brief Send an amount of data in blocking mode * @param hirda: IRDA handle * @param pData: pointer to data buffer * @param Size: amount of data to be sent * @param Timeout: Duration of the timeout * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_RX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; if(hirda->State == HAL_IRDA_STATE_BUSY_RX) { hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; } else { hirda->State = HAL_IRDA_STATE_BUSY_TX; } hirda->TxXferSize = Size; hirda->TxXferCount = Size; while(hirda->TxXferCount > 0) { hirda->TxXferCount--; if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) { tmp = (uint16_t*) pData; hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); pData += 2; } else { hirda->Instance->TDR = (*pData++ & (uint8_t)0xFF); } } if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_RX; } else { hirda->State = HAL_IRDA_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Enables DAC and starts conversion of channel. * @param hdac: pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param Channel: The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @param pData: The destination peripheral Buffer address. * @param Length: The length of data to be transferred from memory to DAC peripheral * @param Alignment: Specifies the data alignment for DAC channel. * This parameter can be one of the following values: * @arg DAC_ALIGN_8B_R: 8bit right data alignment selected * @arg DAC_ALIGN_12B_L: 12bit left data alignment selected * @arg DAC_ALIGN_12B_R: 12bit right data alignment selected * @retval HAL status */ HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_DAC_CHANNEL(Channel)); assert_param(IS_DAC_ALIGN(Alignment)); /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; if(Channel == DAC_CHANNEL_1) { /* Set the DMA transfer complete callback for channel1 */ hdac->DMA_Handle1->XferCpltCallback = DAC_DMAConvCpltCh1; /* Set the DMA half transfer complete callback for channel1 */ hdac->DMA_Handle1->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh1; /* Set the DMA error callback for channel1 */ hdac->DMA_Handle1->XferErrorCallback = DAC_DMAErrorCh1; /* Enable the selected DAC channel1 DMA request */ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN1); /* Case of use of channel 1 */ switch(Alignment) { case DAC_ALIGN_12B_R: /* Get DHR12R1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12R1; break; case DAC_ALIGN_12B_L: /* Get DHR12L1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12L1; break; case DAC_ALIGN_8B_R: /* Get DHR8R1 address */ tmpreg = (uint32_t)&hdac->Instance->DHR8R1; break; default: break; } } else { /* Set the DMA transfer complete callback for channel2 */ hdac->DMA_Handle2->XferCpltCallback = DAC_DMAConvCpltCh2; /* Set the DMA half transfer complete callback for channel2 */ hdac->DMA_Handle2->XferHalfCpltCallback = DAC_DMAHalfConvCpltCh2; /* Set the DMA error callback for channel2 */ hdac->DMA_Handle2->XferErrorCallback = DAC_DMAErrorCh2; /* Enable the selected DAC channel2 DMA request */ SET_BIT(hdac->Instance->CR, DAC_CR_DMAEN2); /* Case of use of channel 2 */ switch(Alignment) { case DAC_ALIGN_12B_R: /* Get DHR12R2 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12R2; break; case DAC_ALIGN_12B_L: /* Get DHR12L2 address */ tmpreg = (uint32_t)&hdac->Instance->DHR12L2; break; case DAC_ALIGN_8B_R: /* Get DHR8R2 address */ tmpreg = (uint32_t)&hdac->Instance->DHR8R2; break; default: break; } } /* Enable the DMA channel */ if(Channel == DAC_CHANNEL_1) { /* Enable the DAC DMA underrun interrupt */ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR1); /* Enable the DMA channel */ HAL_DMA_Start_IT(hdac->DMA_Handle1, (uint32_t)pData, tmpreg, Length); } else { /* Enable the DAC DMA underrun interrupt */ __HAL_DAC_ENABLE_IT(hdac, DAC_IT_DMAUDR2); /* Enable the DMA channel */ HAL_DMA_Start_IT(hdac->DMA_Handle2, (uint32_t)pData, tmpreg, Length); } /* Process Unlocked */ __HAL_UNLOCK(hdac); /* Enable the Peripheral */ __HAL_DAC_ENABLE(hdac, Channel); /* Return function status */ return HAL_OK; }
/** * @brief Configures the selected DAC channel. * @param hdac: pointer to a DAC_HandleTypeDef structure that contains * the configuration information for the specified DAC. * @param sConfig: DAC configuration structure. * @param Channel: The selected DAC channel. * This parameter can be one of the following values: * @arg DAC_CHANNEL_1: DAC Channel1 selected * @arg DAC_CHANNEL_2: DAC Channel2 selected * @retval HAL status */ HAL_StatusTypeDef HAL_DAC_ConfigChannel(DAC_HandleTypeDef* hdac, DAC_ChannelConfTypeDef* sConfig, uint32_t Channel) { uint32_t tmpreg1 = 0, tmpreg2 = 0; uint32_t tickstart = 0; /* Check the DAC parameters */ assert_param(IS_DAC_TRIGGER(sConfig->DAC_Trigger)); assert_param(IS_DAC_OUTPUT_BUFFER_STATE(sConfig->DAC_OutputBuffer)); assert_param(IS_DAC_CHIP_CONNECTION(sConfig->DAC_ConnectOnChipPeripheral)); assert_param(IS_DAC_TRIMMING(sConfig->DAC_UserTrimming)); if ((sConfig->DAC_UserTrimming) == DAC_TRIMMING_USER) { assert_param(IS_DAC_TRIMMINGVALUE(sConfig->DAC_TrimmingValue)); } assert_param(IS_DAC_SAMPLEANDHOLD(sConfig->DAC_SampleAndHold)); if ((sConfig->DAC_SampleAndHold) == DAC_SAMPLEANDHOLD_ENABLE) { assert_param(IS_DAC_SAMPLETIME(sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime)); assert_param(IS_DAC_HOLDTIME(sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime)); assert_param(IS_DAC_REFRESHTIME(sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime)); } assert_param(IS_DAC_CHANNEL(Channel)); /* Process locked */ __HAL_LOCK(hdac); /* Change DAC state */ hdac->State = HAL_DAC_STATE_BUSY; if(sConfig->DAC_SampleAndHold == DAC_SAMPLEANDHOLD_ENABLE) /* Sample on old configuration */ { /* SampleTime */ if (Channel == DAC_CHANNEL_1) { /* Get timeout */ tickstart = HAL_GetTick(); /* SHSR1 can be written when BWST1 equals RESET */ while (((hdac->Instance->SR) & DAC_SR_BWST1)!= RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG) { /* Update error code */ SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT); /* Change the DMA state */ hdac->State = HAL_DAC_STATE_TIMEOUT; return HAL_TIMEOUT; } } HAL_Delay(1); hdac->Instance->SHSR1 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime; } else /* Channel 2 */ { /* SHSR2 can be written when BWST2 equals RESET */ while (((hdac->Instance->SR) & DAC_SR_BWST2)!= RESET) { /* Check for the Timeout */ if((HAL_GetTick() - tickstart) > TIMEOUT_DAC_CALIBCONFIG) { /* Update error code */ SET_BIT(hdac->ErrorCode, HAL_DAC_ERROR_TIMEOUT); /* Change the DMA state */ hdac->State = HAL_DAC_STATE_TIMEOUT; return HAL_TIMEOUT; } } HAL_Delay(1); hdac->Instance->SHSR2 = sConfig->DAC_SampleAndHoldConfig.DAC_SampleTime; } /* HoldTime */ hdac->Instance->SHHR = (sConfig->DAC_SampleAndHoldConfig.DAC_HoldTime)<<Channel; /* RefreshTime */ hdac->Instance->SHRR = (sConfig->DAC_SampleAndHoldConfig.DAC_RefreshTime)<<Channel; } if(sConfig->DAC_UserTrimming == DAC_TRIMMING_USER) /* USER TRIMMING */ { /* Get the DAC CCR value */ tmpreg1 = hdac->Instance->CCR; /* Clear trimming value */ tmpreg1 &= ~(((uint32_t)(DAC_CCR_OTRIM1)) << Channel); /* Configure for the selected trimming offset */ tmpreg2 = sConfig->DAC_TrimmingValue; /* Calculate CCR register value depending on DAC_Channel */ tmpreg1 |= tmpreg2 << Channel; /* Write to DAC CCR */ hdac->Instance->CCR = tmpreg1; } /* else factory trimming is used (factory setting are available at reset)*/ /* SW Nothing has nothing to do */ /* Get the DAC MCR value */ tmpreg1 = hdac->Instance->MCR; /* Clear DAC_MCR_MODE2_0, DAC_MCR_MODE2_1 and DAC_MCR_MODE2_2 bits */ tmpreg1 &= ~(((uint32_t)(DAC_MCR_MODE1)) << Channel); /* Configure for the selected DAC channel: mode, buffer output & on chip peripheral connect */ tmpreg2 = (sConfig->DAC_SampleAndHold | sConfig->DAC_OutputBuffer | sConfig->DAC_ConnectOnChipPeripheral); /* Calculate MCR register value depending on DAC_Channel */ tmpreg1 |= tmpreg2 << Channel; /* Write to DAC MCR */ hdac->Instance->MCR = tmpreg1; /* DAC in normal operating mode hence clear DAC_CR_CENx bit */ CLEAR_BIT (hdac->Instance->CR, DAC_CR_CEN1 << Channel); /* Get the DAC CR value */ tmpreg1 = hdac->Instance->CR; /* Clear TENx, TSELx, WAVEx and MAMPx bits */ tmpreg1 &= ~(((uint32_t)(DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1)) << Channel); /* Configure for the selected DAC channel: trigger */ /* Set TSELx and TENx bits according to DAC_Trigger value */ tmpreg2 = (sConfig->DAC_Trigger); /* Calculate CR register value depending on DAC_Channel */ tmpreg1 |= tmpreg2 << Channel; /* Write to DAC CR */ hdac->Instance->CR = tmpreg1; /* Disable wave generation */ hdac->Instance->CR &= ~(DAC_CR_WAVE1 << Channel); /* Change DAC state */ hdac->State = HAL_DAC_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hdac); /* Return function status */ return HAL_OK; }
/** * @brief Perform a mass erase or erase the specified FLASH memory sectors * @param[in] pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @param[out] SectorError: pointer to variable that * contains the configuration information on faulty sector in case of error * (0xFFFFFFFF means that all the sectors have been correctly erased) * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) { HAL_StatusTypeDef status = HAL_ERROR; uint32_t index = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_TYPEERASE(pEraseInit->TypeErase)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE); if (status == HAL_OK) { /*Initialization of SectorError variable*/ *SectorError = 0xFFFFFFFF; if (pEraseInit->TypeErase == TYPEERASE_MASSERASE) { /*Mass erase to be done*/ FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE); /* if the erase operation is completed, disable the MER Bit */ FLASH->CR &= (~FLASH_MER_BIT); } else { /* Check the parameters */ assert_param(IS_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); /* Erase by sector by sector to be done*/ for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++) { FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)HAL_FLASH_TIMEOUT_VALUE); /* If the erase operation is completed, disable the SER Bit */ FLASH->CR &= (~FLASH_CR_SER); FLASH->CR &= SECTOR_MASK; if (status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty sector*/ *SectorError = index; break; } } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Program halfword, word or double word at a specified address * @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface * The function HAL_FLASH_Lock() should be called after to lock the FLASH interface * * @note If an erase and a program operations are requested simultaneously, * the erase operation is performed before the program one. * * @note FLASH should be previously erased before new programmation (only exception to this * is when 0x0000 is programmed) * * @param TypeProgram: Indicate the way to program at a specified address. * This parameter can be a value of @ref FLASH_Type_Program * @param Address: Specifies the address to be programmed. * @param Data: Specifies the data to be programmed * * @retval HAL_StatusTypeDef HAL Status */ HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) { HAL_StatusTypeDef status = HAL_ERROR; uint8_t index = 0; uint8_t nbiterations = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); assert_param(IS_FLASH_PROGRAM_ADDRESS(Address)); #if defined(FLASH_BANK2_END) if(Address <= FLASH_BANK1_END) { #endif /* FLASH_BANK2_END */ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); #if defined(FLASH_BANK2_END) } else { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); } #endif /* FLASH_BANK2_END */ if(status == HAL_OK) { if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD) { /* Program halfword (16-bit) at a specified address. */ nbiterations = 1; } else if(TypeProgram == FLASH_TYPEPROGRAM_WORD) { /* Program word (32-bit = 2*16-bit) at a specified address. */ nbiterations = 2; } else { /* Program double word (64-bit = 4*16-bit) at a specified address. */ nbiterations = 4; } for (index = 0; index < nbiterations; index++) { FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index))); #if defined(FLASH_BANK2_END) if(Address <= FLASH_BANK1_END) { #endif /* FLASH_BANK2_END */ /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); /* If the program operation is completed, disable the PG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); #if defined(FLASH_BANK2_END) } else { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE); /* If the program operation is completed, disable the PG Bit */ CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG); } #endif /* FLASH_BANK2_END */ /* In case of error, stop programation procedure */ if (status != HAL_OK) { break; } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Configures the ADC injected group and the selected channel to be * linked to the injected group. * @note Possibility to update parameters on the fly: * This function initializes injected group, following calls to this * function can be used to reconfigure some parameters of structure * "ADC_InjectionConfTypeDef" on the fly, without reseting the ADC. * The setting of these parameters is conditioned to ADC state: * this function must be called when ADC is not under conversion. * @param hadc: ADC handle * @param sConfigInjected: Structure of ADC injected group and ADC channel for * injected group. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; __IO uint32_t wait_loop_index = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv)); assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset)); if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) { assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); } /* Process locked */ __HAL_LOCK(hadc); /* Configuration of injected group sequencer: */ /* - if scan mode is disabled, injected channels sequence length is set to */ /* 0x00: 1 channel converted (channel on regular rank 1) */ /* Parameter "InjectedNbrOfConversion" is discarded. */ /* Note: Scan mode is present by hardware on this device and, if */ /* disabled, discards automatically nb of conversions. Anyway, nb of */ /* conversions is forced to 0x00 for alignment over all STM32 devices. */ /* - if scan mode is enabled, injected channels sequence length is set to */ /* parameter "InjectedNbrOfConversion". */ if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) { if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1) { /* Clear the old SQx bits for all injected ranks */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 , ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, ADC_INJECTED_RANK_1, 0x01) ); } /* If another injected rank than rank1 was intended to be set, and could */ /* not due to ScanConvMode disabled, error is reported. */ else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } else { /* Since injected channels rank conv. order depends on total number of */ /* injected conversions, selected rank must be below or equal to total */ /* number of injected conversions to be updated. */ if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion) { /* Clear the old SQx bits for the selected rank */ /* Set the SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) | ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) ); } else { /* Clear the old SQx bits for the selected rank */ MODIFY_REG(hadc->Instance->JSQR , ADC_JSQR_JL | ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank, sConfigInjected->InjectedNbrOfConversion) , 0x00000000 ); } } /* Configuration of injected group */ /* Parameters update conditioned to ADC state: */ /* Parameters that can be updated only when ADC is disabled: */ /* - external trigger to start conversion */ /* Parameters update not conditioned to ADC state: */ /* - Automatic injected conversion */ /* - Injected discontinuous mode */ /* Note: In case of ADC already enabled, caution to not launch an unwanted */ /* conversion while modifying register CR2 by writing 1 to bit ADON. */ if (ADC_IS_ENABLE(hadc) == RESET) { MODIFY_REG(hadc->Instance->CR2 , ADC_CR2_JEXTSEL | ADC_CR2_ADON , ADC_CFGR_JEXTSEL(hadc, sConfigInjected->ExternalTrigInjecConv) ); } /* Configuration of injected group */ /* - Automatic injected conversion */ /* - Injected discontinuous mode */ /* Automatic injected conversion can be enabled if injected group */ /* external triggers are disabled. */ if (sConfigInjected->AutoInjectedConv == ENABLE) { if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* Injected discontinuous can be enabled only if auto-injected mode is */ /* disabled. */ if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) { if (sConfigInjected->AutoInjectedConv == DISABLE) { SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN); } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* InjectedChannel sampling time configuration */ /* For channels 10 to 17 */ if (sConfigInjected->InjectedChannel >= ADC_CHANNEL_10) { MODIFY_REG(hadc->Instance->SMPR1 , ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel) , ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } else /* For channels 0 to 9 */ { MODIFY_REG(hadc->Instance->SMPR2 , ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel) , ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); } /* If ADC1 InjectedChannel_16 or InjectedChannel_17 is selected, enable Temperature sensor */ /* and VREFINT measurement path. */ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) { SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); } /* Configure the offset: offset enable/disable, InjectedChannel, offset value */ switch(sConfigInjected->InjectedRank) { case 1: /* Set injected channel 1 offset */ MODIFY_REG(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1, sConfigInjected->InjectedOffset); break; case 2: /* Set injected channel 2 offset */ MODIFY_REG(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2, sConfigInjected->InjectedOffset); break; case 3: /* Set injected channel 3 offset */ MODIFY_REG(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3, sConfigInjected->InjectedOffset); break; case 4: default: MODIFY_REG(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4, sConfigInjected->InjectedOffset); break; } /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */ /* and VREFINT measurement path. */ if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) { /* For STM32F1 devices with several ADC: Only ADC1 can access internal */ /* measurement channels (VrefInt/TempSensor). If these channels are */ /* intended to be set on other ADC instances, an error is reported. */ if (hadc->Instance == ADC1) { if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET) { SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR)) { /* Delay for temperature sensor stabilization time */ /* Compute number of CPU cycles to wait for */ wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000)); while(wait_loop_index != 0) { wait_loop_index--; } } } } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; tmp_hal_status = HAL_ERROR; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Stop ADC conversion of regular group (and injected channels in * case of auto_injection mode), disable ADC DMA transfer, disable * ADC peripheral. * @note Multimode is kept enabled after this function. To disable multimode * (set with HAL_ADCEx_MultiModeConfigChannel(), ADC must be * reinitialized using HAL_ADC_Init() or HAL_ADC_ReInit(). * @note In case of DMA configured in circular mode, function * HAL_ADC_Stop_DMA must be called after this function with handle of * ADC slave, to properly disable the DMA channel. * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) * @retval None */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; ADC_HandleTypeDef tmphadcSlave; /* Check the parameters */ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC master peripheral */ tmp_hal_status = ADC_ConversionStop_Disable(hadc); /* Check if ADC is effectively disabled */ if (tmp_hal_status != HAL_ERROR) { /* Set a temporary handle of the ADC slave associated to the ADC master */ ADC_MULTI_SLAVE(hadc, &tmphadcSlave); if (tmphadcSlave.Instance == NULL) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } else { /* Disable ADC slave peripheral */ tmp_hal_status = ADC_ConversionStop_Disable(&tmphadcSlave); /* Check if ADC is effectively disabled */ if (tmp_hal_status != HAL_OK) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } /* Disable ADC DMA mode */ CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA); /* Reset configuration of ADC DMA continuous request for dual mode */ CLEAR_BIT(hadc->Instance->CR1, ADC_CR1_DUALMOD); /* Disable the DMA channel (in case of DMA in circular mode or stop while */ /* while DMA transfer is on going) */ tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); /* Check if DMA channel effectively disabled */ if (tmp_hal_status != HAL_ERROR) { /* Change ADC state (ADC master) */ hadc->State = HAL_ADC_STATE_READY; } else { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Enables ADC, starts conversion of regular group and transfers result * through DMA. * Multimode must have been previously configured using * HAL_ADCEx_MultiModeConfigChannel() function. * Interruptions enabled in this function: * - DMA transfer complete * - DMA half transfer * Each of these interruptions has its dedicated callback function. * @note: On STM32F1 devices, ADC slave regular group must be configured * with conversion trigger ADC_SOFTWARE_START. * @note: ADC slave can be enabled preliminarily using single-mode * HAL_ADC_Start() function. * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) * @param pData: The destination Buffer address. * @param Length: The length of data to be transferred from ADC peripheral to memory. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; ADC_HandleTypeDef tmphadcSlave; /* Check the parameters */ assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); /* Process locked */ __HAL_LOCK(hadc); /* Set a temporary handle of the ADC slave associated to the ADC master */ ADC_MULTI_SLAVE(hadc, &tmphadcSlave); /* On STM32F1 devices, ADC slave regular group must be configured with */ /* conversion trigger ADC_SOFTWARE_START. */ /* Note: External trigger of ADC slave must be enabled, it is already done */ /* into function "HAL_ADC_Init()". */ if ((tmphadcSlave.Instance == NULL) || (! ADC_IS_SOFTWARE_START_REGULAR(&tmphadcSlave)) ) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } /* Enable the ADC peripherals: master and slave (in case if not already */ /* enabled previously) */ tmp_hal_status = ADC_Enable(hadc); if (tmp_hal_status != HAL_ERROR) { tmp_hal_status = ADC_Enable(&tmphadcSlave); } /* Start conversion all ADCs of multimode are effectively enabled */ if (tmp_hal_status != HAL_ERROR) { /* State machine update (ADC master): 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; } /* 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); /* Set the DMA transfer complete callback */ hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; /* Set the DMA half transfer complete callback */ hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; /* Set the DMA error callback */ hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ /* start (in case of SW start): */ /* Clear regular group conversion flag and overrun flag */ /* (To ensure of no unknown state from potential previous ADC operations) */ __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); /* Enable ADC DMA mode of ADC master */ SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA); /* Start the DMA channel */ HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); /* Start conversion of regular group if software start has been selected. */ /* If external trigger has been selected, conversion will start at next */ /* trigger event. */ /* Note: Alternate trigger for single conversion could be to force an */ /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/ if (ADC_IS_SOFTWARE_START_REGULAR(hadc)) { /* Start ADC conversion on regular group with SW start */ SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); } else { /* Start ADC conversion on regular group with external trigger */ SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG); } } else { /* Process unlocked */ __HAL_UNLOCK(hadc); } /* Return function status */ return tmp_hal_status; }
/** * @brief Polling for transfer complete. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param CompleteLevel: Specifies the DMA level complete. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) { uint32_t temp; uint32_t tickstart = 0x00; /* Get the level transfer complete flag */ if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Transfer Complete flag */ temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma); } else { /* Half Transfer Complete flag */ temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma); } /* Get tick */ tickstart = HAL_GetTick(); while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET) { if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)) { /* Clear the transfer error flags */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); /* Change the DMA state */ hdma->State= HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_TIMEOUT; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_TIMEOUT; } } } if(CompleteLevel == HAL_DMA_FULL_TRANSFER) { /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers are complete) */ hdma->State = HAL_DMA_STATE_READY; } else { /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers of half buffer are complete) */ hdma->State = HAL_DMA_STATE_READY_HALF; } /* Process unlocked */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Polling for transfer complete. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param CompleteLevel: Specifies the DMA level complete. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout) { uint32_t temp; uint32_t tickstart = 0; if(HAL_DMA_STATE_BUSY != hdma->State) { /* no transfer ongoing */ hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER; return HAL_ERROR; } /* Polling mode not supported in circular mode */ if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC)) { hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED; return HAL_ERROR; } /* Get the level transfer complete flag */ if (HAL_DMA_FULL_TRANSFER == CompleteLevel) { /* Transfer Complete flag */ temp = DMA_FLAG_TC1 << hdma->ChannelIndex; } else { /* Half Transfer Complete flag */ temp = DMA_FLAG_HT1 << hdma->ChannelIndex; } /* Get tick */ tickstart = HAL_GetTick(); while(RESET == (hdma->DmaBaseAddress->ISR & temp)) { if((RESET != (hdma->DmaBaseAddress->ISR & (DMA_FLAG_TE1 << hdma->ChannelIndex)))) { /* When a DMA transfer error occurs */ /* A hardware clear of its EN bits is performed */ /* Clear all flags */ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); /* Update error code */ hdma->ErrorCode = HAL_DMA_ERROR_TE; /* Change the DMA state */ hdma->State= HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { /* Update error code */ hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); return HAL_ERROR; } } } if(HAL_DMA_FULL_TRANSFER == CompleteLevel) { /* Clear the transfer complete flag */ hdma->DmaBaseAddress->IFCR = (DMA_FLAG_TC1 << hdma->ChannelIndex); /* The selected Channelx EN bit is cleared (DMA is disabled and all transfers are complete) */ hdma->State = HAL_DMA_STATE_READY; } else { /* Clear the half transfer complete flag */ hdma->DmaBaseAddress->IFCR = (DMA_FLAG_HT1 << hdma->ChannelIndex); } /* Process unlocked */ __HAL_UNLOCK(hdma); return HAL_OK; }
/** * @brief Handles DMA interrupt request. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @retval None */ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) { /* Transfer Error Interrupt management ***************************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET) { /* Disable the transfer error interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE); /* Clear the transfer error flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_ERROR; /* Process Unlocked */ __HAL_UNLOCK(hdma); if (hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } } /* Half Transfer Complete Interrupt management ******************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET) { /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the half transfer interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); } /* Clear the half transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_READY_HALF; if(hdma->XferHalfCpltCallback != NULL) { /* Half transfer callback */ hdma->XferHalfCpltCallback(hdma); } } } /* Transfer Complete Interrupt management ***********************************/ if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET) { if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET) { if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the transfer complete interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC); } /* Clear the transfer complete flag */ __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); /* Update error code */ SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferCpltCallback != NULL) { /* Transfer complete callback */ hdma->XferCpltCallback(hdma); } } } }
/** * @brief Handle DMA interrupt request. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @retval None */ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma) { uint32_t flag_it = hdma->DmaBaseAddress->ISR; uint32_t source_it = hdma->Instance->CCR; /* Half Transfer Complete Interrupt management ******************************/ if ((RESET != (flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_HT))) { /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */ if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the half transfer interrupt */ __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); } /* Clear the half transfer complete flag */ hdma->DmaBaseAddress->IFCR = (DMA_ISR_HTIF1 << hdma->ChannelIndex); /* DMA peripheral state is not updated in Half Transfer */ /* but in Transfer Complete case */ if(hdma->XferHalfCpltCallback != NULL) { /* Half transfer callback */ hdma->XferHalfCpltCallback(hdma); } } /* Transfer Complete Interrupt management ***********************************/ else if ((RESET != (flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TC))) { if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0) { /* Disable the transfer complete and error interrupt */ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE)); /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; } /* Clear the transfer complete flag */ hdma->DmaBaseAddress->IFCR = (DMA_ISR_TCIF1 << hdma->ChannelIndex); /* Process Unlocked */ __HAL_UNLOCK(hdma); if(hdma->XferCpltCallback != NULL) { /* Transfer complete callback */ hdma->XferCpltCallback(hdma); } } /* Transfer Error Interrupt management **************************************/ else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE))) { /* When a DMA transfer error occurs */ /* A hardware clear of its EN bits is performed */ /* Disable ALL DMA IT */ __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); /* Clear all flags */ hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex); /* Update error code */ hdma->ErrorCode = HAL_DMA_ERROR_TE; /* Change the DMA state */ hdma->State = HAL_DMA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hdma); if (hdma->XferErrorCallback != NULL) { /* Transfer error callback */ hdma->XferErrorCallback(hdma); } } return; }
/** * @brief Deactivate an endpoint * @param hpcd: PCD handle * @param ep_addr: endpoint address * @retval HAL status */ HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) { PCD_EPTypeDef *ep; if ((ep_addr & 0x80) == 0x80) { ep = &hpcd->IN_ep[ep_addr & 0x7F]; } else { ep = &hpcd->OUT_ep[ep_addr & 0x7F]; } ep->num = ep_addr & 0x7F; ep->is_in = (0x80 & ep_addr) != 0; __HAL_LOCK(hpcd); if (ep->doublebuffer == 0) { if (ep->is_in) { PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); /* Configure DISABLE status for the Endpoint*/ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS); } else { PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); /* Configure DISABLE status for the Endpoint*/ PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS); } } /*Double Buffer*/ else { if (ep->is_in==0) { /* Clear the data toggle bits for the endpoint IN/OUT*/ PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); /* Reset value of the data toggle bits for the endpoint out*/ PCD_TX_DTOG(hpcd->Instance, ep->num); PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS); PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS); } else { /* Clear the data toggle bits for the endpoint IN/OUT*/ PCD_CLEAR_RX_DTOG(hpcd->Instance, ep->num); PCD_CLEAR_TX_DTOG(hpcd->Instance, ep->num); PCD_RX_DTOG(hpcd->Instance, ep->num); /* Configure DISABLE status for the Endpoint*/ PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_DIS); PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_DIS); } } __HAL_UNLOCK(hpcd); return HAL_OK; }
/** * @brief Read Page(s) from NAND memory block * @param hnand: pointer to a NAND_HandleTypeDef structure that contains * the configuration information for NAND module. * @param pAddress: pointer to NAND address structure * @param pBuffer: pointer to destination read buffer * @param NumPageToRead: number of pages to read from block * @retval HAL status */ HAL_StatusTypeDef HAL_NAND_Read_Page(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead) { __IO uint32_t index = 0; uint32_t deviceaddress = 0, size = 0, numpagesread = 0, addressstatus = NAND_VALID_ADDRESS; NAND_AddressTypeDef nandaddress; uint32_t addressoffset = 0; /* Process Locked */ __HAL_LOCK(hnand); /* Check the NAND controller state */ if(hnand->State == HAL_NAND_STATE_BUSY) { return HAL_BUSY; } /* Identify the device address */ if(hnand->Init.NandBank == FMC_NAND_BANK2) { deviceaddress = NAND_DEVICE1; } else { deviceaddress = NAND_DEVICE2; } /* Update the NAND controller state */ hnand->State = HAL_NAND_STATE_BUSY; /* Save the content of pAddress as it will be modified */ nandaddress.Block = pAddress->Block; nandaddress.Page = pAddress->Page; nandaddress.Zone = pAddress->Zone; /* Page(s) read loop */ while((NumPageToRead != 0) && (addressstatus == NAND_VALID_ADDRESS)) { /* update the buffer size */ size = hnand->Info.PageSize + ((hnand->Info.PageSize) * numpagesread); /* Get the address offset */ addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); /* Send read page command sequence */ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A; *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); /* for 512 and 1 GB devices, 4th cycle is required */ if(hnand->Info.BlockNbr >= 1024) { *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); } *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1; /* Get Data into Buffer */ for(; index < size; index++) { *(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress; } /* Increment read pages number */ numpagesread++; /* Decrement pages to read */ NumPageToRead--; /* Increment the NAND address */ addressstatus = NAND_AddressIncrement(hnand, &nandaddress); } /* Update the NAND controller state */ hnand->State = HAL_NAND_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hnand); return HAL_OK; }
/** * @brief Receive an amount of data in blocking mode * @param hirda: IRDA handle * @param pData: pointer to data buffer * @param Size: amount of data to be received * @param Timeout: Duration of the timeout * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; uint16_t uhMask; if ((hirda->State == HAL_IRDA_STATE_READY) || (hirda->State == HAL_IRDA_STATE_BUSY_TX)) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; if(hirda->State == HAL_IRDA_STATE_BUSY_TX) { hirda->State = HAL_IRDA_STATE_BUSY_TX_RX; } else { hirda->State = HAL_IRDA_STATE_BUSY_RX; } hirda->RxXferSize = Size; hirda->RxXferCount = Size; /* Computation of the mask to apply to the RDR register of the UART associated to the IRDA */ __HAL_IRDA_MASK_COMPUTATION(hirda); uhMask = hirda->Mask; /* Check data remaining to be received */ while(hirda->RxXferCount > 0) { hirda->RxXferCount--; if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) { tmp = (uint16_t*) pData ; *tmp = (uint16_t)(hirda->Instance->RDR & uhMask); pData +=2; } else { *pData++ = (uint8_t)(hirda->Instance->RDR & (uint8_t)uhMask); } } if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_TX; } else { hirda->State = HAL_IRDA_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Write Spare area(s) to NAND memory * @param hnand: pointer to a NAND_HandleTypeDef structure that contains * the configuration information for NAND module. * @param pAddress: pointer to NAND address structure * @param pBuffer: pointer to source buffer to write * @param NumSpareAreaTowrite: number of spare areas to write to block * @retval HAL status */ HAL_StatusTypeDef HAL_NAND_Write_SpareArea(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumSpareAreaTowrite) { __IO uint32_t index = 0; uint32_t tickstart = 0; uint32_t deviceaddress = 0, size = 0, num_spare_area_written = 0, addressstatus = NAND_VALID_ADDRESS; NAND_AddressTypeDef nandaddress; uint32_t addressoffset = 0; /* Process Locked */ __HAL_LOCK(hnand); /* Check the NAND controller state */ if(hnand->State == HAL_NAND_STATE_BUSY) { return HAL_BUSY; } /* Identify the device address */ if(hnand->Init.NandBank == FMC_NAND_BANK2) { deviceaddress = NAND_DEVICE1; } else { deviceaddress = NAND_DEVICE2; } /* Update the FMC_NAND controller state */ hnand->State = HAL_NAND_STATE_BUSY; /* Save the content of pAddress as it will be modified */ nandaddress.Block = pAddress->Block; nandaddress.Page = pAddress->Page; nandaddress.Zone = pAddress->Zone; /* Spare area(s) write loop */ while((NumSpareAreaTowrite != 0) && (addressstatus == NAND_VALID_ADDRESS)) { /* update the buffer size */ size = (hnand->Info.SpareAreaSize) + ((hnand->Info.SpareAreaSize) * num_spare_area_written); /* Get the address offset */ addressoffset = ARRAY_ADDRESS(&nandaddress, hnand); /* Send write Spare area command sequence */ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_C; *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0; *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = 0x00; *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(addressoffset); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(addressoffset); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(addressoffset); /* for 512 and 1 GB devices, 4th cycle is required */ if(hnand->Info.BlockNbr >= 1024) { *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(addressoffset); } /* Write data to memory */ for(; index < size; index++) { *(__IO uint8_t *)deviceaddress = *(uint8_t *)pBuffer++; } *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1; /* Get tick */ tickstart = HAL_GetTick(); /* Read status until NAND is ready */ while(HAL_NAND_Read_Status(hnand) != NAND_READY) { if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) { return HAL_TIMEOUT; } } /* Increment written spare areas number */ num_spare_area_written++; /* Decrement spare areas to write */ NumSpareAreaTowrite--; /* Increment the NAND address */ addressstatus = NAND_AddressIncrement(hnand, &nandaddress); } /* Update the NAND controller state */ hnand->State = HAL_NAND_STATE_READY; /* Process unlocked */ __HAL_UNLOCK(hnand); return HAL_OK; }
/** * @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((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } /* Check if the I2S Rx request is already enabled */ if((hi2s->Instance->CR2 &SPI_CR2_RXDMAEN) != SPI_CR2_RXDMAEN) { /* Enable Rx DMA Request */ hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN; } /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @brief NAND memory Block erase * @param hnand: pointer to a NAND_HandleTypeDef structure that contains * the configuration information for NAND module. * @param pAddress: pointer to NAND address structure * @retval HAL status */ HAL_StatusTypeDef HAL_NAND_Erase_Block(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress) { uint32_t deviceaddress = 0; uint32_t tickstart = 0; /* Process Locked */ __HAL_LOCK(hnand); /* Check the NAND controller state */ if(hnand->State == HAL_NAND_STATE_BUSY) { return HAL_BUSY; } /* Identify the device address */ if(hnand->Init.NandBank == FMC_NAND_BANK2) { deviceaddress = NAND_DEVICE1; } else { deviceaddress = NAND_DEVICE2; } /* Update the NAND controller state */ hnand->State = HAL_NAND_STATE_BUSY; /* Send Erase block command sequence */ *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE0; *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); /* for 512 and 1 GB devices, 4th cycle is required */ if(hnand->Info.BlockNbr >= 1024) { *(__IO uint8_t *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_4TH_CYCLE(ARRAY_ADDRESS(pAddress, hnand)); } *(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_ERASE1; /* Update the NAND controller state */ hnand->State = HAL_NAND_STATE_READY; /* Get tick */ tickstart = HAL_GetTick(); /* Read status until NAND is ready */ while(HAL_NAND_Read_Status(hnand) != NAND_READY) { if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT) { /* Process unlocked */ __HAL_UNLOCK(hnand); return HAL_TIMEOUT; } } /* Process unlocked */ __HAL_UNLOCK(hnand); 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 = 0; uint32_t tmp1 = 0, tmp2 = 0; /* 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 / 1000000)); while(counter != 0) { 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 Initiates and transmits a CAN frame message. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains * the configuration information for the specified CAN. * @param Timeout: Timeout duration. * @retval HAL status */ HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout) { uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX; uint32_t tickstart = 0; /* Check the parameters */ assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE)); assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR)); assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC)); /* Process locked */ __HAL_LOCK(hcan); if(hcan->State == HAL_CAN_STATE_BUSY_RX) { /* Change CAN state */ hcan->State = HAL_CAN_STATE_BUSY_TX_RX; } else { /* Change CAN state */ hcan->State = HAL_CAN_STATE_BUSY_TX; } /* Select one empty transmit mailbox */ if ((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { transmitmailbox = 0; } else if ((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { transmitmailbox = 1; } else if ((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { transmitmailbox = 2; } if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { /* Set up the Id */ hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; if (hcan->pTxMsg->IDE == CAN_ID_STD) { assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \ hcan->pTxMsg->RTR); } else { assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \ hcan->pTxMsg->IDE | \ hcan->pTxMsg->RTR); } /* Set up the DLC */ hcan->pTxMsg->DLC &= (uint8_t)0x0000000F; hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC; /* Set up the data field */ hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | ((uint32_t)hcan->pTxMsg->Data[2] << 16) | ((uint32_t)hcan->pTxMsg->Data[1] << 8) | ((uint32_t)hcan->pTxMsg->Data[0])); hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | ((uint32_t)hcan->pTxMsg->Data[6] << 16) | ((uint32_t)hcan->pTxMsg->Data[5] << 8) | ((uint32_t)hcan->pTxMsg->Data[4])); /* Request transmission */ hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; /* Get timeout */ tickstart = HAL_GetTick(); /* Check End of transmission flag */ while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox))) { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout)) { hcan->State = HAL_CAN_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hcan); return HAL_TIMEOUT; } } } if(hcan->State == HAL_CAN_STATE_BUSY_TX_RX) { /* Change CAN state */ hcan->State = HAL_CAN_STATE_BUSY_RX; } else { /* Change CAN state */ hcan->State = HAL_CAN_STATE_READY; } /* Process unlocked */ __HAL_UNLOCK(hcan); /* Return function status */ return HAL_OK; } else { /* Change CAN state */ hcan->State = HAL_CAN_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hcan); /* Return function status */ return HAL_ERROR; } }
/** * @brief Configures for the selected ADC injected channel its corresponding * rank in the sequencer and its sample time. * @param hadc: pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * @param sConfigInjected: ADC configuration structure for injected channel. * @retval None */ HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) { #ifdef USE_FULL_ASSERT uint32_t tmp = 0; #endif /* USE_FULL_ASSERT */ /* Check the parameters */ assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); assert_param(IS_ADC_EXT_INJEC_TRIG(sConfigInjected->ExternalTrigInjecConv)); assert_param(IS_ADC_INJECTED_LENGTH(sConfigInjected->InjectedNbrOfConversion)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); #ifdef USE_FULL_ASSERT tmp = ADC_GET_RESOLUTION(hadc); assert_param(IS_ADC_RANGE(tmp, sConfigInjected->InjectedOffset)); #endif /* USE_FULL_ASSERT */ if(sConfigInjected->ExternalTrigInjecConvEdge != ADC_INJECTED_SOFTWARE_START) { assert_param(IS_ADC_EXT_INJEC_TRIG_EDGE(sConfigInjected->ExternalTrigInjecConvEdge)); } /* Process locked */ __HAL_LOCK(hadc); /* if ADC_Channel_10 ... ADC_Channel_18 is selected */ if (sConfigInjected->InjectedChannel > ADC_CHANNEL_9) { /* Clear the old sample time */ hadc->Instance->SMPR1 &= ~ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel); /* Set the new sample time */ hadc->Instance->SMPR1 |= ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); } else /* ADC_Channel include in ADC_Channel_[0..9] */ { /* Clear the old sample time */ hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel); /* Set the new sample time */ hadc->Instance->SMPR2 |= ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel); } /*---------------------------- ADCx JSQR Configuration -----------------*/ hadc->Instance->JSQR &= ~(ADC_JSQR_JL); hadc->Instance->JSQR |= ADC_SQR1(sConfigInjected->InjectedNbrOfConversion); /* Rank configuration */ /* Clear the old SQx bits for the selected rank */ hadc->Instance->JSQR &= ~ADC_JSQR(ADC_JSQR_JSQ1, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); /* Set the SQx bits for the selected rank */ hadc->Instance->JSQR |= ADC_JSQR(sConfigInjected->InjectedChannel, sConfigInjected->InjectedRank,sConfigInjected->InjectedNbrOfConversion); /* Enable external trigger if trigger selection is different of software */ /* start. */ /* Note: This configuration keeps the hardware feature of parameter */ /* ExternalTrigConvEdge "trigger edge none" equivalent to */ /* software start. */ if(sConfigInjected->ExternalTrigInjecConv != ADC_INJECTED_SOFTWARE_START) { /* Select external trigger to start conversion */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConv; /* Select external trigger polarity */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); hadc->Instance->CR2 |= sConfigInjected->ExternalTrigInjecConvEdge; } else { /* Reset the external trigger */ hadc->Instance->CR2 &= ~(ADC_CR2_JEXTSEL); hadc->Instance->CR2 &= ~(ADC_CR2_JEXTEN); } if (sConfigInjected->AutoInjectedConv != DISABLE) { /* Enable the selected ADC automatic injected group conversion */ hadc->Instance->CR1 |= ADC_CR1_JAUTO; } else { /* Disable the selected ADC automatic injected group conversion */ hadc->Instance->CR1 &= ~(ADC_CR1_JAUTO); } if (sConfigInjected->InjectedDiscontinuousConvMode != DISABLE) { /* Enable the selected ADC injected discontinuous mode */ hadc->Instance->CR1 |= ADC_CR1_JDISCEN; } else { /* Disable the selected ADC injected discontinuous mode */ hadc->Instance->CR1 &= ~(ADC_CR1_JDISCEN); } switch(sConfigInjected->InjectedRank) { case 1: /* Set injected channel 1 offset */ hadc->Instance->JOFR1 &= ~(ADC_JOFR1_JOFFSET1); hadc->Instance->JOFR1 |= sConfigInjected->InjectedOffset; break; case 2: /* Set injected channel 2 offset */ hadc->Instance->JOFR2 &= ~(ADC_JOFR2_JOFFSET2); hadc->Instance->JOFR2 |= sConfigInjected->InjectedOffset; break; case 3: /* Set injected channel 3 offset */ hadc->Instance->JOFR3 &= ~(ADC_JOFR3_JOFFSET3); hadc->Instance->JOFR3 |= sConfigInjected->InjectedOffset; break; default: /* Set injected channel 4 offset */ hadc->Instance->JOFR4 &= ~(ADC_JOFR4_JOFFSET4); hadc->Instance->JOFR4 |= sConfigInjected->InjectedOffset; break; } /* if ADC1 Channel_18 is selected enable VBAT Channel */ if ((hadc->Instance == ADC1) && (sConfigInjected->InjectedChannel == ADC_CHANNEL_VBAT)) { /* Enable the VBAT channel*/ ADC->CCR |= ADC_CCR_VBATE; } /* if ADC1 Channel_16 or Channel_17 is selected enable TSVREFE Channel(Temperature sensor and VREFINT) */ if ((hadc->Instance == ADC1) && ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT))) { /* Enable the TSVREFE channel*/ ADC->CCR |= ADC_CCR_TSVREFE; } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return HAL_OK; }
/** * @brief Initiates and transmits a CAN frame message. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains * the configuration information for the specified CAN. * @retval HAL status */ HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan) { uint32_t transmitmailbox = CAN_TXSTATUS_NOMAILBOX; /* Check the parameters */ assert_param(IS_CAN_IDTYPE(hcan->pTxMsg->IDE)); assert_param(IS_CAN_RTR(hcan->pTxMsg->RTR)); assert_param(IS_CAN_DLC(hcan->pTxMsg->DLC)); if((hcan->State == HAL_CAN_STATE_READY) || (hcan->State == HAL_CAN_STATE_BUSY_RX)) { /* Process Locked */ __HAL_LOCK(hcan); /* Select one empty transmit mailbox */ if((hcan->Instance->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { transmitmailbox = 0; } else if((hcan->Instance->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { transmitmailbox = 1; } else if((hcan->Instance->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { transmitmailbox = 2; } if(transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { /* Set up the Id */ hcan->Instance->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; if(hcan->pTxMsg->IDE == CAN_ID_STD) { assert_param(IS_CAN_STDID(hcan->pTxMsg->StdId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->StdId << 21) | \ hcan->pTxMsg->RTR); } else { assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << 3) | \ hcan->pTxMsg->IDE | \ hcan->pTxMsg->RTR); } /* Set up the DLC */ hcan->pTxMsg->DLC &= (uint8_t)0x0000000F; hcan->Instance->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; hcan->Instance->sTxMailBox[transmitmailbox].TDTR |= hcan->pTxMsg->DLC; /* Set up the data field */ hcan->Instance->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)hcan->pTxMsg->Data[3] << 24) | ((uint32_t)hcan->pTxMsg->Data[2] << 16) | ((uint32_t)hcan->pTxMsg->Data[1] << 8) | ((uint32_t)hcan->pTxMsg->Data[0])); hcan->Instance->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)hcan->pTxMsg->Data[7] << 24) | ((uint32_t)hcan->pTxMsg->Data[6] << 16) | ((uint32_t)hcan->pTxMsg->Data[5] << 8) | ((uint32_t)hcan->pTxMsg->Data[4])); if(hcan->State == HAL_CAN_STATE_BUSY_RX) { /* Change CAN state */ hcan->State = HAL_CAN_STATE_BUSY_TX_RX; } else { /* Change CAN state */ hcan->State = HAL_CAN_STATE_BUSY_TX; } /* Set CAN error code to none */ hcan->ErrorCode = HAL_CAN_ERROR_NONE; /* Process Unlocked */ __HAL_UNLOCK(hcan); /* Enable Error warning Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG); /* Enable Error passive Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EPV); /* Enable Bus-off Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_BOF); /* Enable Last error code Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_LEC); /* Enable Error Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_ERR); /* Enable Transmit mailbox empty Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_TME); /* Request transmission */ hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; } } else { return HAL_BUSY; } return HAL_OK; }
/** * @brief Transmit an amount of data in blocking mode * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains * the configuration information for I2S module * @param pData: a 16-bit pointer to 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. * @param Timeout: Timeout duration * @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(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout) { if((pData == NULL ) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hi2s); if(hi2s->State == HAL_I2S_STATE_READY) { 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 state and reset error code */ hi2s->ErrorCode = HAL_I2S_ERROR_NONE; hi2s->State = HAL_I2S_STATE_BUSY_TX; hi2s->pTxBuffPtr = pData; /* Check if the I2S is already enabled */ if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) { /* Enable I2S peripheral */ __HAL_I2S_ENABLE(hi2s); } while(hi2s->TxXferCount > 0) { /* Wait until TXE flag is set */ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); hi2s->TxXferCount--; } /* Wait until TXE flag is set, to confirm the end of the transcation */ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } /* Wait until Busy flag is reset */ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, SET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } hi2s->State = HAL_I2S_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_OK; } else { /* Process Unlocked */ __HAL_UNLOCK(hi2s); return HAL_BUSY; } }
/** * @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; }