Sync MK3<->MK4 MMU2 protocol logic

This commit is contained in:
D.R.racer 2023-09-11 09:07:53 +02:00 committed by DRracer
parent 9e794a47a4
commit f235976f26
3 changed files with 81 additions and 58 deletions

View File

@ -1,8 +1,10 @@
#pragma once
namespace MMU2 {
// Register map for MMU
enum class Register : uint8_t
{
enum class Register : uint8_t {
Project_Major = 0x00,
Project_Minor = 0x01,
Project_Revision = 0x02,
@ -38,3 +40,5 @@ enum class Register : uint8_t
Set_Get_Idler_iRun = 0x20,
Reserved = 0x21,
};
} // namespace MMU2

View File

@ -9,6 +9,11 @@
// irrelevant on Buddy FW, just keep "_millis" as "millis"
#include <wiring_time.h>
#define _millis millis
#ifdef UNITTEST
#define strncmp_P strncmp
#else
#include <Marlin/src/core/serial.h>
#endif
#endif
#include <string.h>
@ -16,7 +21,7 @@
namespace MMU2 {
/// Beware:
/// Beware - on AVR/MK3S:
/// Changing the supportedMmuVersion numbers requires patching MSG_DESC_FW_UPDATE_NEEDED and all its related translations by hand.
///
/// The message reads:
@ -24,6 +29,8 @@ namespace MMU2 {
///
/// Currently, this is not possible to perform automatically at compile time with the existing languages/translations infrastructure.
/// To save space a "dumb" solution was chosen + a few static_assert checks in errors_list.h preventing the code from compiling when the string doesn't match.
/// -----
/// On Buddy FW we should improve the error screen to be able to print formatted strings
static constexpr uint8_t supportedMmuFWVersion[3] PROGMEM = { mmuVersionMajor, mmuVersionMinor, mmuVersionPatch };
const Register ProtocolLogic::regs8Addrs[ProtocolLogic::regs8Count] PROGMEM = {
@ -197,7 +204,11 @@ StepStatus ProtocolLogic::ExpectingMessage() {
}
void ProtocolLogic::SendMsg(RequestMsg rq) {
#ifdef __AVR__
// Buddy FW cannot use stack-allocated txbuff - DMA doesn't work with CCMRAM
// No restrictions on MK3/S/+ though
uint8_t txbuff[Protocol::MaxRequestSize()];
#endif
uint8_t len = Protocol::EncodeRequest(rq, txbuff);
uart->write(txbuff, len);
LogRequestMsg(txbuff, len);
@ -205,7 +216,11 @@ void ProtocolLogic::SendMsg(RequestMsg rq) {
}
void ProtocolLogic::SendWriteMsg(RequestMsg rq) {
#ifdef __AVR__
// Buddy FW cannot use stack-allocated txbuff - DMA doesn't work with CCMRAM
// No restrictions on MK3/S/+ though
uint8_t txbuff[Protocol::MaxRequestSize()];
#endif
uint8_t len = Protocol::EncodeWriteRequest(rq.value, rq.value2, txbuff);
uart->write(txbuff, len);
LogRequestMsg(txbuff, len);
@ -349,6 +364,7 @@ StepStatus ProtocolLogic::ProcessCommandQueryResponse() {
return Processing;
case ResponseMsgParamCodes::Error:
// in case of an error the progress code remains as it has been before
progressCode = ProgressCode::ERRWaitingForUser;
errorCode = static_cast<ErrorCode>(rsp.paramValue);
// keep on reporting the state of fsensor regularly even in command error state
// - the MMU checks FINDA and fsensor even while recovering from errors
@ -469,9 +485,11 @@ StepStatus ProtocolLogic::IdleStep() {
case ResponseMsgParamCodes::Processing:
// @@TODO we may actually use this branch to report progress of manual operation on the MMU
// The MMU sends e.g. X0 P27 after its restart when the user presses an MMU button to move the Selector
progressCode = static_cast<ProgressCode>(rsp.paramValue);
errorCode = ErrorCode::OK;
break;
default:
progressCode = ProgressCode::ERRWaitingForUser;
errorCode = static_cast<ErrorCode>(rsp.paramValue);
StartReading8bitRegisters(); // continue Idle state without restarting the communication
return CommandError;
@ -758,6 +776,7 @@ void ProtocolLogic::LogResponse() {
StepStatus ProtocolLogic::SuppressShortDropOuts(const char *msg_P, StepStatus ss) {
if (dataTO.Record(ss)) {
LogError(msg_P);
dataTO.Reset(); // prepare for another run of consecutive retries before firing an error
return dataTO.InitialCause();
} else {
return Processing; // suppress short drop outs of communication

View File

@ -14,6 +14,7 @@ namespace std {
template <typename T, uint8_t N>
class array {
T data[N];
public:
array() = default;
inline constexpr T *begin() const { return data; }
@ -23,7 +24,7 @@ public:
return data[i];
}
};
}
} // namespace std
#else
#include <array>
@ -34,6 +35,7 @@ public:
#undef CRC
#include "../../../../../../Prusa-Firmware-MMU/src/modules/protocol.h"
#include "buttons.h"
#include "registers.h"
#endif
#include "mmu2_serial.h"
@ -63,16 +65,14 @@ enum StepStatus : uint_fast8_t {
ButtonPushed, ///< The MMU reported the user pushed one of its three buttons.
};
static constexpr uint32_t linkLayerTimeout = 2000; ///< default link layer communication timeout
static constexpr uint32_t dataLayerTimeout = linkLayerTimeout * 3; ///< data layer communication timeout
static constexpr uint32_t heartBeatPeriod = linkLayerTimeout / 2; ///< period of heart beat messages (Q0)
inline constexpr uint32_t linkLayerTimeout = 2000; ///< default link layer communication timeout
inline constexpr uint32_t dataLayerTimeout = linkLayerTimeout * 3; ///< data layer communication timeout
inline constexpr uint32_t heartBeatPeriod = linkLayerTimeout / 2; ///< period of heart beat messages (Q0)
static_assert(heartBeatPeriod < linkLayerTimeout && linkLayerTimeout < dataLayerTimeout, "Incorrect ordering of timeouts");
///< Filter of short consecutive drop outs which are recovered instantly
class DropOutFilter {
StepStatus cause;
uint8_t occurrences;
public:
static constexpr uint8_t maxOccurrences = 10; // ideally set this to >8 seconds -> 12x heartBeatPeriod
static_assert(maxOccurrences > 1, "we should really silently ignore at least 1 comm drop out if recovered immediately afterwards");
@ -86,6 +86,10 @@ public:
/// Rearms the object for further processing - basically call this once the MMU responds with something meaningful (e.g. S0 A2)
inline void Reset() { occurrences = maxOccurrences; }
private:
StepStatus cause;
uint8_t occurrences = maxOccurrences;
};
/// Logic layer of the MMU vs. printer communication protocol
@ -228,15 +232,6 @@ private:
Running ///< normal operation - Idle + Command processing
};
// individual sub-state machines - may be they can be combined into a union since only one is active at once
// or we can blend them into ProtocolLogic at the cost of a less nice code (but hopefully shorter)
// Stopped stopped;
// StartSeq startSeq;
// DelayedRestart delayedRestart;
// Idle idle;
// Command command;
// ProtocolLogicPartBase *currentState; ///< command currently being processed
enum class Scope : uint_fast8_t {
Stopped,
StartSeq,
@ -370,6 +365,11 @@ private:
uint8_t lastFSensor; ///< last state of filament sensor
#ifndef __AVR__
uint8_t txbuff[Protocol::MaxRequestSize()]; ///< In Buddy FW - a static transmit buffer needs to exist as DMA cannot be used from CCMRAM.
///< On MK3/S/+ the transmit buffer is allocated on the stack without restrictions
#endif
// 8bit registers
static constexpr uint8_t regs8Count = 3;
static_assert(regs8Count > 0); // code is not ready for empty lists of registers