STM8S/A Standard Peripherals Firmware Library: stm8s_can.c Source File

STM8S/A

stm8s_can.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm8s_can.c
00004   * @author  MCD Application Team
00005   * @version V2.2.0
00006   * @date    30-September-2014
00007   * @brief   This file contains all the functions for the CAN peripheral.
00008    ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
00012   *
00013   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00014   * You may not use this file except in compliance with the License.
00015   * You may obtain a copy of the License at:
00016   *
00017   *        http://www.st.com/software_license_agreement_liberty_v2
00018   *
00019   * Unless required by applicable law or agreed to in writing, software 
00020   * distributed under the License is distributed on an "AS IS" BASIS, 
00021   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00022   * See the License for the specific language governing permissions and
00023   * limitations under the License.
00024   *
00025   ******************************************************************************
00026   */
00027 
00028 /* Includes ------------------------------------------------------------------*/
00029 #include "stm8s_can.h"
00030 
00031 /** @addtogroup STM8S_StdPeriph_Driver
00032   * @{
00033   */
00034 /* Private typedef -----------------------------------------------------------*/
00035 /* Private define ------------------------------------------------------------*/
00036 #define CAN_IDLIST_IDMASK_MASK ((uint8_t) 0x55)
00037 #define CAN_IDMASK_IDLIST_MASK ((uint8_t) 0xAA)
00038 #define CAN_MODE_MASK ((uint8_t) 0x03)
00039 #define CAN_ACKNOWLEDGE_TIMEOUT ((uint16_t)0xFFFF)
00040 /* Private macro -------------------------------------------------------------*/
00041 /* Private variables ---------------------------------------------------------*/
00042 __IO uint32_t _Id = 0;
00043 __IO uint8_t _IDE = 0;
00044 __IO uint8_t _RTR = 0;
00045 __IO uint8_t _DLC = 0;
00046 __IO uint8_t _Data[8] = {0};
00047 __IO uint8_t _FMI = 0;
00048 /* Private function prototypes -----------------------------------------------*/
00049 static ITStatus CheckITStatus(uint8_t CAN_Reg, uint8_t It_Bit);
00050 
00051 /* Private functions ---------------------------------------------------------*/
00052 /**
00053   * @addtogroup CAN_Public_Functions
00054   * @{
00055   */
00056 
00057 /**
00058   * @brief  Deinitializes the CAN peripheral registers to their default reset values.
00059   * @param  None
00060   * @retval None
00061   */
00062 void CAN_DeInit(void)
00063 {
00064   /* Request initialisation */
00065   CAN->MCR = CAN_MCR_INRQ;
00066   CAN->PSR = CAN_Page_Config;
00067   CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
00068   CAN->Page.Config.ESR = CAN_ESR_RESET_VALUE;
00069   CAN->Page.Config.EIER = CAN_EIER_RESET_VALUE;
00070   CAN->Page.Config.BTR1 = CAN_BTR1_RESET_VALUE;
00071   CAN->Page.Config.BTR2 = CAN_BTR2_RESET_VALUE;
00072   CAN->Page.Config.FMR1 = CAN_FMR1_RESET_VALUE;
00073   CAN->Page.Config.FMR2 = CAN_FMR2_RESET_VALUE;
00074   CAN->Page.Config.FCR1 = CAN_FCR_RESET_VALUE;
00075   CAN->Page.Config.FCR2 = CAN_FCR_RESET_VALUE;
00076   CAN->Page.Config.FCR3 = CAN_FCR_RESET_VALUE;
00077   CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
00078   CAN->PSR = CAN_Page_RxFifo;
00079   CAN->Page.RxFIFO.MDLCR = CAN_MDLC_RESET_VALUE;
00080   CAN->PSR = CAN_Page_TxMailBox0;
00081   CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
00082   CAN->PSR = CAN_Page_TxMailBox1;
00083   CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
00084   CAN->PSR = CAN_Page_TxMailBox2;
00085   CAN->Page.TxMailbox.MDLCR = CAN_MDLC_RESET_VALUE;
00086   
00087   CAN->MCR = CAN_MCR_RESET_VALUE;
00088   CAN->MSR = (uint8_t)(~CAN_MSR_RESET_VALUE);/* rc_w1 */
00089   CAN->TSR = (uint8_t)(~CAN_TSR_RESET_VALUE);/* rc_w1 */
00090   CAN->RFR = (uint8_t)(~CAN_RFR_RESET_VALUE);/* rc_w1 */
00091   CAN->IER = CAN_IER_RESET_VALUE;
00092   CAN->DGR = CAN_DGR_RESET_VALUE;
00093   CAN->PSR = CAN_PSR_RESET_VALUE;
00094 }
00095 
00096 /**
00097   * @brief  Initializes the CAN peripheral according to the specified parameters.
00098   * @param   CAN_MasterCtrl : Master control option, can be one or a combination of @ref CAN_MasterCtrl_TypeDef.
00099   * @param   CAN_Mode : CAN mode , can be one of @ref CAN_Mode_TypeDef.
00100   * @param   CAN_SynJumpWidth : CAN Synchronisation Jump Width , can be one of @ref CAN_SynJumpWidth_TypeDef.
00101   * @param   CAN_BitSeg1 : CAN bit segment 1 , can be one of @ref CAN_BitSeg1_TypeDef.
00102   * @param   CAN_BitSeg2 : CAN bit segment 2 , can be one of @ref CAN_BitSeg2_TypeDef.
00103   * @param   CAN_Prescaler : CAN Baud Rate Prescaler , can be a value from 0x01 to 0xFF.
00104   * @retval Indicates if initialization is succeed. it can be one of @ref CAN_InitStatus_TypeDef enumeration.
00105   */
00106 CAN_InitStatus_TypeDef CAN_Init(CAN_MasterCtrl_TypeDef CAN_MasterCtrl,
00107                                 CAN_Mode_TypeDef CAN_Mode,
00108                                 CAN_SynJumpWidth_TypeDef CAN_SynJumpWidth,
00109                                 CAN_BitSeg1_TypeDef CAN_BitSeg1,
00110                                 CAN_BitSeg2_TypeDef CAN_BitSeg2,
00111                                 uint8_t CAN_Prescaler)
00112 {
00113   CAN_InitStatus_TypeDef InitStatus =  CAN_InitStatus_Failed;
00114   uint16_t timeout = CAN_ACKNOWLEDGE_TIMEOUT;
00115   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00116   
00117   
00118   /* Check the parameters */
00119   assert_param(IS_CAN_MASTERCTRL_OK(CAN_MasterCtrl));
00120   assert_param(IS_CAN_MODE_OK(CAN_Mode));
00121   assert_param(IS_CAN_SYNJUMPWIDTH_OK(CAN_SynJumpWidth));
00122   assert_param(IS_CAN_BITSEG1_OK(CAN_BitSeg1));
00123   assert_param(IS_CAN_BITSEG2_OK(CAN_BitSeg2));
00124   assert_param(IS_CAN_PRESCALER_OK(CAN_Prescaler));
00125   
00126   /* Request initialisation */
00127   CAN->MCR = CAN_MCR_INRQ;
00128   /* Wait the acknowledge */
00129   while (((uint8_t)(CAN->MSR & CAN_MSR_INAK) != 0x01) && ((uint16_t)timeout != 0))
00130   {
00131     timeout--;
00132   }
00133   
00134   /* Check acknowledged */
00135   if ((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
00136   {
00137     
00138     InitStatus =  CAN_InitStatus_Failed;
00139     
00140   }
00141   else
00142   {
00143     /* Set the time triggered communication mode  &  Set the automatic bus-off management  &   Set the automatic wake-up mode
00144     &     Set the no automatic retransmission & Set the receive FIFO locked mode & Set the transmit FIFO priority */
00145     CAN->MCR |= (uint8_t)CAN_MasterCtrl;
00146     
00147     /* Set the bit timing register */
00148     CAN->DGR |= (uint8_t)CAN_Mode ;
00149     CAN->PSR = CAN_Page_Config;
00150     CAN->Page.Config.BTR1 = (uint8_t)((uint8_t)(CAN_Prescaler - (uint8_t)1) | CAN_SynJumpWidth);
00151     CAN->Page.Config.BTR2 = (uint8_t)(CAN_BitSeg1 | (uint8_t)CAN_BitSeg2);
00152     
00153     /* Request leave initialisation */
00154     CAN->MCR &= (uint8_t)(~CAN_MCR_INRQ);
00155     /* Wait the acknowledge */
00156     timeout = 0xFFFF;
00157     while ((((uint8_t)(CAN->MSR & CAN_MSR_INAK) == 0x01))&&(timeout != 0))
00158     {
00159       timeout--;
00160     }
00161     /* Check acknowledged */
00162     if ((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
00163     {
00164       InitStatus = CAN_InitStatus_Failed;
00165     }
00166     else
00167     {
00168       InitStatus = CAN_InitStatus_Success;
00169     }
00170   }
00171   /*Restore Last Page*/
00172   CAN_SelectPage(can_page);
00173   
00174   /* Return the status of initialization */
00175   return (CAN_InitStatus_TypeDef)InitStatus;
00176 }
00177 
00178 /**
00179   * @brief  Initializes the CAN peripheral Filter according to the specified parameters.
00180   * @param   CAN_FilterNumber : CAN Filter number , can be one of @ref CAN_FilterNumber_TypeDef
00181   * @param   CAN_FilterActivation : CAN Filter Activation state , can be one of @ref FunctionalState
00182   * @param   CAN_FilterMode : CAN Filter Mode , can be one of @ref CAN_FilterMode_TypeDef
00183   * @param   CAN_FilterScale : CAN Filter Scale , can be one of @ref CAN_FilterScale_TypeDef
00184   * @param   CAN_FilterID1 : CAN Filter ID 1 , can be a value from 0x00 to 0xFF
00185   * @param   CAN_FilterID2 : CAN Filter ID 2 , can be a value from 0x00 to 0xFF
00186   * @param   CAN_FilterID3 : CAN Filter ID 3 , can be a value from 0x00 to 0xFF
00187   * @param   CAN_FilterID4 : CAN Filter ID 4 , can be a value from 0x00 to 0xFF
00188   * @param   CAN_FilterIDMask1 : CAN Filter ID 1/ Mask 1  , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
00189   * @param   CAN_FilterIDMask2 : CAN Filter ID 2/ Mask 2 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
00190   * @param   CAN_FilterIDMask3 : CAN Filter ID 3/ Mask 3 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
00191   * @param   CAN_FilterIDMask4 : CAN Filter ID 4/ Mask 4 , can be a value from 0x00 to 0xFF depending of CAN_FilterMode parameter
00192   * @retval None
00193   */
00194 void CAN_FilterInit(CAN_FilterNumber_TypeDef CAN_FilterNumber,
00195                     FunctionalState CAN_FilterActivation,
00196                     CAN_FilterMode_TypeDef CAN_FilterMode,
00197                     CAN_FilterScale_TypeDef CAN_FilterScale,
00198                     uint8_t CAN_FilterID1,
00199                     uint8_t CAN_FilterID2,
00200                     uint8_t CAN_FilterID3,
00201                     uint8_t CAN_FilterID4,
00202                     uint8_t CAN_FilterIDMask1,
00203                     uint8_t CAN_FilterIDMask2,
00204                     uint8_t CAN_FilterIDMask3,
00205                     uint8_t CAN_FilterIDMask4)
00206 {
00207   uint8_t fact = 0;
00208   uint8_t fsc  = 0;
00209   uint8_t fmhl = 0;
00210   
00211   CAN_Page_TypeDef can_page_filter = CAN_Page_Filter01;
00212   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00213   
00214   /* Check the parameters */
00215   assert_param(IS_CAN_FILTER_NUMBER_OK(CAN_FilterNumber));
00216   assert_param(IS_FUNCTIONALSTATE_OK(CAN_FilterActivation));
00217   assert_param(IS_CAN_FILTER_MODE_OK(CAN_FilterMode));
00218   assert_param(IS_CAN_FILTER_SCALE_OK(CAN_FilterScale));
00219   
00220   
00221   if (CAN_FilterNumber == CAN_FilterNumber_0)
00222   {
00223     fact = 0x01;
00224     fsc  = 0x00;
00225     fmhl = 0x03;
00226     
00227     can_page_filter = CAN_Page_Filter01;
00228   }
00229   else if (CAN_FilterNumber == CAN_FilterNumber_1)
00230   {
00231     fact = 0x10;
00232     fsc  = 0x04;
00233     fmhl = 0x0C;
00234     
00235     can_page_filter = CAN_Page_Filter01;
00236   }
00237   else if (CAN_FilterNumber == CAN_FilterNumber_2)
00238   {
00239     fact = 0x01;
00240     fsc  = 0x00;
00241     fmhl = 0x30;
00242     
00243     can_page_filter = CAN_Page_Filter23;
00244   }
00245   else if (CAN_FilterNumber == CAN_FilterNumber_3)
00246   {
00247     fact = 0x10;
00248     fsc  = 0x04;
00249     fmhl = 0xC0;
00250     
00251     can_page_filter = CAN_Page_Filter23;
00252   }
00253   else if (CAN_FilterNumber == CAN_FilterNumber_4)
00254   {
00255     fact = 0x01;
00256     fsc  = 0x00;
00257     fmhl = 0x03;
00258     
00259     can_page_filter = CAN_Page_Filter45;
00260   }
00261   else /*if (CAN_FilterNumber == CAN_FilterNumber_5)*/
00262   {
00263     fact = 0x10;
00264     fsc  = 0x04;
00265     fmhl = 0x0C;
00266     
00267     can_page_filter = CAN_Page_Filter45;
00268   }
00269   
00270   
00271   CAN_OperatingModeRequest(CAN_OperatingMode_Initialization);
00272   
00273   CAN->PSR = CAN_Page_Config;
00274   /*---------------------------------------------------------*/
00275   /*Configuration of Filter Scale                            */
00276   /*---------------------------------------------------------*/
00277   
00278   if (can_page_filter == CAN_Page_Filter01) /* FCR1 */
00279   {
00280     /* Filter Deactivation  & Reset the Filter Scale */
00281     CAN->Page.Config.FCR1 &= (uint8_t)(~(uint8_t)(fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc )));
00282     /* Set the new Filter Scale */
00283     CAN->Page.Config.FCR1 |= (uint8_t)(CAN_FilterScale << fsc);
00284   }
00285   else if (can_page_filter == CAN_Page_Filter23) /* FCR2*/
00286   {
00287     /* Filter Deactivation  & Reset the Filter Scale */
00288     CAN->Page.Config.FCR2 &= (uint8_t)~(uint8_t)( fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
00289     
00290     /* Set the new Filter Scale */
00291     CAN->Page.Config.FCR2 |= (uint8_t)(CAN_FilterScale << fsc);
00292     
00293   }
00294   else /*if(can_page_filter == CAN_Page_Filter45)*/ /* FCR3*/
00295   {
00296     /* Filter Deactivation  & Reset the Filter Scale */
00297     CAN->Page.Config.FCR3 &= (uint8_t)~(uint8_t)( fact | (uint8_t)((uint8_t)(CAN_FCR1_FSC00|CAN_FCR1_FSC01) << fsc ));
00298     
00299     /* Set the new Filter Scale */
00300     CAN->Page.Config.FCR3 |= (uint8_t)(CAN_FilterScale << fsc);
00301   }
00302   
00303   /*---------------------------------------------------------*/
00304   /*Configuration of Filter Mode                             */
00305   /*---------------------------------------------------------*/
00306   if (can_page_filter != CAN_Page_Filter45) /* FMR1*/
00307   {
00308     /* Filter Mode */
00309     if (CAN_FilterMode == CAN_FilterMode_IdMask)
00310     {
00311       /*Id/Mask mode for the filter*/
00312       CAN->Page.Config.FMR1 &= (uint8_t)~(fmhl);
00313     }
00314     else if ( CAN_FilterMode == CAN_FilterMode_IdList)
00315     {
00316       /*Identifier list mode for the filter*/
00317       CAN->Page.Config.FMR1 |= (uint8_t)(fmhl);
00318     }
00319     else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
00320     {
00321       /*Identifier list mode is first  for the filter*/
00322       CAN->Page.Config.FMR1 |= (uint8_t)(fmhl & CAN_IDLIST_IDMASK_MASK);
00323     }
00324     else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
00325     {
00326       /*Id Mask mode is first  for the filter*/
00327       CAN->Page.Config.FMR1 |= (uint8_t)(fmhl & CAN_IDMASK_IDLIST_MASK);
00328     }
00329     
00330     
00331   }
00332   else /* FMR2 */
00333   {
00334     
00335     /* Filter Mode */
00336     if (CAN_FilterMode == CAN_FilterMode_IdMask)
00337     {
00338       /*Id/Mask mode for the filter*/
00339       CAN->Page.Config.FMR2 &= (uint8_t)~(fmhl);
00340     }
00341     else if ( CAN_FilterMode == CAN_FilterMode_IdList)
00342     {
00343       /*Identifier list mode for the filter*/
00344       CAN->Page.Config.FMR2 |= (uint8_t)(fmhl);
00345     }
00346     else if ( CAN_FilterMode == CAN_FilterMode_IdList_IdMask)
00347     {
00348       /*Identifier list mode is first  for the filter*/
00349       CAN->Page.Config.FMR2 |= (uint8_t)(fmhl & CAN_IDLIST_IDMASK_MASK);
00350     }
00351     else /* ( CAN_FilterMode == CAN_FilterMode_IdMask_IdList)*/
00352     {
00353       /*Id Mask mode is first  for the filter*/
00354       CAN->Page.Config.FMR2 |= (uint8_t)(fmhl & CAN_IDMASK_IDLIST_MASK);
00355     }
00356   }
00357   /*---------------------------------------------------------*/
00358   /*Configuration of Filter IDs                              */
00359   /*---------------------------------------------------------*/
00360   CAN->PSR = (uint8_t)can_page_filter;
00361   if (fsc != 0)
00362   {
00363     /* Filter Scale */
00364     if (CAN_FilterScale == CAN_FilterScale_8Bit)
00365     {
00366       CAN->Page.Filter.FR09 = CAN_FilterID1;
00367       CAN->Page.Filter.FR10 = CAN_FilterIDMask1;
00368       CAN->Page.Filter.FR11 = CAN_FilterID2;
00369       CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
00370       CAN->Page.Filter.FR13 = CAN_FilterID3;
00371       CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
00372       CAN->Page.Filter.FR15 = CAN_FilterID4;
00373       CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
00374     }
00375     else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
00376     {
00377       CAN->Page.Filter.FR09 = CAN_FilterID1;
00378       CAN->Page.Filter.FR10 = CAN_FilterID2;
00379       CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
00380       CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
00381       CAN->Page.Filter.FR13 = CAN_FilterID3;
00382       CAN->Page.Filter.FR14 = CAN_FilterIDMask3;
00383       CAN->Page.Filter.FR15 = CAN_FilterID4;
00384       CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
00385     }
00386     else if (CAN_FilterScale == CAN_FilterScale_16Bit)
00387     {
00388       CAN->Page.Filter.FR09 = CAN_FilterID1;
00389       CAN->Page.Filter.FR10 = CAN_FilterID2;
00390       CAN->Page.Filter.FR11 = CAN_FilterIDMask1;
00391       CAN->Page.Filter.FR12 = CAN_FilterIDMask2;
00392       CAN->Page.Filter.FR13 = CAN_FilterID3;
00393       CAN->Page.Filter.FR14 = CAN_FilterID4;
00394       CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
00395       CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
00396     }
00397     else if (CAN_FilterScale == CAN_FilterScale_32Bit)
00398     {
00399       CAN->Page.Filter.FR09 = CAN_FilterID1;
00400       CAN->Page.Filter.FR10 = CAN_FilterID2;
00401       CAN->Page.Filter.FR11 = CAN_FilterID3;
00402       CAN->Page.Filter.FR12 = CAN_FilterID4;
00403       CAN->Page.Filter.FR13 = CAN_FilterIDMask1;
00404       CAN->Page.Filter.FR14 = CAN_FilterIDMask2;
00405       CAN->Page.Filter.FR15 = CAN_FilterIDMask3;
00406       CAN->Page.Filter.FR16 = CAN_FilterIDMask4;
00407     }
00408   }
00409   else
00410   {
00411     /* Filter Scale */
00412     if (CAN_FilterScale == CAN_FilterScale_8Bit)
00413     {
00414       CAN->Page.Filter.FR01 = CAN_FilterID1;
00415       CAN->Page.Filter.FR02 = CAN_FilterIDMask1;
00416       CAN->Page.Filter.FR03 = CAN_FilterID2;
00417       CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
00418       CAN->Page.Filter.FR05 = CAN_FilterID3;
00419       CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
00420       CAN->Page.Filter.FR07 = CAN_FilterID4;
00421       CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
00422     }
00423     else if (CAN_FilterScale == CAN_FilterScale_16_8Bit)
00424     {
00425       CAN->Page.Filter.FR01 = CAN_FilterID1;
00426       CAN->Page.Filter.FR02 = CAN_FilterID2;
00427       CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
00428       CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
00429       CAN->Page.Filter.FR05 = CAN_FilterID3;
00430       CAN->Page.Filter.FR06 = CAN_FilterIDMask3;
00431       CAN->Page.Filter.FR07 = CAN_FilterID4;
00432       CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
00433     }
00434     else if (CAN_FilterScale == CAN_FilterScale_16Bit)
00435     {
00436       CAN->Page.Filter.FR01 = CAN_FilterID1;
00437       CAN->Page.Filter.FR02 = CAN_FilterID2;
00438       CAN->Page.Filter.FR03 = CAN_FilterIDMask1;
00439       CAN->Page.Filter.FR04 = CAN_FilterIDMask2;
00440       CAN->Page.Filter.FR05 = CAN_FilterID3;
00441       CAN->Page.Filter.FR06 = CAN_FilterID4;
00442       CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
00443       CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
00444     }
00445     else if (CAN_FilterScale == CAN_FilterScale_32Bit)
00446     {
00447       CAN->Page.Filter.FR01 = CAN_FilterID1;
00448       CAN->Page.Filter.FR02 = CAN_FilterID2;
00449       CAN->Page.Filter.FR03 = CAN_FilterID3;
00450       CAN->Page.Filter.FR04 = CAN_FilterID4;
00451       CAN->Page.Filter.FR05 = CAN_FilterIDMask1;
00452       CAN->Page.Filter.FR06 = CAN_FilterIDMask2;
00453       CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
00454       CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
00455     }
00456   }
00457   
00458   
00459   /*---------------------------------------------------------*/
00460   /*Configuration of Filter Activation                       */
00461   /*---------------------------------------------------------*/
00462   /* Filter activation */
00463   CAN->PSR = CAN_Page_Config;
00464   if (CAN_FilterActivation != DISABLE)
00465   {
00466     if ((CAN_FilterNumber & 0x06) == 0x00) /* FCR1*/
00467     {   CAN->Page.Config.FCR1 |= (uint8_t)fact;
00468     }
00469     else if ((CAN_FilterNumber & 0x06) == 0x02) /*FCR2*/
00470     { CAN->Page.Config.FCR2 |= (uint8_t)fact;
00471     }
00472     else /*if((CAN_FilterNumber & 0x06) == 0x04)*/ /*FCR3*/
00473     { CAN->Page.Config.FCR3 |= (uint8_t)fact;
00474     }
00475   }
00476   CAN_OperatingModeRequest(CAN_OperatingMode_Normal);
00477   /*Restore Last Page*/
00478   CAN_SelectPage(can_page);
00479 }
00480 
00481 /**
00482   * @brief   Enables or disables the specified CAN interrupts.
00483   * @param    CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
00484   * @param   NewState : CAN_IT new state , can be one of @ref FunctionalState
00485   * @retval None
00486   */
00487 void CAN_ITConfig(CAN_IT_TypeDef CAN_IT, FunctionalState NewState)
00488 {
00489   uint8_t tmperrorinterrupt = 0;
00490   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00491   
00492   
00493   /* Check the parameters */
00494   assert_param(IS_CAN_IT_CONFIG_OK(CAN_IT));
00495   assert_param(IS_FUNCTIONALSTATE_OK(NewState));
00496   
00497   tmperrorinterrupt = (uint8_t)(((uint16_t)CAN_IT) >>7);
00498   tmperrorinterrupt = (uint8_t)((uint8_t)((uint16_t)tmperrorinterrupt & 0xF0) | 
00499                                 (uint8_t)((uint8_t)((uint16_t)tmperrorinterrupt & 0x0F) >>1));
00500   
00501   CAN->PSR = CAN_Page_Config;
00502   if (NewState != DISABLE)
00503   {
00504     /* Enable the selected CAN interrupt */
00505     CAN->IER |= (uint8_t)(CAN_IT);
00506     CAN->Page.Config.EIER |= (uint8_t)(tmperrorinterrupt);
00507   }
00508   else
00509   {
00510     /* Disable the selected CAN interrupt */
00511     CAN->IER &= (uint8_t)~(uint8_t)((uint16_t)CAN_IT);
00512     CAN->Page.Config.EIER &= (uint8_t)~(tmperrorinterrupt);
00513   }
00514   /*Restore Last Page*/
00515   CAN_SelectPage(can_page);
00516 }
00517 
00518 /**
00519   * @brief   Enables or Disables the ST7 CAN Compatibility.
00520   * if the ST7 compatibility is Enabled, CAN provides only 2 mailboxes.
00521   * if the ST7 compatibility is Disabled, CAN provides 3 mailboxes.
00522   * @param   CAN_ST7Compatibility : CAN ST7 Compatibility , this parameter can be one of @ref CAN_ST7Compatibility_TypeDef enumeration.
00523   * @retval None
00524   */
00525 void CAN_ST7CompatibilityCmd(CAN_ST7Compatibility_TypeDef CAN_ST7Compatibility)
00526 {
00527   /* Check the parameters */
00528   assert_param(IS_CAN_ST7_COMPATIBILITY_OK(CAN_ST7Compatibility));
00529   /*Reset the old configuration of TXM2E */
00530   CAN->DGR &= (uint8_t)(~CAN_DGR_TXM2E);
00531   
00532   /*Set the old configuration of TXM2E */
00533   CAN->DGR |= (uint8_t)CAN_ST7Compatibility;
00534 }
00535 
00536 /**
00537   * @brief  Enables or disables the CAN Time TriggerOperation communication mode.
00538   * @param   NewState : Mode new state , can be one of @ref FunctionalState
00539   * @retval None
00540   */
00541 void CAN_TTComModeCmd(FunctionalState NewState)
00542 {
00543   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00544   /* Check the parameters */
00545   assert_param(IS_FUNCTIONALSTATE_OK(NewState));
00546   if (NewState != DISABLE)
00547   {
00548     /*Enable the TTCM mode */
00549     CAN->MCR |= CAN_MCR_TTCM;
00550     /*Set TGT bits setting in Tx and FIFO pages*/
00551     CAN->PSR = CAN_Page_TxMailBox0;
00552     CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
00553     CAN->PSR = CAN_Page_TxMailBox1;
00554     CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
00555     CAN->PSR = CAN_Page_TxMailBox2;
00556     CAN->Page.TxMailbox.MDLCR |= CAN_MDLCR_TGT;
00557     CAN->PSR = CAN_Page_RxFifo;
00558     CAN->Page.RxFIFO.MDLCR |= CAN_MDLCR_TGT;
00559   }
00560   else
00561   {
00562     /*Disable the TTCM mode */
00563     CAN->MCR &= ((uint8_t)~CAN_MCR_TTCM);
00564     /*Reset TGT bits setting in Tx and FIFO pages*/
00565     CAN->PSR = CAN_Page_TxMailBox0;
00566     CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
00567     CAN->PSR = CAN_Page_TxMailBox1;
00568     CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
00569     CAN->PSR = CAN_Page_TxMailBox2;
00570     CAN->Page.TxMailbox.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
00571     CAN->PSR = CAN_Page_RxFifo;
00572     CAN->Page.RxFIFO.MDLCR &= ((uint8_t)~CAN_MDLCR_TGT);
00573   }
00574   /*Restore Last Page*/
00575   CAN_SelectPage(can_page);
00576 }
00577 
00578 /**
00579   * @brief  Initiates the transmission of a message.
00580   * @param   CAN_Id the ID number of the message, its size depends on @ref CAN_IDE value.
00581   * @param[in] CAN_IDE the ID type of the message, this parameter can be one of the @ref CAN_Id_TypeDef enumeration.
00582   * @param[in] CAN_RTR the message type, this parameter can be one of the @ref CAN_RTR_TypeDef enumeration.
00583   * @param[in] CAN_DLC the number of data in the message type, this parameter can be a value between 0 to 7.
00584   * @param[in] CAN_Data pointer to a the @ref uint8_t table which contains data to sent.
00585   * @retval Transmit Status, this returned value can be one of the @ref CAN_TxStatus_TypeDef enumeration.
00586   */
00587 CAN_TxStatus_TypeDef CAN_Transmit(uint32_t CAN_Id,
00588                                   CAN_Id_TypeDef CAN_IDE,
00589                                   CAN_RTR_TypeDef CAN_RTR,
00590                                   uint8_t CAN_DLC,
00591                                   uint8_t *CAN_Data)
00592 {
00593   CAN_TxStatus_TypeDef CAN_TxStatus = CAN_TxStatus_NoMailBox;
00594   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00595   /* Check the parameters */
00596   assert_param(IS_CAN_IDTYPE_OK(CAN_IDE));
00597   if (CAN_IDE != CAN_Id_Standard)
00598   {
00599     assert_param(IS_CAN_EXTID_OK(CAN_Id));
00600   }
00601   else
00602   {
00603     assert_param(IS_CAN_STDID_OK(CAN_Id));
00604   }
00605   assert_param(IS_CAN_RTR_OK(CAN_RTR));
00606   assert_param(IS_CAN_DLC_OK(CAN_DLC));
00607   /* Select one empty transmit mailbox */
00608   if ((CAN->TPR & CAN_TPR_TME0) == CAN_TPR_TME0)
00609   {
00610     CAN_TxStatus = CAN_TxStatus_MailBox0Ok;
00611   }
00612   else if ((CAN->TPR & CAN_TPR_TME1) == CAN_TPR_TME1)
00613   {
00614     CAN_TxStatus = CAN_TxStatus_MailBox1Ok;
00615   }
00616   else if ((CAN->TPR & CAN_TPR_TME2) == CAN_TPR_TME2)
00617   {
00618     CAN_TxStatus = CAN_TxStatus_MailBox2Ok;
00619   }
00620   else
00621   {
00622     CAN_TxStatus = CAN_TxStatus_NoMailBox;
00623   }
00624   if (CAN_TxStatus != CAN_TxStatus_NoMailBox)
00625   {
00626     CAN->PSR = (uint8_t)CAN_TxStatus;
00627     /* Set up the Id */
00628     if (CAN_IDE != CAN_Id_Standard)
00629     {
00630       CAN_Id &= (uint32_t)CAN_EXTID_SIZE;
00631       CAN->Page.TxMailbox.MIDR4 = (uint8_t)(CAN_Id);
00632       CAN_Id = CAN_Id>>8;
00633       CAN->Page.TxMailbox.MIDR3 = (uint8_t)(CAN_Id);
00634       CAN_Id = CAN_Id>>8;
00635       CAN->Page.TxMailbox.MIDR2 = (uint8_t)(CAN_Id);
00636       CAN_Id = CAN_Id>>8;
00637       CAN->Page.TxMailbox.MIDR1 = (uint8_t)(CAN_Id |CAN_IDE | CAN_RTR);
00638     }
00639     else
00640     {
00641       CAN_Id &= (uint16_t)CAN_STDID_SIZE;
00642       CAN->Page.TxMailbox.MIDR1 = (uint8_t)((CAN_Id>>6) | (CAN_RTR)) ;
00643       CAN->Page.TxMailbox.MIDR2 = (uint8_t)(CAN_Id<<2);
00644     }
00645     /* Set up the DLC                 */
00646     /*clear old DLC value*/
00647     CAN->Page.TxMailbox.MDLCR &= (uint8_t)0xF0;
00648     /*set the new value of DLC*/
00649     CAN->Page.TxMailbox.MDLCR |= CAN_DLC;
00650     /* Set up the data field */
00651     CAN->Page.TxMailbox.MDAR1 = CAN_Data[0];
00652     CAN->Page.TxMailbox.MDAR2 = CAN_Data[1];
00653     CAN->Page.TxMailbox.MDAR3 = CAN_Data[2];
00654     CAN->Page.TxMailbox.MDAR4 = CAN_Data[3];
00655     CAN->Page.TxMailbox.MDAR5 = CAN_Data[4];
00656     CAN->Page.TxMailbox.MDAR6 = CAN_Data[5];
00657     CAN->Page.TxMailbox.MDAR7 = CAN_Data[6];
00658     CAN->Page.TxMailbox.MDAR8 = CAN_Data[7];
00659     /* Request transmission */
00660     CAN->Page.TxMailbox.MCSR |= CAN_MCSR_TXRQ;
00661   }
00662   /*Restore Last Page*/
00663   CAN_SelectPage(can_page);
00664   return (CAN_TxStatus_TypeDef)CAN_TxStatus;
00665 }
00666 
00667 /**
00668   * @brief  Checks the transmission of a message.
00669   * @param   TransmitMailbox: the number of the mailbox that is used for transmission, can be on of  @ref CAN_TransmitMailBox_TypeDef.
00670   * @retval CAN_TxStatus_Ok if the CAN driver transmits the message, CAN_TxStatus_Failed in an other case.
00671   */
00672 CAN_TxStatus_TypeDef CAN_TransmitStatus(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
00673 {
00674   /* RQCP, TXOK and TME bits */
00675   CAN_TxStatus_TypeDef tstate = CAN_TxStatus_Failed;
00676   uint8_t tmpstate=0;
00677   
00678   /* Check the parameters */
00679   assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
00680   
00681   switch (CAN_TransmitMailbox)
00682   {
00683   case (CAN_TransmitMailBox_0): tmpstate = (uint8_t)((CAN->TSR & (uint8_t)(CAN_TSR_RQCP0|CAN_TSR_TXOK0)));
00684   tmpstate |= (uint8_t)((CAN->TPR & CAN_TPR_TME0));
00685   break;
00686   case (CAN_TransmitMailBox_1): tmpstate = (uint8_t)((uint8_t)(CAN->TSR & (uint8_t)(CAN_TSR_RQCP1|CAN_TSR_TXOK1))>>1);
00687   tmpstate |= (uint8_t)((uint8_t)(CAN->TPR & CAN_TPR_TME1) >> 1);
00688   break;
00689   case (CAN_TransmitMailBox_2): tmpstate = (uint8_t)((uint8_t)(CAN->TSR & (uint8_t)(CAN_TSR_RQCP2|CAN_TSR_TXOK2))>>2);
00690   tmpstate |= (uint8_t)((uint8_t)(CAN->TPR & CAN_TPR_TME2) >> 2);
00691   break;
00692   default:
00693     tstate = CAN_TxStatus_Failed;
00694     break;
00695   }
00696   
00697   switch (tmpstate)
00698   {
00699     /*transmit pending  */
00700   case (0x00): tstate = CAN_TxStatus_Pending;
00701   break;
00702   /* transmit failed  */
00703   case (0x05): tstate = CAN_TxStatus_Failed;
00704   break;
00705   /* transmit succeeded */
00706   case (0x15): tstate = CAN_TxStatus_Ok;
00707   break;
00708   /* transmit mailbox is empty : no activity on this TX mail box */
00709   case (0x04): tstate = CAN_TxStatus_MailBoxEmpty;
00710   break;
00711   default:
00712     tstate = CAN_TxStatus_Failed;
00713     break;
00714   }
00715   
00716   return (CAN_TxStatus_TypeDef)tstate;
00717 }
00718 
00719 /**
00720   * @brief  Cancels a transmit request.
00721   * @param   TransmitMailbox : the Transmission mailbox, can be one of CAN_TransmitMailBox_TypeDef
00722   * @retval None
00723   */
00724 void CAN_CancelTransmit(CAN_TransmitMailBox_TypeDef CAN_TransmitMailbox)
00725 {
00726   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00727   /* Check the parameters */
00728   assert_param(IS_CAN_TRANSMITMAILBOX_OK(CAN_TransmitMailbox));
00729   /*switch to the specific page */
00730   CAN->PSR = (uint8_t)CAN_TransmitMailbox;
00731   /* abort transmission */
00732   CAN->Page.TxMailbox.MCSR |= CAN_MCSR_ABRQ;
00733   /*Restore Last Page*/
00734   CAN_SelectPage(can_page);
00735 }
00736 
00737 /**
00738   * @brief   Releases the CAN FIFO.
00739   * @param  None
00740   * @retval None
00741   */
00742 void CAN_FIFORelease(void)
00743 {
00744   /* Release FIFO*/
00745   CAN->RFR = CAN_RFR_RFOM; /*rc-w1*/
00746 }
00747 
00748 /**
00749   * @brief  Returns the number of pending messages.
00750   * @retval Number of pending messages.
00751   */
00752 CAN_NbrPendingMessage_TypeDef CAN_MessagePending(void)
00753 {
00754   CAN_NbrPendingMessage_TypeDef msgpending = CAN_NbrPendingMessage_0;
00755   msgpending = (CAN_NbrPendingMessage_TypeDef)(CAN->RFR & CAN_RFR_FMP01);
00756   return (CAN_NbrPendingMessage_TypeDef)msgpending;
00757 }
00758 
00759 /**
00760   * @brief   Receives a message which contains CAN Id, IDE, RTR
00761   * DLC, datas and FMI number.
00762   * In order to get these data, use CAN_GetReceivedId(), CAN_GetReceivedIDE(), CAN_GetReceivedRTR(),
00763   * CAN_GetReceivedDLC(), CAN_GetReceivedFMI() and CAN_GetReceivedData() functions.
00764   * @param  None
00765   * @retval None
00766   */
00767 void CAN_Receive(void)
00768 {
00769   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00770   uint32_t temp1 = 0, temp2 = 0, temp3 = 0;
00771   
00772   /* select Fifo page*/
00773   CAN->PSR = CAN_Page_RxFifo;
00774   
00775   /* Get the Id */
00776   _IDE = (uint8_t)(CAN->Page.RxFIFO.MIDR1 & CAN_Id_Extended);
00777   if (_IDE != CAN_Id_Standard)
00778   {
00779     temp1 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR3) << 8);
00780     temp2 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR2) << 16);  
00781     temp3 = ((uint32_t)((uint32_t)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 24);
00782     
00783     _Id = (uint32_t)CAN_EXTID_SIZE & ((CAN->Page.RxFIFO.MIDR4) | temp1 | temp2 | temp3 );
00784   }
00785   else
00786   {
00787     temp1 = (uint16_t)((uint16_t)((uint16_t)((uint16_t)CAN->Page.RxFIFO.MIDR1 & 0x1F) << 6));
00788     temp2 = (uint16_t)((uint16_t)((uint16_t)CAN->Page.RxFIFO.MIDR2 >> 2)&0x3F);
00789     
00790     _Id = (uint16_t)CAN_STDID_SIZE & (temp1 | temp2 );
00791   }
00792   
00793   _RTR = (uint8_t)((uint8_t)0x20 & CAN->Page.RxFIFO.MIDR1);
00794   
00795   /* Get the DLC */
00796   _DLC = (uint8_t)(CAN->Page.RxFIFO.MDLCR & (uint8_t)0x0F);
00797   
00798   /* Get the FMI */
00799   _FMI = CAN->Page.RxFIFO.MFMI;
00800   
00801   /* Get the data field */
00802   _Data[0] = CAN->Page.RxFIFO.MDAR1;
00803   _Data[1] = CAN->Page.RxFIFO.MDAR2;
00804   _Data[2] = CAN->Page.RxFIFO.MDAR3;
00805   _Data[3] = CAN->Page.RxFIFO.MDAR4;
00806   _Data[4] = CAN->Page.RxFIFO.MDAR5;
00807   _Data[5] = CAN->Page.RxFIFO.MDAR6;
00808   _Data[6] = CAN->Page.RxFIFO.MDAR7;
00809   _Data[7] = CAN->Page.RxFIFO.MDAR8;
00810   
00811   /* Release the FIFO */
00812   CAN_FIFORelease();
00813   /*Restore Last Page*/
00814   CAN_SelectPage(can_page);
00815 }
00816 
00817 /**
00818   * @brief  Gets the  CAN Id of the received message.
00819   * @param  None
00820   * @retval the received CAN message Id.
00821   * @par Required preconditions:
00822   * This function is used to get data loaded by CAN_Receive function.
00823   * Before using this function, CAN_Receive function must be called.
00824   */
00825 uint32_t CAN_GetReceivedId(void)
00826 {
00827   return (_Id);
00828 }
00829 
00830 /**
00831   * @brief  Gets the  CAN IDE of the received message.
00832   * @param  None
00833   * @retval the received CAN message IDE.
00834   * @par Required preconditions:
00835   * This function is used to get data loaded by CAN_Receive function.
00836   * Before using this function, CAN_Receive function must be called.
00837   */
00838 CAN_Id_TypeDef CAN_GetReceivedIDE(void)
00839 {
00840   return (CAN_Id_TypeDef)(_IDE);
00841 }
00842 
00843 /**
00844   * @brief  Gets the  CAN RTR of the received message.
00845   * @param  None
00846   * @retval the received CAN message RTR.
00847   * @par Required preconditions:
00848   * This function is used to get data loaded by CAN_Receive function.
00849   * Before using this function, CAN_Receive function must be called.
00850   */
00851 CAN_RTR_TypeDef CAN_GetReceivedRTR(void)
00852 {
00853   return (CAN_RTR_TypeDef)(_RTR);
00854 }
00855 
00856 /**
00857   * @brief  Gets the  CAN DLC of the received message.
00858   * @param  None
00859   * @retval the received CAN message DLC.
00860   * @par Required preconditions:
00861   * This function is used to get data loaded by CAN_Receive function.
00862   * Before using this function, CAN_Receive function must be called.
00863   */
00864 uint8_t CAN_GetReceivedDLC(void)
00865 {
00866   return (_DLC);
00867 }
00868 
00869 /**
00870   * @brief  Gets the  CAN Data of the received message.
00871   * @param   CAN_DataIndexe : number of the received Data, it can
00872   *  be an integer between 0 to 7.
00873   * @retval the received CAN message ith Data.
00874   * @par Required preconditions:
00875   * This function is used to get data loaded by CAN_Receive function.
00876   * Before using this function, CAN_Receive function must be called.
00877   */
00878 uint8_t CAN_GetReceivedData(uint8_t CAN_DataIndex)
00879 {
00880   assert_param(IS_CAN_DLC_OK(CAN_DataIndex));
00881   return (_Data[CAN_DataIndex]);
00882 }
00883 
00884 /**
00885   * @brief  Gets the  CAN FMI of the received message.
00886   * @param  None
00887   * @retval the received CAN message FMI.
00888   * @par Required preconditions:
00889   * This function is used to get data loaded by CAN_Receive function.
00890   * Before using this function, CAN_Receive function must be called.
00891   */
00892 uint8_t CAN_GetReceivedFMI(void)
00893 {
00894   return (_FMI);
00895 }
00896 
00897 /**
00898   * @brief  Returns the Received time stamp.
00899   * @param  None
00900   * @retval uint16_t the received  time stamp.
00901   */
00902 uint16_t CAN_GetMessageTimeStamp(void)
00903 {
00904   uint16_t timestamp = 0;
00905   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
00906   
00907   /*switch to the specific page */
00908   CAN->PSR = CAN_Page_RxFifo;
00909   /* Get the Received Time stamp */
00910   timestamp = CAN->Page.RxFIFO.MTSRL;
00911   timestamp |= (uint16_t)(((uint16_t)CAN->Page.RxFIFO.MTSRH)<<8);
00912   
00913   /*Restore Last Page*/
00914   CAN_SelectPage(can_page);
00915   
00916   return (uint16_t)(timestamp);
00917 }
00918 
00919 /**
00920   * @brief  Enters the Sleep low power mode.
00921   * @param  None
00922   * @retval  CAN_Sleep_Ok if sleep entered, CAN_Sleep_Failed in an other case.
00923   */
00924 CAN_Sleep_TypeDef CAN_Sleep(void)
00925 {
00926   CAN_Sleep_TypeDef sleepstatus = CAN_Sleep_Failed;
00927   
00928   /* Request Sleep mode */
00929   CAN->MCR = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
00930   
00931   /* Sleep mode status */
00932   if ((CAN->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
00933   {
00934     /* Sleep mode not entered */
00935     sleepstatus =  CAN_Sleep_Ok;
00936   }
00937   
00938   /* At this step, sleep mode status */
00939   return (CAN_Sleep_TypeDef) sleepstatus;
00940 }
00941 
00942 /**
00943   * @brief  Wakes the CAN up.
00944   * @param  None
00945   * @retval CAN_WakeUp_Ok if sleep mode left, CAN_WakeUp_Failed in an other  case.
00946   */
00947 CAN_WakeUp_TypeDef CAN_WakeUp(void)
00948 {
00949   CAN_WakeUp_TypeDef wakeupstatus = CAN_WakeUp_Failed;
00950   
00951   /* Wake up request */
00952   CAN->MCR &= (uint8_t)(~CAN_MCR_SLEEP);
00953   
00954   /* Sleep mode status */
00955   if ((CAN->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
00956   {
00957     /* Sleep mode exited */
00958     wakeupstatus = CAN_WakeUp_Ok;
00959   }
00960   
00961   /* At this step, sleep mode status */
00962   return (CAN_WakeUp_TypeDef)wakeupstatus;
00963 }
00964 
00965 /**
00966   * @brief  Select the CAN Operation mode.
00967   * @param  CAN_OperatingMode CAN Operating Mode ,
00968   *         this parameter can be one of @ref CAN_OperatingMode_TypeDef enumeration.
00969   * @retval the status of the requested mode which can be 
00970   *         - CAN_ModeStatus_Failed    CAN failed entring the specific mode
00971   *         - CAN_ModeStatus_Success  CAN Succeed entring the specific mode 
00972 
00973   */
00974 CAN_ModeStatus_TypeDef CAN_OperatingModeRequest(CAN_OperatingMode_TypeDef CAN_OperatingMode)
00975 {
00976   uint16_t timeout = CAN_ACKNOWLEDGE_TIMEOUT;
00977   uint8_t modestatus = 0;
00978   
00979   assert_param(IS_CAN_OPERATINGMODE_OK(CAN_OperatingMode));
00980   
00981   if (CAN_OperatingMode == CAN_OperatingMode_Initialization)
00982   {
00983     /* Request initialisation */
00984     CAN->MCR = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~CAN_MCR_SLEEP)) | CAN_MCR_INRQ);
00985     
00986     /* Wait the acknowledge */
00987     while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK) && (timeout != 0))
00988     {
00989       timeout--;
00990     }
00991     if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_INAK)
00992     {
00993       modestatus = CAN_ModeStatus_Failed;
00994     }
00995     else
00996     {
00997       modestatus = CAN_ModeStatus_Success;  
00998     }
00999     
01000   }
01001   else  if (CAN_OperatingMode == CAN_OperatingMode_Normal)
01002   {
01003     /* Request leave initialisation and sleep mode  and enter Normal mode */
01004     CAN->MCR &= (uint8_t)(~(CAN_MCR_SLEEP|CAN_MCR_INRQ));
01005     
01006     /* Wait the acknowledge */
01007     while (((CAN->MSR & CAN_MODE_MASK) != 0) && (timeout!=0))
01008     {
01009       timeout--;
01010     }
01011     if ((CAN->MSR & CAN_MODE_MASK) != 0)
01012     {
01013       modestatus = CAN_ModeStatus_Failed;
01014     }
01015     else
01016     {
01017       modestatus = CAN_ModeStatus_Success;  
01018     }
01019   }
01020   else  if (CAN_OperatingMode == CAN_OperatingMode_Sleep)
01021   {
01022     /* Request Sleep mode */
01023     CAN->MCR = (uint8_t)((uint8_t)(CAN->MCR & (uint8_t)(~CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
01024     
01025     /* Wait the acknowledge */
01026     while (((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK) && (timeout!=0))
01027     {
01028       timeout--;
01029     }
01030     if ((CAN->MSR & CAN_MODE_MASK) != CAN_MSR_SLAK)
01031     {
01032       modestatus = CAN_ModeStatus_Failed;  
01033     }
01034     else
01035     {
01036       modestatus = CAN_ModeStatus_Success;  
01037     }
01038   }
01039   else
01040   {
01041     modestatus = CAN_ModeStatus_Failed;
01042   }
01043   return (CAN_ModeStatus_TypeDef)(modestatus);
01044 }
01045 
01046 /**
01047   * @brief  Gets the  Last Error Code.
01048   * @param  None
01049   * @retval Error Code.
01050   */
01051 CAN_ErrorCode_TypeDef CAN_GetLastErrorCode(void)
01052 {
01053   CAN_ErrorCode_TypeDef errcode = CAN_ErrorCode_NoErr;
01054   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
01055   
01056   CAN->PSR = CAN_Page_Config;
01057   errcode = (CAN_ErrorCode_TypeDef)((CAN->Page.Config.ESR) & (CAN_ESR_LEC));
01058   
01059   /*Restore Last Page*/
01060   CAN_SelectPage(can_page);
01061   
01062   return (CAN_ErrorCode_TypeDef)(errcode);
01063 }
01064 
01065 /**
01066   * @brief  Clears the CAN's pending flags.
01067   * @param   CAN_FLAG : Flag to be cleared, can be one of the following parameters:
01068   *          CAN_FLAG_RQCP0            Request MailBox0  Flag
01069   *          CAN_FLAG_RQCP1            Request MailBox1  Flag
01070   *          CAN_FLAG_RQCP2            Request MailBox2  Flag
01071   *       CAN_FLAG_FF               FIFO Full  Flag
01072   *       CAN_FLAG_FOV              FIFO Overrun  Flag
01073   *       CAN_FLAG_WKU              wake up   Flag
01074   *          CAN_FLAG_LEC               Last error code Flag
01075   * @retval None
01076   */
01077 void CAN_ClearFlag(CAN_FLAG_TypeDef CAN_Flag)
01078 {
01079   CAN_Page_TypeDef can_page = (CAN_Page_TypeDef)0;
01080   /* Check the parameters */
01081   assert_param(IS_CAN_FLAG_CLEAR_OK(CAN_Flag));
01082   if (((uint16_t)CAN_Flag & 0x0700)!= RESET)
01083   {
01084     if (((uint16_t)CAN_Flag & 0x020B)!= RESET)
01085     {
01086       /*Receive Flags*/
01087       CAN->RFR = (uint8_t)(CAN_Flag);
01088     }
01089     else if (((uint16_t)CAN_Flag & 0x0403)!= RESET)
01090     {
01091       /*Transmit Flags*/
01092       CAN->TSR = (uint8_t)(CAN_Flag);
01093     }
01094     else /*if((CAN_Flag & 0x0108)!=(uint16_t)RESET)*/
01095     {
01096       /*wake up Flags*/
01097       CAN->MSR = (uint8_t)(CAN_Flag);
01098     }
01099   }
01100   else
01101   {
01102     /*Error Flags*/
01103     can_page = CAN_GetSelectedPage();
01104     
01105     /* Clear the selected CAN flags */
01106     CAN->PSR = CAN_Page_Config;
01107     CAN->Page.Config.ESR = (uint8_t)RESET;
01108     
01109     /*Restore Last Page*/
01110     CAN_SelectPage(can_page);
01111   }
01112 }
01113 
01114 /**
01115   * @brief  Checks whether the specified CAN flag is set or not.
01116   * @param   CAN_FLAG: specifies the flag to check, can be one of @ref CAN_FLAG_TypeDef enumeration.
01117   * @retval The new state of CAN_FLAG which can be one of @ref FlagStatus.
01118   */
01119 FlagStatus CAN_GetFlagStatus(CAN_FLAG_TypeDef CAN_Flag)
01120 {
01121   FlagStatus bitstatus = RESET;
01122   CAN_Page_TypeDef can_page = (CAN_Page_TypeDef)0;
01123   
01124   /* Check the parameters */
01125   assert_param(IS_CAN_FLAG_STATUS_OK(CAN_Flag));
01126   
01127   if (((uint16_t)CAN_Flag & 0x0700)!= RESET)
01128   {
01129     if (((uint16_t)CAN_Flag & 0x020B)!= RESET)
01130     {
01131       /*Receive Flags*/
01132       if ((CAN->RFR & (uint16_t)CAN_Flag )!= RESET)
01133       {
01134         /* CAN_FLAG is set */
01135         bitstatus = SET;
01136       }
01137       else
01138       {
01139         /* CAN_FLAG is reset */
01140         bitstatus = RESET;
01141       }
01142       
01143     }
01144     else if (((uint16_t)CAN_Flag & 0x0403)!= RESET)
01145     {
01146       /*Transmit Flags*/
01147       if ((CAN->TSR & (uint16_t)CAN_Flag )!= RESET)
01148       {
01149         /* CAN_FLAG is set */
01150         bitstatus = SET;
01151       }
01152       else
01153       {
01154         /* CAN_FLAG is reset */
01155         bitstatus = RESET;
01156       }
01157     }
01158     else /*if((CAN_Flag & 0x0108)!=(uint16_t)RESET)*/
01159     {
01160       /*wake up Flags*/
01161       if ((CAN->MSR & (uint16_t)CAN_Flag )!= RESET)
01162       {
01163         /* CAN_FLAG is set */
01164         bitstatus = SET;
01165       }
01166       else
01167       {
01168         /* CAN_FLAG is reset */
01169         bitstatus = RESET;
01170       }
01171     }
01172   }
01173   else
01174   {
01175     /*Error Flags*/
01176     can_page = CAN_GetSelectedPage();
01177     
01178     CAN->PSR = CAN_Page_Config;
01179     if ((CAN->Page.Config.ESR & (uint16_t)CAN_Flag) != RESET)
01180     {
01181       /* CAN_FLAG is set */
01182       bitstatus = SET;
01183     }
01184     else
01185     {
01186       /* CAN_FLAG is reset */
01187       bitstatus = RESET;
01188     }
01189     /*Restore Last Page*/
01190     CAN_SelectPage(can_page);
01191   }
01192   
01193   
01194   /* Return the CAN_FLAG status */
01195   return  (FlagStatus)bitstatus;
01196 }
01197 
01198 /**
01199   * @brief  Checks whether the specified CAN interrupt has occurred or not.
01200   * @param   CAN_IT: specifies the CAN interrupt source to check, can be one of @ref CAN_IT_TypeDef.
01201   * @retval The new state of CAN_IT, which can be one of @ref ITStatus.
01202   */
01203 ITStatus CAN_GetITStatus(CAN_IT_TypeDef CAN_IT)
01204 {
01205   ITStatus pendingbitstatus = RESET;
01206   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
01207   
01208   /* Check the parameters */
01209   assert_param(IS_CAN_IT_STATUS_OK(CAN_IT));
01210   
01211   
01212   switch (CAN_IT)
01213   {
01214   case CAN_IT_TME:
01215     if ((CAN->IER & CAN_IER_TMEIE) !=RESET)
01216     {
01217       pendingbitstatus = CheckITStatus(CAN->TSR, CAN_TSR_RQCP012);
01218     }
01219     else
01220     {
01221       pendingbitstatus = RESET;
01222     }
01223     break;
01224     
01225   case CAN_IT_FMP:
01226     if ((CAN->IER & CAN_IER_FMPIE) !=RESET)
01227     {
01228       pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FMP01);
01229     }
01230     else
01231     {
01232       pendingbitstatus = RESET;
01233     }
01234     break;
01235   case CAN_IT_FF:
01236     if ((CAN->IER & CAN_IER_FFIE) !=RESET)
01237     {
01238       pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FULL);
01239     }
01240     else
01241     {
01242       pendingbitstatus = RESET;
01243     }
01244     break;
01245   case CAN_IT_FOV:
01246     if ((CAN->IER & CAN_IER_FOVIE) !=RESET)
01247     {
01248       pendingbitstatus = CheckITStatus(CAN->RFR, CAN_RFR_FOVR);
01249     }
01250     else
01251     {
01252       pendingbitstatus = RESET;
01253     }
01254     break;
01255   case CAN_IT_WKU:
01256     if ((CAN->IER & CAN_IER_WKUIE) !=RESET)
01257     {
01258       pendingbitstatus = CheckITStatus(CAN->MSR, CAN_MSR_WKUI);
01259     }
01260     else
01261     {
01262       pendingbitstatus = RESET;
01263     }
01264     break;
01265     
01266   case CAN_IT_ERR:
01267     CAN->PSR = CAN_Page_Config;
01268     if ((CAN->Page.Config.EIER & CAN_EIER_ERRIE) !=RESET)
01269     {
01270       pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF|CAN_ESR_EPVF|CAN_ESR_BOFF|CAN_ESR_LEC);
01271     }
01272     else
01273     {
01274       pendingbitstatus = RESET;
01275     }
01276     break;
01277     
01278   case CAN_IT_EWG:
01279     CAN->PSR = CAN_Page_Config;
01280     if ((CAN->Page.Config.EIER & CAN_EIER_EWGIE) !=RESET)
01281     {
01282       pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EWGF);
01283     }
01284     else
01285     {
01286       pendingbitstatus = RESET;
01287     }
01288     break;
01289     
01290   case CAN_IT_EPV:
01291     CAN->PSR = CAN_Page_Config;
01292     if ((CAN->Page.Config.EIER & CAN_EIER_EPVIE) !=RESET)
01293     {
01294       pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_EPVF);
01295     }
01296     else
01297     {
01298       pendingbitstatus = RESET;
01299     }
01300     break;
01301   case CAN_IT_BOF:
01302     CAN->PSR = CAN_Page_Config;
01303     if ((CAN->Page.Config.EIER & CAN_EIER_BOFIE) !=RESET)
01304     {
01305       pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_BOFF);
01306     }
01307     else
01308     {
01309       pendingbitstatus = RESET;
01310     }
01311     break;
01312   case CAN_IT_LEC:
01313     CAN->PSR = CAN_Page_Config;
01314     if ((CAN->Page.Config.EIER & CAN_EIER_LECIE) !=RESET)
01315     {
01316       pendingbitstatus = CheckITStatus(CAN->Page.Config.ESR, CAN_ESR_LEC);
01317     }
01318     else
01319     {
01320       pendingbitstatus = RESET;
01321     }
01322     break;
01323   default :
01324     pendingbitstatus = RESET;
01325     break;
01326   }
01327   /*Restore Last Page*/
01328   CAN_SelectPage(can_page);
01329   /* Return the CAN_IT status */
01330   return  (ITStatus)pendingbitstatus;
01331 }
01332 
01333 /**
01334   * @brief   Clears the CAN�s interrupt pending bits.
01335   * @param   CAN_IT: specifies the interrupt pending bit to clear,
01336   *  can be one of the following parameters:
01337   *                            CAN_IT_TME = Transmit mailbox empty interrupt
01338   *                             CAN_IT_FF =FIFO  full    interrupt
01339   *                            CAN_IT_FOV =FIFO  overrun  interrupt
01340   *                             CAN_IT_WKU =Wake-up interrupt
01341   *                             CAN_IT_ERR =General Error interrupt
01342   *                             CAN_IT_EWG =Error warning interrupt
01343   *                             CAN_IT_EPV  =Error passive  interrupt
01344   *                             CAN_IT_BOF = Bus-off   interrupt
01345   *                             CAN_IT_LEC  =Last error code interrupt
01346   * @retval None
01347   */
01348 void CAN_ClearITPendingBit(CAN_IT_TypeDef CAN_IT)
01349 {
01350   CAN_Page_TypeDef can_page = CAN_GetSelectedPage();
01351   /* Check the parameters */
01352   assert_param(IS_CAN_IT_PENDING_BIT_OK(CAN_IT));
01353   
01354   switch (CAN_IT)
01355   {
01356   case CAN_IT_TME:
01357     CAN->TSR = CAN_TSR_RQCP012;/* rc_w1*/
01358     break;
01359     
01360   case CAN_IT_FF:
01361     CAN->RFR = CAN_RFR_FULL; /* rc_w1*/
01362     break;
01363     
01364   case CAN_IT_FOV:
01365     CAN->RFR = CAN_RFR_FOVR; /* rc_w1*/
01366     break;
01367     
01368   case CAN_IT_WKU:
01369     CAN->MSR = CAN_MSR_WKUI;  /* rc_w1*/
01370     break;
01371     
01372   case CAN_IT_ERR:
01373     CAN->PSR = CAN_Page_Config;
01374     CAN->Page.Config.ESR = (uint8_t)CAN_ESR_RESET_VALUE;
01375     CAN->MSR = CAN_MSR_ERRI;
01376     break;
01377     
01378   case CAN_IT_EWG:
01379     CAN->MSR = CAN_MSR_ERRI;
01380     break;
01381     
01382   case CAN_IT_EPV:
01383     CAN->MSR = CAN_MSR_ERRI;
01384     break;
01385     
01386   case CAN_IT_BOF:
01387     CAN->MSR = CAN_MSR_ERRI;
01388     break;
01389     
01390   case CAN_IT_LEC:
01391     CAN->PSR = CAN_Page_Config;
01392     CAN->Page.Config.ESR = (uint8_t)CAN_ESR_RESET_VALUE;
01393     break;
01394 
01395   default :
01396     break;
01397   }
01398   /*Restore Last Page*/
01399   CAN_SelectPage(can_page);
01400 }
01401 
01402 /**
01403   * @brief  Gets the selected registers page.
01404   * @param  None
01405   * @retval the selected page which can be one of the @ref CAN_Page_TypeDef.
01406   */
01407 CAN_Page_TypeDef CAN_GetSelectedPage(void)
01408 {
01409   return (CAN_Page_TypeDef)(CAN->PSR);
01410 }
01411 
01412 /**
01413   * @brief  Sets the registers page to be selected.
01414   * @param   the selected page which can be one of the @ref CAN_Page_TypeDef.
01415   * @retval None
01416   */
01417 void CAN_SelectPage(CAN_Page_TypeDef CAN_Page)
01418 {
01419   CAN->PSR = (uint8_t)CAN_Page;
01420 }
01421 
01422 /**
01423   * @brief  Checks whether the CAN interrupt has occurred or not.
01424   * @param   CAN_Reg: specifies the CAN interrupt register to check.
01425   * @param   It_Bit: specifies the interrupt source bit to check.
01426   * @retval The new state of the CAN Interrupt, which can be one of ITStatus.
01427   */
01428 static ITStatus CheckITStatus(uint8_t CAN_Reg, uint8_t It_Bit)
01429 {
01430   ITStatus pendingbitstatus = RESET;
01431   if ((CAN_Reg & It_Bit) != (uint8_t)RESET)
01432   {
01433     /* CAN_IT is set */
01434     pendingbitstatus = SET;
01435   }
01436   else
01437   {
01438     /* CAN_IT is reset */
01439     pendingbitstatus = RESET;
01440   }
01441   return (ITStatus)pendingbitstatus;
01442 }
01443 
01444 
01445 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
STM8 Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM8 8-bit Microcontrollers platform visit www.st.com