Welcome to mirror list, hosted at ThFree Co, Russian Federation.

GCodeMachineState.h « GCodes « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c5ec5bbb9d2aed056acb51199629be41bc8b99af (plain)
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
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 * 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 <ObjectModel/Variable.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

	abortWhenMovementFinished,							// abort the print when all current moves have completed

	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

	// This group must be contiguous
	probingToolOffset1,
	probingToolOffset2,
	probingToolOffset3,
	probingToolOffset4,

	// These next 7 must be contiguous
	findCenterOfCavity1,
	findCenterOfCavity2,
	findCenterOfCavity3,
	findCenterOfCavity4,
	findCenterOfCavity5,
	findCenterOfCavity6,

	homing1,
	homing2,

	// These next 5 must be contiguous
	toolChange0,
	toolChange1,
	toolChange2,
	toolChangeComplete,

	// These next 6 must be contiguous
	m109ToolChange0,
	m109ToolChange1,
	m109ToolChange2,
	m109ToolChangeComplete,
	m109WaitForTemperature,

	pausing1,
	pausing2,

	filamentChangePause1,
	filamentChangePause2,

	filamentErrorPause1,
	filamentErrorPause2,

	resuming1,
	resuming2,
	resuming3,

	cancelling,

	flashing1,
	flashing2,

	stopping,

	// 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
	processingEvent,
	finishedProcessingEvent,

#if HAS_MASS_STORAGE
	timingSDwrite,
	timingSDread,
#endif

#if HAS_SBC_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
};

#if HAS_SBC_INTERFACE
typedef uint8_t FileId;

constexpr FileId NoFileId = 0;
#endif

// 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; }
	GCodeMachineState *Pop() const noexcept;
	uint8_t GetBlockNesting() const noexcept { return blockNesting; }

	void SetMacroRestartable(bool b) noexcept { macroRestartable = b; }
	bool CanRestartMacro() const noexcept;

	VariableSet variables;											// local variables and parameters
	float feedRate;
#if HAS_MASS_STORAGE || HAS_EMBEDDED_FILES
	FileData fileState;
#endif
#if HAS_SBC_INTERFACE
	FileId fileId;													// virtual ID to distinguish files in different stack levels (only unique per GB)
#endif
	ResourceBitmap lockedResources;
	BlockState blockStates[MaxBlockIndent];
	uint32_t lineNumber;

	uint32_t
		selectedPlane : 2,
		drivesRelative : 1,
		axesRelative : 1,
		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,
		messageAcknowledged : 1,
		messageCancelled : 1,
		localPush : 1,							// true if this stack frame was created by M120, so we use the parent variables
		macroRestartable : 1,					// true if the current macro has used M98 R1 to say that it can be interrupted and restarted
		firstCommandAfterRestart : 1,			// true if this is the first command after restarting a macro that was interrupted
		commandRepeated : 1						// true if the current command is being repeated because it returned GCodeResult::notFinished the first time
#if HAS_SBC_INTERFACE
		, lastCodeFromSbc : 1,
		macroStartedByCode : 1,
		fileFinished : 1
#endif
		;

	Compatibility compatibility;
	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_SBC_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;

	bool CreateBlock(uint16_t indentLevel) noexcept;
	void EndBlock() noexcept;

private:
	GCodeMachineState *previous;
	const char *errorMessage;
	uint8_t blockNesting;
	GCodeState state;
	GCodeResult stateMachineResult;				// the worst status (ok, warning or error) that we encountered while running the state machine
};

#endif /* SRC_GCODES_GCODEMACHINESTATE_H_ */