Bläddra i källkod

Implement read/write registers for M707/M708

D.R.racer 1 år sedan
förälder
incheckning
4d3a5433ad

+ 23 - 35
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));
-            }
-            if( code_seen('C') ) {
-                nrbytes = code_value_uint8();
+                MMU2::mmu2.ReadRegister(uint8_t(strtol(strchr_pointer+1, NULL, 16)));
             }
-            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

+ 12 - 6
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() {

+ 4 - 6
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.

+ 3 - 3
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) {

+ 7 - 7
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

+ 44 - 4
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() {

+ 6 - 0
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);