123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- #pragma once
- #include <stdint.h>
- template<typename T, uint8_t N>
- class array {
- T data[N];
- public:
- array() = default;
- inline constexpr T* begin()const { return data; }
- inline constexpr T* end()const { return data + N; }
- constexpr uint8_t size()const { return N; }
- inline T &operator[](uint8_t i){
- return data[i];
- }
- };
- #include "mmu2/error_codes.h"
- #include "mmu2/progress_codes.h"
- #include "mmu2_protocol.h"
- #include "mmu2_serial.h"
- namespace MMU2 {
- using namespace modules::protocol;
- class ProtocolLogic;
- enum StepStatus : uint_fast8_t {
- Processing = 0,
- MessageReady,
- Finished,
- CommunicationTimeout,
- ProtocolError,
- CommandRejected,
- CommandError,
- VersionMismatch,
- CommunicationRecovered,
- };
- static constexpr uint32_t linkLayerTimeout = 2000;
- static constexpr uint32_t dataLayerTimeout = linkLayerTimeout * 3;
- static constexpr uint32_t heartBeatPeriod = linkLayerTimeout / 2;
- static_assert( heartBeatPeriod < linkLayerTimeout && linkLayerTimeout < dataLayerTimeout, "Incorrect ordering of timeouts");
- class ProtocolLogicPartBase {
- public:
- inline ProtocolLogicPartBase(ProtocolLogic *logic)
- : logic(logic)
- , state(State::Ready) {}
-
- virtual void Restart() = 0;
-
-
- virtual StepStatus Step() = 0;
-
-
- bool ExpectsResponse()const { return state != State::Ready && state != State::Wait; }
- protected:
- ProtocolLogic *logic;
- friend class ProtocolLogic;
-
-
-
- enum class State : uint_fast8_t {
- Ready,
- Wait,
- S0Sent,
- S1Sent,
- S2Sent,
- QuerySent,
- CommandSent,
- FilamentSensorStateSent,
- FINDAReqSent,
- ButtonSent,
- ContinueFromIdle
- };
- State state;
-
-
-
- StepStatus ProcessFINDAReqSent(StepStatus finishedRV, State nextState);
-
-
-
-
- void CheckAndReportAsyncEvents();
-
- void SendQuery();
-
- void SendFINDAQuery();
-
- void SendAndUpdateFilamentSensor();
- void SendButton(uint8_t btn);
- };
- class StartSeq : public ProtocolLogicPartBase {
- public:
- inline StartSeq(ProtocolLogic *logic)
- : ProtocolLogicPartBase(logic) {}
- void Restart() override;
- StepStatus Step() override;
- };
- class Command : public ProtocolLogicPartBase {
- public:
- inline Command(ProtocolLogic *logic)
- : ProtocolLogicPartBase(logic)
- , rq(RequestMsgCodes::unknown, 0) {}
- void Restart() override;
- StepStatus Step() override;
- inline void SetRequestMsg(RequestMsg msg) {
- rq = msg;
- }
- void ContinueFromIdle(){
- state = State::ContinueFromIdle;
- }
- inline const RequestMsg &ReqMsg()const { return rq; }
- private:
- RequestMsg rq;
- };
- class Idle : public ProtocolLogicPartBase {
- public:
- inline Idle(ProtocolLogic *logic)
- : ProtocolLogicPartBase(logic) {}
- void Restart() override;
- StepStatus Step() override;
- };
- class Stopped : public ProtocolLogicPartBase {
- public:
- inline Stopped(ProtocolLogic *logic)
- : ProtocolLogicPartBase(logic) {}
- void Restart() override {}
- StepStatus Step() override { return Processing; }
- };
- class DropOutFilter {
- StepStatus cause;
- uint8_t occurrences;
- public:
- static constexpr uint8_t maxOccurrences = 10;
- static_assert (maxOccurrences > 1, "we should really silently ignore at least 1 comm drop out if recovered immediately afterwards");
- DropOutFilter() = default;
-
-
- bool Record(StepStatus ss);
-
-
- inline StepStatus InitialCause()const { return cause; }
-
-
- inline void Reset(){ occurrences = maxOccurrences; }
- };
- class ProtocolLogic {
- public:
- ProtocolLogic(MMU2Serial *uart);
-
- void Start();
-
- void Stop();
-
- void ToolChange(uint8_t slot);
- void UnloadFilament();
- void LoadFilament(uint8_t slot);
- void EjectFilament(uint8_t slot);
- void CutFilament(uint8_t slot);
- void ResetMMU();
- void Button(uint8_t index);
- void Home(uint8_t mode);
-
- StepStatus Step();
-
- ErrorCode Error() const { return errorCode; }
-
- ProgressCode Progress() const { return progressCode; }
-
- uint8_t CommandInProgress()const;
-
- inline bool Running()const {
- return state == State::Running;
- }
-
- inline bool FindaPressed() const {
- return findaPressed;
- }
- #ifndef UNITTEST
- private:
- #endif
-
- StepStatus ProcessUARTByte(uint8_t c);
- StepStatus ExpectingMessage(uint32_t timeout);
- void SendMsg(RequestMsg rq);
- void SwitchToIdle();
- void HandleCommunicationTimeout();
- StepStatus HandleCommError(const char *msg, StepStatus ss);
- bool Elapsed(uint32_t timeout) const;
- void RecordUARTActivity();
- void RecordReceivedByte(uint8_t c);
- void FormatLastReceivedBytes(char *dst);
- void FormatLastResponseMsgAndClearLRB(char *dst);
- void LogRequestMsg(const uint8_t *txbuff, uint8_t size);
- void LogError(const char *reason);
- void LogResponse();
- void SwitchFromIdleToCommand();
-
- enum class State : uint_fast8_t {
- Stopped,
- InitSequence,
- Running
- };
-
- Stopped stopped;
- StartSeq startSeq;
- Idle idle;
- Command command;
- ProtocolLogicPartBase *currentState;
-
-
-
-
-
-
-
-
-
-
-
- RequestMsg plannedRq;
-
- void PlanGenericRequest(RequestMsg rq);
-
- bool ActivatePlannedRequest();
- uint32_t lastUARTActivityMs;
- DropOutFilter dataTO;
- ResponseMsg rsp;
- State state;
- Protocol protocol;
-
- array<uint8_t, 16> lastReceivedBytes;
- uint8_t lrb;
- MMU2Serial *uart;
- ErrorCode errorCode;
- ProgressCode progressCode;
- uint8_t lastFSensor;
-
- bool findaPressed;
-
- friend class ProtocolLogicPartBase;
- friend class Stopped;
- friend class Command;
- friend class Idle;
- friend class StartSeq;
- friend class MMU2;
- };
- }
|