1 /**
2 ******************************************************************************
3 * @file    HAL_can.c
4 * @author  AE Team
5 * @version V1.5.0
6 * @date    02/08/2017
7 * @brief   This file provides all the CAN firmware functions.
8 ******************************************************************************
9 * @attention
10 *
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, MindMotion SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 *
18 * <h2><center>&copy; COPYRIGHT 2017 MindMotion</center></h2>
19 ******************************************************************************
20 */
21 
22 /* Includes ------------------------------------------------------------------*/
23 #include "HAL_can.h"
24 #include "HAL_rcc.h"
25 
26 /**
27 * @brief: Deinitialinzes the CAN registers to their default reset values
28 * @retval: None
29 */
CAN_DeInit(CAN_TypeDef * CANx)30 void CAN_DeInit(CAN_TypeDef* CANx)
31 {
32   /* Check the parameters */
33   assert_param(IS_CAN_ALL_PERIPH(CANx));
34   switch (*(uint32_t*)&CANx)
35   {
36   case CAN1_BASE:
37     /* Enable CAN1 reset state */
38     RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, ENABLE);
39     /* Release CAN1 from reset state */
40     RCC_APB1PeriphResetCmd(RCC_APB1Periph_CAN1, DISABLE);
41     break;
42   default:
43     break;
44   }
45 
46 }
47 
48 /**
49 * @brief  Initializes the CAN peripheral according to the specified
50 *   parameters in the CAN_InitStruct.
51 * @param CANx: where x can be 1 to select the CAN peripheral.
52 * @param CAN_InitStruct: pointer to a CAN_InitTypeDef structure that
53 *   contains the configuration information for the CAN peripheral.
54 * @retval : Constant indicates initialization succeed which will be
55 *   CANINITFAILED or CANINITOK.
56 */
CAN_Init(CAN_TypeDef * CANx,CAN_Basic_InitTypeDef * CAN_Basic_InitStruct)57 uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_Basic_InitTypeDef* CAN_Basic_InitStruct)
58 {
59   uint8_t InitStatus = CANINITFAILED;
60 
61   /* Check the parameters */
62   assert_param(IS_FUNCTIONAL_STATE(CAN_Basic_InitStruct->SJW));
63   assert_param(IS_FUNCTIONAL_STATE(CAN_Basic_InitStruct->BRP));
64   assert_param(IS_FUNCTIONAL_STATE(CAN_Basic_InitStruct->SAM));
65   assert_param(IS_FUNCTIONAL_STATE(CAN_Basic_InitStruct->TESG2));
66   assert_param(IS_FUNCTIONAL_STATE(CAN_Basic_InitStruct->TESG1));
67 
68   CANx->BTR0 = ((uint32_t)(CAN_Basic_InitStruct->SJW)<<6)|((uint32_t)(CAN_Basic_InitStruct->BRP));
69   CANx->BTR1 = ((uint32_t)(CAN_Basic_InitStruct->SAM)<<7)|((uint32_t)(CAN_Basic_InitStruct->TESG2)<<4)|\
70     ((uint32_t)(CAN_Basic_InitStruct->TESG1));
71   if(CAN_Basic_InitStruct->GTS == ENABLE)
72   {
73     CANx->CMR |= (uint32_t)CAN_SleepMode;
74   }
75   else
76   {
77     CANx->CMR &= ~(uint32_t)CAN_SleepMode;
78   }
79 
80   CANx->CDR |= ((CAN_Basic_InitStruct->CBP)<<6) | ((CAN_Basic_InitStruct->RXINTEN)<<5) | \
81     ((CAN_Basic_InitStruct->CLOSE_OPEN_CLK)<<3) | (CAN_Basic_InitStruct->CDCLK);
82 
83   InitStatus = CANINITOK;
84   return InitStatus;
85 }
86 
87 /**
88 * @brief  Configures the CAN_Basic reception filter according to the specified
89 *         parameters in the CAN_Basic_FilterInitStruct.
90 * @param  CAN_Basic_FilterInitStruct: pointer to a CAN_Basic_FilterInitTypeDef structure that
91 *         contains the configuration information.
92 * @retval None
93 */
CAN_FilterInit(CAN_Basic_FilterInitTypeDef * CAN_Basic_FilterInitStruct)94 void CAN_FilterInit(CAN_Basic_FilterInitTypeDef* CAN_Basic_FilterInitStruct)
95 {
96   /* Filter Mode */
97   CAN1->ACR = CAN_Basic_FilterInitStruct->CAN_FilterId;
98   CAN1->AMR = CAN_Basic_FilterInitStruct->CAN_FilterMaskId;
99 }
100 
101 
102 /**
103 * @brief  Fills each CAN_Basic_InitStruct member with its default value.
104 * @param CAN_Basic_InitStruct : pointer to a CAN_Basic_InitTypeDef structure
105 *   which will be initialized.
106 * @retval : None
107 */
CAN_StructInit(CAN_Basic_InitTypeDef * CAN_Basic_InitStruct)108 void CAN_StructInit(CAN_Basic_InitTypeDef* CAN_Basic_InitStruct)
109 {
110   /*--------------- Reset CAN_Basic init structure parameters values -----------------*/
111 
112 
113   /* initialize the BRP member(where can be set with (0..63))*/
114   CAN_Basic_InitStruct->BRP = 0x0;
115   /* initialize the SJW member(where can be set with (0..3)) */
116   CAN_Basic_InitStruct->SJW = 0x0;
117   /* Initialize the TESG1 member(where can be set with (0..15)) */
118   CAN_Basic_InitStruct->TESG1 = 0x0;
119   /* Initialize the TESG2 member(where can be set with(0..7)) */
120   CAN_Basic_InitStruct->TESG2 = 0x0;
121   /* Initialize the SAM member(where can be set (SET or RESET)) */
122   CAN_Basic_InitStruct->SAM = RESET;
123   /* Initialize the GTS member to Sleep Mode(where can be set (ENABLE or DISABLE)) */
124   CAN_Basic_InitStruct->GTS = DISABLE;
125   /* Initialize the external pin CLKOUT frequence */
126   CAN_Basic_InitStruct->CDCLK = 0x0;
127   /* Initialize the external clk is open or close */
128   CAN_Basic_InitStruct->CLOSE_OPEN_CLK = 0x0;
129   /* Initialize the TX1 pin work as rx interrupt output */
130   CAN_Basic_InitStruct->RXINTEN = 0x0;
131   /* Initialize the CBP of CDR register */
132   CAN_Basic_InitStruct->CBP = 0x0;
133 }
134 
135 /**
136 * @brief  Enables or disables the specified CAN interrupts.
137 * @param CANx: where x can be 1 to select the CAN peripheral.
138 * @param CAN_IT: specifies the CAN interrupt sources to be enabled or
139 *   disabled.
140 *   This parameter can be: CAN_IT_OIE, CAN_IT_EIE, CAN_IT_TIE,
141 *   CAN_IT_RIE,.
142 * @param Newstate: new state of the CAN interrupts.
143 *   This parameter can be: ENABLE or DISABLE.
144 * @retval : None.
145 */
CAN_ITConfig(CAN_TypeDef * CANx,uint32_t CAN_IT,FunctionalState Newstate)146 void CAN_ITConfig(CAN_TypeDef* CANx, uint32_t CAN_IT, FunctionalState Newstate)
147 {
148   /* Check the parameters */
149   assert_param(IS_CAN_ALL_PERIPH(CANx));
150   assert_param(IS_CAN_ITConfig(CAN_IT));
151   assert_param(IS_FUNCTIONAL_STATE(Newstate));
152   if (Newstate != DISABLE)
153   {
154     /* Enable the selected CAN interrupt */
155     CANx->CR |= CAN_IT;
156   }
157   else
158   {
159     /* Disable the selected CAN interrupt */
160     CANx->CR &= ~CAN_IT;
161   }
162 }
163 
164 
165 /**
166 * @brief  Initiates and transmits a CAN frame message.
167 * @param CANx: where x can be 1 to select the CAN peripheral.
168 * @param  TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data.
169 * @retval CANTXOK if the CAN driver transmits the message
170 */
CAN_Transmit(CAN_TypeDef * CANx,CanBasicTxMsg * BasicTxMessage)171 uint8_t CAN_Transmit(CAN_TypeDef* CANx,CanBasicTxMsg* BasicTxMessage)
172 {
173   /* TXOK and TME bits */
174   uint8_t state = 0;
175   /* Check the parameters */
176   assert_param(IS_CAN_RTR(BasicTxMessage->RTR));
177   assert_param(IS_CAN_DLC(BasicTxMessage->DLC));
178 
179   CANx->TXID0 = (BasicTxMessage->IDH);
180   CANx->TXID1 = (BasicTxMessage->IDL<<5)|(BasicTxMessage->RTR<<4)|(BasicTxMessage->DLC);
181   if((FunctionalState)(BasicTxMessage->RTR) != ENABLE)
182   {
183     CANx->TXDR0 = BasicTxMessage->Data[0];
184     CANx->TXDR1 = BasicTxMessage->Data[1];
185     CANx->TXDR2 = BasicTxMessage->Data[2];
186     CANx->TXDR3 = BasicTxMessage->Data[3];
187     CANx->TXDR4 = BasicTxMessage->Data[4];
188     CANx->TXDR5 = BasicTxMessage->Data[5];
189     CANx->TXDR6 = BasicTxMessage->Data[6];
190     CANx->TXDR7 = BasicTxMessage->Data[7];
191   }
192 
193   CANx->CMR = CAN_BASIC_CMR_TR;
194 
195   return state;
196 }
197 
198 /**
199 * @brief  Cancels a transmit request.
200 * @param CANx: where x can be 1 to select the CAN peripheral.
201 
202 * @retval None
203 */
CAN_CancelTransmit(CAN_TypeDef * CANx)204 void CAN_CancelTransmit(CAN_TypeDef* CANx)
205 {
206   /* Check the parameters */
207   assert_param(IS_CAN_ALL_PERIPH(CANx));
208   assert_param(IS_CAN_TRANSMITMAILBOX(Mailbox));
209   /* abort transmission */
210   CANx->CMR = CAN_AT;
211 
212 }
213 
214 /**
215 * @brief  Releases the specified receive FIFO.
216 * @param CANx: where x can be 1 to select the CAN peripheral.
217 * @retval None
218 */
CAN_FIFORelease(CAN_TypeDef * CANx)219 void CAN_FIFORelease(CAN_TypeDef* CANx)
220 {
221   /* Check the parameters */
222   assert_param(IS_CAN_ALL_PERIPH(CANx));
223 
224   /* Release FIFO */
225   CANx->CMR |= (uint32_t)CAN_RRB;
226 
227 }
228 
229 /**
230 * @brief  Receives a correct CAN frame.
231 * @param CANx: where x can be 1 to select the CAN peripheral.
232 * @param  RxMessage: pointer to a structure receive frame which contains CAN Id,
233 *         CAN DLC, CAN data and FMI number.
234 * @retval None
235 */
CAN_Receive(CAN_TypeDef * CANx,CanBasicRxMsg * BasicRxMessage)236 void CAN_Receive(CAN_TypeDef* CANx,CanBasicRxMsg* BasicRxMessage)
237 {
238   uint16_t tempid;
239   /* Check the parameters */
240   assert_param(IS_CAN_ALL_PERIPH(CANx));
241   assert_param(IS_CAN_FIFO(FIFONumber));
242   BasicRxMessage->RTR = (uint8_t)((CANx->RXID1)>>4)&0x1;
243   BasicRxMessage->DLC = (uint8_t)((CANx->RXID1)&0xf);
244   tempid = (uint16_t)(((CANx->RXID1)&0xe0)>>5);
245   tempid |= (uint16_t)(CANx->RXID0<<3);
246   BasicRxMessage->ID = tempid;
247   BasicRxMessage->Data[0] = CAN1->RXDR0;
248   BasicRxMessage->Data[1] = CAN1->RXDR1;
249   BasicRxMessage->Data[2] = CAN1->RXDR2;
250   BasicRxMessage->Data[3] = CAN1->RXDR3;
251   BasicRxMessage->Data[4] = CAN1->RXDR4;
252   BasicRxMessage->Data[5] = CAN1->RXDR5;
253   BasicRxMessage->Data[6] = CAN1->RXDR6;
254   BasicRxMessage->Data[7] = CAN1->RXDR7;
255   CAN_FIFORelease( CANx);
256 }
257 
258 /**
259 * @brief: Select the Sleep mode or not in Basic workmode
260 * @param: NewState to go into the Sleep mode or go out
261 * @retval: None
262 */
CAN_Sleep(CAN_TypeDef * CANx)263 uint8_t CAN_Sleep(CAN_TypeDef* CANx)
264 {
265   uint8_t sleepstatus = CANSLEEPFAILED;
266 
267   /* Check the parameters */
268   assert_param(IS_CAN_ALL_PERIPH(CANx));
269   CANx->CMR |= CAN_SleepMode;
270   if((CANx->CMR&0x10)==CAN_SleepMode)
271   {
272     sleepstatus =  CANSLEEPOK;
273   }
274   /* At this step, sleep mode status */
275   return (uint8_t)sleepstatus;
276 
277 }
278 
279 /**
280 * @brief  Wakes the CAN up.
281 * @param CANx: where x can be 1 to select the CAN peripheral.
282 * @retval : CANWAKEUPOK if sleep mode left, CANWAKEUPFAILED in an other
283 *   case.
284 */
CAN_WakeUp(CAN_TypeDef * CANx)285 uint8_t CAN_WakeUp(CAN_TypeDef* CANx)
286 {
287   uint8_t wakeupstatus = CANWAKEUPFAILED;
288 
289   /* Check the parameters */
290   assert_param(IS_CAN_ALL_PERIPH(CANx));
291 
292   /* Wake up request */
293   CANx->CMR &= ~CAN_SleepMode;
294 
295   /* Sleep mode status */
296   if((CANx->CMR&0x01)==0)
297   {
298     /* Sleep mode exited */
299     wakeupstatus = CANWAKEUPOK;
300   }
301   /* At this step, sleep mode status */
302   return (uint8_t)wakeupstatus;
303 }
304 
305 
306 /**
307 * @brief  Checks whether the specified CAN flag is set or not.
308 * @param  CANx: where x can be 1 or 2 to to select the CAN peripheral.
309 * @param  CAN_FLAG: specifies the flag to check.
310 *          This parameter can be one of the following values:
311 *            @arg CAN_STATUS_RBS: Receive buffer status
312 *            @arg CAN_STATUS_DOS: Data overflow status
313 *            @arg CAN_STATUS_TBS: Transmit buffer status
314 *            @arg CAN_STATUS_TCS: Transmit complete status
315 *            @arg CAN_STATUS_RS: Receiving status
316 *            @arg CAN_STATUS_TS: Transmiting status
317 *            @arg CAN_STATUS_ES: Error status
318 *            @arg CAN_STATUS_BS: bus status, close or open
319 * @retval The new state of CAN_FLAG (SET or RESET).
320 */
CAN_GetFlagStatus(CAN_TypeDef * CANx,uint32_t CAN_FLAG)321 FlagStatus CAN_GetFlagStatus(CAN_TypeDef* CANx,uint32_t CAN_FLAG)
322 {
323   FlagStatus bitstatus = RESET;
324 
325   /* Check the parameters */
326   assert_param(IS_CAN_ALL_PERIPH(CANx));
327   assert_param(IS_CAN_GET_FLAG(CAN_FLAG));
328 
329 
330   if((CANx->SR & CAN_FLAG) == CAN_FLAG)
331   {
332     /* CAN_FLAG is set */
333     bitstatus = SET;
334   }
335   else
336   {
337     /* CAN_FLAG is reset */
338     bitstatus = RESET;
339   }
340   /* Return the CAN_FLAG status */
341   return bitstatus;
342 }
343 
344 /**
345 * @brief  Checks whether the specified CAN interrupt has occurred or not.
346 * @param CANx: where x can be 1 to select the CAN peripheral.
347 * @param  CAN_IT: specifies the CAN interrupt source to check.
348 *          This parameter can be one of the following values:
349 *            @arg CAN_IT_RI: Receive FIFO not empty Interrupt
350 *            @arg CAN_IT_TI: Transmit Interrupt
351 *            @arg CAN_IT_EI: ERROR Interrupt
352 *            @arg CAN_IT_DOI: Data voerflow Interrupt
353 *            @arg CAN_IT_WUI: Wakeup Interrupt
354 *            @arg CAN_IT_ALL: use it can enble all Interrupt
355 * @retval The current state of CAN_IT (SET or RESET).
356 */
CAN_GetITStatus(CAN_TypeDef * CANx,uint32_t CAN_IT)357 ITStatus CAN_GetITStatus(CAN_TypeDef* CANx, uint32_t CAN_IT)
358 {
359   ITStatus itstatus = RESET;
360 
361   /* Check the parameters */
362   assert_param(IS_CAN_ALL_PERIPH(CANx));
363   assert_param(IS_CAN_IT(CAN_IT));
364 
365   /* check the interrupt enable bit */
366   if((CANx->IR & CAN_IT) != CAN_IT)
367   {
368     itstatus = RESET;
369   }
370   else
371   {
372     itstatus = SET;
373   }
374 
375   return itstatus;
376 }
377 
378 
379 /**
380 * @brief: Select the can work as peli mode or basic mode
381 * @param  CANx: where x can be 1 or 2 to to select the CAN peripheral.
382 * @param  CAN_MODE: specifies the work mode:CAN_BASICMode,CAN_PELIMode
383 * @retval: None
384 */
CAN_Mode_Cmd(CAN_TypeDef * CANx,uint32_t CAN_MODE)385 void CAN_Mode_Cmd(CAN_TypeDef* CANx, uint32_t CAN_MODE)
386 {
387   /* Check the parameters */
388   assert_param(IS_CAN_ALL_PERIPH(CANx));
389 
390   CANx->CDR |= CAN_MODE;
391 }
392 
393 
394 /**
395 * @brief: Select the Reset mode or not
396 * @param  CANx: where x can be 1 or 2 to to select the CAN peripheral.
397 * @param: NewState to go into the Reset mode or go out
398 * @retval: None
399 */
CAN_ResetMode_Cmd(CAN_TypeDef * CANx,FunctionalState NewState)400 void CAN_ResetMode_Cmd(CAN_TypeDef* CANx,FunctionalState NewState)
401 {
402   /* Check the parameters */
403   assert_param(IS_CAN_ALL_PERIPH(CANx));
404 
405   if(NewState == ENABLE)
406   {
407     CANx->CR |= CAN_ResetMode;
408   }
409   else
410   {
411     CANx->CR &= ~CAN_ResetMode;
412   }
413 }
414 
415 /**
416 * @brief  Clear the data overflow.
417 * @param  CANx: where x can be 1 or 2 to to select the CAN peripheral.
418 * @retval None
419 */
CAN_ClearDataOverflow(CAN_TypeDef * CANx)420 void CAN_ClearDataOverflow(CAN_TypeDef* CANx)
421 {
422   /* Check the parameters */
423   assert_param(IS_CAN_ALL_PERIPH(CANx));
424 
425   CANx->CMR |= (uint32_t)CAN_CDO;
426 
427 }
428 
429 /**
430 * @brief  Clears the CAN's IT pending.
431 * @param  CANx: where x can be 1 or 2 to to select the CAN peripheral.
432 * @retval None
433 */
CAN_ClearITPendingBit(CAN_TypeDef * CANx)434 void CAN_ClearITPendingBit(CAN_TypeDef* CANx)
435 {
436   uint32_t temp=0;
437   temp = temp;
438   temp = CANx->IR; //read this register clear all interrupt
439 
440 }
441 
442 
443 
444 /**
445 * @brief: Select the Sleep mode or not in Peli workmode
446 * @param: NewState to go into the Sleep mode or go out
447 * @retval: None
448 */
CAN_Peli_SleepMode_Cmd(FunctionalState NewState)449 void CAN_Peli_SleepMode_Cmd(FunctionalState NewState)
450 {
451   if(NewState == ENABLE)
452     CAN1_PELI->MOD |= CAN_SleepMode;
453   else
454     CAN1_PELI->MOD &= ~CAN_SleepMode;
455 }
456 
457 
458 /**
459 * @brief  Fills each CAN1_PELI_InitStruct member with its default value.
460 * @param CAN_Peli_InitStruct : pointer to a CAN_Peli_InitTypeDef structure
461 *   which will be initialized.
462 * @retval : None
463 */
CAN_Peli_StructInit(CAN_Peli_InitTypeDef * CAN_Peli_InitStruct)464 void CAN_Peli_StructInit(CAN_Peli_InitTypeDef* CAN_Peli_InitStruct)
465 {
466   /*--------------- Reset CAN_Peli init structure parameters values -----------------*/
467 
468   /* initialize the BRP member(where can be set with (0..63))*/
469   CAN_Peli_InitStruct->BRP = 0x0;
470   /* initialize the SJW member(where can be set with (0..3)) */
471   CAN_Peli_InitStruct->SJW = 0x0;
472   /* Initialize the TESG1 member(where can be set with (0..15)) */
473   CAN_Peli_InitStruct->TESG1 = 0x0;
474   /* Initialize the TESG2 member(where can be set with(0..7)) */
475   CAN_Peli_InitStruct->TESG2 = 0x0;
476   /* Initialize the SAM member(where can be set (SET or RESET)) */
477   CAN_Peli_InitStruct->SAM = RESET;
478   /* Initialize the LOM member*/
479   CAN_Peli_InitStruct->LOM = DISABLE;
480   /* Initialize the STM member*/
481   CAN_Peli_InitStruct->STM = DISABLE;
482   /* Initialize the SM member*/
483   CAN_Peli_InitStruct->SM = DISABLE;
484   CAN_Peli_InitStruct->SRR = DISABLE;
485   CAN_Peli_InitStruct->EWLR = 0x96;
486 }
487 
488 /**
489 * @brief  Initializes the CAN_Peli peripheral according to the specified
490 *         parameters in the CAN_Peli_InitStruct.
491 * @param  CAN_Basic_InitStruct: pointer to a CAN_Peli_InitTypeDef structure that contains
492 *         the configuration information for the CAN peripheral in the peli workmode.
493 * @retval None
494 */
CAN_Peli_Init(CAN_Peli_InitTypeDef * CAN_Peli_InitStruct)495 void CAN_Peli_Init(CAN_Peli_InitTypeDef* CAN_Peli_InitStruct)
496 {
497   /* Check the parameters */
498   assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->SJW));
499   assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->BRP));
500   assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->SAM));
501   assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->TESG2));
502   assert_param(IS_FUNCTIONAL_STATE(CAN_InitStruct->TESG1));
503 
504   CAN1_PELI->BTR0 = ((uint32_t)CAN_Peli_InitStruct->SJW<<6)|((uint32_t)CAN_Peli_InitStruct->BRP);
505   CAN1_PELI->BTR1 = ((uint32_t)CAN_Peli_InitStruct->SAM<<7)|((uint32_t)CAN_Peli_InitStruct->TESG2<<4)|\
506     ((uint32_t)CAN_Peli_InitStruct->TESG1);
507   if(CAN_Peli_InitStruct->LOM == ENABLE)
508     CAN1_PELI->MOD |= (uint32_t)CAN_ListenOnlyMode;
509   else
510     CAN1_PELI->MOD &= ~(uint32_t)CAN_ListenOnlyMode;
511   if(CAN_Peli_InitStruct->STM == ENABLE)
512     CAN1_PELI->MOD |= (uint32_t)CAN_SeftTestMode;
513   else
514     CAN1_PELI->MOD &= ~(uint32_t)CAN_SeftTestMode;
515   if(CAN_Peli_InitStruct->SM == ENABLE)
516     CAN1_PELI->MOD |= (uint32_t)CAN_SleepMode;
517   else
518     CAN1_PELI->MOD &= ~(uint32_t)CAN_SleepMode;
519   CAN1_PELI->EWLR = (uint32_t)CAN_Peli_InitStruct->EWLR;
520 }
521 
522 
523 
524 /**
525 * @brief  Configures the CAN_Peli reception filter according to the specified
526 *         parameters in the CAN_Peli_FilterInitStruct.
527 * @param  CAN_Peli_FilterInitStruct: pointer to a CAN_Peli_FilterInitTypeDef structure that
528 *         contains the configuration information.
529 * @retval None
530 */
CAN_Peli_FilterInit(CAN_Peli_FilterInitTypeDef * CAN_Peli_FilterInitStruct)531 void CAN_Peli_FilterInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
532 {
533   if(CAN_Peli_FilterInitStruct->AFM == CAN_FilterMode_Singal)
534     CAN1_PELI->MOD |= (uint32_t)CAN_FilterMode_Singal;
535   else
536     CAN1_PELI->MOD &= (uint32_t)CAN_FilterMode_Double;
537 
538   CAN1_PELI->FF = CAN_Peli_FilterInitStruct->CAN_FilterId0;
539   CAN1_PELI->ID0 = CAN_Peli_FilterInitStruct->CAN_FilterId1;
540   CAN1_PELI->ID1 = CAN_Peli_FilterInitStruct->CAN_FilterId2;
541   CAN1_PELI->DATA0 = CAN_Peli_FilterInitStruct->CAN_FilterId3;
542 
543   CAN1_PELI->DATA1 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId0;
544   CAN1_PELI->DATA2 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId1;
545   CAN1_PELI->DATA3 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId2;
546   CAN1_PELI->DATA4 = CAN_Peli_FilterInitStruct->CAN_FilterMaskId3;
547 }
548 
549 /**
550 * @brief  Fills each CAN_Peli_FilterInitStruct member with its default value.
551 * @param  CAN_Peli_FilterInitStruct: pointer to a CAN_InitTypeDef structure which ill be initialized.
552 * @retval None
553 */
CAN_Peli_FilterStructInit(CAN_Peli_FilterInitTypeDef * CAN_Peli_FilterInitStruct)554 void CAN_Peli_FilterStructInit(CAN_Peli_FilterInitTypeDef* CAN_Peli_FilterInitStruct)
555 {
556   CAN_Peli_FilterInitStruct->CAN_FilterId0 = 0;
557   CAN_Peli_FilterInitStruct->CAN_FilterId1 = 0;
558   CAN_Peli_FilterInitStruct->CAN_FilterId2 = 0;
559   CAN_Peli_FilterInitStruct->CAN_FilterId3 = 0;
560 
561   CAN_Peli_FilterInitStruct->CAN_FilterMaskId0 = 0;
562   CAN_Peli_FilterInitStruct->CAN_FilterMaskId1 = 0;
563   CAN_Peli_FilterInitStruct->CAN_FilterMaskId2 = 0;
564   CAN_Peli_FilterInitStruct->CAN_FilterMaskId3 = 0;
565 }
566 
567 
568 /**
569 * @brief  Initiates and transmits a CAN frame message.
570 * @param  TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data.
571 * @retval None
572 */
CAN_Peli_Transmit(CanPeliTxMsg * PeliTxMessage)573 void CAN_Peli_Transmit(CanPeliTxMsg* PeliTxMessage)
574 {
575   /* Check the parameters */
576   assert_param(IS_CAN_RTR(PeliTxMessage->RTR));
577   assert_param(IS_CAN_DLC(PeliTxMessage->DLC));
578 
579   CAN1_PELI->FF = (PeliTxMessage->FF<<7)|(PeliTxMessage->RTR<<6)|(PeliTxMessage->DLC);
580   if(((FunctionalState)PeliTxMessage->FF) != ENABLE)
581   {
582     CAN1_PELI->ID0 = (PeliTxMessage->IDHH);
583 //    CAN1_PELI->ID1 = ((PeliTxMessage->IDHL)<<5);
584     CAN1_PELI->ID1 = (PeliTxMessage->IDHL&0xE0);
585     if((FunctionalState)(PeliTxMessage->RTR) != ENABLE)
586     {
587       CAN1_PELI->DATA0 = PeliTxMessage->Data[0];
588       CAN1_PELI->DATA1 = PeliTxMessage->Data[1];
589       CAN1_PELI->DATA2 = PeliTxMessage->Data[2];
590       CAN1_PELI->DATA3 = PeliTxMessage->Data[3];
591       CAN1_PELI->DATA4 = PeliTxMessage->Data[4];
592       CAN1_PELI->DATA5 = PeliTxMessage->Data[5];
593       CAN1_PELI->DATA6 = PeliTxMessage->Data[6];
594       CAN1_PELI->DATA7 = PeliTxMessage->Data[7];
595     }
596   }
597   else
598   {
599     CAN1_PELI->ID0 = PeliTxMessage->IDHH;
600     CAN1_PELI->ID1 = PeliTxMessage->IDHL;
601     CAN1_PELI->DATA0 = PeliTxMessage->IDLH;
602     CAN1_PELI->DATA1 = PeliTxMessage->IDLL;
603     if((FunctionalState)(PeliTxMessage->RTR) != ENABLE)
604     {
605       CAN1_PELI->DATA2 = PeliTxMessage->Data[0];
606       CAN1_PELI->DATA3 = PeliTxMessage->Data[1];
607       CAN1_PELI->DATA4 = PeliTxMessage->Data[2];
608       CAN1_PELI->DATA5 = PeliTxMessage->Data[3];
609       CAN1_PELI->DATA6 = PeliTxMessage->Data[4];
610       CAN1_PELI->DATA7 = PeliTxMessage->Data[5];
611       CAN1_PELI->DATA8 = PeliTxMessage->Data[6];
612       CAN1_PELI->DATA9 = PeliTxMessage->Data[7];
613     }
614   }
615   if(CAN1_PELI->MOD&CAN_PELI_MOD_STM)
616   {
617     CAN1->CMR = CAN_PELI_CMR_SRR|CAN_PELI_CMR_AT;
618   }
619   else
620   {
621     CAN1->CMR = CAN_TR|CAN_AT;
622   }
623 
624 }
625 
626 
627 
628 /**
629 * @brief  Initiates and transmits a CAN frame message.
630 * @param  TxMessage: pointer to a structure which contains CAN Id, CAN DLC and CAN data.
631 * @retval None
632 */
CAN_Peli_TransmitRepeat(CanPeliTxMsg * PeliTxMessage)633 void CAN_Peli_TransmitRepeat(CanPeliTxMsg* PeliTxMessage)
634 {
635   /* Check the parameters */
636   assert_param(IS_CAN_RTR(PeliTxMessage->RTR));
637   assert_param(IS_CAN_DLC(PeliTxMessage->DLC));
638 
639   CAN1_PELI->FF = (PeliTxMessage->FF<<7)|(PeliTxMessage->RTR<<6)|(PeliTxMessage->DLC);
640   if(((FunctionalState)PeliTxMessage->FF) != ENABLE)
641   {
642     CAN1_PELI->ID0 = (PeliTxMessage->IDHH);
643     CAN1_PELI->ID1 = ((PeliTxMessage->IDHL)<<5);
644     if((FunctionalState)(PeliTxMessage->RTR) != ENABLE)
645     {
646       CAN1_PELI->DATA0 = PeliTxMessage->Data[0];
647       CAN1_PELI->DATA1 = PeliTxMessage->Data[1];
648       CAN1_PELI->DATA2 = PeliTxMessage->Data[2];
649       CAN1_PELI->DATA3 = PeliTxMessage->Data[3];
650       CAN1_PELI->DATA4 = PeliTxMessage->Data[4];
651       CAN1_PELI->DATA5 = PeliTxMessage->Data[5];
652       CAN1_PELI->DATA6 = PeliTxMessage->Data[6];
653       CAN1_PELI->DATA7 = PeliTxMessage->Data[7];
654     }
655   }
656   else
657   {
658     CAN1_PELI->ID0 = PeliTxMessage->IDHH;
659     CAN1_PELI->ID1 = PeliTxMessage->IDHL;
660     CAN1_PELI->DATA0 = PeliTxMessage->IDLH;
661     CAN1_PELI->DATA1 = PeliTxMessage->IDLL;
662     if((FunctionalState)(PeliTxMessage->RTR) != ENABLE)
663     {
664       CAN1_PELI->DATA2 = PeliTxMessage->Data[0];
665       CAN1_PELI->DATA3 = PeliTxMessage->Data[1];
666       CAN1_PELI->DATA4 = PeliTxMessage->Data[2];
667       CAN1_PELI->DATA5 = PeliTxMessage->Data[3];
668       CAN1_PELI->DATA6 = PeliTxMessage->Data[4];
669       CAN1_PELI->DATA7 = PeliTxMessage->Data[5];
670       CAN1_PELI->DATA8 = PeliTxMessage->Data[6];
671       CAN1_PELI->DATA9 = PeliTxMessage->Data[7];
672     }
673   }
674 
675   if(CAN1_PELI->MOD&CAN_PELI_MOD_STM)
676   {
677 		CAN1->CMR = CAN_PELI_CMR_SRR|CAN_PELI_CMR_AT;
678   }
679   else
680   {
681     CAN1->CMR = CAN_PELI_CMR_TR;
682   }
683 }
684 
685 /** @defgroup CAN_Group3 CAN Frames Reception functions
686 *  @brief    CAN Frames Reception functions
687 *
688 @verbatim
689 ===============================================================================
690 ##### CAN Frames Reception functions #####
691 ===============================================================================
692 [..] This section provides functions allowing to
693 (+) Receive a correct CAN frame.
694 (+) Release a specified receive FIFO
695 (+) Return the number of the pending received CAN frames.
696 
697 @endverbatim
698 * @{
699 */
700 
701 
702 /**
703 * @brief  Receives a correct CAN frame.
704 * @param  RxMessage: pointer to a structure receive frame which contains CAN Id,
705 *         CAN DLC, CAN data and FMI number.
706 * @retval None
707 */
CAN_Peli_Receive(CanPeliRxMsg * PeliRxMessage)708 void CAN_Peli_Receive(CanPeliRxMsg* PeliRxMessage)
709 {
710   uint32_t tempid;
711   PeliRxMessage->FF = (CAN1_PELI->FF)>>7;
712   PeliRxMessage->RTR = ((CAN1_PELI->FF)>>6)&0x1;
713   PeliRxMessage->DLC = (CAN1_PELI->FF)&0xf;
714 
715   if(((FunctionalState)PeliRxMessage->FF) != ENABLE)
716   {
717     tempid = (uint32_t)(CAN1_PELI->ID1>>5);
718     tempid |= (uint32_t)(CAN1_PELI->ID0<<3);
719     PeliRxMessage->ID = tempid;
720     PeliRxMessage->Data[0] = CAN1_PELI->DATA0;
721     PeliRxMessage->Data[1] = CAN1_PELI->DATA1;
722     PeliRxMessage->Data[2] = CAN1_PELI->DATA2;
723     PeliRxMessage->Data[3] = CAN1_PELI->DATA3;
724     PeliRxMessage->Data[4] = CAN1_PELI->DATA4;
725     PeliRxMessage->Data[5] = CAN1_PELI->DATA5;
726     PeliRxMessage->Data[6] = CAN1_PELI->DATA6;
727     PeliRxMessage->Data[7] = CAN1_PELI->DATA7;
728   }
729   else
730   {
731     tempid = (uint32_t)((CAN1_PELI->DATA1&0xf8)>>3);
732     tempid |= (uint32_t)(CAN1_PELI->DATA0<<5);
733     tempid |= (uint32_t)(CAN1_PELI->ID1<<13);
734     tempid |= (uint32_t)(CAN1_PELI->ID0<<21);
735     PeliRxMessage->ID = tempid;
736     PeliRxMessage->Data[0] = CAN1_PELI->DATA2;
737     PeliRxMessage->Data[1] = CAN1_PELI->DATA3;
738     PeliRxMessage->Data[2] = CAN1_PELI->DATA4;
739     PeliRxMessage->Data[3] = CAN1_PELI->DATA5;
740     PeliRxMessage->Data[4] = CAN1_PELI->DATA6;
741     PeliRxMessage->Data[5] = CAN1_PELI->DATA7;
742     PeliRxMessage->Data[6] = CAN1_PELI->DATA8;
743     PeliRxMessage->Data[7] = CAN1_PELI->DATA9;
744   }
745   CAN_FIFORelease( CAN1);
746 }
747 
748 
749 /**
750 * @brief  Get available current informatoin in receive FIFO only in Peli workmode.
751 * @retval The value in reg RMC
752 */
CAN_Peli_GetRxFIFOInfo(void)753 uint32_t CAN_Peli_GetRxFIFOInfo(void)
754 {
755   return CAN1_PELI->RMC;
756 }
757 
758 
759 /** @defgroup CAN_Group5 CAN Bus Error management functions
760 *  @brief    CAN Bus Error management functions
761 *
762 @verbatim
763 ===============================================================================
764 ##### CAN Bus Error management functions #####
765 ===============================================================================
766 
767 @endverbatim
768 * @{
769 */
770 
771 /**
772 * @brief  Returns the CAN's last error code (LEC).
773 * @retval Error code:
774 *          - CAN_ERRORCODE_NoErr: No Error
775 *          - CAN_ERRORCODE_StuffErr: Stuff Error
776 *          - CAN_ERRORCODE_FormErr: Form Error
777 *          - CAN_ERRORCODE_ACKErr : Acknowledgment Error
778 *          - CAN_ERRORCODE_BitRecessiveErr: Bit Recessive Error
779 *          - CAN_ERRORCODE_BitDominantErr: Bit Dominant Error
780 *          - CAN_ERRORCODE_CRCErr: CRC Error
781 *          - CAN_ERRORCODE_SoftwareSetErr: Software Set Error
782 */
CAN_Peli_GetLastErrorCode(void)783 uint8_t CAN_Peli_GetLastErrorCode(void)
784 {
785   uint8_t errorcode=0;
786 
787   /* Get the error code*/
788   errorcode = ((uint8_t)CAN1_PELI->ECC);
789 
790   /* Return the error code*/
791   return errorcode;
792 }
793 /**
794 * @brief  Returns the CAN Receive Error Counter (REC).
795 * @note   In case of an error during reception, this counter is incremented
796 *         by 1 or by 8 depending on the error condition as defined by the CAN
797 *         standard. After every successful reception, the counter is
798 *         decremented by 1 or reset to 120 if its value was higher than 128.
799 *         When the counter value exceeds 127, the CAN controller enters the
800 *         error passive state.
801 * @retval CAN Receive Error Counter.
802 */
CAN_Peli_GetReceiveErrorCounter(void)803 uint8_t CAN_Peli_GetReceiveErrorCounter(void)
804 {
805   uint8_t counter=0;
806 
807   /* Check the parameters */
808   assert_param(IS_CAN_ALL_PERIPH(CANx));
809 
810   /* Get the Receive Error Counter*/
811   counter = (uint8_t)(CAN1_PELI->RXERR);
812 
813   /* Return the Receive Error Counter*/
814   return counter;
815 }
816 
817 
818 /**
819 * @brief  Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
820 * @retval LSB of the 8-bit CAN Transmit Error Counter.
821 */
CAN_Peli_GetLSBTransmitErrorCounter(void)822 uint8_t CAN_Peli_GetLSBTransmitErrorCounter(void)
823 {
824   uint8_t counter=0;
825 
826   /* Check the parameters */
827   assert_param(IS_CAN_ALL_PERIPH(CANx));
828 
829   /* Get the LSB of the 8-bit CAN Transmit Error Counter(TEC) */
830   counter = (uint8_t)(CAN1_PELI->TXERR);
831 
832   /* Return the LSB of the 8-bit CAN Transmit Error Counter(TEC) */
833   return counter;
834 }
835 /** @defgroup CAN_Group6 Interrupts and flags management functions
836 *  @brief   Interrupts and flags management functions
837 *
838 @verbatim
839 ===============================================================================
840 ##### Interrupts and flags management functions #####
841 ===============================================================================
842 [..] This section provides functions allowing to configure the CAN Interrupts
843 and to get the status and clear flags and Interrupts pending bits.
844 [..] The CAN provides 14 Interrupts sources and 15 Flags:
845 
846 *** Flags ***
847 =============
848 */
849 /**
850 * @brief  Enables or disables the specified CAN interrupts in peli workmode.
851 * @param  CAN_IT: specifies the CAN interrupt sources to be enabled or disabled.
852 *          This parameter can be:
853 *            @arg CAN_IT_RI: Receive FIFO not empty Interrupt
854 *            @arg CAN_IT_TI: Transmit Interrupt
855 *            @arg CAN_IT_EI: ERROR Interrupt
856 *            @arg CAN_IT_DOI: Data voerflow Interrupt
857 *            @arg CAN_IT_WUI: Wakeup Interrupt
858 *            @arg CAN_IT_EPI(only Peli): passive error Interrupt
859 *            @arg CAN_IT_ALI(only Peli): arbiter lose Interrupt
860 *            @arg CAN_IT_BEI(only Peli): bus error Interrupt
861 @arg CAN_IT_ALL: use it can enble all Interrupt
862 * @param  NewState: new state of the CAN interrupts.
863 *          This parameter can be: ENABLE or DISABLE.
864 * @retval None
865 */
CAN_Peli_ITConfig(uint32_t CAN_IT,FunctionalState NewState)866 void CAN_Peli_ITConfig(uint32_t CAN_IT, FunctionalState NewState)
867 {
868   /* Check the parameters */
869   assert_param(IS_CAN_IT(CAN_IT));
870   assert_param(IS_FUNCTIONAL_STATE(NewState));
871 
872   if (NewState != DISABLE)
873   {
874     /* Enable the selected CAN interrupt */
875     CAN1_PELI->IER |= CAN_IT;
876   }
877   else
878   {
879     /* Disable the selected CAN interrupt */
880     CAN1_PELI->IER &= ~CAN_IT;
881   }
882 }
883 
884 
885 /**
886 * @brief  Checks whether the specified CAN interrupt has occurred or not.
887 * @param  CAN_IT: specifies the CAN interrupt source to check.
888 *          This parameter can be one of the following values:
889 *            @arg CAN_IT_RI: Receive FIFO not empty Interrupt
890 *            @arg CAN_IT_TI: Transmit Interrupt
891 *            @arg CAN_IT_EI: ERROR Interrupt
892 *            @arg CAN_IT_DOI: Data voerflow Interrupt
893 *            @arg CAN_IT_WUI: Wakeup Interrupt
894 *            @arg CAN_IT_EPI(only Peli): passive error Interrupt
895 *            @arg CAN_IT_ALI(only Peli): arbiter lose Interrupt
896 *            @arg CAN_IT_BEI(only Peli): bus error Interrupt
897 @arg CAN_IT_ALL: use it can enble all Interrupt
898 * @retval The current state of CAN_IT (SET or RESET).
899 */
CAN_Peli_GetITStatus(uint32_t CAN_IT)900 ITStatus CAN_Peli_GetITStatus(uint32_t CAN_IT)
901 {
902   ITStatus itstatus = RESET;
903   /* Check the parameters */
904   assert_param(IS_CAN_IT(CAN_IT));
905 
906   /* check the interrupt enable bit */
907   if((CAN1_PELI->IR & CAN_IT) != CAN_IT)
908   {
909     itstatus = RESET;
910   }
911   else
912   {
913     itstatus = SET;
914   }
915 
916   return itstatus;
917 }
918 
919 /**
920 * @brief  Config CAN_Peli_InitTypeDef baud parameter.
921 * @param  CAN_Peli_InitTypeDef: CAN struct.
922 * @param  SrcClk: CAN module clock.
923 * @param  baud: specified baud.
924 * @retval The current state of CAN_IT (SET or RESET).
925 */
CAN_AutoCfg_BaudParam(CAN_Peli_InitTypeDef * CAN_Peli_InitStruct,unsigned int SrcClk,unsigned int baud)926 void CAN_AutoCfg_BaudParam(CAN_Peli_InitTypeDef  *CAN_Peli_InitStruct,unsigned int SrcClk,unsigned int baud )
927 {
928   unsigned int i,value = baud,record = 1;
929   unsigned int remain = 0,sumPrescaler = 0;
930   while(( baud == 0 )||( SrcClk == 0 ));//��ֹ�����ʼ�ʱ��Ϊ0
931   sumPrescaler = SrcClk/baud;//�ܷ�Ƶ
932   sumPrescaler = sumPrescaler/2;//
933   for( i = 25;i > 3;i -- )
934   {
935     remain = sumPrescaler - ((sumPrescaler / i)*i);
936     if( remain == 0 )		//����
937     {
938       record = i;
939       break;
940     }
941     else
942     {
943       if(remain < value)
944       {
945         value = remain;
946         record = i;
947       }
948     }
949   }
950   CAN_Peli_InitStruct->SJW = 0;
951   CAN_Peli_InitStruct->BRP = (sumPrescaler/record) - 1;
952   CAN_Peli_InitStruct->TESG2 = (record-3)/3;
953   CAN_Peli_InitStruct->TESG1 = (record-3) - CAN_Peli_InitStruct->TESG2;
954 }
955 /**
956 * @}
957 */
958 
959 /**
960 * @}
961 */
962 
963 /**
964 * @}
965 */
966 
967 /*-------------------------(C) COPYRIGHT 2017 MindMotion ----------------------*/
968 
969