diff --git a/examples/OpenCyphal-ToF-Distance-Sensor-Node/OpenCyphal-ToF-Distance-Sensor-Node.ino b/examples/OpenCyphal-ToF-Distance-Sensor-Node/OpenCyphal-ToF-Distance-Sensor-Node.ino index b9e8f86d..0c6c652d 100644 --- a/examples/OpenCyphal-ToF-Distance-Sensor-Node/OpenCyphal-ToF-Distance-Sensor-Node.ino +++ b/examples/OpenCyphal-ToF-Distance-Sensor-Node/OpenCyphal-ToF-Distance-Sensor-Node.ino @@ -30,8 +30,6 @@ #undef min #include -#include "NodeInfo.h" - /************************************************************************************** * NAMESPACE **************************************************************************************/ @@ -161,6 +159,24 @@ static RegisterNatural16 reg_ro_uavcan_pub_distance_id ("uavcan.pub.distance.id static RegisterString reg_ro_uavcan_pub_distance_type("uavcan.pub.distance.type", Register::Access::ReadOnly, Register::Persistent::No, "uavcan.primitive.scalar.Real32.1.0"); static RegisterList reg_list; +/* NODE INFO **************************************************************************/ + +static NodeInfo node_info +( + /* uavcan.node.Version.1.0 protocol_version */ + 1, 0, + /* uavcan.node.Version.1.0 hardware_version */ + 1, 0, + /* uavcan.node.Version.1.0 software_version */ + 0, 1, + /* saturated uint64 software_vcs_revision_id */ + NULL, + /* saturated uint8[16] unique_id */ + OpenCyphalUniqueId(), + /* saturated uint8[<=50] name */ + "107-systems.tof-sensor-node" +); + /************************************************************************************** * SETUP/LOOP **************************************************************************************/ @@ -209,7 +225,7 @@ void setup() /* Register callbacks for node info and register api. */ - node_hdl.subscribe>(onGetInfo_1_0_Request_Received); + node_info.subscribe(node_hdl); reg_list.add(reg_rw_uavcan_node_id); reg_list.add(reg_ro_uavcan_node_description); @@ -261,14 +277,6 @@ void mcp2515_onReceiveBufferFull(CanardFrame const & frame) node_hdl.onCanFrameReceived(frame, micros()); } -void onGetInfo_1_0_Request_Received(CanardRxTransfer const &transfer, Node & node_hdl) -{ - DBG_INFO("onGetInfo_1_0_Request_Received"); - GetInfo_1_0::Response<> rsp = GetInfo_1_0::Response<>(); - memcpy(&rsp.data, &NODE_INFO, sizeof(uavcan_node_GetInfo_Response_1_0)); - node_hdl.respond(rsp, transfer.metadata.remote_node_id, transfer.metadata.transfer_id); -} - void publish_heartbeat(Node & u, uint32_t const uptime, Heartbeat_1_0<>::Mode const mode) { Heartbeat_1_0<> hb; diff --git a/examples/tools/PrintUniqueId/PrintUniqueId.ino b/examples/tools/PrintUniqueId/PrintUniqueId.ino new file mode 100644 index 00000000..fcb71539 --- /dev/null +++ b/examples/tools/PrintUniqueId/PrintUniqueId.ino @@ -0,0 +1,29 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include <107-Arduino-Cyphal.h> + +/************************************************************************************** + * SETUP/LOOP + **************************************************************************************/ + +void setup() +{ + Serial.begin(115200); + while (!Serial) { } + + Serial.println(OpenCyphalUniqueId); +} + +void loop() +{ + +} diff --git a/src/107-Arduino-Cyphal.h b/src/107-Arduino-Cyphal.h index ea780b93..a324609c 100644 --- a/src/107-Arduino-Cyphal.h +++ b/src/107-Arduino-Cyphal.h @@ -14,6 +14,8 @@ #include "Node.h" #include "Types.h" +#include "NodeInfo.h" #include "register/RegisterList.h" +#include "utility/UniqueId16.h" #endif /* _107_ARDUINO_CYPHAL_H_ */ diff --git a/src/NodeInfo.cpp b/src/NodeInfo.cpp new file mode 100644 index 00000000..e5e1862a --- /dev/null +++ b/src/NodeInfo.cpp @@ -0,0 +1,61 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDES + **************************************************************************************/ + +#include "NodeInfo.h" + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +NodeInfo::NodeInfo(uint8_t const protocol_major, uint8_t const protocol_minor, + uint8_t const hardware_major, uint8_t const hardware_minor, + uint8_t const software_major, uint8_t const software_minor, + uint64_t const software_vcs_revision_id, + UniqueId16Array const unique_id, + std::string const & name) +{ + _node_info.protocol_version.major = protocol_major; + _node_info.protocol_version.minor = protocol_minor; + + _node_info.hardware_version.major = hardware_major; + _node_info.hardware_version.minor = hardware_minor; + + _node_info.software_version.major = software_major; + _node_info.software_version.minor = software_minor; + + _node_info.software_vcs_revision_id = software_vcs_revision_id; + + memcpy(_node_info.unique_id, unique_id.data(), sizeof(_node_info.unique_id)); + + _node_info.name.count = std::min(name.length(), uavcan_node_GetInfo_Response_1_0_name_ARRAY_CAPACITY_); + memcpy(_node_info.name.elements, name.c_str(), _node_info.name.count); +} + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +void NodeInfo::subscribe(Node & node_hdl) +{ + node_hdl.subscribe> + ([this](CanardRxTransfer const & transfer, Node & node_hdl) { this->onGetInfo_1_0_Request_Received(transfer, node_hdl); }); +} + +/************************************************************************************** + * PRIVATE MEMBER FUNCTIONS + **************************************************************************************/ + +void NodeInfo::onGetInfo_1_0_Request_Received(CanardRxTransfer const & transfer, Node & node_hdl) +{ + uavcan::node::GetInfo_1_0::Response<> rsp = uavcan::node::GetInfo_1_0::Response<>(); + memcpy(&rsp.data, &_node_info, sizeof(uavcan_node_GetInfo_Response_1_0)); + node_hdl.respond(rsp, transfer.metadata.remote_node_id, transfer.metadata.transfer_id); +} diff --git a/src/NodeInfo.h b/src/NodeInfo.h new file mode 100644 index 00000000..05f70dc8 --- /dev/null +++ b/src/NodeInfo.h @@ -0,0 +1,45 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +#ifndef ARDUINO_OPENCYPHAL_NODE_INFO_H_ +#define ARDUINO_OPENCYPHAL_NODE_INFO_H_ + +/************************************************************************************** + * INCLUDES + **************************************************************************************/ + +#include + +#include "Node.h" +#include "utility/UniqueId16.h" + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class NodeInfo +{ +public: + + NodeInfo(uint8_t const protocol_major, uint8_t const protocol_minor, + uint8_t const hardware_major, uint8_t const hardware_minor, + uint8_t const software_major, uint8_t const software_minor, + uint64_t const software_vcs_revision_id, + UniqueId16Array const unique_id, + std::string const & name); + + + void subscribe(Node & node_hdl); + + +private: + uavcan_node_GetInfo_Response_1_0 _node_info; + + void onGetInfo_1_0_Request_Received(CanardRxTransfer const & transfer, Node & node_hdl); +}; + +#endif /* ARDUINO_OPENCYPHAL_NODE_INFO_H_ */ diff --git a/src/utility/CritSec-rp2040.cpp b/src/utility/CritSec-rp2040.cpp index e8bfbe00..a00c80c3 100644 --- a/src/utility/CritSec-rp2040.cpp +++ b/src/utility/CritSec-rp2040.cpp @@ -11,7 +11,7 @@ #include "CritSec.h" -#if defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT) +#if defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED) #include /************************************************************************************** @@ -28,4 +28,4 @@ extern "C" void crit_sec_leave() interrupts(); } -#endif /* ARDUINO_ARCH_RP2040 */ +#endif /* defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED) */ diff --git a/src/utility/UniqueId16-esp32.cpp b/src/utility/UniqueId16-esp32.cpp new file mode 100644 index 00000000..36a30898 --- /dev/null +++ b/src/utility/UniqueId16-esp32.cpp @@ -0,0 +1,43 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include "UniqueId16.h" + +#if defined(ARDUINO_ARCH_ESP32) + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace impl +{ + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +UniqueId16::UniqueId16() +: _unique_id{0} +{ + size_t constexpr CHIP_ID_SIZE = 6; + uint64_t const chipid = ESP.getEfuseMac(); + memcpy(_unique_id, &chipid, CHIP_ID_SIZE); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* impl */ + +#endif /* defined(ARDUINO_ARCH_ESP32) */ diff --git a/src/utility/UniqueId16-rp2040.cpp b/src/utility/UniqueId16-rp2040.cpp new file mode 100644 index 00000000..bcbf87e8 --- /dev/null +++ b/src/utility/UniqueId16-rp2040.cpp @@ -0,0 +1,45 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include "UniqueId16.h" + +#if defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED) + +#include +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace impl +{ + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +UniqueId16::UniqueId16() +: _unique_id{0} +{ + pico_unique_board_id_t pico_id; + pico_get_unique_board_id(&pico_id); + + memcpy(_unique_id, pico_id.id, PICO_UNIQUE_BOARD_ID_SIZE_BYTES); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* impl */ + +#endif /* defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARDUINO_NANO_RP2040_CONNECT) */ diff --git a/examples/OpenCyphal-ToF-Distance-Sensor-Node/NodeInfo.h b/src/utility/UniqueId16-samd.cpp similarity index 55% rename from examples/OpenCyphal-ToF-Distance-Sensor-Node/NodeInfo.h rename to src/utility/UniqueId16-samd.cpp index c8fc739e..9b338166 100644 --- a/examples/OpenCyphal-ToF-Distance-Sensor-Node/NodeInfo.h +++ b/src/utility/UniqueId16-samd.cpp @@ -5,14 +5,22 @@ * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. */ -#ifndef NODE_INFO_H_ -#define NODE_INFO_H_ +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include "UniqueId16.h" + +#ifdef ARDUINO_ARCH_SAMD + +#include /************************************************************************************** - * INCLUDES + * NAMESPACE **************************************************************************************/ -#include <107-Arduino-Cyphal.h> +namespace impl +{ /************************************************************************************** * DEFINES @@ -24,53 +32,32 @@ #define ATSAMD21G18_SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048) /************************************************************************************** - * TYPEDEF + * CTOR/DTOR **************************************************************************************/ -union UniqueId +UniqueId16::UniqueId16() { - struct __attribute__((packed)) + union { - uint32_t w0, w1, w2, w3; - } word_buf; - uint8_t byte_buf[16]; -}; - -/************************************************************************************** - * CONSTANTS - **************************************************************************************/ + struct __attribute__((packed)) + { + uint32_t w0, w1, w2, w3; + } word_buf; + uint8_t byte_buf[16]; + } uid; -UniqueId const UNIQUE_ID = []() -{ - UniqueId uid; uid.word_buf.w0 = ATSAMD21G18_SERIAL_NUMBER_WORD_0; uid.word_buf.w1 = ATSAMD21G18_SERIAL_NUMBER_WORD_1; uid.word_buf.w2 = ATSAMD21G18_SERIAL_NUMBER_WORD_2; uid.word_buf.w3 = ATSAMD21G18_SERIAL_NUMBER_WORD_3; - return uid; -} (); -static const uavcan_node_GetInfo_Response_1_0 NODE_INFO = { - /* uavcan.node.Version.1.0 protocol_version */ - {1, 0}, - /* uavcan.node.Version.1.0 hardware_version */ - {1, 0}, - /* uavcan.node.Version.1.0 software_version */ - {0, 1}, - /* saturated uint64 software_vcs_revision_id */ - NULL, - /* saturated uint8[16] unique_id */ - { - UNIQUE_ID.byte_buf[ 0], UNIQUE_ID.byte_buf[ 1], UNIQUE_ID.byte_buf[ 2], UNIQUE_ID.byte_buf[ 3], - UNIQUE_ID.byte_buf[ 4], UNIQUE_ID.byte_buf[ 5], UNIQUE_ID.byte_buf[ 6], UNIQUE_ID.byte_buf[ 7], - UNIQUE_ID.byte_buf[ 8], UNIQUE_ID.byte_buf[ 9], UNIQUE_ID.byte_buf[10], UNIQUE_ID.byte_buf[11], - UNIQUE_ID.byte_buf[12], UNIQUE_ID.byte_buf[13], UNIQUE_ID.byte_buf[14], UNIQUE_ID.byte_buf[15] - }, - /* saturated uint8[<=50] name */ - { - "107-systems.tof-sensor-node", - strlen("107-systems.tof-sensor-node") - }, -}; + memcpy(_unique_id, uid.byte_buf, sizeof(_unique_id)); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* impl */ -#endif /* NODE_INFO_H_ */ +#endif /* ARDUINO_ARCH_SAMD */ diff --git a/src/utility/UniqueId16.cpp b/src/utility/UniqueId16.cpp new file mode 100644 index 00000000..19269b1c --- /dev/null +++ b/src/utility/UniqueId16.cpp @@ -0,0 +1,77 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include "UniqueId16.h" + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace impl +{ + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +#if !defined(ARDUINO_ARCH_SAMD) && !defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_MBED) +# warning "No Unique ID support for your platform, defaulting to hard-coded ID" +UniqueId16::UniqueId16() +: _unique_id{0} +{ } +#endif + +/************************************************************************************** + * PUBLIC MEMBER FUNCTIONS + **************************************************************************************/ + +UniqueId16 const & UniqueId16::instance() +{ + static UniqueId16 instance; + return instance; +} + +uint8_t UniqueId16::operator[](size_t const idx) const +{ + if (idx < ID_SIZE) + return _unique_id[idx]; + else + return 0; +} + +UniqueId16::Array UniqueId16::operator()() const +{ + Array uid; + std::copy(std::begin(_unique_id), + std::end (_unique_id), + std::begin(uid)); + return uid; +} + +size_t UniqueId16::printTo(Print & p) const +{ + char msg[ID_SIZE * 2 + 1] = {0}; /* Reserve enough space for displaying ID including string 0 termination. */ + snprintf(msg, sizeof(msg), "%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X%0X", + _unique_id[ 0], _unique_id[ 1], _unique_id[ 2], _unique_id[ 3], + _unique_id[ 4], _unique_id[ 5], _unique_id[ 6], _unique_id[ 7], + _unique_id[ 8], _unique_id[ 9], _unique_id[10], _unique_id[11], + _unique_id[12], _unique_id[13], _unique_id[14], _unique_id[15]); + + return p.write(msg); +} + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* impl */ diff --git a/src/utility/UniqueId16.h b/src/utility/UniqueId16.h new file mode 100644 index 00000000..a056523c --- /dev/null +++ b/src/utility/UniqueId16.h @@ -0,0 +1,80 @@ +/** + * This software is distributed under the terms of the MIT License. + * Copyright (c) 2020 LXRobotics. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/107-Arduino-Cyphal/graphs/contributors. + */ + +#ifndef ARDUINO_UNIQUE_ID_H_ +#define ARDUINO_UNIQUE_ID_H_ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include +#include + +#include +#include + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace impl +{ + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class UniqueId16 : +#if defined(ARDUINO_ARCH_ESP32) +public Printable +#else +public arduino::Printable +#endif +{ +public: + static size_t constexpr ID_SIZE = 16; + + virtual ~UniqueId16() { } + UniqueId16(UniqueId16 const &) = delete; + + static UniqueId16 const & instance(); + + uint8_t operator[](size_t const idx) const; + typedef std::array Array; + Array operator()() const; + + + virtual size_t printTo(Print & p) const override; + + +private: + UniqueId16(); + uint8_t _unique_id[ID_SIZE]; +}; + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* impl */ + +/************************************************************************************** + * TYPEDEF + **************************************************************************************/ + +typedef impl::UniqueId16::Array UniqueId16Array; + +/************************************************************************************** + * DEFINE + **************************************************************************************/ + +#define OpenCyphalUniqueId impl::UniqueId16::instance() + +#endif /* ARDUINO_UNIQUE_ID_H_ */