/** * @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_ISR_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 occured 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_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_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_ISR_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_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_ARBLST)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE|CEC_ISR_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_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE)) != 0) { /* copy ISR for error handling purposes */ hcec->ErrorCode = tempisr; /* clear all error flags by default */ __HAL_CEC_CLEAR_FLAG(hcec, (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_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 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 = 0U; uint32_t tmp1 = 0U, tmp2 = 0U; ADC_Common_TypeDef *tmpADC_Common; /* 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); /* 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 Multimode enabled */ if(HAL_IS_BIT_CLR(tmpADC_Common->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 SMARTCARD interrupt requests handling. * @param hsc: SMARTCARD handle * @retval None */ void HAL_SMARTCARD_IRQHandler(SMARTCARD_HandleTypeDef *hsc) { uint32_t isrflags = READ_REG(hsc->Instance->ISR); uint32_t cr1its = READ_REG(hsc->Instance->CR1); uint32_t cr3its = READ_REG(hsc->Instance->CR3); uint32_t dmarequest = 0x00U; uint32_t errorflags = 0x00U; /* If no error occurs */ errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); if(errorflags == RESET) { /* SMARTCARD in mode Receiver -------------------------------------------------*/ if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { SMARTCARD_Receive_IT(hsc); return; } } /* If some errors occur */ if((errorflags != RESET) && ((cr3its & (USART_CR3_EIE | USART_CR1_PEIE)) != RESET)) { /* SMARTCARD parity error interrupt occurred ---------------------------*/ if(((isrflags & SMARTCARD_FLAG_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_PE; } /* SMARTCARD frame error interrupt occurred ----------------------------*/ if(((isrflags & SMARTCARD_FLAG_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_FE; } /* SMARTCARD noise error interrupt occurred ----------------------------*/ if(((isrflags & SMARTCARD_FLAG_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_NE; } /* SMARTCARD Over-Run interrupt occurred -------------------------------*/ if(((isrflags & SMARTCARD_FLAG_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) { hsc->ErrorCode |= HAL_SMARTCARD_ERROR_ORE; } /* Call the Error call Back in case of Errors */ if(hsc->ErrorCode != HAL_SMARTCARD_ERROR_NONE) { /* SMARTCARD in mode Receiver -----------------------------------------------*/ if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) { SMARTCARD_Receive_IT(hsc); } /* If Overrun error occurs, or if any error occurs in DMA mode reception, consider error as blocking */ dmarequest = HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR); if(((hsc->ErrorCode & HAL_SMARTCARD_ERROR_ORE) != RESET) || dmarequest) { /* Blocking error : transfer is aborted Set the SMARTCARD state ready to be able to start again the process, Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ SMARTCARD_EndRxTransfer(hsc); /* Disable the SMARTCARD DMA Rx request if enabled */ if (HAL_IS_BIT_SET(hsc->Instance->CR3, USART_CR3_DMAR)) { CLEAR_BIT(hsc->Instance->CR3, USART_CR3_DMAR); /* Abort the SMARTCARD DMA Rx channel */ if(hsc->hdmarx != NULL) { /* Set the SMARTCARD DMA Abort callback : will lead to call HAL_SMARTCARD_ErrorCallback() at end of DMA abort procedure */ hsc->hdmarx->XferAbortCallback = SMARTCARD_DMAAbortOnError; if(HAL_DMA_Abort_IT(hsc->hdmarx) != HAL_OK) { /* Call Directly XferAbortCallback function in case of error */ hsc->hdmarx->XferAbortCallback(hsc->hdmarx); } } else { /* Call user error callback */ HAL_SMARTCARD_ErrorCallback(hsc); } } else { /* Call user error callback */ HAL_SMARTCARD_ErrorCallback(hsc); } } else { /* Call user error callback */ HAL_SMARTCARD_ErrorCallback(hsc); hsc->ErrorCode = HAL_SMARTCARD_ERROR_NONE; } } return; } /* End if some error occurs */ /* SMARTCARD in mode Transmitter -------------------------------------------*/ if(((isrflags & SMARTCARD_FLAG_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { SMARTCARD_Transmit_IT(hsc); return; } /* SMARTCARD in mode Transmitter (transmission end) ------------------------*/ if(((isrflags & SMARTCARD_FLAG_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { /* Disable the SMARTCARD Transmit Complete Interrupt */ CLEAR_BIT(hsc->Instance->CR1, USART_CR1_TCIE); /* Disable the SMARTCARD Error Interrupt: (Frame error, noise error, overrun error) */ CLEAR_BIT(hsc->Instance->CR3, USART_CR3_EIE); /* Tx process is ended, restore hsmartcard->gState to Ready */ hsc->gState = HAL_SMARTCARD_STATE_READY; HAL_SMARTCARD_TxCpltCallback(hsc); return; } }
/** * @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 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. * @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 blocking mode. * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains * the configuration information for SWPMI module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be received * @param Timeout: Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SWPMI_Receive(SWPMI_HandleTypeDef *hswpmi, uint32_t *pData, uint16_t Size, uint32_t Timeout) { uint32_t tickstart = HAL_GetTick(); HAL_StatusTypeDef status = HAL_OK; if((pData == NULL ) || (Size == 0)) { status = HAL_ERROR; } else { /* Process Locked */ __HAL_LOCK(hswpmi); if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_TX)) { /* Check if a non-blocking transmit process is ongoing or not */ if(hswpmi->State == HAL_SWPMI_STATE_READY) { hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; /* Disable any receiver interrupts */ CLEAR_BIT(hswpmi->Instance->IER, SWPMI_IT_SRIE | SWPMI_IT_RIE | SWPMI_IT_RXBERIE | SWPMI_IT_RXOVRIE | SWPMI_IT_RXBFIE); /* Enable SWPMI peripheral if not */ SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); } else { hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; } do { /* Wait the RXNE to read data */ if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXNE)) { (*pData++) = hswpmi->Instance->RDR; Size--; } else { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { status = HAL_TIMEOUT; break; } } } } while(Size != 0); if(status == HAL_OK) { if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_RXBFF)) { /* Clear RXBFF at end of reception */ WRITE_REG(hswpmi->Instance->ICR, SWPMI_FLAG_RXBFF); } /* Check if a non-blocking transmit Process is ongoing or not */ if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) { hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; } else { hswpmi->State = HAL_SWPMI_STATE_READY; } } } else { status = HAL_BUSY; } } if((status != HAL_OK) && (status != HAL_BUSY)) { hswpmi->State = HAL_SWPMI_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hswpmi); return status; }
/** * @brief Perform an ADC automatic self-calibration * Calibration prerequisite: ADC must be disabled (execute this * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). * During calibration process, ADC is enabled. ADC is let enabled at * the completion of this function. * @param hadc: ADC handle * @retval HAL status */ HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc) { HAL_StatusTypeDef tmp_hal_status = HAL_OK; uint32_t tickstart; __IO uint32_t wait_loop_index = 0; /* Check the parameters */ assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); /* Process locked */ __HAL_LOCK(hadc); /* 1. Calibration prerequisite: */ /* - ADC must be disabled for at least two ADC clock cycles in disable */ /* mode before ADC enable */ /* Stop potential conversion on going, on regular and injected groups */ /* Disable ADC peripheral */ tmp_hal_status = ADC_ConversionStop_Disable(hadc); /* Check if ADC is effectively disabled */ if (tmp_hal_status != HAL_ERROR) { /* Hardware prerequisite: delay before starting the calibration. */ /* - Computation of CPU clock cycles corresponding to ADC clock cycles. */ /* - Wait for the expected ADC clock cycles delay */ wait_loop_index = ((SystemCoreClock / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES ); while(wait_loop_index != 0) { wait_loop_index--; } /* 2. Enable the ADC peripheral */ ADC_Enable(hadc); /* 3. Resets ADC calibration registers */ SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL); tickstart = HAL_GetTick(); /* Wait for calibration reset completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } /* 4. Start ADC calibration */ SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL); tickstart = HAL_GetTick(); /* Wait for calibration completion */ while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL)) { if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) { /* Update ADC state machine to error */ hadc->State = HAL_ADC_STATE_ERROR; /* Process unlocked */ __HAL_UNLOCK(hadc); return HAL_ERROR; } } } /* Process unlocked */ __HAL_UNLOCK(hadc); /* Return function status */ return tmp_hal_status; }
/** * @brief Transmit an amount of data in blocking mode. * @param hswpmi: pointer to a SWPMI_HandleTypeDef structure that contains * the configuration information for SWPMI module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be sent * @param Timeout: Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SWPMI_Transmit(SWPMI_HandleTypeDef *hswpmi, uint32_t* pData, uint16_t Size, uint32_t Timeout) { uint32_t tickstart = HAL_GetTick(); HAL_StatusTypeDef status = HAL_OK; if((pData == NULL ) || (Size == 0)) { status = HAL_ERROR; } else { /* Process Locked */ __HAL_LOCK(hswpmi); if((hswpmi->State == HAL_SWPMI_STATE_READY) || (hswpmi->State == HAL_SWPMI_STATE_BUSY_RX)) { /* Check if a non-blocking receive process is ongoing or not */ if(hswpmi->State == HAL_SWPMI_STATE_READY) { hswpmi->State = HAL_SWPMI_STATE_BUSY_TX; /* Disable any transmitter interrupts */ __HAL_SWPMI_DISABLE_IT(hswpmi, SWPMI_IT_TCIE | SWPMI_IT_TIE | SWPMI_IT_TXUNRIE | SWPMI_IT_TXBEIE); /* Disable any transmitter flags */ __HAL_SWPMI_CLEAR_FLAG(hswpmi, SWPMI_FLAG_TXBEF | SWPMI_FLAG_TXUNRF | SWPMI_FLAG_TCF); /* Enable SWPMI peripheral if not */ SET_BIT(hswpmi->Instance->CR, SWPMI_CR_SWPACT); } else { hswpmi->State = HAL_SWPMI_STATE_BUSY_TX_RX; } do { /* Wait the TXE to write data */ if(HAL_IS_BIT_SET(hswpmi->Instance->ISR, SWPMI_FLAG_TXE)) { hswpmi->Instance->TDR = (*pData++); Size--; } else { /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout)) { status = HAL_TIMEOUT; break; } } } } while(Size != 0); /* Wait on TXBEF flag to be able to start a second transfer */ if(SWPMI_WaitOnFlagSetUntilTimeout(hswpmi, SWPMI_FLAG_TXBEF, Timeout) != HAL_OK) { status = HAL_TIMEOUT; } if(status == HAL_OK) { /* Check if a non-blocking receive Process is ongoing or not */ if(hswpmi->State == HAL_SWPMI_STATE_BUSY_TX_RX) { hswpmi->State = HAL_SWPMI_STATE_BUSY_RX; } else { hswpmi->State = HAL_SWPMI_STATE_READY; } } } else { status = HAL_BUSY; } } if((status != HAL_OK) && (status != HAL_BUSY)) { hswpmi->State = HAL_SWPMI_STATE_READY; } /* Process Unlocked */ __HAL_UNLOCK(hswpmi); return status; }
/** * @brief Receives an amount of data in non blocking mode. * @param hirda: IRDA handle * @retval HAL status */ static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda) { uint16_t* tmp; uint32_t tmp1 = 0; tmp1 = hirda->State; if((tmp1 == HAL_IRDA_STATE_BUSY_RX) || (tmp1 == HAL_IRDA_STATE_BUSY_TX_RX)) { /* Process Locked */ __HAL_LOCK(hirda); if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { tmp = (uint16_t*) hirda->pRxBuffPtr; if(hirda->Init.Parity == IRDA_PARITY_NONE) { *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF); hirda->pRxBuffPtr += 2; } else { *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF); hirda->pRxBuffPtr += 1; } } else { if(hirda->Init.Parity == IRDA_PARITY_NONE) { *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF); } else { *hirda->pRxBuffPtr++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F); } } if(--hirda->RxXferCount == 0) { while(HAL_IS_BIT_SET(hirda->Instance->SR, IRDA_FLAG_RXNE)) { } __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_RXNE); if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_TX; } else { /* Disable the IRDA Parity Error Interrupt */ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_PE); /* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_ERR); hirda->State = HAL_IRDA_STATE_READY; } /* Call the Process Unlocked before calling the Rx call back API to give the possibiity to start again the receiption under the Rx call back API */ __HAL_UNLOCK(hirda); HAL_IRDA_RxCpltCallback(hirda); return HAL_OK; } /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }
/** * @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(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0)) { transmitmailbox = 0; } else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1)) { transmitmailbox = 1; } else if(HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2)) { transmitmailbox = 2; } else { transmitmailbox = CAN_TXSTATUS_NOMAILBOX; } 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 << CAN_TI0R_STID_BIT_POSITION) | hcan->pTxMsg->RTR); } else { assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) | 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 */ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) ); WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) ); 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 interrupts: */ /* - Enable Error warning Interrupt */ /* - Enable Error passive Interrupt */ /* - Enable Bus-off Interrupt */ /* - Enable Last error code Interrupt */ /* - Enable Error Interrupt */ /* - Enable Transmit mailbox empty Interrupt */ __HAL_CAN_ENABLE_IT(hcan, CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR | CAN_IT_TME ); /* Request transmission */ hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; } } else { return HAL_BUSY; } 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: Specify Timeout value * @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 (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0)) { transmitmailbox = 0; } else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME1)) { transmitmailbox = 1; } else if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME2)) { transmitmailbox = 2; } else { transmitmailbox = CAN_TXSTATUS_NOMAILBOX; } 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 << CAN_TI0R_STID_BIT_POSITION) | hcan->pTxMsg->RTR); } else { assert_param(IS_CAN_EXTID(hcan->pTxMsg->ExtId)); hcan->Instance->sTxMailBox[transmitmailbox].TIR |= ((hcan->pTxMsg->ExtId << CAN_TI0R_EXID_BIT_POSITION) | 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 */ WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, ((uint32_t)hcan->pTxMsg->Data[3] << CAN_TDL0R_DATA3_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[2] << CAN_TDL0R_DATA2_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[1] << CAN_TDL0R_DATA1_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[0] << CAN_TDL0R_DATA0_BIT_POSITION) ); WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, ((uint32_t)hcan->pTxMsg->Data[7] << CAN_TDL0R_DATA3_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[6] << CAN_TDL0R_DATA2_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[5] << CAN_TDL0R_DATA1_BIT_POSITION) | ((uint32_t)hcan->pTxMsg->Data[4] << CAN_TDL0R_DATA0_BIT_POSITION) ); /* Request transmission */ SET_BIT(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; /* Process unlocked */ __HAL_UNLOCK(hcan); } 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 Initializes the CAN peripheral according to the specified * parameters in the CAN_InitStruct. * @param hcan: pointer to a CAN_HandleTypeDef structure that contains * the configuration information for the specified CAN. * @retval HAL status */ HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef* hcan) { uint32_t status = CAN_INITSTATUS_FAILED; /* Default init status */ uint32_t tickstart = 0; uint32_t tmp_mcr = 0; /* Check CAN handle */ if(hcan == NULL) { return HAL_ERROR; } /* Check the parameters */ assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TTCM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ABOM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AWUM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.NART)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.RFLM)); assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TXFP)); assert_param(IS_CAN_MODE(hcan->Init.Mode)); assert_param(IS_CAN_SJW(hcan->Init.SJW)); assert_param(IS_CAN_BS1(hcan->Init.BS1)); assert_param(IS_CAN_BS2(hcan->Init.BS2)); assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler)); if(hcan->State == HAL_CAN_STATE_RESET) { /* Allocate lock resource and initialize it */ hcan->Lock = HAL_UNLOCKED; /* Init the low level hardware */ HAL_CAN_MspInit(hcan); } /* Initialize the CAN state*/ hcan->State = HAL_CAN_STATE_BUSY; /* Exit from sleep mode */ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP); /* Request initialisation */ SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait the acknowledge */ while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK)) { if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE) { hcan->State= HAL_CAN_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hcan); return HAL_TIMEOUT; } } /* Check acknowledge */ if ((hcan->Instance->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { /* Set the time triggered communication mode */ if (hcan->Init.TTCM == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_TTCM); } /* Set the automatic bus-off management */ if (hcan->Init.ABOM == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_ABOM); } /* Set the automatic wake-up mode */ if (hcan->Init.AWUM == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_AWUM); } /* Set the no automatic retransmission */ if (hcan->Init.NART == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_NART); } /* Set the receive FIFO locked mode */ if (hcan->Init.RFLM == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_RFLM); } /* Set the transmit FIFO priority */ if (hcan->Init.TXFP == ENABLE) { SET_BIT(tmp_mcr, CAN_MCR_TXFP); } /* Update register MCR */ MODIFY_REG(hcan->Instance->MCR, CAN_MCR_TTCM | CAN_MCR_ABOM | CAN_MCR_AWUM | CAN_MCR_NART | CAN_MCR_RFLM | CAN_MCR_TXFP, tmp_mcr); /* Set the bit timing register */ WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode | hcan->Init.SJW | hcan->Init.BS1 | hcan->Init.BS2 | (hcan->Init.Prescaler - 1) )); /* Request leave initialisation */ CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ); /* Get timeout */ tickstart = HAL_GetTick(); /* Wait the acknowledge */ while(HAL_IS_BIT_CLR(hcan->Instance->MSR, CAN_MSR_INAK)) { if((HAL_GetTick()-tickstart) > CAN_TIMEOUT_VALUE) { hcan->State= HAL_CAN_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hcan); return HAL_TIMEOUT; } } /* Check acknowledged */ if (HAL_IS_BIT_SET(hcan->Instance->MSR, CAN_MSR_INAK)) { status = CAN_INITSTATUS_SUCCESS; } } if(status == CAN_INITSTATUS_SUCCESS) { /* Set CAN error code to none */ hcan->ErrorCode = HAL_CAN_ERROR_NONE; /* Initialize the CAN state */ hcan->State = HAL_CAN_STATE_READY; /* Return function status */ return HAL_OK; } else { /* Initialize the CAN state */ hcan->State = HAL_CAN_STATE_ERROR; /* Return function status */ return HAL_ERROR; } }