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

LinuxInterface.h « Linux « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b28d88d26572e9951a086c459038d4c8d107254f (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
/*
 * LinuxInterface.h
 *
 *  Created on: 29 Mar 2019
 *      Authors: Christian
 */

#ifndef SRC_LINUX_LINUXINTERFACE_H_
#define SRC_LINUX_LINUXINTERFACE_H_

#include <RepRapFirmware.h>

#if HAS_LINUX_INTERFACE

#include "RTOSIface/RTOSIface.h"

#include "GCodes/GCodes.h"
#include "GCodes/GCodeChannel.h"
#include "GCodes/GCodeFileInfo.h"
#include "LinuxMessageFormats.h"
#include "DataTransfer.h"

class Platform;

class GCodeBuffer;

class OutputBuffer;
class OutputStack;

//#define TRACK_FILE_CODES			// Uncomment this to enable code <-> code reply tracking for the file G-code channel

// G-Code input class for an SPI channel
class LinuxInterface
{
public:
	LinuxInterface() noexcept;

	// The Init method must be called prior to calling any of the other methods. Use reprap.UsingLinuxInterface() to guard calls to other members.
	// OTOH, calling Init when we don't have a SBC connected may cause problems due to noise pickup on the SPI CS and clock inputs
	void Init() noexcept;
	void Spin() noexcept;														// Only called in standalone mode by the main loop
	[[noreturn]] void TaskLoop() noexcept;
	void Diagnostics(MessageType mtype) noexcept;
	bool IsConnected() const noexcept { return isConnected; }

	void EventOccurred(bool timeCritical = false) noexcept;						// Called when a new event has happened. It can optionally start off a new transfer immediately
	GCodeResult HandleM576(GCodeBuffer& gb, const StringRef& reply) noexcept;	// Set the SPI communication parameters

	bool HasPrintStarted();
	bool HasPrintStopped();
	StopPrintReason GetPrintStopReason() const { return printStopReason; }
	bool FillBuffer(GCodeBuffer &gb) noexcept;									// Try to fill up the G-code buffer with the next available G-code

	void SetPauseReason(FilePosition position, PrintPausedReason reason) noexcept;	// Notify Linux that the print has been paused

	void HandleGCodeReply(MessageType type, const char *reply) noexcept;		// accessed by Platform
	void HandleGCodeReply(MessageType type, OutputBuffer *buffer) noexcept;		// accessed by Platform

	bool GetFileChunk(const char *filename, uint32_t offset, char *buffer, uint32_t& bufferLength, uint32_t& fileLength) noexcept;

	bool FileExists(const char *filename) noexcept;
	bool DeleteFileOrDirectory(const char *fileOrDirectory) noexcept;

	FileHandle OpenFile(const char *filename, OpenMode mode, FilePosition& fileLength, uint32_t preAllocSize = 0) noexcept;
	int ReadFile(FileHandle handle, char *buffer, size_t bufferLength) noexcept;
	bool WriteFile(FileHandle handle, const char *buffer, size_t bufferLength) noexcept;
	bool SeekFile(FileHandle handle, FilePosition offset) noexcept;
	bool TruncateFile(FileHandle handle) noexcept;
	void CloseFile(FileHandle handle) noexcept;

private:
	DataTransfer transfer;
	bool isConnected;
	uint32_t numDisconnects, numTimeouts;

	uint32_t maxDelayBetweenTransfers, numMaxEvents;
	volatile bool delaying;
	volatile uint32_t numEvents;

	GCodeFileInfo fileInfo;
	FilePosition pauseFilePosition;
	PrintPausedReason pauseReason;
	bool reportPause, reportPauseWritten, printStarted, printStopped;
	StopPrintReason printStopReason;

	char *codeBuffer;
	volatile uint16_t rxPointer, txPointer, txEnd;
	volatile bool sendBufferUpdate;

	uint32_t iapWritePointer;
	uint32_t iapRamAvailable;											// must be at least 64Kb otherwise the SPI IAP can't work

	// Data needed when a CAN expansion board requests a firmware file chunk
	volatile bool waitingForFileChunk;
	bool fileChunkRequestSent;
	String<MaxFilenameLength> requestedFileName;
	uint32_t requestedFileOffset, requestedFileLength;
	BinarySemaphore requestedFileSemaphore;
	char *requestedFileBuffer;
	int32_t requestedFileDataLength;

	// File I/O
	Mutex fileMutex;													// locked while a file operation is performed
	BinarySemaphore fileSemaphore;										// resolved when the requested file operation has finished

	enum class FileOperation {
		none,
		checkFileExists,
		deleteFileOrDirectory,
		openRead,
		openWrite,
		openAppend,
		read,
		write,
		seek,
		truncate,
		close
	} fileOperation;
	bool fileOperationPending;

	const char *filePath;
	FileHandle fileHandle;
	bool fileSuccess;

	uint32_t filePreAllocSize;
	char *fileReadBuffer;
	const char *fileWriteBuffer;
	size_t fileBufferLength, numFileWriteRequests;
	FilePosition fileOffset;

	static volatile OutputStack gcodeReply;
	static Mutex gcodeReplyMutex;											// static so that the LinuxInterface is safe to delete even is the mutex is linked into the mutex chain or is in use

#ifdef TRACK_FILE_CODES
	volatile size_t fileCodesRead, fileCodesHandled, fileMacrosRunning, fileMacrosClosing;
#endif

	void InvalidateBufferChannel(GCodeChannel channel) noexcept;            // Invalidate every buffered G-code of the corresponding channel from the buffer ring
};

inline void LinuxInterface::SetPauseReason(FilePosition position, PrintPausedReason reason) noexcept
{
	TaskCriticalSectionLocker locker;
	pauseFilePosition = position;
	pauseReason = reason;
	reportPauseWritten = false;
	reportPause = true;
}

inline bool LinuxInterface::HasPrintStarted()
{
	TaskCriticalSectionLocker locker;
	if (printStarted)
	{
		printStarted = false;
		return true;
	}
	return false;
}

inline bool LinuxInterface::HasPrintStopped()
{
	TaskCriticalSectionLocker locker;
	if (printStopped)
	{
		printStopped = false;
		return true;
	}
	return false;
}

#endif

#endif