clang-format
This commit is contained in:
parent
0555376502
commit
528abcb8d8
|
|
@ -15,22 +15,22 @@
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
// As of FW 3.12 we only support building the FW with only one extruder, all the multi-extruder infrastructure will be removed.
|
// As of FW 3.12 we only support building the FW with only one extruder, all the multi-extruder infrastructure will be removed.
|
||||||
// Saves at least 800B of code size
|
// Saves at least 800B of code size
|
||||||
static_assert(EXTRUDERS==1);
|
static_assert(EXTRUDERS == 1);
|
||||||
|
|
||||||
constexpr float MMM_TO_MMS(float MM_M){ return MM_M / 60.0f; }
|
constexpr float MMM_TO_MMS(float MM_M) { return MM_M / 60.0f; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace MMU2 {
|
namespace MMU2 {
|
||||||
|
|
||||||
template<typename F>
|
template <typename F>
|
||||||
void waitForHotendTargetTemp(uint16_t delay, F f){
|
void waitForHotendTargetTemp(uint16_t delay, F f) {
|
||||||
while (((thermal_degTargetHotend() - thermal_degHotend()) > 5)) {
|
while (((thermal_degTargetHotend() - thermal_degHotend()) > 5)) {
|
||||||
f();
|
f();
|
||||||
safe_delay_keep_alive(delay);
|
safe_delay_keep_alive(delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForHotendTargetTempBeep(){
|
void WaitForHotendTargetTempBeep() {
|
||||||
waitForHotendTargetTemp(3000, []{ });
|
waitForHotendTargetTemp(3000, []{ });
|
||||||
MakeSound(Prompt);
|
MakeSound(Prompt);
|
||||||
}
|
}
|
||||||
|
|
@ -51,8 +51,7 @@ MMU2::MMU2()
|
||||||
, unloadFilamentStarted(false)
|
, unloadFilamentStarted(false)
|
||||||
, loadingToNozzle(false)
|
, loadingToNozzle(false)
|
||||||
, toolchange_counter(0)
|
, toolchange_counter(0)
|
||||||
, tmcFailures(0)
|
, tmcFailures(0) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::Start() {
|
void MMU2::Start() {
|
||||||
|
|
@ -75,13 +74,13 @@ void MMU2::Stop() {
|
||||||
PowerOff(); // This also disables the MMU in the EEPROM.
|
PowerOff(); // This also disables the MMU in the EEPROM.
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::StopKeepPowered(){
|
void MMU2::StopKeepPowered() {
|
||||||
state = xState::Stopped;
|
state = xState::Stopped;
|
||||||
logic.Stop();
|
logic.Stop();
|
||||||
mmu2Serial.close();
|
mmu2Serial.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::Reset(ResetForm level){
|
void MMU2::Reset(ResetForm level) {
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case Software:
|
case Software:
|
||||||
ResetX0();
|
ResetX0();
|
||||||
|
|
@ -101,11 +100,11 @@ void MMU2::ResetX0() {
|
||||||
logic.ResetMMU(); // Send soft reset
|
logic.ResetMMU(); // Send soft reset
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::TriggerResetPin(){
|
void MMU2::TriggerResetPin() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::PowerCycle(){
|
void MMU2::PowerCycle() {
|
||||||
// cut the power to the MMU and after a while restore it
|
// cut the power to the MMU and after a while restore it
|
||||||
// Sadly, MK3/S/+ cannot do this
|
// Sadly, MK3/S/+ cannot do this
|
||||||
// NOTE: the below will toggle the EEPROM var. Should we
|
// NOTE: the below will toggle the EEPROM var. Should we
|
||||||
|
|
@ -115,36 +114,36 @@ void MMU2::PowerCycle(){
|
||||||
PowerOn();
|
PowerOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::PowerOff(){
|
void MMU2::PowerOff() {
|
||||||
power_off();
|
power_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::PowerOn(){
|
void MMU2::PowerOn() {
|
||||||
power_on();
|
power_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::ReadRegister(uint8_t address){
|
bool MMU2::ReadRegister(uint8_t address) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
do {
|
do {
|
||||||
logic.ReadRegister(address); // we may signal the accepted/rejected status of the response as return value of this function
|
logic.ReadRegister(address); // we may signal the accepted/rejected status of the response as return value of this function
|
||||||
} while( ! manage_response(false, false) );
|
} while (!manage_response(false, false));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::WriteRegister(uint8_t address, uint16_t data){
|
bool MMU2::WriteRegister(uint8_t address, uint16_t data) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// special case - intercept requests of extra loading distance and perform the change even on the printer's side
|
// special case - intercept requests of extra loading distance and perform the change even on the printer's side
|
||||||
if( address == 0x0b ){
|
if (address == 0x0b) {
|
||||||
logic.PlanExtraLoadDistance(data);
|
logic.PlanExtraLoadDistance(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
logic.WriteRegister(address, data); // we may signal the accepted/rejected status of the response as return value of this function
|
logic.WriteRegister(address, data); // we may signal the accepted/rejected status of the response as return value of this function
|
||||||
} while( ! manage_response(false, false) );
|
} while (!manage_response(false, false));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -193,13 +192,13 @@ struct ReportingRAII {
|
||||||
: cip(cip) {
|
: cip(cip) {
|
||||||
BeginReport(cip, (uint16_t)ProgressCode::EngagingIdler);
|
BeginReport(cip, (uint16_t)ProgressCode::EngagingIdler);
|
||||||
}
|
}
|
||||||
inline ~ReportingRAII(){
|
inline ~ReportingRAII() {
|
||||||
EndReport(cip, (uint16_t)ProgressCode::OK);
|
EndReport(cip, (uint16_t)ProgressCode::OK);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MMU2::WaitForMMUReady(){
|
bool MMU2::WaitForMMUReady() {
|
||||||
switch(State()){
|
switch (State()) {
|
||||||
case xState::Stopped:
|
case xState::Stopped:
|
||||||
return false;
|
return false;
|
||||||
case xState::Connecting:
|
case xState::Connecting:
|
||||||
|
|
@ -210,11 +209,11 @@ bool MMU2::WaitForMMUReady(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::RetryIfPossible(uint16_t ec){
|
bool MMU2::RetryIfPossible(uint16_t ec) {
|
||||||
if (logic.RetryAttempts()) {
|
if (logic.RetryAttempts()) {
|
||||||
SetButtonResponse(ButtonOperations::Retry);
|
SetButtonResponse(ButtonOperations::Retry);
|
||||||
// check, that Retry is actually allowed on that operation
|
// check, that Retry is actually allowed on that operation
|
||||||
if( ButtonAvailable(ec) != NoButton ){
|
if (ButtonAvailable(ec) != NoButton) {
|
||||||
logic.SetInAutoRetry(true);
|
logic.SetInAutoRetry(true);
|
||||||
SERIAL_ECHOLNPGM("RetryButtonPressed");
|
SERIAL_ECHOLNPGM("RetryButtonPressed");
|
||||||
// We don't decrement until the button is acknowledged by the MMU.
|
// We don't decrement until the button is acknowledged by the MMU.
|
||||||
|
|
@ -226,20 +225,19 @@ bool MMU2::RetryIfPossible(uint16_t ec){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::VerifyFilamentEnteredPTFE()
|
bool MMU2::VerifyFilamentEnteredPTFE() {
|
||||||
{
|
|
||||||
planner_synchronize();
|
planner_synchronize();
|
||||||
|
|
||||||
if (WhereIsFilament() == FilamentState::NOT_PRESENT) return false;
|
if (WhereIsFilament() == FilamentState::NOT_PRESENT)
|
||||||
|
return false;
|
||||||
|
|
||||||
uint8_t fsensorState = 0;
|
uint8_t fsensorState = 0;
|
||||||
// MMU has finished its load, push the filament further by some defined constant length
|
// MMU has finished its load, push the filament further by some defined constant length
|
||||||
// If the filament sensor reads 0 at any moment, then report FAILURE
|
// If the filament sensor reads 0 at any moment, then report FAILURE
|
||||||
MoveE(MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
|
MoveE(MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
|
||||||
MoveE( - (MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION)), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
|
MoveE(-(MMU2_EXTRUDER_PTFE_LENGTH + MMU2_EXTRUDER_HEATBREAK_LENGTH - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION)), MMU2_VERIFY_LOAD_TO_NOZZLE_FEED_RATE);
|
||||||
|
|
||||||
while(planner_any_moves())
|
while (planner_any_moves()) {
|
||||||
{
|
|
||||||
// Wait for move to finish and monitor the fsensor the entire time
|
// Wait for move to finish and monitor the fsensor the entire time
|
||||||
// A single 0 reading will set the bit.
|
// A single 0 reading will set the bit.
|
||||||
fsensorState |= (WhereIsFilament() == FilamentState::NOT_PRESENT);
|
fsensorState |= (WhereIsFilament() == FilamentState::NOT_PRESENT);
|
||||||
|
|
@ -247,8 +245,7 @@ bool MMU2::VerifyFilamentEnteredPTFE()
|
||||||
marlin_manage_inactivity(true);
|
marlin_manage_inactivity(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsensorState)
|
if (fsensorState) {
|
||||||
{
|
|
||||||
IncrementLoadFails();
|
IncrementLoadFails();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -257,14 +254,14 @@ bool MMU2::VerifyFilamentEnteredPTFE()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::ToolChangeCommonOnce(uint8_t slot){
|
bool MMU2::ToolChangeCommonOnce(uint8_t slot) {
|
||||||
static_assert(MAX_RETRIES > 1); // need >1 retries to do the cut in the last attempt
|
static_assert(MAX_RETRIES > 1); // need >1 retries to do the cut in the last attempt
|
||||||
for(uint8_t retries = MAX_RETRIES; retries; --retries){
|
for (uint8_t retries = MAX_RETRIES; retries; --retries) {
|
||||||
for(;;) {
|
for (;;) {
|
||||||
Disable_E0(); // it may seem counterintuitive to disable the E-motor, but it gets enabled in the planner whenever the E-motor is to move
|
Disable_E0(); // it may seem counterintuitive to disable the E-motor, but it gets enabled in the planner whenever the E-motor is to move
|
||||||
tool_change_extruder = slot;
|
tool_change_extruder = slot;
|
||||||
logic.ToolChange(slot); // let the MMU pull the filament out and push a new one in
|
logic.ToolChange(slot); // let the MMU pull the filament out and push a new one in
|
||||||
if( manage_response(true, true) )
|
if (manage_response(true, true))
|
||||||
break;
|
break;
|
||||||
// otherwise: failed to perform the command - unload first and then let it run again
|
// otherwise: failed to perform the command - unload first and then let it run again
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
|
|
@ -280,12 +277,12 @@ bool MMU2::ToolChangeCommonOnce(uint8_t slot){
|
||||||
// something else is seriously broken and stopping a print is probably our best option.
|
// something else is seriously broken and stopping a print is probably our best option.
|
||||||
}
|
}
|
||||||
// reset current position to whatever the planner thinks it is
|
// reset current position to whatever the planner thinks it is
|
||||||
planner_set_current_position_E( planner_get_current_position_E() );
|
planner_set_current_position_E(planner_get_current_position_E());
|
||||||
if (VerifyFilamentEnteredPTFE()){
|
if (VerifyFilamentEnteredPTFE()) {
|
||||||
return true; // success
|
return true; // success
|
||||||
} else { // Prepare a retry attempt
|
} else { // Prepare a retry attempt
|
||||||
unload();
|
unload();
|
||||||
if( retries == 2 && cutter_enabled()){
|
if (retries == 2 && cutter_enabled()) {
|
||||||
cut_filament(slot, false); // try cutting filament tip at the last attempt
|
cut_filament(slot, false); // try cutting filament tip at the last attempt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -293,8 +290,8 @@ bool MMU2::ToolChangeCommonOnce(uint8_t slot){
|
||||||
return false; // couldn't accomplish the task
|
return false; // couldn't accomplish the task
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::ToolChangeCommon(uint8_t slot){
|
void MMU2::ToolChangeCommon(uint8_t slot) {
|
||||||
while( ! ToolChangeCommonOnce(slot) ){ // while not successfully fed into extruder's PTFE tube
|
while (!ToolChangeCommonOnce(slot)) { // while not successfully fed into extruder's PTFE tube
|
||||||
// failed autoretry, report an error by forcing a "printer" error into the MMU infrastructure - it is a hack to leverage existing code
|
// failed autoretry, report an error by forcing a "printer" error into the MMU infrastructure - it is a hack to leverage existing code
|
||||||
// @@TODO theoretically logic layer may not need to be spoiled with the printer error - may be just the manage_response needs it...
|
// @@TODO theoretically logic layer may not need to be spoiled with the printer error - may be just the manage_response needs it...
|
||||||
logic.SetPrinterError(ErrorCode::LOAD_TO_EXTRUDER_FAILED);
|
logic.SetPrinterError(ErrorCode::LOAD_TO_EXTRUDER_FAILED);
|
||||||
|
|
@ -312,7 +309,7 @@ void MMU2::ToolChangeCommon(uint8_t slot){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::tool_change(uint8_t slot) {
|
bool MMU2::tool_change(uint8_t slot) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (slot != extruder) {
|
if (slot != extruder) {
|
||||||
|
|
@ -338,14 +335,14 @@ bool MMU2::tool_change(uint8_t slot) {
|
||||||
///- Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
|
///- Tx Same as T?, except nozzle doesn't have to be preheated. Tc must be placed after extruder nozzle is preheated to finish filament load.
|
||||||
///- Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
|
///- Tc Load to nozzle after filament was prepared by Tx and extruder nozzle is already heated.
|
||||||
bool MMU2::tool_change(char code, uint8_t slot) {
|
bool MMU2::tool_change(char code, uint8_t slot) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FSensorBlockRunout blockRunout;
|
FSensorBlockRunout blockRunout;
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case '?': {
|
case '?': {
|
||||||
waitForHotendTargetTemp(100, []{});
|
waitForHotendTargetTemp(100, [] {});
|
||||||
load_filament_to_nozzle(slot);
|
load_filament_to_nozzle(slot);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
@ -357,7 +354,7 @@ bool MMU2::tool_change(char code, uint8_t slot) {
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'c': {
|
case 'c': {
|
||||||
waitForHotendTargetTemp(100, []{});
|
waitForHotendTargetTemp(100, [] {});
|
||||||
execute_load_to_nozzle_sequence();
|
execute_load_to_nozzle_sequence();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
@ -378,16 +375,16 @@ uint8_t MMU2::get_tool_change_tool() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::set_filament_type(uint8_t /*slot*/, uint8_t /*type*/) {
|
bool MMU2::set_filament_type(uint8_t /*slot*/, uint8_t /*type*/) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// @@TODO - this is not supported in the new MMU yet
|
// @@TODO - this is not supported in the new MMU yet
|
||||||
// slot = slot; // @@TODO
|
// slot = slot; // @@TODO
|
||||||
// type = type; // @@TODO
|
// type = type; // @@TODO
|
||||||
// cmd_arg = filamentType;
|
// cmd_arg = filamentType;
|
||||||
// command(MMU_CMD_F0 + index);
|
// command(MMU_CMD_F0 + index);
|
||||||
|
|
||||||
if( ! manage_response(false, false) ){
|
if (!manage_response(false, false)) {
|
||||||
// @@TODO failed to perform the command - retry
|
// @@TODO failed to perform the command - retry
|
||||||
;
|
;
|
||||||
} // true, true); -- Comment: how is it possible for a filament type set to fail?
|
} // true, true); -- Comment: how is it possible for a filament type set to fail?
|
||||||
|
|
@ -396,7 +393,7 @@ bool MMU2::set_filament_type(uint8_t /*slot*/, uint8_t /*type*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::unload() {
|
bool MMU2::unload() {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
WaitForHotendTargetTempBeep();
|
WaitForHotendTargetTempBeep();
|
||||||
|
|
@ -408,10 +405,10 @@ bool MMU2::unload() {
|
||||||
|
|
||||||
// we assume the printer managed to relieve filament tip from the gears,
|
// we assume the printer managed to relieve filament tip from the gears,
|
||||||
// so repeating that part in case of an MMU restart is not necessary
|
// so repeating that part in case of an MMU restart is not necessary
|
||||||
for(;;) {
|
for (;;) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
logic.UnloadFilament();
|
logic.UnloadFilament();
|
||||||
if( manage_response(false, true) )
|
if (manage_response(false, true))
|
||||||
break;
|
break;
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
}
|
}
|
||||||
|
|
@ -424,23 +421,23 @@ bool MMU2::unload() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /* = true */){
|
bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /*= true*/) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( enableFullScreenMsg ){
|
if (enableFullScreenMsg) {
|
||||||
FullScreenMsgCut(slot);
|
FullScreenMsgCut(slot);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if( FindaDetectsFilament() ){
|
if (FindaDetectsFilament()) {
|
||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportingRAII rep(CommandInProgress::CutFilament);
|
ReportingRAII rep(CommandInProgress::CutFilament);
|
||||||
for(;;){
|
for (;;) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
logic.CutFilament(slot);
|
logic.CutFilament(slot);
|
||||||
if( manage_response(false, true) )
|
if (manage_response(false, true))
|
||||||
break;
|
break;
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
}
|
}
|
||||||
|
|
@ -451,7 +448,7 @@ bool MMU2::cut_filament(uint8_t slot, bool enableFullScreenMsg /* = true */){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::loading_test(uint8_t slot){
|
bool MMU2::loading_test(uint8_t slot) {
|
||||||
FullScreenMsgTest(slot);
|
FullScreenMsgTest(slot);
|
||||||
tool_change(slot);
|
tool_change(slot);
|
||||||
planner_synchronize();
|
planner_synchronize();
|
||||||
|
|
@ -461,16 +458,16 @@ bool MMU2::loading_test(uint8_t slot){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::load_filament(uint8_t slot) {
|
bool MMU2::load_filament(uint8_t slot) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FullScreenMsgLoad(slot);
|
FullScreenMsgLoad(slot);
|
||||||
|
|
||||||
ReportingRAII rep(CommandInProgress::LoadFilament);
|
ReportingRAII rep(CommandInProgress::LoadFilament);
|
||||||
for(;;) {
|
for (;;) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
logic.LoadFilament(slot);
|
logic.LoadFilament(slot);
|
||||||
if( manage_response(false, false) )
|
if (manage_response(false, false))
|
||||||
break;
|
break;
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
}
|
}
|
||||||
|
|
@ -484,16 +481,17 @@ bool MMU2::load_filament(uint8_t slot) {
|
||||||
|
|
||||||
struct LoadingToNozzleRAII {
|
struct LoadingToNozzleRAII {
|
||||||
MMU2 &mmu2;
|
MMU2 &mmu2;
|
||||||
explicit inline LoadingToNozzleRAII(MMU2 &mmu2):mmu2(mmu2){
|
explicit inline LoadingToNozzleRAII(MMU2 &mmu2)
|
||||||
|
: mmu2(mmu2) {
|
||||||
mmu2.loadingToNozzle = true;
|
mmu2.loadingToNozzle = true;
|
||||||
}
|
}
|
||||||
inline ~LoadingToNozzleRAII(){
|
inline ~LoadingToNozzleRAII() {
|
||||||
mmu2.loadingToNozzle = false;
|
mmu2.loadingToNozzle = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool MMU2::load_filament_to_nozzle(uint8_t slot) {
|
bool MMU2::load_filament_to_nozzle(uint8_t slot) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
LoadingToNozzleRAII ln(*this);
|
LoadingToNozzleRAII ln(*this);
|
||||||
|
|
@ -506,7 +504,7 @@ bool MMU2::load_filament_to_nozzle(uint8_t slot) {
|
||||||
ReportingRAII rep(CommandInProgress::ToolChange);
|
ReportingRAII rep(CommandInProgress::ToolChange);
|
||||||
FSensorBlockRunout blockRunout;
|
FSensorBlockRunout blockRunout;
|
||||||
|
|
||||||
if( extruder != MMU2_NO_TOOL ){ // we already have some filament loaded - free it + shape its tip properly
|
if (extruder != MMU2_NO_TOOL) { // we already have some filament loaded - free it + shape its tip properly
|
||||||
filament_ramming();
|
filament_ramming();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,22 +519,22 @@ bool MMU2::load_filament_to_nozzle(uint8_t slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::eject_filament(uint8_t slot, bool enableFullScreenMsg /* = true */) {
|
bool MMU2::eject_filament(uint8_t slot, bool enableFullScreenMsg /* = true */) {
|
||||||
if( ! WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( enableFullScreenMsg ){
|
if (enableFullScreenMsg) {
|
||||||
FullScreenMsgEject(slot);
|
FullScreenMsgEject(slot);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if( FindaDetectsFilament() ){
|
if (FindaDetectsFilament()) {
|
||||||
unload();
|
unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportingRAII rep(CommandInProgress::EjectFilament);
|
ReportingRAII rep(CommandInProgress::EjectFilament);
|
||||||
for(;;) {
|
for (;;) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
logic.EjectFilament(slot);
|
logic.EjectFilament(slot);
|
||||||
if( manage_response(false, true) )
|
if (manage_response(false, true))
|
||||||
break;
|
break;
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
}
|
}
|
||||||
|
|
@ -547,19 +545,20 @@ bool MMU2::eject_filament(uint8_t slot, bool enableFullScreenMsg /* = true */) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::Button(uint8_t index){
|
void MMU2::Button(uint8_t index) {
|
||||||
LogEchoEvent_P(PSTR("Button"));
|
LogEchoEvent_P(PSTR("Button"));
|
||||||
logic.Button(index);
|
logic.Button(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::Home(uint8_t mode){
|
void MMU2::Home(uint8_t mode) {
|
||||||
logic.Home(mode);
|
logic.Home(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::SaveHotendTemp(bool turn_off_nozzle) {
|
void MMU2::SaveHotendTemp(bool turn_off_nozzle) {
|
||||||
if (mmu_print_saved & SavedState::Cooldown) return;
|
if (mmu_print_saved & SavedState::Cooldown)
|
||||||
|
return;
|
||||||
|
|
||||||
if (turn_off_nozzle && !(mmu_print_saved & SavedState::CooldownPending)){
|
if (turn_off_nozzle && !(mmu_print_saved & SavedState::CooldownPending)) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
resume_hotend_temp = thermal_degTargetHotend();
|
resume_hotend_temp = thermal_degTargetHotend();
|
||||||
mmu_print_saved |= SavedState::CooldownPending;
|
mmu_print_saved |= SavedState::CooldownPending;
|
||||||
|
|
@ -573,7 +572,7 @@ void MMU2::SaveAndPark(bool move_axes) {
|
||||||
Disable_E0();
|
Disable_E0();
|
||||||
planner_synchronize();
|
planner_synchronize();
|
||||||
|
|
||||||
if (move_axes){
|
if (move_axes) {
|
||||||
mmu_print_saved |= SavedState::ParkExtruder;
|
mmu_print_saved |= SavedState::ParkExtruder;
|
||||||
resume_position = planner_current_position(); // save current pos
|
resume_position = planner_current_position(); // save current pos
|
||||||
|
|
||||||
|
|
@ -599,14 +598,14 @@ void MMU2::ResumeHotendTemp() {
|
||||||
}
|
}
|
||||||
if ((mmu_print_saved & SavedState::Cooldown) && resume_hotend_temp) {
|
if ((mmu_print_saved & SavedState::Cooldown) && resume_hotend_temp) {
|
||||||
LogEchoEvent_P(PSTR("Resuming Temp"));
|
LogEchoEvent_P(PSTR("Resuming Temp"));
|
||||||
// @@TODO MMU2_ECHO_MSGRPGM(PSTR("Restoring hotend temperature "));
|
// @@TODO MMU2_ECHO_MSGRPGM(PSTR("Restoring hotend temperature "));
|
||||||
SERIAL_ECHOLN(resume_hotend_temp);
|
SERIAL_ECHOLN(resume_hotend_temp);
|
||||||
mmu_print_saved &= ~(SavedState::Cooldown);
|
mmu_print_saved &= ~(SavedState::Cooldown);
|
||||||
thermal_setTargetHotend(resume_hotend_temp);
|
thermal_setTargetHotend(resume_hotend_temp);
|
||||||
FullScreenMsgRestoringTemperature();
|
FullScreenMsgRestoringTemperature();
|
||||||
//@todo better report the event and let the GUI do its work somewhere else
|
//@todo better report the event and let the GUI do its work somewhere else
|
||||||
ReportErrorHookSensorLineRender();
|
ReportErrorHookSensorLineRender();
|
||||||
waitForHotendTargetTemp(100, []{
|
waitForHotendTargetTemp(100, [] {
|
||||||
marlin_manage_inactivity(true);
|
marlin_manage_inactivity(true);
|
||||||
mmu2.mmu_loop_inner(false);
|
mmu2.mmu_loop_inner(false);
|
||||||
ReportErrorHookDynamicRender();
|
ReportErrorHookDynamicRender();
|
||||||
|
|
@ -617,7 +616,7 @@ void MMU2::ResumeHotendTemp() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::ResumeUnpark(){
|
void MMU2::ResumeUnpark() {
|
||||||
if (mmu_print_saved & SavedState::ParkExtruder) {
|
if (mmu_print_saved & SavedState::ParkExtruder) {
|
||||||
LogEchoEvent_P(PSTR("Resuming XYZ"));
|
LogEchoEvent_P(PSTR("Resuming XYZ"));
|
||||||
|
|
||||||
|
|
@ -631,11 +630,11 @@ void MMU2::ResumeUnpark(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::CheckUserInput(){
|
void MMU2::CheckUserInput() {
|
||||||
auto btn = ButtonPressed((uint16_t)lastErrorCode);
|
auto btn = ButtonPressed((uint16_t)lastErrorCode);
|
||||||
|
|
||||||
// Was a button pressed on the MMU itself instead of the LCD?
|
// Was a button pressed on the MMU itself instead of the LCD?
|
||||||
if (btn == Buttons::NoButton && lastButton != Buttons::NoButton){
|
if (btn == Buttons::NoButton && lastButton != Buttons::NoButton) {
|
||||||
btn = lastButton;
|
btn = lastButton;
|
||||||
lastButton = Buttons::NoButton; // Clear it.
|
lastButton = Buttons::NoButton; // Clear it.
|
||||||
}
|
}
|
||||||
|
|
@ -648,7 +647,7 @@ void MMU2::CheckUserInput(){
|
||||||
SERIAL_ECHOLN(btn);
|
SERIAL_ECHOLN(btn);
|
||||||
|
|
||||||
// clear the explicit printer error as soon as possible so that the MMU error screens + reporting doesn't get too confused
|
// clear the explicit printer error as soon as possible so that the MMU error screens + reporting doesn't get too confused
|
||||||
if( lastErrorCode == ErrorCode::LOAD_TO_EXTRUDER_FAILED ){
|
if (lastErrorCode == ErrorCode::LOAD_TO_EXTRUDER_FAILED) {
|
||||||
// A horrible hack - clear the explicit printer error allowing manage_response to recover on MMU's Finished state
|
// A horrible hack - clear the explicit printer error allowing manage_response to recover on MMU's Finished state
|
||||||
// Moreover - if the MMU is currently doing something (like the LoadFilament - see comment above)
|
// Moreover - if the MMU is currently doing something (like the LoadFilament - see comment above)
|
||||||
// we'll actually wait for it automagically in manage_response and after it finishes correctly,
|
// we'll actually wait for it automagically in manage_response and after it finishes correctly,
|
||||||
|
|
@ -668,7 +667,7 @@ void MMU2::CheckUserInput(){
|
||||||
// A quick hack: for specific error codes move the E-motor every time.
|
// A quick hack: for specific error codes move the E-motor every time.
|
||||||
// Not sure if we can rely on the fsensor.
|
// Not sure if we can rely on the fsensor.
|
||||||
// Just plan the move, let the MMU take over when it is ready
|
// Just plan the move, let the MMU take over when it is ready
|
||||||
switch(lastErrorCode){
|
switch (lastErrorCode) {
|
||||||
case ErrorCode::FSENSOR_DIDNT_SWITCH_OFF:
|
case ErrorCode::FSENSOR_DIDNT_SWITCH_OFF:
|
||||||
case ErrorCode::FSENSOR_TOO_EARLY:
|
case ErrorCode::FSENSOR_TOO_EARLY:
|
||||||
HelpUnloadToFinda();
|
HelpUnloadToFinda();
|
||||||
|
|
@ -714,11 +713,11 @@ bool MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||||
// - finished ok -> proceed with reading other commands
|
// - finished ok -> proceed with reading other commands
|
||||||
safe_delay_keep_alive(0); // calls LogicStep() and remembers its return status
|
safe_delay_keep_alive(0); // calls LogicStep() and remembers its return status
|
||||||
|
|
||||||
if (mmu_print_saved & SavedState::CooldownPending){
|
if (mmu_print_saved & SavedState::CooldownPending) {
|
||||||
if (!nozzleTimeout.running()){
|
if (!nozzleTimeout.running()) {
|
||||||
nozzleTimeout.start();
|
nozzleTimeout.start();
|
||||||
LogEchoEvent_P(PSTR("Cooling Timeout started"));
|
LogEchoEvent_P(PSTR("Cooling Timeout started"));
|
||||||
} else if (nozzleTimeout.expired(DEFAULT_SAFETYTIMER_TIME_MINS*60*1000ul)){ // mins->msec.
|
} else if (nozzleTimeout.expired(DEFAULT_SAFETYTIMER_TIME_MINS * 60 * 1000ul)) { // mins->msec.
|
||||||
mmu_print_saved &= ~(SavedState::CooldownPending);
|
mmu_print_saved &= ~(SavedState::CooldownPending);
|
||||||
mmu_print_saved |= SavedState::Cooldown;
|
mmu_print_saved |= SavedState::Cooldown;
|
||||||
thermal_setTargetHotend(0);
|
thermal_setTargetHotend(0);
|
||||||
|
|
@ -755,7 +754,7 @@ bool MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||||
case CommunicationTimeout:
|
case CommunicationTimeout:
|
||||||
case ProtocolError:
|
case ProtocolError:
|
||||||
case ButtonPushed:
|
case ButtonPushed:
|
||||||
if (! logic.InAutoRetry()){
|
if (!logic.InAutoRetry()) {
|
||||||
// Don't proceed to the park/save if we are doing an autoretry.
|
// Don't proceed to the park/save if we are doing an autoretry.
|
||||||
SaveAndPark(move_axes);
|
SaveAndPark(move_axes);
|
||||||
SaveHotendTemp(turn_off_nozzle);
|
SaveHotendTemp(turn_off_nozzle);
|
||||||
|
|
@ -794,9 +793,8 @@ StepStatus MMU2::LogicStep(bool reportErrors) {
|
||||||
// can be silently handed over to a higher layer, no processing necessary at this spot
|
// can be silently handed over to a higher layer, no processing necessary at this spot
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if(reportErrors) {
|
if (reportErrors) {
|
||||||
switch (ss)
|
switch (ss) {
|
||||||
{
|
|
||||||
case CommandError:
|
case CommandError:
|
||||||
ReportError(logic.Error(), ErrorSourceMMU);
|
ReportError(logic.Error(), ErrorSourceMMU);
|
||||||
break;
|
break;
|
||||||
|
|
@ -821,7 +819,7 @@ StepStatus MMU2::LogicStep(bool reportErrors) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( logic.Running() ){
|
if (logic.Running()) {
|
||||||
state = xState::Active;
|
state = xState::Active;
|
||||||
}
|
}
|
||||||
return ss;
|
return ss;
|
||||||
|
|
@ -852,8 +850,8 @@ void MMU2::execute_extruder_sequence(const E_Step *sequence, uint8_t steps) {
|
||||||
void MMU2::execute_load_to_nozzle_sequence() {
|
void MMU2::execute_load_to_nozzle_sequence() {
|
||||||
planner_synchronize();
|
planner_synchronize();
|
||||||
// Compensate for configurable Extra Loading Distance
|
// Compensate for configurable Extra Loading Distance
|
||||||
planner_set_current_position_E( planner_get_current_position_E() - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION) );
|
planner_set_current_position_E(planner_get_current_position_E() - (logic.ExtraLoadDistance() - MMU2_FILAMENT_SENSOR_POSITION));
|
||||||
execute_extruder_sequence(load_to_nozzle_sequence, sizeof(load_to_nozzle_sequence) / sizeof (load_to_nozzle_sequence[0]));
|
execute_extruder_sequence(load_to_nozzle_sequence, sizeof(load_to_nozzle_sequence) / sizeof(load_to_nozzle_sequence[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
||||||
|
|
@ -870,7 +868,7 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
||||||
// Right now the filtering of MMU_NOT_RESPONDING is done in ReportErrorHook() as it is not a problem if mmu2.cpp
|
// Right now the filtering of MMU_NOT_RESPONDING is done in ReportErrorHook() as it is not a problem if mmu2.cpp
|
||||||
|
|
||||||
// Depending on the Progress code, we may want to do some action when an error occurs
|
// Depending on the Progress code, we may want to do some action when an error occurs
|
||||||
switch (logic.Progress()){
|
switch (logic.Progress()) {
|
||||||
case ProgressCode::UnloadingToFinda:
|
case ProgressCode::UnloadingToFinda:
|
||||||
unloadFilamentStarted = false;
|
unloadFilamentStarted = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -882,12 +880,12 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ec != lastErrorCode ){ // deduplicate: only report changes in error codes into the log
|
if (ec != lastErrorCode) { // deduplicate: only report changes in error codes into the log
|
||||||
lastErrorCode = ec;
|
lastErrorCode = ec;
|
||||||
lastErrorSource = res;
|
lastErrorSource = res;
|
||||||
LogErrorEvent_P( _O(PrusaErrorTitle(PrusaErrorCodeIndex((uint16_t)ec))) );
|
LogErrorEvent_P(_O(PrusaErrorTitle(PrusaErrorCodeIndex((uint16_t)ec))));
|
||||||
|
|
||||||
if( ec != ErrorCode::OK ){
|
if (ec != ErrorCode::OK) {
|
||||||
IncrementMMUFails();
|
IncrementMMUFails();
|
||||||
|
|
||||||
// check if it is a "power" failure - we consider TMC-related errors as power failures
|
// check if it is a "power" failure - we consider TMC-related errors as power failures
|
||||||
|
|
@ -908,7 +906,7 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !mmu2.RetryIfPossible((uint16_t)ec) ) {
|
if (!mmu2.RetryIfPossible((uint16_t)ec)) {
|
||||||
// If retry attempts are all used up
|
// If retry attempts are all used up
|
||||||
// or if 'Retry' operation is not available
|
// or if 'Retry' operation is not available
|
||||||
// raise the MMU error sceen and wait for user input
|
// raise the MMU error sceen and wait for user input
|
||||||
|
|
@ -921,16 +919,15 @@ void MMU2::ReportError(ErrorCode ec, ErrorSource res) {
|
||||||
&& mmu2Magic[3] == '2'
|
&& mmu2Magic[3] == '2'
|
||||||
&& mmu2Magic[4] == ':'
|
&& mmu2Magic[4] == ':'
|
||||||
&& strlen_constexpr(mmu2Magic) == 5,
|
&& strlen_constexpr(mmu2Magic) == 5,
|
||||||
"MMU2 logging prefix mismatch, must be updated at various spots"
|
"MMU2 logging prefix mismatch, must be updated at various spots");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::ReportProgress(ProgressCode pc) {
|
void MMU2::ReportProgress(ProgressCode pc) {
|
||||||
ReportProgressHook((CommandInProgress)logic.CommandInProgress(), (uint16_t)pc);
|
ReportProgressHook((CommandInProgress)logic.CommandInProgress(), (uint16_t)pc);
|
||||||
LogEchoEvent_P( _O(ProgressCodeToText((uint16_t)pc)) );
|
LogEchoEvent_P(_O(ProgressCodeToText((uint16_t)pc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::OnMMUProgressMsg(ProgressCode pc){
|
void MMU2::OnMMUProgressMsg(ProgressCode pc) {
|
||||||
if (pc != lastProgressCode) {
|
if (pc != lastProgressCode) {
|
||||||
OnMMUProgressMsgChanged(pc);
|
OnMMUProgressMsgChanged(pc);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -938,7 +935,7 @@ void MMU2::OnMMUProgressMsg(ProgressCode pc){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::OnMMUProgressMsgChanged(ProgressCode pc){
|
void MMU2::OnMMUProgressMsgChanged(ProgressCode pc) {
|
||||||
ReportProgress(pc);
|
ReportProgress(pc);
|
||||||
lastProgressCode = pc;
|
lastProgressCode = pc;
|
||||||
switch (pc) {
|
switch (pc) {
|
||||||
|
|
@ -967,11 +964,11 @@ void MMU2::OnMMUProgressMsgChanged(ProgressCode pc){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((noinline)) MMU2::HelpUnloadToFinda(){
|
void __attribute__((noinline)) MMU2::HelpUnloadToFinda() {
|
||||||
MoveE(- MMU2_RETRY_UNLOAD_TO_FINDA_LENGTH, MMU2_RETRY_UNLOAD_TO_FINDA_FEED_RATE);
|
MoveE(-MMU2_RETRY_UNLOAD_TO_FINDA_LENGTH, MMU2_RETRY_UNLOAD_TO_FINDA_FEED_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::OnMMUProgressMsgSame(ProgressCode pc){
|
void MMU2::OnMMUProgressMsgSame(ProgressCode pc) {
|
||||||
switch (pc) {
|
switch (pc) {
|
||||||
case ProgressCode::UnloadingToFinda:
|
case ProgressCode::UnloadingToFinda:
|
||||||
if (unloadFilamentStarted && !planner_any_moves()) { // Only plan a move if there is no move ongoing
|
if (unloadFilamentStarted && !planner_any_moves()) { // Only plan a move if there is no move ongoing
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,13 @@
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
#include "mmu2_protocol_logic.h"
|
#include "mmu2_protocol_logic.h"
|
||||||
typedef float feedRate_t;
|
typedef float feedRate_t;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "protocol_logic.h"
|
#include "protocol_logic.h"
|
||||||
#include "../../Marlin/src/core/macros.h"
|
#include "../../Marlin/src/core/macros.h"
|
||||||
#include "../../Marlin/src/core/types.h"
|
#include "../../Marlin/src/core/types.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct E_Step;
|
struct E_Step;
|
||||||
|
|
@ -43,7 +44,7 @@ public:
|
||||||
|
|
||||||
inline xState State() const { return state; }
|
inline xState State() const { return state; }
|
||||||
|
|
||||||
inline bool Enabled()const { return State() == xState::Active; }
|
inline bool Enabled() const { return State() == xState::Active; }
|
||||||
|
|
||||||
/// Different levels of resetting the MMU
|
/// Different levels of resetting the MMU
|
||||||
enum ResetForm : uint8_t {
|
enum ResetForm : uint8_t {
|
||||||
|
|
@ -53,7 +54,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Saved print state on error.
|
/// Saved print state on error.
|
||||||
enum SavedState: uint8_t {
|
enum SavedState : uint8_t {
|
||||||
None = 0, // No state saved.
|
None = 0, // No state saved.
|
||||||
ParkExtruder = 1, // The extruder was parked.
|
ParkExtruder = 1, // The extruder was parked.
|
||||||
Cooldown = 2, // The extruder was allowed to cool.
|
Cooldown = 2, // The extruder was allowed to cool.
|
||||||
|
|
@ -61,7 +62,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Source of operation error
|
/// Source of operation error
|
||||||
enum ErrorSource: uint8_t {
|
enum ErrorSource : uint8_t {
|
||||||
ErrorSourcePrinter = 0,
|
ErrorSourcePrinter = 0,
|
||||||
ErrorSourceMMU = 1,
|
ErrorSourceMMU = 1,
|
||||||
ErrorSourceNone = 0xFF,
|
ErrorSourceNone = 0xFF,
|
||||||
|
|
@ -150,9 +151,9 @@ public:
|
||||||
void Home(uint8_t mode);
|
void Home(uint8_t mode);
|
||||||
|
|
||||||
/// @returns current state of FINDA (true=filament present, false=filament not present)
|
/// @returns current state of FINDA (true=filament present, false=filament not present)
|
||||||
inline bool FindaDetectsFilament()const { return logic.FindaPressed(); }
|
inline bool FindaDetectsFilament() const { return logic.FindaPressed(); }
|
||||||
|
|
||||||
inline uint16_t TotalFailStatistics()const { return logic.FailStatistics(); }
|
inline uint16_t TotalFailStatistics() const { return logic.FailStatistics(); }
|
||||||
|
|
||||||
/// @returns Current error code
|
/// @returns Current error code
|
||||||
inline ErrorCode MMUCurrentErrorCode() const { return logic.Error(); }
|
inline ErrorCode MMUCurrentErrorCode() const { return logic.Error(); }
|
||||||
|
|
@ -162,11 +163,11 @@ public:
|
||||||
|
|
||||||
/// @returns the version of the connected MMU FW.
|
/// @returns the version of the connected MMU FW.
|
||||||
/// In the future we'll return the trully detected FW version
|
/// In the future we'll return the trully detected FW version
|
||||||
Version GetMMUFWVersion()const {
|
Version GetMMUFWVersion() const {
|
||||||
if( State() == xState::Active ){
|
if (State() == xState::Active) {
|
||||||
return { logic.MmuFwVersionMajor(), logic.MmuFwVersionMinor(), logic.MmuFwVersionRevision() };
|
return { logic.MmuFwVersionMajor(), logic.MmuFwVersionMinor(), logic.MmuFwVersionRevision() };
|
||||||
} else {
|
} else {
|
||||||
return { 0, 0, 0};
|
return { 0, 0, 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +188,7 @@ public:
|
||||||
/// Set toolchange counter to zero
|
/// Set toolchange counter to zero
|
||||||
inline void ClearToolChangeCounter() { toolchange_counter = 0; };
|
inline void ClearToolChangeCounter() { toolchange_counter = 0; };
|
||||||
|
|
||||||
inline uint16_t TMCFailures()const { return tmcFailures; }
|
inline uint16_t TMCFailures() const { return tmcFailures; }
|
||||||
inline void IncrementTMCFailures() { ++tmcFailures; }
|
inline void IncrementTMCFailures() { ++tmcFailures; }
|
||||||
inline void ClearTMCFailures() { tmcFailures = 0; }
|
inline void ClearTMCFailures() { tmcFailures = 0; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ uint8_t PrusaErrorCodeIndex(uint16_t ec);
|
||||||
|
|
||||||
/// @returns pointer to a PROGMEM string representing the Title of the Prusa-Error-Codes error
|
/// @returns pointer to a PROGMEM string representing the Title of the Prusa-Error-Codes error
|
||||||
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
||||||
const char * PrusaErrorTitle(uint8_t i);
|
const char *PrusaErrorTitle(uint8_t i);
|
||||||
|
|
||||||
/// @returns pointer to a PROGMEM string representing the multi-page Description of the Prusa-Error-Codes error
|
/// @returns pointer to a PROGMEM string representing the multi-page Description of the Prusa-Error-Codes error
|
||||||
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
||||||
const char * PrusaErrorDesc(uint8_t i);
|
const char *PrusaErrorDesc(uint8_t i);
|
||||||
|
|
||||||
/// @returns the actual numerical value of the Prusa-Error-Codes error
|
/// @returns the actual numerical value of the Prusa-Error-Codes error
|
||||||
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
/// @param i index of the error - obtained by calling ErrorCodeIndex
|
||||||
|
|
@ -27,10 +27,10 @@ uint8_t PrusaErrorButtons(uint8_t i);
|
||||||
|
|
||||||
/// @returns pointer to a PROGMEM string representing the Title of a button
|
/// @returns pointer to a PROGMEM string representing the Title of a button
|
||||||
/// @param i index of the error - obtained by calling PrusaErrorButtons + extracting low or high nibble from the Btns pair
|
/// @param i index of the error - obtained by calling PrusaErrorButtons + extracting low or high nibble from the Btns pair
|
||||||
const char * PrusaErrorButtonTitle(uint8_t bi);
|
const char *PrusaErrorButtonTitle(uint8_t bi);
|
||||||
|
|
||||||
/// @returns pointer to a PROGMEM string representing the "More" button
|
/// @returns pointer to a PROGMEM string representing the "More" button
|
||||||
const char * PrusaErrorButtonMore();
|
const char *PrusaErrorButtonMore();
|
||||||
|
|
||||||
/// Sets the selected button for later pick-up by the MMU state machine.
|
/// Sets the selected button for later pick-up by the MMU state machine.
|
||||||
/// Used to save the GUI selection/decoupling
|
/// Used to save the GUI selection/decoupling
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,36 @@ void LogEchoEvent_P(const char *msg);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#define SERIAL_MMU2() { serialprintPGM(mmu2Magic); }
|
#define SERIAL_MMU2() \
|
||||||
|
{ serialprintPGM(mmu2Magic); }
|
||||||
|
|
||||||
#define MMU2_ECHO_MSGLN(S) do{ SERIAL_ECHO_START; SERIAL_MMU2(); SERIAL_ECHOLN(S); }while(0)
|
#define MMU2_ECHO_MSGLN(S) \
|
||||||
#define MMU2_ERROR_MSGLN(S) MMU2_ECHO_MSGLN(S) //!@todo Decide MMU2 errors on serial line
|
do { \
|
||||||
#define MMU2_ECHO_MSGRPGM(S) do{ SERIAL_ECHO_START; SERIAL_MMU2(); SERIAL_ECHORPGM(S); }while(0)
|
SERIAL_ECHO_START(); \
|
||||||
#define MMU2_ERROR_MSGRPGM(S) MMU2_ECHO_MSGRPGM(S) //!@todo Decide MMU2 errors on serial line
|
SERIAL_MMU2(); \
|
||||||
|
SERIAL_ECHOLN(S); \
|
||||||
|
} while (0)
|
||||||
|
#define MMU2_ERROR_MSGLN(S) MMU2_ECHO_MSGLN(S) //!@todo Decide MMU2 errors on serial line
|
||||||
|
#define MMU2_ECHO_MSGRPGM(S) \
|
||||||
|
do { \
|
||||||
|
SERIAL_ECHO_START(); \
|
||||||
|
SERIAL_MMU2(); \
|
||||||
|
SERIAL_ECHO(S); \
|
||||||
|
} while (0)
|
||||||
|
#define MMU2_ERROR_MSGRPGM(S) MMU2_ECHO_MSGRPGM(S) //!@todo Decide MMU2 errors on serial line
|
||||||
|
#define MMU2_ECHO_MSG(S) \
|
||||||
|
do { \
|
||||||
|
SERIAL_ECHO_START(); \
|
||||||
|
SERIAL_MMU2(); \
|
||||||
|
SERIAL_ECHO(S); \
|
||||||
|
} while (0)
|
||||||
|
#define MMU2_ERROR_MSG(S) MMU2_ECHO_MSG(S) //!@todo Decide MMU2 errors on serial line
|
||||||
|
|
||||||
#else // #ifndef UNITTEST
|
#else // #ifndef UNITTEST
|
||||||
|
|
||||||
#define MMU2_ECHO_MSGLN(S) /* */
|
#define MMU2_ECHO_MSGLN(S) /* */
|
||||||
#define MMU2_ERROR_MSGLN(S) /* */
|
#define MMU2_ERROR_MSGLN(S) /* */
|
||||||
#define MMU2_ECHO_MSGRPGM(S) /* */
|
#define MMU2_ECHO_MSGRPGM(S) /* */
|
||||||
#define MMU2_ERROR_MSGRPGM(S) /* */
|
#define MMU2_ERROR_MSGRPGM(S) /* */
|
||||||
|
|
||||||
#endif // #ifndef UNITTEST
|
#endif // #ifndef UNITTEST
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
#include "mmu2_fsensor.h"
|
#include "mmu2_fsensor.h"
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
// on MK3/S/+ we shuffle the timers a bit, thus "_millis" may not equal "millis"
|
// on MK3/S/+ we shuffle the timers a bit, thus "_millis" may not equal "millis"
|
||||||
#include "system_timer.h"
|
#include "system_timer.h"
|
||||||
#else
|
#else
|
||||||
// irrelevant on Buddy FW, just keep "_millis" as "millis"
|
// irrelevant on Buddy FW, just keep "_millis" as "millis"
|
||||||
#include <wiring_time.h>
|
#include <wiring_time.h>
|
||||||
#define _millis millis
|
#define _millis millis
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -52,10 +52,10 @@ void ProtocolLogic::StartReading8bitRegisters() {
|
||||||
SendReadRegister(pgm_read_byte(regs8Addrs + regIndex), ScopeState::Reading8bitRegisters);
|
SendReadRegister(pgm_read_byte(regs8Addrs + regIndex), ScopeState::Reading8bitRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolLogic::ProcessRead8bitRegister(){
|
void ProtocolLogic::ProcessRead8bitRegister() {
|
||||||
regs8[regIndex] = rsp.paramValue;
|
regs8[regIndex] = rsp.paramValue;
|
||||||
++regIndex;
|
++regIndex;
|
||||||
if(regIndex >= regs8Count){
|
if (regIndex >= regs8Count) {
|
||||||
// proceed with reading 16bit registers
|
// proceed with reading 16bit registers
|
||||||
StartReading16bitRegisters();
|
StartReading16bitRegisters();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -68,10 +68,10 @@ void ProtocolLogic::StartReading16bitRegisters() {
|
||||||
SendReadRegister(pgm_read_byte(regs16Addrs + regIndex), ScopeState::Reading16bitRegisters);
|
SendReadRegister(pgm_read_byte(regs16Addrs + regIndex), ScopeState::Reading16bitRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolLogic::ScopeState __attribute__((noinline)) ProtocolLogic::ProcessRead16bitRegister(ProtocolLogic::ScopeState stateAtEnd){
|
ProtocolLogic::ScopeState __attribute__((noinline)) ProtocolLogic::ProcessRead16bitRegister(ProtocolLogic::ScopeState stateAtEnd) {
|
||||||
regs16[regIndex] = rsp.paramValue;
|
regs16[regIndex] = rsp.paramValue;
|
||||||
++regIndex;
|
++regIndex;
|
||||||
if(regIndex >= regs16Count){
|
if (regIndex >= regs16Count) {
|
||||||
return stateAtEnd;
|
return stateAtEnd;
|
||||||
} else {
|
} else {
|
||||||
SendReadRegister(pgm_read_byte(regs16Addrs + regIndex), ScopeState::Reading16bitRegisters);
|
SendReadRegister(pgm_read_byte(regs16Addrs + regIndex), ScopeState::Reading16bitRegisters);
|
||||||
|
|
@ -84,9 +84,9 @@ void ProtocolLogic::StartWritingInitRegisters() {
|
||||||
SendWriteRegister(pgm_read_byte(initRegs8Addrs + regIndex), initRegs8[regIndex], ScopeState::WritingInitRegisters);
|
SendWriteRegister(pgm_read_byte(initRegs8Addrs + regIndex), initRegs8[regIndex], ScopeState::WritingInitRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool __attribute__((noinline)) ProtocolLogic::ProcessWritingInitRegister(){
|
bool __attribute__((noinline)) ProtocolLogic::ProcessWritingInitRegister() {
|
||||||
++regIndex;
|
++regIndex;
|
||||||
if(regIndex >= initRegs8Count){
|
if (regIndex >= initRegs8Count) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
SendWriteRegister(pgm_read_byte(initRegs8Addrs + regIndex), initRegs8[regIndex], ScopeState::WritingInitRegisters);
|
SendWriteRegister(pgm_read_byte(initRegs8Addrs + regIndex), initRegs8[regIndex], ScopeState::WritingInitRegisters);
|
||||||
|
|
@ -114,7 +114,7 @@ void ProtocolLogic::SendReadRegister(uint8_t index, ScopeState nextState) {
|
||||||
scopeState = nextState;
|
scopeState = nextState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolLogic::SendWriteRegister(uint8_t index, uint16_t value, ScopeState nextState){
|
void ProtocolLogic::SendWriteRegister(uint8_t index, uint16_t value, ScopeState nextState) {
|
||||||
SendWriteMsg(RequestMsg(RequestMsgCodes::Write, index, value));
|
SendWriteMsg(RequestMsg(RequestMsgCodes::Write, index, value));
|
||||||
scopeState = nextState;
|
scopeState = nextState;
|
||||||
}
|
}
|
||||||
|
|
@ -130,12 +130,12 @@ struct OldMMUFWDetector {
|
||||||
Matched };
|
Matched };
|
||||||
|
|
||||||
/// @returns true when "ok\n" gets detected
|
/// @returns true when "ok\n" gets detected
|
||||||
State Detect(uint8_t c){
|
State Detect(uint8_t c) {
|
||||||
// consume old MMU FW's data if any -> avoid confusion of protocol decoder
|
// consume old MMU FW's data if any -> avoid confusion of protocol decoder
|
||||||
if(ok == 0 && c == 'o'){
|
if (ok == 0 && c == 'o') {
|
||||||
++ok;
|
++ok;
|
||||||
return State::MatchingPart;
|
return State::MatchingPart;
|
||||||
} else if(ok == 1 && c == 'k'){
|
} else if (ok == 1 && c == 'k') {
|
||||||
++ok;
|
++ok;
|
||||||
return State::Matched;
|
return State::Matched;
|
||||||
}
|
}
|
||||||
|
|
@ -162,13 +162,13 @@ StepStatus ProtocolLogic::ExpectingMessage() {
|
||||||
return MessageReady;
|
return MessageReady;
|
||||||
case DecodeStatus::NeedMoreData:
|
case DecodeStatus::NeedMoreData:
|
||||||
break;
|
break;
|
||||||
case DecodeStatus::Error:{
|
case DecodeStatus::Error: {
|
||||||
// consume old MMU FW's data if any -> avoid confusion of protocol decoder
|
// consume old MMU FW's data if any -> avoid confusion of protocol decoder
|
||||||
auto old = oldMMUh4x0r.Detect(c);
|
auto old = oldMMUh4x0r.Detect(c);
|
||||||
if( old == OldMMUFWDetector::State::Matched ){
|
if (old == OldMMUFWDetector::State::Matched) {
|
||||||
// Old MMU FW 1.0.6 detected. Firmwares are incompatible.
|
// Old MMU FW 1.0.6 detected. Firmwares are incompatible.
|
||||||
return VersionMismatch;
|
return VersionMismatch;
|
||||||
} else if( old == OldMMUFWDetector::State::MatchingPart ){
|
} else if (old == OldMMUFWDetector::State::MatchingPart) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +195,7 @@ void ProtocolLogic::SendMsg(RequestMsg rq) {
|
||||||
RecordUARTActivity();
|
RecordUARTActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolLogic::SendWriteMsg(RequestMsg rq){
|
void ProtocolLogic::SendWriteMsg(RequestMsg rq) {
|
||||||
uint8_t txbuff[Protocol::MaxRequestSize()];
|
uint8_t txbuff[Protocol::MaxRequestSize()];
|
||||||
uint8_t len = Protocol::EncodeWriteRequest(rq.value, rq.value2, txbuff);
|
uint8_t len = Protocol::EncodeWriteRequest(rq.value, rq.value2, txbuff);
|
||||||
uart->write(txbuff, len);
|
uart->write(txbuff, len);
|
||||||
|
|
@ -242,7 +242,7 @@ StepStatus ProtocolLogic::ProcessVersionResponse(uint8_t stage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StepStatus ProtocolLogic::ScopeStep() {
|
StepStatus ProtocolLogic::ScopeStep() {
|
||||||
if ( ! ExpectsResponse() ) {
|
if (!ExpectsResponse()) {
|
||||||
// we are waiting for something
|
// we are waiting for something
|
||||||
switch (currentScope) {
|
switch (currentScope) {
|
||||||
case Scope::DelayedRestart:
|
case Scope::DelayedRestart:
|
||||||
|
|
@ -296,7 +296,7 @@ StepStatus ProtocolLogic::StartSeqStep() {
|
||||||
}
|
}
|
||||||
return Processing;
|
return Processing;
|
||||||
case ScopeState::WritingInitRegisters:
|
case ScopeState::WritingInitRegisters:
|
||||||
if( ProcessWritingInitRegister() ){
|
if (ProcessWritingInitRegister()) {
|
||||||
SendAndUpdateFilamentSensor();
|
SendAndUpdateFilamentSensor();
|
||||||
}
|
}
|
||||||
return Processing;
|
return Processing;
|
||||||
|
|
@ -354,7 +354,7 @@ StepStatus ProtocolLogic::ProcessCommandQueryResponse() {
|
||||||
case ResponseMsgParamCodes::Finished:
|
case ResponseMsgParamCodes::Finished:
|
||||||
// We must check whether the "finished" is actually related to the command issued into the MMU
|
// We must check whether the "finished" is actually related to the command issued into the MMU
|
||||||
// It can also be an X0 F which means MMU just successfully restarted.
|
// It can also be an X0 F which means MMU just successfully restarted.
|
||||||
if( ReqMsg().code == rsp.request.code && ReqMsg().value == rsp.request.value ){
|
if (ReqMsg().code == rsp.request.code && ReqMsg().value == rsp.request.value) {
|
||||||
progressCode = ProgressCode::OK;
|
progressCode = ProgressCode::OK;
|
||||||
scopeState = ScopeState::Ready;
|
scopeState = ScopeState::Ready;
|
||||||
rq = RequestMsg(RequestMsgCodes::unknown, 0); // clear the successfully finished request
|
rq = RequestMsg(RequestMsgCodes::unknown, 0); // clear the successfully finished request
|
||||||
|
|
@ -449,7 +449,7 @@ StepStatus ProtocolLogic::IdleStep() {
|
||||||
StartReading8bitRegisters();
|
StartReading8bitRegisters();
|
||||||
return ButtonPushed;
|
return ButtonPushed;
|
||||||
case ResponseMsgParamCodes::Finished:
|
case ResponseMsgParamCodes::Finished:
|
||||||
if( ReqMsg().code != RequestMsgCodes::unknown ){
|
if (ReqMsg().code != RequestMsgCodes::unknown) {
|
||||||
// got reset while doing some other command - the originally issued command was interrupted!
|
// got reset while doing some other command - the originally issued command was interrupted!
|
||||||
// this must be solved by the upper layer, protocol logic doesn't have all the context (like unload before trying again)
|
// this must be solved by the upper layer, protocol logic doesn't have all the context (like unload before trying again)
|
||||||
IdleRestart();
|
IdleRestart();
|
||||||
|
|
@ -526,8 +526,7 @@ ProtocolLogic::ProtocolLogic(MMU2Serial *uart, uint8_t extraLoadDistance, uint8_
|
||||||
, lastFSensor((uint8_t)WhereIsFilament())
|
, lastFSensor((uint8_t)WhereIsFilament())
|
||||||
, regIndex(0)
|
, regIndex(0)
|
||||||
, retryAttempts(MAX_RETRIES)
|
, retryAttempts(MAX_RETRIES)
|
||||||
, inAutoRetry(false)
|
, inAutoRetry(false) {
|
||||||
{
|
|
||||||
// @@TODO currently, I don't see a way of writing the initialization better :(
|
// @@TODO currently, I don't see a way of writing the initialization better :(
|
||||||
// I'd like to write something like: initRegs8 { extraLoadDistance, pulleySlowFeedrate }
|
// I'd like to write something like: initRegs8 { extraLoadDistance, pulleySlowFeedrate }
|
||||||
// avr-gcc seems to like such a syntax, ARM gcc doesn't
|
// avr-gcc seems to like such a syntax, ARM gcc doesn't
|
||||||
|
|
@ -583,11 +582,11 @@ void ProtocolLogic::Home(uint8_t mode) {
|
||||||
PlanGenericRequest(RequestMsg(RequestMsgCodes::Home, mode));
|
PlanGenericRequest(RequestMsg(RequestMsgCodes::Home, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolLogic::ReadRegister(uint8_t address){
|
void ProtocolLogic::ReadRegister(uint8_t address) {
|
||||||
PlanGenericRequest(RequestMsg(RequestMsgCodes::Read, address));
|
PlanGenericRequest(RequestMsg(RequestMsgCodes::Read, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolLogic::WriteRegister(uint8_t address, uint16_t data){
|
void ProtocolLogic::WriteRegister(uint8_t address, uint16_t data) {
|
||||||
PlanGenericRequest(RequestMsg(RequestMsgCodes::Write, address, data));
|
PlanGenericRequest(RequestMsg(RequestMsgCodes::Write, address, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,23 +598,23 @@ void ProtocolLogic::PlanGenericRequest(RequestMsg rq) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtocolLogic::ActivatePlannedRequest() {
|
bool ProtocolLogic::ActivatePlannedRequest() {
|
||||||
switch(plannedRq.code){
|
switch (plannedRq.code) {
|
||||||
case RequestMsgCodes::Button:
|
case RequestMsgCodes::Button:
|
||||||
// only issue the button to the MMU and do not restart the state machines
|
// only issue the button to the MMU and do not restart the state machines
|
||||||
SendButton(plannedRq.value);
|
SendButton(plannedRq.value);
|
||||||
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
||||||
return true;
|
return true;
|
||||||
case RequestMsgCodes::Read:
|
case RequestMsgCodes::Read:
|
||||||
SendReadRegister(plannedRq.value, ScopeState::ReadRegisterSent );
|
SendReadRegister(plannedRq.value, ScopeState::ReadRegisterSent);
|
||||||
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
||||||
return true;
|
return true;
|
||||||
case RequestMsgCodes::Write:
|
case RequestMsgCodes::Write:
|
||||||
SendWriteRegister(plannedRq.value, plannedRq.value2, ScopeState::WriteRegisterSent );
|
SendWriteRegister(plannedRq.value, plannedRq.value2, ScopeState::WriteRegisterSent);
|
||||||
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
||||||
return true;
|
return true;
|
||||||
case RequestMsgCodes::unknown:
|
case RequestMsgCodes::unknown:
|
||||||
return false;
|
return false;
|
||||||
default:// commands
|
default: // commands
|
||||||
currentScope = Scope::Command;
|
currentScope = Scope::Command;
|
||||||
SetRequestMsg(plannedRq);
|
SetRequestMsg(plannedRq);
|
||||||
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
plannedRq = RequestMsg(RequestMsgCodes::unknown, 0);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
constexpr inline int strlen_constexpr(const char* str){
|
constexpr inline int strlen_constexpr(const char *str) {
|
||||||
return *str ? 1 + strlen_constexpr(str + 1) : 0;
|
return *str ? 1 + strlen_constexpr(str + 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue