/** * @brief Send data in interrupt 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). * @retval HAL status */ HAL_StatusTypeDef HAL_CEC_Transmit_IT(CEC_HandleTypeDef *hcec, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size) { uint8_t temp = 0; /* if the IP isn't already busy and if there is no previous transmission already pending due to arbitration lost */ if (((hcec->State == HAL_CEC_STATE_READY) || (hcec->State == HAL_CEC_STATE_STANDBY_RX)) && (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) == RESET)) { 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->pTxBuffPtr = pData; hcec->State = HAL_CEC_STATE_BUSY_TX; hcec->ErrorCode = HAL_CEC_ERROR_NONE; /* Disable Peripheral to write CEC_IER register */ __HAL_CEC_DISABLE(hcec); /* Enable the following two CEC Transmission interrupts as * well as the following CEC Transmission Errors interrupts: * Tx Byte Request IT * End of Transmission IT * Tx Missing Acknowledge IT * Tx-Error IT * Tx-Buffer Underrun IT * Tx arbitration lost */ __HAL_CEC_ENABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND|CEC_IER_TX_ALL_ERR); /* Enable the Peripheral */ __HAL_CEC_ENABLE(hcec); /* initialize the number of bytes to send, * 0 means only one header is sent (ping operation) */ hcec->TxXferCount = Size; /* Process Unlocked */ __HAL_UNLOCK(hcec); /* in case of no payload (Size = 0), sender is only pinging the system; * Set TX End of Message (TXEOM) bit, must be set before writing data to TXDR */ if (Size == 0) { __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); return HAL_OK; } /* if the IP is already busy or if there is a previous transmission already pending due to arbitration loss */ else if ((hcec->State == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) { __HAL_LOCK(hcec); /* set state to BUSY TX, in case it wasn't set already (case * of transmission new attempt after arbitration loss) */ if (hcec->State != HAL_CEC_STATE_BUSY_TX) { hcec->State = HAL_CEC_STATE_BUSY_TX; } /* if all data have been sent */ if(hcec->TxXferCount == 0) { /* Disable Peripheral to write CEC_IER register */ __HAL_CEC_DISABLE(hcec); /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND); /* Disable the CEC Transmission Error Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR); /* Enable the Peripheral */ __HAL_CEC_ENABLE(hcec); __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR|CEC_FLAG_TXEND); hcec->State = 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); HAL_CEC_TxCpltCallback(hcec); return HAL_OK; } else { if (hcec->TxXferCount == 1) { /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); } /* clear Tx-Byte request flag */ __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR); hcec->Instance->TXDR = *hcec->pTxBuffPtr++; hcec->TxXferCount--; /* Process Unlocked */ __HAL_UNLOCK(hcec); return HAL_OK; } } else { return HAL_BUSY; } }
/** * @brief Send data in interrupt mode * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Transmit_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec) { /* if the IP is already busy or if there is a previous transmission already pending due to arbitration loss */ if ((hcec->State == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) { __HAL_LOCK(hcec); /* set state to BUSY TX, in case it wasn't set already (case * of transmission new attempt after arbitration loss) */ if (hcec->State != HAL_CEC_STATE_BUSY_TX) { hcec->State = HAL_CEC_STATE_BUSY_TX; } /* if all data have been sent */ if(hcec->TxXferCount == 0U) { /* Disable Peripheral to write CEC_IER register */ __HAL_CEC_DISABLE(hcec); /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND); /* Disable the CEC Transmission Error Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR); /* Enable the Peripheral */ __HAL_CEC_ENABLE(hcec); __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR|CEC_FLAG_TXEND); hcec->State = 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); HAL_CEC_TxCpltCallback(hcec); return HAL_OK; } else { if (hcec->TxXferCount == 1U) { /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); } /* clear Tx-Byte request flag */ __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR); hcec->Instance->TXDR = *hcec->pTxBuffPtr++; hcec->TxXferCount--; /* Process Unlocked */ __HAL_UNLOCK(hcec); return HAL_OK; } } else { return HAL_BUSY; } }
/** * @brief Send data in interrupt mode * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Transmit_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec) { uint32_t tmp_state = 0; tmp_state = hcec->State; /* if the IP is already busy or if there is a previous transmission already pending due to arbitration loss */ if(((tmp_state == HAL_CEC_STATE_BUSY_TX) || (tmp_state == HAL_CEC_STATE_BUSY_TX_RX)) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) { /* if all data have been sent */ if(hcec->TxXferCount == 0) { /* Acknowledge successful completion by writing 0x00 */ MODIFY_REG(hcec->Instance->CSR, CEC_FLAG_TRANSMIT_MASK, 0x00); /* Check if a receive process is ongoing or not */ if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX) { /* Interrupts are not disabled due to reception still ongoing */ hcec->State = HAL_CEC_STATE_BUSY_RX; } else { /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE); hcec->State = HAL_CEC_STATE_READY; } HAL_CEC_TxCpltCallback(hcec); return HAL_OK; } else { /* Reduce the number of bytes to transfer by one */ hcec->TxXferCount--; /* Write data to TX buffer*/ hcec->Instance->TXD = *hcec->pTxBuffPtr++; /* 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); } return HAL_OK; } } else { return HAL_BUSY; } }
/** * @brief Send data in interrupt mode * @param hcec: CEC handle. * Function called under interruption only, once * interruptions have been enabled by HAL_CEC_Transmit_IT() * @retval HAL status */ static HAL_StatusTypeDef CEC_Transmit_IT(CEC_HandleTypeDef *hcec) { /* if the IP is already busy or if there is a previous transmission already pending due to arbitration loss */ if ((hcec->State == HAL_CEC_STATE_BUSY_TX) || (__HAL_CEC_GET_TRANSMISSION_START_FLAG(hcec) != RESET)) { /* set state to BUSY TX, in case it wasn't set already (case * of transmission new attempt after arbitration loss) */ if (hcec->State != HAL_CEC_STATE_BUSY_TX) { hcec->State = HAL_CEC_STATE_BUSY_TX; } /* if all data have been sent */ if(hcec->TxXferCount == 0) { /* Disable Peripheral to write CEC_IER register */ __HAL_CEC_DISABLE(hcec); /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_TXBR|CEC_IT_TXEND); /* Disable the CEC Transmission Error Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IER_TX_ALL_ERR); /* Enable the Peripheral */ __HAL_CEC_ENABLE(hcec); __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR|CEC_FLAG_TXEND); /* If RX interruptions are enabled, return to HAL_CEC_STATE_STANDBY_RX state */ if (__HAL_CEC_GET_IT_SOURCE(hcec, (CEC_IT_RXBR|CEC_IT_RXEND) ) != RESET) { hcec->State = HAL_CEC_STATE_STANDBY_RX; } else { hcec->State = HAL_CEC_STATE_READY; } HAL_CEC_TxCpltCallback(hcec); return HAL_OK; } else { if (hcec->TxXferCount == 1) { /* if this is the last byte transmission, set TX End of Message (TXEOM) bit */ __HAL_CEC_LAST_BYTE_TX_SET(hcec); } /* clear Tx-Byte request flag */ __HAL_CEC_CLEAR_FLAG(hcec,CEC_FLAG_TXBR); hcec->Instance->TXDR = *hcec->pTxBuffPtr++; hcec->TxXferCount--; return HAL_OK; } } 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 error status register for further error handling purposes */ hcec->ErrorCode = READ_BIT(hcec->Instance->ESR, CEC_ESR_ALL_ERROR); /* Transmit error */ if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TERR) != RESET)) { /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_TERR); /* Check if a receive process is ongoing or not */ if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX) { /* Interrupts are not disabled due to reception still ongoing */ hcec->State = HAL_CEC_STATE_BUSY_RX; } else { /* Disable the CEC Transmission Interrupts */ __HAL_CEC_DISABLE_IT(hcec, CEC_IT_IE); hcec->State = HAL_CEC_STATE_READY; } } /* Receive error */ if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RERR) != RESET)) { /* Acknowledgement of the error */ __HAL_CEC_CLEAR_FLAG(hcec, CEC_FLAG_RERR); /* Check if a transmit process is ongoing or not */ if(hcec->State == HAL_CEC_STATE_BUSY_TX_RX) { /* Interrupts are not disabled due to reception 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; } } if ((hcec->ErrorCode & CEC_ESR_ALL_ERROR) != 0) { HAL_CEC_ErrorCallback(hcec); } /* Transmit byte request or block transfer finished */ if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_TBTRF) != RESET)) { CEC_Transmit_IT(hcec); } /* Receive byte or block transfer finished */ if((__HAL_CEC_GET_FLAG(hcec, CEC_FLAG_RBTF) != RESET)) { CEC_Receive_IT(hcec); } }