📄 stm8s_can.c
字号:
/**
* @brief Returns the number of pending messages.
* @retval Number of pending messages.
*/
CAN_NbrPendingMessage_TypeDef CAN_MessagePending(void)
{
CAN_NbrPendingMessage_TypeDef msgpending = CAN_NbrPendingMessage_0;
msgpending = (u8)(CAN->RFR & CAN_RFR_FMP01);
return (CAN_NbrPendingMessage_TypeDef)msgpending;
}
/**
* @brief Receives a message which contains CAN Id, IDE, RTR
* DLC, datas and FMI number.
* In order to get these data, use CAN_GetReceivedId(), CAN_GetReceivedIDE(), CAN_GetReceivedRTR(),
* CAN_GetReceivedDLC(), CAN_GetReceivedFMI() and CAN_GetReceivedData() functions.
* @par Parameters:
* None
* @retval None
*/
void CAN_Receive(void)
{
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* select Fifo page*/
CAN->PSR = CAN_Page_RxFifo;
/* Get the Id */
_IDE = (u8)(CAN->Page.RxFIFO.MIDR1 & CAN_Id_Extended);
if (_IDE != CAN_Id_Standard)
{
_Id = (u32)CAN_EXTID_SIZE & ((CAN->Page.RxFIFO.MIDR4) | ((u32)((u32)CAN->Page.RxFIFO.MIDR3) << 8) | ((u32)((u32)CAN->Page.RxFIFO.MIDR2) << 16) | ((u32)((u32)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 24) );
}
else
{
_Id = (u16)CAN_STDID_SIZE & ((u16)((u16)(CAN->Page.RxFIFO.MIDR1 & 0x1F) << 6) | ((CAN->Page.RxFIFO.MIDR2 >> 2)&0x3F) );
}
_RTR = (u8)(0x20 & CAN->Page.RxFIFO.MIDR1);
/* Get the DLC */
_DLC = (u8)(CAN->Page.RxFIFO.MDLCR & 0x0F);
/* Get the FMI */
_FMI = CAN->Page.RxFIFO.MFMI;
/* Get the data field */
_Data[0] = CAN->Page.RxFIFO.MDAR1;
_Data[1] = CAN->Page.RxFIFO.MDAR2;
_Data[2] = CAN->Page.RxFIFO.MDAR3;
_Data[3] = CAN->Page.RxFIFO.MDAR4;
_Data[4] = CAN->Page.RxFIFO.MDAR5;
_Data[5] = CAN->Page.RxFIFO.MDAR6;
_Data[6] = CAN->Page.RxFIFO.MDAR7;
_Data[7] = CAN->Page.RxFIFO.MDAR8;
/* Release the FIFO */
CAN_FIFORelease();
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/**
* @brief Gets the CAN Id of the received message.
* @par Parameters:
* None
* @retval the received CAN message Id.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
u32 CAN_GetReceivedId(void)
{
return (_Id);
}
/**
* @brief Gets the CAN IDE of the received message.
* @par Parameters:
* None
* @retval the received CAN message IDE.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
CAN_Id_TypeDef CAN_GetReceivedIDE(void)
{
return (_IDE);
}
/**
* @brief Gets the CAN RTR of the received message.
* @par Parameters:
* None
* @retval the received CAN message RTR.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
CAN_RTR_TypeDef CAN_GetReceivedRTR(void)
{
return (_RTR);
}
/**
* @brief Gets the CAN DLC of the received message.
* @par Parameters:
* None
* @retval the received CAN message DLC.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
u8 CAN_GetReceivedDLC(void)
{
return (_DLC);
}
/**
* @brief Gets the CAN Data of the received message.
* @param[in] CAN_DataIndexe : number of the received Data, it can
* be an integer between 0 to 7.
* @retval the received CAN message ith Data.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
u8 CAN_GetReceivedData(u8 CAN_DataIndex)
{
assert_param(IS_CAN_DLC_OK(CAN_DataIndex));
return (_Data[CAN_DataIndex]);
}
/**
* @brief Gets the CAN FMI of the received message.
* @par Parameters:
* None
* @retval the received CAN message FMI.
* @par Required preconditions:
* This function is used to get data loaded by CAN_Receive function.
* Before using this function, CAN_Receive function must be called.
*/
u8 CAN_GetReceivedFMI(void)
{
return (_FMI);
}
/**
* @brief Returns the Received time stamp.
* @par Parameters:
* None
* @retval u16 the received time stamp.
*/
u16 CAN_GetMessageTimeStamp(void)
{
u16 time;
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/*switch to the specific page */
CAN->PSR = CAN_Page_RxFifo;
/* Get the Received Time stamp */
time = CAN->Page.RxFIFO.MTSRL;
time |= (u16)(((u16)CAN->Page.RxFIFO.MTSRH)<<8);
/*Restore Last Page*/
CAN_SelectPage(can_page);
return (u16)(time);
}
/**
* @brief Enters the Sleep low power mode.
* @par Parameters:
* None
* @retval CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed in an other case.
*/
CAN_Sleep_TypeDef CAN_Sleep(void)
{
CAN_Sleep_TypeDef sleepstatus = CAN_Sleep_Failed;
/* Request Sleep mode */
CAN->MCR = (u8)(((CAN->MCR) & (u8)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
/* Sleep mode status */
if ((CAN->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
{
/* Sleep mode not entered */
sleepstatus = CAN_Sleep_Ok;
}
/* At this step, sleep mode status */
return (CAN_Sleep_TypeDef) sleepstatus;
}
/**
* @brief Wakes the CAN up.
* @par Parameters:
* None
* @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed in an other case.
*/
CAN_WakeUp_TypeDef CAN_WakeUp(void)
{
CAN_WakeUp_TypeDef wakeupstatus = CAN_WakeUp_Failed;
/* Wake up request */
CAN->MCR &= (u8)(~CAN_MCR_SLEEP);
/* Sleep mode status */
if ((CAN->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
{
/* Sleep mode exited */
wakeupstatus = CAN_WakeUp_Ok;
}
/* At this step, sleep mode status */
return (CAN_WakeUp_TypeDef)wakeupstatus;
}
/**
* @brief Select the CAN clock input.
* @param[in] CAN_ClockSource : CAN clock input, can be one of @ref CAN_ClockSource_TypeDef.
* @retval None
*/
void CAN_SelectClock(CAN_ClockSource_TypeDef CAN_ClockSource)
{
u16 timeout =0;
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
/* Check the parameters */
assert_param(IS_CAN_CLOCKSOURCE_OK(CAN_ClockSource));
/* Request initialisation */
CAN->MCR |= (CAN_MCR_INRQ & ((u8)(~CAN_MCR_SLEEP)));
CAN->PSR = CAN_Page_Config;
if (CAN_ClockSource != CAN_ClockSource_Internal)
{
CAN->Page.Config.BTR2 |= (u8)CAN_BTR2_CLKS;
}
else
{
CAN->Page.Config.BTR2 &= (u8)(~CAN_BTR2_CLKS);
}
/* Request leave initialisation */
CAN->MCR &= (u8)(~CAN_MCR_INRQ);
/* Wait the acknowledge */
while ((timeout != 0)&&((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK))
{
timeout--;
}
/*Restore Last Page*/
CAN_SelectPage(can_page);
}
/**
* @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 None
*/
CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
{
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.
*/
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 the folowing parameters:
* CAN_FLAG_RQCP0 Request MailBox0 Flag
* CAN_FLAG_RQCP1 Request MailBox1 Flag
* CAN_FLAG_RQCP2 Request MailBox2 Flag
* CAN_FLAG_FF FIFO Full Flag
* CAN_FLAG_FOV FIFO Overrun Flag
* CAN_FLAG_WKU wake up Flag
* CAN_FLAG_LEC Last error code Flag
* @retval None
*/
void CAN_ClearFlag(CAN_Flag_TypeDef CAN_Flag)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -