1 /*
2  * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Change Logs:
19  * Date           Author        Notes
20  * 2020-01-14     wangyq        the first version
21  * 2021-04-20     liuhy         the second version
22  */
23 
24 #include "drv_can.h"
25 
26 #ifdef RT_USING_CAN
27 
28 static struct es32f3_can can;
29 
30 
get_can_baud_index(rt_uint32_t baud,can_init_t * init)31 static rt_uint32_t get_can_baud_index(rt_uint32_t baud,can_init_t * init)
32 {
33 /* attention !!! baud calculation example: Pclk / ((1 + seg1 + seg2) * psc)       Pclk=48 / ((1 + seg1=3 + seg2=2) * 8) = 1MHz */
34     double target,temp,min;
35     uint32_t i,j,j_max,near = 0;
36     target = (double)(ald_cmu_get_pclk1_clock());
37     target/= baud;                               /*计算误差1*/
38 
39     min = 0xFFFFFFFF;
40 
41     for(i = 1 + 16 + 8 ;i > 2;i--)     /*SYNC_SEG + SEG1 + SEG2*/
42     {
43         j_max = target/i/(0.98) + 1;                          /*缩小范围*/
44         j_max = (j_max > 1024) ? (1024) : (j_max);
45 
46         for(j = target/i/1.02 ;j < j_max;j++)
47         {
48             temp = target/i/j;                      /*计算误差2*/
49             temp = (temp > 1) ? (temp - 1) : (1 - temp);
50             temp+= ((1.0 * i * j) / 0xFFFFFFFF) ;
51 
52             if(temp < min)
53             {
54                 if(temp > 0.000001)
55                 {
56                      near = (i<<16) + j;
57                      min = temp;
58                 }
59                 else
60                 {
61                      init->seg1 = (can_seg1_t)((i - 1)*2/3-1);
62                      init->seg2 = (can_seg2_t)(i - init->seg1 - 1 - 1 - 1);
63                      init->psc = j;
64 
65                      return 0;
66                  }
67              }
68          }
69     }
70 
71     if(min < 0.01)
72     {
73         i = near>>16;
74         j = near % (1<<16);
75         init->seg1 = (can_seg1_t)((i - 1)*2/3-1);
76         init->seg2 = (can_seg2_t)(i - init->seg1 - 1 - 1 - 1);
77         init->psc = j;
78 
79         return 0;
80     }
81     else
82     {
83         return 1;
84     }
85 }
86 
87 
_can_config(struct rt_can_device * can_device,struct can_configure * cfg)88 static rt_err_t _can_config(struct rt_can_device *can_device, struct can_configure *cfg)
89 {
90     struct es32f3_can *drv_can;
91 
92     RT_ASSERT(can_device);
93     RT_ASSERT(cfg);
94     drv_can = (struct es32f3_can *)can_device->parent.user_data;
95     RT_ASSERT(drv_can);
96 
97     drv_can->CanHandle.perh = CAN0;
98     drv_can->CanHandle.init.ttcm = DISABLE;
99     drv_can->CanHandle.init.abom = ENABLE;
100     drv_can->CanHandle.init.awk = DISABLE;
101     drv_can->CanHandle.init.artx = (type_func_t)ES_CAN0_AUTO_BAN_RE_T;
102     drv_can->CanHandle.init.rfom   = DISABLE;
103     drv_can->CanHandle.init.txmp   = ENABLE;
104 
105     switch (cfg->mode)
106     {
107     case RT_CAN_MODE_NORMAL:
108         drv_can->CanHandle.init.mode = CAN_MODE_NORMAL;
109         break;
110     case RT_CAN_MODE_LISTEN:
111         drv_can->CanHandle.init.mode = CAN_MODE_SILENT;
112         break;
113     case RT_CAN_MODE_LOOPBACK:
114         drv_can->CanHandle.init.mode = CAN_MODE_LOOPBACK;
115         break;
116     case RT_CAN_MODE_LOOPBACKANLISTEN:
117         drv_can->CanHandle.init.mode = CAN_MODE_SILENT_LOOPBACK;
118         break;
119     }
120     /*配置参数*/
121     if(get_can_baud_index(cfg->baud_rate,&(drv_can->CanHandle.init)))
122     {
123         return -RT_ERROR;
124     }
125     drv_can->CanHandle.init.sjw = (can_sjw_t)(cfg->reserved);
126 
127     /* init can */
128     if (ald_can_init(&drv_can->CanHandle) != OK)
129     {
130         return -RT_ERROR;
131     }
132     /* default filter config */
133     ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
134 
135     return RT_EOK;
136 }
137 
_can_control(struct rt_can_device * can_device,int cmd,void * arg)138 static rt_err_t _can_control(struct rt_can_device *can_device, int cmd, void *arg)
139 {
140     rt_uint32_t argval;
141 
142     struct es32f3_can *drv_can;
143 
144 #ifdef RT_CAN_USING_HDR
145     struct rt_can_filter_config *filter_cfg;
146 #endif
147 
148     RT_ASSERT(can_device != RT_NULL);
149     drv_can = (struct es32f3_can *)can_device->parent.user_data;
150     RT_ASSERT(drv_can != RT_NULL);
151 
152     switch (cmd)
153     {
154     case RT_DEVICE_CTRL_CLR_INT:
155         argval = (rt_uint32_t) arg;
156         if (argval == RT_DEVICE_FLAG_INT_RX)
157         {
158             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FP0, DISABLE);
159             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FF0, DISABLE);
160             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FOV0, DISABLE);
161             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FP1, DISABLE);
162             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FF1, DISABLE);
163             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FOV1, DISABLE);
164         }
165         else if (argval == RT_DEVICE_FLAG_INT_TX)
166         {
167             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, DISABLE);
168         }
169         else if (argval == RT_DEVICE_CAN_INT_ERR)
170         {
171             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_WARN, DISABLE);
172             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_PERR, DISABLE);
173             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_BOF, DISABLE);
174             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_PRERR, DISABLE);
175             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_ERR, DISABLE);
176         }
177         break;
178     case RT_DEVICE_CTRL_SET_INT:
179         argval = (rt_uint32_t) arg;
180         if (argval == RT_DEVICE_FLAG_INT_RX)
181         {
182             NVIC_SetPriority(CAN0_RX0_IRQn, 1);
183             NVIC_EnableIRQ(CAN0_RX0_IRQn);
184 
185             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FP0, ENABLE);
186 //            ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FF0, ENABLE);
187             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FOV0, ENABLE);
188             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FP1, ENABLE);
189 //            ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FF1, ENABLE);
190             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_FOV1, ENABLE);
191 
192         }
193         else if (argval == RT_DEVICE_FLAG_INT_TX)
194         {
195             NVIC_SetPriority(CAN0_TX_IRQn, 1);
196             NVIC_EnableIRQ(CAN0_TX_IRQn);
197 
198             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_TXM, ENABLE);
199         }
200         else if (argval == RT_DEVICE_CAN_INT_ERR)
201         {
202             NVIC_SetPriority(CAN0_EXCEPTION_IRQn, 1);
203             NVIC_EnableIRQ(CAN0_EXCEPTION_IRQn);
204 
205             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_WARN, ENABLE);
206             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_PERR, ENABLE);
207             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_BOF, ENABLE);
208             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_PRERR, ENABLE);
209             ald_can_interrupt_config(&drv_can->CanHandle, CAN_IT_ERR, ENABLE);
210 
211         }
212         break;
213 #ifdef RT_CAN_USING_HDR
214     case RT_CAN_CMD_SET_FILTER:
215         if (RT_NULL == arg)
216         {
217             /* default filter config */
218             ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
219         }
220         else
221         {
222             filter_cfg = (struct rt_can_filter_config *)arg;
223             /* get default filter */
224             for (int i = 0; i < filter_cfg->count; i++)
225             {
226 
227                 /*默认过滤表判断*/
228                 if(filter_cfg->items[i].hdr_bank < drv_can->device.config.maxhdr)
229                     drv_can->FilterConfig.number = filter_cfg->items[i].hdr_bank;
230                 else
231                     drv_can->FilterConfig.number = ES_C_CAN_DEFAULT_FILTER_NUMBER;
232 
233                if(filter_cfg->items[i].mode)
234                {
235                     /*标识符列表模式: 类型匹配 ,id匹配为:接收的id = 配置的id
236                                                                 或者 = 配置的mask ,通过*/
237                     /*扩展帧*/
238                     if(filter_cfg->items[i].ide)
239                     {
240 //                         filter_cfg->items[i].id =  filter_cfg->items[i].id ;    /*id 29 位*/
241                          filter_cfg->items[i].mask = ((filter_cfg->items[i].mask << 3) |
242                                                     (filter_cfg->items[i].ide << 2) |
243                                                     (filter_cfg->items[i].rtr << 1));
244                     }
245                     else  /*标准帧*/
246                     {
247                          filter_cfg->items[i].id = (filter_cfg->items[i].id << 18);
248                          filter_cfg->items[i].mask = ((filter_cfg->items[i].mask << 21) |
249                                                     (filter_cfg->items[i].ide << 2) |
250                                                     (filter_cfg->items[i].rtr << 1));
251                     }
252                 }
253                 else
254                 {
255                     /*标识符掩码模式*/
256                     /*扩展帧*/
257                     if(filter_cfg->items[i].ide)
258                     {
259                          filter_cfg->items[i].mask = (filter_cfg->items[i].mask)<<3;
260                     }
261                     else  /*标准帧*/
262                     {
263                          filter_cfg->items[i].id = (filter_cfg->items[i].id)<<18;
264                          filter_cfg->items[i].mask = (filter_cfg->items[i].mask)<<21;
265                     }
266 
267 #if   ES_C_CAN_FILTER_FRAME_TYPE
268                     /*匹配类型*/
269                     filter_cfg->items[i].mask |= 0x6;
270 #endif
271 
272                 }
273 
274                 drv_can->FilterConfig.id_high = (filter_cfg->items[i].id >> 13) & 0xFFFF;
275                 drv_can->FilterConfig.id_low = ((filter_cfg->items[i].id << 3) |
276                                                 (filter_cfg->items[i].ide << 2) |
277                                                 (filter_cfg->items[i].rtr << 1)) & 0xFFFF;
278                 drv_can->FilterConfig.mask_id_high = (filter_cfg->items[i].mask >> 16) & 0xFFFF;
279                 drv_can->FilterConfig.mask_id_low = filter_cfg->items[i].mask & 0xFFFF;
280 
281                 drv_can->FilterConfig.mode = (can_filter_mode_t)filter_cfg->items[i].mode;
282                 /* Filter conf */
283                 ald_can_filter_config(&drv_can->CanHandle, &drv_can->FilterConfig);
284             }
285         }
286         break;
287 
288 #endif
289     case RT_CAN_CMD_SET_MODE:
290         argval = (rt_uint32_t) arg;
291         if (argval != RT_CAN_MODE_NORMAL &&
292                 argval != RT_CAN_MODE_LISTEN &&
293                 argval != RT_CAN_MODE_LOOPBACK &&
294                 argval != RT_CAN_MODE_LOOPBACKANLISTEN)
295         {
296             return -RT_ERROR;
297         }
298         if (argval != drv_can->device.config.mode)
299         {
300             drv_can->device.config.mode = argval;
301             return _can_config(&drv_can->device, &drv_can->device.config);
302         }
303         break;
304     case RT_CAN_CMD_SET_BAUD:
305         argval = (rt_uint32_t) arg;
306 
307         if (argval != drv_can->device.config.baud_rate)
308         {
309             drv_can->device.config.baud_rate = argval;
310             return _can_config(&drv_can->device, &drv_can->device.config);
311         }
312         break;
313     case RT_CAN_CMD_SET_PRIV:
314         argval = (rt_uint32_t) arg;
315         if (argval != RT_CAN_MODE_PRIV &&
316                 argval != RT_CAN_MODE_NOPRIV)
317         {
318             return -RT_ERROR;
319         }
320         if (argval != drv_can->device.config.privmode)
321         {
322             drv_can->device.config.privmode = argval;
323             return _can_config(&drv_can->device, &drv_can->device.config);
324         }
325         break;
326     case RT_CAN_CMD_GET_STATUS:
327     {
328         rt_uint32_t errtype;
329         errtype = drv_can->CanHandle.perh->ERRSTAT;
330         drv_can->device.status.rcverrcnt = errtype >> 24;
331         drv_can->device.status.snderrcnt = (errtype >> 16 & 0xFF);
332         drv_can->device.status.lasterrtype = errtype & 0x70;
333         drv_can->device.status.errcode = errtype & 0x07;
334 
335         rt_memcpy(arg, &drv_can->device.status, sizeof(drv_can->device.status));
336     }
337     break;
338     }
339 
340     return RT_EOK;
341 }
342 
_can_sendmsg(struct rt_can_device * can,const void * buf,rt_uint32_t box_num)343 static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
344 {
345     can_handle_t *h_can;
346     h_can = &((struct es32f3_can *) can->parent.user_data)->CanHandle;
347     struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
348     can_tx_msg_t txheader = {0};
349     can_state_t state = h_can->state;
350 
351     /* Check the parameters */
352     RT_ASSERT(IS_CAN_DATA_LEN(pmsg->len));
353 
354     if ((state == CAN_STATE_READY) ||
355             (state == CAN_STATE_BUSY_RX0))
356     {
357         /*check select mailbox  is empty */
358         switch (1 << box_num)
359         {
360         case CAN_TX_MAILBOX_0:
361             if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM0) != SET)
362             {
363                 /* Change CAN state */
364                 h_can->state = CAN_STATE_ERROR;
365                 /* Return function status */
366                 return -RT_ERROR;
367             }
368             break;
369         case CAN_TX_MAILBOX_1:
370             if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM1) != SET)
371             {
372                 /* Change CAN state */
373                 h_can->state = CAN_STATE_ERROR;
374                 /* Return function status */
375                 return -RT_ERROR;
376             }
377             break;
378         case CAN_TX_MAILBOX_2:
379             if (ald_can_get_flag_status(h_can, CAN_FLAG_TXM2) != SET)
380             {
381                 /* Change CAN state */
382                 h_can->state = CAN_STATE_ERROR;
383                 /* Return function status */
384                 return -RT_ERROR;
385             }
386             break;
387         default:
388             RT_ASSERT(0);
389             break;
390         }
391 
392         if (RT_CAN_STDID == pmsg->ide)
393         {
394             txheader.type = CAN_ID_STD;
395             RT_ASSERT(IS_CAN_STDID(pmsg->id));
396             txheader.std = pmsg->id;
397         }
398         else
399         {
400             txheader.type = CAN_ID_EXT;
401             RT_ASSERT(IS_CAN_EXTID(pmsg->id));
402             txheader.ext = pmsg->id;
403         }
404 
405         if (RT_CAN_DTR == pmsg->rtr)
406         {
407             txheader.rtr = CAN_RTR_DATA;
408         }
409         else
410         {
411             txheader.rtr = CAN_RTR_REMOTE;
412         }
413         /* clear TIR */
414         h_can->perh->TxMailBox[box_num].TXID &= CAN_TXID0_TXMREQ_MSK;
415 
416         /* Set up the Id */
417         if (RT_CAN_STDID == pmsg->ide)
418         {
419             h_can->perh->TxMailBox[box_num].TXID |= (txheader.std << CAN_TXID0_STDID_POSS) | (txheader.rtr << CAN_TXID0_RTR_POS);
420         }
421         else
422         {
423             h_can->perh->TxMailBox[box_num].TXID |= (txheader.ext << CAN_TXID0_EXID_POSS) | (txheader.type << CAN_TXID0_IDE_POS) | (txheader.rtr << CAN_TXID0_RTR_POS);
424         }
425         /* Set up the DLC */
426         h_can->perh->TxMailBox[box_num].TXFCON = pmsg->len & 0x0FU;
427         /* Set up the data field */
428         WRITE_REG(h_can->perh->TxMailBox[box_num].TXDH,
429                   ((uint32_t)pmsg->data[7] << CAN_TXDH0_BYTE7_POSS) |
430                   ((uint32_t)pmsg->data[6] << CAN_TXDH0_BYTE6_POSS) |
431                   ((uint32_t)pmsg->data[5] << CAN_TXDH0_BYTE5_POSS) |
432                   ((uint32_t)pmsg->data[4] << CAN_TXDH0_BYTE4_POSS));
433         WRITE_REG(h_can->perh->TxMailBox[box_num].TXDL,
434                   ((uint32_t)pmsg->data[3] << CAN_TXDL0_BYTE3_POSS) |
435                   ((uint32_t)pmsg->data[2] << CAN_TXDL0_BYTE2_POSS) |
436                   ((uint32_t)pmsg->data[1] << CAN_TXDL0_BYTE1_POSS) |
437                   ((uint32_t)pmsg->data[0] << CAN_TXDL0_BYTE0_POSS));
438         /* Request transmission */
439         SET_BIT(h_can->perh->TxMailBox[box_num].TXID, CAN_TXID0_TXMREQ_MSK);
440 
441         return RT_EOK;
442     }
443     else
444     {
445         /* Update error code */
446         h_can->err |= 0x00040000U;
447 
448         return -RT_ERROR;
449     }
450 
451 
452 }
453 
_can_recvmsg(struct rt_can_device * can,void * buf,rt_uint32_t fifo)454 static int _can_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t fifo)
455 {
456     can_handle_t *h_can;
457     struct rt_can_msg *pmsg;
458     can_rx_msg_t rxheader = {0};
459 
460     RT_ASSERT(can);
461 
462     h_can = &((struct es32f3_can *)can->parent.user_data)->CanHandle;
463     pmsg = (struct rt_can_msg *) buf;
464 
465     /* get data */
466     if (ald_can_recv(h_can, (can_rx_fifo_t)fifo, &rxheader, 0xFFFF) != OK)
467         return -RT_ERROR;
468     pmsg->data[0] = rxheader.data[0];
469     pmsg->data[1] = rxheader.data[1];
470     pmsg->data[2] = rxheader.data[2];
471     pmsg->data[3] = rxheader.data[3];
472     pmsg->data[4] = rxheader.data[4];
473     pmsg->data[5] = rxheader.data[5];
474     pmsg->data[6] = rxheader.data[6];
475     pmsg->data[7] = rxheader.data[7];
476 
477     /* get id */
478     if (CAN_ID_STD == rxheader.type)
479     {
480         pmsg->ide = RT_CAN_STDID;
481         pmsg->id = rxheader.std;
482     }
483     else
484     {
485         pmsg->ide = RT_CAN_EXTID;
486         pmsg->id = rxheader.ext;
487     }
488     /* get type */
489     if (CAN_RTR_DATA == rxheader.rtr)
490     {
491         pmsg->rtr = RT_CAN_DTR;
492     }
493     else
494     {
495         pmsg->rtr = RT_CAN_RTR;
496     }
497     /* get len */
498     pmsg->len = rxheader.len;
499     /* get hdr_index */
500     pmsg->hdr_index = (rxheader.fmi + 1) >> 1;
501 
502     return RT_EOK;
503 }
504 
505 
506 static const struct rt_can_ops _can_ops =
507 {
508     _can_config,
509     _can_control,
510     _can_sendmsg,
511     _can_recvmsg,
512 };
513 
_can_rx_isr(struct rt_can_device * can,rt_uint32_t fifo)514 static void _can_rx_isr(struct rt_can_device *can, rt_uint32_t fifo)
515 {
516     can_handle_t *h_can;
517     RT_ASSERT(can);
518     h_can = &((struct es32f3_can *) can->parent.user_data)->CanHandle;
519 
520     switch (fifo)
521     {
522     case CAN_RX_FIFO0:
523         /* Check Overrun flag for FIFO0 */
524         if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV0) && ald_can_get_it_status(h_can, CAN_IT_FOV0))
525         {
526             /* Clear FIFO0 Overrun Flag */
527             ald_can_clear_flag_status(h_can, CAN_FLAG_FOV0);
528             rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
529         }
530         /* RX interrupt */
531         else
532         {
533            if(CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO0) != 0)
534             {
535             /* save to user list */
536             rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
537             }
538 
539             /* Clear FIFO0 rx Flag */
540             SET_BIT(h_can->perh->RXF0, CAN_RXF0_FREE_MSK);
541         }
542         break;
543     case CAN_RX_FIFO1:
544         /* Check Overrun flag for FIFO1 */
545         if (ald_can_get_flag_status(h_can, CAN_FLAG_FOV1) && ald_can_get_it_status(h_can, CAN_IT_FOV1))
546         {
547             /* Clear FIFO1 Overrun Flag */
548             ald_can_clear_flag_status(h_can, CAN_FLAG_FOV1);
549             rt_hw_can_isr(can, RT_CAN_EVENT_RXOF_IND | fifo << 8);
550         }
551         /* RX interrupt */
552         else
553         {
554             if(CAN_RX_MSG_PENDING(h_can, CAN_RX_FIFO1) != 0)
555             {
556             /* save to user list */
557             rt_hw_can_isr(can, RT_CAN_EVENT_RX_IND | fifo << 8);
558             }
559 
560             /* Clear FIFO0 rx Flag */
561             SET_BIT(h_can->perh->RXF1, CAN_RXF1_FREE_MSK);
562         }
563         break;
564     }
565 }
566 
567 /**
568  * @brief This function handles CAN0 TX interrupts. transmit fifo0/1/2 is empty can trigger this interrupt
569  */
CAN0_TX_Handler(void)570 void CAN0_TX_Handler(void)
571 {
572     rt_interrupt_enter();
573     can_handle_t *h_can;
574     h_can = &can.CanHandle;
575 
576     /* TX interrupt. transmit fifo0/1/2 is empty can trigger this interrupt */
577     if (ald_can_get_flag_status(h_can, CAN_FLAG_M0REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
578     {
579         if (ald_can_get_flag_status(h_can, CAN_FLAG_M0TXC))
580         {
581             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 0 << 8);
582         }
583         else
584         {
585             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
586         }
587         /* Clear transmission status flag M0REQC */
588         ald_can_clear_flag_status(h_can, CAN_FLAG_M0REQC);
589     }
590     else if (ald_can_get_flag_status(h_can, CAN_FLAG_M1REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
591     {
592         if (ald_can_get_flag_status(h_can, CAN_FLAG_M1TXC))
593         {
594             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 1 << 8);
595         }
596         else
597         {
598             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
599         }
600         ald_can_clear_flag_status(h_can, CAN_FLAG_M1REQC);
601     }
602     else if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC) && ald_can_get_it_status(h_can, CAN_IT_TXM))
603     {
604         if (ald_can_get_flag_status(h_can, CAN_FLAG_M2REQC))
605         {
606             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_DONE | 2 << 8);
607         }
608         else
609         {
610             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
611         }
612         ald_can_clear_flag_status(h_can, CAN_FLAG_M2REQC);
613     }
614 
615     rt_interrupt_leave();
616 }
617 
618 /**
619  * @brief This function handles CAN0 RX0 interrupts.
620  */
CAN0_RX0_Handler(void)621 void CAN0_RX0_Handler(void)
622 {
623     rt_interrupt_enter();
624     _can_rx_isr(&can.device, CAN_RX_FIFO0);
625     rt_interrupt_leave();
626 }
627 
628 /**
629  * @brief This function handles CAN0 RX1 interrupts.
630  */
CAN0_RX1_Handler(void)631 void CAN0_RX1_Handler(void)
632 {
633     rt_interrupt_enter();
634     _can_rx_isr(&can.device, CAN_RX_FIFO1);
635     rt_interrupt_leave();
636 }
637 
638 /**
639  * @brief This function handles CAN interrupts.
640  */
CAN0_EXCEPTION_Handler(void)641 void CAN0_EXCEPTION_Handler(void)
642 {
643     rt_interrupt_enter();
644 
645     rt_uint32_t errtype;
646     can_handle_t *h_can;
647 
648     h_can = &can.CanHandle;
649     errtype = h_can->perh->ERRSTAT;
650 
651     switch ((errtype & 0x70) >> 4)
652     {
653     case RT_CAN_BUS_BIT_PAD_ERR:
654         can.device.status.bitpaderrcnt++;
655         break;
656     case RT_CAN_BUS_FORMAT_ERR:
657         can.device.status.formaterrcnt++;
658         break;
659     case RT_CAN_BUS_ACK_ERR:/* attention !!! test ack err's unit is transmit unit */
660         can.device.status.ackerrcnt++;
661         if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
662             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 0 << 8);
663         else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
664             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 1 << 8);
665         else if (!READ_BIT(can.CanHandle.perh->TXSTAT, CAN_FLAG_M0TXC))
666             rt_hw_can_isr(&can.device, RT_CAN_EVENT_TX_FAIL | 2 << 8);
667         break;
668     case RT_CAN_BUS_IMPLICIT_BIT_ERR:
669     case RT_CAN_BUS_EXPLICIT_BIT_ERR:
670         can.device.status.biterrcnt++;
671         break;
672     case RT_CAN_BUS_CRC_ERR:
673         can.device.status.crcerrcnt++;
674         break;
675     }
676 
677     can.device.status.lasterrtype = errtype & 0x70;
678     can.device.status.rcverrcnt = errtype >> 24;
679     can.device.status.snderrcnt = (errtype >> 16 & 0xFF);
680     can.device.status.errcode = errtype & 0x07;
681     h_can->perh->IFC |= CAN_IFC_ERRIFC_MSK;
682 
683     rt_interrupt_leave();
684 }
685 
rt_hw_can_init(void)686 int rt_hw_can_init(void)
687 {
688     gpio_init_t h_gpio;
689 
690     /* Initialize can common pin */
691     h_gpio.odos = GPIO_PUSH_PULL;
692     h_gpio.pupd = GPIO_PUSH_UP;
693     h_gpio.podrv = GPIO_OUT_DRIVE_6;
694     h_gpio.nodrv = GPIO_OUT_DRIVE_6;
695     h_gpio.flt  = GPIO_FILTER_DISABLE;
696     h_gpio.type = GPIO_TYPE_TTL;
697 
698 #if  defined(ES_CAN0_RX_GPIO_FUNC)&&defined(ES_CAN0_RX_GPIO_PORT)&&defined(ES_CAN0_RX_GPIO_PIN)
699     /* Initialize can rx pin */
700     h_gpio.mode = GPIO_MODE_INPUT;
701     h_gpio.func = ES_CAN0_RX_GPIO_FUNC;
702     ald_gpio_init(ES_CAN0_RX_GPIO_PORT, ES_CAN0_RX_GPIO_PIN, &h_gpio);
703 #endif
704 
705 
706 #if  defined(ES_CAN0_TX_GPIO_FUNC)&&defined(ES_CAN0_TX_GPIO_PORT)&&defined(ES_CAN0_TX_GPIO_PIN)
707     /* Initialize can tx pin */
708     h_gpio.mode = GPIO_MODE_OUTPUT;
709     h_gpio.func = ES_CAN0_TX_GPIO_FUNC;
710     ald_gpio_init(ES_CAN0_TX_GPIO_PORT, ES_CAN0_TX_GPIO_PIN, &h_gpio);
711 #endif
712 
713 
714     /* config default filter */
715     can_filter_t filter = {0};
716     filter.id_high = 0x0000;
717     filter.id_low = 0x0000;
718     filter.mask_id_high = 0x0000;
719     filter.mask_id_low = 0x0000;
720     filter.fifo = CAN_FILTER_FIFO0;
721     filter.number = ES_C_CAN_DEFAULT_FILTER_NUMBER;
722     filter.mode = CAN_FILTER_MODE_MASK;
723     filter.scale = CAN_FILTER_SCALE_32;
724     filter.active = ENABLE;
725 
726     can.FilterConfig = filter;
727     can.device.config = (struct can_configure)ES_CAN0_CONFIG;
728 #ifdef RT_CAN_USING_HDR
729     can.device.config.maxhdr = 14;
730 #endif
731     can.device.config.privmode = RT_CAN_MODE_NOPRIV;
732     can.device.config.ticks = 50;
733     can.device.config.reserved = ES_CAN0_SJW;
734     /* register CAN1 device */
735     rt_hw_can_register(&can.device, ES_DEVICE_NAME_CAN0, &_can_ops, &can);
736 
737     return 0;
738 }
739 INIT_BOARD_EXPORT(rt_hw_can_init);
740 
741 #endif /* BSP_USING_CAN */
742