Prusa-MMU-Private
PrusaMultiMaterialUpgradev3firmwareforMK3SMK4
Prusa Multi Material Unit for the MKS3 and MK4

Introduction

This is the new firmware for the Multi Material Unit (MMU).

Motivation

The key motivation for developing a new firmware structure were as follows:

  • adding a possibility of reporting the MMU's state even during running commands - the architecture of the original MM-control-01 project didn't allow to achieve this requirement
  • while being able to report the internal state of the MMU, the printer should be able to describe the error states clearly on its LCD without leaving the user to rely on some blinking LEDs
  • modular design prepared for possible future upgrades

Project structure

  • cmake
  • lib
  • src
  • tests
  • utils

Firmware architecture

The whole firmware is composed of simple state machines which run all at once - it is a kind of simple cooperative multi-tasking while not eating up any significant resources by deploying generic task switching solutions like RTOS or similar. The general rule is to avoid waiting inside these state machines, no state machine is allowed to block execution of others. That implies making separate waiting states which only check for some condition to be true before proceeding further.

The firmware is separated into 4 layers:

  • HAL is responsible for talking to the physical hardware, in our case an AVR processor and its peripherals, TMC2130 stepper drivers, shift registers etc.
  • modules are the components abstracted of the real hardware and/or connection. A typical example are the buttons, LEDs, Idler, Selector etc.
  • logic layer is the application logic - this layer provides the sequences and logical relations between modules thus forming the behavior of the MMU.
  • main is the top layer, it is responsible for initialization of the whole firmware and performing the main loop, where the stepping of all the automata is located.

The whole architecture becomes obvious from the following picture:

dot_inline_dotgraph_1.png

Sidenote: due to avr-gcc 5.4 limitations we cannot use proper Singleton patterns but have to rely on global variables of each state machine.

Protocol description

The communication protocol between the printer and the MMU has only been extended to minimize the influence on existing MMU interface implementation. However, the backwards compatibility has not been kept and at least some changes are necessary. The good news is that the Slicer's MMU code is fully backwards compatible.

Error sources and handling

There are several different types/sources of errors in the MMU:

  • runtime sensors
  • algorithmic errors
  • hardware component failures

For a list of currently supported error states please see error_codes.h .

Runtime sensors

Errors like this are abnormal operational states resulting from the fact, that some of the sensors didn't report an expected state. E.g. FINDA didn't trigger or the printer didn't send a trigger command from its filament sensor. These failures cannot be predicted and can be only resolved partially by the MMU.

The logic layer state machines check for these failures and act upon:

  • Cut filament: detects FINDA_DIDNT_SWITCH_OFF, FINDA_DIDNT_SWITCH_ON
  • Eject filament: detects FINDA_DIDNT_SWITCH_OFF, FINDA_DIDNT_SWITCH_ON
  • Load filament: detects FINDA_DIDNT_SWITCH_ON, FSENSOR_DIDNT_SWITCH_ON
  • Tool change: detects FINDA_DIDNT_SWITCH_OFF/FINDA_DIDNT_SWITCH_ON, FSENSOR_DIDNT_SWITCH_OFF/FSENSOR_DIDNT_SWITCH_ON
  • Load filament: detects FINDA_DIDNT_SWITCH_OFF, FSENSOR_DIDNT_SWITCH_OFF

Algorithmic errors

This kind of errors represents unhandled states of state machines - which should not happen ;) or at least the ocurrance can be mitigated by careful testing of the firmware code base. Logic layer state machines check their internal state and if they by chance get into an unhandled state, they switch into an error state INTERNAL.

Hardware failures

This kind of errors is extremely hard to tackle in full scale. Basically any HW component can fail (including the HW chips on the mainboard) and we only have limited knowledge about such situations. So under hardware failures we consider only stuff which can be detected by any means

  • mostly CPU peripherals, especially the TMC2130 drivers, which are capable of some degree of error reporting.

Error reporting

There are basically 2 ways of reporting an error to the user

  • via USART communication with the printer - implies the communication works - the preferred way
  • LEDs blinking - implies the shift registers work and the LEDs work as well - backup way

The USART communication can report errors of the currently running command (see response to Q0).

LEDs' blinking is to be defined yet, the previous firmware used elaborate blinking schemes to report all kinds of errors which most users were unable to decipher/act upon.

Tests and quality assurance

Unit tests

The firmware architecture was designed with unit testing in mind, thus each firmware layer has only the least amount of necessary dependencies to surrounding code. This approach greatly simplified the definition of unit testing procedures with only a small amount stubs necessary.

Each firmware layer has its own subdirectory, the directory tree follows the firmware structure

The usage of stubs at each layer

Integration tests

Powering up the board

Upon startup, the board tries to initialize all the necessary peripherals. The progress of initialization is visualized by individual LEDs turning green. That includes:

  • LED 4: shift register - however if the shift register doesn't work we really can't signalize anything, only internal variables will be accessible if the UART works.
  • LED 3: USART - if both shift register and the UART are dead, we are sitting ducks :(
  • LED 2: SPI
  • LED 1: TMC2130 - this may actually report some error
  • LED 0: ADC

Ideally, the board has all the green LEDs on after startup - that signalizes all the peripherals started correctly.