Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2021-10-04 18:29:00 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-10-04 18:29:00 +0300
commite9aec3423d1ed4d8d0a543ba0ca073770b7a4638 (patch)
treebb511deedde00467f6abfbe919319b42171cf08a /src/Platform
parentd4ff8360603832d2738d0158cba4877b9a064dcd (diff)
Handle CanMessageAnnounceNew, also refactored handling of unique IDs
Diffstat (limited to 'src/Platform')
-rw-r--r--src/Platform/Platform.cpp129
-rw-r--r--src/Platform/Platform.h9
-rw-r--r--src/Platform/RepRap.cpp6
-rw-r--r--src/Platform/UniqueId.cpp29
-rw-r--r--src/Platform/UniqueId.h25
5 files changed, 79 insertions, 119 deletions
diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp
index 3b0ddabc..2fcaeec9 100644
--- a/src/Platform/Platform.cpp
+++ b/src/Platform/Platform.cpp
@@ -45,10 +45,6 @@
#include <Accelerometers/Accelerometers.h>
#if SAM4E || SAM4S || SAME70
-# include <Flash.h> // for flash_read_unique_id()
-#endif
-
-#if SAM4E || SAM4S || SAME70
# include <AnalogIn.h>
# include <DmacManager.h>
using LegacyAnalogIn::AdcBits;
@@ -251,7 +247,7 @@ constexpr ObjectModelTableEntry Platform::objectModelTable[] =
#endif
{ "supportsDirectDisplay", OBJECT_MODEL_FUNC_NOSELF(SUPPORT_12864_LCD ? true : false), ObjectModelEntryFlags::verbose },
#if MCU_HAS_UNIQUE_ID
- { "uniqueId", OBJECT_MODEL_FUNC(self->GetUniqueIdString()), ObjectModelEntryFlags::none },
+ { "uniqueId", OBJECT_MODEL_FUNC(self->uniqueId), ObjectModelEntryFlags::none },
#endif
#if HAS_12V_MONITOR
{ "v12", OBJECT_MODEL_FUNC(self, 6), ObjectModelEntryFlags::live },
@@ -456,7 +452,17 @@ void Platform::Init() noexcept
#endif
#if MCU_HAS_UNIQUE_ID
- ReadUniqueId();
+ uniqueId.SetFromCurrentBoard();
+ if (uniqueId.IsValid())
+ {
+ uniqueId.GenerateMacAddress(defaultMacAddress);
+ }
+ else
+ {
+ defaultMacAddress.SetDefault();
+ }
+#else
+ defaultMacAddress.SetDefault();
#endif
// Real-time clock
@@ -878,109 +884,6 @@ void Platform::ResetVoltageMonitors() noexcept
reprap.BoardsUpdated();
}
-#if MCU_HAS_UNIQUE_ID
-
-// Read the unique ID of the MCU, if it has one
-void Platform::ReadUniqueId()
-{
-# if SAME5x
- for (size_t i = 0; i < 4; ++i)
- {
- uniqueId[i] = *reinterpret_cast<const uint32_t*>(SerialNumberAddresses[i]);
- }
-# else
- memset(uniqueId, 0, sizeof(uniqueId));
-
- const bool cacheWasEnabled = Cache::Disable();
-#if SAM4E || SAM4S || SAME70
- const bool success = Flash::ReadUniqueId(uniqueId);
-#else
- const bool success = flash_read_unique_id(uniqueId) == 0;
-#endif
- if (cacheWasEnabled)
- {
- Cache::Enable();
- }
-
- if (success)
- {
-# endif
- // Put the checksum at the end
- // We only print 30 5-bit characters = 128 data bits + 22 checksum bits. So compress the 32 checksum bits into 22.
- uniqueId[4] = uniqueId[0] ^ uniqueId[1] ^ uniqueId[2] ^ uniqueId[3];
- uniqueId[4] ^= (uniqueId[4] >> 10);
-
- // On the Duet Ethernet and SAM E70, use the unique chip ID as most of the MAC address.
- // The unique ID is 128 bits long whereas the whole MAC address is only 48 bits,
- // so we can't guarantee that each Duet will get a unique MAC address this way.
- memset(defaultMacAddress.bytes, 0, sizeof(defaultMacAddress.bytes));
- defaultMacAddress.bytes[0] = 0xBE; // use a fixed first byte with the locally-administered bit set
- const uint8_t * const idBytes = reinterpret_cast<const uint8_t *>(uniqueId);
- for (size_t i = 0; i < 15; ++i)
- {
- defaultMacAddress.bytes[(i % 5) + 1] ^= idBytes[i];
- }
-
- // Convert the unique ID and checksum to a string as 30 base5 alphanumeric digits
- char *digitPtr = uniqueIdChars;
- for (size_t i = 0; i < 30; ++i)
- {
- if ((i % 5) == 0 && i != 0)
- {
- *digitPtr++ = '-';
- }
- const size_t index = (i * 5) / 32;
- const size_t shift = (i * 5) % 32;
- uint32_t val = uniqueId[index] >> shift;
- if (shift > 32 - 5)
- {
- // We need some bits from the next dword too
- val |= uniqueId[index + 1] << (32 - shift);
- }
- val &= 31;
- char c;
- if (val < 10)
- {
- c = val + '0';
- }
- else
- {
- c = val + ('A' - 10);
- // We have 26 letters in the usual A-Z alphabet and we only need 22 of them plus 0-9.
- // So avoid using letters C, E, I and O which are easily mistaken for G, F, 1 and 0.
- if (c >= 'C')
- {
- ++c;
- }
- if (c >= 'E')
- {
- ++c;
- }
- if (c >= 'I')
- {
- ++c;
- }
- if (c >= 'O')
- {
- ++c;
- }
- }
- *digitPtr++ = c;
- }
- *digitPtr = 0;
-
-# if !SAME5x
- }
- else
- {
- defaultMacAddress.SetDefault();
- strcpy(uniqueIdChars, "unknown");
- }
-# endif
-}
-
-#endif
-
// Send the beep command to the aux channel. There is no flow control on this port, so it can't block for long.
void Platform::PanelDueBeep(int freq, int ms) noexcept
{
@@ -2114,7 +2017,8 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, Ou
#if MCU_HAS_UNIQUE_ID
if (!testFailed)
{
- buf->lcatf("Board ID: %s", GetUniqueIdString());
+ buf->lcat("Board ID: ");
+ uniqueId.AppendCharsToBuffer(buf);
}
#endif
}
@@ -4703,7 +4607,7 @@ GCodeResult Platform::UpdateRemoteStepsPerMmAndMicrostepping(AxesBitmap axesAndE
return CanInterface::SetRemoteDriverStepsPerMmAndMicrostepping(data, reply);
}
-void Platform::OnProcessingCanMessage()
+void Platform::OnProcessingCanMessage() noexcept
{
#ifdef DUET3MINI // MB6HC doesn't yet have a ACT LED
whenLastCanMessageProcessed = millis();
@@ -4746,8 +4650,7 @@ GCodeResult Platform::GetSetAncillaryPwm(GCodeBuffer& gb, const StringRef& reply
// Get a pseudo-random number (not a true random number)
uint32_t Platform::Random() noexcept
{
- const uint32_t clocks = StepTimer::GetTimerTicks();
- return clocks ^ uniqueId[0] ^ uniqueId[1] ^ uniqueId[2] ^ uniqueId[3];
+ return StepTimer::GetTimerTicks() ^ uniqueId.GetHash();
}
#endif
diff --git a/src/Platform/Platform.h b/src/Platform/Platform.h
index 615cdd62..01b19307 100644
--- a/src/Platform/Platform.h
+++ b/src/Platform/Platform.h
@@ -30,6 +30,7 @@ Licence: GPL
#include <Fans/FansManager.h>
#include <Heating/TemperatureError.h>
#include "OutputMemory.h"
+#include "UniqueId.h"
#include <Storage/FileStore.h>
#include <Storage/FileData.h>
#include <Storage/MassStorage.h> // must be after Pins.h because it needs NumSdCards defined
@@ -621,8 +622,8 @@ public:
pre(gpinPortNumber < MaxGpInPorts) { return gpinPorts[gpinPortNumber]; }
#if MCU_HAS_UNIQUE_ID
+ const UniqueId& GetUniqueId() const noexcept { return uniqueId; }
uint32_t Random() noexcept;
- const char *GetUniqueIdString() const noexcept { return uniqueIdChars; }
#endif
#if SUPPORT_CAN_EXPANSION
@@ -647,7 +648,7 @@ public:
#endif
#if SUPPORT_CAN_EXPANSION
- void OnProcessingCanMessage(); // called when we start processing any CAN message except for regular messages e.g. time sync
+ void OnProcessingCanMessage() noexcept; // called when we start processing any CAN message except for regular messages e.g. time sync
#endif
protected:
@@ -688,9 +689,7 @@ private:
// Board and processor
#if MCU_HAS_UNIQUE_ID
- void ReadUniqueId();
- uint32_t uniqueId[5];
- char uniqueIdChars[30 + 5 + 1]; // 30 characters, 5 separators, 1 null terminator
+ UniqueId uniqueId;
#endif
BoardType board;
diff --git a/src/Platform/RepRap.cpp b/src/Platform/RepRap.cpp
index cd15506a..2645e555 100644
--- a/src/Platform/RepRap.cpp
+++ b/src/Platform/RepRap.cpp
@@ -909,7 +909,11 @@ void RepRap::Diagnostics(MessageType mtype) noexcept
// (uint32_t)platform, (uint32_t)network, (uint32_t)move, (uint32_t)heat, (uint32_t)gCodes, (uint32_t)scanner, (uint32_t)printMonitor, (uint32_t)portControl);
#if MCU_HAS_UNIQUE_ID
- platform->MessageF(mtype, "Board ID: %s\n", platform->GetUniqueIdString());
+ {
+ String<StringLength50> idChars;
+ platform->GetUniqueId().AppendCharsToString(idChars.GetRef());
+ platform->MessageF(mtype, "Board ID: %s\n", idChars.c_str());
+ }
#endif
// Show the used and free buffer counts. Do this early in case we are running out of them and the diagnostics get truncated.
diff --git a/src/Platform/UniqueId.cpp b/src/Platform/UniqueId.cpp
new file mode 100644
index 00000000..c3b4d495
--- /dev/null
+++ b/src/Platform/UniqueId.cpp
@@ -0,0 +1,29 @@
+/*
+ * UniqueId.cpp
+ *
+ * Created on: 4 Oct 2021
+ * Author: David
+ */
+
+#include "UniqueId.h"
+
+// Append the unique ID in character form to an output buffer
+void UniqueId::AppendCharsToBuffer(OutputBuffer *buf) const noexcept
+{
+ AppendCharsTo([buf](char c)-> void { buf->cat(c);});
+}
+
+// Generate a MAC address from this unique ID. Caller should check IsValid() first.
+void UniqueId::GenerateMacAddress(MacAddress& addr) const noexcept
+{
+ // The unique ID is 128 bits long whereas the whole MAC address is only 48 bits, so we can't guarantee that each Duet will get a unique MAC address this way.
+ memset(addr.bytes, 0, sizeof(addr.bytes));
+ addr.bytes[0] = 0xBE; // use a fixed first byte with the locally-administered bit set
+ const uint8_t * const idBytes = reinterpret_cast<const uint8_t *>(data);
+ for (size_t i = 0; i < 15; ++i)
+ {
+ addr.bytes[(i % 5) + 1] ^= idBytes[i];
+ }
+}
+
+// End
diff --git a/src/Platform/UniqueId.h b/src/Platform/UniqueId.h
new file mode 100644
index 00000000..dc51db66
--- /dev/null
+++ b/src/Platform/UniqueId.h
@@ -0,0 +1,25 @@
+/*
+ * UniqueId.h
+ *
+ * Created on: 4 Oct 2021
+ * Author: David
+ *
+ * This class extends UniqueIdBase to add additional functions
+ */
+
+#ifndef SRC_PLATFORM_UNIQUEID_H_
+#define SRC_PLATFORM_UNIQUEID_H_
+
+#include <UniqueIdBase.h>
+#include <Platform/OutputMemory.h>
+#include <Networking/NetworkDefs.h>
+
+// Unique ID class extended with some additional functions
+class UniqueId : public UniqueIdBase
+{
+public:
+ void AppendCharsToBuffer(OutputBuffer *buf) const noexcept;
+ void GenerateMacAddress(MacAddress& addr) const noexcept;
+};
+
+#endif /* SRC_PLATFORM_UNIQUEID_H_ */