/**
  * @brief  Clears the CANx reception buffer interrupt pending bit,
  *         does nothing if transmission interrupt pending bit is specified.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: The number of the buffer
  * @param  Status_Flag: specifies the interrupt pending bit to clear.
  *         This parameter can be of the following values:
            CAN_STATUS_RX_READY:    Flag indicating that there are messages received
            CAN_STATUS_TX_READY:    Flag indicating that there are buffers for transmitting
  * @retval None.
  */
void CAN_ITClearRxTxPendingBit(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, uint32_t Status_Flag)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_IT_RXTX_FLAG(Status_Flag));

  tmpreg = CANx->BUF_CON[BufferNumber];

  if (Status_Flag == CAN_STATUS_RX_READY)
  {
    tmpreg &= ~CAN_STATUS_RX_FULL;
  }
  /* FIXME: Setting of TX_REQ bit here, initiates a retransmission of a previous
     message. For this reason, the following branch has been commented out.
     The transmission interrupt pending bit will be automatically cleared when you
     start the next transmission.

  else if (Status_Flag == CAN_STATUS_TX_READY)
  {
    tmpreg |= CAN_STATUS_TX_REQ;
  }
  */

  CANx->BUF_CON[BufferNumber] = tmpreg;
}
/**
  * @brief  Reads received message (containing both header and data) from buffer.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for reception.
  * @param  RxMessage: pointer to a CAN_RxMsgTypeDef.
  * @retval None
  */
void CAN_GetRawReceivedData(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_RxMsgTypeDef* RxMessage)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));

  /* Get the DLC */
  tmpreg = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].DLC));

  RxMessage->Rx_Header.DLC = (uint8_t)(tmpreg & CAN_DLC_DATA_LENGTH);
  /* Get the IDE */
  RxMessage->Rx_Header.IDE = CAN_ID_STD;
  if ((tmpreg & CAN_DLC_IDE) != 0)
  {
    RxMessage->Rx_Header.IDE = CAN_ID_EXT;
  }
  /* Get the OVER_EN */
  RxMessage->Rx_Header.OVER_EN = DISABLE;
  tmpreg = CAN_ReadBufferSFR(&(CANx->BUF_CON[BufferNumber]));
  if ((tmpreg & CAN_BUF_CON_OVER_EN) != 0)
  {
    RxMessage->Rx_Header.OVER_EN = ENABLE;
  }
  /* Get the Id */
  RxMessage->Rx_Header.ID = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].ID));

  /* Get the data field */
  RxMessage->Data[0] = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].DATAL));
  RxMessage->Data[1] = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].DATAH));
}
/**
  * @brief  Returns the CANx_BUF_xx_CON Register value.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: The number of the buffer.
  * @retval The CANx_BUF_xx_CON Register value.
  */
uint32_t CAN_GetBufferStatus(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));

  return CANx->BUF_CON[BufferNumber];
}
/**
  * @brief  Reads the received data from buffer.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for reception.
  * @param  RxBuffer: CAN_DataTypeDef array to place received data to.
  * @retval None
  */
void CAN_GetReceivedData(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_DataTypeDef RxBuffer)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));

  RxBuffer[0] = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].DATAL));
  RxBuffer[1] = CAN_ReadBufferSFR(&(CANx->CAN_BUF[BufferNumber].DATAH));
}
/**
  * @brief  Initializes the CANx Buffer filter and mask according to the specified
  *         parameters in the CAN_FilterInitStruct.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values: CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for reception.
  * @param  CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef
  *         structure that contains the configuration information.
  * @retval None.
  */
void CAN_FilterInit(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_FilterInitTypeDef* CAN_FilterInitStruct)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_ID(CAN_FilterInitStruct->Filter_ID));
  assert_param(IS_CAN_ID(CAN_FilterInitStruct->Mask_ID));

  CANx->CAN_BUF_FILTER[BufferNumber].FILTER  = CAN_FilterInitStruct->Filter_ID;
  CANx->CAN_BUF_FILTER[BufferNumber].MASK    = CAN_FilterInitStruct->Mask_ID;
}
/**
  * @brief  Releases the buffer.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer to be released.
  * @retval None.
  */
void CAN_BufferRelease(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));

  tmpreg = CANx->BUF_CON[BufferNumber];
  tmpreg &= ~CAN_STATUS_EN;
  CANx->BUF_CON[BufferNumber] = tmpreg;
}
/**
  * @brief  Initiates the transmission of a message.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for transmission.
  * @param  TxMessage: pointer to a CAN_TxMsgTypeDef structure.
  * @retval None
  */
void CAN_Transmit(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_TxMsgTypeDef* TxMessage)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
  assert_param(IS_CAN_DLC(TxMessage->DLC));
  assert_param(IS_FUNCTIONAL_STATE(TxMessage->PRIOR_0));
  assert_param(IS_CAN_ID(TxMessage->ID));

  /* Configure CAN_BUF_ID and CAN_BUF_DLC registers */
  /* Packet format */
  if (TxMessage->IDE == CAN_ID_STD)
  {
    /* Standard */
    tmpreg = CAN_BUF_DLC_STD + TxMessage->DLC;
  }
  else
  {
    /* Extended */
    tmpreg = CAN_BUF_DLC_EXT + TxMessage->DLC;
  }
  CANx->CAN_BUF[BufferNumber].DLC = tmpreg;
  CANx->CAN_BUF[BufferNumber].ID  = TxMessage->ID;

  /* Buffer data unit */
  CANx->CAN_BUF[BufferNumber].DATAL = TxMessage->Data[0];
  CANx->CAN_BUF[BufferNumber].DATAH = TxMessage->Data[1];

  /* Configure CAN_BUF_CON register */
  tmpreg = 0;
  /* Transmission priority */
  if (TxMessage->PRIOR_0 != DISABLE)
  {
    tmpreg |= CAN_BUF_CON_PRIOR_0;
  }
  /* Set transmission request bit */
  tmpreg |= CAN_BUF_CON_TX_REQ;
  /* Enable buffer */
  tmpreg |= CAN_BUF_CON_EN;

  CANx->BUF_CON[BufferNumber] = tmpreg;
}
/**
  * @brief  Checks whether the specified transmission buffer interrupt has occurred or not.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: The number of the buffer
  * @retval The new state of ~TX_REQ[BufferNumber] flag (SET or RESET).
  */
ITStatus CAN_GetTxITStatus(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber)
{
  FlagStatus bitstatus;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));

  if ((CANx->TX & CANx->INT_TX & (((uint32_t)0x1) << BufferNumber)) == 0)
  {
    bitstatus = RESET;
  }
  else
  {
    bitstatus = SET;
  }

  return bitstatus;
}
/**
  * @brief  Starts the waiting for the receiving of a message.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for reception.
  * @param  OverWrite: Enables or disables overwrite mode.
  *         This parameter can be one of the following values:
  *         ENABLE, DISABLE.
  * @retval None
  */
void CAN_Receive(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, FunctionalState OverWrite)
{
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_FUNCTIONAL_STATE(OverWrite));

  /* Configure CAN_BUF_CON register */
  /* Overwrite mode */
  if (OverWrite != DISABLE)
  {
    tmpreg = CAN_BUF_CON_OVER_EN;
  }
  /* Configure buffer for receiving and enable it */
  tmpreg |= CAN_BUF_CON_RX_TXN | CAN_BUF_CON_EN;

  CANx->BUF_CON[BufferNumber] = tmpreg;
}
/**
  * @brief  Initiates the Remote Transfer Request.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: the number of the buffer that is used for transmission.
  * @param  RTRMessage: pointer to a CAN_RTRMessageTypeDef structure.
  * @retval None
  */
