1 /**
2   ******************************************************************************
3   * @file    tae32f53xx_ll_can.c
4   * @author  MCD Application Team
5   * @brief   CAN LL Module Driver.
6   *
7   ******************************************************************************
8   * @attention
9   *
10   * <h2><center>&copy; Copyright (c) 2020 Tai-Action.
11   * All rights reserved.</center></h2>
12   *
13   * This software is licensed by Tai-Action under BSD 3-Clause license,
14   * the "License"; You may not use this file except in compliance with the
15   * License. You may obtain a copy of the License at:
16   *                        opensource.org/licenses/BSD-3-Clause
17   *
18   ******************************************************************************
19   */
20 
21 /* Includes ------------------------------------------------------------------*/
22 #include "tae32f53xx_ll.h"
23 
24 
25 #define DBG_TAG             "CAN LL"
26 #define DBG_LVL             DBG_ERROR
27 #include "dbg/tae32f53xx_dbg.h"
28 
29 
30 /** @addtogroup TAE32F53xx_LL_Driver
31   * @{
32   */
33 
34 /** @defgroup CAN_LL CAN LL
35   * @brief    CAN LL Module Driver
36   * @{
37   */
38 
39 #ifdef LL_CAN_MODULE_ENABLED
40 
41 /* Private define ------------------------------------------------------------*/
42 /* Private variables ---------------------------------------------------------*/
43 /* Private typedef -----------------------------------------------------------*/
44 /* Private macro -------------------------------------------------------------*/
45 /* Private function prototypes -----------------------------------------------*/
46 /** @addtogroup CAN_LL_Private_Functions
47   * @{
48   */
49 LL_StatusETypeDef LL_CAN_AcceptFilCfg(CAN_TypeDef *Instance, CAN_AcceptFilCfgTypeDef *fil_cfg);
50 /**
51   * @}
52   */
53 
54 /* Exported functions --------------------------------------------------------*/
55 /** @defgroup CAN_LL_Exported_Functions CAN LL Exported Functions
56   * @brief    CAN LL Exported Functions
57   * @{
58   */
59 
60 /** @defgroup CAN_LL_Exported_Functions_Group1 Initialization and de-initialization functions
61   * @brief    Initialization and de-initialization functions
62   * @{
63   */
64 
65 /**
66   * @brief  CAN LL Init
67   * @param  Instance Specifies CAN peripheral
68   * @param  user_cfg user config pointer
69   * @return Status of the Initialization
70   */
LL_CAN_Init(CAN_TypeDef * Instance,CAN_UserCfgTypeDef * user_cfg)71 LL_StatusETypeDef LL_CAN_Init(CAN_TypeDef *Instance, CAN_UserCfgTypeDef *user_cfg)
72 {
73     assert_param(Instance);
74     assert_param(user_cfg);
75 
76     /* Init the low level hardware eg. Clock, NVIC */
77     LL_CAN_MspInit(Instance);
78 
79     /* Set reset status to config some register which can config in reset status only */
80     __LL_CAN_Reset_Set(Instance);
81 
82     //Baudrate config
83     assert_param(user_cfg->baudrate);
84     __LL_CAN_SS_Prescaler_Set(Instance, (LL_SYSCTRL_AHBClkGet() / 10 / user_cfg->baudrate - 1));
85 
86     //Bit timing config
87     __LL_CAN_SS_BitTimingSeg1_Set(Instance, user_cfg->bit_timing_seg1);
88     __LL_CAN_SS_BitTimingSeg2_Set(Instance, user_cfg->bit_timing_seg2);
89     __LL_CAN_SS_SyncJumpWidth_Set(Instance, user_cfg->bit_timing_sjw);
90 
91     //Acceptance filter config
92     for (uint8_t i = 0; i < user_cfg->accept_fil_cfg_num; i++) {
93         LL_CAN_AcceptFilCfg(Instance, (CAN_AcceptFilCfgTypeDef *)&user_cfg->accept_fil_cfg_ptr[i]);
94     }
95 
96     /*Clear reset status to config other register */
97     __LL_CAN_Reset_Clr(Instance);
98 
99     //RX buffer almost full and error warning limit set
100     __LL_CAN_RxBufAlmostFullLimit_Set(Instance, user_cfg->rx_almost_full_limit);
101     __LL_CAN_ErrWarnLimit_Set(Instance, user_cfg->err_limit);
102 
103     return LL_OK;
104 }
105 
106 /**
107   * @brief  CAN LL DeInit
108   * @param  Instance Specifies CAN peripheral
109   * @return Status of the DeInitialization
110   */
LL_CAN_DeInit(CAN_TypeDef * Instance)111 LL_StatusETypeDef LL_CAN_DeInit(CAN_TypeDef *Instance)
112 {
113     /* DeInit the low level hardware eg. Clock, NVIC */
114     LL_CAN_MspDeInit(Instance);
115 
116     return LL_OK;
117 }
118 
119 /**
120   * @brief  Initializes the CAN MSP.
121   * @param  Instance Specifies CAN peripheral
122   * @return None
123   */
LL_CAN_MspInit(CAN_TypeDef * Instance)124 __WEAK void LL_CAN_MspInit(CAN_TypeDef *Instance)
125 {
126     /* Prevent unused argument(s) compilation warning */
127     LL_UNUSED(Instance);
128     /* NOTE: This function should not be modified, when the callback is needed,
129              the LL_CAN_MspInit could be implemented in the user file
130      */
131 }
132 
133 /**
134   * @brief  DeInitializes the CAN MSP
135   * @param  Instance Specifies CAN peripheral
136   * @return None
137   */
LL_CAN_MspDeInit(CAN_TypeDef * Instance)138 __WEAK void LL_CAN_MspDeInit(CAN_TypeDef *Instance)
139 {
140     /* Prevent unused argument(s) compilation warning */
141     LL_UNUSED(Instance);
142     /* NOTE: This function should not be modified, when the callback is needed,
143              the LL_CAN_MspDeInit could be implemented in the user file
144      */
145 }
146 
147 /**
148   * @}
149   */
150 
151 /** @defgroup CAN_LL_Exported_Functions_Group2 Send data functions
152   * @brief    Send data functions
153   * @{
154   */
155 
156 /**
157   * @brief  CAN LL send standard primary transmit buffer
158   * @param  Instance Specifies CAN peripheral
159   * @param  buf_fmt buffer format pointer
160   * @param  buf buffer pointer
161   * @return success send length in byte
162   */
LL_CAN_SendStandard_PTB(CAN_TypeDef * Instance,CAN_TxBufFormatTypeDef * buf_fmt,uint32_t * buf)163 uint32_t LL_CAN_SendStandard_PTB(CAN_TypeDef *Instance, CAN_TxBufFormatTypeDef *buf_fmt, uint32_t *buf)
164 {
165     uint32_t i, j;
166 
167     assert_param(Instance);
168     assert_param(buf_fmt);
169     assert_param(buf);
170 
171     //TX buffer select PTB
172     __LL_CAN_TxBufSel_PTB(Instance);
173 
174     //Write buffer format data to TX buffer
175     Instance->TXBUF[0] = *((uint32_t *)buf_fmt);
176     Instance->TXBUF[1] = *(((uint32_t *)buf_fmt) + 1);
177 
178     //Write data to TX buffer
179     for (i = 0, j = 0; i < buf_fmt->data_len_code; i += 4, j++) {
180         Instance->TXBUF[2 + j] = *buf++;
181     }
182 
183     //TX primary enable
184     __LL_CAN_TxPriEn_Set(Instance);
185 
186     //Wait TX complete
187     while (__LL_CAN_TxPriEn_Get(Instance));
188 
189     return buf_fmt->data_len_code;
190 }
191 
192 /**
193   * @brief  CAN LL send standard secondary transmit buffer
194   * @param  Instance Specifies CAN peripheral
195   * @param  buf_fmt buffer format pointer
196   * @param  buf buffer pointer
197   * @return success send length in byte
198   */
LL_CAN_SendStandard_STB(CAN_TypeDef * Instance,CAN_TxBufFormatTypeDef * buf_fmt,uint32_t * buf)199 uint32_t LL_CAN_SendStandard_STB(CAN_TypeDef *Instance, CAN_TxBufFormatTypeDef *buf_fmt, uint32_t *buf)
200 {
201     uint32_t i, j;
202 
203     assert_param(Instance);
204     assert_param(buf_fmt);
205     assert_param(buf);
206 
207     //TX buffer select STB
208     __LL_CAN_TxBufSel_STB(Instance);
209 
210     //Write buffer format data to TX buffer
211     Instance->TXBUF[0] = *((uint32_t *)buf_fmt);
212     Instance->TXBUF[1] = *(((uint32_t *)buf_fmt) + 1);
213 
214     //Write data to TX buffer
215     for (i = 0, j = 0; i < buf_fmt->data_len_code; i += 4, j++) {
216         Instance->TXBUF[2 + j] = *buf++;
217     }
218 
219     //TX buffer Secondary next
220     __LL_CAN_TxSecNext_Set(Instance);
221 
222     //TX secondary send one start
223     __LL_CAN_TxSecOne_Set(Instance);
224 
225     //Wait TX complete
226     while (__LL_CAN_TxSecOne_Get(Instance));
227 
228     return buf_fmt->data_len_code;
229 }
230 
231 /**
232   * @brief  CAN LL send a multi-package standard secondary transmit buffer
233   * @param  Instance Specifies CAN peripheral
234   * @param  buf_fmt buffer format pointer
235   * @param  buf buffer pointer
236   * @param  send_cnt send packets count
237   * @return success send length in byte
238   */
LL_CAN_SendStandard_STB_Multi(CAN_TypeDef * Instance,CAN_TxBufFormatTypeDef * buf_fmt,uint32_t * buf,uint32_t send_cnt)239 uint32_t LL_CAN_SendStandard_STB_Multi(CAN_TypeDef *Instance, CAN_TxBufFormatTypeDef *buf_fmt,
240                                        uint32_t *buf, uint32_t send_cnt)
241 {
242     uint32_t i, j, cnt;
243 
244     assert_param(Instance);
245     assert_param(buf_fmt);
246     assert_param(buf);
247 
248     //TX buffer select STB
249     __LL_CAN_TxBufSel_STB(Instance);
250 
251     for (cnt = 0; cnt < send_cnt; cnt++) {
252         //Write buffer format data to TX buffer
253         Instance->TXBUF[0] = *((uint32_t *)buf_fmt);
254         Instance->TXBUF[1] = *(((uint32_t *)buf_fmt) + 1);
255 
256         //Write data to TX buffer
257         for (i = 0, j = 0; i < buf_fmt->data_len_code; i += 4, j++) {
258             Instance->TXBUF[2 + j] = *buf++;
259         }
260 
261         //TX buffer Secondary next
262         __LL_CAN_TxSecNext_Set(Instance);
263 
264         //TX buffer Secondary full and send
265         if (__LL_CAN_IsTxSecBufFull(Instance)) {
266             //TX secondary send all start
267             __LL_CAN_TxSecAll_Set(Instance);
268 
269             //Wait TX complete
270             while (__LL_CAN_TxSecAll_Get(Instance));
271         }
272     }
273 
274     //TX secondary send all start
275     __LL_CAN_TxSecAll_Set(Instance);
276 
277     //Wait TX complete
278     while (__LL_CAN_TxSecAll_Get(Instance));
279 
280     return buf_fmt->data_len_code * send_cnt;
281 }
282 
283 /**
284   * @}
285   */
286 
287 /** @defgroup CAN_LL_Exported_Functions_Interrupt CAN Interrupt handler and call back
288   * @brief    CAN Interrupt handler and call back
289   * @{
290   */
291 
292 /**
293   * @brief  CAN IRQ Handler
294   * @param  Instance Specifies CAN peripheral
295   * @note   All interrupt pending will be reset immediately after a read access
296   * @return None
297   */
LL_CAN_IRQHandler(CAN_TypeDef * Instance)298 void LL_CAN_IRQHandler(CAN_TypeDef *Instance)
299 {
300     uint8_t txrx_int_sta = __LL_CAN_IntSta_Get(Instance);
301     uint8_t err_int_sta  = __LL_CAN_ErrIntSta_Get(Instance);
302 
303     if (txrx_int_sta & CAN_RX_INT_STA_Msk) {
304         LL_CAN_RxCallback(Instance);
305     }
306 
307     if (txrx_int_sta & CAN_RX_BUF_OVER_INT_STA_Msk) {
308         LL_CAN_RxOverCallback(Instance);
309     }
310 
311     if (txrx_int_sta & CAN_RX_BUF_FULL_INT_STA_Msk) {
312         LL_CAN_RxFullCallback(Instance);
313     }
314 
315     if (txrx_int_sta & CAN_RX_BUF_ALMOST_FULL_INT_STA_Msk) {
316         LL_CAN_RxAlmostFullCallback(Instance);
317     }
318 
319     if (txrx_int_sta & CAN_TX_PRI_INT_STA_Msk) {
320         LL_CAN_TxPriCallback(Instance);
321     }
322 
323     if (txrx_int_sta & CAN_TX_SEC_INT_STA_Msk) {
324         LL_CAN_TxSecCallback(Instance);
325     }
326 
327     if (txrx_int_sta & CAN_ERR_INT_STA_Msk) {
328         LL_CAN_ErrCallback(Instance);
329     }
330 
331     if (txrx_int_sta & CAN_ABORT_INT_STA_Msk) {
332         LL_CAN_AbortCallback(Instance);
333     }
334 
335 
336     if (err_int_sta & CAN_ERR_PASS_INT_STA_Msk) {
337         LL_CAN_ErrPassiveCallback(Instance);
338     }
339 
340     if (err_int_sta & CAN_ARB_LOST_INT_STA_Msk) {
341         LL_CAN_ArbLostCallback(Instance);
342     }
343 
344     if (err_int_sta & CAN_BUS_ERR_INT_STA_Msk) {
345         LL_CAN_BusErrCallback(Instance);
346     }
347 }
348 
349 
350 /**
351   * @brief  CAN RX interrupt callback
352   * @param  Instance Specifies CAN peripheral
353   * @return None
354   */
LL_CAN_RxCallback(CAN_TypeDef * Instance)355 __WEAK void LL_CAN_RxCallback(CAN_TypeDef *Instance)
356 {
357     /* Prevent unused argument(s) compilation warning */
358     LL_UNUSED(Instance);
359     /* NOTE: This function should not be modified, when the callback is needed,
360              the LL_CAN_RxCallback could be implemented in the user file
361      */
362 }
363 
364 /**
365   * @brief  CAN RX over interrupt callback
366   * @param  Instance Specifies CAN peripheral
367   * @return None
368   */
LL_CAN_RxOverCallback(CAN_TypeDef * Instance)369 __WEAK void LL_CAN_RxOverCallback(CAN_TypeDef *Instance)
370 {
371     /* Prevent unused argument(s) compilation warning */
372     LL_UNUSED(Instance);
373     /* NOTE: This function should not be modified, when the callback is needed,
374              the LL_CAN_RxOverCallback could be implemented in the user file
375      */
376 }
377 
378 /**
379   * @brief  CAN RX full interrupt callback
380   * @param  Instance Specifies CAN peripheral
381   * @return None
382   */
LL_CAN_RxFullCallback(CAN_TypeDef * Instance)383 __WEAK void LL_CAN_RxFullCallback(CAN_TypeDef *Instance)
384 {
385     /* Prevent unused argument(s) compilation warning */
386     LL_UNUSED(Instance);
387     /* NOTE: This function should not be modified, when the callback is needed,
388              the LL_CAN_RxFullCallback could be implemented in the user file
389      */
390 }
391 
392 /**
393   * @brief  CAN RX almost full interrupt callback
394   * @param  Instance Specifies CAN peripheral
395   * @return None
396   */
LL_CAN_RxAlmostFullCallback(CAN_TypeDef * Instance)397 __WEAK void LL_CAN_RxAlmostFullCallback(CAN_TypeDef *Instance)
398 {
399     /* Prevent unused argument(s) compilation warning */
400     LL_UNUSED(Instance);
401     /* NOTE: This function should not be modified, when the callback is needed,
402              the LL_CAN_RxAlmostFullCallback could be implemented in the user file
403      */
404 }
405 
406 /**
407   * @brief  CAN TX primary interrupt callback
408   * @param  Instance Specifies CAN peripheral
409   * @return None
410   */
LL_CAN_TxPriCallback(CAN_TypeDef * Instance)411 __WEAK void LL_CAN_TxPriCallback(CAN_TypeDef *Instance)
412 {
413     /* Prevent unused argument(s) compilation warning */
414     LL_UNUSED(Instance);
415     /* NOTE: This function should not be modified, when the callback is needed,
416              the LL_CAN_TxPriCallback could be implemented in the user file
417      */
418 }
419 
420 /**
421   * @brief  CAN TX secondary interrupt callback
422   * @param  Instance Specifies CAN peripheral
423   * @return None
424   */
LL_CAN_TxSecCallback(CAN_TypeDef * Instance)425 __WEAK void LL_CAN_TxSecCallback(CAN_TypeDef *Instance)
426 {
427     /* Prevent unused argument(s) compilation warning */
428     LL_UNUSED(Instance);
429     /* NOTE: This function should not be modified, when the callback is needed,
430              the LL_CAN_TxSecCallback could be implemented in the user file
431      */
432 }
433 
434 /**
435   * @brief  CAN error interrupt callback
436   * @param  Instance Specifies CAN peripheral
437   * @return None
438   */
LL_CAN_ErrCallback(CAN_TypeDef * Instance)439 __WEAK void LL_CAN_ErrCallback(CAN_TypeDef *Instance)
440 {
441     /* Prevent unused argument(s) compilation warning */
442     LL_UNUSED(Instance);
443     /* NOTE: This function should not be modified, when the callback is needed,
444              the LL_CAN_ErrCallback could be implemented in the user file
445      */
446 }
447 
448 /**
449   * @brief  CAN abort interrupt callback
450   * @param  Instance Specifies CAN peripheral
451   * @return None
452   */
LL_CAN_AbortCallback(CAN_TypeDef * Instance)453 __WEAK void LL_CAN_AbortCallback(CAN_TypeDef *Instance)
454 {
455     /* Prevent unused argument(s) compilation warning */
456     LL_UNUSED(Instance);
457     /* NOTE: This function should not be modified, when the callback is needed,
458              the LL_CAN_AbortCallback could be implemented in the user file
459      */
460 }
461 
462 /**
463   * @brief  CAN error passive interrupt callback
464   * @param  Instance Specifies CAN peripheral
465   * @return None
466   */
LL_CAN_ErrPassiveCallback(CAN_TypeDef * Instance)467 __WEAK void LL_CAN_ErrPassiveCallback(CAN_TypeDef *Instance)
468 {
469     /* Prevent unused argument(s) compilation warning */
470     LL_UNUSED(Instance);
471     /* NOTE: This function should not be modified, when the callback is needed,
472              the LL_CAN_ErrPassiveCallback could be implemented in the user file
473      */
474 }
475 
476 /**
477   * @brief  CAN arbitration lost interrupt callback
478   * @param  Instance Specifies CAN peripheral
479   * @return None
480   */
LL_CAN_ArbLostCallback(CAN_TypeDef * Instance)481 __WEAK void LL_CAN_ArbLostCallback(CAN_TypeDef *Instance)
482 {
483     /* Prevent unused argument(s) compilation warning */
484     LL_UNUSED(Instance);
485     /* NOTE: This function should not be modified, when the callback is needed,
486              the LL_CAN_ArbLostCallback could be implemented in the user file
487      */
488 }
489 
490 /**
491   * @brief  CAN bus error interrupt callback
492   * @param  Instance Specifies CAN peripheral
493   * @return None
494   */
LL_CAN_BusErrCallback(CAN_TypeDef * Instance)495 __WEAK void LL_CAN_BusErrCallback(CAN_TypeDef *Instance)
496 {
497     /* Prevent unused argument(s) compilation warning */
498     LL_UNUSED(Instance);
499     /* NOTE: This function should not be modified, when the callback is needed,
500              the LL_CAN_BusErrCallback could be implemented in the user file
501      */
502 }
503 
504 
505 /**
506   * @}
507   */
508 
509 /**
510   * @}
511   */
512 
513 /* Private functions ---------------------------------------------------------*/
514 /** @defgroup CAN_LL_Private_Functions CAN LL Private Functions
515   * @brief    CAN LL Private Functions
516   * @{
517   */
518 
519 /**
520   * @brief  CAN LL acceptance filter config
521   * @param  Instance Specifies CAN peripheral
522   * @param  fil_cfg filter config pointer
523   * @return Config result
524   */
LL_CAN_AcceptFilCfg(CAN_TypeDef * Instance,CAN_AcceptFilCfgTypeDef * fil_cfg)525 LL_StatusETypeDef LL_CAN_AcceptFilCfg(CAN_TypeDef *Instance, CAN_AcceptFilCfgTypeDef *fil_cfg)
526 {
527     assert_param(Instance);
528     assert_param(fil_cfg);
529 
530     //Check in reset status or not
531     if (!__LL_CAN_ResetSta_Get(Instance)) {
532         LOG_E("Acceptance filter register can config in reset status only!\n");
533         return LL_ERROR;
534     }
535 
536     //CAN acceptance filter Code and Mask config
537     __LL_CAN_AcceptFilAddr_Set(Instance, fil_cfg->slot);
538     __LL_CAN_AcceptFilContentSel_Code(Instance);
539     __LL_CAN_AcceptFilCodeOrMaskVal_Set(Instance, fil_cfg->code_val);
540     __LL_CAN_AcceptFilContentSel_Mask(Instance);
541     __LL_CAN_AcceptFilCodeOrMaskVal_Set(Instance, fil_cfg->mask_val);
542 
543     //CAN acceptance filter enable
544     __LL_CAN_AcceptFil_En(Instance, ((uint8_t)fil_cfg->slot));
545 
546     return LL_OK;
547 }
548 
549 
550 /**
551   * @}
552   */
553 
554 #endif  /* LL_CAN_MODULE_ENABLED */
555 
556 /**
557   * @}
558   */
559 
560 /**
561   * @}
562   */
563 
564 /************************* (C) COPYRIGHT Tai-Action *****END OF FILE***********/
565 
566