1 /*! 2 * @file apm32f0xx_can.c 3 * 4 * @brief This file contains all the functions for the CAN peripheral 5 * 6 * @version V1.0.3 7 * 8 * @date 2022-09-20 9 * 10 * @attention 11 * 12 * Copyright (C) 2020-2022 Geehy Semiconductor 13 * 14 * You may not use this file except in compliance with the 15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE). 16 * 17 * The program is only for reference, which is distributed in the hope 18 * that it will be useful and instructional for customers to develop 19 * their software. Unless required by applicable law or agreed to in 20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT 21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions 23 * and limitations under the License. 24 */ 25 26 /* include */ 27 #include "apm32f0xx_can.h" 28 #include "apm32f0xx_rcm.h" 29 30 /** @addtogroup APM32F0xx_StdPeriphDriver 31 @{ 32 */ 33 34 /** @addtogroup CAN_Driver 35 @{ 36 */ 37 38 /** @defgroup CAN_Macros Macros 39 @{ 40 */ 41 42 /**@} end of group CAN_Macros */ 43 44 /** @defgroup CAN_Enumerations Enumerations 45 @{ 46 */ 47 48 /**@} end of group CAN_Enumerations */ 49 50 /** @defgroup CAN_Structures Structures 51 @{ 52 */ 53 54 /**@} end of group CAN_Structures */ 55 56 /** @defgroup CAN_Variables Variables 57 @{ 58 */ 59 60 /**@} end of group CAN_Variables */ 61 62 /** @defgroup CAN_Functions Functions 63 @{ 64 */ 65 66 /*! 67 * @brief Reset CAN peripheral registers to their default values. 68 * 69 * @param None 70 * 71 * @retval None 72 * 73 */ CAN_Reset(void)74void CAN_Reset(void) 75 { 76 RCM_EnableAPB1PeriphReset(RCM_APB1_PERIPH_CAN); 77 RCM_DisableAPB1PeriphReset(RCM_APB1_PERIPH_CAN); 78 } 79 80 /*! 81 * @brief Congfig the CAN peripheral using the specified parameters in the canConfig. 82 * 83 * @param canConfig : pointer to a CAN_Config_T structure that contains 84 * the configuration information for the CAN peripheral. 85 * 86 * @retval Configuration status (SET or RESET) 87 */ CAN_Config(CAN_Config_T * canConfig)88uint8_t CAN_Config(CAN_Config_T* canConfig) 89 { 90 uint8_t InitStatus = RESET; 91 uint32_t ackWait = 0x00000000; 92 93 CAN->MCTRL_B.SLEEPREQ = BIT_RESET; 94 95 CAN->MCTRL_B.INITREQ = BIT_SET; 96 97 while ((CAN->MSTS_B.INITFLG != BIT_SET) && (ackWait != (uint32_t)0x00FFFFFF)) 98 { 99 ackWait++; 100 } 101 102 if (CAN->MSTS_B.INITFLG != BIT_SET) 103 { 104 InitStatus = RESET; 105 } 106 else 107 { 108 if (canConfig->timeTrigComMode == ENABLE) 109 { 110 CAN->MCTRL_B.TTCM = BIT_SET; 111 } 112 else 113 { 114 CAN->MCTRL_B.TTCM = BIT_RESET; 115 } 116 117 if (canConfig->autoBusOffManage == ENABLE) 118 { 119 CAN->MCTRL_B.ALBOFFM = BIT_SET; 120 } 121 else 122 { 123 CAN->MCTRL_B.ALBOFFM = BIT_RESET; 124 } 125 126 if (canConfig->autoWakeUpMode == ENABLE) 127 { 128 CAN->MCTRL_B.AWUPCFG = BIT_SET; 129 } 130 else 131 { 132 CAN->MCTRL_B.AWUPCFG = BIT_RESET; 133 } 134 135 if (canConfig->nonAutoRetran == ENABLE) 136 { 137 CAN->MCTRL_B.ARTXMD = BIT_SET; 138 } 139 else 140 { 141 CAN->MCTRL_B.ARTXMD = BIT_RESET; 142 } 143 144 if (canConfig->rxFIFOLockMode == ENABLE) 145 { 146 CAN->MCTRL_B.RXFLOCK = BIT_SET; 147 } 148 else 149 { 150 CAN->MCTRL_B.RXFLOCK = BIT_RESET; 151 } 152 153 if (canConfig->txFIFOPriority == ENABLE) 154 { 155 CAN->MCTRL_B.TXFPCFG = BIT_SET; 156 } 157 else 158 { 159 CAN->MCTRL_B.TXFPCFG = BIT_RESET; 160 } 161 162 CAN->BITTIM = (uint32_t)canConfig->mode << 30; 163 CAN->BITTIM_B.RSYNJW = canConfig->syncJumpWidth; 164 CAN->BITTIM_B.TIMSEG1 = canConfig->timeSegment1; 165 CAN->BITTIM_B.TIMSEG2 = canConfig->timeSegment2; 166 CAN->BITTIM_B.BRPSC = canConfig->prescaler - 1; 167 168 CAN->MCTRL_B.INITREQ = BIT_RESET; 169 170 ackWait = 0x00000000; 171 172 while ((CAN->MSTS_B.INITFLG == BIT_SET) && (ackWait != (uint32_t)0x00FFFFFF)) 173 { 174 ackWait++; 175 } 176 177 if (CAN->MSTS_B.INITFLG == BIT_RESET) 178 { 179 InitStatus = SET; 180 } 181 else 182 { 183 InitStatus = RESET; 184 } 185 } 186 return InitStatus; 187 } 188 189 /*! 190 * @brief Congfig the CAN filter according to the specified parameters in the filterConfig. 191 * 192 * @param filterConfig: pointer to a CAN_Filter_Config_T structure that 193 * contains the configuration information. 194 * 195 * @retval None 196 */ CAN_ConfigFilter(CAN_FilterConfig_T * filterConfig)197void CAN_ConfigFilter(CAN_FilterConfig_T* filterConfig) 198 { 199 uint16_t filterNumber = 0; 200 201 filterNumber = BIT0 << filterConfig->filterNumber; 202 203 CAN->FCTRL_B.FIM = BIT_SET; 204 205 CAN->FACT &= ~filterNumber; 206 207 if (filterConfig->filterScale == CAN_FILTER_SCALE_16BIT) 208 { 209 CAN->FSCFG &= ~filterNumber; 210 211 CAN->sFilterRegister[filterConfig->filterNumber].R1 = 212 ((0x0000FFFF & filterConfig->filterMaskIdLow) << 16) | 213 (0x0000FFFF & filterConfig->filterIdLow); 214 215 CAN->sFilterRegister[filterConfig->filterNumber].R2 = 216 ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) | 217 (0x0000FFFF & filterConfig->filterIdHigh); 218 } 219 220 if (filterConfig->filterScale == CAN_FILTER_SCALE_32BIT) 221 { 222 CAN->FSCFG |= filterNumber; 223 224 CAN->sFilterRegister[filterConfig->filterNumber].R1 = 225 ((0x0000FFFF & filterConfig->filterIdHigh) << 16) | 226 (0x0000FFFF & filterConfig->filterIdLow); 227 228 CAN->sFilterRegister[filterConfig->filterNumber].R2 = 229 ((0x0000FFFF & filterConfig->filterMaskIdHigh) << 16) | 230 (0x0000FFFF & filterConfig->filterMaskIdLow); 231 } 232 233 if (filterConfig->filterMode == CAN_FILTER_MODE_IDMASK) 234 { 235 CAN->FMCFG &= ~filterNumber; 236 } 237 else 238 { 239 CAN->FMCFG |= filterNumber; 240 } 241 242 if (filterConfig->filterFIFO == CAN_FIFO_0) 243 { 244 CAN->FFASS &= ~filterNumber; 245 } 246 else 247 { 248 CAN->FFASS |= filterNumber; 249 } 250 251 if (filterConfig->filterActivation == ENABLE) 252 { 253 CAN->FACT |= filterNumber; 254 } 255 256 CAN->FCTRL_B.FIM = BIT_RESET; 257 } 258 259 /*! 260 * @brief Fills each canConfig member with its default value. 261 * 262 * @param canConfig : Pointer to a CAN_Config_T structure which is used for configuration. 263 * 264 * @retval None 265 */ CAN_ConfigStructInit(CAN_Config_T * canConfig)266void CAN_ConfigStructInit(CAN_Config_T* canConfig) 267 { 268 canConfig->timeTrigComMode = DISABLE; 269 270 canConfig->autoBusOffManage = DISABLE; 271 272 canConfig->autoWakeUpMode = DISABLE; 273 274 canConfig->nonAutoRetran = DISABLE; 275 276 canConfig->rxFIFOLockMode = DISABLE; 277 278 canConfig->txFIFOPriority = DISABLE; 279 280 canConfig->mode = CAN_MODE_NORMAL; 281 282 canConfig->syncJumpWidth = CAN_SJW_1; 283 284 canConfig->timeSegment1 = CAN_TIME_SEGMENT1_4; 285 286 canConfig->timeSegment2 = CAN_TIME_SEGMENT2_3; 287 288 canConfig->prescaler = 1; 289 } 290 291 /*! 292 * @brief Select the start bank filter for slave CAN. 293 * 294 * @param bankNumber:Select the start slave bank filter from 1 to 27. 295 * 296 * @retval None 297 * 298 * @note This function applies only to APM32 Connectivity line devices. 299 */ CAN_StartBankSlave(uint8_t bankNumber)300void CAN_StartBankSlave(uint8_t bankNumber) 301 { 302 CAN->FCTRL_B.FIM = BIT_SET; 303 304 CAN->FCTRL &= 0xFFFFC0F1; 305 CAN->FCTRL |= (uint32_t)(bankNumber) << 8; 306 307 CAN->FCTRL_B.FIM = BIT_RESET; 308 } 309 310 /*! 311 * @brief Enable the Debug Freeze mdoe for CAN. 312 * 313 * @param None 314 * 315 * @retval None 316 */ CAN_EnableDebugFreeze(void)317void CAN_EnableDebugFreeze(void) 318 { 319 CAN->MCTRL_B.DBGFRZE = BIT_SET; 320 } 321 322 /*! 323 * @brief Disable the Debug Freeze mode for CAN. 324 * 325 * @param None 326 * 327 * @retval None 328 */ CAN_DisableDebugFreeze(void)329void CAN_DisableDebugFreeze(void) 330 { 331 CAN->MCTRL_B.DBGFRZE = BIT_RESET; 332 } 333 334 /*! 335 * @brief Enables the Time Triggered Communication mode for CAN. 336 * 337 * @param None 338 * 339 * @retval None 340 */ CAN_EnableTTComMode(void)341void CAN_EnableTTComMode(void) 342 { 343 CAN->MCTRL_B.TTCM = BIT_SET; 344 345 CAN->sTxMailBox[0].TXDLEN_B.TXGT = BIT_SET; 346 CAN->sTxMailBox[1].TXDLEN_B.TXGT = BIT_SET; 347 CAN->sTxMailBox[2].TXDLEN_B.TXGT = BIT_SET; 348 } 349 350 /*! 351 * @brief Disables the Time Triggered Communication mode for CAN. 352 * 353 * @param None 354 * 355 * @retval None 356 */ CAN_DisableTTComMode(void)357void CAN_DisableTTComMode(void) 358 { 359 CAN->MCTRL_B.TTCM = BIT_RESET; 360 361 CAN->sTxMailBox[0].TXDLEN_B.TXGT = BIT_RESET; 362 CAN->sTxMailBox[1].TXDLEN_B.TXGT = BIT_RESET; 363 CAN->sTxMailBox[2].TXDLEN_B.TXGT = BIT_RESET; 364 } 365 366 /*! 367 * @brief Transmit a message from TxMessage of CAN_Tx_Message structure. 368 * 369 * @param TxMessage : Pointer to a structure which contains CAN Id, CAN DLCODE and CAN data. 370 * 371 * @retval Returns the number of the transmit mailbox state.It can be one of value: 372 * @arg 0: Transmit mailbox 0 373 * @arg 1: Transmit mailbox 1 374 * @arg 2: Transmit mailbox 2 375 * @arg 4: There is no empty mailbox 376 */ CAN_TxMessage(CAN_Tx_Message * TxMessage)377uint8_t CAN_TxMessage(CAN_Tx_Message* TxMessage) 378 { 379 uint8_t TxMailbox = 0; 380 381 if ((CAN->TXSTS_B.TXMEFLG0 == BIT_SET)) 382 { 383 TxMailbox = 0; 384 } 385 else if ((CAN->TXSTS_B.TXMEFLG1 == BIT_SET)) 386 { 387 TxMailbox = 1; 388 } 389 else if ((CAN->TXSTS_B.TXMEFLG2 == BIT_SET)) 390 { 391 TxMailbox = 2; 392 } 393 else 394 { 395 TxMailbox = CAN_TX_MAILBOX_FULL; 396 } 397 398 if (TxMailbox != CAN_TX_MAILBOX_FULL) 399 { 400 /* Set up the Id */ 401 CAN->sTxMailBox[TxMailbox].TXMID &= BIT0; 402 if (TxMessage->typeID == CAN_TYPEID_STD) 403 { 404 CAN->sTxMailBox[TxMailbox].TXMID |= (((uint32_t)TxMessage->stanID << 21) | \ 405 TxMessage->typeID | \ 406 TxMessage->remoteTxReq); 407 } 408 else 409 { 410 CAN->sTxMailBox[TxMailbox].TXMID |= (((uint32_t)TxMessage->extenID << 3) | \ 411 TxMessage->typeID | \ 412 TxMessage->remoteTxReq); 413 } 414 415 /* Set up the DLCODE */ 416 CAN->sTxMailBox[TxMailbox].TXDLEN_B.DLCODE = (TxMessage->dataLengthCode & 0x0F); 417 418 /* Set up the data field */ 419 CAN->sTxMailBox[TxMailbox].TXMDH_B.DATABYTE7 = TxMessage->data[7]; 420 CAN->sTxMailBox[TxMailbox].TXMDH_B.DATABYTE6 = TxMessage->data[6]; 421 CAN->sTxMailBox[TxMailbox].TXMDH_B.DATABYTE5 = TxMessage->data[5]; 422 CAN->sTxMailBox[TxMailbox].TXMDH_B.DATABYTE4 = TxMessage->data[4]; 423 424 CAN->sTxMailBox[TxMailbox].TXMDL_B.DATABYTE3 = TxMessage->data[3]; 425 CAN->sTxMailBox[TxMailbox].TXMDL_B.DATABYTE2 = TxMessage->data[2]; 426 CAN->sTxMailBox[TxMailbox].TXMDL_B.DATABYTE1 = TxMessage->data[1]; 427 CAN->sTxMailBox[TxMailbox].TXMDL_B.DATABYTE0 = TxMessage->data[0]; 428 429 /* Request transmission */ 430 CAN->sTxMailBox[TxMailbox].TXMID |= BIT0; 431 } 432 433 return TxMailbox; 434 } 435 436 /*! 437 * @brief Reads the status of a transmission. 438 * 439 * @param TxMailbox: the number of the mailbox 440 * This parameter can be one of the following values: 441 * @arg CAN_MAILBOX_0 : Transmit mailbox 0 442 * @arg CAN_MAILBOX_1 : Transmit mailbox 1 443 * @arg CAN_MAILBOX_2 : Transmit mailbox 2 444 * 445 * @retval Returns the transmission state. 446 * It can be one of the following values: 447 * @arg CAN_TX_FAILED 448 * @arg CAN_TX_OK 449 * @arg CAN_TX_WAITING 450 */ CAN_TxMessageStatus(CAN_MAILBOX_T TxMailbox)451uint8_t CAN_TxMessageStatus(CAN_MAILBOX_T TxMailbox) 452 { 453 uint8_t state = CAN_TX_FAILED; 454 455 switch (TxMailbox) 456 { 457 case (CAN_MAILBOX_0): 458 if (CAN->TXSTS_B.REQCFLG0 && CAN->TXSTS_B.TXSUSFLG0 && CAN->TXSTS_B.TXMEFLG0) 459 { 460 state = CAN_TX_OK; 461 } 462 else if (!(CAN->TXSTS_B.REQCFLG0 || CAN->TXSTS_B.TXSUSFLG0 || CAN->TXSTS_B.TXMEFLG0)) 463 { 464 state = CAN_TX_WAITING; 465 } 466 break; 467 468 case (CAN_MAILBOX_1): 469 if (CAN->TXSTS_B.REQCFLG1 && CAN->TXSTS_B.TXSUSFLG1 && CAN->TXSTS_B.TXMEFLG1) 470 { 471 state = CAN_TX_OK; 472 } 473 else if (!(CAN->TXSTS_B.REQCFLG1 || CAN->TXSTS_B.TXSUSFLG1 || CAN->TXSTS_B.TXMEFLG1)) 474 { 475 state = CAN_TX_WAITING; 476 } 477 break; 478 479 case (CAN_MAILBOX_2): 480 if (CAN->TXSTS_B.REQCFLG2 && CAN->TXSTS_B.TXSUSFLG2 && CAN->TXSTS_B.TXMEFLG2) 481 { 482 state = CAN_TX_OK; 483 } 484 else if (!(CAN->TXSTS_B.REQCFLG2 || CAN->TXSTS_B.TXSUSFLG2 || CAN->TXSTS_B.TXMEFLG2)) 485 { 486 state = CAN_TX_WAITING; 487 } 488 break; 489 490 default: 491 break; 492 } 493 494 return state; 495 } 496 497 /*! 498 * @brief Cancels a transmit request. 499 * 500 * @param TxMailbox: the number of the mailbox 501 * This parameter can be one of the following values: 502 * @arg CAN_MAILBOX_0 : Abort transmission request for mailbox 0 503 * @arg CAN_MAILBOX_1 : Abort transmission request for mailbox 1 504 * @arg CAN_MAILBOX_2 : Abort transmission request for mailbox 2 505 * 506 * @retval None 507 */ CAN_CancelTx(CAN_MAILBOX_T TxMailbox)508void CAN_CancelTx(CAN_MAILBOX_T TxMailbox) 509 { 510 switch (TxMailbox) 511 { 512 case 0: 513 CAN->TXSTS_B.ABREQFLG0 = BIT_SET; 514 break; 515 516 case 1: 517 CAN->TXSTS_B.ABREQFLG1 = BIT_SET; 518 break; 519 520 case 2: 521 CAN->TXSTS_B.ABREQFLG2 = BIT_SET; 522 break; 523 524 default: 525 break; 526 } 527 } 528 529 /*! 530 * @brief Receive a valid message through the filter. 531 * 532 * @param FIFONumber: The number of Receive FIFO 533 * This parameter can be one of the following values: 534 * @arg CAN_FIFO_0 : CAN FIFO 0 used to receive 535 * @arg CAN_FIFO_1 : CAN FIFO 1 used to receive 536 * 537 * @param RxMessage : pointer to a structure that is used to receive message 538 * 539 * @retval None 540 */ CAN_RxMessage(uint8_t FIFONumber,CAN_Rx_Message * RxMessage)541void CAN_RxMessage(uint8_t FIFONumber, CAN_Rx_Message* RxMessage) 542 { 543 RxMessage->typeID = (CAN_TYPEID_T)(BIT2 & CAN->sRxFIFO[FIFONumber].RXMID); 544 545 if (RxMessage->typeID == CAN_TYPEID_STD) 546 { 547 RxMessage->stanID = CAN->sRxFIFO[FIFONumber].RXMID_B.STDID; 548 } 549 else 550 { 551 RxMessage->extenID = (CAN->sRxFIFO[FIFONumber].RXMID_B.STDID << 18); 552 RxMessage->extenID |= CAN->sRxFIFO[FIFONumber].RXMID_B.EXTID; 553 } 554 555 RxMessage->remoteTxReq = (CAN_RTXR_T)(BIT1 & CAN->sRxFIFO[FIFONumber].RXMID); 556 RxMessage->dataLengthCode = CAN->sRxFIFO[FIFONumber].RXDLEN_B.DLCODE; 557 RxMessage->filterMatchIndex = CAN->sRxFIFO[FIFONumber].RXDLEN_B.FMIDX; 558 559 RxMessage->data[7] = CAN->sRxFIFO[FIFONumber].RXMDH_B.DATABYTE7; 560 RxMessage->data[6] = CAN->sRxFIFO[FIFONumber].RXMDH_B.DATABYTE6; 561 RxMessage->data[5] = CAN->sRxFIFO[FIFONumber].RXMDH_B.DATABYTE5; 562 RxMessage->data[4] = CAN->sRxFIFO[FIFONumber].RXMDH_B.DATABYTE4; 563 564 RxMessage->data[3] = CAN->sRxFIFO[FIFONumber].RXMDL_B.DATABYTE3; 565 RxMessage->data[2] = CAN->sRxFIFO[FIFONumber].RXMDL_B.DATABYTE2; 566 RxMessage->data[1] = CAN->sRxFIFO[FIFONumber].RXMDL_B.DATABYTE1; 567 RxMessage->data[0] = CAN->sRxFIFO[FIFONumber].RXMDL_B.DATABYTE0; 568 569 if (FIFONumber == CAN_FIFO_0) 570 { 571 CAN->RXF0_B.RFOM0 = BIT_SET; 572 } 573 else 574 { 575 CAN->RXF1_B.RFOM1 = BIT_SET; 576 } 577 } 578 579 /*! 580 * @brief Releases the specified receive FIFO. 581 * 582 * @param FIFONumber : the number of receive FIFO 583 * This parameter can be one of the following values: 584 * @arg CAN_FIFO_0 : CAN FIFO 0 used to receive 585 * @arg CAN_FIFO_1 : CAN FIFO 1 used to receive 586 * 587 * @retval None 588 */ CAN_ReleaseFIFO(uint8_t FIFONumber)589void CAN_ReleaseFIFO(uint8_t FIFONumber) 590 { 591 if (FIFONumber == CAN_FIFO_0) 592 { 593 CAN->RXF0_B.RFOM0 = BIT_SET; 594 } 595 else 596 { 597 CAN->RXF1_B.RFOM1 = BIT_SET; 598 } 599 } 600 601 /*! 602 * @brief Reads the number of pending messages. 603 * 604 * @param FIFONumber : the number of receive FIFO 605 * This parameter can be one of the following values: 606 * @arg CAN_FIFO_0 : CAN FIFO 0 used to receive 607 * @arg CAN_FIFO_1 : CAN FIFO 1 used to receive 608 * 609 * @retval which is the number of pending message. 610 */ CAN_PendingMessage(uint8_t FIFONumber)611uint8_t CAN_PendingMessage(uint8_t FIFONumber) 612 { 613 if (FIFONumber == CAN_FIFO_0) 614 { 615 return CAN->RXF0_B.FMNUM0; 616 } 617 else 618 { 619 return CAN->RXF1_B.FMNUM1; 620 } 621 } 622 623 /*! 624 * @brief Select the CAN Operation mode. 625 * 626 * @param operatingMode: CAN Operating Mode 627 * This parameter can be one of the following values: 628 * @arg CAN_OPERATING_MODE_INIT : Initialization mode 629 * @arg CAN_OPERATING_MODE_NORMAL: Normal mode 630 * @arg CAN_OPERATING_MODE_SLEEP : sleep mode 631 * 632 * @retval status: 0 : CAN failed entering the specific mode 633 * 1 : CAN Succeed entering the specific mode 634 */ CAN_OperatingMode(CAN_OPERATING_MODE_T operatingMode)635uint8_t CAN_OperatingMode(CAN_OPERATING_MODE_T operatingMode) 636 { 637 uint8_t status = RESET; 638 uint32_t timeout = 0x00FFFFFF; 639 uint8_t sleepflg, initfig; 640 641 sleepflg = CAN->MSTS_B.SLEEPFLG; 642 initfig = CAN->MSTS_B.INITFLG; 643 644 switch ((uint8_t)operatingMode) 645 { 646 case CAN_OPERATING_MODE_INIT: 647 CAN->MCTRL_B.SLEEPREQ = BIT_RESET; 648 CAN->MCTRL_B.INITREQ = BIT_SET; 649 650 while ((sleepflg | !initfig) && (timeout != 0)) 651 { 652 sleepflg = CAN->MSTS_B.SLEEPFLG; 653 initfig = CAN->MSTS_B.INITFLG; 654 timeout--; 655 } 656 657 if (sleepflg | !initfig) 658 { 659 status = RESET; 660 } 661 else 662 { 663 status = SET; 664 } 665 break; 666 667 case CAN_OPERATING_MODE_NORMAL: 668 669 CAN->MCTRL_B.INITREQ = BIT_RESET; 670 CAN->MCTRL_B.SLEEPREQ = BIT_RESET; 671 672 while ((sleepflg | initfig) && (timeout != 0)) 673 { 674 sleepflg = CAN->MSTS_B.SLEEPFLG; 675 initfig = CAN->MSTS_B.INITFLG; 676 timeout--; 677 } 678 679 if (sleepflg | initfig) 680 { 681 status = RESET; 682 } 683 else 684 { 685 status = SET; 686 } 687 break; 688 689 case CAN_OPERATING_MODE_SLEEP: 690 CAN->MCTRL_B.INITREQ = BIT_RESET; 691 CAN->MCTRL_B.SLEEPREQ = BIT_SET; 692 693 while ((!sleepflg | initfig) && (timeout != 0)) 694 { 695 sleepflg = CAN->MSTS_B.SLEEPFLG; 696 initfig = CAN->MSTS_B.INITFLG; 697 timeout--; 698 } 699 700 if (!sleepflg | initfig) 701 { 702 status = RESET; 703 } 704 else 705 { 706 status = SET; 707 } 708 break; 709 710 default: 711 status = RESET; 712 break; 713 } 714 715 return status; 716 } 717 718 /*! 719 * @brief Enters the sleep mode. 720 * 721 * @param None 722 * 723 * @retval status: 0 : Into sleep fail 724 * 1 : Into sleep success 725 */ CAN_SleepMode(void)726uint8_t CAN_SleepMode(void) 727 { 728 CAN_SLEEP_T sleepstatus = CAN_SLEEP_FAILED; 729 730 CAN->MCTRL_B.INITREQ = BIT_RESET; 731 CAN->MCTRL_B.SLEEPREQ = BIT_SET; 732 733 if ((CAN->MSTS_B.SLEEPFLG == BIT_SET) && (CAN->MSTS_B.INITFLG == BIT_RESET)) 734 { 735 sleepstatus = CAN_SLEEP_OK; 736 } 737 738 return (uint8_t)sleepstatus; 739 } 740 741 /*! 742 * @brief Wakes up the CAN from sleep mode. 743 * 744 * @param None 745 * 746 * @retval status: 0 : WakeUp CAN fail 747 * 1 : WakeUp CAN success 748 */ CAN_WakeUpMode(void)749uint8_t CAN_WakeUpMode(void) 750 { 751 uint32_t slakWait = 0x00FFFFFF; 752 CAN_WUP_T wakeupstatus = CAN_WAKEUP_FAILED; 753 754 CAN->MCTRL_B.SLEEPREQ = BIT_RESET; 755 756 while ((CAN->MSTS_B.SLEEPFLG == BIT_SET) && (slakWait != 0x00)) 757 { 758 slakWait--; 759 } 760 if (CAN->MSTS_B.SLEEPFLG != BIT_SET) 761 { 762 wakeupstatus = CAN_WAKEUP_OK; 763 } 764 return (uint8_t)wakeupstatus; 765 } 766 767 /*! 768 * @brief Read the last error code of CAN. 769 * 770 * @param None 771 * 772 * @retval CAN_ErrorCode 773 */ CAN_ReadLastErrorCode(void)774uint8_t CAN_ReadLastErrorCode(void) 775 { 776 uint8_t errorcode = 0; 777 errorcode = CAN->ERRSTS_B.LERRC; 778 return errorcode; 779 } 780 781 /*! 782 * @brief Read the Receive Error Counter of CAN. 783 * 784 * @param None 785 * 786 * @retval CAN Receive Error Counter. 787 */ CAN_ReadRxErrorCounter(void)788uint8_t CAN_ReadRxErrorCounter(void) 789 { 790 uint8_t counter = 0; 791 counter = CAN->ERRSTS_B.RXERRCNT; 792 return counter; 793 } 794 795 /*! 796 * @brief Reads the Least significant byte of the 9-bit CAN Transmit Error Counter. 797 * 798 * @param None 799 * 800 * @retval Least significant byte of the 9-bit CAN Transmit Error Counter. 801 */ CAN_ReadLSBTxErrorCounter(void)802uint8_t CAN_ReadLSBTxErrorCounter(void) 803 { 804 uint8_t counter = 0; 805 counter = CAN->ERRSTS_B.TXERRCNT; 806 return counter; 807 } 808 809 /*! 810 * @brief Enables the specified CAN interrupts. 811 * 812 * @param interrupt: Selects the CAN interrupt sources to be enabled. 813 * The parameter can be any combination of the following values: 814 * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt 815 * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt 816 * @arg CAN_INT_F0FUL: FIFO 0 full Interrupt 817 * @arg CAN_INT_F0OVR: FIFO 0 overrun Interrupt 818 * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt 819 * @arg CAN_INT_F1FUL: FIFO 1 full Interrupt 820 * @arg CAN_INT_F1OVR: FIFO 1 overrun Interrupt 821 * @arg CAN_INT_EWIE : Error warning Interrupt 822 * @arg CAN_INT_EPIE : Error passive Interrupt 823 * @arg CAN_INT_BOIE : Bus-off Interrupt 824 * @arg CAN_INT_LEC : Last error code Interrupt 825 * @arg CAN_INT_ERR : Error Interrupt 826 * @arg CAN_INT_WUP : Wake-up Interrupt 827 * @arg CAN_INT_SLE : Sleep acknowledge Interrupt 828 * 829 * @retval None 830 */ CAN_EnableInterrupt(uint32_t interrupt)831void CAN_EnableInterrupt(uint32_t interrupt) 832 { 833 CAN->INTEN |= interrupt; 834 } 835 836 /*! 837 * @brief Disables the specified CAN interrupts. 838 * 839 * @param interrupt: Selects the CAN interrupt sources to be disabled. 840 * The parameter can be any combination of the following values: 841 * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt 842 * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt 843 * @arg CAN_INT_F0FUL: FIFO 0 full Interrupt 844 * @arg CAN_INT_F0OVR: FIFO 0 overrun Interrupt 845 * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt 846 * @arg CAN_INT_F1FUL: FIFO 1 full Interrupt 847 * @arg CAN_INT_F1OVR: FIFO 1 overrun Interrupt 848 * @arg CAN_INT_WUP : Wake-up Interrupt 849 * @arg CAN_INT_SLE : Sleep acknowledge Interrupt 850 * @arg CAN_INT_EWIE : Error warning Interrupt 851 * @arg CAN_INT_EPIE : Error passive Interrupt 852 * @arg CAN_INT_BOIE : Bus-off Interrupt 853 * @arg CAN_INT_LEC : Last error code Interrupt 854 * @arg CAN_INT_ERR : Error Interrupt 855 * 856 * @retval None 857 */ CAN_DisableInterrupt(uint32_t interrupt)858void CAN_DisableInterrupt(uint32_t interrupt) 859 { 860 CAN->INTEN &= ~interrupt; 861 } 862 863 /*! 864 * @brief Reads the specified CAN flag status. 865 * 866 * @param flag: specifies the flag of CAN. 867 * The parameter can be one of following values: 868 * @arg CAN_FLAG_EWF : Error Warning Flag 869 * @arg CAN_FLAG_EPF : Error Passive Flag 870 * @arg CAN_FLAG_BOF : Bus-Off Flag 871 * @arg CAN_FLAG_LEC : Last error code Flag 872 * @arg CAN_FLAG_WUP : Wake up Flag 873 * @arg CAN_FLAG_SLAK : Sleep acknowledge Flag 874 * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag 875 * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag 876 * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag 877 * @arg CAN_FLAG_FMP0 : FIFO 0 Message Pending Flag 878 * @arg CAN_FLAG_FF0 : FIFO 0 Full Flag 879 * @arg CAN_FLAG_FOV0 : FIFO 0 Overrun Flag 880 * @arg CAN_FLAG_FMP1 : FIFO 1 Message Pending Flag 881 * @arg CAN_FLAG_FF1 : FIFO 1 Full Flag 882 * @arg CAN_FLAG_FOV1 : FIFO 1 Overrun Flag 883 * 884 * @retval staus : RESET or SET 885 */ CAN_ReadStatusFlag(CAN_FLAG_T flag)886uint8_t CAN_ReadStatusFlag(CAN_FLAG_T flag) 887 { 888 uint8_t status = RESET; 889 890 if ((flag & 0x00F00000) != (uint32_t)RESET) 891 { 892 if ((CAN->ERRSTS & (flag & 0x000FFFFF)) != (uint32_t)RESET) 893 { 894 status = SET; 895 } 896 else 897 { 898 status = RESET; 899 } 900 } 901 else if ((flag & 0x01000000) != (uint32_t)RESET) 902 { 903 if ((CAN->MSTS & (flag & 0x000FFFFF)) != (uint32_t)RESET) 904 { 905 status = SET; 906 } 907 else 908 { 909 status = RESET; 910 } 911 } 912 else if ((flag & 0x02000000) != (uint32_t)RESET) 913 { 914 if ((CAN->TXSTS & (flag & 0x000FFFFF)) != (uint32_t)RESET) 915 { 916 status = SET; 917 } 918 else 919 { 920 status = RESET; 921 } 922 } 923 else if ((flag & 0x04000000) != (uint32_t)RESET) 924 { 925 if ((CAN->RXF0 & (flag & 0x000FFFFF)) != (uint32_t)RESET) 926 { 927 status = SET; 928 } 929 else 930 { 931 status = RESET; 932 } 933 } 934 else 935 { 936 if ((CAN->RXF1 & (flag & 0x000FFFFF)) != (uint32_t)RESET) 937 { 938 status = SET; 939 } 940 else 941 { 942 status = RESET; 943 } 944 } 945 return status; 946 } 947 948 /*! 949 * @brief Clears the status flags of CAN. 950 * 951 * @param flag : specifies the flag to clear. 952 * The parameter can be one of following values: 953 * @arg CAN_FLAG_LEC : Last error code Flag 954 * @arg CAN_FLAG_WUP : Wake up Flag 955 * @arg CAN_FLAG_SLAK : Sleep acknowledge Flag 956 * @arg CAN_FLAG_RQCP0: Request MailBox0 Flag 957 * @arg CAN_FLAG_RQCP1: Request MailBox1 Flag 958 * @arg CAN_FLAG_RQCP2: Request MailBox2 Flag 959 * @arg CAN_FLAG_FF0 : FIFO 0 Full Flag 960 * @arg CAN_FLAG_FOV0 : FIFO 0 Overrun Flag 961 * @arg CAN_FLAG_FF1 : FIFO 1 Full Flag 962 * @arg CAN_FLAG_FOV1 : FIFO 1 Overrun Flag 963 * 964 * @retval None 965 */ CAN_ClearStatusFlag(CAN_FLAG_T flag)966void CAN_ClearStatusFlag(CAN_FLAG_T flag) 967 { 968 uint32_t flagtmp = 0; 969 970 if (flag == CAN_FLAG_LEC) 971 { 972 CAN->ERRSTS_B.LERRC = 0; 973 } 974 else 975 { 976 flagtmp = flag & 0x000FFFFF; 977 978 if ((flag & 0x01000000) != RESET) 979 { 980 CAN->MSTS = flagtmp; 981 } 982 else if ((flag & 0x02000000) != RESET) 983 { 984 CAN->TXSTS = flagtmp; 985 } 986 else if ((flag & 0x04000000) != RESET) 987 { 988 CAN->RXF0 = flagtmp; 989 } 990 else 991 { 992 CAN->RXF1 = flagtmp; 993 } 994 } 995 } 996 997 /*! 998 * @brief Reads the specified CAN interrupt flag status. 999 * 1000 * @param interrupt: specifies the CAN interrupt source. 1001 * The parameter can be one of following values: 1002 * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt 1003 * @arg CAN_INT_F0MP : FIFO 0 message pending Interrupt 1004 * @arg CAN_INT_F0FUL: FIFO 0 full Interrupt 1005 * @arg CAN_INT_F0OVR: FIFO 0 overrun Interrupt 1006 * @arg CAN_INT_F1MP : FIFO 1 message pending Interrupt 1007 * @arg CAN_INT_F1FUL: FIFO 1 full Interrupt 1008 * @arg CAN_INT_F1OVR: FIFO 1 overrun Interrupt 1009 * @arg CAN_INT_EWIE : Error warning Interrupt 1010 * @arg CAN_INT_EPIE : Error passive Interrupt 1011 * @arg CAN_INT_BOIE : Bus-off Interrupt 1012 * @arg CAN_INT_LEC : Last error code Interrupt 1013 * @arg CAN_INT_ERR : Error Interrupt 1014 * @arg CAN_INT_WUP : Wake-up Interrupt 1015 * @arg CAN_INT_SLE : Sleep acknowledge Interrupt 1016 * 1017 * @retval status : SET or RESET 1018 */ CAN_ReadIntFlag(CAN_INT_T interrupt)1019uint8_t CAN_ReadIntFlag(CAN_INT_T interrupt) 1020 { 1021 uint8_t status = 0; 1022 1023 if ((CAN->INTEN & interrupt) != RESET) 1024 { 1025 switch (interrupt) 1026 { 1027 case CAN_INT_TXME: 1028 status = CAN->TXSTS_B.REQCFLG0; 1029 status |= CAN->TXSTS_B.REQCFLG1; 1030 status |= CAN->TXSTS_B.REQCFLG2; 1031 break; 1032 case CAN_INT_F0MP: 1033 status = !(!CAN->RXF0_B.FMNUM0); 1034 break; 1035 case CAN_INT_F0FUL: 1036 status = CAN->RXF0_B.FFULLFLG0; 1037 break; 1038 case CAN_INT_F0OVR: 1039 status = CAN->RXF0_B.FOVRFLG0; 1040 break; 1041 case CAN_INT_F1MP: 1042 status = !(!CAN->RXF1_B.FMNUM1); 1043 break; 1044 case CAN_INT_F1FUL: 1045 status = CAN->RXF1_B.FFULLFLG1; 1046 break; 1047 case CAN_INT_F1OVR: 1048 status = CAN->RXF1_B.FOVRFLG1; 1049 break; 1050 case CAN_INT_EWIE: 1051 status = CAN->ERRSTS_B.ERRWFLG; 1052 break; 1053 case CAN_INT_EPIE: 1054 status = CAN->ERRSTS_B.ERRPFLG; 1055 break; 1056 case CAN_INT_BOIE: 1057 status = CAN->ERRSTS_B.BOFLG; 1058 break; 1059 case CAN_INT_LEC: 1060 status = !(!CAN->ERRSTS_B.LERRC); 1061 break; 1062 case CAN_INT_ERR: 1063 status = CAN->MSTS_B.ERRIFLG; 1064 break; 1065 case CAN_INT_WUP: 1066 status = CAN->MSTS_B.WUPIFLG; 1067 break; 1068 case CAN_INT_SLE: 1069 status = CAN->MSTS_B.SLEEPIFLG; 1070 break; 1071 default: 1072 status = RESET; 1073 break; 1074 } 1075 } 1076 else 1077 { 1078 status = RESET; 1079 } 1080 return status; 1081 } 1082 1083 /*! 1084 * @brief Clears the CAN's interrupt flag. 1085 * 1086 * @param interrupt: specifies the interrupt flag to clear. 1087 * The parameter can be any combination of the following values: 1088 * @arg CAN_INT_TXME : Transmit mailbox empty Interrupt 1089 * @arg CAN_INT_F0FUL: FIFO 0 full Interrupt 1090 * @arg CAN_INT_F0OVR: FIFO 0 overrun Interrupt 1091 * @arg CAN_INT_F1FUL: FIFO 1 full Interrupt 1092 * @arg CAN_INT_F1OVR: FIFO 1 overrun Interrupt 1093 * @arg CAN_INT_EWIE : Error warning Interrupt 1094 * @arg CAN_INT_EPIE : Error passive Interrupt 1095 * @arg CAN_INT_BOIE : Bus-off Interrupt 1096 * @arg CAN_INT_LEC : Last error code Interrupt 1097 * @arg CAN_INT_ERR : Error Interrupt 1098 * @arg CAN_INT_WUP : Wake-up Interrupt 1099 * @arg CAN_INT_SLE : Sleep acknowledge Interrupt 1100 * 1101 * @retval None 1102 */ CAN_ClearIntFlag(uint32_t interrupt)1103void CAN_ClearIntFlag(uint32_t interrupt) 1104 { 1105 if (interrupt & CAN_INT_TXME) 1106 { 1107 CAN->TXSTS_B.REQCFLG0 = BIT_SET; 1108 CAN->TXSTS_B.REQCFLG1 = BIT_SET; 1109 CAN->TXSTS_B.REQCFLG2 = BIT_SET; 1110 } 1111 if (interrupt & CAN_INT_F0FUL) 1112 { 1113 CAN->RXF0_B.FFULLFLG0 = BIT_SET; 1114 } 1115 if (interrupt & CAN_INT_F0OVR) 1116 { 1117 CAN->RXF0_B.FOVRFLG0 = BIT_SET; 1118 } 1119 if (interrupt & CAN_INT_F1FUL) 1120 { 1121 CAN->RXF1_B.FFULLFLG1 = BIT_SET; 1122 } 1123 if (interrupt & CAN_INT_F1OVR) 1124 { 1125 CAN->RXF1_B.FOVRFLG1 = BIT_SET; 1126 } 1127 if (interrupt & CAN_INT_EWIE) 1128 { 1129 /** Note : the corresponding Flag is cleared by hardware 1130 * depending of the CAN Bus status 1131 */ 1132 CAN->MSTS_B.ERRIFLG = BIT_SET; 1133 } 1134 if (interrupt & CAN_INT_EPIE) 1135 { 1136 /** Note : the corresponding Flag is cleared by hardware 1137 * depending of the CAN Bus status 1138 */ 1139 CAN->MSTS_B.ERRIFLG = BIT_SET; 1140 } 1141 if (interrupt & CAN_INT_BOIE) 1142 { 1143 /** Note : the corresponding Flag is cleared by hardware 1144 * depending of the CAN Bus status 1145 */ 1146 CAN->MSTS_B.ERRIFLG = BIT_SET; 1147 } 1148 if (interrupt & CAN_INT_LEC) 1149 { 1150 CAN->ERRSTS_B.LERRC = 0; 1151 CAN->MSTS_B.ERRIFLG = BIT_SET; 1152 } 1153 if (interrupt & CAN_INT_ERR) 1154 { 1155 CAN->ERRSTS_B.LERRC = 0; 1156 CAN->MSTS_B.ERRIFLG = BIT_SET; 1157 } 1158 if (interrupt & CAN_INT_WUP) 1159 { 1160 CAN->MSTS_B.WUPIFLG = BIT_SET; 1161 } 1162 if (interrupt & CAN_INT_SLE) 1163 { 1164 CAN->MSTS_B.SLEEPIFLG = BIT_SET; 1165 } 1166 } 1167 1168 /**@} end of group CAN_Functions */ 1169 /**@} end of group CAN_Driver */ 1170 /**@} end of group APM32F0xx_StdPeriphDriver */ 1171