diff options
author | David Crocker <dcrocker@eschertech.com> | 2020-12-28 14:23:52 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2020-12-28 14:23:52 +0300 |
commit | 44f3b93ddec110ecde6d5b5f8c32cdd8f4cfea22 (patch) | |
tree | 82eb659348214ef8228526d45e54d3016bf51b9b | |
parent | f6b6be2b85b4cf83a366ffe56de89a1cbdc2a2de (diff) |
Partially implemented M954
-rw-r--r-- | src/CAN/CanInterface.cpp | 140 | ||||
-rw-r--r-- | src/CAN/CanInterface.h | 10 | ||||
-rw-r--r-- | src/CAN/CommandProcessor.cpp | 19 | ||||
-rw-r--r-- | src/Endstops/EndstopsManager.cpp | 4 | ||||
-rw-r--r-- | src/Endstops/SwitchEndstop.cpp | 6 | ||||
-rw-r--r-- | src/Endstops/SwitchEndstop.h | 3 | ||||
-rw-r--r-- | src/Fans/FansManager.cpp | 2 | ||||
-rw-r--r-- | src/Fans/RemoteFan.cpp | 4 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 4 | ||||
-rw-r--r-- | src/GCodes/GCodes2.cpp | 17 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 22 | ||||
-rw-r--r-- | src/GPIO/GpInPort.cpp | 12 | ||||
-rw-r--r-- | src/GPIO/GpInPort.h | 2 | ||||
-rw-r--r-- | src/GPIO/GpOutPort.h | 2 | ||||
-rw-r--r-- | src/Hardware/IoPorts.cpp | 2 | ||||
-rw-r--r-- | src/Heating/Heat.cpp | 4 | ||||
-rw-r--r-- | src/Heating/RemoteHeater.cpp | 8 | ||||
-rw-r--r-- | src/Platform.cpp | 2 | ||||
-rw-r--r-- | src/RepRapFirmware.h | 17 |
19 files changed, 179 insertions, 101 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp index 08bb748e..6fda53b9 100644 --- a/src/CAN/CanInterface.cpp +++ b/src/CAN/CanInterface.cpp @@ -61,7 +61,16 @@ static uint32_t lastTimeSent = 0; static uint32_t longestWaitTime = 0; static uint16_t longestWaitMessageType = 0; -static bool inEutMode = false; +static CanAddress myAddress = +#ifdef DUET3ATE + CanId::ATEMasterAddress; +#else + CanId::MasterAddress; +#endif + +#if SUPPORT_REMOTE_COMMANDS +static bool inExpansionMode = false; +#endif //#define CAN_DEBUG @@ -194,7 +203,7 @@ static void configure_mcan() noexcept // Set up a filter to receive all request messages addressed to us in FIFO 0 mcan_get_extended_message_filter_element_default(&et_filter); - et_filter.F0.bit.EFID1 = (CanId::MasterAddress << CanId::DstAddressShift); + et_filter.F0.bit.EFID1 = (CanInterface::GetCanAddress() << CanId::DstAddressShift); et_filter.F0.bit.EFEC = MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_EFEC_STF0M_Val; // RxFifoIndexRequest et_filter.F1.bit.EFID2 = (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit; et_filter.F1.bit.EFT = 2; @@ -210,12 +219,22 @@ static void configure_mcan() noexcept // Set up a filter to receive response messages in FIFO 1 mcan_get_extended_message_filter_element_default(&et_filter); - et_filter.F0.bit.EFID1 = (CanId::MasterAddress << CanId::DstAddressShift) | CanId::ResponseBit; + et_filter.F0.bit.EFID1 = (CanInterface::GetCanAddress() << CanId::DstAddressShift) | CanId::ResponseBit; et_filter.F0.bit.EFEC = MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_EFEC_STF1M_Val; // RxFifoIndexResponse et_filter.F1.bit.EFID2 = (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit; et_filter.F1.bit.EFT = 2; mcan_set_rx_extended_filter(&mcan_instance, &et_filter, 2); +# ifdef DUET3_ATE + // Also respond to requests addressed to board 0 so we can update firmware on ATE boards + mcan_get_extended_message_filter_element_default(&et_filter); + et_filter.F0.bit.EFID1 = (CanId::MasterAddress << CanId::DstAddressShift); + et_filter.F0.bit.EFEC = MCAN_EXTENDED_MESSAGE_FILTER_ELEMENT_F0_EFEC_STF0M_Val; // RxFifoIndexRequest + et_filter.F1.bit.EFID2 = (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit; + et_filter.F1.bit.EFT = 2; + mcan_set_rx_extended_filter(&mcan_instance, &et_filter, 3); +# endif + mcan_enable_interrupt(&mcan_instance, (mcan_interrupt_source)(MCAN_FORMAT_ERROR | MCAN_ACKNOWLEDGE_ERROR | MCAN_BUS_OFF | MCAN_RX_FIFO_0_NEW_MESSAGE | MCAN_RX_FIFO_1_NEW_MESSAGE | MCAN_RX_FIFO_0_LOST_MESSAGE | MCAN_RX_FIFO_1_MESSAGE_LOST)); @@ -314,6 +333,50 @@ extern "C" [[noreturn]] void CanSenderLoop(void *) noexcept; extern "C" [[noreturn]] void CanClockLoop(void *) noexcept; extern "C" [[noreturn]] void CanReceiverLoop(void *) noexcept; +#if SAME5x + +static void InitReceiveFilters() noexcept +{ + // Set up a filter to receive all request messages addressed to us in FIFO 0 + can0dev->SetExtendedFilterElement(0, CanDevice::RxBufferNumber::fifo0, + CanInterface::GetCanAddress() << CanId::DstAddressShift, + (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); + + // Set up a filter to receive all broadcast messages also in FIFO 0 + can0dev->SetExtendedFilterElement(1, CanDevice::RxBufferNumber::fifo0, + CanId::BroadcastAddress << CanId::DstAddressShift, + CanId::BoardAddressMask << CanId::DstAddressShift); + + // Set up a filter to receive response messages in FIFO 1 + can0dev->SetExtendedFilterElement(2, RxBufferIndexResponse, + (CanInterface::GetCanAddress() << CanId::DstAddressShift) | CanId::ResponseBit, + (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); +# ifdef DUET3_ATE + // Also respond to requests addressed to board 0 so we can update firmware on ATE boards + can0dev->SetExtendedFilterElement(3, CanDevice::RxBufferNumber::fifo0, + CanId::MasterAddress << CanId::DstAddressShift, + (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); +# endif +} + +#endif + +#if SUPPORT_REMOTE_COMMANDS + +static void ReInit() noexcept +{ +#if SAME70 + mcan_stop(&mcan_instance); + configure_mcan(); // this includes initialising the receive filters +#else + can0dev->Disable(); + InitReceiveFilters(); + can0dev->Enable(); +#endif +} + +#endif + void CanInterface::Init() noexcept { CanMessageBuffer::Init(NumCanBuffers); @@ -340,27 +403,7 @@ void CanInterface::Init() noexcept CanTiming timing; timing.SetDefaults(); can0dev = CanDevice::Init(0, CanDeviceNumber, Can0Config, can0Memory, timing); - - // Set up a filter to receive all request messages addressed to us in FIFO 0 - can0dev->SetExtendedFilterElement(0, CanDevice::RxBufferNumber::fifo0, - MyAddress << CanId::DstAddressShift, - (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); - - // Set up a filter to receive all broadcast messages also in FIFO 0 - can0dev->SetExtendedFilterElement(1, CanDevice::RxBufferNumber::fifo0, - CanId::BroadcastAddress << CanId::DstAddressShift, - CanId::BoardAddressMask << CanId::DstAddressShift); - - // Set up a filter to receive response messages in FIFO 1 - can0dev->SetExtendedFilterElement(2, RxBufferIndexResponse, - (MyAddress << CanId::DstAddressShift) | CanId::ResponseBit, - (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); -# ifdef DUET3_ATE - // Also respond to requests addressed to board 0 so we can update firmware on ATE boards - can0dev->SetExtendedFilterElement(3, CanDevice::RxBufferNumber::fifo0, - CanId::MasterAddress << CanId::DstAddressShift, - (CanId::BoardAddressMask << CanId::DstAddressShift) | CanId::ResponseBit); -# endif + InitReceiveFilters(); can0dev->Enable(); #else mcan_init_once(&mcan_instance, MCAN_MODULE); @@ -396,11 +439,30 @@ void CanInterface::Shutdown() noexcept #endif } -bool CanInterface::InEutMode() noexcept +CanAddress CanInterface::GetCanAddress() noexcept +{ + return myAddress; +} + +#if SUPPORT_REMOTE_COMMANDS + +bool CanInterface::InExpansionMode() noexcept +{ + return inExpansionMode; +} + +void CanInterface::SwitchToExpansionMode(CanAddress addr) noexcept { - return inEutMode; + TaskCriticalSectionLocker lock; + + myAddress = addr; + inExpansionMode = true; + reprap.GetGCodes().SwitchToExpansionMode(); + ReInit(); // reset the CAN filters to account for our new CAN address } +#endif + // Allocate a CAN request ID CanRequestId CanInterface::AllocateRequestId(CanAddress destination) noexcept { @@ -497,7 +559,9 @@ extern "C" [[noreturn]] void CanClockLoop(void *) noexcept for (;;) { - if (!inEutMode) +#if SUPPORT_REMOTE_COMMANDS + if (!inExpansionMode) +#endif { CanMessageTimeSync * const msg = buf.SetupBroadcastMessage<CanMessageTimeSync>(CanInterface::GetCanAddress()); #if USE_NEW_CAN_DRIVER @@ -991,7 +1055,7 @@ GCodeResult CanInterface::RemoteDiagnostics(MessageType mt, uint32_t boardAddres // It's a diagnostic test CanMessageBuffer * const buf = AllocateBuffer(&gb); const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto const msg = buf->SetupRequestMessage<CanMessageDiagnosticTest>(rid, MyAddress, (CanAddress)boardAddress); + auto const msg = buf->SetupRequestMessage<CanMessageDiagnosticTest>(rid, GetCanAddress(), (CanAddress)boardAddress); msg->testType = type; msg->invertedTestType = ~type; if (type == (uint16_t)DiagnosticTestType::AccessMemory) @@ -1038,7 +1102,7 @@ GCodeResult CanInterface::CreateHandle(CanAddress boardAddress, RemoteInputHandl } const CanRequestId rid = AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageCreateInputMonitor>(rid, MyAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageCreateInputMonitor>(rid, GetCanAddress(), boardAddress); msg->handle = h; msg->threshold = threshold; msg->minInterval = minInterval; @@ -1113,7 +1177,7 @@ GCodeResult CanInterface::ReadRemoteHandles(CanAddress boardAddress, RemoteInput } const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageReadInputsRequest>(rid, MyAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageReadInputsRequest>(rid, GetCanAddress(), boardAddress); msg->mask = mask; msg->pattern = pattern; const GCodeResult rslt = SendRequestAndGetCustomReply(buf, rid, reply, nullptr, CanMessageType::readInputsReply, @@ -1150,7 +1214,7 @@ GCodeResult CanInterface::WriteGpio(CanAddress boardAddress, uint8_t portNumber, { CanMessageBuffer * const buf = AllocateBuffer(&gb); const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageWriteGpio>(rid, MyAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageWriteGpio>(rid, GetCanAddress(), boardAddress); msg->portNumber = portNumber; msg->pwm = pwm; msg->isServo = isServo; @@ -1222,7 +1286,7 @@ GCodeResult CanInterface::ChangeAddressAndNormalTiming(GCodeBuffer& gb, const St CanMessageBufferHandle buf(AllocateBuffer(&gb)); const CanRequestId rid = CanInterface::AllocateRequestId((uint8_t)oldAddress); - auto msg = buf.Access()->SetupRequestMessage<CanMessageSetAddressAndNormalTiming>(rid, MyAddress, (uint8_t)oldAddress); + auto msg = buf.Access()->SetupRequestMessage<CanMessageSetAddressAndNormalTiming>(rid, GetCanAddress(), (uint8_t)oldAddress); msg->oldAddress = (uint8_t)oldAddress; if (gb.Seen('A')) @@ -1255,7 +1319,7 @@ GCodeResult CanInterface::CreateFilamentMonitor(DriverId driver, uint8_t type, c { CanMessageBuffer* const buf = AllocateBuffer(&gb); const CanRequestId rid = CanInterface::AllocateRequestId(driver.boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageCreateFilamentMonitor>(rid, MyAddress, driver.boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageCreateFilamentMonitor>(rid, GetCanAddress(), driver.boardAddress); msg->driver = driver.localDriver; msg->type = type; return SendRequestAndGetStandardReply(buf, rid, reply); @@ -1283,7 +1347,7 @@ GCodeResult CanInterface::DeleteFilamentMonitor(DriverId driver, GCodeBuffer* gb { CanMessageBuffer* const buf = AllocateBuffer(gb); const CanRequestId rid = CanInterface::AllocateRequestId(driver.boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageDeleteFilamentMonitor>(rid, MyAddress, driver.boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageDeleteFilamentMonitor>(rid, GetCanAddress(), driver.boardAddress); msg->driver = driver.localDriver; return SendRequestAndGetStandardReply(buf, rid, reply); } @@ -1294,14 +1358,6 @@ GCodeResult CanInterface::DeleteFilamentMonitor(DriverId driver, GCodeBuffer* gb } } -// Enter test mode, called in response to a command from the ATE -void CanInterface::EnterTestMode(uint32_t param) noexcept -{ -#ifndef DUET3_ATE - inEutMode = true; -#endif -} - #endif // End diff --git a/src/CAN/CanInterface.h b/src/CAN/CanInterface.h index 7a0c7ca9..a9148275 100644 --- a/src/CAN/CanInterface.h +++ b/src/CAN/CanInterface.h @@ -62,14 +62,18 @@ private: namespace CanInterface { + // Note: GetCanAddress() in this namespace is now declared in RepRapFirmware.h to overcome ordering issues constexpr uint32_t CanResponseTimeout = 1000; // Low level functions void Init() noexcept; void Shutdown() noexcept; - inline CanAddress GetCanAddress() noexcept { return MyAddress; } - bool InEutMode() noexcept; +#if SUPPORT_REMOTE_COMMANDS + bool InExpansionMode() noexcept; + void SwitchToExpansionMode(CanAddress addr) noexcept; +#endif + CanRequestId AllocateRequestId(CanAddress destination) noexcept; GCodeResult SendRequestAndGetStandardReply(CanMessageBuffer *buf, CanRequestId rid, const StringRef& reply, uint8_t *extra = nullptr) noexcept; GCodeResult SendRequestAndGetCustomReply(CanMessageBuffer *buf, CanRequestId rid, const StringRef& reply, uint8_t *extra, CanMessageType replyType, std::function<void(const CanMessageBuffer*) /*noexcept*/> callback) noexcept; @@ -118,8 +122,6 @@ namespace CanInterface GCodeResult WriteGpio(CanAddress boardAddress, uint8_t portNumber, float pwm, bool isServo, const GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); GCodeResult ChangeAddressAndNormalTiming(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); GCodeResult ChangeFastTiming(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException); - - void EnterTestMode(uint32_t param) noexcept; } // Members of template class CanDriversData diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp index 304beb57..c7d78700 100644 --- a/src/CAN/CommandProcessor.cpp +++ b/src/CAN/CommandProcessor.cpp @@ -39,15 +39,6 @@ constexpr size_t MaxFileChunkSize = 448; // Maximum size of file chunks for read char sbcFirmwareChunk[MaxFileChunkSize]; #endif -// Enter test mode -static void EnterTestMode(const CanMessageEnterTestMode& msg) noexcept -{ - if (msg.passwd == CanMessageEnterTestMode::Passwd) - { - CanInterface::EnterTestMode(msg.parameter); - } -} - // Handle a firmware update request static void HandleFirmwareBlockRequest(CanMessageBuffer *buf) noexcept pre(buf->id.MsgType() == CanMessageType::firmwareBlockRequest) @@ -379,7 +370,7 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept { const CanMessageType id = buf->id.MsgType(); #if SUPPORT_REMOTE_COMMANDS - if (CanInterface::InEutMode()) + if (CanInterface::InExpansionMode()) { String<StringLength500> reply; const StringRef& replyRef = reply.GetRef(); @@ -524,10 +515,14 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept FilamentMonitor::UpdateRemoteFilamentStatus(buf->id.Src(), buf->msg.filamentMonitorsStatus); break; +#if SUPPORT_REMOTE_COMMANDS case CanMessageType::enterTestMode: - EnterTestMode(buf->msg.enterTestMode); + if (buf->msg.enterTestMode.passwd == CanMessageEnterTestMode::Passwd) + { + CanInterface::SwitchToExpansionMode(buf->msg.enterTestMode.address); + } break; - +#endif case CanMessageType::driversStatusReport: // not handled yet default: if (reprap.Debug(moduleCan)) diff --git a/src/Endstops/EndstopsManager.cpp b/src/Endstops/EndstopsManager.cpp index 4639f681..e8104eef 100644 --- a/src/Endstops/EndstopsManager.cpp +++ b/src/Endstops/EndstopsManager.cpp @@ -25,7 +25,7 @@ #include <Heating/Sensors/TemperatureSensor.h> #if SUPPORT_CAN_EXPANSION -# include "CanMessageBuffer.h" +# include <CanMessageBuffer.h> #endif ReadWriteLock EndstopsManager::endstopsLock; @@ -680,7 +680,7 @@ GCodeResult EndstopsManager::HandleM558(GCodeBuffer& gb, const StringRef &reply) gb.Seen('C'); gb.GetReducedString(pinNames.GetRef()); const CanAddress boardAddress = IoPort::RemoveBoardAddress(pinNames.GetRef()); - if (boardAddress != CanId::MasterAddress) + if (boardAddress != CanInterface::GetCanAddress()) { RemoteZProbe *newRemoteProbe = new RemoteZProbe(probeNumber, boardAddress, (ZProbeType)probeType); const GCodeResult rslt = newRemoteProbe->Create(pinNames.GetRef(), reply); diff --git a/src/Endstops/SwitchEndstop.cpp b/src/Endstops/SwitchEndstop.cpp index b3464d74..d1615a9a 100644 --- a/src/Endstops/SwitchEndstop.cpp +++ b/src/Endstops/SwitchEndstop.cpp @@ -38,7 +38,7 @@ void SwitchEndstop::ReleasePorts() noexcept --numPortsUsed; #if SUPPORT_CAN_EXPANSION const CanAddress bn = boardNumbers[numPortsUsed]; - if (bn != CanId::MasterAddress) + if (bn != CanInterface::GetCanAddress()) { RemoteInputHandle h(RemoteInputHandle::typeEndstop, GetAxis(), numPortsUsed); String<StringLength100> reply; @@ -81,7 +81,7 @@ GCodeResult SwitchEndstop::Configure(const char *pinNames, const StringRef& repl #if SUPPORT_CAN_EXPANSION const CanAddress boardAddress = IoPort::RemoveBoardAddress(pn.GetRef()); boardNumbers[numPortsUsed] = boardAddress; - if (boardAddress != CanId::MasterAddress) + if (boardAddress != CanInterface::GetCanAddress()) { RemoteInputHandle h(RemoteInputHandle::typeEndstop, GetAxis(), numPortsUsed); const GCodeResult rslt = CanInterface::CreateHandle(boardAddress, h, pn.c_str(), 0, MinimumSwitchReportInterval, states[numPortsUsed], reply); @@ -237,7 +237,7 @@ void SwitchEndstop::AppendDetails(const StringRef& str) noexcept { str.cat(' '); #if SUPPORT_CAN_EXPANSION - if (boardNumbers[i] != CanId::MasterAddress) + if (boardNumbers[i] != CanInterface::GetCanAddress()) { RemoteInputHandle h(RemoteInputHandle::typeEndstop, GetAxis(), i); String<StringLength100> reply; diff --git a/src/Endstops/SwitchEndstop.h b/src/Endstops/SwitchEndstop.h index a4f33da6..75117daf 100644 --- a/src/Endstops/SwitchEndstop.h +++ b/src/Endstops/SwitchEndstop.h @@ -9,7 +9,6 @@ #define SRC_ENDSTOPS_SWITCHENDSTOP_H_ #include "Endstop.h" - #include "GCodes/GCodeResult.h" // Switch-type endstop, either on the main board or on a CAN-connected board @@ -45,7 +44,7 @@ private: inline bool IsTriggered(size_t index) const noexcept { #if SUPPORT_CAN_EXPANSION - return (boardNumbers[index] == CanId::MasterAddress) ? ports[index].ReadDigital() : states[index]; + return (boardNumbers[index] == CanInterface::GetCanAddress()) ? ports[index].ReadDigital() : states[index]; #else return ports[index].ReadDigital(); #endif diff --git a/src/Fans/FansManager.cpp b/src/Fans/FansManager.cpp index cbadd375..dea10be7 100644 --- a/src/Fans/FansManager.cpp +++ b/src/Fans/FansManager.cpp @@ -110,7 +110,7 @@ GCodeResult FansManager::ConfigureFanPort(GCodeBuffer& gb, const StringRef& repl #if SUPPORT_CAN_EXPANSION const CanAddress board = IoPort::RemoveBoardAddress(pinName.GetRef()); - if (board != CanId::MasterAddress) + if (board != CanInterface::GetCanAddress()) { auto *newFan = new RemoteFan(fanNum, board); const GCodeResult rslt = newFan->ConfigurePort(pinName.c_str(), freq, reply); diff --git a/src/Fans/RemoteFan.cpp b/src/Fans/RemoteFan.cpp index c2d860cc..957cf649 100644 --- a/src/Fans/RemoteFan.cpp +++ b/src/Fans/RemoteFan.cpp @@ -85,7 +85,7 @@ bool RemoteFan::UpdateFanConfiguration(const StringRef& reply) noexcept } const CanRequestId rid = CanInterface::AllocateRequestId(boardNumber); - auto msg = buf->SetupRequestMessage<CanMessageFanParameters>(rid, CanId::MasterAddress, boardNumber); + auto msg = buf->SetupRequestMessage<CanMessageFanParameters>(rid, CanInterface::GetCanAddress(), boardNumber); msg->fanNumber = fanNumber; msg->blipTime = blipTime; msg->val = val; @@ -109,7 +109,7 @@ GCodeResult RemoteFan::Refresh(const StringRef& reply) noexcept } const CanRequestId rid = CanInterface::AllocateRequestId(boardNumber); - auto msg = buf->SetupRequestMessage<CanMessageSetFanSpeed>(rid, CanId::MasterAddress, boardNumber); + auto msg = buf->SetupRequestMessage<CanMessageSetFanSpeed>(rid, CanInterface::GetCanAddress(), boardNumber); msg->fanNumber = fanNumber; msg->pwm = val; return CanInterface::SendRequestAndGetStandardReply(buf, rid, reply); diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index 421de8a0..180c06a7 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -253,6 +253,10 @@ public: # endif #endif +#if SUPPORT_REMOTE_COMMANDS + void SwitchToExpansionMode() noexcept; +#endif + static constexpr const char *AllowedAxisLetters = "XYZUVWABCD"; // Standard macro filenames diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp index 38f1be29..74686748 100644 --- a/src/GCodes/GCodes2.cpp +++ b/src/GCodes/GCodes2.cpp @@ -1544,7 +1544,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx if (gb.Seen('B')) { const uint32_t board = gb.GetUIValue(); - if (board != CanId::MasterAddress) + if (board != CanInterface::GetCanAddress()) { result = CanInterface::GetRemoteFirmwareDetails(board, gb, reply); break; @@ -1767,8 +1767,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx const unsigned int type = (gb.Seen('P')) ? gb.GetIValue() : 0; const MessageType mt = (MessageType)(gb.GetResponseMessageType() | PushFlag); // set the Push flag to combine multiple messages into a single OutputBuffer chain #if SUPPORT_CAN_EXPANSION - const uint32_t board = (gb.Seen('B')) ? gb.GetUIValue() : 0; - if (board != CanId::MasterAddress) + const uint32_t board = (gb.Seen('B')) ? gb.GetUIValue() : CanInterface::GetCanAddress(); + if (board != CanInterface::GetCanAddress()) { result = CanInterface::RemoteDiagnostics(mt, board, type, gb, reply); break; @@ -4392,6 +4392,15 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx break; #endif +#if SUPPORT_REMOTE_COMMANDS + case 954: // configure as expansion board + { + CanAddress addr = gb.GetLimitedUIValue('A', 1, CanId::MaxCanAddress + 1); + CanInterface::SwitchToExpansionMode(addr); + } + break; +#endif + case 997: // Perform firmware update result = UpdateFirmware(gb, reply); break; @@ -4414,7 +4423,7 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx if (gb.Seen('B')) { const uint32_t address = gb.GetUIValue(); - if (address != CanId::MasterAddress) + if (address != CanInterface::GetCanAddress()) { result = reprap.GetExpansion().ResetRemote(address, gb, reply); break; diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index c5ae6fa3..34e8c758 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -740,6 +740,24 @@ GCodeResult GCodes::DoDriveMapping(GCodeBuffer& gb, const StringRef& reply) THRO return GCodeResult::ok; } +#if SUPPORT_REMOTE_COMMANDS + +// Switch the board into expansion mode. We map all drivers to individual axes. +void GCodes::SwitchToExpansionMode() noexcept +{ + numExtruders = 0; + numVisibleAxes = numTotalAxes = NumDirectDrivers; + memcpy(axisLetters, AllowedAxisLetters, sizeof(axisLetters)); + for (size_t axis = 0; axis < NumDirectDrivers; ++axis) + { + DriverId driver; + driver.SetLocal(axis); + platform.SetAxisDriversConfig(axis, 1, &driver); + } +} + +#endif + // Handle G38.[2-5] GCodeResult GCodes::StraightProbe(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException) { @@ -1067,7 +1085,7 @@ GCodeResult GCodes::UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) if (gb.Seen('B')) { const uint32_t boardNumber = gb.GetUIValue(); - if (boardNumber != CanId::MasterAddress) + if (boardNumber != CanInterface::GetCanAddress()) { return reprap.GetExpansion().UpdateRemoteFirmware(boardNumber, gb, reply); } @@ -1264,7 +1282,7 @@ GCodeResult GCodes::ConfigureDriver(GCodeBuffer& gb, const StringRef& reply) THR gb.MustSee('P'); const DriverId id = gb.GetDriverId(); #if SUPPORT_CAN_EXPANSION - if (id.boardAddress != CanId::MasterAddress) + if (id.boardAddress != CanInterface::GetCanAddress()) { return CanInterface::ConfigureRemoteDriver(id, gb, reply); } diff --git a/src/GPIO/GpInPort.cpp b/src/GPIO/GpInPort.cpp index cd2b28b7..e71c1d82 100644 --- a/src/GPIO/GpInPort.cpp +++ b/src/GPIO/GpInPort.cpp @@ -42,7 +42,7 @@ bool GpInputPort::GetState() const noexcept { // Temporary implementation until we use interrupts to track input pin state changes #if SUPPORT_CAN_EXPANSION - if (boardAddress != CanId::MasterAddress) + if (boardAddress != CanInterface::GetCanAddress()) { return currentState; } @@ -55,7 +55,7 @@ bool GpInputPort::IsUnused() const noexcept { return #if SUPPORT_CAN_EXPANSION - boardAddress == CanId::MasterAddress && + boardAddress == CanInterface::GetCanAddress() && #endif !port.IsValid(); } @@ -69,7 +69,7 @@ GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const S // Remove any existing assignment #if SUPPORT_CAN_EXPANSION - if (boardAddress != CanId::MasterAddress) + if (boardAddress != CanInterface::GetCanAddress()) { const GCodeResult rslt = CanInterface::DeleteHandle(boardAddress, handle, reply); if (rslt != GCodeResult::ok) @@ -79,7 +79,7 @@ GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const S reprap.GetPlatform().Message(mtype, reply.c_str()); reply.Clear(); } - boardAddress = CanId::MasterAddress; + boardAddress = CanInterface::GetCanAddress(); } #endif port.Release(); @@ -89,7 +89,7 @@ GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const S #if SUPPORT_CAN_EXPANSION const CanAddress newBoard = IoPort::RemoveBoardAddress(pinName.GetRef()); - if (newBoard != CanId::MasterAddress) + if (newBoard != CanInterface::GetCanAddress()) { handle.Set(RemoteInputHandle::typeGpIn, gpinNumber, 0); rslt = CanInterface::CreateHandle(newBoard, handle, pinName.c_str(), 0, MinimumGpinReportInterval, currentState, reply); @@ -123,7 +123,7 @@ GCodeResult GpInputPort::Configure(uint32_t gpinNumber, GCodeBuffer &gb, const S { // Report the pin details #if SUPPORT_CAN_EXPANSION - if (boardAddress != CanId::MasterAddress) + if (boardAddress != CanInterface::GetCanAddress()) { const GCodeResult rslt = CanInterface::GetHandlePinName(boardAddress, handle, currentState, reply); if (rslt != GCodeResult::ok) diff --git a/src/GPIO/GpInPort.h b/src/GPIO/GpInPort.h index 7159ff36..f1e04b65 100644 --- a/src/GPIO/GpInPort.h +++ b/src/GPIO/GpInPort.h @@ -22,7 +22,7 @@ class GpInputPort INHERIT_OBJECT_MODEL public: GpInputPort() noexcept : #if SUPPORT_CAN_EXPANSION - boardAddress (CanId::MasterAddress), + boardAddress(CanInterface::GetCanAddress()), #endif currentState(false) { } GpInputPort(const GpInputPort&) = delete; diff --git a/src/GPIO/GpOutPort.h b/src/GPIO/GpOutPort.h index 83d844e5..b1b19145 100644 --- a/src/GPIO/GpOutPort.h +++ b/src/GPIO/GpOutPort.h @@ -21,7 +21,7 @@ public: GpOutputPort() noexcept : lastPwm(0.0) #if SUPPORT_CAN_EXPANSION - , boardAddress(CanId::MasterAddress) + , boardAddress(CanInterface::GetCanAddress()) #endif { } diff --git a/src/Hardware/IoPorts.cpp b/src/Hardware/IoPorts.cpp index 4453ab6e..56546258 100644 --- a/src/Hardware/IoPorts.cpp +++ b/src/Hardware/IoPorts.cpp @@ -546,7 +546,7 @@ uint16_t IoPort::ReadAnalog() const noexcept portName.Erase(prefix, numToSkip - prefix + 1); // remove the board address prefix return (CanAddress)boardAddress; } - return CanInterface::MyAddress; + return CanInterface::GetCanAddress(); #else if (numToSkip != prefix && portName[numToSkip] == '.') { diff --git a/src/Heating/Heat.cpp b/src/Heating/Heat.cpp index 9723a5af..6e1ac761 100644 --- a/src/Heating/Heat.cpp +++ b/src/Heating/Heat.cpp @@ -499,7 +499,7 @@ GCodeResult Heat::ConfigureHeater(GCodeBuffer& gb, const StringRef& reply) const PwmFrequency freq = (gb.Seen('Q')) ? min<PwmFrequency>(gb.GetPwmFrequency(), MaxHeaterPwmFrequency) : DefaultHeaterPwmFreq; #if SUPPORT_CAN_EXPANSION - Heater * const newHeater = (board != CanId::MasterAddress) ? (Heater *)new RemoteHeater(heater, board) : new LocalHeater(heater); + Heater * const newHeater = (board != CanInterface::GetCanAddress()) ? (Heater *)new RemoteHeater(heater, board) : new LocalHeater(heater); #else Heater * const newHeater = new LocalHeater(heater); #endif @@ -960,7 +960,7 @@ GCodeResult Heat::ConfigureSensor(GCodeBuffer& gb, const StringRef& reply) THROW #if SUPPORT_CAN_EXPANSION if (boardAddress == CanId::NoAddress) { - boardAddress = CanId::MasterAddress; // no port name was given, so default to master + boardAddress = CanInterface::GetCanAddress(); // no port name was given, so default to local } TemperatureSensor * const newSensor = TemperatureSensor::Create(sensorNum, boardAddress, typeName.c_str(), reply); #else diff --git a/src/Heating/RemoteHeater.cpp b/src/Heating/RemoteHeater.cpp index 317d7b7a..4012e387 100644 --- a/src/Heating/RemoteHeater.cpp +++ b/src/Heating/RemoteHeater.cpp @@ -77,7 +77,7 @@ void RemoteHeater::SwitchOff() noexcept else { const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanId::MasterAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanInterface::GetCanAddress(), boardAddress); msg->heaterNumber = GetHeaterNumber(); msg->setPoint = GetTargetTemperature(); msg->command = CanMessageSetHeaterTemperature::commandOff; @@ -99,7 +99,7 @@ GCodeResult RemoteHeater::ResetFault(const StringRef& reply) noexcept } const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanId::MasterAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanInterface::GetCanAddress(), boardAddress); msg->heaterNumber = GetHeaterNumber(); msg->setPoint = GetTargetTemperature(); msg->command = CanMessageSetHeaterTemperature::commandResetFault; @@ -150,7 +150,7 @@ void RemoteHeater::Suspend(bool sus) noexcept if (buf != nullptr) { const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanId::MasterAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanInterface::GetCanAddress(), boardAddress); msg->heaterNumber = GetHeaterNumber(); msg->setPoint = GetTargetTemperature(); msg->command = (sus) ? CanMessageSetHeaterTemperature::commandSuspend : CanMessageSetHeaterTemperature::commandUnsuspend; @@ -175,7 +175,7 @@ GCodeResult RemoteHeater::SwitchOn(const StringRef& reply) noexcept } const CanRequestId rid = CanInterface::AllocateRequestId(boardAddress); - auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanId::MasterAddress, boardAddress); + auto msg = buf->SetupRequestMessage<CanMessageSetHeaterTemperature>(rid, CanInterface::GetCanAddress(), boardAddress); msg->heaterNumber = GetHeaterNumber(); msg->setPoint = GetTargetTemperature(); msg->command = CanMessageSetHeaterTemperature::commandOn; diff --git a/src/Platform.cpp b/src/Platform.cpp index e3b80cc2..e4fe9d09 100644 --- a/src/Platform.cpp +++ b/src/Platform.cpp @@ -1,6 +1,6 @@ /**************************************************************************************************** - RepRapFirmware - Platform: RepRapPro Ormerod with Duet controller + RepRapFirmware Platform contains all the code and definitions to deal with machine-dependent things such as control pins, bed area, number of extruders, tolerable accelerations and speeds and so on. diff --git a/src/RepRapFirmware.h b/src/RepRapFirmware.h index d1236f78..a6f12699 100644 --- a/src/RepRapFirmware.h +++ b/src/RepRapFirmware.h @@ -124,15 +124,10 @@ static_assert(NumNamedPins <= 255 || sizeof(LogicalPin) > 1, "Need 16-bit logica #if SUPPORT_CAN_EXPANSION # include <CanId.h> -// We have to declare CanInterface::MyAddress here because CanInterface.h needs to include this file for the declaration of DriverId +// We have to declare CanInterface::GetCanAddress here because CanInterface.h needs to include this file for the declaration of DriverId namespace CanInterface { -constexpr CanAddress MyAddress = -# ifdef DUET3ATE - CanId::ATEMasterAddress; - #else - CanId::MasterAddress; -# endif + CanAddress GetCanAddress() noexcept; } #endif @@ -167,7 +162,7 @@ struct DriverId CanAddress boardAddress; - DriverId() noexcept : localDriver(0), boardAddress(CanInterface::MyAddress) { } + DriverId() noexcept : localDriver(0), boardAddress(CanInterface::GetCanAddress()) { } // Constructor used by ATE configurations DriverId(CanAddress addr, uint8_t drv) noexcept : localDriver(drv), boardAddress(addr) { } @@ -182,11 +177,11 @@ struct DriverId void SetLocal(unsigned int driver) noexcept { localDriver = (uint8_t)driver; - boardAddress = CanId::MasterAddress; + boardAddress = CanInterface::GetCanAddress(); } - bool IsLocal() const noexcept { return boardAddress == CanInterface::MyAddress; } - bool IsRemote() const noexcept { return boardAddress != CanInterface::MyAddress; } + bool IsLocal() const noexcept { return boardAddress == CanInterface::GetCanAddress(); } + bool IsRemote() const noexcept { return boardAddress != CanInterface::GetCanAddress(); } bool operator<(const DriverId other) const noexcept { |