drv_can.c 9.8 KB

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