dev_can.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include "dev_can.h"
  2. #include "dev_iap.h"
  3. #include "queue.h"
  4. #include <stdint.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. queue_entry(pdu_tag, 30) can_tx_queue;
  8. queue_entry(pdu_tag, 30) can_rx_queue;
  9. double pow_branch(double x, long long N)
  10. {
  11. double ans = 1.0;
  12. // 贡献的初始值为 x
  13. double x_contribute = x;
  14. // 在对 N 进行二进制拆分的同时计算答案
  15. while (N > 0)
  16. {
  17. if (N % 2 == 1)
  18. {
  19. // 如果 N 二进制表示的最低位为 1,那么需要计入贡献
  20. ans *= x_contribute;
  21. }
  22. // 将贡献不断地平方
  23. x_contribute *= x_contribute;
  24. // 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
  25. N = N >> 1;
  26. }
  27. return ans;
  28. }
  29. double pow(double x, double N)
  30. {
  31. return N >= 0 ? pow_branch(x, N) : 1.0 / pow_branch(x, -N);
  32. }
  33. uint8_t recv_can_id = 0;
  34. static uint64_t base_data;
  35. void data_bit_move(uint8_t start_bit, uint8_t bit_len, uint64_t data)
  36. {
  37. uint64_t mask = 0;
  38. uint64_t source_data = (uint64_t)data;
  39. mask = pow(2, bit_len) - 1;
  40. base_data |= (mask & source_data) << start_bit;
  41. }
  42. void product_array(uint8_t send_array[8])
  43. {
  44. send_array[0] = (uint8_t)base_data;
  45. send_array[1] = (uint8_t)(base_data >> 8);
  46. send_array[2] = (uint8_t)(base_data >> 16);
  47. send_array[3] = (uint8_t)(base_data >> 24);
  48. send_array[4] = (uint8_t)(base_data >> 32);
  49. send_array[5] = (uint8_t)(base_data >> 40);
  50. send_array[6] = (uint8_t)(base_data >> 48);
  51. send_array[7] = (uint8_t)(base_data >> 56);
  52. base_data = 0;
  53. }
  54. uint8_t push_can_message_to_queue(uint32_t id, uint8_t len, uint8_t *p_data)
  55. {
  56. pdu_tag response_msg;
  57. QUEUE_STATUS result_status;
  58. response_msg.id.r = id;
  59. response_msg.reg.dlc = len;
  60. memcpy(&response_msg.data.u8_buf[0], p_data, len);
  61. if (id > 0x7FF)
  62. {
  63. response_msg.reg.ide = CAN_Id_Extended;
  64. }
  65. else
  66. {
  67. response_msg.reg.ide = CAN_Id_Standard;
  68. }
  69. __disable_irq();
  70. en_queue(&can_tx_queue, response_msg, result_status);
  71. __enable_irq();
  72. if (result_status != Q_OK)
  73. {
  74. return 0;
  75. }
  76. return 1;
  77. }
  78. static uint8_t can_tx_frame(pdu_tag can_message)
  79. {
  80. uint8_t result = CAN_TxStatus_NoMailBox;
  81. result = drv_can_msg_tx(can_message.id.r, can_message.reg.ide, can_message.data.u8_buf, can_message.reg.dlc);
  82. return result;
  83. }
  84. void can_tx_callback(void)
  85. {
  86. pdu_tag tx_data;
  87. QUEUE_STATUS result_status;
  88. de_queue(&can_tx_queue, tx_data, result_status);
  89. if (result_status == Q_OK) // 返回值为1代表读取成功
  90. {
  91. can_tx_frame(tx_data);
  92. CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);
  93. }
  94. else
  95. {
  96. CAN_ITConfig(CAN1, CAN_IT_TME, DISABLE);
  97. }
  98. }
  99. void can_rx_callback(CanRxMsg rx_message)
  100. {
  101. pdu_tag data;
  102. QUEUE_STATUS result;
  103. switch (rx_message.ExtId)
  104. {
  105. case 0x18DFF4E1:
  106. data.id.r = 0x18DFF4E1;
  107. data.reg.dlc = rx_message.DLC;
  108. memcpy(&data.data.u8_buf[0], rx_message.Data, rx_message.DLC);
  109. en_queue(&can_rx_queue, data, result);
  110. break;
  111. default:
  112. return;
  113. }
  114. }
  115. can_rx_tab can_tab[] = {
  116. 0x18DFF4E1,
  117. iap_rec_handler,
  118. };
  119. void can_start_send(void)
  120. {
  121. pdu_tag tx_msg;
  122. QUEUE_STATUS result_status;
  123. if (0 == ((CAN1->IER) & 0x1))
  124. {
  125. de_queue(&can_tx_queue, tx_msg, result_status);
  126. if (result_status == Q_OK) // 返回值为1代表读取成功
  127. {
  128. can_tx_frame(tx_msg);
  129. CAN_ITConfig(CAN1, CAN_IT_TME, ENABLE);
  130. }
  131. }
  132. }
  133. static uint8_t can_rx_process(void)
  134. {
  135. uint8_t i;
  136. uint8_t flg = 0;
  137. pdu_tag rec_msg;
  138. QUEUE_STATUS result;
  139. for (uint8_t j = 0; j < 15; j++)
  140. {
  141. __disable_irq();
  142. de_queue(&can_rx_queue, rec_msg, result);
  143. __enable_irq();
  144. if (Q_OK == result)
  145. {
  146. for (i = 0; i < ARR_SIZE(can_tab); i++)
  147. {
  148. if (can_tab[i].id == rec_msg.id.r)
  149. {
  150. can_tab[i].p_func(rec_msg);
  151. break;
  152. }
  153. }
  154. }
  155. }
  156. }
  157. void dev_can_network_init(void)
  158. {
  159. drv_can_init();
  160. queue_init(&can_rx_queue);
  161. queue_init(&can_tx_queue);
  162. drv_can_rx_back_init(can_rx_callback);
  163. drv_can_tx_back_init(can_tx_callback);
  164. }
  165. void can_process(void)
  166. {
  167. can_rx_process();
  168. can_start_send();
  169. }