/** * @brief Check the IRDA Idle State * @param hirda: IRDA handle * @retval HAL status */ static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) { /* Initialize the IRDA ErrorCode */ hirda->ErrorCode = HAL_IRDA_ERROR_NONE; /* Check if the Transmitter is enabled */ if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { /* Wait until TEACK flag is set */ if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) { hirda->State= HAL_IRDA_STATE_TIMEOUT; return HAL_TIMEOUT; } } /* Check if the Receiver is enabled */ if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, TEACK_REACK_TIMEOUT) != HAL_OK) { hirda->State= HAL_IRDA_STATE_TIMEOUT; return HAL_TIMEOUT; } } /* Process Unlocked */ __HAL_UNLOCK(hirda); /* Initialize the IRDA state*/ hirda->State= HAL_IRDA_STATE_READY; return HAL_OK; }
/** * @brief DMA IRDA Tx transfer completed callback * @param hdma: DMA handle * @retval None */ static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; hirda->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the IRDA CR3 register */ hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT); /* Wait for IRDA TC Flag */ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, IRDA_TXDMA_TIMEOUTVALUE) != HAL_OK) { /* Timeout Occured */ HAL_IRDA_ErrorCallback(hirda); } else { /* No Timeout */ if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_RX; } else { hirda->State = HAL_IRDA_STATE_READY; } HAL_IRDA_TxCpltCallback(hirda); } }
/** * @brief DMA IRDA transmit process complete callback. * @param hdma : DMA handle * @retval None */ static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; hirda->TxXferCount = 0; /* Wait for IRDA TC Flag */ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, IRDA_TIMEOUT_VALUE) != HAL_OK) { /* Timeout Occured */ hirda->State = HAL_IRDA_STATE_TIMEOUT; HAL_IRDA_ErrorCallback(hirda); } else { /* No Timeout */ /* Check if a receive process is ongoing or not */ if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_RX; } else { hirda->State = HAL_IRDA_STATE_READY; } HAL_IRDA_TxCpltCallback(hirda); } }
/** * @brief Receive an amount of data in non blocking mode. * Function called under interruption only, once * interruptions have been enabled by HAL_IRDA_Transmit_IT() * @param hirda: IRDA handle * @retval HAL status */ static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda) { uint16_t* tmp; if((hirda->State == HAL_IRDA_STATE_BUSY_TX) || (hirda->State == HAL_IRDA_STATE_BUSY_TX_RX)) { if(hirda->TxXferCount == 0) { /* Disable the IRDA Transmit Data Register Empty Interrupt */ __HAL_IRDA_DISABLE_IT(hirda, IRDA_IT_TXE); if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_RX; } else { /* 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; } /* Wait on TC flag to be able to start a second transfer */ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_IT_TC, RESET, IRDA_TIMEOUT_VALUE) != HAL_OK) { return HAL_TIMEOUT; } HAL_IRDA_TxCpltCallback(hirda); return HAL_OK; } else { if ((hirda->Init.WordLength == IRDA_WORDLENGTH_9B) && (hirda->Init.Parity == IRDA_PARITY_NONE)) { tmp = (uint16_t*) hirda->pTxBuffPtr; hirda->Instance->TDR = (*tmp & (uint16_t)0x01FF); hirda->pTxBuffPtr += 2; } else { hirda->Instance->TDR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0xFF); } hirda->TxXferCount--; return HAL_OK; } } else { return HAL_BUSY; } }
/** * @brief Check the IRDA Idle State. * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @retval HAL status */ static HAL_StatusTypeDef IRDA_CheckIdleState(IRDA_HandleTypeDef *hirda) { uint32_t tickstart = 0; /* Initialize the IRDA ErrorCode */ hirda->ErrorCode = HAL_IRDA_ERROR_NONE; /* Init tickstart for timeout managment*/ tickstart = HAL_GetTick(); /* Check if the Transmitter is enabled */ if((hirda->Instance->CR1 & USART_CR1_TE) == USART_CR1_TE) { /* Wait until TEACK flag is set */ if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_TEACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) { /* Timeout occurred */ return HAL_TIMEOUT; } } /* Check if the Receiver is enabled */ if((hirda->Instance->CR1 & USART_CR1_RE) == USART_CR1_RE) { if(IRDA_WaitOnFlagUntilTimeout(hirda, USART_ISR_REACK, RESET, tickstart, IRDA_TEACK_REACK_TIMEOUT) != HAL_OK) { /* Timeout occurred */ return HAL_TIMEOUT; } } /* Initialize the IRDA state*/ hirda->gState= HAL_IRDA_STATE_READY; hirda->RxState= HAL_IRDA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; }
/** * @brief DMA IRDA transmit process complete callback. * @param hdma : DMA handle * @retval None */ static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma) { IRDA_HandleTypeDef* hirda = ( IRDA_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; /* DMA Normal mode */ if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) { hirda->TxXferCount = 0; /* Disable the DMA transfer for transmit request by setting the DMAT bit in the IRDA CR3 register */ hirda->Instance->CR3 &= (uint16_t)~((uint16_t)USART_CR3_DMAT); /* Wait for IRDA TC Flag */ if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, IRDA_TIMEOUT_VALUE) != HAL_OK) { /* Timeout occurred */ hirda->State = HAL_IRDA_STATE_TIMEOUT; HAL_IRDA_ErrorCallback(hirda); } else { /* No Timeout */ /* Check if a receive process is ongoing or not */ if(hirda->State == HAL_IRDA_STATE_BUSY_TX_RX) { hirda->State = HAL_IRDA_STATE_BUSY_RX; } else { hirda->State = HAL_IRDA_STATE_READY; } HAL_IRDA_TxCpltCallback(hirda); } } /* DMA Circular mode */ else { HAL_IRDA_TxCpltCallback(hirda); } }
/** * @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 == 0U)) { 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 */ IRDA_MASK_COMPUTATION(hirda); uhMask = hirda->Mask; /* Check data remaining to be received */ while(hirda->RxXferCount > 0U) { 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 +=2U; } 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 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 == 0U)) { 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 > 0U) { 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)0x01FFU); pData +=2; } else { hirda->Instance->TDR = (*pData++ & (uint8_t)0xFFU); } } 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 Receive an amount of data in blocking mode. * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be received * @param Timeout: Specify timeout value * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp = 0; uint32_t tmp_state = 0; tmp_state = hirda->State; if((tmp_state == HAL_IRDA_STATE_READY) || (tmp_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; /* Check the remain data to be received */ while(hirda->RxXferCount > 0) { if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData ; if(hirda->Init.Parity == IRDA_PARITY_NONE) { *tmp = (uint16_t)(hirda->Instance->DR & IRDA_DR_MASK_U16_9DATABITS); pData +=2; } else { *tmp = (uint16_t)(hirda->Instance->DR & IRDA_DR_MASK_U16_8DATABITS); pData +=1; } } else { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if(hirda->Init.Parity == IRDA_PARITY_NONE) { *pData++ = (uint8_t)(hirda->Instance->DR & IRDA_DR_MASK_U8_8DATABITS); } else { *pData++ = (uint8_t)(hirda->Instance->DR & IRDA_DR_MASK_U8_7DATABITS); } } hirda->RxXferCount--; } 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 Sends an amount of data in blocking mode. * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be sent * @param Timeout: Specify timeout value * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp = 0; uint32_t tmp1 = 0; tmp1 = hirda->State; if((tmp1 == HAL_IRDA_STATE_READY) || (tmp1 == HAL_IRDA_STATE_BUSY_RX)) { if((pData == HAL_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) { if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; WRITE_REG(hirda->Instance->DR,(*tmp & IRDA_DR_MASK_U16_9DATABITS)); if(hirda->Init.Parity == IRDA_PARITY_NONE) { pData +=2; } else { pData +=1; } } else { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } WRITE_REG(hirda->Instance->DR, (*pData++ & IRDA_DR_MASK_U8_8DATABITS)); } hirda->TxXferCount--; } 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 Receive an amount of data in blocking mode. * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be received * @param Timeout: Specify timeout value * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; /* Check that a Rx process is not already ongoing */ if(hirda->RxState == HAL_IRDA_STATE_READY) { if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; hirda->RxState = HAL_IRDA_STATE_BUSY_RX; hirda->RxXferSize = Size; hirda->RxXferCount = Size; /* Check the remain data to be received */ while(hirda->RxXferCount > 0U) { hirda->RxXferCount--; if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData ; if(hirda->Init.Parity == IRDA_PARITY_NONE) { *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FFU); pData +=2U; } else { *tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FFU); pData +=1U; } } else { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } if(hirda->Init.Parity == IRDA_PARITY_NONE) { *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FFU); } else { *pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007FU); } } } /* At end of Rx process, restore hirda->RxState to Ready */ hirda->RxState = HAL_IRDA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Sends an amount of data in blocking mode. * @param hirda: pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @param pData: Pointer to data buffer * @param Size: Amount of data to be sent * @param Timeout: Specify timeout value * @retval HAL status */ HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout) { uint16_t* tmp; /* Check that a Tx process is not already ongoing */ if(hirda->gState == HAL_IRDA_STATE_READY) { if((pData == NULL) || (Size == 0U)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; hirda->gState = HAL_IRDA_STATE_BUSY_TX; hirda->TxXferSize = Size; hirda->TxXferCount = Size; while(hirda->TxXferCount > 0U) { hirda->TxXferCount--; if(hirda->Init.WordLength == IRDA_WORDLENGTH_9B) { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } tmp = (uint16_t*) pData; hirda->Instance->DR = (*tmp & (uint16_t)0x01FFU); if(hirda->Init.Parity == IRDA_PARITY_NONE) { pData +=2U; } else { pData +=1U; } } else { if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } hirda->Instance->DR = (*pData++ & (uint8_t)0xFFU); } } if(IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, Timeout) != HAL_OK) { return HAL_TIMEOUT; } /* At end of Tx process, restore hirda->gState to Ready */ hirda->gState = HAL_IRDA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }
/** * @brief Receive an amount of data in blocking mode. * @param hirda: Pointer to a IRDA_HandleTypeDef structure that contains * the configuration information for the specified IRDA module. * @param pData: Pointer to data buffer. * @param Size: Amount of data to be received. * @param Timeout: Specify timeout value. * @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; uint32_t tickstart = 0; /* Check that a Rx process is not already ongoing */ if(hirda->RxState == HAL_IRDA_STATE_READY) { if((pData == NULL) || (Size == 0)) { return HAL_ERROR; } /* Process Locked */ __HAL_LOCK(hirda); hirda->ErrorCode = HAL_IRDA_ERROR_NONE; hirda->RxState = HAL_IRDA_STATE_BUSY_RX; /* Init tickstart for timeout managment*/ tickstart = HAL_GetTick(); hirda->RxXferSize = Size; hirda->RxXferCount = Size; /* Computation of the mask to apply to the RDR register of the UART associated to the IRDA */ 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, tickstart, 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); } } /* At end of Rx process, restore hirda->RxState to Ready */ hirda->RxState = HAL_IRDA_STATE_READY; /* Process Unlocked */ __HAL_UNLOCK(hirda); return HAL_OK; } else { return HAL_BUSY; } }