1 
2 #include "rtconfig.h"
3 #ifdef BSP_USING_CAN
4 #include <rtdevice.h>
5 #include "drv_can.h"
6 #define LOG_TAG      "can_drv"
7 #include "drv_log.h"
8 #include "fcan.h"
9 #include "fio_mux.h"
10 #include "interrupt.h"
11 #include "fcpu_info.h"
12 /*can test example*/
13 static rt_device_t can0_dev;            /* CAN device handle */
14 static rt_device_t can1_dev;            /* CAN device handle */
15 static struct rt_semaphore can0_rx_sem;
16 static struct rt_semaphore can1_rx_sem;
17 static struct rt_can_msg rxmsg = {0};
18 
can0_rx_call(rt_device_t dev,rt_size_t size)19 static rt_err_t can0_rx_call(rt_device_t dev, rt_size_t size)
20 {
21     /* The CAN generates an interrupt after receiving data, calls this callback function, and then sends the received semaphore */
22     rt_sem_release(&can0_rx_sem);
23     return RT_EOK;
24 }
25 
can0_rx_thread(void * parameter)26 static void can0_rx_thread(void *parameter)
27 {
28     int i;
29     rt_err_t res = RT_EOK;
30     rt_device_set_rx_indicate(can0_dev, can0_rx_call);
31     while (1)
32     {
33         /* The hdr value is - 1, which means reading data directly from the uselist */
34         rxmsg.hdr_index = -1;
35         /* Blocking waiting to receive semaphore */
36         res = rt_sem_take(&can0_rx_sem, RT_WAITING_FOREVER);
37         RT_ASSERT(res == RT_EOK);
38         /* Read a frame of data from CAN */
39         rt_device_read(can0_dev, 0, &rxmsg, sizeof(rxmsg));
40         /* Print data ID and conten */
41         LOG_D("ID:%x\n", rxmsg.id);
42         LOG_D("DATA: ");
43         for (i = 0; i < 8; i++)
44         {
45             LOG_D("%2x ", rxmsg.data[i]);
46         }
47 
48         LOG_D("\n");
49     }
50 }
51 
can1_rx_call(rt_device_t dev,rt_size_t size)52 static rt_err_t can1_rx_call(rt_device_t dev, rt_size_t size)
53 {
54     /* The CAN generates an interrupt after receiving data, calls this callback function, and then sends the received semaphore */
55     rt_sem_release(&can1_rx_sem);
56     return RT_EOK;
57 }
58 
can1_rx_thread(void * parameter)59 static void can1_rx_thread(void *parameter)
60 {
61     int i;
62     rt_err_t res = RT_EOK;
63     rt_device_set_rx_indicate(can1_dev, can1_rx_call);
64     while (1)
65     {
66         /* The hdr value is - 1, which means reading data directly from the uselist */
67         rxmsg.hdr_index = -1;
68         /* Blocking waiting to receive semaphore */
69         res = rt_sem_take(&can1_rx_sem, RT_WAITING_FOREVER);
70         RT_ASSERT(res == RT_EOK);
71         /* Read a frame of data from CAN */
72         rt_device_read(can1_dev, 0, &rxmsg, sizeof(rxmsg));
73         /* Print data ID and conten */
74         LOG_D("ID:%x\n", rxmsg.id);
75         LOG_D("DATA: ");
76         for (i = 0; i < 8; i++)
77         {
78             LOG_D("%2x ", rxmsg.data[i]);
79         }
80 
81         LOG_D("\n");
82     }
83 }
84 
can_loopback_sample()85 rt_err_t can_loopback_sample()
86 {
87     struct rt_can_msg msg = {0};
88     rt_err_t res = RT_EOK;;
89     rt_thread_t thread;
90 
91     /* Find CAN device */
92     can0_dev = rt_device_find("CAN0");
93     if (!can0_dev)
94     {
95         rt_kprintf("Find CAN0 failed.\n");
96         return -RT_ERROR;
97     }
98 
99     /* Find CAN device */
100     can1_dev = rt_device_find("CAN1");
101     if (!can1_dev)
102     {
103         rt_kprintf("Find CAN1 failed.\n");
104         return -RT_ERROR;
105     }
106 
107     /* Initialize CAN receive signal quantity */
108     res = rt_sem_init(&can0_rx_sem, "can0_rx_sem", 0, RT_IPC_FLAG_FIFO);
109     RT_ASSERT(res == RT_EOK);
110 
111     res = rt_sem_init(&can1_rx_sem, "can1_rx_sem", 0, RT_IPC_FLAG_FIFO);
112     RT_ASSERT(res == RT_EOK);
113 
114     /* Open the CAN device in the way of interrupt reception and transmission */
115     res = rt_device_open(can0_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
116     rt_device_control(can0_dev, RT_CAN_CMD_SET_BAUD, CAN800kBaud);
117     RT_ASSERT(res == RT_EOK);
118 
119     res = rt_device_open(can1_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
120     rt_device_control(can1_dev, RT_CAN_CMD_SET_BAUD, CAN800kBaud);
121     RT_ASSERT(res == RT_EOK);
122 
123     /* Create data receiving thread */
124     thread = rt_thread_create("can0_rx", can0_rx_thread, RT_NULL, 4096, 10, 10);
125     if (thread != RT_NULL)
126     {
127         res = rt_thread_startup(thread);
128         RT_ASSERT(res == RT_EOK);
129     }
130     else
131     {
132         rt_kprintf("Create can0_rx thread failed.\n");
133     }
134     thread = rt_thread_create("can1_rx", can1_rx_thread, RT_NULL, 4096, 10, 10);
135     if (thread != RT_NULL)
136     {
137         res = rt_thread_startup(thread);
138         RT_ASSERT(res == RT_EOK);
139     }
140     else
141     {
142         rt_kprintf("Create can1_rx thread failed.\n");
143     }
144 
145 
146     msg.id = 0x78;              /* ID = 0x78 */
147     msg.ide = RT_CAN_STDID;     /* Standard format */
148     msg.rtr = RT_CAN_DTR;       /* Data frame */
149     msg.len = 8;                /* Data length is 8 */
150     /* Send CAN data */
151     for (int i = 0; i < 5; i++)
152     {
153         /* 8-byte data to be sent */
154         msg.data[0] = 0x0;
155         msg.data[1] = 0x1;
156         msg.data[2] = 0x2;
157         msg.data[3] = 0x3;
158         msg.data[4] = 0x4;
159         msg.data[5] = 0x5;
160         msg.data[6] = 0x6;
161         msg.data[7] = 0x7;
162         rt_device_write(can0_dev, 0, &msg, sizeof(msg));
163         rt_thread_mdelay(100);
164         for (int i = 0; i < 8; i++)
165         {
166             if (msg.data[i] != rxmsg.data[i])
167             {
168                 res = RT_ERROR;
169                 goto exit;
170             }
171         }
172     }
173 
174     /* Send CAN data */
175     for (int i = 0; i < 5; i++)
176     {
177         /* 8-byte data to be sent */
178         msg.data[0] = 0x0;
179         msg.data[1] = 0x1;
180         msg.data[2] = 0x2;
181         msg.data[3] = 0x3;
182         msg.data[4] = 0x4;
183         msg.data[5] = 0x5;
184         msg.data[6] = 0x6;
185         msg.data[7] = 0x7;
186         rt_device_write(can1_dev, 0, &msg, sizeof(msg));
187         rt_thread_mdelay(100);
188         for (int i = 0; i < 8; i++)
189         {
190             if (msg.data[i] != rxmsg.data[i])
191             {
192                 res = RT_ERROR;
193                 goto exit;
194             }
195         }
196     }
197 exit:
198     /* print message on example run result */
199     if (res == RT_EOK)
200     {
201         rt_kprintf("%s@%d:Can loopback test example [success].\r\n", __func__, __LINE__);
202     }
203     else
204     {
205         rt_kprintf("%s@%d:Can loopback test example [failure], res = %d\r\n", __func__, __LINE__, res);
206     }
207 
208     return res;
209 }
210 /* Enter can_sample command for testing */
211 MSH_CMD_EXPORT(can_loopback_sample, can device sample);
212 #endif