can_loopback_sample.c 5.9 KB

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