/** ****************************************************************************** * @file xl_mcan.c * @author Kirk ,xu.wang * @version 4.5.2 * @date Fri Mar 26 17:29:12 2021 * @brief This file provide function about MCAN firmware program ****************************************************************************** * @attention * * 2019 by Chipways Communications,Inc. All Rights Reserved. * This software is supplied under the terms of a license * agreement or non-disclosure agreement with Chipways. * Passing on and copying of this document,and communication * of its contents is not permitted without prior written * authorization. * *

© COPYRIGHT 2019 Chipways

****************************************************************************** */ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus */ /* Includes ---------------------------------------------------------------*/ #include "xl_mcan.h" /** @addtogroup XL6600_StdPeriph_Driver * @{ */ /** @defgroup MCAN MCAN Module * @brief MCAN Driver Modules Library * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ /** @defgroup MCAN_Private_Functions * @{ */ /** * @brief ½«MCANÍâÉè¼Ä´æÆ÷È¥³õʼ»¯,¸´Î». * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval None. */ void MCAN_DeInit(MCAN_Type* MCANx) { /* Deinitializes to default reset values */ MCANx->CANMOD = 0x01; MCANx->CANCMR = 0x00; MCANx->CANBTR0 = 0x00; MCANx->CANBTR1 = 0x00; MCANx->CANIER = 0x00; } /** * @brief ¸ù¾ÝÔÚMCAN_InitStructÖÐÖ¸¶¨²ÎÊý³õʼ»¯MCANÍâÉè. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param MCAN_InitStruct: MCAN³õʼ»¯ÅäÖýṹÌå * @retval None */ void MCAN_Init(MCAN_Type* MCANx, const MCAN_InitTypeDef* MCAN_InitStruct) { /* enter reset mode */ MCAN_SetMode(MCANx,MCAN_RESETMODE); /* Set the nominal bit timing register */ MCANx->CANBTR0 &= ~(MCAN_CANBTR0_BRP_MASK | MCAN_CANBTR0_SJW_MASK); MCANx->CANBTR0 |= ((MCAN_InitStruct->MCAN_BRP) | (MCAN_InitStruct->MCAN_SJW << MCAN_CANBTR0_SJW_SHIFT)); MCANx->CANBTR1 &= ~(MCAN_CANBTR1_TSEG1_MASK | MCAN_CANBTR1_TSEG2_MASK |\ MCAN_CANBTR1_SAMP_MASK); MCANx->CANBTR1 |= ((MCAN_InitStruct->MCAN_TSEG1) | (MCAN_InitStruct->MCAN_TSEG2 << MCAN_CANBTR1_TSEG2_SHIFT)|\ (MCAN_InitStruct->MCAN_SAMP << MCAN_CANBTR1_SAMP_SHIFT)); /* Set the FD data bit timing register */ MCANx->CANFDBTR0 &= ~(MCAN_CANFDBTR0_FDBRP_MASK | MCAN_CANFDBTR0_FDSJW_MASK); MCANx->CANFDBTR0 |= ((MCAN_InitStruct->MCAN_FDBRP) | (MCAN_InitStruct->MCAN_FDSJW << MCAN_CANFDBTR0_FDSJW_SHIFT)); MCANx->CANFDBTR1 &= ~(MCAN_CANFDBTR1_FDTSEG1_MASK | MCAN_CANFDBTR1_FDTSEG2_MASK |\ MCAN_CANFDBTR1_FDSAMP_MASK); MCANx->CANFDBTR1 |= ((MCAN_InitStruct->MCAN_FDTSEG1) | (MCAN_InitStruct->MCAN_FDTSEG2 << MCAN_CANFDBTR1_FDTSEG2_SHIFT)|\ (MCAN_InitStruct->MCAN_FDSAMP << MCAN_CANFDBTR1_FDSAMP_SHIFT)); /* clear reset mode if in this mode*/ MCANx->CANMOD &= ~MCAN_CANMOD_RM_MASK; } /** * @brief MCANxʹÄÜ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param State: MCANxʹÄÜ״̬ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg ENABLE: MCANxʹÄÜ * @arg DISABLE: MCANxʧÄÜ * @retval None. */ void MCAN_Enable(MCAN_Type* MCANx, FunctionalState NewState) { if(NewState == ENABLE) { MCANx->CANCMR |= MCAN_CANCMR_EN_MASK; } else { MCANx->CANCMR &= ~MCAN_CANCMR_EN_MASK; } } /** * @brief ÆôÓûò½ûÓÃMCAN FD * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param State: MCANx FDʹÄÜ״̬ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg ENABLE: MCANx FDʹÄÜ * @arg DISABLE: MCANx FDʧÄÜ * @retval None. */ void MCAN_FDCmd(MCAN_Type* MCANx, FunctionalState NewState) { if(NewState != DISABLE ) { /* Enable the can FD */ MCANx->CANMOD |= MCAN_CANMOD_FDM_MASK ; } else { /* Disable the can FD */ MCANx->CANMOD &= ~MCAN_CANMOD_FDM_MASK ; } } /** * @brief ÔÚFDģʽÏÂÑ¡Ôñ·¢Ë͸ñʽÀàÐÍ¡£ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param FdFormat: ÔÚFDģʽÏÂÑ¡Ôñ·¢Ë͸ñʽÀàÐÍ¡£ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_FDM_NOMFrame: ·¢ËÍ֡ΪÆÕͨCANÊý¾ÝÖ¡ * @arg MCAN_FDM_FDFrame: ·¢ËÍ֡ΪCAN FDÖ¡ * @retval None. */ void MCAN_FDSendFormatSel(MCAN_Type* MCANx, uint8_t FdFormat) { if(FdFormat == MCAN_FDM_FDFrame ) { /* send the FD frame in FD mode */ MCANx->CANMOD |= MCAN_CANMOD_FDTREN_MASK ; } else { /* send the nominal frame in FD mode */ MCANx->CANMOD &= ~MCAN_CANMOD_FDTREN_MASK ; } } /** * @brief ÉèÖò¹³¥Ê±¼ä¡£ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param CompensateTime:ÉèÖ÷¢ËÍÑÓʱ²¹³¥µÄʱ¼ä,·¶Î§Îª0x00~0x1F * @retval None. */ void MCAN_FDTDCSet(MCAN_Type* MCANx, uint32_t CompensateTime) { /* set the compensation time */ MCANx->CANTDCS &= ~MCAN_CANTDCS_TDCT_MASK; MCANx->CANTDCS |= (CompensateTime & (uint32_t)0x1F); } /** * @brief ÆôÓûò½ûÓÃMCAN FDÑÓʱ²¹³¥¹¦ÄÜ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param NewState: Ñ¡Ôñ״̬ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg ENABLE: ʹÄÜMCAN FDÑÓʱ²¹³¥¹¦ÄÜ * @arg DISABLE: ʧÄÜMCAN FDÑÓʱ²¹³¥¹¦ÄÜ * @retval None. */ void MCAN_FDTDCENCmd(MCAN_Type* MCANx, FunctionalState NewState) { if(NewState != DISABLE ) { /* Enable the FD time delay compensation feature */ MCANx->CANMOD |= MCAN_CANMOD_FDTDCEN_MASK ; } else { /* Disable the FD time delay compensation feature */ MCANx->CANMOD &= ~MCAN_CANMOD_FDTDCEN_MASK ; } } /** * @brief ÉèÖÿª¹Øµã²¹³¥Ê±¼ä. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param CompensateTime: ²¹³¥É趨ʱ¼ä,·¶Î§Îª0x00~0x7F. * @retval None. */ void MCAN_FDHFCSet(MCAN_Type* MCANx, uint32_t CompensateTime) { /* set the compensation time */ MCANx->CANHFC &= ~MCAN_CANHFC_HFCT_MASK; MCANx->CANHFC |= (CompensateTime & (uint32_t)0x7F); } /** * @brief ¸ù¾ÝÔÚMCAN_FilterStructÖеÄÖ¸¶¨²ÎÊýÅäÖÃMCANÍâÉè¹ýÂËģʽ. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param MCAN_FilterStruct:Ö¸Ïò°üº¬MCANÍâÉèÅäÖÃÐÅÏ¢µÄMCAN_FilterDef ½á¹¹µÄÖ¸Õë. * @retval None. */ void MCAN_FilterConfig(MCAN_Type* MCANx, const MCAN_FilterDef* MCAN_FilterStruct) { uint32_t MCAN_Mask; uint32_t MCAN_ID; /* enter reset mode */ MCAN_SetMode(MCANx,MCAN_RESETMODE); /* Set the filter mode */ MCANx->CANMOD &=~MCAN_CANMOD_AFM_MASK; MCANx->CANMOD |= (MCAN_FilterStruct->MCAN_FiltMode << MCAN_CANMOD_AFM_SHIFT); /* config the accept and mask register */ /* if use single filter, 32bit filter */ if(MCAN_FilterStruct->MCAN_FiltMode==MCAN_Single_Filter) { /* ID(standard )+RTR=12 bit*/ if(MCAN_FilterStruct->MCAN_IDMode==MCAN_Standard_Frame) { MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_IDAR)<<21); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_IDMR)<<21); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[1]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[1]=(MCAN_Mask>>16); MCANx->CANAR.CANACR[2]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[2]=0xFF; //data bytes1 do not care MCANx->CANAR.CANACR[3]=(MCAN_ID); MCANx->CANAR.CANAMR[3]=0xFF; //data bytes2 do not care } /* ID( extended)+RTR=30 bit*/ else if(MCAN_FilterStruct->MCAN_IDMode==MCAN_Extended_Frame) { MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_IDAR)<<3); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_IDMR)<<3); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[1]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[1]=(MCAN_Mask>>16); MCANx->CANAR.CANACR[2]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[2]=(MCAN_Mask>>8); MCANx->CANAR.CANACR[3]=(MCAN_ID); MCANx->CANAR.CANAMR[3]=(MCAN_Mask); } else { MCAN_ID=(uint32_t)(MCAN_FilterStruct->MCAN_IDAR); MCAN_Mask=(uint32_t)(MCAN_FilterStruct->MCAN_IDMR); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[1]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[1]=(MCAN_Mask>>16); MCANx->CANAR.CANACR[2]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[2]=(MCAN_Mask>>8); MCANx->CANAR.CANACR[3]=(MCAN_ID); MCANx->CANAR.CANAMR[3]=(MCAN_Mask); } } /* else use dual filter, 16bit filter */ else { /* ID(standard )+RTR=12 bit*/ if(MCAN_FilterStruct->MCAN_IDMode==MCAN_Standard_Frame) { MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_IDAR)<<5); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_IDMR)<<5); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>8); MCANx->CANAR.CANACR[1]=(MCAN_ID); MCANx->CANAR.CANAMR[1]=(MCAN_Mask | 0x0000000Fu); MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_DIDAR)<<5); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_DIDMR)<<5); MCANx->CANAR.CANACR[2]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[2]=(MCAN_Mask>>8); MCANx->CANAR.CANACR[3]=(MCAN_ID); MCANx->CANAR.CANAMR[3]=(MCAN_Mask| 0x0000000Fu); } /* ID( extended)+RTR=30 bit*/ else if(MCAN_FilterStruct->MCAN_IDMode==MCAN_Extended_Frame) { MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_IDAR)<<3); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_IDMR)<<3); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[1]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[1]=((MCAN_Mask>>16) | 0x0000000Fu); MCAN_ID=(uint32_t)((MCAN_FilterStruct->MCAN_DIDAR)<<3); MCAN_Mask=(uint32_t)((MCAN_FilterStruct->MCAN_DIDMR)<<3); MCANx->CANAR.CANACR[2]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[2]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[3]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[3]=((MCAN_Mask>>16)| 0x0000000Fu); } else { MCAN_ID=(uint32_t)(MCAN_FilterStruct->MCAN_IDAR); MCAN_Mask=(uint32_t)(MCAN_FilterStruct->MCAN_IDMR); /* according to the accept rule */ MCANx->CANAR.CANACR[0]=(MCAN_ID>>24); MCANx->CANAR.CANAMR[0]=(MCAN_Mask>>24); MCANx->CANAR.CANACR[1]=(MCAN_ID>>16); MCANx->CANAR.CANAMR[1]=(MCAN_Mask>>16); MCANx->CANAR.CANACR[2]=(MCAN_ID>>8); MCANx->CANAR.CANAMR[2]=(MCAN_Mask>>8); MCANx->CANAR.CANACR[3]=(MCAN_ID); MCANx->CANAR.CANAMR[3]=(MCAN_Mask); } } /* clear reset mode if in this mode*/ MCANx->CANMOD &=~MCAN_CANMOD_RM_MASK; } /** * @brief ¼ÓÔØ´«Êäµ½TX»º³åÇøËùÐèµÄÊý¾Ý¡£ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param TxMessage: Ö¸ÏòÒ»¸ö°üº¬MCAN Id£¬MCAN DLCºÍMCANÊý¾ÝµÄ½á¹¹¡£ * @retval None. */ void MCAN_LoadTransmitData(MCAN_Type *MCANx, const MCAN_MsgTypeDef* TxMessage) { uint8_t i = 0; uint32_t datasize = 0; /* Set up the Tx frame information */ MCANx->CANTB[0]= (0x000000FFu&((TxMessage->MCAN_FF << 7) | (TxMessage->MCAN_RTR << 6) | (TxMessage->MCAN_FDBRS << 5)| \ (TxMessage->MCAN_FDESI << 4) | (TxMessage->MCAN_DLC))); /* get actually data size */ if((TxMessage->MCAN_DLC) < MCAN_DLC_DATASIZE12) { datasize=(TxMessage->MCAN_DLC); } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE12) { datasize=12; } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE16) { datasize=16; } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE20) { datasize=20; } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE24) { datasize=24; } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE32) { datasize=32; } else if ((TxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE48) { datasize=48; } else { datasize=64; } /* Set up the ID */ if (TxMessage->MCAN_FF == MCAN_Standard_Frame) { MCANx->CANTB[1]=(0xFFu&(TxMessage->MCAN_ID>>3)); MCANx->CANTB[2]=(0xF0u&((TxMessage->MCAN_ID<<5)|(TxMessage->MCAN_RTR<<4))); /* Set up the data field */ for (i=0;iCANTB[i+3u] = (uint32_t)TxMessage->MCAN_Data[i]; } } else { MCANx->CANTB[1]=(0xFFu&(TxMessage->MCAN_ID>>21)); MCANx->CANTB[2]=(0xFFu&(TxMessage->MCAN_ID>>13)); MCANx->CANTB[3]=(0xFFu&(TxMessage->MCAN_ID>>5)); MCANx->CANTB[4]=(0xFCu&((TxMessage->MCAN_ID<<3)|(TxMessage->MCAN_RTR<<2))); /* Set up the data field */ for (i=0;iCANTB[i+5u] = (uint32_t)TxMessage->MCAN_Data[i]; } } } /** * @brief ½ÓÊÕÊý¾Ý * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param RxMessage: Ö¸Ïò°üº¬MCAN Id, MCAN DLC, MCANÊý¾ÝµÄ½á¹¹½ÓÊÕÏûÏ¢µÄÖ¸Õë¡£ * @retval None. */ void MCAN_ReceiveData(MCAN_Type *MCANx, MCAN_MsgTypeDef* RxMessage) { uint8_t i=0; uint32_t temp=0; uint32_t datasize = 0; /* Get the FF */ RxMessage->MCAN_FF = ((0x80u & MCANx->CANRB[0]) >> 7); /* Get the RTR */ RxMessage->MCAN_RTR = (0x40u & MCANx->CANRB[0]); /* Get the BRS */ RxMessage->MCAN_FDBRS = (0x20u & MCANx->CANRB[0]); /* Get the ESI */ RxMessage->MCAN_FDESI = (0x10u & MCANx->CANRB[0]); /* Get the DLC */ RxMessage->MCAN_DLC = (0x0Fu & MCANx->CANRB[0]); /* get actually data size */ if((RxMessage->MCAN_DLC) < MCAN_DLC_DATASIZE12) { datasize=(RxMessage->MCAN_DLC); } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE12) { datasize=12; } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE16) { datasize=16; } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE20) { datasize=20; } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE24) { datasize=24; } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE32) { datasize=32; } else if ((RxMessage->MCAN_DLC) == MCAN_DLC_DATASIZE48) { datasize=48; } else { datasize=64; } /* Get the Id and data */ if (RxMessage->MCAN_FF == MCAN_Standard_Frame) { /* Get the Id */ temp = MCANx->CANRB[1]<<8; RxMessage->MCAN_ID = (0x7FFu & ((temp| MCANx->CANRB[2])>>5)); /* Get the data field */ for (i=0;iMCAN_Data[i] = (uint8_t)MCANx->CANRB[i+3u]; } } else { /* Get the Id */ temp = MCANx->CANRB[1]<<24; temp |= MCANx->CANRB[2]<<16; temp |= MCANx->CANRB[3]<<8; temp |= MCANx->CANRB[4]; temp >>=3; RxMessage->MCAN_ID = 0x1FFFFFFFu & temp; /* Get the data field */ for (i=0;iMCAN_Data[i] = (uint8_t)MCANx->CANRB[i+5u]; } } /* RX finished, return to Normal Operating Mode */ MCAN_SetCmd(MCANx,MCAN_ReleaseReceiveBuffer); //Aaron he add 20180328 } /** * @brief ÅäÖÃCAN¿ØÖÆÆ÷µÄģʽ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param MCAN_ModeType: ģʽѡÔñ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_NORMALMODE: ˯Ãßģʽ * @arg MCAN_RESETMODE: seltestģʽ * @arg MCAN_LISTENONLYMODE: listen nolyģʽ * @arg MCAN_SELFTESTMODE: ÖØÖÃģʽ * @arg MCAN_SLEEPMODE: Õý³£²Ù×÷ģʽ * @retval None. */ void MCAN_SetMode(MCAN_Type *MCANx, uint8_t MCAN_ModeType) { switch(MCAN_ModeType) { case MCAN_NORMALMODE: /* enable the normal mode */ /* clear reset mode if in this mode*/ MCANx->CANMOD &=~MCAN_CANMOD_RM_MASK; /* clear listen only mode if in this mode*/ MCANx->CANMOD &=~MCAN_CANMOD_LOM_MASK; /* clear self test mode if in this mode*/ MCANx->CANMOD &=~MCAN_CANMOD_STM_MASK; /* clear sleep mode if in this mode*/ MCANx->CANMOD &=~MCAN_CANMOD_SM_MASK; break; case MCAN_RESETMODE: /* set the reset mode*/ MCANx->CANMOD |= MCAN_CANMOD_RM_MASK; break; case MCAN_LISTENONLYMODE: /* set the listen only mode*/ MCANx->CANMOD |=MCAN_CANMOD_LOM_MASK; break; case MCAN_SELFTESTMODE: /* set the self test mode*/ MCANx->CANMOD |=MCAN_CANMOD_STM_MASK; break; case MCAN_SLEEPMODE: /* enable wakeup interrupt */ MCAN_InterruptEn(MCANx,MCAN_WakeUpInterruptEn,ENABLE); /* set the sleep mode */ MCANx->CANMOD |= MCAN_CANMOD_SM_MASK; break; default: /* error if do not set mode */ break; } } /** * @brief »½ÐÑMCAN. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval None. */ void MCAN_WakeUp(MCAN_Type *MCANx) { /* clear sleep mode */ MCANx->CANMOD &=~MCAN_CANMOD_SM_MASK; } /** * @brief ÉèÖÃÃüÁîλÒÔÆô¶¯MCAN¿ØÖÆÆ÷´«Êä²ãÄڵIJÙ×÷ * @param MCANx: Ñ¡ÔñCANÍâÉè * @param ÃüÁîÀàÐÍ£ºÖжÏÀàÐÍ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_TransmissionRequest: ·¢ËÍÇëÇó * @arg MCAN_AbortTransmission£º´«ÊäÖÐÖ¹ * @arg MCAN_ReleaseReceiveBuffer£º ÊͷŽÓÊÕ»º³å * @arg MCAN_ClearDataOverrun£º ÇåÁãÊý¾ÝÒç³ö * @arg MCAN_SelfReceptionRequest£º×Ô½ÓÊÕÇëÇó * @retval None */ void MCAN_SetCmd(MCAN_Type *MCANx, uint8_t MCAN_CommandType) { /* set the selected command */ MCANx->CANCMR |= MCAN_CommandType; } /** * @brief Çå³ý½ÓÊÕÖжÏ. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval None. */ void MCAN_ClearReceiveInterrupt(MCAN_Type *MCANx) { /* there is no further data to read in the Receive Buffer.*/ /* then realse the receive buffer meantime clear receive interrupt*/ MCAN_SetCmd(MCANx,MCAN_ReleaseReceiveBuffer); } /** * @brief »ñÈ¡MCANxÍâÉèÖ¸¶¨×´Ì¬ * @param MCANx: Ñ¡ÔñMCANÍâÉè * @param UART_StatusType: ״̬ÀàÐÍ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_ReceiveBufferStatus: ½ÓÊÕ»º³åÇø×´Ì¬ * @arg MCAN_DataOverrunStatus: Êý¾ÝÒç³ö״̬ * @arg MCAN_TransBufferStatus: ·¢ËÍ»º³åÇø×´Ì¬ * @arg MCAN_TransCompleteStatus: ´«ÊäÍê³É״̬ * @arg MCAN_ReceiveStatus: ½ÓÊÕ״̬ * @arg MCAN_TransmitStatus: ·¢ËÍ״̬ * @arg MCAN_ErrorStatus: ´íÎó״̬ * @arg MCAN_BusStatus: ×ÜÏß״̬ * @retval µ±Ç°×´Ì¬(TRUE or FALSE) */ FlagStatus MCAN_GetStatus(const MCAN_Type *MCANx, MCAN_StatusTypeDef MCAN_StatusType) { return (((MCANx->CANSR >> (uint8_t)MCAN_StatusType)&(uint32_t)0x01) != (uint32_t)0); } /** * @brief »ñÈ¡MCANxÖ¸¶¨ÖжÏԴ״̬ * @param MCANx: Ñ¡ÔñMCANÍâÉè * @param MCAN_InterruptFlgDef: ÖжÏÀàÐÍ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_ReceiveInterrupt: ½ÓÊÕÖÐ¶Ï * @arg MCAN_TransmitInterrupt: ·¢ËÍÖÐ¶Ï * @arg MCAN_ErrorWarningInterrupt: ´íÎ󾯸æÖÐ¶Ï * @arg MCAN_DataOverrunInterrupt: Êý¾ÝÒç³öÖÐ¶Ï * @arg MCAN_WakeUpInterrupt: »½ÐÑÖÐ¶Ï * @arg MCAN_ErrorPassiveInterrupt: ´íÎó±»¶¯ÖÐ¶Ï * @arg MCAN_ArbitrationLostInterrupt: ÖٲöªÊ§ÖÐ¶Ï * @arg MCAN_BusErrorInterrupt: ×ÜÏß´íÎóÖÐ¶Ï * @retval µ±Ç°×´Ì¬(TRUE or FALSE) */ ITStatus MCAN_GetInterruptFlg(const MCAN_Type *MCANx, MCAN_InterruptFlgDef MCAN_InterruptFlg) { return (((MCANx->CANIR >> (uint8_t)MCAN_InterruptFlg)&(uint32_t)0x01) != (uint32_t)0); } /** * @brief ʹÄÜMCANÖ¸¶¨ÖÐ¶Ï * @param MCANx: Ñ¡ÔñMCANÍâÉè * @param MCAN_InterruptFlgDef: ÖжÏÀàÐÍ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg MCAN_ReceiveInterruptEn: ½ÓÊÕÖÐ¶Ï * @arg MCAN_TransmitInterruptEn: ·¢ËÍÖÐ¶Ï * @arg MCAN_ErrorWarningInterruptEn: ´íÎ󾯸æÖÐ¶Ï * @arg MCAN_DataOverrunInterruptEn: Êý¾ÝÒç³öÖÐ¶Ï * @arg MCAN_WakeUpInterruptEn: »½ÐÑÖÐ¶Ï * @arg MCAN_ErrorPassiveInterruptEn: ´íÎó±»¶¯ÖÐ¶Ï * @arg MCAN_ArbitrationLostInterruptEn: ÖٲöªÊ§ÖÐ¶Ï * @arg MCAN_BusErrorInterruptEn: ×ÜÏß´íÎóÖÐ¶Ï * @param State: ÖжÏʹÄÜ״̬ * Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ: * @arg ENABLE: ÖжÏʹÄÜ * @arg DISABLE: ÖжÏʧÄÜ * @retval None */ void MCAN_InterruptEn(MCAN_Type *MCANx, MCAN_InterruptEnDef MCAN_Interrupt, FunctionalState NewState) { if (NewState != DISABLE) { /* Enable the selected MCAN interrupts */ MCANx->CANIER |= ((uint32_t)1<<(uint8_t)MCAN_Interrupt); } else { /* Disable the selected MCAN interrupts */ MCANx->CANIER &= ~((uint32_t)1<<(uint8_t)MCAN_Interrupt); } } /** * @brief ·µ»ØMCANxÖٲöªÊ§²¶»ñ(ALC). * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval Arbitration Lost position.·µ»ØÖٲöªÊ§Î»Öᣠ*/ uint8_t MCAN_ArbitrationLostCap(const MCAN_Type *MCANx) { /* Return the Arbitration Lost*/ return (uint8_t)MCANx->CANALC; } /** * @brief ·µ»ØÓйØ×ÜÏßÉÏ´íÎóÀàÐͺÍλÖõÄÐÅÏ¢¡£ * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param MCAN_BusErrorCapture: Ö¸Ïò°üº¬MCANÍâÉèÅäÖÃÐÅÏ¢µÄMCAN_BusErrorCaptureDef½á¹¹µÄÖ¸Õë¡£ * @retval None. */ uint8_t MCAN_GetBusErrorType(const MCAN_Type *MCANx, MCAN_BusErrorCaptureDef MCAN_BusErrorCapture) { uint8_t errorcap=0; /* Get the error position */ if(MCAN_BusErrorCapture==MCAN_BusErrorPosition) { errorcap = (uint8_t)(MCANx->CANECC & MCAN_CANECC_SEGMENT_MASK); } /* Get the error direction */ else if(MCAN_BusErrorCapture==MCAN_BusErrorDirection) { errorcap = (uint8_t)((MCANx->CANECC & MCAN_CANECC_DIR_MASK)>>5); } /* Get the error type */ else //(Can_BusErrorCapture==MCAN_BusErrorType) { errorcap = (uint8_t)((MCANx->CANECC & MCAN_CANECC_ERROR_MASK)>>6); } /* Return the Error Information on the bus*/ return errorcap; } /** * @brief ·µ»ØMCANx½ÓÊÕ´íÎó¼ÆÊýÆ÷ (RXERR). * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval Receive Error Counter.·µ»Ø½ÓÊÕµ½µÄ´íÎó¼ÆÊýÆ÷ ¡£ */ uint8_t MCAN_GetReceiveErrorCounter(const MCAN_Type *MCANx) { /* Return the Receive Error Counter*/ return (uint8_t)MCANx->CANRXERR; } /** * @brief ·µ»ØMCANx Tramsmit´íÎó¼ÆÊýÆ÷ (TXERR). * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval Transmit Error Counter.·µ»ØCANx Tramsmit´íÎó¼ÆÊýÆ÷ ¡£ */ uint8_t MCAN_GetTransmitErrorCounter(const MCAN_Type *MCANx) { /* Return the Transmit Error Counter*/ return (uint8_t)(MCANx->CANTXERR); } /** * @brief ·µ»ØMCANx½ÓÊÕÐÅÏ¢¼ÆÊýÆ÷(RMC). * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @retval Receive Message Counter.·µ»Ø½ÓÊÕÐÅÏ¢¼ÆÊýÆ÷¡£ */ uint8_t MCAN_GetReceiveMessageCounter(const MCAN_Type *MCANx) { /* Return the Receive Message Counter*/ return (uint8_t)(MCANx->CANRMC); } /** * @brief ÔÚÖØÖÃģʽ¸Ä±ä´íÎóÉèÖÃ. * @param MCANx: Ñ¡ÔñMCANÍâÉè. * @param MCAN_ErrorSetting: Ö¸Ïò°üº¬MCANÍâÉèÅäÖÃÐÅÏ¢µÄMCAN_ErrorSettingDef½á¹¹µÄÖ¸Õë¡£ * @retval None. */ void MCAN_ErrorSettingModify(MCAN_Type *MCANx, const MCAN_ErrorSettingDef *MCAN_ErrorSetting) { /* modify the error warning limit in Reset Mode */ MCANx->CANEWLR &= ~MCAN_CANEWLR_EWL_MASK; MCANx->CANEWLR |= (MCAN_ErrorSetting->MCAN_ErrorWarningLimit); /* modify the receive error in Reset Mode */ MCANx->CANRXERR &= ~MCAN_CANRXERR_RXERR_MASK; MCANx->CANRXERR |= (MCAN_ErrorSetting->MCAN_ReceiveErrorCount); /* modify the transimit error in Reset Mode */ MCANx->CANTXERR &= ~MCAN_CANTXERR_TXERR_MASK; MCANx->CANTXERR |= (MCAN_ErrorSetting->MCAN_TranmitErrorCount); } /** * @} */ /** * @} */ /** * @} */ #ifdef __cplusplus } #endif /* __cplusplus */