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>© 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