From 4d3a5433ad40a319dfaa2cec38785dcd0808327d Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Wed, 7 Sep 2022 15:58:09 +0200 Subject: [PATCH] Implement read/write registers for M707/M708 --- Firmware/Marlin_main.cpp | 58 +++++++++++++------------------- Firmware/mmu2.cpp | 18 ++++++---- Firmware/mmu2.h | 10 +++--- Firmware/mmu2_protocol.cpp | 6 ++-- Firmware/mmu2_protocol.h | 14 ++++---- Firmware/mmu2_protocol_logic.cpp | 48 +++++++++++++++++++++++--- Firmware/mmu2_protocol_logic.h | 6 ++++ 7 files changed, 99 insertions(+), 61 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f2dbc2b1c..907c081b5 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -8648,64 +8648,52 @@ Sigma_Exit: ### M707 - Read from MMU register #### Usage - M707 [ A | C ] + M707 [ A ] - M707 A0x14 C2 - Read two bytes from register 0x14 + M707 A0x14 - Read a 16bit integer from register 0x14 and prints the result onto the serial line. + + Does nothing if the A parameter is not present or if MMU is not enabled. #### Parameters - - `A` - Address of register in hexidecimal. Default value is 0. - - `C` - Number of bytes to read. Default value is 0. + - `A` - Address of register in hexidecimal. */ - case 707: - { - uint8_t addr = 0; - uint8_t nrbytes = 0; - if ( MMU2::mmu2.Enabled() ) - { + case 707: { + if ( MMU2::mmu2.Enabled() ) { if( code_seen('A') ) { - addr = uint8_t(strtol(strchr_pointer+1, NULL, 0)); + MMU2::mmu2.ReadRegister(uint8_t(strtol(strchr_pointer+1, NULL, 16))); } - if( code_seen('C') ) { - nrbytes = code_value_uint8(); - } - MMU2::mmu2.ReadRegister(addr, nrbytes); } - } - break; + } break; /*! ### M708 - Write to MMU register #### Usage - M708 [ A | X | C ] + M708 [ A | X ] - M708 A0x14 X30 C1 - Write to register 0x14 the value 30 which is 1 byte. + M708 A0x14 X30 - Write to register 0x14 the value 30. + + Does nothing if A parameter is missing #### Parameters - - `A` - Address of register in hexidecimal. Default value is 0. - - `X` - Data to write. Default value is 0. - - `C` - Number of bytes to write. Default value is 0. + - `A` - Address of register in hexidecimal. + - `X` - Data to write (16-bit integer). Default value 0. */ - case 708: - { - uint8_t addr = 0; - uint8_t data = 0; - uint8_t nrbytes = 0; - if ( MMU2::mmu2.Enabled() ) - { + case 708: { + if ( MMU2::mmu2.Enabled() ){ + uint8_t addr = 0; if( code_seen('A') ) { - addr = uint8_t(strtol(strchr_pointer+1, NULL, 0)); + addr = uint8_t(strtol(strchr_pointer+1, NULL, 16)); } + uint8_t data = 0; if( code_seen('X') ) { data = code_value_uint8(); } - if( code_seen('C') ) { - nrbytes = code_value_uint8(); + if(addr){ + MMU2::mmu2.WriteRegister(addr, data); } - MMU2::mmu2.WriteRegister(addr, data, nrbytes); } - } - break; + } break; /*! ### M709 - MMU turn on/off/reset diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index fd154c195..0a84c972d 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -178,14 +178,20 @@ void MMU2::PowerOn(){ power_on(); } -void MMU2::ReadRegister(uint8_t address, uint8_t nrbytes){ - // TODO, implement for gcode M707 - // Currently this function is NOP +bool MMU2::ReadRegister(uint8_t address){ + if( ! WaitForMMUReady()) + return false; + logic.ReadRegister(address); // we may signal the accepted/rejected status of the response as return value of this function + manage_response(false, false); + return true; } -void MMU2::WriteRegister(uint8_t address, uint8_t data, uint8_t nrbytes){ - // TODO, implement for gcode M708 - // Currently this function is NOP +bool MMU2::WriteRegister(uint8_t address, uint16_t data){ + if( ! WaitForMMUReady()) + return false; + logic.WriteRegister(address, data); // we may signal the accepted/rejected status of the response as return value of this function + manage_response(false, false); + return true; } void MMU2::mmu_loop() { diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index 88be8c7bc..4ebf78668 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -87,16 +87,14 @@ public: /// Read from a MMU register (See gcode M707) /// @param address Address of register in hexidecimal - /// @param nrbytes Number of bytes to read - /// @returns no return - void ReadRegister(uint8_t address, uint8_t nrbytes); + /// @returns true upon success + bool ReadRegister(uint8_t address); /// Write from a MMU register (See gcode M708) /// @param address Address of register in hexidecimal /// @param data Data to write to register - /// @param nrbytes Number of bytes to write - /// @returns no return - void WriteRegister(uint8_t address, uint8_t data, uint8_t nrbytes); + /// @returns true upon success + bool WriteRegister(uint8_t address, uint16_t data); /// The main loop of MMU processing. diff --git a/Firmware/mmu2_protocol.cpp b/Firmware/mmu2_protocol.cpp index 91c645dd4..1ccd63c56 100644 --- a/Firmware/mmu2_protocol.cpp +++ b/Firmware/mmu2_protocol.cpp @@ -271,10 +271,10 @@ uint8_t Protocol::EncodeResponseCmdAR(const RequestMsg &msg, ResponseMsgParamCod uint8_t Protocol::EncodeResponseReadFINDA(const RequestMsg &msg, uint8_t findaValue, uint8_t *txbuff) { return EncodeResponseRead(msg, true, findaValue, txbuff); -} -uint8_t Protocol::EncodeResponseVersion(const RequestMsg &msg, uint16_t value, uint8_t *txbuff) { - return EncodeResponseRead(msg, true, value, txbuff); + + + } uint8_t Protocol::EncodeResponseQueryOperation(const RequestMsg &msg, ResponseCommandStatus rcs, uint8_t *txbuff) { diff --git a/Firmware/mmu2_protocol.h b/Firmware/mmu2_protocol.h index 870999df9..65f7e8ab0 100644 --- a/Firmware/mmu2_protocol.h +++ b/Firmware/mmu2_protocol.h @@ -57,7 +57,7 @@ struct RequestMsg { uint8_t crc = 0; crc = modules::crc::CRC8::CCITT_updateCX(0, (uint8_t)code); crc = modules::crc::CRC8::CCITT_updateCX(crc, value); - crc = modules::crc::CRC8::CCITT_updateCX(crc, value2); + crc = modules::crc::CRC8::CCITT_updateW(crc, value2); return crc; } @@ -179,12 +179,12 @@ public: /// @returns number of bytes written into txbuff static uint8_t EncodeResponseReadFINDA(const RequestMsg &msg, uint8_t findaValue, uint8_t *txbuff); - /// Encode response to Version query - /// @param msg source request message for this response - /// @param value version number (0-255) - /// @param txbuff where to format the message - /// @returns number of bytes written into txbuff - static uint8_t EncodeResponseVersion(const RequestMsg &msg, uint16_t value, uint8_t *txbuff); + + + + + + /// Encode response to Query operation status /// @param msg source request message for this response diff --git a/Firmware/mmu2_protocol_logic.cpp b/Firmware/mmu2_protocol_logic.cpp index 46c94e344..0fc4b9989 100644 --- a/Firmware/mmu2_protocol_logic.cpp +++ b/Firmware/mmu2_protocol_logic.cpp @@ -6,7 +6,7 @@ namespace MMU2 { -static const uint8_t supportedMmuFWVersion[3] PROGMEM = { 2, 1, 1 }; +static const uint8_t supportedMmuFWVersion[3] PROGMEM = { 2, 1, 3 }; void ProtocolLogic::CheckAndReportAsyncEvents() { // even when waiting for a query period, we need to report a change in filament sensor's state @@ -47,6 +47,10 @@ void ProtocolLogic::SendReadRegister(uint8_t index, ScopeState nextState) { scopeState = nextState; } +void ProtocolLogic::SendWriteRegister(uint8_t index, uint16_t value, ScopeState nextState){ + SendWriteMsg(RequestMsg(RequestMsgCodes::Write, index, value)); + scopeState = nextState; +} // searches for "ok\n" in the incoming serial data (that's the usual response of the old MMU FW) struct OldMMUFWDetector { @@ -124,6 +128,14 @@ void ProtocolLogic::SendMsg(RequestMsg rq) { RecordUARTActivity(); } +void ProtocolLogic::SendWriteMsg(RequestMsg rq){ + uint8_t txbuff[Protocol::MaxRequestSize()]; + uint8_t len = Protocol::EncodeWriteRequest(rq.value, rq.value2, txbuff); + uart->write(txbuff, len); + LogRequestMsg(txbuff, len); + RecordUARTActivity(); +} + void ProtocolLogic::StartSeqRestart() { retries = maxRetries; SendVersion(0); @@ -394,6 +406,16 @@ StepStatus ProtocolLogic::IdleStep() { } SendFINDAQuery(); return Processing; + case ScopeState::ReadRegisterSent: + if (rsp.paramCode == ResponseMsgParamCodes::Accepted) { + // @@TODO just dump the value onto the serial + } + return Finished; + case ScopeState::WriteRegisterSent: + if (rsp.paramCode == ResponseMsgParamCodes::Accepted) { + // @@TODO do something? Retry if not accepted? + } + return Finished; default: return ProtocolError; } @@ -475,6 +497,14 @@ void ProtocolLogic::Home(uint8_t mode) { PlanGenericRequest(RequestMsg(RequestMsgCodes::Home, mode)); } +void ProtocolLogic::ReadRegister(uint8_t address){ + PlanGenericRequest(RequestMsg(RequestMsgCodes::Read, address)); +} + +void ProtocolLogic::WriteRegister(uint8_t address, uint16_t data){ + PlanGenericRequest(RequestMsg(RequestMsgCodes::Write, address, data)); +} + void ProtocolLogic::PlanGenericRequest(RequestMsg rq) { plannedRq = rq; if (!ExpectsResponse()) { @@ -483,19 +513,29 @@ void ProtocolLogic::PlanGenericRequest(RequestMsg rq) { } bool ProtocolLogic::ActivatePlannedRequest() { - if (plannedRq.code == RequestMsgCodes::Button) { + switch(plannedRq.code){ + case RequestMsgCodes::Button: // only issue the button to the MMU and do not restart the state machines SendButton(plannedRq.value); plannedRq = RequestMsg(RequestMsgCodes::unknown, 0); return true; - } else if (plannedRq.code != RequestMsgCodes::unknown) { + case RequestMsgCodes::Read: + SendReadRegister(plannedRq.value, ScopeState::ReadRegisterSent ); + plannedRq = RequestMsg(RequestMsgCodes::unknown, 0); + return true; + case RequestMsgCodes::Write: + SendWriteRegister(plannedRq.value, plannedRq.value2, ScopeState::WriteRegisterSent ); + plannedRq = RequestMsg(RequestMsgCodes::unknown, 0); + return true; + case RequestMsgCodes::unknown: + return false; + default:// commands currentScope = Scope::Command; SetRequestMsg(plannedRq); plannedRq = RequestMsg(RequestMsgCodes::unknown, 0); CommandRestart(); return true; } - return false; } StepStatus ProtocolLogic::SwitchFromIdleToCommand() { diff --git a/Firmware/mmu2_protocol_logic.h b/Firmware/mmu2_protocol_logic.h index 9c07837f4..ea1372406 100644 --- a/Firmware/mmu2_protocol_logic.h +++ b/Firmware/mmu2_protocol_logic.h @@ -88,6 +88,8 @@ public: void ResetMMU(); void Button(uint8_t index); void Home(uint8_t mode); + void ReadRegister(uint8_t address); + void WriteRegister(uint8_t address, uint16_t data); /// Step the state machine StepStatus Step(); @@ -131,6 +133,7 @@ private: #endif StepStatus ExpectingMessage(); void SendMsg(RequestMsg rq); + void SendWriteMsg(RequestMsg rq); void SwitchToIdle(); StepStatus SuppressShortDropOuts(const char *msg_P, StepStatus ss); StepStatus HandleCommunicationTimeout(); @@ -187,6 +190,8 @@ private: FINDAReqSent, StatisticsSent, ButtonSent, + ReadRegisterSent, + WriteRegisterSent, // States which do not expect a message - MSb set NotExpectsResponse = 0x80, @@ -217,6 +222,7 @@ private: void SendButton(uint8_t btn); void SendVersion(uint8_t stage); void SendReadRegister(uint8_t index, ScopeState nextState); + void SendWriteRegister(uint8_t index, uint16_t value, ScopeState nextState); StepStatus ProcessVersionResponse(uint8_t stage);