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