dronecan.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #include "dronecan.h"
  2. #include "drv_vkweigher_vls300.h"
  3. #include <string.h>
  4. #include "soft_timer.h"
  5. static struct dronecan __dronecan = {0};
  6. uint8_t memory_pool[DRONECAN_CANARD_MEMORY_POOL_SIZE] = {0};
  7. CanardInstance canard_ins;
  8. bool dronecan_lock_status = false;
  9. void dronecan_lock() {
  10. dronecan_lock_status = 1;
  11. }
  12. void dronecan_unlock() {
  13. dronecan_lock_status = 0;
  14. }
  15. int dronecan_request_or_respond(uint8_t dest_id,
  16. CanardTxTransfer *tx_transfer) {
  17. int ret = 0;
  18. if (dronecan_lock_status == UNLOCK) {
  19. dronecan_lock();
  20. ret = canardRequestOrRespondObj(&canard_ins, dest_id, tx_transfer);
  21. dronecan_unlock();
  22. }
  23. return ret;
  24. }
  25. static void onTransferReceived(CanardInstance *ins,
  26. CanardRxTransfer *transfer) {
  27. // if (flyfire_onRecieved(ins, transfer)) {
  28. // return;
  29. // } else if (hbwEscOnRecieved(ins, transfer)) {
  30. // return;
  31. // } else if (sinemotorEscOnRecieved(ins, transfer)) {
  32. // return;
  33. // } else if (tmotorEscOnRecieved(ins, transfer)) {
  34. // return;
  35. // } else if (uavcanEscOnRecieved(ins, transfer)) {
  36. // return;
  37. // } else
  38. if (vkWeigher_Vls300_OnRecieved(ins, transfer)) {
  39. return;
  40. }
  41. }
  42. static bool shouldAcceptTransfer(const CanardInstance *ins,
  43. uint64_t *out_data_type_signature,
  44. uint16_t data_type_id,
  45. CanardTransferType transfer_type,
  46. uint8_t source_node_id) {
  47. // /* 火萤降落伞相关消息 */
  48. // if (flyfireShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
  49. // transfer_type, source_node_id)) {
  50. // return true;
  51. // }
  52. // /* 好盈电调相关消息 */
  53. // if (hbwEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
  54. // transfer_type, source_node_id)) {
  55. // return true;
  56. // }
  57. // /* 弦动电调相关消息 */
  58. // if (sinemotorEscShouldAcceptTransfer(ins, out_data_type_signature,
  59. // data_type_id, transfer_type,
  60. // source_node_id)) {
  61. // return true;
  62. // }
  63. // /* tmotor电调相关消息 */
  64. // if (tmotorEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
  65. // transfer_type, source_node_id)) {
  66. // return true;
  67. // }
  68. // /* uavcan电调相关消息 */
  69. // if (uavcanEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
  70. // transfer_type, source_node_id)) {
  71. // return true;
  72. // }
  73. /* dronecan weigher 称重器相关消息 */
  74. if (vkWeigher_Vls300_shouldAcceptTransfer(ins, out_data_type_signature,
  75. data_type_id, transfer_type,
  76. source_node_id)) {
  77. return true;
  78. }
  79. return false;
  80. }
  81. // static void send_node_status(struct dronecan *dcan) {
  82. // static uint8_t transfer_id = 0;
  83. // struct uavcan_protocol_NodeStatus msg;
  84. // uint8_t buffer[UAVCAN_PROTOCOL_NODESTATUS_MAX_SIZE] = {0};
  85. // msg.uptime_sec = systime_now_ms() / 1000;
  86. // msg.sub_mode = 0;
  87. // msg.mode = UAVCAN_PROTOCOL_NODESTATUS_MODE_OPERATIONAL;
  88. // msg.health = UAVCAN_PROTOCOL_NODESTATUS_HEALTH_OK;
  89. // uint32_t len = uavcan_protocol_NodeStatus_encode(&msg, buffer);
  90. // CanardTxTransfer tx_transfer = {
  91. // .data_type_signature = UAVCAN_PROTOCOL_NODESTATUS_SIGNATURE,
  92. // .data_type_id = UAVCAN_PROTOCOL_NODESTATUS_ID,
  93. // .inout_transfer_id = &transfer_id,
  94. // .priority = CANARD_TRANSFER_PRIORITY_MEDIUM,
  95. // .transfer_type = CanardTransferTypeBroadcast,
  96. // .payload = buffer,
  97. // .payload_len = len,
  98. // .iface_mask = 0xff, /* 发送到所有接口 */
  99. // };
  100. // dronecan_broadcast(dcan, &tx_transfer);
  101. // }
  102. void dronecan_tx_processing(void) {
  103. struct dronecan *dcan = &__dronecan;
  104. // Transmit the frames in the queue.
  105. while (1) {
  106. CanardCANFrame tx_frame = {0};
  107. CanardCANFrame *tx_frame_p = NULL;
  108. if( dronecan_lock_status == UNLOCK )
  109. {
  110. dronecan_lock();
  111. tx_frame_p = canardPeekTxQueue(&canard_ins);
  112. if (tx_frame_p == NULL)
  113. {
  114. /* 没有发送消息, 结束发送 */
  115. dronecan_unlock();
  116. break;
  117. }
  118. }
  119. else
  120. {
  121. break;
  122. }
  123. /* 将消息拷贝出来 */
  124. memcpy(&tx_frame, tx_frame_p, sizeof(tx_frame));
  125. canardPopTxQueue(&canard_ins);
  126. dronecan_unlock(dcan);
  127. /* 通过 can 接口发送消息 */
  128. can_send_msg_normal(tx_frame.data, tx_frame.data_len, tx_frame.id);
  129. }
  130. static int clear_time = 0;
  131. /* 每秒清理一次 canard 过期消息 */
  132. if( HAL_GetTick() - clear_time > 1000 )
  133. {
  134. if( dronecan_lock_status == UNLOCK )
  135. {
  136. clear_time = HAL_GetTick();
  137. dronecan_lock();
  138. canardCleanupStaleTransfers(&canard_ins, Get_Systimer_Us());
  139. dronecan_unlock();
  140. }
  141. }
  142. }
  143. /**
  144. * @brief dronecan 回调函数, 当 can 接口接收到消息时调用
  145. *
  146. * @param msg can 消息
  147. * @param iface_id can 接口 id, 用于管理多个不同 can 接口
  148. * @return int 1-是 dronecan 消息, 0-不是 dronecan 消息
  149. */
  150. int dronecan_rx_callback(CAN_RxHeaderTypeDef Rxhead,uint8_t data[]) {
  151. int ret = 0;
  152. CanardCANFrame rx_frame = {0};
  153. rx_frame.id = Rxhead.ExtId;
  154. if (Rxhead.IDE == CAN_ID_EXT) {
  155. rx_frame.id |= CANARD_CAN_FRAME_EFF;
  156. }
  157. if (Rxhead.RTR == CAN_RTR_REMOTE) {
  158. rx_frame.id |= CANARD_CAN_FRAME_RTR;
  159. }
  160. rx_frame.data_len = Rxhead.DLC;
  161. memcpy(rx_frame.data, &data[0], Rxhead.DLC);
  162. uint64_t timestamp = Get_Systimer_Us();
  163. int16_t res;
  164. if(dronecan_lock_status == UNLOCK)
  165. {
  166. dronecan_lock();
  167. res = canardHandleRxFrame(&canard_ins, &rx_frame, timestamp);
  168. dronecan_unlock();
  169. }
  170. if (res == CANARD_OK) {
  171. ret = 1;
  172. }
  173. return ret;
  174. }
  175. // static void timer_out_cb(void *arg) {
  176. // if (arg) {
  177. // struct dronecan *dcan = arg;
  178. // send_node_status(dcan);
  179. // }
  180. // }
  181. void dronecan_init(void) {
  182. struct dronecan *dcan = &__dronecan;
  183. canardInit(&canard_ins, &memory_pool,
  184. DRONECAN_CANARD_MEMORY_POOL_SIZE, onTransferReceived,
  185. shouldAcceptTransfer, dcan);
  186. canardSetLocalNodeID(&canard_ins,
  187. DRONECAN_CANARD_DEFAULT_LOCAL_NODE_ID);
  188. }
  189. /**
  190. * @brief dronecan 发送广播消息
  191. *
  192. * @param dcan dronecan 对象
  193. * @param tx_transfer 发送消息对象
  194. * @return int 发送到 canard 发送队列的消息计数
  195. */
  196. int dronecan_broadcast(struct dronecan *dcan, CanardTxTransfer *tx_transfer) {
  197. int ret = 0;
  198. if (dronecan_lock_status == UNLOCK) {
  199. dronecan_lock();
  200. ret = canardBroadcastObj(&canard_ins, tx_transfer);
  201. dronecan_unlock();
  202. }
  203. return ret;
  204. }