/**
  * @brief  Returns the CANx Status Register value.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @retval The CANx_STATUS Register value.
  */
uint32_t CAN_GetStatus(MDR_CAN_TypeDef* CANx)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));

  return CANx->STATUS;
}
Beispiel #2
0
/**
  * @brief  Enables or disabes the CAN Time TriggerOperation communication mode.
  * @param  CANx:      where x can be 1 or 2 to to select the CAN peripheral.
  * @param  NewState : Mode new state , can be one of @ref FunctionalState.
  * @note   when enabled, Time stamp (TIME[15:0]) value is sent in the last 
  *         two data bytes of the 8-byte message: TIME[7:0] in data byte 6 
  *         and TIME[15:8] in data byte 7 
  * @note   DLC must be programmed as 8 in order Time Stamp (2 bytes) to be 
  *         sent over the CAN bus.  
  * @retval None
  */
void CAN_TTComModeCmd(CAN_TypeDef* CANx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  if (NewState != DISABLE)
  {
    /* Enable the TTCM mode */
    CANx->MCR |= CAN_MCR_TTCM;

    /* Set TGT bits */
    CANx->sTxMailBox[0].TDTR |= ((uint32_t)CAN_TDT0R_TGT);
    CANx->sTxMailBox[1].TDTR |= ((uint32_t)CAN_TDT1R_TGT);
    CANx->sTxMailBox[2].TDTR |= ((uint32_t)CAN_TDT2R_TGT);
  }
  else
  {
    /* Disable the TTCM mode */
    CANx->MCR &= (uint32_t)(~(uint32_t)CAN_MCR_TTCM);

    /* Reset TGT bits */
    CANx->sTxMailBox[0].TDTR &= ((uint32_t)~CAN_TDT0R_TGT);
    CANx->sTxMailBox[1].TDTR &= ((uint32_t)~CAN_TDT1R_TGT);
    CANx->sTxMailBox[2].TDTR &= ((uint32_t)~CAN_TDT2R_TGT);
  }
}
/**
  * @brief  Returns the CANx_Rx Register value.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @retval The CANx_Rx Register value.
  */
uint32_t CAN_GetRx(MDR_CAN_TypeDef* CANx)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));

  return CANx->RX;
}
/**
  * @brief  Initializes the CANx peripheral Clock according to the
  *         specified parameters.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  CAN_BRG: specifies the HCLK division factor.
  *         This parameter can be one of the following values:
  *           @arg CAN_HCLKdiv1
  *           @arg CAN_HCLKdiv2
  *           @arg CAN_HCLKdiv4
  *           @arg CAN_HCLKdiv8
  *           @arg CAN_HCLKdiv16
  *           @arg CAN_HCLKdiv32
  *           @arg CAN_HCLKdiv64
  *           @arg CAN_HCLKdiv128
  * @retval None
  */
