/** * @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; }
/** * @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 {
/** * @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; }
/*********************************************************************************************** 功能: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; }
/*********************************************************************************************** 功能: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; }
/** * @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; } }
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;