📄 stm8s_can.c
字号:
}
/**
* @brief Select the CAN Operation mode.
* @param[in] CAN_OperatingMode CAN Operating Mode , this parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
* @retval void None
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
{
u8 tmpreg =0;
u16 timeout = CAN_ACKNOWLEDGE_TIMEOUT;
assert_param(IS_CAN_OPERATINGMODE_OK(CAN_OperatingMode));
if(CAN_OperatingMode == CAN_OperatingMode_Initialization)
{
/* Request initialisation */
CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_SLEEP)) | CAN_MCR_INRQ);
/* Wait the acknowledge */
while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0))
{
timeout--;
}
if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK)
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
}
else
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
}
}
else if(CAN_OperatingMode == CAN_OperatingMode_Normal)
{
/* Request leave initialisation and sleep mode and enter Normal mode */
CAN->MCR &= (u8)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ));
/* Wait the acknowledge */
while (((CAN->MSR & CAN_MODE_MASK) != 0) && (timeout!=0))
{
timeout--;
}
if ((CAN->MSR & CAN_MODE_MASK) != 0)
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
}
else
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
}
}
else if(CAN_OperatingMode == CAN_OperatingMode_Sleep)
{
/* Request Sleep mode */
CAN->MCR = (u8)((CAN->MCR & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
/* Wait the acknowledge */
while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0))
{
timeout--;
}
if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK)
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
}
else
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Success);
}
}
else
{
return (CAN_ModeStatus_TypeDef)(CAN_ModeStatus_Failed);
}
}
/**
* @brief Gets the Last Error Code.
* @par Parameters:
* None
* @retval Error Code.
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(void)
{
CAN_ErrorCode_TypeDef errcode = CAN_ErrorCode_NoErr;
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
CAN->PSR = CAN_Page_Config;
errcode = (u8)((CAN->Page.Config.ESR) & (CAN_ESR_LEC));
/*Restore Last Page*/
CAN_SelectPage(can_page);
return (CAN_ErrorCode_TypeDef)(errcode);
}
/**
* @brief Clears the CAN's pending flags.
* @param[in] CAN_FLAG : Flag to be cleared, can be one of @ref CAN_Flag_TypeDef.
* check that the correspondant Flag can be cleared (read IS_CAN_FLAG_CLEAR_OK assert
* possibilities.
* @retval void None
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
void CAN_ClearFlag(CAN_Flag_TypeDef CAN_Flag)
{
CAN_Page_TypeDef can_page = 0;
/* Check the parameters */
assert_param(IS_CAN_FLAG_CLEAR_OK(CAN_Flag));
if((CAN_Flag & 0x0700)!=(u16)RESET)
{
if((CAN_Flag & 0x020B)!=(u16)RESET)
{
/*Receive Flags*/
CAN->RFR = (u8)(CAN_Flag);
}
else if((CAN_Flag & 0x0403)!=(u16)RESET)
{
/*Transmit Flags*/
CAN->TSR = (u8)(CAN_Flag);
}
else /*if((CAN_Flag & 0x0108)!=(u16)RESET)*/
{
/*wake up Flags*/
CAN->MSR = (u8)(CAN_Flag);
}
}
else
{
/*Error Flags*/
can_page = CAN_GetSelectedPage();
/* Clear the selected CAN flags */
CAN->PSR = CAN_Page_Config;
CAN->Page.Config.ESR = (u8)RESET;
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
}
/**
* @brief Checks whether the specified CAN flag is set or not.
* @param[in] CAN_FLAG: specifies the flag to check, can be one of @ref CAN_Flag_TypeDef enumeration.
* @retval The new state of CAN_FLAG which can be one of @ref FlagStatus.
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
FlagStatus CAN_GetFlagStatus(CAN_Flag_TypeDef CAN_Flag)
{
FlagStatus bitstatus = RESET;
CAN_Page_TypeDef can_page = 0;
/* Check the parameters */
assert_param(IS_CAN_FLAG_STATUS_OK(CAN_Flag));
if((CAN_Flag & 0x0700)!=(u16)RESET)
{
if((CAN_Flag & 0x020B)!=(u16)RESET)
{
/*Receive Flags*/
if((CAN->RFR & CAN_Flag )!= (u16)RESET)
{
/* CAN_FLAG is set */
bitstatus = SET;
}
else
{
/* CAN_FLAG is reset */
bitstatus = RESET;
}
}
else if((CAN_Flag & 0x0403)!=(u16)RESET)
{
/*Transmit Flags*/
if((CAN->TSR & CAN_Flag )!= (u16)RESET)
{
/* CAN_FLAG is set */
bitstatus = SET;
}
else
{
/* CAN_FLAG is reset */
bitstatus = RESET;
}
}
else /*if((CAN_Flag & 0x0108)!=(u16)RESET)*/
{
/*wake up Flags*/
if((CAN->MSR & CAN_Flag )!= (u16)RESET)
{
/* CAN_FLAG is set */
bitstatus = SET;
}
else
{
/* CAN_FLAG is reset */
bitstatus = RESET;
}
}
}
else
{
/*Error Flags*/
can_page = CAN_GetSelectedPage();
CAN->PSR = CAN_Page_Config;
if ((CAN->Page.Config.ESR & CAN_Flag) != (u32)RESET)
{
/* CAN_FLAG is set */
bitstatus = SET;
}
else
{
/* CAN_FLAG is reset */
bitstatus = RESET;
}
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/* Return the CAN_FLAG status */
return (FlagStatus)bitstatus;
}
/**
* @brief Checks whether the specified CAN interrupt has occurred or not.
* @param[in] CAN_IT: specifies the CAN interrupt source to check, can be one of @ref CAN_IT_TypeDef.
* @retval The new state of CAN_IT, which can be one of @ref ITStatus.
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
ITStatus CAN_GetITStatus(CAN_IT_TypeDef CAN_IT)
{
ITStatus pendingbitstatus = RESET;
u8 itreg1;
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* Check the parameters */
assert_param(IS_CAN_IT_STATUS_OK(CAN_IT));
switch (CAN_IT)
{
case CAN_IT_TME:
if((CAN->IER & CAN_IER_TMEIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP012);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_FMP:
if((CAN->IER & CAN_IER_FMPIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FMP01);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_FF:
if((CAN->IER & CAN_IER_FFIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FULL);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_FOV:
if((CAN->IER & CAN_IER_FOVIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FOVR);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_WKU:
if((CAN->IER & CAN_IER_WKUIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->MSR, CAN_MSR_WKUI);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_ERR:
CAN->PSR = CAN_Page_Config;
if((CAN->Page.Config.EIER & CAN_EIER_ERRIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF|CAN_ESR_EPVF|CAN_ESR_BOFF|CAN_ESR_LEC);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_EWG:
CAN->PSR = CAN_Page_Config;
if((CAN->Page.Config.EIER & CAN_EIER_EWGIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_EPV:
CAN->PSR = CAN_Page_Config;
if((CAN->Page.Config.EIER & CAN_EIER_EPVIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EPVF);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_BOF:
CAN->PSR = CAN_Page_Config;
if((CAN->Page.Config.EIER & CAN_EIER_BOFIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_BOFF);
}
else
{
pendingbitstatus = RESET;
}
break;
case CAN_IT_LEC:
CAN->PSR = CAN_Page_Config;
if((CAN->Page.Config.EIER & CAN_EIER_LECIE) !=RESET)
{
pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_LEC);
}
else
{
pendingbitstatus = RESET;
}
break;
default :
pendingbitstatus = RESET;
break;
}
/*Restore Last Page*/
CAN_SelectPage(can_page);
/* Return the CAN_IT status */
return (ITStatus)pendingbitstatus;
}
/**
* @brief Clears the CAN抯 interrupt pending bits.
* @param[in] CAN_IT: specifies the interrupt pending bit to clear, can be one of @ref CAN_IT_TypeDef.
* @retval void None
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
void CAN_ClearITPendingBit(CAN_IT_TypeDef CAN_IT)
{
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* Check the parameters */
assert_param(IS_CAN_IT_PENDING_BIT_OK(CAN_IT));
switch (CAN_IT)
{
case CAN_IT_TME:
CAN->TSR = CAN_TSR_RQCP012;/* rc_w1*/
break;
case CAN_IT_FF:
CAN->RFR = CAN_RFR_FULL; /* rc_w1*/
break;
case CAN_IT_FOV:
CAN->RFR = CAN_RFR_FOVR; /* rc_w1*/
break;
case CAN_IT_WKU:
CAN->MSR = CAN_MSR_WKUI; /* rc_w1*/
break;
case CAN_IT_ERR:
CAN->PSR = CAN_Page_Config;
CAN->Page.Config.ESR = (u8)CAN_ESR_RESET_VALUE;
CAN->MSR = CAN_MSR_ERRI;
break;
case CAN_IT_EWG:
CAN->MSR = CAN_MSR_ERRI;
break;
case CAN_IT_EPV:
CAN->MSR = CAN_MSR_ERRI;
break;
case CAN_IT_BOF:
CAN->MSR = CAN_MSR_ERRI;
break;
case CAN_IT_LEC:
CAN->PSR = CAN_Page_Config;
CAN->Page.Config.ESR = (u8)CAN_ESR_RESET_VALUE;
break;
default :
break;
}
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/**
* @brief Gets the selected registers page.
* @par Parameters:
* None
* @retval the selected page which can be one of the @ref CAN_Page_TypeDef.
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
CAN_Page_TypeDef CAN_GetSelectedPage(void)
{
return (CAN_Page_TypeDef)(CAN->PSR);
}
/**
* @brief Sets the registers page to be selected.
* @param[in] the selected page which can be one of the @ref CAN_Page_TypeDef.
* @retval void None
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
void CAN_SelectPage(CAN_Page_TypeDef CAN_Page)
{
CAN->PSR = CAN_Page;
}
/**
* @brief Checks whether the CAN interrupt has occurred or not.
* @param[in] CAN_Reg: specifies the CAN interrupt register to check.
* @param[in] It_Bit: specifies the interrupt source bit to check.
* @retval The new state of the CAN Interrupt, which can be one of ITStatus.
* @par Required preconditions:
* None
* @par Called functions:
* None
*/
static ITStatus CheckITStatus(u8 CAN_Reg, u8 It_Bit)
{
ITStatus pendingbitstatus = RESET;
if ((CAN_Reg & It_Bit) != (u8)RESET)
{
/* CAN_IT is set */
pendingbitstatus = SET;
}
else
{
/* CAN_IT is reset */
pendingbitstatus = RESET;
}
return (ITStatus)pendingbitstatus;
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -