|
|
/**
|
|
|
******************************************************************************
|
|
|
* @file stm8s_can.c
|
|
|
* @author MCD Application Team
|
|
|
* @version V2.2.0
|
|
|
* @date 30-September-2014
|
|
|
* @brief This file contains all the functions for the CAN peripheral.
|
|
|
******************************************************************************
|
|
|
* @attention
|
|
|
*
|
|
|
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
|
|
*
|
|
|
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
|
|
|
* You may not use this file except in compliance with the License.
|
|
|
* You may obtain a copy of the License at:
|
|
|
*
|
|
|
* http://www.st.com/software_license_agreement_liberty_v2
|
|
|
*
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
*
|
|
|
******************************************************************************
|
|
|
*/
|
|
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
#include "stm8s_can.h"
|
|
|
|
|
|
/** @addtogroup STM8S_StdPeriph_Driver
|
|
|
* @{
|
|
|
*/
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
#define CAN_IDLIST_IDMASK_MASK ((uint8_t) 0x55)
|
|
|
#define CAN_IDMASK_IDLIST_MASK ((uint8_t) 0xAA)
|
|
|
#define CAN_MODE_MASK ((uint8_t) 0x03)
|
|
|
#define CAN_ACKNOWLEDGE_TIMEOUT ((uint16_t)0xFFFF)
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
__IO uint32_t _Id = 0;
|
|
|
__IO uint8_t _IDE = 0;
|
|
|
__IO uint8_t _RTR = 0;
|
|
|
__IO uint8_t _DLC = 0;
|
|
|
__IO uint8_t _Data[8] = {0};
|
|
|
__IO uint8_t _FMI = 0;
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
static ITStatus CheckITStatus(uint8_t CAN_Reg, uint8_t It_Bit);
|
|
|
|
|
|
/* Private functions ---------------------------------------------------------*/
|
|
|
/**
|
|
|
* @addtogroup CAN_Public_Functions
|
|
|
* @{
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
* @brief Deinitializes the CAN peripheral registers to their default reset values.
|
|
|
* @param None
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_DeInit(void)
|
|
|
{
|
|
|
/* Request initialisation */
|
|
|
CAN->MCR = CAN_MCR_INRQ;
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
|
|
|
CAN->Page.Config.ESR = CAN_ESR_RESET_VALUE;
|
|
|
CAN->Page.Config.EIER = CAN_EIER_RESET_VALUE;
|
|
|
CAN->Page.Config.BTR1 = CAN_BTR1_RESET_VALUE;
|
|
|
CAN->Page.Config.BTR2 = CAN_BTR2_RESET_VALUE;
|
|
|
CAN->Page.Config.FMR1 = CAN_FMR1_RESET_VALUE;
|
|
|
CAN->Page.Config.FMR2 = CAN_FMR2_RESET_VALUE;
|
|
|
CAN->Page.Config.FCR1 = CAN_FCR_RESET_VALUE;
|
|
|
CAN->Page.Config.FCR2 = CAN_FCR_RESET_VALUE;
|
|
|
CAN->Page.Config.FCR3 = CAN_FCR_RESET_VALUE;
|
|
|
CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
|
|
|
CAN->PSR = CAN_Page_RxFifo;
|
|
|
CAN->Page.RxFIFO.MDLCR = CAN_MDLC_RESET_VALUE;
|
|
|
CAN->PSR = CAN_Page_TxMailBox0;
|
|
|
CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
|
|
|
CAN->PSR = CAN_Page_TxMailBox1;
|
|
|
CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
|
|
|
CAN->PSR = CAN_Page_TxMailBox2;
|
|
|
CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
|
|
|
|
|
|
CAN->MCR = CAN_MCR_RESET_VALUE;
|
|
|
CAN->MSR = (uint8_t)(~CAN_MSR_RESET_VALUE);/* rc_w1 */
|
|
|
CAN->TSR = (uint8_t)(~CAN_TSR_RESET_VALUE);/* rc_w1 */
|
|
|
CAN->RFR = (uint8_t)(~CAN_RFR_RESET_VALUE);/* rc_w1 */
|
|
|
CAN->IER = CAN_IER_RESET_VALUE;
|
|
|
CAN->DGR = CAN_DGR_RESET_VALUE;
|
|
|
CAN->PSR = CAN_PSR_RESET_VALUE;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Initializes the CAN peripheral according to the specified parameters.
|
|
|
* @param CAN_MasterCtrl : Master control option, can be one or a combination of @ref CAN_MasterCtrl_TypeDef.
|
|
|
* @param CAN_Mode : CAN mode , can be one of @ref CAN_Mode_TypeDef.
|
|
|
* @param CAN_SynJumpWidth : CAN Synchronisation Jump Width , can be one of @ref CAN_SynJumpWidth_TypeDef.
|
|
|
* @param CAN_BitSeg1 : CAN bit segment 1 , can be one of @ref CAN_BitSeg1_TypeDef.
|
|
|
* @param CAN_BitSeg2 : CAN bit segment 2 , can be one of @ref CAN_BitSeg2_TypeDef.
|
|
|
* @param CAN_Prescaler : CAN Baud Rate Prescaler , can be a value from 0x01 to 0xFF.
|
|
|
* @retval Indicates if initialization is succeed. it can be one of @ref CAN_InitStatus_TypeDef enumeration.
|
|
|
*/
|
|
|
CAN_InitStatus_TypeDef CAN_Init(CAN_MasterCtrl_TypeDef CAN_MasterCtrl,
|
|
|
CAN_Mode_TypeDef CAN_Mode,
|
|
|
CAN_SynJumpWidth_TypeDef CAN_SynJumpWidth,
|
|
|
CAN_BitSeg1_TypeDef CAN_BitSeg1,
|
|
|
CAN_BitSeg2_TypeDef CAN_BitSeg2,
|
|
|
uint8_t CAN_Prescaler)
|
|
|
{
|
|
|
CAN_InitStatus_TypeDef InitStatus = CAN_InitStatus_Failed;
|
|
|
uint16_t timeout = CAN_ACKNOWLEDGE_TIMEOUT;
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_MASTERCTRL_OK(CAN_MasterCtrl));
|
|
|
assert_param(IS_CAN_MODE_OK(CAN_Mode));
|
|
|
assert_param(IS_CAN_SYNJUMPWIDTH_OK(CAN_SynJumpWidth));
|
|
|
assert_param(IS_CAN_BITSEG1_OK(CAN_BitSeg1));
|
|
|
assert_param(IS_CAN_BITSEG2_OK(CAN_BitSeg2));
|
|
|
assert_param(IS_CAN_PRESCALER_OK(CAN_Prescaler));
|
|
|
|
|
|
/* Request initialisation */
|
|
|
CAN->MCR = CAN_MCR_INRQ;
|
|
|
/* Wait the acknowledge */
|
|
|
while (((uint8_t)(CAN->MSR & CAN_MSR_INAK) != 0x01) && ((uint16_t)timeout != 0))
|
|
|
{
|
|
|
timeout--;
|
|
|
}
|
|
|
|
|
|
/* Check acknowledged */
|
|
|
if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
|
|
|
{
|
|
|
|
|
|
InitStatus = CAN_InitStatus_Failed;
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Set the time triggered communication mode & Set the automatic bus-off management & Set the automatic wake-up mode
|
|
|
& Set the no automatic retransmission & Set the receive FIFO locked mode & Set the transmit FIFO priority */
|
|
|
CAN->MCR |= (uint8_t)CAN_MasterCtrl;
|
|
|
|
|
|
/* Set the bit timing register */
|
|
|
CAN->DGR |= (uint8_t)CAN_Mode ;
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
CAN->Page.Config.BTR1 = (uint8_t)((uint8_t)(CAN_Prescaler - (uint8_t)1) | CAN_SynJumpWidth);
|
|
|
CAN->Page.Config.BTR2 = (uint8_t)(CAN_BitSeg1 | (uint8_t)CAN_BitSeg2);
|
|
|
|
|
|
/* Request leave initialisation */
|
|
|
CAN->MCR &= (uint8_t)(~CAN_MCR_INRQ);
|
|
|
/* Wait the acknowledge */
|
|
|
timeout = 0xFFFF;
|
|
|
while ((((uint8_t)(CAN->MSR & CAN_MSR_INAK) == 0x01))&&(timeout != 0))
|
|
|
{
|
|
|
timeout--;
|
|
|
}
|
|
|
/* Check acknowledged */
|
|
|
if ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
|
|
|
{
|
|
|
InitStatus = CAN_InitStatus_Failed;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
InitStatus = CAN_InitStatus_Success;
|
|
|
}
|
|
|
}
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
|
|
|
/* Return the status of initialization */
|
|
|
return (CAN_InitStatus_TypeDef)InitStatus;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Initializes the CAN peripheral Filter according to the specified parameters.
|
|
|
* @param CAN_FilterNumber : CAN Filter number , can be one of @ref CAN_FilterNumber_TypeDef
|
|
|
* @param CAN_FilterActivation : CAN Filter Activation state , can be one of @ref FunctionalState
|
|
|
* @param CAN_FilterMode : CAN Filter Mode , can be one of @ref CAN_FilterMode_TypeDef
|
|
|
* @param CAN_FilterScale : CAN Filter Scale , can be one of @ref CAN_FilterScale_TypeDef
|
|
|
* @param CAN_FilterID1 : CAN Filter ID 1 , can be a value from 0x00 to 0xFF
|
|
|
* @param CAN_FilterID2 : CAN Filter ID 2 , can be a value from 0x00 to 0xFF
|
|
|
* @param CAN_FilterID3 : CAN Filter ID 3 , can be a value from 0x00 to 0xFF
|
|
|
* @param CAN_FilterID4 : CAN Filter ID 4 , can be a value from 0x00 to 0xFF
|
|
|
* @param CAN_FilterIDMask1 : CAN Filter ID 1/ Mask 1 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
|
|
|
* @param CAN_FilterIDMask2 : CAN Filter ID 2/ Mask 2 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
|
|
|
* @param CAN_FilterIDMask3 : CAN Filter ID 3/ Mask 3 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
|
|
|
* @param CAN_FilterIDMask4 : CAN Filter ID 4/ Mask 4 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_FilterInit(CAN_FilterNumber_TypeDef CAN_FilterNumber,
|
|
|
FunctionalState CAN_FilterActivation,
|
|
|
CAN_FilterMode_TypeDef CAN_FilterMode,
|
|
|
CAN_FilterScale_TypeDef CAN_FilterScale,
|
|
|
uint8_t CAN_FilterID1,
|
|
|
uint8_t CAN_FilterID2,
|
|
|
uint8_t CAN_FilterID3,
|
|
|
uint8_t CAN_FilterID4,
|
|
|
uint8_t CAN_FilterIDMask1,
|
|
|
uint8_t CAN_FilterIDMask2,
|
|
|
uint8_t CAN_FilterIDMask3,
|
|
|
uint8_t CAN_FilterIDMask4)
|
|
|
{
|
|
|
uint8_t fact = 0;
|
|
|
uint8_t fsc = 0;
|
|
|
uint8_t fmhl = 0;
|
|
|
|
|
|
CAN_Page_TypeDef can_page_filter = CAN_Page_Filter01;
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_FILTER_NUMBER_OK(CAN_FilterNumber));
|
|
|
assert_param(IS_FUNCTIONALSTATE_OK(CAN_FilterActivation));
|
|
|
assert_param(IS_CAN_FILTER_MODE_OK(CAN_FilterMode));
|
|
|
assert_param(IS_CAN_FILTER_SCALE_OK(CAN_FilterScale));
|
|
|
|
|
|
|
|
|
if (CAN_FilterNumber == CAN_FilterNumber_0)
|
|
|
{
|
|
|
fact = 0x01;
|
|
|
fsc = 0x00;
|
|
|
fmhl = 0x03;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter01;
|
|
|
}
|
|
|
else if (CAN_FilterNumber == CAN_FilterNumber_1)
|
|
|
{
|
|
|
fact = 0x10;
|
|
|
fsc = 0x04;
|
|
|
fmhl = 0x0C;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter01;
|
|
|
}
|
|
|
else if (CAN_FilterNumber == CAN_FilterNumber_2)
|
|
|
{
|
|
|
fact = 0x01;
|
|
|
fsc = 0x00;
|
|
|
fmhl = 0x30;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter23;
|
|
|
}
|
|
|
else if (CAN_FilterNumber == CAN_FilterNumber_3)
|
|
|
{
|
|
|
fact = 0x10;
|
|
|
fsc = 0x04;
|
|
|
fmhl = 0xC0;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter23;
|
|
|
}
|
|
|
else if (CAN_FilterNumber == CAN_FilterNumber_4)
|
|
|
{
|
|
|
fact = 0x01;
|
|
|
fsc = 0x00;
|
|
|
fmhl = 0x03;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter45;
|
|
|
}
|
|
|
else /*if (CAN_FilterNumber == CAN_FilterNumber_5)*/
|
|
|
{
|
|
|
fact = 0x10;
|
|
|
fsc = 0x04;
|
|
|
fmhl = 0x0C;
|
|
|
|
|
|
can_page_filter = CAN_Page_Filter45;
|
|
|
}
|
|
|
|
|
|
|
|
|
CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
|
|
|
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
/*---------------------------------------------------------*/
|
|
|
/*Configuration of Filter Scale */
|
|
|
/*---------------------------------------------------------*/
|
|
|
|
|
|
if (can_page_filter == CAN_Page_Filter01) /* FCR1 */
|
|
|
{
|
|
|
/* Filter Deactivation & Reset the Filter Scale */
|
|
|
CAN->Page.Config.FCR1 &= (uint8_t)(~(uint8_t)(fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc )));
|
|
|
/* Set the new Filter Scale */
|
|
|
CAN->Page.Config.FCR1 |= (uint8_t)(CAN_FilterScale << fsc);
|
|
|
}
|
|
|
else if (can_page_filter == CAN_Page_Filter23) /* FCR2*/
|
|
|
{
|
|
|
/* Filter Deactivation & Reset the Filter Scale */
|
|
|
CAN->Page.Config.FCR2 &= (uint8_t)~(uint8_t)( fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
|
|
|
|
|
|
/* Set the new Filter Scale */
|
|
|
CAN->Page.Config.FCR2 |= (uint8_t)(CAN_FilterScale << fsc);
|
|
|
|
|
|
}
|
|
|
else /*if(can_page_filter == CAN_Page_Filter45)*/ /* FCR3*/
|
|
|
{
|
|
|
/* Filter Deactivation & Reset the Filter Scale */
|
|
|
CAN->Page.Config.FCR3 &= (uint8_t)~(uint8_t)( fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
|
|
|
|
|
|
/* Set the new Filter Scale */
|
|
|
CAN->Page.Config.FCR3 |= (uint8_t)(CAN_FilterScale << fsc);
|
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------*/
|
|
|
/*Configuration of Filter Mode */
|
|
|
/*---------------------------------------------------------*/
|
|
|
if (can_page_filter != CAN_Page_Filter45) /* FMR1*/
|
|
|
{
|
|
|
/* Filter Mode */
|
|
|
if (CAN_FilterMode == CAN_FilterMode_IdMask)
|
|
|
{
|
|
|
/*Id/Mask mode for the filter*/
|
|
|
CAN->Page.Config.FMR1 &= (uint8_t)~(fmhl);
|
|
|
}
|
|
|
else if ( CAN_FilterMode == CAN_FilterMode_IdList)
|
|
|
{
|
|
|
/*Identifier list mode for the filter*/
|
|
|
CAN->Page.Config.FMR1 |= (uint8_t)(fmhl);
|
|
|
}
|
|
|
else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
|
|
|
{
|
|
|
/*Identifier list mode is first for the filter*/
|
|
|
CAN->Page.Config.FMR1 |= (uint8_t)(fmhl & CAN_IDLIST_IDMASK_MASK);
|
|
|
}
|
|
|
else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
|
|
|
{
|
|
|
/*Id Mask mode is first for the filter*/
|
|
|
CAN->Page.Config.FMR1 |= (uint8_t)(fmhl & CAN_IDMASK_IDLIST_MASK);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
else /* FMR2 */
|
|
|
{
|
|
|
|
|
|
/* Filter Mode */
|
|
|
if (CAN_FilterMode == CAN_FilterMode_IdMask)
|
|
|
{
|
|
|
/*Id/Mask mode for the filter*/
|
|
|
CAN->Page.Config.FMR2 &= (uint8_t)~(fmhl);
|
|
|
}
|
|
|
else if ( CAN_FilterMode == CAN_FilterMode_IdList)
|
|
|
{
|
|
|
/*Identifier list mode for the filter*/
|
|
|
CAN->Page.Config.FMR2 |= (uint8_t)(fmhl);
|
|
|
}
|
|
|
else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
|
|
|
{
|
|
|
/*Identifier list mode is first for the filter*/
|
|
|
CAN->Page.Config.FMR2 |= (uint8_t)(fmhl & CAN_IDLIST_IDMASK_MASK);
|
|
|
}
|
|
|
else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
|
|
|
{
|
|
|
/*Id Mask mode is first for the filter*/
|
|
|
CAN->Page.Config.FMR2 |= (uint8_t)(fmhl & CAN_IDMASK_IDLIST_MASK);
|
|
|
}
|
|
|
}
|
|
|
/*---------------------------------------------------------*/
|
|
|
/*Configuration of Filter IDs */
|
|
|
/*---------------------------------------------------------*/
|
|
|
CAN->PSR = (uint8_t)can_page_filter;
|
|
|
if (fsc != 0)
|
|
|
{
|
|
|
/* Filter Scale */
|
|
|
if (CAN_FilterScale == CAN_FilterScale_8Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR09 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR10 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR11 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR13 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR15 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR09 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR10 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR13 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR15 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_16Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR09 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR10 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR13 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR14 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_32Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR09 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR10 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR11 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR12 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR13 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR14 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Filter Scale */
|
|
|
if (CAN_FilterScale == CAN_FilterScale_8Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR01 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR02 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR03 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR05 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR07 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR01 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR02 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR05 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR07 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_16Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR01 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR02 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR05 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR06 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
else if (CAN_FilterScale == CAN_FilterScale_32Bit)
|
|
|
{
|
|
|
CAN->Page.Filter.FR01 = CAN_FilterID1;
|
|
|
CAN->Page.Filter.FR02 = CAN_FilterID2;
|
|
|
CAN->Page.Filter.FR03 = CAN_FilterID3;
|
|
|
CAN->Page.Filter.FR04 = CAN_FilterID4;
|
|
|
CAN->Page.Filter.FR05 = CAN_FilterIDMask1;
|
|
|
CAN->Page.Filter.FR06 = CAN_FilterIDMask2;
|
|
|
CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
|
|
|
CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/*---------------------------------------------------------*/
|
|
|
/*Configuration of Filter Activation */
|
|
|
/*---------------------------------------------------------*/
|
|
|
/* Filter activation */
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
if (CAN_FilterActivation != DISABLE)
|
|
|
{
|
|
|
if ((CAN_FilterNumber & 0x06) == 0x00) /* FCR1*/
|
|
|
{ CAN->Page.Config.FCR1 |= (uint8_t)fact;
|
|
|
}
|
|
|
else if ((CAN_FilterNumber & 0x06) == 0x02) /*FCR2*/
|
|
|
{ CAN->Page.Config.FCR2 |= (uint8_t)fact;
|
|
|
}
|
|
|
else /*if((CAN_FilterNumber & 0x06) == 0x04)*/ /*FCR3*/
|
|
|
{ CAN->Page.Config.FCR3 |= (uint8_t)fact;
|
|
|
}
|
|
|
}
|
|
|
CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Enables or disables the specified CAN interrupts.
|
|
|
* @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
|
|
|
* @param NewState : CAN_IT new state , can be one of @ref FunctionalState
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_ITConfig(CAN_IT_TypeDef CAN_IT, FunctionalState NewState)
|
|
|
{
|
|
|
uint8_t tmperrorinterrupt = 0;
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_IT_CONFIG_OK(CAN_IT));
|
|
|
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
|
|
|
|
|
tmperrorinterrupt = (uint8_t)(((uint16_t)CAN_IT) >>7);
|
|
|
tmperrorinterrupt = (uint8_t)((uint8_t)((uint16_t)tmperrorinterrupt & 0xF0) |
|
|
|
(uint8_t)((uint8_t)((uint16_t)tmperrorinterrupt & 0x0F) >>1));
|
|
|
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
if (NewState != DISABLE)
|
|
|
{
|
|
|
/* Enable the selected CAN interrupt */
|
|
|
CAN->IER |= (uint8_t)(CAN_IT);
|
|
|
CAN->Page.Config.EIER |= (uint8_t)(tmperrorinterrupt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Disable the selected CAN interrupt */
|
|
|
CAN->IER &= (uint8_t)~(uint8_t)((uint16_t)CAN_IT);
|
|
|
CAN->Page.Config.EIER &= (uint8_t)~(tmperrorinterrupt);
|
|
|
}
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Enables or Disables the ST7 CAN Compatibility.
|
|
|
* if the ST7 compatibility is Enabled, CAN provides only 2 mailboxes.
|
|
|
* if the ST7 compatibility is Disabled, CAN provides 3 mailboxes.
|
|
|
* @param CAN_ST7Compatibility : CAN ST7 Compatibility , this parameter can be one of @ref CAN_ST7Compatibility_TypeDef enumeration.
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_ST7CompatibilityCmd(CAN_ST7Compatibility_TypeDef CAN_ST7Compatibility)
|
|
|
{
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_ST7_COMPATIBILITY_OK(CAN_ST7Compatibility));
|
|
|
/*Reset the old configuration of TXM2E */
|
|
|
CAN->DGR &= (uint8_t)(~CAN_DGR_TXM2E);
|
|
|
|
|
|
/*Set the old configuration of TXM2E */
|
|
|
CAN->DGR |= (uint8_t)CAN_ST7Compatibility;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Enables or disables the CAN Time TriggerOperation communication mode.
|
|
|
* @param NewState : Mode new state , can be one of @ref FunctionalState
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_TTComModeCmd(FunctionalState NewState)
|
|
|
{
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_FUNCTIONALSTATE_OK(NewState));
|
|
|
if (NewState != DISABLE)
|
|
|
{
|
|
|
/*Enable the TTCM mode */
|
|
|
CAN->MCR |= CAN_MCR_TTCM;
|
|
|
/*Set TGT bits setting in Tx and FIFO pages*/
|
|
|
CAN->PSR = CAN_Page_TxMailBox0;
|
|
|
CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
|
|
|
CAN->PSR = CAN_Page_TxMailBox1;
|
|
|
CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
|
|
|
CAN->PSR = CAN_Page_TxMailBox2;
|
|
|
CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
|
|
|
CAN->PSR = CAN_Page_RxFifo;
|
|
|
CAN->Page.RxFIFO.MDLCR |= CAN_MDLCR_TGT;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/*Disable the TTCM mode */
|
|
|
CAN->MCR &= ((uint8_t)~CAN_MCR_TTCM);
|
|
|
/*Reset TGT bits setting in Tx and FIFO pages*/
|
|
|
CAN->PSR = CAN_Page_TxMailBox0;
|
|
|
CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
|
|
|
CAN->PSR = CAN_Page_TxMailBox1;
|
|
|
CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
|
|
|
CAN->PSR = CAN_Page_TxMailBox2;
|
|
|
CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
|
|
|
CAN->PSR = CAN_Page_RxFifo;
|
|
|
CAN->Page.RxFIFO.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
|
|
|
}
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Initiates the transmission of a message.
|
|
|
* @param CAN_Id the ID number of the message, its size depends on @ref CAN_IDE value.
|
|
|
* @param[in] CAN_IDE the ID type of the message, this parameter can be one of the @ref CAN_Id_TypeDef enumeration.
|
|
|
* @param[in] CAN_RTR the message type, this parameter can be one of the @ref CAN_RTR_TypeDef enumeration.
|
|
|
* @param[in] CAN_DLC the number of data in the message type, this parameter can be a value between 0 to 7.
|
|
|
* @param[in] CAN_Data pointer to a the @ref uint8_t table which contains data to sent.
|
|
|
* @retval Transmit Status, this returned value can be one of the @ref CAN_TxStatus_TypeDef enumeration.
|
|
|
*/
|
|
|
CAN_TxStatus_TypeDef CAN_Transmit(uint32_t CAN_Id,
|
|
|
CAN_Id_TypeDef CAN_IDE,
|
|
|
CAN_RTR_TypeDef CAN_RTR,
|
|
|
uint8_t CAN_DLC,
|
|
|
uint8_t *CAN_Data)
|
|
|
{
|
|
|
CAN_TxStatus_TypeDef CAN_TxStatus = CAN_TxStatus_NoMailBox;
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_IDTYPE_OK(CAN_IDE));
|
|
|
if (CAN_IDE != CAN_Id_Standard)
|
|
|
{
|
|
|
assert_param(IS_CAN_EXTID_OK(CAN_Id));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
assert_param(IS_CAN_STDID_OK(CAN_Id));
|
|
|
}
|
|
|
assert_param(IS_CAN_RTR_OK(CAN_RTR));
|
|
|
assert_param(IS_CAN_DLC_OK(CAN_DLC));
|
|
|
/* Select one empty transmit mailbox */
|
|
|
if ((CAN->TPR & CAN_TPR_TME0) == CAN_TPR_TME0)
|
|
|
{
|
|
|
CAN_TxStatus = CAN_TxStatus_MailBox0Ok;
|
|
|
}
|
|
|
else if ((CAN->TPR & CAN_TPR_TME1) == CAN_TPR_TME1)
|
|
|
{
|
|
|
CAN_TxStatus = CAN_TxStatus_MailBox1Ok;
|
|
|
}
|
|
|
else if ((CAN->TPR & CAN_TPR_TME2) == CAN_TPR_TME2)
|
|
|
{
|
|
|
CAN_TxStatus = CAN_TxStatus_MailBox2Ok;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CAN_TxStatus = CAN_TxStatus_NoMailBox;
|
|
|
}
|
|
|
if (CAN_TxStatus != CAN_TxStatus_NoMailBox)
|
|
|
{
|
|
|
CAN->PSR = (uint8_t)CAN_TxStatus;
|
|
|
/* Set up the Id */
|
|
|
if (CAN_IDE != CAN_Id_Standard)
|
|
|
{
|
|
|
CAN_Id &= (uint32_t)CAN_EXTID_SIZE;
|
|
|
CAN->Page.TxMailbox.MIDR4 = (uint8_t)(CAN_Id);
|
|
|
CAN_Id = CAN_Id>>8;
|
|
|
CAN->Page.TxMailbox.MIDR3 = (uint8_t)(CAN_Id);
|
|
|
CAN_Id = CAN_Id>>8;
|
|
|
CAN->Page.TxMailbox.MIDR2 = (uint8_t)(CAN_Id);
|
|
|
CAN_Id = CAN_Id>>8;
|
|
|
CAN->Page.TxMailbox.MIDR1 = (uint8_t)(CAN_Id |CAN_IDE | CAN_RTR);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CAN_Id &= (uint16_t)CAN_STDID_SIZE;
|
|
|
CAN->Page.TxMailbox.MIDR1 = (uint8_t)((CAN_Id>>6) | (CAN_RTR)) ;
|
|
|
CAN->Page.TxMailbox.MIDR2 = (uint8_t)(CAN_Id<<2);
|
|
|
}
|
|
|
/* Set up the DLC */
|
|
|
/*clear old DLC value*/
|
|
|
CAN->Page.TxMailbox.MDLCR &= (uint8_t)0xF0;
|
|
|
/*set the new value of DLC*/
|
|
|
CAN->Page.TxMailbox.MDLCR |= CAN_DLC;
|
|
|
/* Set up the data field */
|
|
|
CAN->Page.TxMailbox.MDAR1 = CAN_Data[0];
|
|
|
CAN->Page.TxMailbox.MDAR2 = CAN_Data[1];
|
|
|
CAN->Page.TxMailbox.MDAR3 = CAN_Data[2];
|
|
|
CAN->Page.TxMailbox.MDAR4 = CAN_Data[3];
|
|
|
CAN->Page.TxMailbox.MDAR5 = CAN_Data[4];
|
|
|
CAN->Page.TxMailbox.MDAR6 = CAN_Data[5];
|
|
|
CAN->Page.TxMailbox.MDAR7 = CAN_Data[6];
|
|
|
CAN->Page.TxMailbox.MDAR8 = CAN_Data[7];
|
|
|
/* Request transmission */
|
|
|
CAN->Page.TxMailbox.MCSR |= CAN_MCSR_TXRQ;
|
|
|
}
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
return (CAN_TxStatus_TypeDef)CAN_TxStatus;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Checks the transmission of a message.
|
|
|
* @param TransmitMailbox: the number of the mailbox that is used for transmission, can be on of @ref CAN_TransmitMailBox_TypeDef.
|
|
|
* @retval CAN_TxStatus_Ok if the CAN driver transmits the message, CAN_TxStatus_Failed in an other case.
|
|
|
*/
|
|
|
CAN_TxStatus_TypeDef CAN_TransmitStatus(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
|
|
|
{
|
|
|
/* RQCP, TXOK and TME bits */
|
|
|
CAN_TxStatus_TypeDef tstate = CAN_TxStatus_Failed;
|
|
|
uint8_t tmpstate=0;
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
|
|
|
|
|
|
switch (CAN_TransmitMailbox)
|
|
|
{
|
|
|
case (CAN_TransmitMailBox_0): tmpstate = (uint8_t)((CAN->TSR & (uint8_t)(CAN_TSR_RQCP0|CAN_TSR_TXOK0)));
|
|
|
tmpstate |= (uint8_t)((CAN->TPR & CAN_TPR_TME0));
|
|
|
break;
|
|
|
case (CAN_TransmitMailBox_1): tmpstate = (uint8_t)((uint8_t)(CAN->TSR & (uint8_t)(CAN_TSR_RQCP1|CAN_TSR_TXOK1))>>1);
|
|
|
tmpstate |= (uint8_t)((uint8_t)(CAN->TPR & CAN_TPR_TME1) >> 1);
|
|
|
break;
|
|
|
case (CAN_TransmitMailBox_2): tmpstate = (uint8_t)((uint8_t)(CAN->TSR & (uint8_t)(CAN_TSR_RQCP2|CAN_TSR_TXOK2))>>2);
|
|
|
tmpstate |= (uint8_t)((uint8_t)(CAN->TPR & CAN_TPR_TME2) >> 2);
|
|
|
break;
|
|
|
default:
|
|
|
tstate = CAN_TxStatus_Failed;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
switch (tmpstate)
|
|
|
{
|
|
|
/*transmit pending */
|
|
|
case (0x00): tstate = CAN_TxStatus_Pending;
|
|
|
break;
|
|
|
/* transmit failed */
|
|
|
case (0x05): tstate = CAN_TxStatus_Failed;
|
|
|
break;
|
|
|
/* transmit succeeded */
|
|
|
case (0x15): tstate = CAN_TxStatus_Ok;
|
|
|
break;
|
|
|
/* transmit mailbox is empty : no activity on this TX mail box */
|
|
|
case (0x04): tstate = CAN_TxStatus_MailBoxEmpty;
|
|
|
break;
|
|
|
default:
|
|
|
tstate = CAN_TxStatus_Failed;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
return (CAN_TxStatus_TypeDef)tstate;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Cancels a transmit request.
|
|
|
* @param TransmitMailbox : the Transmission mailbox, can be one of CAN_TransmitMailBox_TypeDef
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_CancelTransmit(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
|
|
|
{
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
|
|
|
/*switch to the specific page */
|
|
|
CAN->PSR = (uint8_t)CAN_TransmitMailbox;
|
|
|
/* abort transmission */
|
|
|
CAN->Page.TxMailbox.MCSR |= CAN_MCSR_ABRQ;
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Releases the CAN FIFO.
|
|
|
* @param None
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_FIFORelease(void)
|
|
|
{
|
|
|
/* Release FIFO*/
|
|
|
CAN->RFR = CAN_RFR_RFOM; /*rc-w1*/
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @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 = (CAN_NbrPendingMessage_TypeDef)(CAN->RFR & CAN_RFR_FMP01);
|
|
|
return (CAN_NbrPendingMessage_TypeDef)msgpending;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Receives a message which contains CAN Id, IDE, RTR
|
|
|
* DLC, data and FMI number.
|
|
|
* In order to get these data, use CAN_GetReceivedId(), CAN_GetReceivedIDE(), CAN_GetReceivedRTR(),
|
|
|
* CAN_GetReceivedDLC(), CAN_GetReceivedFMI() and CAN_GetReceivedData() functions.
|
|
|
* @param None
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_Receive(void)
|
|
|
{
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
uint32_t temp1 = 0, temp2 = 0, temp3 = 0;
|
|
|
|
|
|
/* select Fifo page*/
|
|
|
CAN->PSR = CAN_Page_RxFifo;
|
|
|
|
|
|
/* Get the Id */
|
|
|
_IDE = (uint8_t)(CAN->Page.RxFIFO.MIDR1 & CAN_Id_Extended);
|
|
|
if (_IDE != CAN_Id_Standard)
|
|
|
{
|
|
|
temp1 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR3) << 8);
|
|
|
temp2 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR2) << 16);
|
|
|
temp3 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 24);
|
|
|
|
|
|
_Id = (uint32_t)CAN_EXTID_SIZE & ((CAN->Page.RxFIFO.MIDR4) | temp1 | temp2 | temp3 );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
temp1 = (uint16_t)((uint16_t)((uint16_t)((uint16_t)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 6));
|
|
|
temp2 = (uint16_t)((uint16_t)((uint16_t)CAN->Page.RxFIFO.MIDR2 >> 2)&0x3F);
|
|
|
|
|
|
_Id = (uint16_t)CAN_STDID_SIZE & (temp1 | temp2 );
|
|
|
}
|
|
|
|
|
|
_RTR = (uint8_t)((uint8_t)0x20 & CAN->Page.RxFIFO.MIDR1);
|
|
|
|
|
|
/* Get the DLC */
|
|
|
_DLC = (uint8_t)(CAN->Page.RxFIFO.MDLCR & (uint8_t)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.
|
|
|
* @param 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.
|
|
|
*/
|
|
|
uint32_t CAN_GetReceivedId(void)
|
|
|
{
|
|
|
return (_Id);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the CAN IDE of the received message.
|
|
|
* @param 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 (CAN_Id_TypeDef)(_IDE);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the CAN RTR of the received message.
|
|
|
* @param 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 (CAN_RTR_TypeDef)(_RTR);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the CAN DLC of the received message.
|
|
|
* @param 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.
|
|
|
*/
|
|
|
uint8_t CAN_GetReceivedDLC(void)
|
|
|
{
|
|
|
return (_DLC);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the CAN Data of the received message.
|
|
|
* @param 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.
|
|
|
*/
|
|
|
uint8_t CAN_GetReceivedData(uint8_t CAN_DataIndex)
|
|
|
{
|
|
|
assert_param(IS_CAN_DLC_OK(CAN_DataIndex));
|
|
|
return (_Data[CAN_DataIndex]);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the CAN FMI of the received message.
|
|
|
* @param 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.
|
|
|
*/
|
|
|
uint8_t CAN_GetReceivedFMI(void)
|
|
|
{
|
|
|
return (_FMI);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Returns the Received time stamp.
|
|
|
* @param None
|
|
|
* @retval uint16_t the received time stamp.
|
|
|
*/
|
|
|
uint16_t CAN_GetMessageTimeStamp(void)
|
|
|
{
|
|
|
uint16_t timestamp = 0;
|
|
|
CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
|
|
|
|
|
|
/*switch to the specific page */
|
|
|
CAN->PSR = CAN_Page_RxFifo;
|
|
|
/* Get the Received Time stamp */
|
|
|
timestamp = CAN->Page.RxFIFO.MTSRL;
|
|
|
timestamp |= (uint16_t)(((uint16_t)CAN->Page.RxFIFO.MTSRH)<<8);
|
|
|
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
|
|
|
return (uint16_t)(timestamp);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Enters the Sleep low power mode.
|
|
|
* @param 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 = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~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.
|
|
|
* @param 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 &= (uint8_t)(~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 Operation mode.
|
|
|
* @param CAN_OperatingMode CAN Operating Mode ,
|
|
|
* this parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
|
|
|
* @retval the status of the requested mode which can be
|
|
|
* - CAN_ModeStatus_Failed CAN failed entering the specific mode
|
|
|
* - CAN_ModeStatus_Success CAN Succeed entering the specific mode
|
|
|
|
|
|
*/
|
|
|
CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
|
|
|
{
|
|
|
uint16_t timeout = CAN_ACKNOWLEDGE_TIMEOUT;
|
|
|
uint8_t modestatus = 0;
|
|
|
|
|
|
assert_param(IS_CAN_OPERATINGMODE_OK(CAN_OperatingMode));
|
|
|
|
|
|
if (CAN_OperatingMode == CAN_OperatingMode_Initialization)
|
|
|
{
|
|
|
/* Request initialisation */
|
|
|
CAN->MCR = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~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)
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Failed;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Success;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (CAN_OperatingMode == CAN_OperatingMode_Normal)
|
|
|
{
|
|
|
/* Request leave initialisation and sleep mode and enter Normal mode */
|
|
|
CAN->MCR &= (uint8_t)(~(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)
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Failed;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Success;
|
|
|
}
|
|
|
}
|
|
|
else if (CAN_OperatingMode == CAN_OperatingMode_Sleep)
|
|
|
{
|
|
|
/* Request Sleep mode */
|
|
|
CAN->MCR = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~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)
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Failed;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Success;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
modestatus = CAN_ModeStatus_Failed;
|
|
|
}
|
|
|
return (CAN_ModeStatus_TypeDef)(modestatus);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the Last Error Code.
|
|
|
* @param 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 = (CAN_ErrorCode_TypeDef)((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 CAN_FLAG : Flag to be cleared, can be one of the following 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)
|
|
|
{
|
|
|
CAN_Page_TypeDef can_page = (CAN_Page_TypeDef)0;
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_FLAG_CLEAR_OK(CAN_Flag));
|
|
|
if (((uint16_t)CAN_Flag & 0x0700)!= RESET)
|
|
|
{
|
|
|
if (((uint16_t)CAN_Flag & 0x020B)!= RESET)
|
|
|
{
|
|
|
/*Receive Flags*/
|
|
|
CAN->RFR = (uint8_t)(CAN_Flag);
|
|
|
}
|
|
|
else if (((uint16_t)CAN_Flag & 0x0403)!= RESET)
|
|
|
{
|
|
|
/*Transmit Flags*/
|
|
|
CAN->TSR = (uint8_t)(CAN_Flag);
|
|
|
}
|
|
|
else /*if((CAN_Flag & 0x0108)!=(uint16_t)RESET)*/
|
|
|
{
|
|
|
/*wake up Flags*/
|
|
|
CAN->MSR = (uint8_t)(CAN_Flag);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/*Error Flags*/
|
|
|
can_page = CAN_GetSelectedPage();
|
|
|
|
|
|
/* Clear the selected CAN flags */
|
|
|
CAN->PSR = CAN_Page_Config;
|
|
|
CAN->Page.Config.ESR = (uint8_t)RESET;
|
|
|
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Checks whether the specified CAN flag is set or not.
|
|
|
* @param 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.
|
|
|
*/
|
|
|
FlagStatus CAN_GetFlagStatus(CAN_FLAG_TypeDef CAN_Flag)
|
|
|
{
|
|
|
FlagStatus bitstatus = RESET;
|
|
|
CAN_Page_TypeDef can_page = (CAN_Page_TypeDef)0;
|
|
|
|
|
|
/* Check the parameters */
|
|
|
assert_param(IS_CAN_FLAG_STATUS_OK(CAN_Flag));
|
|
|
|
|
|
if (((uint16_t)CAN_Flag & 0x0700)!= RESET)
|
|
|
{
|
|
|
if (((uint16_t)CAN_Flag & 0x020B)!= RESET)
|
|
|
{
|
|
|
/*Receive Flags*/
|
|
|
if ((CAN->RFR & (uint16_t)CAN_Flag )!= RESET)
|
|
|
{
|
|
|
/* CAN_FLAG is set */
|
|
|
bitstatus = SET;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* CAN_FLAG is reset */
|
|
|
bitstatus = RESET;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if (((uint16_t)CAN_Flag & 0x0403)!= RESET)
|
|
|
{
|
|
|
/*Transmit Flags*/
|
|
|
if ((CAN->TSR & (uint16_t)CAN_Flag )!= RESET)
|
|
|
{
|
|
|
/* CAN_FLAG is set */
|
|
|
bitstatus = SET;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* CAN_FLAG is reset */
|
|
|
bitstatus = RESET;
|
|
|
}
|
|
|
}
|
|
|
else /*if((CAN_Flag & 0x0108)!=(uint16_t)RESET)*/
|
|
|
{
|
|
|
/*wake up Flags*/
|
|
|
if ((CAN->MSR & (uint16_t)CAN_Flag )!= 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 & (uint16_t)CAN_Flag) != 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 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.
|
|
|
*/
|
|
|
ITStatus CAN_GetITStatus(CAN_IT_TypeDef CAN_IT)
|
|
|
{
|
|
|
ITStatus pendingbitstatus = RESET;
|
|
|
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<EFBFBD>s interrupt pending bits.
|
|
|
* @param CAN_IT: specifies the interrupt pending bit to clear,
|
|
|
* can be one of the following parameters:
|
|
|
* CAN_IT_TME = Transmit mailbox empty interrupt
|
|
|
* CAN_IT_FF =FIFO full interrupt
|
|
|
* CAN_IT_FOV =FIFO overrun interrupt
|
|
|
* CAN_IT_WKU =Wake-up interrupt
|
|
|
* CAN_IT_ERR =General Error interrupt
|
|
|
* CAN_IT_EWG =Error warning interrupt
|
|
|
* CAN_IT_EPV =Error passive interrupt
|
|
|
* CAN_IT_BOF = Bus-off interrupt
|
|
|
* CAN_IT_LEC =Last error code interrupt
|
|
|
* @retval 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 = (uint8_t)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 = (uint8_t)CAN_ESR_RESET_VALUE;
|
|
|
break;
|
|
|
|
|
|
default :
|
|
|
break;
|
|
|
}
|
|
|
/*Restore Last Page*/
|
|
|
CAN_SelectPage(can_page);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Gets the selected registers page.
|
|
|
* @param None
|
|
|
* @retval the selected page which can be one of the @ref CAN_Page_TypeDef.
|
|
|
*/
|
|
|
CAN_Page_TypeDef CAN_GetSelectedPage(void)
|
|
|
{
|
|
|
return (CAN_Page_TypeDef)(CAN->PSR);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Sets the registers page to be selected.
|
|
|
* @param the selected page which can be one of the @ref CAN_Page_TypeDef.
|
|
|
* @retval None
|
|
|
*/
|
|
|
void CAN_SelectPage(CAN_Page_TypeDef CAN_Page)
|
|
|
{
|
|
|
CAN->PSR = (uint8_t)CAN_Page;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Checks whether the CAN interrupt has occurred or not.
|
|
|
* @param CAN_Reg: specifies the CAN interrupt register to check.
|
|
|
* @param It_Bit: specifies the interrupt source bit to check.
|
|
|
* @retval The new state of the CAN Interrupt, which can be one of ITStatus.
|
|
|
*/
|
|
|
static ITStatus CheckITStatus(uint8_t CAN_Reg, uint8_t It_Bit)
|
|
|
{
|
|
|
ITStatus pendingbitstatus = RESET;
|
|
|
if ((CAN_Reg & It_Bit) != (uint8_t)RESET)
|
|
|
{
|
|
|
/* CAN_IT is set */
|
|
|
pendingbitstatus = SET;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* CAN_IT is reset */
|
|
|
pendingbitstatus = RESET;
|
|
|
}
|
|
|
return (ITStatus)pendingbitstatus;
|
|
|
}
|
|
|
|
|
|
|
|
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
|
|