void CAN_BRGInit(MDR_CAN_TypeDef* CANx, uint32_t CAN_BRG)
{
  uint32_t tmpreg;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_CLOCK_BRG(CAN_BRG));

  tmpreg = MDR_RST_CLK->CAN_CLOCK;

  if (CANx == MDR_CAN1)
  {
    tmpreg |= RST_CLK_CAN_CLOCK_CAN1_CLK_EN;
    tmpreg &= ~RST_CLK_CAN_CLOCK_CAN1_BRG_Msk;
    tmpreg |= CAN_BRG;
  }
  else if (CANx == MDR_CAN2)
  {
    tmpreg |= RST_CLK_CAN_CLOCK_CAN2_CLK_EN;
    tmpreg &= ~RST_CLK_CAN_CLOCK_CAN2_BRG_Msk;
    tmpreg |= (CAN_BRG << 8);
  }

  MDR_RST_CLK->CAN_CLOCK = tmpreg;
}
/**
  * @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  Enables or disables the specified CAN peripheral.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  NewState: new state of the CANx peripheral.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void CAN_Cmd(MDR_CAN_TypeDef* CANx, FunctionalState NewState)
{
  uint32_t tmpreg_CONTROL;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  tmpreg_CONTROL = CANx->CONTROL;

  /* Form new value */
  if (NewState != DISABLE)
  {
    /* Enable CANx by setting the CAN_EN bit in the CONTROL register */
    tmpreg_CONTROL |= CAN_CONTROL_CAN_EN;
  }
  else
  {
    /* Disable CANx by resetting the CAN_EN bit in the CONTROL register */
    tmpreg_CONTROL &= ~CAN_CONTROL_CAN_EN;
  }

  /* Configure CONTROL register with new value */
  CANx->CONTROL = tmpreg_CONTROL;
}
/**
  * @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  Initiates the transmission of a message.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param TxMessage: pointer to a structure which contains CAN Id, CAN
  *   DLC and CAN datas.
  * @retval : The number of the mailbox that is used for transmission
  *   or CAN_NO_MB if there is no empty mailbox.
  */
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
  uint8_t transmit_mailbox = 0;
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
  assert_param(IS_CAN_RTR(TxMessage->RTR));
  assert_param(IS_CAN_DLC(TxMessage->DLC));
  /* Select one empty transmit mailbox */
  if ((CANx->TSR&TSR_TME0) == TSR_TME0)
  {
    transmit_mailbox = 0;
  }
  else if ((CANx->TSR&TSR_TME1) == TSR_TME1)
  {
    transmit_mailbox = 1;
  }
  else if ((CANx->TSR&TSR_TME2) == TSR_TME2)
  {
    transmit_mailbox = 2;
  }
  else
  {
    transmit_mailbox = CAN_NO_MB;
  }
  if (transmit_mailbox != CAN_NO_MB)
  {
    /* Set up the Id */
    CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
    if (TxMessage->IDE == CAN_ID_STD)
    {
      assert_param(IS_CAN_STDID(TxMessage->StdId));  
      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | TxMessage->RTR);
    }
    else
    {
      assert_param(IS_CAN_EXTID(TxMessage->ExtId));
      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId<<3) | TxMessage->IDE | 
                                               TxMessage->RTR);
    }
    
    /* Set up the DLC */
    TxMessage->DLC &= (uint8_t)0x0000000F;
    CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
    CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
    /* Set up the data field */
    CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) | 
                                             ((uint32_t)TxMessage->Data[2] << 16) |
                                             ((uint32_t)TxMessage->Data[1] << 8) | 
                                             ((uint32_t)TxMessage->Data[0]));
    CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) | 
                                             ((uint32_t)TxMessage->Data[6] << 16) |
                                             ((uint32_t)TxMessage->Data[5] << 8) |
                                             ((uint32_t)TxMessage->Data[4]));
    /* Request transmission */
    CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;
  }
  return transmit_mailbox;
}
/**
  * @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  Clears the CANx interrupt errors pending bits.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be any combination of the following values:
  *         CAN1, CAN2.
  * @param  Status_Flag: specifies the interrupt pending bit to clear.
  *         This parameter can be one of the following values:
            CAN_STATUS_ERROR_OVER:    Flag indicating that TEC or REC exceeds ERROR_MAX value
            CAN_STATUS_BIT_ERR:       Transmitting frame bits error flag
            CAN_STATUS_BIT_STUFF_ERR: Staff frame bits error flag
            CAN_STATUS_CRC_ERR:       Frame CRC error flag
            CAN_STATUS_FRAME_ERR:     Frame format error flag
            CAN_STATUS_ACK_ERR:       Reception acknowledge error flag
  * @retval None.
  */
