mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 17:03:35 +08:00
156 lines
3.5 KiB
C++
156 lines
3.5 KiB
C++
/*
|
|
* Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <cassert>
|
|
#include <algorithm>
|
|
#include <uavcan/internal/transport/can_io.hpp>
|
|
|
|
namespace uavcan
|
|
{
|
|
|
|
enum NodeIDConstants
|
|
{
|
|
NODE_ID_BROADCAST = 0,
|
|
NODE_ID_MAX = 127,
|
|
NODE_ID_INVALID = 255
|
|
};
|
|
|
|
enum TransferType
|
|
{
|
|
SERVICE_RESPONSE = 0,
|
|
SERVICE_REQUEST = 1,
|
|
MESSAGE_BROADCAST = 2,
|
|
MESSAGE_UNICAST = 3,
|
|
NUM_TRANSFER_TYPES = 4
|
|
};
|
|
|
|
|
|
class TransferID
|
|
{
|
|
uint8_t value_;
|
|
|
|
public:
|
|
enum { BITLEN = 4 };
|
|
enum { MAX = (1 << BITLEN) - 1 };
|
|
|
|
TransferID()
|
|
: value_(0)
|
|
{ }
|
|
|
|
TransferID(uint8_t value) // implicit
|
|
: value_(value)
|
|
{
|
|
value_ &= MAX;
|
|
assert(value == value_);
|
|
}
|
|
|
|
bool operator!=(TransferID rhs) const { return !operator==(rhs); }
|
|
bool operator==(TransferID rhs) const { return get() == rhs.get(); }
|
|
|
|
void increment()
|
|
{
|
|
value_ = (value_ + 1) & MAX;
|
|
}
|
|
|
|
uint8_t get() const
|
|
{
|
|
assert(value_ <= MAX);
|
|
return value_;
|
|
}
|
|
|
|
/**
|
|
* Amount of increment() calls to reach rhs value.
|
|
*/
|
|
int forwardDistance(TransferID rhs) const;
|
|
};
|
|
|
|
|
|
struct Frame
|
|
{
|
|
enum { DATA_TYPE_ID_MAX = 1023 };
|
|
enum { NODE_ID_MAX = 127 };
|
|
enum { FRAME_INDEX_MAX = 31 };
|
|
|
|
uint8_t payload[8];
|
|
TransferType transfer_type;
|
|
uint_fast16_t data_type_id;
|
|
uint_fast8_t payload_len;
|
|
uint_fast8_t source_node_id;
|
|
uint_fast8_t frame_index;
|
|
TransferID transfer_id;
|
|
bool last_frame;
|
|
|
|
Frame()
|
|
: transfer_type(TransferType(0))
|
|
, data_type_id(0)
|
|
, payload_len(0)
|
|
, source_node_id(0)
|
|
, frame_index(0)
|
|
, transfer_id(0)
|
|
, last_frame(false)
|
|
{
|
|
std::fill(payload, payload + sizeof(payload), 0);
|
|
}
|
|
|
|
Frame(const uint8_t* payload, uint_fast8_t payload_len, uint_fast16_t data_type_id, TransferType transfer_type,
|
|
uint_fast8_t source_node_id, uint_fast8_t frame_index, TransferID transfer_id, bool last_frame)
|
|
: transfer_type(transfer_type)
|
|
, data_type_id(data_type_id)
|
|
, payload_len(payload_len)
|
|
, source_node_id(source_node_id)
|
|
, frame_index(frame_index)
|
|
, transfer_id(transfer_id)
|
|
, last_frame(last_frame)
|
|
{
|
|
assert(data_type_id <= DATA_TYPE_ID_MAX);
|
|
assert(source_node_id <= NODE_ID_MAX);
|
|
assert(frame_index <= FRAME_INDEX_MAX);
|
|
assert(payload && payload_len <= sizeof(payload));
|
|
std::copy(payload, payload + payload_len, this->payload);
|
|
}
|
|
|
|
bool parse(const CanFrame& can_frame);
|
|
|
|
CanFrame compile() const;
|
|
|
|
bool operator!=(const Frame& rhs) const { return !operator==(rhs); }
|
|
bool operator==(const Frame& rhs) const
|
|
{
|
|
return
|
|
(transfer_type == rhs.transfer_type) &&
|
|
(data_type_id == rhs.data_type_id) &&
|
|
(source_node_id == rhs.source_node_id) &&
|
|
(frame_index == rhs.frame_index) &&
|
|
(transfer_id == rhs.transfer_id) &&
|
|
(last_frame == rhs.last_frame) &&
|
|
(payload_len == rhs.payload_len) &&
|
|
std::equal(payload, payload + payload_len, rhs.payload);
|
|
}
|
|
};
|
|
|
|
|
|
struct RxFrame : public Frame
|
|
{
|
|
uint_fast64_t timestamp;
|
|
uint_fast8_t iface_index;
|
|
|
|
RxFrame()
|
|
: timestamp(0)
|
|
, iface_index(0)
|
|
{ }
|
|
|
|
bool parse(const CanRxFrame& can_frame)
|
|
{
|
|
if (!Frame::parse(can_frame))
|
|
return false;
|
|
timestamp = can_frame.timestamp;
|
|
iface_index = can_frame.iface_index;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
}
|