1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
/*
* GCodeMachineState.h
*
* Created on: 15 Nov 2016
* Author: David
*/
#ifndef SRC_GCODES_GCODEMACHINESTATE_H_
#define SRC_GCODES_GCODEMACHINESTATE_H_
#include <RepRapFirmware.h>
#include <Storage/FileData.h>
#include <General/FreelistManager.h>
#include <General/NamedEnum.h>
#include <GCodes/GCodeResult.h>
// Enumeration to list all the possible states that the Gcode processing machine may be in
enum class GCodeState : uint8_t
{
normal, // not doing anything and ready to process a new GCode
waitingForSpecialMoveToComplete, // doing a special move, so we must wait for it to finish before processing another GCode
waitingForSegmentedMoveToGo, // doing an arc move, so we must check whether it completes normally
probingToolOffset,
findCenterOfCavityMin,
findCenterOfCavityR,
findCenterOfCavityMax,
homing1,
homing2,
// These next 5 must be contiguous
toolChange0,
toolChange1,
toolChange2,
toolChange3,
toolChangeComplete,
// These next 6 must be contiguous
m109ToolChange0,
m109ToolChange1,
m109ToolChange2,
m109ToolChange3,
m109ToolChangeComplete,
m109WaitForTemperature,
pausing1,
pausing2,
filamentChangePause1,
filamentChangePause2,
filamentErrorPause1,
filamentErrorPause2,
resuming1,
resuming2,
resuming3,
flashing1,
flashing2,
stoppingWithHeatersOff,
stoppingWithHeatersOn,
// These next 9 must be contiguous
gridProbing1,
gridProbing2a,
gridProbing2b,
gridProbing3,
gridProbing4,
gridProbing4a,
gridProbing5,
gridProbing6,
gridProbing7,
// These next 10 must be contiguous
probingAtPoint0,
probingAtPoint1,
probingAtPoint2a,
probingAtPoint2b,
probingAtPoint3,
probingAtPoint4,
probingAtPoint4a,
probingAtPoint5,
probingAtPoint6,
probingAtPoint7,
// These next 4 must be contiguous
straightProbe0,
straightProbe1,
straightProbe2,
straightProbe3,
doingFirmwareRetraction,
doingFirmwareUnRetraction,
loadingFilament,
unloadingFilament,
checkError, // go to this state after doing a macro when we need to check for a stored error message
#if HAS_MASS_STORAGE
timingSDwrite,
timingSDread,
#endif
#if HAS_LINUX_INTERFACE
waitingForAcknowledgement,
#endif
#if HAS_VOLTAGE_MONITOR
powerFailPausing1
#endif
};
// Other firmware that we might switch to be compatible with. The ordering is as for M555 starting with 0.
NamedEnum(Compatibility, uint8_t, Default, RepRapFirmware, Marlin, Teacup, Sprinter, Repetier, NanoDLP);
// Type of the block we are in when processing conditional GCode
enum class BlockType : uint8_t
{
plain, // a normal block
ifTrue, // the block immediately after 'if' when the condition was true, or after 'elif' when the condition was true and previous conditions were false
ifFalseNoneTrue, // the block immediately after 'if' when the condition was false, or after 'elif' when all conditions so far were false
ifFalseHadTrue, // the block immediately after 'elif' when we have already seem a true condition
loop // block inside a 'while' command
};
// Class to hold the state of gcode execution for some input source
class GCodeMachineState
{
public:
typedef Bitmap<uint32_t> ResourceBitmap;
// Class to record the state of blocks when using conditional GCode
class BlockState
{
public:
BlockType GetType() const noexcept { return blockType; }
uint32_t GetIterations() const noexcept { return iterationsDone; }
uint32_t GetLineNumber() const noexcept { return lineNumber; }
FilePosition GetFilePosition() const noexcept { return fpos; }
uint16_t GetIndent() const noexcept { return indentLevel; }
void SetLoopBlock(FilePosition filePos, uint32_t lineNum) noexcept { blockType = BlockType::loop; fpos = filePos; lineNumber = lineNum; iterationsDone = 0; }
void SetPlainBlock() noexcept { blockType = BlockType::plain; iterationsDone = 0; }
void SetPlainBlock(uint16_t p_indentLevel) noexcept { blockType = BlockType::plain; iterationsDone = 0; indentLevel = p_indentLevel; }
void SetIfTrueBlock() noexcept { blockType = BlockType::ifTrue; iterationsDone = 0; }
void SetIfFalseNoneTrueBlock() noexcept { blockType = BlockType::ifFalseNoneTrue; iterationsDone = 0; }
void SetIfFalseHadTrueBlock() noexcept { blockType = BlockType::ifFalseHadTrue; iterationsDone = 0; }
void IncrementIterations() noexcept { ++iterationsDone; }
private:
FilePosition fpos; // the file offset at which the current block started
uint32_t lineNumber; // the line number at which the current block started
uint32_t iterationsDone;
uint16_t indentLevel; // the indentation of this block
BlockType blockType; // the type of this block
};
void* operator new(size_t sz) noexcept { return FreelistManager::Allocate<GCodeMachineState>(); }
void operator delete(void* p) noexcept { FreelistManager::Release<GCodeMachineState>(p); }
GCodeMachineState() noexcept;
GCodeMachineState(GCodeMachineState&, bool withinSameFile) noexcept; // this chains the new one to the previous one
GCodeMachineState(const GCodeMachineState&) = delete; // copying these would be a bad idea
~GCodeMachineState() noexcept;
GCodeState GetState() const noexcept { return state; }
void SetState(GCodeState newState) noexcept;
inline void AdvanceState() noexcept { state = static_cast<GCodeState>(static_cast<uint8_t>(state) + 1); }
GCodeMachineState *GetPrevious() const noexcept { return previous; }
float feedRate;
#if HAS_MASS_STORAGE
FileData fileState;
#endif
#if HAS_LINUX_INTERFACE
uint32_t fileId; // virtual file ID to deal with stack push/pops when a file is being cancelled or finished in the wrong stack level
#endif
ResourceBitmap lockedResources;
BlockState blockStates[MaxBlockIndent];
uint32_t lineNumber;
uint32_t
drivesRelative : 1,
axesRelative : 1,
#if HAS_LINUX_INTERFACE
lastCodeFromSbc : 1,
isMacroFromCode : 1,
isFileFinished : 1,
fileError: 1,
#endif
doingFileMacro : 1,
waitWhileCooling : 1,
runningM501 : 1,
runningM502 : 1,
volumetricExtrusion : 1,
g53Active : 1, // true if seen G53 on this line of GCode
runningSystemMacro : 1, // true if running a system macro file
usingInches : 1, // true if units are inches not mm
waitingForAcknowledgement : 1,
#if HAS_LINUX_INTERFACE
waitingForAcknowledgementSent : 1,
#endif
messageAcknowledged : 1,
messageCancelled : 1;
Compatibility compatibility;
uint8_t blockNesting;
uint16_t stateParameter; // a parameter, the meaning of which depends on what state we are in
bool DoingFile() const noexcept;
void CloseFile() noexcept;
void WaitForAcknowledgement() noexcept;
#if HAS_LINUX_INTERFACE
void SetFileExecuting() noexcept;
#endif
bool UsingMachineCoordinates() const noexcept { return g53Active || runningSystemMacro; }
// Set the error message and associated state
void SetError(const char *msg) noexcept;
void SetWarning(const char *msg) noexcept;
void RetrieveStateMachineResult(GCodeResult& rslt, const StringRef& reply) const noexcept;
// Copy values that may have been altered into this state record
// Called after running config.g and after running resurrect.g
void CopyStateFrom(const GCodeMachineState& other) noexcept;
BlockState& CurrentBlockState() noexcept;
const BlockState& CurrentBlockState() const noexcept;
int32_t GetIterations() const noexcept;
uint16_t CurrentBlockIndent() const noexcept { return CurrentBlockState().GetIndent(); }
bool CreateBlock(uint16_t indentLevel) noexcept;
void EndBlock() noexcept;
private:
GCodeMachineState *previous;
const char *errorMessage;
GCodeState state;
GCodeResult stateMachineResult; // the worst status (ok, warning or error) that we encountered while running the state machine
};
#endif /* SRC_GCODES_GCODEMACHINESTATE_H_ */
|