PFW-1530 Add Tune to Selector screen and more

- Rename "Idler" to "Sensitivity"
- Implement ReadRegisterInner() as a way to read register in blocking contexts such as manage_response()
This allows us to show the current EEPROM value on the printer's LCD
This commit is contained in:
Guðni Már Gilbert 2023-08-05 15:39:18 +00:00 committed by DRracer
parent 9e4fd08031
commit 1cda696e14
5 changed files with 84 additions and 11 deletions

View File

@ -80,6 +80,7 @@ void MMU2::StopKeepPowered() {
void MMU2::Tune() {
switch (lastErrorCode) {
case ErrorCode::HOMING_SELECTOR_FAILED:
case ErrorCode::HOMING_IDLER_FAILED:
{
// Prompt a menu for different values
@ -147,6 +148,29 @@ bool MMU2::ReadRegister(uint8_t address) {
logic.ReadRegister(address); // we may signal the accepted/rejected status of the response as return value of this function
} while (!manage_response(false, false));
// Update cached value
lastReadRegisterValue = logic.rsp.paramValue;
return true;
}
bool MMU2::ReadRegisterInner(uint8_t address) {
if (!WaitForMMUReady())
return false;
// Plan a request for the register value at address
logic.ReadRegister(address);
do {
// Maintain MMU communications
marlin_manage_inactivity(true);
mmu_loop_inner(false);
} while (
logicStepLastStatus != StepStatus::Finished
&& logic.rsp.request.value == address // If the MMU protocol is busy decoding another request, we must wait
);
// Update cached value
lastReadRegisterValue = logic.rsp.paramValue;
return true;
}

View File

@ -88,6 +88,12 @@ public:
/// @returns true upon success
bool ReadRegister(uint8_t address);
/// Variant of ReadRegister which runs in blocking context such as manage_response()
/// Be careful of using this as it is not recursion protected!
/// @param address Address of register in hexidecimal
/// @return true upon success
bool ReadRegisterInner(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
@ -194,6 +200,12 @@ public:
inline void IncrementTMCFailures() { ++tmcFailures; }
inline void ClearTMCFailures() { tmcFailures = 0; }
/// Retrieve cached value parsed from ReadRegister()
/// or using M707
inline uint16_t GetLastReadRegisterValue() const {
return lastReadRegisterValue;
};
private:
/// Perform software self-reset of the MMU (sends an X0 command)
void ResetX0();
@ -301,6 +313,7 @@ private:
ErrorCode lastErrorCode = ErrorCode::MMU_NOT_RESPONDING;
ErrorSource lastErrorSource = ErrorSource::ErrorSourceNone;
Buttons lastButton = Buttons::NoButton;
uint16_t lastReadRegisterValue = 0;
StepStatus logicStepLastStatus;

View File

@ -380,7 +380,7 @@ static const uint8_t errorButtons[] PROGMEM = {
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//FSENSOR_TOO_EARLY
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//INSPECT_FINDA
Btns(ButtonOperations::Continue, ButtonOperations::NoOperation),//LOAD_TO_EXTRUDER_FAILED
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_HOME
Btns(ButtonOperations::Retry, ButtonOperations::Tune),//SELECTOR_CANNOT_HOME
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_MOVE
Btns(ButtonOperations::Retry, ButtonOperations::Tune),//IDLER_CANNOT_HOME
Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_MOVE

View File

@ -205,7 +205,6 @@ Buttons ButtonAvailable(uint16_t ec) {
case ERR_MECHANICAL_FSENSOR_FILAMENT_STUCK:
case ERR_MECHANICAL_FSENSOR_TOO_EARLY:
case ERR_MECHANICAL_INSPECT_FINDA:
case ERR_MECHANICAL_SELECTOR_CANNOT_HOME:
case ERR_MECHANICAL_SELECTOR_CANNOT_MOVE:
case ERR_MECHANICAL_IDLER_CANNOT_MOVE:
case ERR_MECHANICAL_PULLEY_CANNOT_MOVE:
@ -218,6 +217,7 @@ Buttons ButtonAvailable(uint16_t ec) {
break;
}
break;
case ERR_MECHANICAL_SELECTOR_CANNOT_HOME:
case ERR_MECHANICAL_IDLER_CANNOT_HOME:
switch (buttonSelectedOperation) {
// may be allow move selector right and left in the future

View File

@ -1,3 +1,4 @@
#include <avr/pgmspace.h>
#include "mmu2.h"
#include "mmu2_log.h"
#include "mmu2_reporting.h"
@ -360,24 +361,59 @@ void ScreenClear(){
lcd_clear();
}
// These are global while testing this concept
uint8_t stallGuardValue = 6; // default
bool tuningDone = false;
struct TuneItem {
uint8_t address;
uint8_t minValue;
uint8_t maxValue;
} __attribute__((packed));
static const TuneItem TuneItems[] PROGMEM = {
{ (uint8_t)Register::Selector_sg_thrs_R, 1, 4},
{ (uint8_t)Register::Idler_sg_thrs_R, 4, 7},
};
static_assert(sizeof(TuneItems)/sizeof(TuneItem) == 2);
typedef struct
{
menu_data_edit_t reserved; //13 bytes reserved for number editing functions
int8_t status; // 1 byte
uint8_t currentValue; // 1 byte
TuneItem item; // 3 bytes
} _menu_tune_data_t;
static_assert(sizeof(_menu_tune_data_t) == 18);
static_assert(sizeof(menu_data)>= sizeof(_menu_tune_data_t),"_menu_tune_data_t doesn't fit into menu_data");
void tuneIdlerStallguardThresholdMenu() {
constexpr uint8_t maxStallguardThreshold = 7;
constexpr uint8_t minStallguardThreshold = 4;
static constexpr _menu_tune_data_t * const _md = (_menu_tune_data_t*)&(menu_data[0]);
if (_md->status == 0)
{
_md->status = 1; // Menu entered for the first time
lcd_timeoutToStatus.stop(); // Do not timeout the screen
// Fetch the TuneItem from PROGMEM
const uint8_t offset = (mmu2.MMUCurrentErrorCode() == ErrorCode::HOMING_IDLER_FAILED) ? 1 : 0;
memcpy_P(&(_md->item), &TuneItems[offset], sizeof(TuneItem));
// Fetch the value which is currently in MMU EEPROM
mmu2.ReadRegisterInner((uint8_t)_md->item.address);
_md->currentValue = mmu2.GetLastReadRegisterValue();
}
MENU_BEGIN();
ON_MENU_LEAVE(
tuningDone = true;
mmu2.WriteRegister(0x19, (uint16_t)stallGuardValue);
mmu2.WriteRegister(_md->item.address, (uint16_t)_md->currentValue);
);
MENU_ITEM_BACK_P(_i("Done"));
MENU_ITEM_EDIT_int3_P(
_i("Idler"),
&stallGuardValue,
minStallguardThreshold,
maxStallguardThreshold
_i("Sensitivity"),
&_md->currentValue,
_md->item.minValue,
_md->item.maxValue
);
MENU_END();
}