2 ******************************************************************************
\r
3 * @file stm32f10x_can.c
\r
4 * @author MCD Application Team
\r
7 * @brief This file provides all the CAN firmware functions.
\r
8 ******************************************************************************
\r
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
\r
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
\r
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
\r
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
\r
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
\r
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
\r
18 * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
\r
21 /* Includes ------------------------------------------------------------------*/
\r
22 #include "stm32f10x_can.h"
\r
23 #include "stm32f10x_rcc.h"
\r
25 /** @addtogroup STM32F10x_StdPeriph_Driver
\r
30 * @brief CAN driver modules
\r
34 /** @defgroup CAN_Private_TypesDefinitions
\r
42 /** @defgroup CAN_Private_Defines
\r
46 /* CAN Master Control Register bits */
\r
48 #define MCR_DBF ((uint32_t)0x00010000) /* software master reset */
\r
50 /* CAN Mailbox Transmit Request */
\r
51 #define TMIDxR_TXRQ ((uint32_t)0x00000001) /* Transmit mailbox request */
\r
53 /* CAN Filter Master Register bits */
\r
54 #define FMR_FINIT ((uint32_t)0x00000001) /* Filter init mode */
\r
56 /* Time out for INAK bit */
\r
57 #define INAK_TIMEOUT ((uint32_t)0x0000FFFF)
\r
58 /* Time out for SLAK bit */
\r
59 #define SLAK_TIMEOUT ((uint32_t)0x0000FFFF)
\r
63 /* Flags in TSR register */
\r
64 #define CAN_FLAGS_TSR ((uint32_t)0x08000000)
\r
65 /* Flags in RF1R register */
\r
66 #define CAN_FLAGS_RF1R ((uint32_t)0x04000000)
\r
67 /* Flags in RF0R register */
\r
68 #define CAN_FLAGS_RF0R ((uint32_t)0x02000000)
\r
69 /* Flags in MSR register */
\r
70 #define CAN_FLAGS_MSR ((uint32_t)0x01000000)
\r
71 /* Flags in ESR register */
\r
72 #define CAN_FLAGS_ESR ((uint32_t)0x00F00000)
\r
79 /** @defgroup CAN_Private_Macros
\r
87 /** @defgroup CAN_Private_Variables
\r
95 /** @defgroup CAN_Private_FunctionPrototypes
\r
99 static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit);
\r
105 /** @defgroup CAN_Private_Functions
\r
110 * @brief Deinitializes the CAN peripheral registers to their default reset values.
\r
111 * @param CANx: where x can be 1 or 2 to select the CAN peripheral.
\r
114 void CAN_DeInit(CAN_TypeDef* CANx)
\r
116 /* Check the parameters */
\r
117 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
121 /* Enable CAN1 reset state */
\r
122 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
\r
123 /* Release CAN1 from reset state */
\r
124 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
\r
128 /* Enable CAN2 reset state */
\r
129 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, ENABLE);
\r
130 /* Release CAN2 from reset state */
\r
131 RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN2, DISABLE);
\r
136 * @brief Initializes the CAN peripheral according to the specified
\r
137 * parameters in the CAN_InitStruct.
\r
138 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
139 * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that
\r
140 * contains the configuration information for the CAN peripheral.
\r
141 * @retval Constant indicates initialization succeed which will be
\r
142 * CANINITFAILED or CANINITOK.
\r
144 uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
\r
146 uint8_t InitStatus = CANINITFAILED;
\r
147 uint32_t wait_ack = 0x00000000;
\r
148 /* Check the parameters */
\r
149 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
150 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TTCM));
\r
151 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_ABOM));
\r
152 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_AWUM));
\r
153 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_NART));
\r
154 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_RFLM));
\r
155 assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->CAN_TXFP));
\r
156 assert_param(IS_CAN_MODE(CAN_InitStruct->CAN_Mode));
\r
157 assert_param(IS_CAN_SJW(CAN_InitStruct->CAN_SJW));
\r
158 assert_param(IS_CAN_BS1(CAN_InitStruct->CAN_BS1));
\r
159 assert_param(IS_CAN_BS2(CAN_InitStruct->CAN_BS2));
\r
160 assert_param(IS_CAN_PRESCALER(CAN_InitStruct->CAN_Prescaler));
\r
162 /* exit from sleep mode */
\r
163 CANx->MCR &= (~(uint32_t)CAN_MCR_SLEEP);
\r
165 /* Request initialisation */
\r
166 CANx->MCR |= CAN_MCR_INRQ ;
\r
168 /* Wait the acknowledge */
\r
169 while (((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT))
\r
174 /* ...and check acknowledged */
\r
175 if ((CANx->MSR & CAN_MSR_INAK) != CAN_MSR_INAK)
\r
177 InitStatus = CANINITFAILED;
\r
181 /* Set the time triggered communication mode */
\r
182 if (CAN_InitStruct->CAN_TTCM == ENABLE)
\r
184 CANx->MCR |= CAN_MCR_TTCM;
\r
188 CANx->MCR &= ~(uint32_t)CAN_MCR_TTCM;
\r
191 /* Set the automatic bus-off management */
\r
192 if (CAN_InitStruct->CAN_ABOM == ENABLE)
\r
194 CANx->MCR |= CAN_MCR_ABOM;
\r
198 CANx->MCR &= ~(uint32_t)CAN_MCR_ABOM;
\r
201 /* Set the automatic wake-up mode */
\r
202 if (CAN_InitStruct->CAN_AWUM == ENABLE)
\r
204 CANx->MCR |= CAN_MCR_AWUM;
\r
208 CANx->MCR &= ~(uint32_t)CAN_MCR_AWUM;
\r
211 /* Set the no automatic retransmission */
\r
212 if (CAN_InitStruct->CAN_NART == ENABLE)
\r
214 CANx->MCR |= CAN_MCR_NART;
\r
218 CANx->MCR &= ~(uint32_t)CAN_MCR_NART;
\r
221 /* Set the receive FIFO locked mode */
\r
222 if (CAN_InitStruct->CAN_RFLM == ENABLE)
\r
224 CANx->MCR |= CAN_MCR_RFLM;
\r
228 CANx->MCR &= ~(uint32_t)CAN_MCR_RFLM;
\r
231 /* Set the transmit FIFO priority */
\r
232 if (CAN_InitStruct->CAN_TXFP == ENABLE)
\r
234 CANx->MCR |= CAN_MCR_TXFP;
\r
238 CANx->MCR &= ~(uint32_t)CAN_MCR_TXFP;
\r
241 /* Set the bit timing register */
\r
242 CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | ((uint32_t)CAN_InitStruct->CAN_SJW << 24) |
\r
243 ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) |
\r
244 ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1);
\r
246 /* Request leave initialisation */
\r
247 CANx->MCR &= ~(uint32_t)CAN_MCR_INRQ;
\r
249 /* Wait the acknowledge */
\r
252 while (((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) && (wait_ack != INAK_TIMEOUT))
\r
257 /* ...and check acknowledged */
\r
258 if ((CANx->MSR & CAN_MSR_INAK) == CAN_MSR_INAK)
\r
260 InitStatus = CANINITFAILED;
\r
264 InitStatus = CANINITOK ;
\r
268 /* At this step, return the status of initialization */
\r
273 * @brief Initializes the CAN peripheral according to the specified
\r
274 * parameters in the CAN_FilterInitStruct.
\r
275 * @param CAN_FilterInitStruct: pointer to a CAN_FilterInitTypeDef
\r
276 * structure that contains the configuration information.
\r
279 void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct)
\r
281 uint32_t filter_number_bit_pos = 0;
\r
282 /* Check the parameters */
\r
283 assert_param(IS_CAN_FILTER_NUMBER(CAN_FilterInitStruct->CAN_FilterNumber));
\r
284 assert_param(IS_CAN_FILTER_MODE(CAN_FilterInitStruct->CAN_FilterMode));
\r
285 assert_param(IS_CAN_FILTER_SCALE(CAN_FilterInitStruct->CAN_FilterScale));
\r
286 assert_param(IS_CAN_FILTER_FIFO(CAN_FilterInitStruct->CAN_FilterFIFOAssignment));
\r
287 assert_param(IS_FUNCTIONAL_STATE(CAN_FilterInitStruct->CAN_FilterActivation));
\r
289 filter_number_bit_pos = ((uint32_t)0x00000001) << CAN_FilterInitStruct->CAN_FilterNumber;
\r
291 /* Initialisation mode for the filter */
\r
292 CAN1->FMR |= FMR_FINIT;
\r
294 /* Filter Deactivation */
\r
295 CAN1->FA1R &= ~(uint32_t)filter_number_bit_pos;
\r
298 if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_16bit)
\r
300 /* 16-bit scale for the filter */
\r
301 CAN1->FS1R &= ~(uint32_t)filter_number_bit_pos;
\r
303 /* First 16-bit identifier and First 16-bit mask */
\r
304 /* Or First 16-bit identifier and Second 16-bit identifier */
\r
305 CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
\r
306 ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow) << 16) |
\r
307 (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
\r
309 /* Second 16-bit identifier and Second 16-bit mask */
\r
310 /* Or Third 16-bit identifier and Fourth 16-bit identifier */
\r
311 CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
\r
312 ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
\r
313 (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh);
\r
316 if (CAN_FilterInitStruct->CAN_FilterScale == CAN_FilterScale_32bit)
\r
318 /* 32-bit scale for the filter */
\r
319 CAN1->FS1R |= filter_number_bit_pos;
\r
320 /* 32-bit identifier or First 32-bit identifier */
\r
321 CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR1 =
\r
322 ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdHigh) << 16) |
\r
323 (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterIdLow);
\r
324 /* 32-bit mask or Second 32-bit identifier */
\r
325 CAN1->sFilterRegister[CAN_FilterInitStruct->CAN_FilterNumber].FR2 =
\r
326 ((0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdHigh) << 16) |
\r
327 (0x0000FFFF & (uint32_t)CAN_FilterInitStruct->CAN_FilterMaskIdLow);
\r
331 if (CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdMask)
\r
333 /*Id/Mask mode for the filter*/
\r
334 CAN1->FM1R &= ~(uint32_t)filter_number_bit_pos;
\r
336 else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */
\r
338 /*Identifier list mode for the filter*/
\r
339 CAN1->FM1R |= (uint32_t)filter_number_bit_pos;
\r
342 /* Filter FIFO assignment */
\r
343 if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO0)
\r
345 /* FIFO 0 assignation for the filter */
\r
346 CAN1->FFA1R &= ~(uint32_t)filter_number_bit_pos;
\r
349 if (CAN_FilterInitStruct->CAN_FilterFIFOAssignment == CAN_FilterFIFO1)
\r
351 /* FIFO 1 assignation for the filter */
\r
352 CAN1->FFA1R |= (uint32_t)filter_number_bit_pos;
\r
355 /* Filter activation */
\r
356 if (CAN_FilterInitStruct->CAN_FilterActivation == ENABLE)
\r
358 CAN1->FA1R |= filter_number_bit_pos;
\r
361 /* Leave the initialisation mode for the filter */
\r
362 CAN1->FMR &= ~FMR_FINIT;
\r
366 * @brief Fills each CAN_InitStruct member with its default value.
\r
367 * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure which
\r
368 * will be initialized.
\r
371 void CAN_StructInit(CAN_InitTypeDef* CAN_InitStruct)
\r
373 /* Reset CAN init structure parameters values */
\r
374 /* Initialize the time triggered communication mode */
\r
375 CAN_InitStruct->CAN_TTCM = DISABLE;
\r
376 /* Initialize the automatic bus-off management */
\r
377 CAN_InitStruct->CAN_ABOM = DISABLE;
\r
378 /* Initialize the automatic wake-up mode */
\r
379 CAN_InitStruct->CAN_AWUM = DISABLE;
\r
380 /* Initialize the no automatic retransmission */
\r
381 CAN_InitStruct->CAN_NART = DISABLE;
\r
382 /* Initialize the receive FIFO locked mode */
\r
383 CAN_InitStruct->CAN_RFLM = DISABLE;
\r
384 /* Initialize the transmit FIFO priority */
\r
385 CAN_InitStruct->CAN_TXFP = DISABLE;
\r
386 /* Initialize the CAN_Mode member */
\r
387 CAN_InitStruct->CAN_Mode = CAN_Mode_Normal;
\r
388 /* Initialize the CAN_SJW member */
\r
389 CAN_InitStruct->CAN_SJW = CAN_SJW_1tq;
\r
390 /* Initialize the CAN_BS1 member */
\r
391 CAN_InitStruct->CAN_BS1 = CAN_BS1_4tq;
\r
392 /* Initialize the CAN_BS2 member */
\r
393 CAN_InitStruct->CAN_BS2 = CAN_BS2_3tq;
\r
394 /* Initialize the CAN_Prescaler member */
\r
395 CAN_InitStruct->CAN_Prescaler = 1;
\r
399 * @brief Select the start bank filter for slave CAN.
\r
400 * @note This function applies only to STM32 Connectivity line devices.
\r
401 * @param CAN_BankNumber: Select the start slave bank filter from 1..27.
\r
404 void CAN_SlaveStartBank(uint8_t CAN_BankNumber)
\r
406 /* Check the parameters */
\r
407 assert_param(IS_CAN_BANKNUMBER(CAN_BankNumber));
\r
408 /* enter Initialisation mode for the filter */
\r
409 CAN1->FMR |= FMR_FINIT;
\r
410 /* Select the start slave bank */
\r
411 CAN1->FMR &= (uint32_t)0xFFFFC0F1 ;
\r
412 CAN1->FMR |= (uint32_t)(CAN_BankNumber)<<8;
\r
413 /* Leave Initialisation mode for the filter */
\r
414 CAN1->FMR &= ~FMR_FINIT;
\r
418 * @brief Enables or disables the specified CANx interrupts.
\r
419 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
420 * @param CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
\r
421 * This parameter can be:
\r
435 * @param NewState: new state of the CAN interrupts.
\r
436 * This parameter can be: ENABLE or DISABLE.
\r
439 void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState NewState)
\r
441 /* Check the parameters */
\r
442 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
443 assert_param(IS_CAN_IT(CAN_IT));
\r
444 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
446 if (NewState != DISABLE)
\r
448 /* Enable the selected CANx interrupt */
\r
449 CANx->IER |= CAN_IT;
\r
453 /* Disable the selected CANx interrupt */
\r
454 CANx->IER &= ~CAN_IT;
\r
459 * @brief Initiates the transmission of a message.
\r
460 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
461 * @param TxMessage: pointer to a structure which contains CAN Id, CAN
\r
462 * DLC and CAN datas.
\r
463 * @retval The number of the mailbox that is used for transmission
\r
464 * or CAN_NO_MB if there is no empty mailbox.
\r
466 uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
\r
468 uint8_t transmit_mailbox = 0;
\r
469 /* Check the parameters */
\r
470 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
471 assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
\r
472 assert_param(IS_CAN_RTR(TxMessage->RTR));
\r
473 assert_param(IS_CAN_DLC(TxMessage->DLC));
\r
475 /* Select one empty transmit mailbox */
\r
476 if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
\r
478 transmit_mailbox = 0;
\r
480 else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
\r
482 transmit_mailbox = 1;
\r
484 else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
\r
486 transmit_mailbox = 2;
\r
490 transmit_mailbox = CAN_NO_MB;
\r
493 if (transmit_mailbox != CAN_NO_MB)
\r
495 /* Set up the Id */
\r
496 CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
\r
497 if (TxMessage->IDE == CAN_ID_STD)
\r
499 assert_param(IS_CAN_STDID(TxMessage->StdId));
\r
500 CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->StdId << 21) | TxMessage->RTR);
\r
504 assert_param(IS_CAN_EXTID(TxMessage->ExtId));
\r
505 CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId<<3) | TxMessage->IDE |
\r
510 /* Set up the DLC */
\r
511 TxMessage->DLC &= (uint8_t)0x0000000F;
\r
512 CANx->sTxMailBox[transmit_mailbox].TDTR &= (uint32_t)0xFFFFFFF0;
\r
513 CANx->sTxMailBox[transmit_mailbox].TDTR |= TxMessage->DLC;
\r
515 /* Set up the data field */
\r
516 CANx->sTxMailBox[transmit_mailbox].TDLR = (((uint32_t)TxMessage->Data[3] << 24) |
\r
517 ((uint32_t)TxMessage->Data[2] << 16) |
\r
518 ((uint32_t)TxMessage->Data[1] << 8) |
\r
519 ((uint32_t)TxMessage->Data[0]));
\r
520 CANx->sTxMailBox[transmit_mailbox].TDHR = (((uint32_t)TxMessage->Data[7] << 24) |
\r
521 ((uint32_t)TxMessage->Data[6] << 16) |
\r
522 ((uint32_t)TxMessage->Data[5] << 8) |
\r
523 ((uint32_t)TxMessage->Data[4]));
\r
524 /* Request transmission */
\r
525 CANx->sTxMailBox[transmit_mailbox].TIR |= TMIDxR_TXRQ;
\r
527 return transmit_mailbox;
\r
531 * @brief Checks the transmission of a message.
\r
532 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
533 * @param TransmitMailbox: the number of the mailbox that is used for transmission.
\r
534 * @retval CANTXOK if the CAN driver transmits the message, CANTXFAILED in an other case.
\r
536 uint8_t CAN_TransmitStatus(CAN_TypeDef* CANx, uint8_t TransmitMailbox)
\r
538 /* RQCP, TXOK and TME bits */
\r
540 /* Check the parameters */
\r
541 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
542 assert_param(IS_CAN_TRANSMITMAILBOX(TransmitMailbox));
\r
543 switch (TransmitMailbox)
\r
545 case (0): state |= (uint8_t)((CANx->TSR & CAN_TSR_RQCP0) << 2);
\r
546 state |= (uint8_t)((CANx->TSR & CAN_TSR_TXOK0) >> 0);
\r
547 state |= (uint8_t)((CANx->TSR & CAN_TSR_TME0) >> 26);
\r
549 case (1): state |= (uint8_t)((CANx->TSR & CAN_TSR_RQCP1) >> 6);
\r
550 state |= (uint8_t)((CANx->TSR & CAN_TSR_TXOK1) >> 8);
\r
551 state |= (uint8_t)((CANx->TSR & CAN_TSR_TME1) >> 27);
\r
553 case (2): state |= (uint8_t)((CANx->TSR & CAN_TSR_RQCP2) >> 14);
\r
554 state |= (uint8_t)((CANx->TSR & CAN_TSR_TXOK2) >> 16);
\r
555 state |= (uint8_t)((CANx->TSR & CAN_TSR_TME2) >> 28);
\r
558 state = CANTXFAILED;
\r
563 /* transmit pending */
\r
564 case (0x0): state = CANTXPENDING;
\r
566 /* transmit failed */
\r
567 case (0x5): state = CANTXFAILED;
\r
569 /* transmit succedeed */
\r
570 case (0x7): state = CANTXOK;
\r
573 state = CANTXFAILED;
\r
580 * @brief Cancels a transmit request.
\r
581 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
582 * @param Mailbox: Mailbox number.
\r
585 void CAN_CancelTransmit(CAN_TypeDef* CANx, uint8_t Mailbox)
\r
587 /* Check the parameters */
\r
588 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
589 assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox));
\r
590 /* abort transmission */
\r
593 case (0): CANx->TSR |= CAN_TSR_ABRQ0;
\r
595 case (1): CANx->TSR |= CAN_TSR_ABRQ1;
\r
597 case (2): CANx->TSR |= CAN_TSR_ABRQ2;
\r
605 * @brief Releases a FIFO.
\r
606 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
607 * @param FIFONumber: FIFO to release, CAN_FIFO0 or CAN_FIFO1.
\r
610 void CAN_FIFORelease(CAN_TypeDef* CANx, uint8_t FIFONumber)
\r
612 /* Check the parameters */
\r
613 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
614 assert_param(IS_CAN_FIFO(FIFONumber));
\r
615 /* Release FIFO0 */
\r
616 if (FIFONumber == CAN_FIFO0)
\r
618 CANx->RF0R |= CAN_RF0R_RFOM0;
\r
620 /* Release FIFO1 */
\r
621 else /* FIFONumber == CAN_FIFO1 */
\r
623 CANx->RF1R |= CAN_RF1R_RFOM1;
\r
628 * @brief Returns the number of pending messages.
\r
629 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
630 * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
\r
631 * @retval NbMessage which is the number of pending message.
\r
633 uint8_t CAN_MessagePending(CAN_TypeDef* CANx, uint8_t FIFONumber)
\r
635 uint8_t message_pending=0;
\r
636 /* Check the parameters */
\r
637 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
638 assert_param(IS_CAN_FIFO(FIFONumber));
\r
639 if (FIFONumber == CAN_FIFO0)
\r
641 message_pending = (uint8_t)(CANx->RF0R&(uint32_t)0x03);
\r
643 else if (FIFONumber == CAN_FIFO1)
\r
645 message_pending = (uint8_t)(CANx->RF1R&(uint32_t)0x03);
\r
649 message_pending = 0;
\r
651 return message_pending;
\r
655 * @brief Receives a message.
\r
656 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
657 * @param FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
\r
658 * @param RxMessage: pointer to a structure receive message which
\r
659 * contains CAN Id, CAN DLC, CAN datas and FMI number.
\r
662 void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
\r
664 /* Check the parameters */
\r
665 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
666 assert_param(IS_CAN_FIFO(FIFONumber));
\r
668 RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR;
\r
669 if (RxMessage->IDE == CAN_ID_STD)
\r
671 RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
\r
675 RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);
\r
678 RxMessage->RTR = (uint8_t)0x02 & CANx->sFIFOMailBox[FIFONumber].RIR;
\r
680 RxMessage->DLC = (uint8_t)0x0F & CANx->sFIFOMailBox[FIFONumber].RDTR;
\r
682 RxMessage->FMI = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDTR >> 8);
\r
683 /* Get the data field */
\r
684 RxMessage->Data[0] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDLR;
\r
685 RxMessage->Data[1] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 8);
\r
686 RxMessage->Data[2] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 16);
\r
687 RxMessage->Data[3] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDLR >> 24);
\r
688 RxMessage->Data[4] = (uint8_t)0xFF & CANx->sFIFOMailBox[FIFONumber].RDHR;
\r
689 RxMessage->Data[5] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 8);
\r
690 RxMessage->Data[6] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 16);
\r
691 RxMessage->Data[7] = (uint8_t)0xFF & (CANx->sFIFOMailBox[FIFONumber].RDHR >> 24);
\r
692 /* Release the FIFO */
\r
693 CAN_FIFORelease(CANx, FIFONumber);
\r
697 * @brief Enables or disables the DBG Freeze for CAN.
\r
698 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
699 * @param NewState: new state of the CAN peripheral.
\r
700 * This parameter can be: ENABLE or DISABLE.
\r
703 void CAN_DBGFreeze(CAN_TypeDef* CANx, FunctionalState NewState)
\r
705 /* Check the parameters */
\r
706 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
707 assert_param(IS_FUNCTIONAL_STATE(NewState));
\r
709 if (NewState != DISABLE)
\r
711 /* Enable Debug Freeze */
\r
712 CANx->MCR |= MCR_DBF;
\r
716 /* Disable Debug Freeze */
\r
717 CANx->MCR &= ~MCR_DBF;
\r
722 * @brief Enters the low power mode.
\r
723 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
724 * @retval CANSLEEPOK if sleep entered, CANSLEEPFAILED in an other case.
\r
726 uint8_t CAN_Sleep(CAN_TypeDef* CANx)
\r
728 uint8_t sleepstatus = CANSLEEPFAILED;
\r
730 /* Check the parameters */
\r
731 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
733 /* Request Sleep mode */
\r
734 CANx->MCR = (((CANx->MCR) & (uint32_t)(~(uint32_t)CAN_MCR_INRQ)) | CAN_MCR_SLEEP);
\r
736 /* Sleep mode status */
\r
737 if ((CANx->MSR & (CAN_MSR_SLAK|CAN_MSR_INAK)) == CAN_MSR_SLAK)
\r
739 /* Sleep mode not entered */
\r
740 sleepstatus = CANSLEEPOK;
\r
742 /* At this step, sleep mode status */
\r
743 return (uint8_t)sleepstatus;
\r
747 * @brief Wakes the CAN up.
\r
748 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
749 * @retval CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other case.
\r
751 uint8_t CAN_WakeUp(CAN_TypeDef* CANx)
\r
753 uint32_t wait_slak = SLAK_TIMEOUT;
\r
754 uint8_t wakeupstatus = CANWAKEUPFAILED;
\r
756 /* Check the parameters */
\r
757 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
759 /* Wake up request */
\r
760 CANx->MCR &= ~(uint32_t)CAN_MCR_SLEEP;
\r
762 /* Sleep mode status */
\r
763 while(((CANx->MSR & CAN_MSR_SLAK) == CAN_MSR_SLAK)&&(wait_slak!=0x00))
\r
767 if((CANx->MSR & CAN_MSR_SLAK) != CAN_MSR_SLAK)
\r
769 /* Sleep mode exited */
\r
770 wakeupstatus = CANWAKEUPOK;
\r
772 /* At this step, sleep mode status */
\r
773 return (uint8_t)wakeupstatus;
\r
777 * @brief Checks whether the specified CAN flag is set or not.
\r
778 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
779 * @param CAN_FLAG: specifies the flag to check.
\r
780 * This parameter can be one of the following flags:
\r
796 * @retval The new state of CAN_FLAG (SET or RESET).
\r
798 FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
\r
800 FlagStatus bitstatus = RESET;
\r
802 /* Check the parameters */
\r
803 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
804 assert_param(IS_CAN_GET_FLAG(CAN_FLAG));
\r
807 if((CAN_FLAG & CAN_FLAGS_ESR) != (uint32_t)RESET)
\r
809 /* Check the status of the specified CAN flag */
\r
810 if ((CANx->ESR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
\r
812 /* CAN_FLAG is set */
\r
817 /* CAN_FLAG is reset */
\r
821 else if((CAN_FLAG & CAN_FLAGS_MSR) != (uint32_t)RESET)
\r
823 /* Check the status of the specified CAN flag */
\r
824 if ((CANx->MSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
\r
826 /* CAN_FLAG is set */
\r
831 /* CAN_FLAG is reset */
\r
835 else if((CAN_FLAG & CAN_FLAGS_TSR) != (uint32_t)RESET)
\r
837 /* Check the status of the specified CAN flag */
\r
838 if ((CANx->TSR & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
\r
840 /* CAN_FLAG is set */
\r
845 /* CAN_FLAG is reset */
\r
849 else if((CAN_FLAG & CAN_FLAGS_RF0R) != (uint32_t)RESET)
\r
851 /* Check the status of the specified CAN flag */
\r
852 if ((CANx->RF0R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
\r
854 /* CAN_FLAG is set */
\r
859 /* CAN_FLAG is reset */
\r
863 else /* If(CAN_FLAG & CAN_FLAGS_RF1R != (uint32_t)RESET) */
\r
865 /* Check the status of the specified CAN flag */
\r
866 if ((uint32_t)(CANx->RF1R & (CAN_FLAG & 0x000FFFFF)) != (uint32_t)RESET)
\r
868 /* CAN_FLAG is set */
\r
873 /* CAN_FLAG is reset */
\r
877 /* Return the CAN_FLAG status */
\r
882 * @brief Clears the CAN's pending flags.
\r
883 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
884 * @param CAN_FLAG: specifies the flag to clear.
\r
885 * This parameter can be one of the following flags:
\r
898 void CAN_ClearFlag(CAN_TypeDef* CANx, uint32_t CAN_FLAG)
\r
900 uint32_t flagtmp=0;
\r
901 /* Check the parameters */
\r
902 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
903 assert_param(IS_CAN_CLEAR_FLAG(CAN_FLAG));
\r
905 if (CAN_FLAG == CAN_FLAG_LEC) /* ESR register */
\r
907 /* Clear the selected CAN flags */
\r
908 CANx->ESR = (uint32_t)RESET;
\r
910 else /* MSR or TSR or RF0R or RF1R */
\r
912 flagtmp = CAN_FLAG & 0x000FFFFF;
\r
914 if ((CAN_FLAG & CAN_FLAGS_RF0R)!=(uint32_t)RESET)
\r
916 /* Receive Flags */
\r
917 CANx->RF0R = (uint32_t)(flagtmp);
\r
919 else if ((CAN_FLAG & CAN_FLAGS_RF1R)!=(uint32_t)RESET)
\r
921 /* Receive Flags */
\r
922 CANx->RF1R = (uint32_t)(flagtmp);
\r
924 else if ((CAN_FLAG & CAN_FLAGS_TSR)!=(uint32_t)RESET)
\r
926 /* Transmit Flags */
\r
927 CANx->TSR = (uint32_t)(flagtmp);
\r
929 else /* If((CAN_FLAG & CAN_FLAGS_MSR)!=(uint32_t)RESET) */
\r
931 /* Operating mode Flags */
\r
932 CANx->MSR = (uint32_t)(flagtmp);
\r
938 * @brief Checks whether the specified CANx interrupt has occurred or not.
\r
939 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
940 * @param CAN_IT: specifies the CAN interrupt source to check.
\r
941 * This parameter can be one of the following flags:
\r
956 * @retval The current state of CAN_IT (SET or RESET).
\r
958 ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT)
\r
960 ITStatus itstatus = RESET;
\r
961 /* Check the parameters */
\r
962 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
963 assert_param(IS_CAN_IT(CAN_IT));
\r
965 /* check the enable interrupt bit */
\r
966 if((CANx->IER & CAN_IT) != RESET)
\r
968 /* in case the Interrupt is enabled, .... */
\r
972 /* Check CAN_TSR_RQCPx bits */
\r
973 itstatus = CheckITStatus(CANx->TSR, CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2);
\r
976 /* Check CAN_RF0R_FMP0 bit */
\r
977 itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FMP0);
\r
980 /* Check CAN_RF0R_FULL0 bit */
\r
981 itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FULL0);
\r
984 /* Check CAN_RF0R_FOVR0 bit */
\r
985 itstatus = CheckITStatus(CANx->RF0R, CAN_RF0R_FOVR0);
\r
988 /* Check CAN_RF1R_FMP1 bit */
\r
989 itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FMP1);
\r
992 /* Check CAN_RF1R_FULL1 bit */
\r
993 itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FULL1);
\r
996 /* Check CAN_RF1R_FOVR1 bit */
\r
997 itstatus = CheckITStatus(CANx->RF1R, CAN_RF1R_FOVR1);
\r
1000 /* Check CAN_MSR_WKUI bit */
\r
1001 itstatus = CheckITStatus(CANx->MSR, CAN_MSR_WKUI);
\r
1004 /* Check CAN_MSR_SLAKI bit */
\r
1005 itstatus = CheckITStatus(CANx->MSR, CAN_MSR_SLAKI);
\r
1008 /* Check CAN_ESR_EWGF bit */
\r
1009 itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EWGF);
\r
1012 /* Check CAN_ESR_EPVF bit */
\r
1013 itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EPVF);
\r
1016 /* Check CAN_ESR_BOFF bit */
\r
1017 itstatus = CheckITStatus(CANx->ESR, CAN_ESR_BOFF);
\r
1020 /* Check CAN_ESR_LEC bit */
\r
1021 itstatus = CheckITStatus(CANx->ESR, CAN_ESR_LEC);
\r
1024 /* Check CAN_MSR_ERRI, CAN_ESR_EWGF, CAN_ESR_EPVF, CAN_ESR_BOFF and CAN_ESR_LEC bits */
\r
1025 itstatus = CheckITStatus(CANx->ESR, CAN_ESR_EWGF|CAN_ESR_EPVF|CAN_ESR_BOFF|CAN_ESR_LEC);
\r
1026 itstatus |= CheckITStatus(CANx->MSR, CAN_MSR_ERRI);
\r
1029 /* in case of error, return RESET */
\r
1036 /* in case the Interrupt is not enabled, return RESET */
\r
1040 /* Return the CAN_IT status */
\r
1045 * @brief Clears the CANx
\92s interrupt pending bits.
\r
1046 * @param CANx: where x can be 1 or 2 to to select the CAN peripheral.
\r
1047 * @param CAN_IT: specifies the interrupt pending bit to clear.
\r
1062 void CAN_ClearITPendingBit(CAN_TypeDef* CANx, uint32_t CAN_IT)
\r
1064 /* Check the parameters */
\r
1065 assert_param(IS_CAN_ALL_PERIPH(CANx));
\r
1066 assert_param(IS_CAN_CLEAR_IT(CAN_IT));
\r
1071 /* Clear CAN_TSR_RQCPx (rc_w1)*/
\r
1072 CANx->TSR = CAN_TSR_RQCP0|CAN_TSR_RQCP1|CAN_TSR_RQCP2;
\r
1075 /* Clear CAN_RF0R_FULL0 (rc_w1)*/
\r
1076 CANx->RF0R = CAN_RF0R_FULL0;
\r
1079 /* Clear CAN_RF0R_FOVR0 (rc_w1)*/
\r
1080 CANx->RF0R = CAN_RF0R_FOVR0;
\r
1083 /* Clear CAN_RF1R_FULL1 (rc_w1)*/
\r
1084 CANx->RF1R = CAN_RF1R_FULL1;
\r
1087 /* Clear CAN_RF1R_FOVR1 (rc_w1)*/
\r
1088 CANx->RF1R = CAN_RF1R_FOVR1;
\r
1091 /* Clear CAN_MSR_WKUI (rc_w1)*/
\r
1092 CANx->MSR = CAN_MSR_WKUI;
\r
1095 /* Clear CAN_MSR_SLAKI (rc_w1)*/
\r
1096 CANx->MSR = CAN_MSR_SLAKI;
\r
1099 /* Clear CAN_MSR_ERRI (rc_w1) */
\r
1100 CANx->MSR = CAN_MSR_ERRI;
\r
1101 /* Note : the corresponding Flag is cleared by hardware depending of the CAN Bus status*/
\r
1104 /* Clear CAN_MSR_ERRI (rc_w1) */
\r
1105 CANx->MSR = CAN_MSR_ERRI;
\r
1106 /* Note : the corresponding Flag is cleared by hardware depending of the CAN Bus status*/
\r
1109 /* Clear CAN_MSR_ERRI (rc_w1) */
\r
1110 CANx->MSR = CAN_MSR_ERRI;
\r
1111 /* Note : the corresponding Flag is cleared by hardware depending of the CAN Bus status*/
\r
1114 /* Clear LEC bits */
\r
1115 CANx->ESR = RESET;
\r
1116 /* Clear CAN_MSR_ERRI (rc_w1) */
\r
1117 CANx->MSR = CAN_MSR_ERRI;
\r
1120 /*Clear LEC bits */
\r
1121 CANx->ESR = RESET;
\r
1122 /* Clear CAN_MSR_ERRI (rc_w1) */
\r
1123 CANx->MSR = CAN_MSR_ERRI;
\r
1124 /* Note : BOFF, EPVF and EWGF Flags are cleared by hardware depending of the CAN Bus status*/
\r
1132 * @brief Checks whether the CAN interrupt has occurred or not.
\r
1133 * @param CAN_Reg: specifies the CAN interrupt register to check.
\r
1134 * @param It_Bit: specifies the interrupt source bit to check.
\r
1135 * @retval The new state of the CAN Interrupt (SET or RESET).
\r
1137 static ITStatus CheckITStatus(uint32_t CAN_Reg, uint32_t It_Bit)
\r
1139 ITStatus pendingbitstatus = RESET;
\r
1141 if ((CAN_Reg & It_Bit) != (uint32_t)RESET)
\r
1143 /* CAN_IT is set */
\r
1144 pendingbitstatus = SET;
\r
1148 /* CAN_IT is reset */
\r
1149 pendingbitstatus = RESET;
\r
1151 return pendingbitstatus;
\r
1166 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
\r