示例#1
0
/**
  * @brief Send data in interrupt mode 
  * @param hcec: CEC handle 
  * @param InitiatorAddress: Initiator address
  * @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 InitiatorAddress, uint8_t DestinationAddress, uint8_t *pData, uint32_t Size)
{
  /* if the IP isn't already busy and if there is no previous transmission
     already pending due to arbitration lost */
  if (hcec->gState == HAL_CEC_STATE_READY) 
  {    
    if((pData == NULL ) && (Size > 0U)) 
    {
      return  HAL_ERROR;                                    
    }

    assert_param(IS_CEC_ADDRESS(DestinationAddress)); 
    assert_param(IS_CEC_ADDRESS(InitiatorAddress)); 
    assert_param(IS_CEC_MSGSIZE(Size));

    /* Process Locked */
    __HAL_LOCK(hcec);
    hcec->pTxBuffPtr = pData;
    hcec->gState = 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;
    
    /* 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 == 0U)
    {
      __HAL_CEC_LAST_BYTE_TX_SET(hcec);
    }

    /* send header block */
    hcec->Instance->TXDR = ((uint8_t)(InitiatorAddress << CEC_INITIATOR_LSB_POS) |(uint8_t) DestinationAddress);
    /* Set TX Start of Message  (TXSOM) bit */
    __HAL_CEC_FIRST_BYTE_TX_SET(hcec);
	    
    /* Process Unlocked */
    __HAL_UNLOCK(hcec); 
  
    return HAL_OK;

  }
  else
  {
    return HAL_BUSY;
  }
}
示例#2
0
/**
  * @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;   
  }
}
示例#3
0
/**
  * @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_FLAG_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 occurred 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_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0)
        {
          /* copy ISR for error handling purposes */
          hcec->ErrorCode = tempisr;
         /* clear all error flags by default */
         __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_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_FLAG_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_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_ARBLST)) != 0)
      {
        /* copy ISR for error handling purposes */
        hcec->ErrorCode = tempisr;
        /* clear all error flags by default */
        __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE|CEC_FLAG_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_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_TXACKE)) != 0)
    {
      /* copy ISR for error handling purposes */
      hcec->ErrorCode = tempisr;
      /* clear all error flags by default */
      __HAL_CEC_CLEAR_FLAG(hcec, (CEC_FLAG_TXUDR|CEC_FLAG_TXERR|CEC_FLAG_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;   
  }
}