STM8S/A Standard Peripherals Drivers
|
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.3.0 00006 * @date 16-June-2017 00007 * @brief This file contains all the functions for the CAN peripheral. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© 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 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 CAN_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 CAN_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, data 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_DataIndex : 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 entering the specific mode 00971 * - CAN_ModeStatus_Success CAN Succeed entering 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 CAN_Page: 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 * @} 01446 */ 01447 01448 /** 01449 * @} 01450 */ 01451 01452 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/