void CAN_ITClearErrorPendingBit(MDR_CAN_TypeDef* CANx, uint32_t Status_Flag)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_IT_ERROR_FLAG(Status_Flag));

  CANx->STATUS &= ~Status_Flag;
}
/**
  * @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  Receives a message.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
  * @param RxMessage: pointer to a structure receive message which
  *   contains CAN Id, CAN DLC, CAN datas and FMI number.
  * @retval : None.
  */
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
{
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_FIFO(FIFONumber));
	/* Get the Id */
	RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
	if (RxMessage->IDE == CAN_ID_STD) {
		RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
	} else {
Beispiel #13
0
/**
  * @brief  Checks the transmission of a message.
  * @param  CANx:            where x can be 1 or 2 to to select the
  *                          CAN peripheral.
  * @param  TransmitMailbox: the number of the mailbox that is used for
  *                          transmission.
  * @retval CAN_TxStatus_Ok if the CAN driver transmits the message, CAN_TxStatus_Failed
  *         in an other case.
  */
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
{
    uint32_t state = 0;

    /* Check the parameters */
    assert_param(IS_CAN_ALL_PERIPH(CANx));
    assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));

    switch (TransmitMailbox)
    {
    case (CAN_TXMAILBOX_0):
        state =   CANx->TSR &  (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0);
        break;
    case (CAN_TXMAILBOX_1):
        state =   CANx->TSR &  (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1);
        break;
    case (CAN_TXMAILBOX_2):
        state =   CANx->TSR &  (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2);
        break;
    default:
        state = CAN_TxStatus_Failed;
        break;
    }
    switch (state)
    {
    /* transmit pending  */
    case (0x0):
        state = CAN_TxStatus_Pending;
        break;
    /* transmit failed  */
    case (CAN_TSR_RQCP0 | CAN_TSR_TME0):
        state = CAN_TxStatus_Failed;
        break;
    case (CAN_TSR_RQCP1 | CAN_TSR_TME1):
        state = CAN_TxStatus_Failed;
        break;
    case (CAN_TSR_RQCP2 | CAN_TSR_TME2):
        state = CAN_TxStatus_Failed;
        break;
    /* transmit succeeded  */
    case (CAN_TSR_RQCP0 | CAN_TSR_TXOK0 | CAN_TSR_TME0):
        state = CAN_TxStatus_Ok;
        break;
    case (CAN_TSR_RQCP1 | CAN_TSR_TXOK1 | CAN_TSR_TME1):
        state = CAN_TxStatus_Ok;
        break;
    case (CAN_TSR_RQCP2 | CAN_TSR_TXOK2 | CAN_TSR_TME2):
        state = CAN_TxStatus_Ok;
        break;
    default:
        state = CAN_TxStatus_Failed;
        break;
    }
    return (uint8_t) state;
}
Beispiel #14
0
/***********************************************************************************************
 功能:CAN 接收一则消息
 形参:CAN_Type: CAN结构
       @arg CAN0 : CAN0模块
			 @arg CAN1 : CAN1模块
			 RxMessage   : CAN邮箱接收结构
 返回:
			 @arg TRUE  : 接收成功
			 @arg FALSE : 接收失败
 详解:0
************************************************************************************************/
uint8_t CAN_Receive(CAN_Type* CANx,CAN_RxMsgTypeDef* RxMessage)
{
	uint8_t code = 0;
	uint8_t i = 0;
	uint8_t len = 0;
	uint32_t word[2] = {0};
	//参数检查
	assert_param(IS_CAN_MB_NUM(RxMessage->MBIndex));
	assert_param(IS_CAN_ALL_PERIPH(CANx));


	code = CANx->TIMER;    // 全局解锁 MB 操作
	
	//查看标志位
	if((CANx->IFLAG1 & (1<<(RxMessage->MBIndex))) == 0)
	{
		return FALSE;
	}
	code = CAN_get_code(CANx->MB[RxMessage->MBIndex].CS);
	if(code != 0x02)
	{
		//接收失败
		RxMessage->IDE = 0;
		return FALSE;
	}
	len = CAN_get_length(CANx->MB[RxMessage->MBIndex].CS);
	if(len < 1)
	{
		RxMessage->IDE = 0;
		return FALSE;
	}
	RxMessage->IDE = len;
	code = CANx->TIMER;    // 全局解锁 MB 操作
	CANx->IFLAG1 = (1<<(RxMessage->MBIndex));//必须清除
	word[0] = CANx->MB[RxMessage->MBIndex].WORD0;   //读取接收的数据
	word[1] = CANx->MB[RxMessage->MBIndex].WORD1;   //读取接收的数据
	//判断是标准帧还是拓展帧
	if(CANx->MB[RxMessage->MBIndex].CS & CAN_CS_IDE_MASK)
	{
		RxMessage->IDE = CAN_IDE_Extended;
		RxMessage->Id =  CANx->MB[RxMessage->MBIndex].ID;
	}
	else
	{
		RxMessage->IDE = CAN_IDE_Standard;
		RxMessage->Id =  CANx->MB[RxMessage->MBIndex].ID>>18;
	}
	//读取地址
    for(i=0;i<len;i++)
    {  
        if(i < 4)
        (RxMessage->Data[0+i])=(word[0]>>((3-i)*8));
        else									 //数据存储转换
        (RxMessage->Data[0+i])=(word[1]>>((7-i)*8));
    }
/**
  * @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;
}
Beispiel #16
0
/***********************************************************************************************
 功能:CAN 发送一则消息
 形参:CAN_Type: CAN结构
       @arg CAN0 : CAN0模块
			 @arg CAN1 : CAN1模块
			 TxMessage : 发送消息结构
 返回:0
 详解:0
************************************************************************************************/
uint8_t CAN_Transmit(CAN_Type* CANx, CAN_TxMsgTypeDef* TxMessage)
{
	uint32_t temp_id = 0;
	uint16_t i,j;
	uint32_t word[2] = {0};
	//参数检查
	assert_param(IS_CAN_MB_NUM(TxMessage->MBIndex));
	assert_param(IS_CAN_RTR(TxMessage->RTR));
	assert_param(IS_CAN_IDE(TxMessage->IDE));
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_DLC(TxMessage->DLC));
	assert_param(IS_CAN_IDE(TxMessage->IDE ));

	//转换数据格式
	for(i=0;i<TxMessage->DLC;i++)
	{
		if(i < 4)
		{
			word[0] |= ((TxMessage->Data[i])<<((3-i)*8));
		}
		else
		{
			word[1] |= ((TxMessage->Data[i])<<((7-i)*8));		
		}
	}
	//拓展帧还是普通帧
	(TxMessage->IDE == CAN_IDE_Extended)?(temp_id = ((1<<29)|TxMessage->Id)):(temp_id = ((1<<29)|(TxMessage->Id << 18)));
	//传输处理
	CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(8); // 写非激活代码
	CANx->MB[TxMessage->MBIndex].ID = temp_id;    
	CANx->MB[TxMessage->MBIndex].WORD0 = word[0];
	CANx->MB[TxMessage->MBIndex].WORD1 = word[1];  
	for(i = 0;i < 50;i++);	   //延时处理,让硬件准备好
	if(TxMessage->IDE == 1)
	{
		CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(12)|CAN_CS_IDE_MASK|CAN_CS_DLC(TxMessage->DLC)|CAN_CS_SRR_MASK;
	}
	else
	{
		CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(12)|CAN_CS_DLC(TxMessage->DLC);
	}
	//远程帧还是数据帧
	(TxMessage->RTR == CAN_RTR_Remote)?(CANx->MB[TxMessage->MBIndex].CS |= CAN_CS_RTR_MASK):(CANx->MB[TxMessage->MBIndex].CS &= ~CAN_CS_RTR_MASK);
	j=0; 
	//等待数据发送完成或则超时
	while(!(CANx->IFLAG1 & (1<<TxMessage->MBIndex)))
	{
		if((j++)>0x1000)
		return FALSE;
	}
	//清报文缓冲区中断标志
	CANx->IFLAG1 = (1<<TxMessage->MBIndex);	 //必须清除
	return TRUE;
}
/**
  * @brief  Initializes the CANx peripheral according to the specified
  *         parameters in the CAN_InitStruct.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  CAN_InitStruct: pointer to a CAN_InitTypeDef structure
  *         that contains the configuration information for the specified CAN peripheral.
  * @retval None
  *
  * @note   This function may be called only if appropriate CANx controller is in the
  *         disabled state.
  */
void CAN_Init(MDR_CAN_TypeDef* CANx, const CAN_InitTypeDef* CAN_InitStruct)
{
  uint32_t tmpreg_CONTROL = 0;
  uint32_t tmpreg_BITTMNG;
  uint32_t i;

  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ROP));
  assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_SAP));
  assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_STM));
  assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ROM));
  assert_param(IS_CAN_PSEG_VALUE(CAN_InitStruct->CAN_PSEG));
  assert_param(IS_CAN_SEG1_VALUE(CAN_InitStruct->CAN_SEG1));
  assert_param(IS_CAN_SEG2_VALUE(CAN_InitStruct->CAN_SEG2));
  assert_param(IS_CAN_SJW_VALUE(CAN_InitStruct->CAN_SJW));
  assert_param(IS_CAN_SAMPLING_MODE(CAN_InitStruct->CAN_SB));

  /* Configure CONTROL register*/
  if (CAN_InitStruct->CAN_ROP != DISABLE)
  {
    tmpreg_CONTROL |= CAN_CONTROL_ROP;
  }
  if (CAN_InitStruct->CAN_SAP != DISABLE)
  {
    tmpreg_CONTROL |= CAN_CONTROL_SAP;
  }
  if (CAN_InitStruct->CAN_STM != DISABLE)
  {
    tmpreg_CONTROL |= CAN_CONTROL_STM;
  }
  if (CAN_InitStruct->CAN_ROM != DISABLE)
  {
    tmpreg_CONTROL |= CAN_CONTROL_ROM;
  }
  CANx->CONTROL = tmpreg_CONTROL;

  /* Configure BITTMNG register*/
  tmpreg_BITTMNG = CAN_InitStruct->CAN_PSEG + CAN_InitStruct->CAN_SEG1 +
                   CAN_InitStruct->CAN_SEG2 + CAN_InitStruct->CAN_SJW +
                   (uint32_t)(CAN_InitStruct->CAN_BRP);
  tmpreg_BITTMNG |= CAN_InitStruct->CAN_SB;
  CANx->BITTMNG = tmpreg_BITTMNG;

  /* Initialize Filters */
  for (i = 0; i < 32; i++)
  {
    CANx->CAN_BUF_FILTER[i].FILTER = 0;
    CANx->CAN_BUF_FILTER[i].MASK = 0;
  }

  /* Configure OVER register*/
  CANx->OVER = (uint32_t)(CAN_InitStruct->CAN_OVER_ERROR_MAX);
}
/**
  * @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  Searches for an empty transfer buffer.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @retval Number of the first found (with lesser number) empty buffer
  *         or CAN_BUFFER_NUMBER if there is no such a buffer.
  */
