/** * @brief Receive data in interrupt mode. * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Receive_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec) { static uint32_t temp; if(hcec->RxState == HAL_CEC_STATE_BUSY_RX) { temp = hcec->Instance->CSR; /* Store received data */ hcec->RxXferSize++; *hcec->Init.RxBuffer++ = hcec->Instance->RXD; /* Acknowledge received byte by writing 0x00 */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00U); /* If the End Of Message is reached */ if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM)) { /* Interrupts are not disabled due to transmission still ongoing */ hcec->RxState = HAL_CEC_STATE_READY; HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize); return HAL_OK; } else { return HAL_BUSY; } } else { return HAL_BUSY; } }
/** * @brief Receive data in interrupt mode. * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Receive_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec) { static uint32_t temp; uint32_t tmp_state = 0; tmp_state = hcec->State; if((tmp_state == HAL_CEC_STATE_BUSY_RX) || (tmp_state == HAL_CEC_STATE_BUSY_TX_RX)) { temp = hcec->Instance->CSR; /* Store received data */ *hcec->pRxBuffPtr++ = hcec->Instance->RXD; /* Acknowledge received byte by writing 0x00 */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_RECEIVE_MASK, 0x00); /* Increment the number of received data */ if(hcec->RxXferSize == CEC_RXXFERSIZE_INITIALIZE) { hcec->RxXferSize = 0; } else { hcec->RxXferSize++; } /* If the End Of Message is reached */ if(HAL_IS_BIT_SET(temp, CEC_FLAG_REOM)) { if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX) { /* Interrupts are not disabled due to transmission still ongoing */ hcec->State = HAL_CEC_STATE_BUSY_TX; } else { /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE); hcec->State = HAL_CEC_STATE_READY; } HAL_CEC_RxCpltCallback(hcec); return HAL_OK; } else { return HAL_BUSY; } } else { return HAL_BUSY; } }
/** * @brief This function handles CEC interrupt requests. * @param hcec: CEC handle * @retval None */ void HAL_CEC_IRQHandler(CEC_HandleTypeDef *hcec) { /* save interrupts register for further error or interrupts handling purposes */ uint32_t reg = 0U; reg = hcec->Instance->ISR; /* ----------------------------Arbitration Lost Management----------------------------------*/ /* CEC TX arbitration error interrupt occurred --------------------------------------*/ if((reg & CEC_FLAG_ARBLST) != RESET) { hcec->ErrorCode = HAL_CEC_ERROR_ARBLST; __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_ARBLST); } /* ----------------------------Rx Management----------------------------------*/ /* CEC RX byte received interrupt ---------------------------------------------------*/ if((reg & CEC_FLAG_RXBR) != RESET) { /* reception is starting */ hcec->RxState = HAL_CEC_STATE_BUSY_RX; hcec->RxXferSize++; /* read received byte */ *hcec->Init.RxBuffer++ = hcec->Instance->RXDR; __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR); } /* CEC RX end received interrupt ---------------------------------------------------*/ if((reg & CEC_FLAG_RXEND) != RESET) { /* clear IT */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXEND); /* Rx process is completed, restore hcec->RxState to Ready */ hcec->RxState = HAL_CEC_STATE_READY; hcec->ErrorCode = HAL_CEC_ERROR_NONE; hcec->Init.RxBuffer -= hcec->RxXferSize; HAL_CEC_RxCpltCallback(hcec, hcec->RxXferSize); hcec->RxXferSize = 0U; } /* ----------------------------Tx Management----------------------------------*/ /* CEC TX byte request interrupt ------------------------------------------------*/ if((reg & CEC_FLAG_TXBR) != RESET) { if (hcec->TxXferCount == 0U) { /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); hcec->Instance->TXDR = *hcec->pTxBuffPtr++; } else { hcec->Instance->TXDR = *hcec->pTxBuffPtr++; hcec->TxXferCount--; } /* clear Tx-Byte request flag */ __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR); } /* CEC TX end interrupt ------------------------------------------------*/ if((reg & CEC_FLAG_TXEND) != RESET) { __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TXEND); /* Tx process is ended, restore hcec->gState to Ready */ hcec->gState = HAL_CEC_STATE_READY; /* Call the Process Unlocked before calling the Tx call back API to give the possibility to start again the Transmission under the Tx call back API */ __HAL_UNLOCK(hcec); hcec->ErrorCode = HAL_CEC_ERROR_NONE; HAL_CEC_TxCpltCallback(hcec); } /* ----------------------------Rx/Tx Error Management----------------------------------*/ if ((reg & (CEC_ISR_RXOVR|CEC_ISR_BRE|CEC_ISR_SBPE|CEC_ISR_LBPE|CEC_ISR_RXACKE|CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE)) != 0U) { hcec->ErrorCode = reg; __HAL_CEC_CLEAR_FLAG(hcec, HAL_CEC_ERROR_RXOVR|HAL_CEC_ERROR_BRE|CEC_FLAG_LBPE|CEC_FLAG_SBPE|HAL_CEC_ERROR_RXACKE|HAL_CEC_ERROR_TXUDR|HAL_CEC_ERROR_TXERR|HAL_CEC_ERROR_TXACKE); if((reg & (CEC_ISR_RXOVR|CEC_ISR_BRE|CEC_ISR_SBPE|CEC_ISR_LBPE|CEC_ISR_RXACKE)) != RESET) { hcec->Init.RxBuffer-=hcec->RxXferSize; hcec->RxXferSize = 0U; hcec->RxState = HAL_CEC_STATE_READY; } else if (((reg & (CEC_ISR_TXUDR|CEC_ISR_TXERR|CEC_ISR_TXACKE)) != RESET) && ((reg & CEC_ISR_ARBLST) == RESET)) { /* Set the CEC state ready to be able to start again the process */ hcec->gState = HAL_CEC_STATE_READY; } /* Error Call Back */ HAL_CEC_ErrorCallback(hcec); } }
/** * @brief Receive data in interrupt mode. * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Receive_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Receive_IT(CEC_HandleTypeDef *hcec) { uint32_t tempisr; /* Three different conditions are tested to carry out the RX IT processing: * - the IP is in reception stand-by (the IP state is HAL_CEC_STATE_STANDBY_RX) and * the reception of the first byte is starting * - a message reception is already on-going (the IP state is HAL_CEC_STATE_BUSY_RX) * and a new byte is being received * - a transmission has just been started (the IP state is HAL_CEC_STATE_BUSY_TX) * but has been interrupted by a new message reception or discarded due to * arbitration loss: the reception of the first or higher priority message * (the arbitration winner) is starting */ if ((hcec->State == HAL_CEC_STATE_STANDBY_RX) || (hcec->State == HAL_CEC_STATE_BUSY_RX) || (hcec->State == HAL_CEC_STATE_BUSY_TX)) { /* reception is starting */ hcec->State = HAL_CEC_STATE_BUSY_RX; tempisr = (uint32_t) (hcec->Instance->ISR); if ((tempisr & CEC_FLAG_RXBR) != 0) { /* Process Locked */ __HAL_LOCK(hcec); /* read received byte */ *hcec->pRxBuffPtr++ = hcec->Instance->RXDR; /* if last byte has been received */ if ((tempisr & CEC_FLAG_RXEND) != 0) { /* clear IT */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR|CEC_FLAG_RXEND); /* RX interrupts are not disabled at this point. * Indeed, to disable the IT, the IP must be disabled first * which resets the TXSOM flag. In case of arbitration loss, * this leads to a transmission abort. * Therefore, RX interruptions disabling if so required, * is done in HAL_CEC_RxCpltCallback */ /* IP state is moved to READY. * If the IP must remain in standby mode to listen * any new message, it is up to HAL_CEC_RxCpltCallback * to move it again to HAL_CEC_STATE_STANDBY_RX */ hcec->State = HAL_CEC_STATE_READY; /* Call the Process Unlocked before calling the Rx call back API */ __HAL_UNLOCK(hcec); HAL_CEC_RxCpltCallback(hcec); return HAL_OK; } __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RXBR); hcec->RxXferSize++; /* Process Unlocked */ __HAL_UNLOCK(hcec); return HAL_OK; } else { return HAL_BUSY; } } else { return HAL_BUSY; } }