can.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #include <stdio.h>
  2. #include "os/queue.h"
  3. #include "bsp/bsp_driver.h"
  4. #include "libs/utils.h"
  5. #include "libs/circle_buffer.h"
  6. #define CAN_RX_MESSAGE_RX_ID 1
  7. #define CAN_SEND_QUEUE_SIZE 32
  8. #define RX_ID_OFFSET 16
  9. #define CAN_SEND_OK 0
  10. #define CAN_SEND_ERROR -1
  11. #define CAN_SEND_WAIT_TIMEOUT -2
  12. #define TX_NUM 64
  13. #define RX_NUM 64
  14. static c_buffer_t g_tx_circle;
  15. static c_buffer_t g_rx_circle;
  16. static uint8_t _g_tx_buffer[sizeof(can_tx_message_type) * TX_NUM + 1];
  17. static uint8_t _g_rx_buffer[sizeof(can_rx_message_type) * RX_NUM + 1];
  18. static int shark_send_can0_data(can_tx_message_type *P_message);
  19. static uint8_t can_get_mailbox(uint32_t can_periph);
  20. /* this function can be overide by app, which need recv the can frame */
  21. __weak void handle_can_frame(can_id_t id, uint8_t *data, int len){
  22. }
  23. void can_rx_poll(void){
  24. can_rx_message_type message;
  25. if (circle_get_data(&g_rx_circle, (uint8_t *)&message, sizeof(message)) != sizeof(message)) {
  26. return;
  27. }
  28. can_id_t can_id;
  29. can_id.id = message.extended_id;
  30. handle_can_frame(can_id, message.data, message.dlc);
  31. return ;
  32. }
  33. void can_tx_poll(void){
  34. can_tx_message_type can_tr_m;
  35. if (CAN1->ests_bit.bof){
  36. shark_can0_reset();
  37. }
  38. while (can_get_mailbox((u32)CAN1) != CAN_TX_STATUS_NO_EMPTY) {
  39. if (circle_get_data(&g_tx_circle, (uint8_t * )&can_tr_m, sizeof(can_tr_m)) != sizeof(can_tr_m)) {
  40. break;
  41. }
  42. can_message_transmit(CAN1,&can_tr_m);
  43. }
  44. }
  45. static u32 _can_poll_task(void *args) {
  46. can_rx_poll();
  47. can_tx_poll();
  48. return 0;
  49. }
  50. static __inline__ void can_fifo_recv(can_rx_fifo_num_type fifo){
  51. can_rx_message_type Rxmessage;
  52. can_message_receive(CAN1, fifo, &Rxmessage);
  53. circle_put_data(&g_rx_circle, (uint8_t *)&Rxmessage, sizeof(Rxmessage));
  54. }
  55. void USBFS_L_CAN1_RX0_IRQHandler(void)
  56. {
  57. can_fifo_recv(CAN_RX_FIFO0);
  58. }
  59. void CAN0_RX1_IRQHandler(void)
  60. {
  61. can_fifo_recv(CAN_RX_FIFO1);
  62. }
  63. static void shark_can0_txrx_pin_config(void){
  64. gpio_init_type gpio_init_struct;
  65. /* enable can clock */
  66. crm_periph_clock_enable(CAN_PIN_RCU, TRUE);
  67. #ifdef CAN_REMAP
  68. gpio_pin_remap_config(CAN_REMAP,TRUE);
  69. #endif
  70. gpio_default_para_init(&gpio_init_struct);
  71. /* can tx pin */
  72. gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  73. gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  74. gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  75. gpio_init_struct.gpio_pins = CAN_TX_PIN;
  76. gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  77. gpio_init(CAN_TX_GROUP, &gpio_init_struct);
  78. /* can rx pin */
  79. gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  80. gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
  81. gpio_init_struct.gpio_pins = CAN_RX_PIN;
  82. gpio_init_struct.gpio_pull = GPIO_PULL_UP;
  83. gpio_init(CAN_RX_GROUP, &gpio_init_struct);
  84. }
  85. static void shark_can0_config(void)
  86. {
  87. can_base_type can_base_struct;
  88. can_baudrate_type can_baudrate_struct;
  89. can_filter_init_type can_filter_init_struct;
  90. crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, TRUE);
  91. /* can base init */
  92. can_default_para_init(&can_base_struct);
  93. can_base_struct.mode_selection = CAN_MODE_COMMUNICATE;
  94. can_base_struct.ttc_enable = FALSE;
  95. can_base_struct.aebo_enable = TRUE;
  96. can_base_struct.aed_enable = TRUE;
  97. can_base_struct.prsf_enable = FALSE;
  98. can_base_struct.mdrsel_selection = CAN_DISCARDING_FIRST_RECEIVED;
  99. can_base_struct.mmssr_selection = CAN_SENDING_BY_REQUEST;
  100. can_base_init(CAN1, &can_base_struct);
  101. //CAN0_SPEED==250 //250k bps
  102. /* can baudrate, set baudrate = pclk/(baudrate_div *(1 + bts1_size + bts2_size)) */
  103. can_baudrate_struct.baudrate_div = 40;
  104. can_baudrate_struct.rsaw_size = CAN_RSAW_1TQ;
  105. can_baudrate_struct.bts1_size = CAN_BTS1_5TQ;
  106. can_baudrate_struct.bts2_size = CAN_BTS2_4TQ;
  107. can_baudrate_set(CAN1, &can_baudrate_struct);
  108. /* can filter 0 config */
  109. can_filter_init_struct.filter_activate_enable = TRUE;
  110. can_filter_init_struct.filter_mode = CAN_FILTER_MODE_ID_MASK;
  111. can_filter_init_struct.filter_fifo = CAN_FILTER_FIFO0;
  112. can_filter_init_struct.filter_number = 0;
  113. can_filter_init_struct.filter_bit = CAN_FILTER_32BIT;
  114. can_filter_init_struct.filter_id_high = (((CAN_MY_ADDRESS << 3) >> 16) & 0xFFFF); /* extended identifier is 29 bit */
  115. can_filter_init_struct.filter_id_low = ((CAN_MY_ADDRESS << 3) & 0xFFFF) | 0x04;
  116. can_filter_init_struct.filter_mask_high = ((CAN_FILTER_DEST_MASK << 3) >> 16) & 0xFFFF; /* extended identifier is 29 bit */
  117. can_filter_init_struct.filter_mask_low = ((CAN_FILTER_DEST_MASK << 3) & 0xFFFF) | 0x04;
  118. can_filter_init(CAN1, &can_filter_init_struct);
  119. // nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
  120. nvic_irq_enable(USBFS_L_CAN1_RX0_IRQn,CAN_IRQ_PRIORITY,0);
  121. /* enable can receive FIFO0 not empty interrupt */
  122. can_interrupt_enable(CAN1, CAN_RF0MIEN_INT, TRUE);
  123. }
  124. static int shark_send_can0_data(can_tx_message_type *P_message){
  125. can_tx_poll();
  126. if (circle_put_data(&g_tx_circle, (u8 *)P_message, sizeof(can_tx_message_type))){
  127. return CAN_SEND_OK;
  128. }
  129. return CAN_SEND_ERROR;
  130. }
  131. static uint8_t can_get_mailbox(uint32_t can_periph)
  132. {
  133. uint8_t transmit_mailbox = CAN_TX_MAILBOX0;
  134. can_type* can_x = CAN1;
  135. /* select one empty transmit mailbox */
  136. if(can_x->tsts_bit.tm0ef)
  137. {
  138. transmit_mailbox = CAN_TX_MAILBOX0;
  139. }
  140. else if(can_x->tsts_bit.tm1ef)
  141. {
  142. transmit_mailbox = CAN_TX_MAILBOX1;
  143. }
  144. else if(can_x->tsts_bit.tm2ef)
  145. {
  146. transmit_mailbox = CAN_TX_MAILBOX2;
  147. }
  148. else
  149. {
  150. transmit_mailbox = CAN_TX_STATUS_NO_EMPTY;
  151. }
  152. /* return no mailbox empty */
  153. if(CAN_TX_STATUS_NO_EMPTY == transmit_mailbox){
  154. return CAN_TX_STATUS_NO_EMPTY;
  155. }
  156. return transmit_mailbox;
  157. }
  158. int shark_can0_send_message(uint32_t can_id, const void*buff, int len){
  159. can_tx_message_type trasnmit_msg;
  160. can_id_t can_frame_id;
  161. u32 total_frames = ((len + 7) >> 3);
  162. int send_len = len;
  163. u32 frame_id = 1;
  164. can_frame_id.id = can_id;
  165. can_frame_id.total = total_frames;
  166. while(send_len > 0){
  167. can_frame_id.idx = frame_id;
  168. trasnmit_msg.standard_id = 0;
  169. trasnmit_msg.extended_id = can_frame_id.id;
  170. trasnmit_msg.frame_type = CAN_TFT_DATA;
  171. trasnmit_msg.id_type = CAN_ID_EXTENDED;
  172. trasnmit_msg.dlc = min(CAN_DATA_SIZE,send_len);
  173. memcpy((char *)trasnmit_msg.data, (char *)buff + (len - send_len), trasnmit_msg.dlc);
  174. send_len -= trasnmit_msg.dlc;
  175. frame_id ++;
  176. if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
  177. return CAN_SEND_ERROR;
  178. }
  179. }
  180. return CAN_SEND_OK;
  181. }
  182. int shark_can0_send_ext_message(uint32_t can_id, const void*buff, int len){
  183. can_tx_message_type trasnmit_msg;
  184. trasnmit_msg.standard_id = 0;
  185. trasnmit_msg.extended_id = can_id;
  186. trasnmit_msg.frame_type = CAN_TFT_DATA;
  187. trasnmit_msg.id_type = CAN_ID_EXTENDED;
  188. trasnmit_msg.dlc = min(CAN_DLC_LENGTH,len);
  189. memcpy((char *)trasnmit_msg.data, (char *)buff, trasnmit_msg.dlc);
  190. if (shark_send_can0_data(&trasnmit_msg) != CAN_SEND_OK){
  191. return CAN_SEND_ERROR;
  192. }
  193. return CAN_SEND_OK;
  194. }
  195. void shark_can0_reset(void){
  196. shark_can0_txrx_pin_config();
  197. shark_can0_config();
  198. }
  199. void shark_can0_deinit(void){
  200. can_reset(CAN1);
  201. crm_periph_clock_enable(CRM_CAN1_PERIPH_CLOCK, FALSE);
  202. }
  203. void shark_can0_init(void){
  204. circle_buffer_init(&g_tx_circle, _g_tx_buffer, sizeof(_g_tx_buffer));
  205. circle_buffer_init(&g_rx_circle, _g_rx_buffer, sizeof(_g_rx_buffer));
  206. shark_task_create(_can_poll_task, NULL);
  207. shark_can0_txrx_pin_config();
  208. shark_can0_config();
  209. }