diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3b35e8529..e6cd140a3 100644 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -9850,6 +9850,10 @@ void save_statistics(unsigned long _total_filament_used, unsigned long _total_pr total_filament_used = 0; + if (MMU2::mmu2.Enabled()) + { + MMU2::mmu2.update_tool_change_counter_eeprom(); + } } float calculate_extruder_multiplier(float diameter) { diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index 09e4ee35c..e26f8b72f 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -118,6 +118,7 @@ MMU2::MMU2() , loadingToNozzle(false) , inAutoRetry(false) , retryAttempts(MAX_RETRIES) + , toolchange_counter(0) { } @@ -301,10 +302,11 @@ void MMU2::DecrementRetryAttempts(){ } } -void MMU2::increment_tool_change_counter() +void MMU2::update_tool_change_counter_eeprom() { uint32_t toolchanges = eeprom_read_dword((uint32_t*)EEPROM_TOTAL_TOOLCHANGE_COUNT); - eeprom_write_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT, ++toolchanges); + eeprom_update_dword((uint32_t *)EEPROM_TOTAL_TOOLCHANGE_COUNT, toolchanges + (uint32_t)read_toolchange_counter()); + reset_toolchange_counter(); } bool MMU2::tool_change(uint8_t index) { diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index a4af76d02..c931445ef 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -182,7 +182,7 @@ public: bool is_mmu_error_monitor_active; /// Method to read-only mmu_print_saved - bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; } + inline bool MMU_PRINT_SAVED() const { return mmu_print_saved != SavedState::None; } /// Automagically "press" a Retry button if we have any retry attempts left /// @param ec ErrorCode enum value @@ -193,9 +193,19 @@ public: // Called by the MMU protocol when a sent button is acknowledged. void DecrementRetryAttempts(); -private: /// increments tool change counter in EEPROM - void increment_tool_change_counter(); + /// ATmega2560 EEPROM has only 100'000 write/erase cycles + /// so we can't call this function on every tool change. + void update_tool_change_counter_eeprom(); + + /// @return count for toolchange in current print + inline uint16_t read_toolchange_counter() const { return toolchange_counter; }; + + inline void reset_toolchange_counter() { toolchange_counter = 0; }; + +private: + // Increment the toolchange counter via SRAM to reserve EEPROM write cycles + inline void increment_tool_change_counter() { ++toolchange_counter; }; /// Reset the retryAttempts back to the default value void ResetRetryAttempts(); @@ -291,6 +301,7 @@ private: bool inAutoRetry; uint8_t retryAttempts; + uint16_t toolchange_counter; }; /// following Marlin's way of doing stuff - one and only instance of MMU implementation in the code base