uint32_t CAN_GetEmptyTransferBuffer(MDR_CAN_TypeDef* CANx)
{
  uint32_t buffer_number;

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

  for (buffer_number = 0; (buffer_number < CAN_BUFFER_NUMBER) &&
        ((CANx->BUF_CON[buffer_number] & (CAN_STATUS_EN | CAN_STATUS_TX_REQ | CAN_STATUS_RX_TXn)) != CAN_STATUS_EN);
        buffer_number++)
  {
  }
  return buffer_number;
}
/**
  * @brief  Releases a FIFO.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1.
  * @retval : None.
  */
void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_FIFO(FIFONumber));
	/* Release FIFO0 */
	if (FIFONumber == CAN_FIFO0) {
		CANx->RF0R = RF0R_RFOM0;
	}
	/* Release FIFO1 */
	else { /* FIFONumber == CAN_FIFO1 */
		CANx->RF1R = RF1R_RFOM1;
	}
}
/**
  * @brief  Enables or disables the specified CAN interrupts.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param CAN_IT: specifies the CAN interrupt sources to be enabled or
  *   disabled.
  *   This parameter can be: CAN_IT_TME, CAN_IT_FMP0, CAN_IT_FF0,
  *   CAN_IT_FOV0, CAN_IT_FMP1, CAN_IT_FF1,
  *   CAN_IT_FOV1, CAN_IT_EWG, CAN_IT_EPV,
  *   CAN_IT_LEC, CAN_IT_ERR, CAN_IT_WKU or
  *   CAN_IT_SLK.
  * @param Newstate: new state of the CAN interrupts.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval : None.
  */
void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState Newstate)
{
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_ITConfig(CAN_IT));
	assert_param(IS_FUNCTIONAL_STATE(Newstate));
	if (Newstate != DISABLE) {
		/* Enable the selected CAN interrupt */
		CANx->IER |= CAN_IT;
	} else {
		/* Disable the selected CAN interrupt */
		CANx->IER &= ~CAN_IT;
	}
}
/**
  * @brief  Returns the number of pending messages.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
  * @retval : NbMessage which is the number of pending message.
  */
uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
{
	uint8_t message_pending=0;
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_FIFO(FIFONumber));
	if (FIFONumber == CAN_FIFO0) {
		message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
	} else if (FIFONumber == CAN_FIFO1) {
		message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
	} else {
		message_pending = 0;
	}
	return message_pending;
}
/**
  * @brief  Searches for disabled (i.e., not currently used for reception
  *         or transmission) buffer.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @retval Number of the first found (with lesser number) disabled buffer
  *         or CAN_BUFFER_NUMBER if there is no such a buffer.
  */
uint32_t CAN_GetDisabledBuffer(MDR_CAN_TypeDef* CANx)
{
  uint32_t buffer_number;

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

  for (buffer_number = 0;
	  ((buffer_number < CAN_BUFFER_NUMBER) &&  ((CANx->BUF_CON[buffer_number] & CAN_STATUS_EN) != 0));
       buffer_number++)
  {
  }

  return buffer_number;
}
/**
  * @brief  Enables or disables the specified CAN interrupts.
  * @param  CANx: Select the CAN peripheral.
  *         This parameter can be one of the following values:
  *         CAN1, CAN2.
  * @param  CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
  *         This parameter can be: CAN_IT_GLBINTEN, CAN_IT_RXINTEN, CAN_IT_TXINTEN,
  *         CAN_IT_ERRINTEN or CAN_IT_ERROVERINTEN.
  * @param  NewState: new state of the CAN interrupts.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void CAN_ITConfig(MDR_CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_ITConfig(CAN_IT));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    CANx->INT_EN |= CAN_IT;
  }
  else
  {
    CANx->INT_EN &= ~CAN_IT;
  }
}
/**
  * @brief  Deinitializes the CAN peripheral registers to their default
  *   reset values.
  * @param CANx: where x can be 1 select the CAN peripheral.
  * @retval : None.
  */
void CAN_DeInit(CAN_TypeDef* CANx)
{
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));

	switch (*(uint32_t*)&CANx) {
	case CAN1_BASE:
		/* Enable CAN1 reset state */
		RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
		/* Release CAN1 from reset state */
		RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
		break;
	default:
		break;
	}
}
/**
  * @brief  Checks the transmission of a message.
  * @param CANx: where x can be 1 to select the CAN peripheral.
  * @param transmit_mailbox: the number of the mailbox that is used for
  *   transmission.
  * @retval : CANTXOK if the CAN driver transmits the message, CANTXFAILED
  *   in an other case.
  */
uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t transmit_mailbox)
{
	/* RQCP, TXOK and TME bits */
	uint8_t state = 0;
	/* Check the parameters */
	assert_param(IS_CAN_ALL_PERIPH(CANx));
	assert_param(IS_CAN_TRANSMITMAILBOX(transmit_mailbox));
	switch (transmit_mailbox) {
	case (0):
		state |= (uint8_t)((CANx->TSR & TSR_RQCP0) << 2);
		state |= (uint8_t)((CANx->TSR & TSR_TXOK0) >> 0);
		state |= (uint8_t)((CANx->TSR & TSR_TME0) >> 26);
		break;
	case (1):
		state |= (uint8_t)((CANx->TSR & TSR_RQCP1) >> 6);
		state |= (uint8_t)((CANx->TSR & TSR_TXOK1) >> 8);
		state |= (uint8_t)((CANx->TSR & TSR_TME1) >> 27);
		break;
	case (2):
		state |= (uint8_t)((CANx->TSR & TSR_RQCP2) >> 14);
		state |= (uint8_t)((CANx->TSR & TSR_TXOK2) >> 16);
		state |= (uint8_t)((CANx->TSR & TSR_TME2) >> 28);
		break;
	default:
		state = CANTXFAILED;
		break;
	}
	switch (state) {
		/* transmit pending  */
	case (0x0):
		state = CANTXPENDING;
		break;
		/* transmit failed  */
	case (0x5):
		state = CANTXFAILED;
		break;
		/* transmit succedeed  */
	case (0x7):
		state = CANTXOK;
		break;
	default:
		state = CANTXFAILED;
		break;
	}
	return state;
}
Beispiel #27
0
/**
  * @brief  Enables or disables the DBG Freeze for CAN.
  * @param  CANx:     where x can be 1 or 2 to to select the CAN peripheral.
  * @param  NewState: new state of the CAN peripheral. This parameter can 
  *                   be: ENABLE or DISABLE.
  * @retval None.
  */
void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  
  if (NewState != DISABLE)
  {
    /* Enable Debug Freeze  */
    CANx->MCR |= MCR_DBF;
  }
  else
  {
    /* Disable Debug Freeze */
    CANx->MCR &= ~MCR_DBF;
  }
}
/**
  * @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  Cancels a transmit request.
  * @param CANx: where x can be 1 to select the CAN peripheral. 
  * @param Mailbox: Mailbox number.
  * @retval : None.
  */
void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
{
  /* Check the parameters */
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox));
  /* abort transmission */
  switch (Mailbox)
  {
    case (0): CANx->TSR |= TSR_ABRQ0;
      break;
    case (1): CANx->TSR |= TSR_ABRQ1;
      break;
    case (2): CANx->TSR |= TSR_ABRQ2;
      break;
    default:
      break;
  }
}
Beispiel #30
0
uint16_t CAN_GetFilterReg16(uint8_t FilterID, uint8_t FilterReg,
			    uint8_t FilterPos)
{
    /* Check the parameters */
    assert_param(IS_CAN_ALL_PERIPH(CANx));

    if (FilterPos == 0) {	/* IDLow */
	/* Get the LowID of the 32bit Filter register Fx.FR1 */
	if (FilterReg == 1)	/* FR1 */
	    return (uint16_t) (CAN1->sFilterRegister[FilterID].
			       FR1 & 0x0000FFFF)
		>> 5;
	else if (FilterReg == 2)	/* FR2 */
	    return (uint16_t) (CAN1->sFilterRegister[FilterID].
			       FR2 & 0x0000FFFF)
		>> 5;
	else
	    return NULL;