drv_can.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. * Copyright (c) 2006-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-10-29 mazhiyuan first version
  9. * 2025-02-11 kurisaW support can and canfd drivers for RZ family
  10. */
  11. #include "drv_can.h"
  12. static struct ra_can_config can_config[] =
  13. {
  14. #ifdef BSP_USING_CAN0
  15. CAN0_CONFIG,
  16. #endif
  17. #ifdef BSP_USING_CAN1
  18. CAN1_CONFIG
  19. #endif
  20. };
  21. enum
  22. {
  23. #ifdef BSP_USING_CAN0
  24. CAN0_INDEX,
  25. #endif
  26. #ifdef BSP_USING_CAN1
  27. CAN1_INDEX,
  28. #endif
  29. };
  30. static struct ra_can can_obj[sizeof(can_config) / sizeof(can_config[0])] = {0};
  31. static const struct ra_baud_rate_tab can_baud_rate_tab[] =
  32. {
  33. {CAN1MBaud, 3, 6, 3, 1 + 4},
  34. {CAN800kBaud, 4, 15, 5, 1 + 2},
  35. {CAN500kBaud, 4, 14, 5, 1 + 4},
  36. {CAN250kBaud, 4, 14, 5, 1 + 9},
  37. {CAN125kBaud, 4, 14, 5, 1 + 19},
  38. {CAN100kBaud, 4, 14, 5, 1 + 24},
  39. {CAN50kBaud, 4, 14, 5, 1 + 49},
  40. {CAN20kBaud, 4, 14, 5, 1 + 124},
  41. {CAN10kBaud, 4, 14, 5, 1 + 249}
  42. };
  43. #if defined(BSP_USING_CANFD)
  44. #define can_instance_ctrl_t canfd_instance_ctrl_t
  45. #define R_CAN_Open R_CANFD_Open
  46. #define R_BSP_IrqStatusClear R_BSP_IrqClearPending
  47. #define R_CAN_ModeTransition R_CANFD_ModeTransition
  48. #define R_CAN_InfoGet R_CANFD_InfoGet
  49. #define R_CAN_Write R_CANFD_Write
  50. #endif
  51. static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
  52. {
  53. rt_uint32_t len, index;
  54. len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
  55. for (index = 0; index < len; index++)
  56. {
  57. if (can_baud_rate_tab[index].baud_rate == baud)
  58. return index;
  59. }
  60. return 0; /* default baud is CAN1MBaud */
  61. }
  62. static void ra_can_get_config(void)
  63. {
  64. struct can_configure config = CANDEFAULTCONFIG;
  65. #ifdef BSP_USING_CAN0
  66. can_obj[CAN0_INDEX].can_dev.config = config;
  67. can_obj[CAN0_INDEX].can_dev.config.msgboxsz = 32;
  68. can_obj[CAN0_INDEX].can_dev.config.sndboxnumber = 1;
  69. can_obj[CAN0_INDEX].can_dev.config.ticks = 50;
  70. #endif
  71. #ifdef BSP_USING_CAN1
  72. can_obj[CAN1_INDEX].can_dev.config = config;
  73. can_obj[CAN1_INDEX].can_dev.config.msgboxsz = 32;
  74. can_obj[CAN1_INDEX].can_dev.config.sndboxnumber = 1;
  75. can_obj[CAN1_INDEX].can_dev.config.ticks = 50;
  76. #endif
  77. }
  78. rt_err_t ra_can_configure(struct rt_can_device *can_dev, struct can_configure *cfg)
  79. {
  80. struct ra_can *can;
  81. RT_ASSERT(can_dev != RT_NULL);
  82. RT_ASSERT(cfg != RT_NULL);
  83. fsp_err_t err = FSP_SUCCESS;
  84. can = rt_container_of(can_dev, struct ra_can, can_dev);
  85. RT_ASSERT(can != RT_NULL);
  86. err = R_CAN_Open(can->config->p_api_ctrl, can->config->p_cfg);
  87. if (FSP_SUCCESS != err)
  88. {
  89. return -RT_ERROR;
  90. }
  91. return RT_EOK;
  92. }
  93. rt_err_t ra_can_control(struct rt_can_device *can_dev, int cmd, void *arg)
  94. {
  95. struct ra_can *can;
  96. can_info_t can_info;
  97. rt_uint32_t argval;
  98. RT_ASSERT(can_dev != RT_NULL);
  99. can = rt_container_of(can_dev, struct ra_can, can_dev);
  100. switch (cmd)
  101. {
  102. case RT_DEVICE_CTRL_CLR_INT:
  103. R_BSP_IrqStatusClear((IRQn_Type)arg);
  104. break;
  105. case RT_CAN_CMD_SET_BAUD:
  106. argval = (rt_uint32_t) arg;
  107. if (argval != CAN1MBaud &&
  108. argval != CAN800kBaud &&
  109. argval != CAN500kBaud &&
  110. argval != CAN250kBaud &&
  111. argval != CAN125kBaud &&
  112. argval != CAN100kBaud &&
  113. argval != CAN50kBaud &&
  114. argval != CAN20kBaud &&
  115. argval != CAN10kBaud)
  116. {
  117. return -RT_ERROR;
  118. }
  119. if (argval != can->can_dev.config.baud_rate)
  120. {
  121. can->can_dev.config.baud_rate = argval;
  122. uint32_t index = get_can_baud_index(argval);
  123. can->config->p_cfg->p_bit_timing->baud_rate_prescaler = can_baud_rate_tab[index].prescaler;
  124. can->config->p_cfg->p_bit_timing->synchronization_jump_width = can_baud_rate_tab[index].sjw;
  125. can->config->p_cfg->p_bit_timing->time_segment_1 = can_baud_rate_tab[index].ts1;
  126. can->config->p_cfg->p_bit_timing->time_segment_2 = can_baud_rate_tab[index].ts2;
  127. return ra_can_configure(&can->can_dev, &can->can_dev.config);
  128. }
  129. break;
  130. case RT_CAN_CMD_SET_MODE:
  131. argval = (rt_uint32_t) arg;
  132. if (argval != RT_CAN_MODE_NORMAL &&
  133. argval != RT_CAN_MODE_LISTEN &&
  134. argval != RT_CAN_MODE_LOOPBACK)
  135. {
  136. return -RT_ERROR;
  137. }
  138. if (argval != can->can_dev.config.mode)
  139. {
  140. can_test_mode_t mode_to_set;
  141. can->can_dev.config.mode = argval;
  142. switch (argval)
  143. {
  144. case RT_CAN_MODE_NORMAL:
  145. mode_to_set = CAN_TEST_MODE_DISABLED;
  146. case RT_CAN_MODE_LISTEN:
  147. mode_to_set = CAN_TEST_MODE_LISTEN;
  148. case RT_CAN_MODE_LOOPBACK:
  149. mode_to_set = CAN_TEST_MODE_LOOPBACK_INTERNAL;
  150. }
  151. R_CAN_ModeTransition(can->config->p_api_ctrl, ((can_instance_ctrl_t *)(can->config->p_api_ctrl))->operation_mode, mode_to_set);
  152. }
  153. break;
  154. case RT_CAN_CMD_GET_STATUS:
  155. R_CAN_InfoGet(can->config->p_api_ctrl, &can_info);
  156. can->can_dev.status.rcverrcnt = can_info.error_count_receive;
  157. can->can_dev.status.snderrcnt = can_info.error_count_transmit;
  158. can->can_dev.status.errcode = can_info.error_code;
  159. rt_memcpy(arg, &can->can_dev.status, sizeof(can->can_dev.status));
  160. break;
  161. default:
  162. return -RT_ERROR;
  163. }
  164. return RT_EOK;
  165. }
  166. rt_ssize_t ra_can_sendmsg(struct rt_can_device *can_dev, const void *buf, rt_uint32_t boxno)
  167. {
  168. struct ra_can *can;
  169. can_frame_t g_can_tx_frame;
  170. struct rt_can_msg *msg_rt = (struct rt_can_msg *)buf;
  171. RT_ASSERT(can_dev != RT_NULL);
  172. RT_ASSERT(buf != RT_NULL);
  173. g_can_tx_frame.id = msg_rt->id;
  174. g_can_tx_frame.id_mode = msg_rt->ide;
  175. g_can_tx_frame.type = msg_rt->rtr;
  176. g_can_tx_frame.data_length_code = msg_rt->len;
  177. #if defined(BSP_USING_CANFD) && defined(BSP_USING_CAN_RZ)
  178. g_can_tx_frame.options = 0;
  179. #elif defined(BSP_USING_CANFD)
  180. g_can_tx_frame.options = CANFD_FRAME_OPTION_FD | CANFD_FRAME_OPTION_BRS;
  181. #else
  182. g_can_tx_frame.options = 0;
  183. #endif
  184. memcpy(g_can_tx_frame.data, msg_rt->data, 8);
  185. can = rt_container_of(can_dev, struct ra_can, can_dev);
  186. RT_ASSERT(boxno < can->config->num_of_mailboxs);
  187. if (R_CAN_Write(can->config->p_api_ctrl, boxno, &g_can_tx_frame) != FSP_SUCCESS)
  188. {
  189. rt_exit_critical();
  190. return -RT_ERROR;
  191. }
  192. return RT_EOK;
  193. }
  194. rt_ssize_t ra_can_recvmsg(struct rt_can_device *can_dev, void *buf, rt_uint32_t boxno)
  195. {
  196. struct rt_can_msg *msg_rt = (struct rt_can_msg *)buf;
  197. can_frame_t *msg_ra;
  198. struct ra_can *can;
  199. RT_ASSERT(can_dev != RT_NULL);
  200. RT_ASSERT(buf != RT_NULL);
  201. can = rt_container_of(can_dev, struct ra_can, can_dev);
  202. RT_ASSERT(boxno < can->config->num_of_mailboxs);
  203. if (can->callback_args->mailbox != boxno)
  204. return 0;
  205. #if defined(BSP_USING_CANFD)
  206. msg_ra = &can->callback_args->frame;
  207. #else
  208. msg_ra = can->callback_args->p_frame;
  209. #endif
  210. msg_rt->id = msg_ra->id;
  211. msg_rt->ide = msg_ra->id_mode;
  212. msg_rt->rtr = msg_ra->type;
  213. msg_rt->rsv = RT_NULL;
  214. msg_rt->len = msg_ra->data_length_code;
  215. msg_rt->priv = boxno;
  216. msg_rt->hdr_index = RT_NULL;
  217. memcpy(msg_rt->data, msg_ra->data, msg_ra->data_length_code);
  218. return sizeof(struct rt_can_msg);
  219. }
  220. const struct rt_can_ops ra_can_ops =
  221. {
  222. .configure = ra_can_configure,
  223. .control = ra_can_control,
  224. .sendmsg = ra_can_sendmsg,
  225. .recvmsg = ra_can_recvmsg
  226. };
  227. #ifdef BSP_USING_CAN0
  228. void can0_callback(can_callback_args_t *p_args)
  229. {
  230. rt_interrupt_enter();
  231. switch (p_args->event)
  232. {
  233. case CAN_EVENT_TX_COMPLETE:
  234. rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_TX_DONE | p_args->mailbox << 8);
  235. break;
  236. case CAN_EVENT_RX_COMPLETE:
  237. can_obj[CAN0_INDEX].callback_args = p_args;
  238. if (p_args->event == CAN_EVENT_RX_COMPLETE)
  239. rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_RX_IND | p_args->mailbox << 8);
  240. break;
  241. case CAN_EVENT_TX_ABORTED:
  242. rt_hw_can_isr(&can_obj[CAN0_INDEX].can_dev, RT_CAN_EVENT_TX_FAIL | p_args->mailbox << 8);
  243. break;
  244. case CAN_EVENT_MAILBOX_MESSAGE_LOST: //overwrite/overrun error event
  245. case CAN_EVENT_BUS_RECOVERY: //Bus recovery error event
  246. case CAN_EVENT_ERR_BUS_OFF: //error Bus Off event
  247. case CAN_EVENT_ERR_PASSIVE: //error passive event
  248. case CAN_EVENT_ERR_WARNING: //error warning event
  249. case CAN_EVENT_ERR_BUS_LOCK: //error bus lock
  250. case CAN_EVENT_ERR_CHANNEL: //error channel
  251. case CAN_EVENT_ERR_GLOBAL: //error global
  252. case CAN_EVENT_TX_FIFO_EMPTY: //error transmit FIFO is empty
  253. {
  254. break;
  255. }
  256. }
  257. rt_interrupt_leave();
  258. }
  259. #endif
  260. #ifdef BSP_USING_CAN1
  261. void can1_callback(can_callback_args_t *p_args)
  262. {
  263. rt_interrupt_enter();
  264. switch (p_args->event)
  265. {
  266. case CAN_EVENT_TX_COMPLETE:
  267. rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_TX_DONE | p_args->mailbox << 8);
  268. break;
  269. case CAN_EVENT_RX_COMPLETE:
  270. can_obj[CAN1_INDEX].callback_args = p_args;
  271. if (p_args->event == CAN_EVENT_RX_COMPLETE)
  272. rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_RX_IND | p_args->mailbox << 8);
  273. break;
  274. case CAN_EVENT_TX_ABORTED:
  275. rt_hw_can_isr(&can_obj[CAN1_INDEX].can_dev, RT_CAN_EVENT_TX_FAIL | p_args->mailbox << 8);
  276. break;
  277. case CAN_EVENT_MAILBOX_MESSAGE_LOST: //overwrite/overrun error event
  278. case CAN_EVENT_BUS_RECOVERY: //Bus recovery error event
  279. case CAN_EVENT_ERR_BUS_OFF: //error Bus Off event
  280. case CAN_EVENT_ERR_PASSIVE: //error passive event
  281. case CAN_EVENT_ERR_WARNING: //error warning event
  282. case CAN_EVENT_ERR_BUS_LOCK: //error bus lock
  283. case CAN_EVENT_ERR_CHANNEL: //error channel
  284. case CAN_EVENT_ERR_GLOBAL: //error global
  285. {
  286. break;
  287. }
  288. }
  289. rt_interrupt_leave();
  290. }
  291. #endif
  292. int rt_hw_can_init(void)
  293. {
  294. rt_err_t result = 0;
  295. rt_size_t obj_num = sizeof(can_obj) / sizeof(struct ra_can);
  296. ra_can_get_config();
  297. for (int i = 0; i < obj_num; i++)
  298. {
  299. /* init CAN object */
  300. can_obj[i].config = &can_config[i];
  301. can_obj[i].can_dev.ops = &ra_can_ops;
  302. /* register CAN device */
  303. result = rt_hw_can_register(&can_obj[i].can_dev, can_obj[i].config->name, can_obj[i].can_dev.ops, RT_NULL);
  304. RT_ASSERT(result == RT_EOK);
  305. }
  306. return result;
  307. }
  308. INIT_BOARD_EXPORT(rt_hw_can_init);