diff options
author | David Crocker <dcrocker@eschertech.com> | 2019-12-04 23:40:21 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2019-12-04 23:40:21 +0300 |
commit | e3ccb17cbd9edc18774d3d92def5a53c3312532f (patch) | |
tree | 8dc06839e691965d8c88eb9c9a5f9c3a245b708f | |
parent | 9cea4d41a71b37d6487c0814bfcf491a77a45a15 (diff) |
Support remote M408 and M122 P1 for ATE
Also fixed typo in M557 error messages, and faster CRC calculation on SAME70
-rw-r--r-- | src/CAN/CanInterface.cpp | 20 | ||||
-rw-r--r-- | src/CAN/CanInterface.h | 3 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 39 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 4 | ||||
-rw-r--r-- | src/Platform.cpp | 42 | ||||
-rw-r--r-- | src/Platform.h | 4 | ||||
-rw-r--r-- | src/Storage/CRC32.cpp | 24 | ||||
-rw-r--r-- | src/Version.h | 2 |
8 files changed, 68 insertions, 70 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index 16c52035..f3670200 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -798,7 +798,7 @@ GCodeResult CanInterface::SetRemoteDriverStallParameters(const CanDriversList& d return GCodeResult::ok; } -static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply, uint8_t *extra = nullptr) +static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, uint8_t param, GCodeBuffer& gb, const StringRef& reply, uint8_t *extra = nullptr) { if (boardAddress > CanId::MaxNormalAddress) { @@ -816,27 +816,26 @@ static GCodeResult GetRemoteInfo(uint8_t infoType, uint32_t boardAddress, GCodeB const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); auto msg = buf->SetupRequestMessage<CanMessageReturnInfo>(rid, CanId::MasterAddress, (CanAddress)boardAddress); msg->type = infoType; + msg->param = param; return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply, extra); } // Get diagnostics from an expansion board -GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) +GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddress, unsigned int type, GCodeBuffer& gb, const StringRef& reply) { Platform& p = reprap.GetPlatform(); - // Older expansion board firmware provides parts 0,1,2 - // Newer expansion board firmware always provides at least part0, and the 'extra' field says what the last part number is uint8_t currentPart = 0; uint8_t lastPart; GCodeResult res; do { - res = GetRemoteInfo(CanMessageReturnInfo::typeDiagnosticsPart0 + currentPart, boardAddress, gb, reply, &lastPart); + res = GetRemoteInfo(CanMessageReturnInfo::typeDiagnosticsPart0 + currentPart, boardAddress, type, gb, reply, &lastPart); if (res != GCodeResult::ok) { return res; } - if (currentPart == 0) + if (type == 0 && currentPart == 0) { p.MessageF(mt, "Diagnostics for board %u:\n", (unsigned int)boardAddress); } @@ -844,13 +843,18 @@ GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddres p.Message(mt, reply.c_str()); reply.Clear(); ++currentPart; - } while (currentPart <= ((lastPart == 0) ? 2 : lastPart)); + } while (currentPart <= lastPart); return res; } +GCodeResult CanInterface::RemoteM408(uint32_t boardAddress, unsigned int form, unsigned int type, GCodeBuffer& gb, const StringRef& reply) +{ + return GetRemoteInfo(CanMessageReturnInfo::typeM408, boardAddress, type, gb, reply, nullptr); +} + GCodeResult CanInterface::GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply) { - return GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, gb, reply); + return GetRemoteInfo(CanMessageReturnInfo::typeFirmwareVersion, boardAddress, 0, gb, reply); } // Tell an expansion board to update diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index aaa30191..460843a1 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -69,7 +69,8 @@ namespace CanInterface void SendBroadcast(CanMessageBuffer *buf); GCodeResult GetRemoteFirmwareDetails(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); - GCodeResult RemoteDiagnostics(MessageType mt, uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); + GCodeResult RemoteDiagnostics(MessageType mt, uint32_t boardAddress, unsigned int type, GCodeBuffer& gb, const StringRef& reply); + GCodeResult RemoteM408(uint32_t boardAddress, unsigned int form, unsigned int type, GCodeBuffer& gb, const StringRef& reply); GCodeResult UpdateRemoteFirmware(uint32_t boardAddress, GCodeBuffer& gb, const StringRef& reply); bool IsFlashing(); diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 5880ebd1..06f8882e 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1706,27 +1706,24 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) case 122: { - const int val = (gb.Seen('P')) ? gb.GetIValue() : 0; - if (val == 0) - { - // Set the Push flag to combine multiple messages into a single OutputBuffer chain - const MessageType mt = (MessageType)(gb.GetResponseMessageType() | PushFlag); + const unsigned int type = (gb.Seen('P')) ? gb.GetIValue() : 0; + const MessageType mt = (MessageType)(gb.GetResponseMessageType() | PushFlag); #if SUPPORT_CAN_EXPANSION - if (gb.Seen('B')) - { - const uint32_t board = gb.GetUIValue(); - if (board != CanId::MasterAddress) - { - result = CanInterface::RemoteDiagnostics(mt, board, gb, reply); - break; - } - } + const uint32_t board = (gb.Seen('B')) ? gb.GetUIValue() : 0; + if (board != CanId::MasterAddress) + { + result = CanInterface::RemoteDiagnostics(mt, board, type, gb, reply); + break; + } #endif + if (type == 0) + { + // Set the Push flag to combine multiple messages into a single OutputBuffer chain reprap.Diagnostics(mt); } else { - result = platform.DiagnosticTest(gb, reply, val); + result = platform.DiagnosticTest(gb, reply, type); } } break; @@ -2661,12 +2658,20 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) case 408: // Get status in JSON format { - const int form = gb.Seen('P') ? gb.GetIValue() : 0; + const unsigned int form = (gb.Seen('P')) ? gb.GetUIValue() : 0; + const unsigned int type = gb.Seen('S') ? gb.GetUIValue() : 0; +#if SUPPORT_CAN_EXPANSION + const uint32_t board = (gb.Seen('B')) ? gb.GetUIValue() : 0; + if (board != 0) + { + result = CanInterface::RemoteM408(board, form, type, gb, reply); + break; + } +#endif switch (form) { case 0: { - const int type = gb.Seen('S') ? gb.GetIValue() : 0; const int seq = gb.Seen('R') ? gb.GetIValue() : -1; if (&gb == auxGCode && (type == 0 || type == 2)) { diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index a79974d9..1ee06696 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -279,14 +279,14 @@ GCodeResult GCodes::DefineGrid(GCodeBuffer& gb, const StringRef &reply) if (seenX != seenY) { - reply.copy("specify both or neither of X and Y in M577"); + reply.copy("specify both or neither of X and Y in M557"); return GCodeResult::error; } if (!seenX && !seenR) { // Must have given just the S or P parameter - reply.copy("specify at least radius or X and Y ranges in M577"); + reply.copy("specify at least radius or X and Y ranges in M557"); return GCodeResult::error; } diff --git a/src/Platform.cpp b/src/Platform.cpp index 1b66e040..da06f6fc 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -1116,7 +1116,7 @@ void Platform::Spin() #endif // Diagnostics test - if (debugCode == (int)DiagnosticTestType::TestSpinLockup) + if (debugCode == (unsigned int)DiagnosticTestType::TestSpinLockup) { for (;;) {} } @@ -2066,13 +2066,13 @@ void Platform::Diagnostics(MessageType mtype) #endif } -GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, int d) +GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, unsigned int d) { static const uint32_t dummy[2] = { 0, 0 }; switch (d) { - case (int)DiagnosticTestType::PrintTestReport: + case (unsigned int)DiagnosticTestType::PrintTestReport: { const MessageType mtype = gb.GetResponseMessageType(); bool testFailed = false; @@ -2236,35 +2236,35 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in } break; - case (int)DiagnosticTestType::TestWatchdog: + case (unsigned int)DiagnosticTestType::TestWatchdog: deliberateError = true; - SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk); // disable the system tick interrupt so that we get a watchdog timeout reset + SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk); // disable the system tick interrupt so that we get a watchdog timeout reset break; - case (int)DiagnosticTestType::TestSpinLockup: + case (unsigned int)DiagnosticTestType::TestSpinLockup: deliberateError = true; - debugCode = d; // tell the Spin function to loop + debugCode = d; // tell the Spin function to loop break; - case (int)DiagnosticTestType::TestSerialBlock: // write an arbitrary message via debugPrintf() + case (unsigned int)DiagnosticTestType::TestSerialBlock: // write an arbitrary message via debugPrintf() deliberateError = true; debugPrintf("Diagnostic Test\n"); break; - case (int)DiagnosticTestType::DivideByZero: // do an integer divide by zero to test exception handling + case (unsigned int)DiagnosticTestType::DivideByZero: // do an integer divide by zero to test exception handling deliberateError = true; - (void)RepRap::DoDivide(1, 0); // call function in another module so it can't be optimised away + (void)RepRap::DoDivide(1, 0); // call function in another module so it can't be optimised away break; - case (int)DiagnosticTestType::UnalignedMemoryAccess: // do an unaligned memory access to test exception handling + case (unsigned int)DiagnosticTestType::UnalignedMemoryAccess: // do an unaligned memory access to test exception handling deliberateError = true; - SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; // by default, unaligned memory accesses are allowed, so change that - __DSB(); // make sure that instruction completes - __DMB(); // don't allow prefetch + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; // by default, unaligned memory accesses are allowed, so change that + __DSB(); // make sure that instruction completes + __DMB(); // don't allow prefetch (void)*(reinterpret_cast<const volatile char*>(dummy) + 1); break; - case (int)DiagnosticTestType::BusFault: + case (unsigned int)DiagnosticTestType::BusFault: // Read from the "Undefined (Abort)" area #if SAME70 # if USE_MPU @@ -2286,11 +2286,11 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in #endif break; - case (int)DiagnosticTestType::PrintMoves: + case (unsigned int)DiagnosticTestType::PrintMoves: DDA::PrintMoves(); break; - case (int)DiagnosticTestType::TimeSquareRoot: // Show the square root calculation time. Caution: may disable interrupt for several tens of microseconds. + case (unsigned int)DiagnosticTestType::TimeSquareRoot: // Show the square root calculation time. Caution: may disable interrupt for several tens of microseconds. { bool ok1 = true; uint32_t tim1 = 0; @@ -2332,7 +2332,7 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in } break; - case (int)DiagnosticTestType::TimeSinCos: // Show the sin/cosine calculation time. Caution: may disable interrupt for several tens of microseconds. + case (unsigned int)DiagnosticTestType::TimeSinCos: // Show the sin/cosine calculation time. Caution: may disable interrupt for several tens of microseconds. { bool ok = true; uint32_t tim1 = 0; @@ -2371,7 +2371,7 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in } break; - case (int)DiagnosticTestType::TimeSDWrite: + case (unsigned int)DiagnosticTestType::TimeSDWrite: #if HAS_MASS_STORAGE return reprap.GetGCodes().StartSDTiming(gb, reply); #else @@ -2379,7 +2379,7 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in return GCodeResult::errorNotSupported; #endif - case (int)DiagnosticTestType::PrintObjectSizes: + case (unsigned int)DiagnosticTestType::PrintObjectSizes: reply.printf( "DDA %u, DM %u, Tool %u, GCodeBuffer %u, heater %u" #if HAS_NETWORKING && !HAS_LEGACY_NETWORKING @@ -2393,7 +2393,7 @@ GCodeResult Platform::DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, in break; #ifdef DUET_NG - case (int)DiagnosticTestType::PrintExpanderStatus: + case (unsigned int)DiagnosticTestType::PrintExpanderStatus: reply.printf("Expander status %04X\n", DuetExpansion::DiagnosticRead()); break; #endif diff --git a/src/Platform.h b/src/Platform.h index a18e4193..805bad57 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -135,7 +135,7 @@ enum class BoardType : uint8_t /***************************************************************************************************/ // Enumeration to describe various tests we do in response to the M122 command -enum class DiagnosticTestType : int +enum class DiagnosticTestType : unsigned int { PrintTestReport = 1, // run some tests and report the processor ID @@ -267,7 +267,7 @@ public: void Exit(); // Shut down tidily. Calling Init after calling this should reset to the beginning void Diagnostics(MessageType mtype); - GCodeResult DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, int d); + GCodeResult DiagnosticTest(GCodeBuffer& gb, const StringRef& reply, unsigned int d); void LogError(ErrorCode e) { errorCodeBits |= (uint32_t)e; } [[noreturn]] void SoftwareReset(uint16_t reason, const uint32_t *stk = nullptr); diff --git a/src/Storage/CRC32.cpp b/src/Storage/CRC32.cpp index 297e4c75..ea5762c0 100644 --- a/src/Storage/CRC32.cpp +++ b/src/Storage/CRC32.cpp @@ -175,7 +175,7 @@ void CRC32::Update(char c) // Original algorithm (1 byte per loop iteration, 1K table): 7 instructions, 11 clocks (11 clocks/byte) // Algorithm currently used on non-SAME70 processors (4 bytes per loop iteration, 1K table): 19 instructions, 26 clocks (6.5 clocks/byte) // Slicing-by-4 using 1 dword per loop iteration: 15 instructions, 18 clocks (4.5 clocks/byte) -// Slicing-by-4 using 1 quadword per loop iteration: 28 instructions, 30 clocks (3.75 clocks/byte) +// Slicing-by-4 using 1 quadword per loop iteration: 28 instructions, 31 clocks (3.875 clocks/byte) void CRC32::Update(const char *s, size_t len) { // The speed of this function affects the speed of file uploads, so make it as fast as possible. Sadly the SAME70 doesn't do hardware CRC calculation. @@ -183,13 +183,13 @@ void CRC32::Update(const char *s, size_t len) uint32_t locCrc = crc; const char * const end = s + len; -#if SAME70 - // Process any bytes at the start until we reach a quadword boundary - while ((reinterpret_cast<uint32_t>(s) & 7) != 0 && s != end) + // Process any bytes at the start until we reach a dword boundary + while ((reinterpret_cast<uint32_t>(s) & 3) != 0 && s != end) { locCrc = (CRC_32_TAB[(locCrc ^ *s++) & 0xFF] ^ (locCrc >> 8)); } +#if SAME70 const char * const endAligned = s + ((end - s) & ~7); while (s != endAligned) { @@ -200,19 +200,7 @@ void CRC32::Update(const char *s, size_t len) locCrc = CRC_32_TAB[(data1 >> 24) & 0xFF] ^ CRC_32_TAB1[(data1 >> 16) & 0xFF] ^ CRC_32_TAB2[(data1 >> 8) & 0xFF] ^ CRC_32_TAB3[data1 & 0xFF]; s += 8; } - - // Process up to 7 bytes at the end - while (s != end) - { - locCrc = (CRC_32_TAB[(locCrc ^ *s++) & 0xFF] ^ (locCrc >> 8)); - } #else - // Process any bytes at the start until we reach a dword boundary - while ((reinterpret_cast<uint32_t>(s) & 3) != 0 && s != end) - { - locCrc = (CRC_32_TAB[(locCrc ^ *s++) & 0xFF] ^ (locCrc >> 8)); - } - const char * const endAligned = s + ((end - s) & ~3); while (s != endAligned) { @@ -223,13 +211,13 @@ void CRC32::Update(const char *s, size_t len) locCrc = (CRC_32_TAB[(locCrc ^ (data >> 16)) & 0xFF] ^ (locCrc >> 8)); locCrc = (CRC_32_TAB[(locCrc ^ (data >> 24)) & 0xFF] ^ (locCrc >> 8)); } +#endif - // Process up to 3 bytes at the end + // Process up to 7 (SAME70) or 3 (others) bytes at the end while (s != end) { locCrc = (CRC_32_TAB[(locCrc ^ *s++) & 0xFF] ^ (locCrc >> 8)); } -#endif crc = locCrc; } diff --git a/src/Version.h b/src/Version.h index 18bcae7d..f479e24f 100644 --- a/src/Version.h +++ b/src/Version.h @@ -20,7 +20,7 @@ #endif #ifndef DATE -# define DATE "2019-12-02b2" +# define DATE "2019-12-04b1" #endif #define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d" |