| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- #include "dronecan.h"
- #include "drv_vkweigher_vls300.h"
- #include <string.h>
- #include "soft_timer.h"
- static struct dronecan __dronecan = {0};
- uint8_t memory_pool[DRONECAN_CANARD_MEMORY_POOL_SIZE] = {0};
- CanardInstance canard_ins;
- bool dronecan_lock_status = false;
- void dronecan_lock() {
- dronecan_lock_status = 1;
- }
- void dronecan_unlock() {
- dronecan_lock_status = 0;
- }
- int dronecan_request_or_respond(uint8_t dest_id,
- CanardTxTransfer *tx_transfer) {
- int ret = 0;
- if (dronecan_lock_status == UNLOCK) {
- dronecan_lock();
- ret = canardRequestOrRespondObj(&canard_ins, dest_id, tx_transfer);
- dronecan_unlock();
- }
- return ret;
- }
- static void onTransferReceived(CanardInstance *ins,
- CanardRxTransfer *transfer) {
- // if (flyfire_onRecieved(ins, transfer)) {
- // return;
- // } else if (hbwEscOnRecieved(ins, transfer)) {
- // return;
- // } else if (sinemotorEscOnRecieved(ins, transfer)) {
- // return;
- // } else if (tmotorEscOnRecieved(ins, transfer)) {
- // return;
- // } else if (uavcanEscOnRecieved(ins, transfer)) {
- // return;
- // } else
- if (vkWeigher_Vls300_OnRecieved(ins, transfer)) {
- return;
- }
- }
- static bool shouldAcceptTransfer(const CanardInstance *ins,
- uint64_t *out_data_type_signature,
- uint16_t data_type_id,
- CanardTransferType transfer_type,
- uint8_t source_node_id) {
- // /* 火萤降落伞相关消息 */
- // if (flyfireShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
- // transfer_type, source_node_id)) {
- // return true;
- // }
- // /* 好盈电调相关消息 */
- // if (hbwEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
- // transfer_type, source_node_id)) {
- // return true;
- // }
- // /* 弦动电调相关消息 */
- // if (sinemotorEscShouldAcceptTransfer(ins, out_data_type_signature,
- // data_type_id, transfer_type,
- // source_node_id)) {
- // return true;
- // }
- // /* tmotor电调相关消息 */
- // if (tmotorEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
- // transfer_type, source_node_id)) {
- // return true;
- // }
- // /* uavcan电调相关消息 */
- // if (uavcanEscShouldAcceptTransfer(ins, out_data_type_signature, data_type_id,
- // transfer_type, source_node_id)) {
- // return true;
- // }
- /* dronecan weigher 称重器相关消息 */
- if (vkWeigher_Vls300_shouldAcceptTransfer(ins, out_data_type_signature,
- data_type_id, transfer_type,
- source_node_id)) {
- return true;
- }
- return false;
- }
- // static void send_node_status(struct dronecan *dcan) {
- // static uint8_t transfer_id = 0;
- // struct uavcan_protocol_NodeStatus msg;
- // uint8_t buffer[UAVCAN_PROTOCOL_NODESTATUS_MAX_SIZE] = {0};
- // msg.uptime_sec = systime_now_ms() / 1000;
- // msg.sub_mode = 0;
- // msg.mode = UAVCAN_PROTOCOL_NODESTATUS_MODE_OPERATIONAL;
- // msg.health = UAVCAN_PROTOCOL_NODESTATUS_HEALTH_OK;
- // uint32_t len = uavcan_protocol_NodeStatus_encode(&msg, buffer);
- // CanardTxTransfer tx_transfer = {
- // .data_type_signature = UAVCAN_PROTOCOL_NODESTATUS_SIGNATURE,
- // .data_type_id = UAVCAN_PROTOCOL_NODESTATUS_ID,
- // .inout_transfer_id = &transfer_id,
- // .priority = CANARD_TRANSFER_PRIORITY_MEDIUM,
- // .transfer_type = CanardTransferTypeBroadcast,
- // .payload = buffer,
- // .payload_len = len,
- // .iface_mask = 0xff, /* 发送到所有接口 */
- // };
- // dronecan_broadcast(dcan, &tx_transfer);
- // }
- void dronecan_tx_processing(void) {
- struct dronecan *dcan = &__dronecan;
- // Transmit the frames in the queue.
- while (1) {
- CanardCANFrame tx_frame = {0};
- CanardCANFrame *tx_frame_p = NULL;
- if( dronecan_lock_status == UNLOCK )
- {
- dronecan_lock();
- tx_frame_p = canardPeekTxQueue(&canard_ins);
- if (tx_frame_p == NULL)
- {
- /* 没有发送消息, 结束发送 */
- dronecan_unlock();
- break;
- }
- }
- else
- {
- break;
- }
-
- /* 将消息拷贝出来 */
- memcpy(&tx_frame, tx_frame_p, sizeof(tx_frame));
- canardPopTxQueue(&canard_ins);
- dronecan_unlock(dcan);
- /* 通过 can 接口发送消息 */
- can_send_msg_normal(tx_frame.data, tx_frame.data_len, tx_frame.id);
- }
- static int clear_time = 0;
- /* 每秒清理一次 canard 过期消息 */
- if( HAL_GetTick() - clear_time > 1000 )
- {
- if( dronecan_lock_status == UNLOCK )
- {
- clear_time = HAL_GetTick();
- dronecan_lock();
- canardCleanupStaleTransfers(&canard_ins, Get_Systimer_Us());
- dronecan_unlock();
- }
- }
- }
- /**
- * @brief dronecan 回调函数, 当 can 接口接收到消息时调用
- *
- * @param msg can 消息
- * @param iface_id can 接口 id, 用于管理多个不同 can 接口
- * @return int 1-是 dronecan 消息, 0-不是 dronecan 消息
- */
- int dronecan_rx_callback(CAN_RxHeaderTypeDef Rxhead,uint8_t data[]) {
- int ret = 0;
- CanardCANFrame rx_frame = {0};
- rx_frame.id = Rxhead.ExtId;
- if (Rxhead.IDE == CAN_ID_EXT) {
- rx_frame.id |= CANARD_CAN_FRAME_EFF;
- }
- if (Rxhead.RTR == CAN_RTR_REMOTE) {
- rx_frame.id |= CANARD_CAN_FRAME_RTR;
- }
- rx_frame.data_len = Rxhead.DLC;
- memcpy(rx_frame.data, &data[0], Rxhead.DLC);
- uint64_t timestamp = Get_Systimer_Us();
- int16_t res;
- if(dronecan_lock_status == UNLOCK)
- {
- dronecan_lock();
- res = canardHandleRxFrame(&canard_ins, &rx_frame, timestamp);
- dronecan_unlock();
- }
- if (res == CANARD_OK) {
- ret = 1;
- }
- return ret;
- }
- // static void timer_out_cb(void *arg) {
- // if (arg) {
- // struct dronecan *dcan = arg;
- // send_node_status(dcan);
- // }
- // }
- void dronecan_init(void) {
- struct dronecan *dcan = &__dronecan;
- canardInit(&canard_ins, &memory_pool,
- DRONECAN_CANARD_MEMORY_POOL_SIZE, onTransferReceived,
- shouldAcceptTransfer, dcan);
- canardSetLocalNodeID(&canard_ins,
- DRONECAN_CANARD_DEFAULT_LOCAL_NODE_ID);
- }
- /**
- * @brief dronecan 发送广播消息
- *
- * @param dcan dronecan 对象
- * @param tx_transfer 发送消息对象
- * @return int 发送到 canard 发送队列的消息计数
- */
- int dronecan_broadcast(struct dronecan *dcan, CanardTxTransfer *tx_transfer) {
- int ret = 0;
- if (dronecan_lock_status == UNLOCK) {
- dronecan_lock();
- ret = canardBroadcastObj(&canard_ins, tx_transfer);
- dronecan_unlock();
- }
- return ret;
- }
|