void CAN_SendRTR(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_RTRMessageTypeDef* RTRMessage)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_IDTYPE(RTRMessage->IDE));
  assert_param(IS_FUNCTIONAL_STATE(RTRMessage->PRIOR_0));
  assert_param(IS_CAN_ID(RTRMessage->ID));

  /* Configure CAN_BUF_ID and CAN_BUF_DLC registers */
  /* Packet format */
  if (RTRMessage->IDE == CAN_ID_STD)
  {
    /* Standard */
    tmpreg = CAN_BUF_DLC_STD;
  }
  else
  {
    /* Extended */
    tmpreg = CAN_BUF_DLC_EXT;
  }
  CANx->CAN_BUF[BufferNumber].DLC = tmpreg + CAN_RTR_REMOTE;
  CANx->CAN_BUF[BufferNumber].ID  = RTRMessage->ID;

  /* Configure CAN_BUF_CON register */
  tmpreg = 0;
  /* Transmission priority */
  if (RTRMessage->PRIOR_0 != DISABLE)
  {
    tmpreg |= CAN_BUF_CON_PRIOR_0;
  }
  /* Set transmission request bit */
  tmpreg |= CAN_BUF_CON_TX_REQ;
  /* Enable buffer */
  tmpreg |= CAN_BUF_CON_EN;

  CANx->BUF_CON[BufferNumber] = tmpreg;
}
void CAN_RTRReply(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, CAN_RTRReplyTypeDef* RTRReplyMessage)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_IDTYPE(RTRReplyMessage->IDE));
  assert_param(IS_CAN_ID(RTRReplyMessage->ID));
  assert_param(IS_CAN_DLC(RTRReplyMessage->DLC));

  /* Configure CAN_BUF_ID and CAN_BUF_DLC registers */
  /* Configure CAN_BUF_ID and CAN_BUF_DLC registers */
  /* Packet format */
  if (RTRReplyMessage->IDE == CAN_ID_STD)
  {
    /* Standard */
    tmpreg = CAN_BUF_DLC_STD + RTRReplyMessage->DLC;
  }
  else
  {
    /* Extended */
    tmpreg = CAN_BUF_DLC_EXT + RTRReplyMessage->DLC;
  }
  CANx->CAN_BUF[BufferNumber].DLC = tmpreg;
  CANx->CAN_BUF[BufferNumber].ID  = RTRReplyMessage->ID;

  /* Buffer data unit */
  CANx->CAN_BUF[BufferNumber].DATAL = RTRReplyMessage->Data[0];
  CANx->CAN_BUF[BufferNumber].DATAH = RTRReplyMessage->Data[1];

  /* Configure CAN_BUF_CON register */
  /* Set RTR_EN bit */
  tmpreg = CAN_STATUS_RTR_EN;
  /* Enable buffer */
  tmpreg |= CAN_BUF_CON_EN;

  CANx->BUF_CON[BufferNumber] = tmpreg;
}
/**
  * @brief  Clears the CANx transmission or reception buffer interrupt
  *         pending bits.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  BufferNumber: The number of the buffer
  * @param  Status_Flag: specifies the interrupt pending bit to clear.
  *         This parameter can be of the following values:
            CAN_STATUS_RX_READY:    Flag indicating that there are messages received
            CAN_STATUS_TX_READY:    Flag indicating that there are buffers for transmitting
  * @retval None.
  */
void CAN_ITClearRxTxPendingBit(MDR_CAN_TypeDef* CANx, uint32_t BufferNumber, uint32_t Status_Flag)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_BUFFER(BufferNumber));
  assert_param(IS_CAN_IT_RXTX_FLAG(Status_Flag));

  tmpreg = CANx->BUF_CON[BufferNumber];

  if (Status_Flag == CAN_STATUS_RX_READY)
  {
    tmpreg &= ~CAN_STATUS_RX_FULL;
  }
  else if (Status_Flag == CAN_STATUS_TX_READY)
  {
    tmpreg |= CAN_STATUS_TX_REQ;
  }

  CANx->BUF_CON[BufferNumber] = tmpreg;
}