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
|
/*
* FilamentMonitor.h
*
* Created on: 20 Jul 2017
* Author: David
*/
#ifndef SRC_FILAMENTSENSORS_FILAMENTMONITOR_H_
#define SRC_FILAMENTSENSORS_FILAMENTMONITOR_H_
#include <RepRapFirmware.h>
#include <Hardware/IoPorts.h>
#include <ObjectModel/ObjectModel.h>
#include <RTOSIface/RTOSIface.h>
#include <RRF3Common.h>
#if SUPPORT_CAN_EXPANSION
struct CanMessageFilamentMonitorsStatus;
#endif
#if SUPPORT_REMOTE_COMMANDS
struct CanMessageCreateFilamentMonitor;
struct CanMessageDeleteFilamentMonitor;
struct CanMessageGeneric;
class CanMessageGenericParser;
#endif
class FilamentMonitor INHERIT_OBJECT_MODEL
{
public:
FilamentMonitor(const FilamentMonitor&) = delete;
// Configure this sensor, returning true if error and setting 'seen' if we processed any configuration parameters
virtual GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, bool& seen) THROWS(GCodeException) = 0;
#if SUPPORT_REMOTE_COMMANDS
// Configure this sensor, returning an error code and setting 'seen' if we processed any configuration parameters
virtual GCodeResult Configure(const CanMessageGenericParser& parser, const StringRef& reply) noexcept = 0;
#endif
// Call the following at intervals to check the status. This is only called when extrusion is in progress or imminent.
// 'filamentConsumed' is the net amount of extrusion since the last call to this function.
virtual FilamentSensorStatus Check(bool isPrinting, bool fromIsr, uint32_t isrMillis, float filamentConsumed) noexcept = 0;
// Clear the measurement state - called when we are not printing a file. Return the present/not present status if available.
virtual FilamentSensorStatus Clear() noexcept = 0;
// Print diagnostic info for this sensor
virtual void Diagnostics(MessageType mtype, unsigned int extruder) noexcept = 0;
// ISR for when the pin state changes. It should return true if the ISR wants the commanded extrusion to be fetched.
virtual bool Interrupt() noexcept = 0;
// Call this to disable the interrupt before deleting a filament monitor
virtual void Disable() noexcept;
// Override the virtual destructor if your derived class allocates any dynamic memory
virtual ~FilamentMonitor() noexcept;
// Return the type of this sensor
unsigned int GetType() const noexcept { return type; }
// Check that this monitor still refers to a valid extruder
bool IsValid(size_t extruderNumber) const noexcept;
// Get the status of the filament monitor as a string
const char *GetStatusText() const noexcept { return lastStatus.ToString(); }
// Static initialisation
static void InitStatic() noexcept;
// Poll the filament sensors
static void Spin() noexcept;
// Check the drive assignments. Called when M584 may have been used to remap extruder drives. Return true if we need to output the warning appended to 'reply'.
static bool CheckDriveAssignments(const StringRef& reply) noexcept;
// Close down the filament monitors, in particular stop them generating interrupts. Called when we are about to update firmware.
static void Exit() noexcept;
// Handle M591
static GCodeResult Configure(GCodeBuffer& gb, const StringRef& reply, unsigned int extruder) THROWS(GCodeException)
pre(extruder < MaxExtruders; extruder < reprap.GetGCodes().GetNumExtruders());
// Send diagnostics info
static void Diagnostics(MessageType mtype) noexcept;
#if SUPPORT_OBJECT_MODEL
// Get the number of monitors to report in the OM
static size_t GetNumMonitorsToReport() noexcept;
// Get access to a filament monitor when we already have a read lock
static FilamentMonitor *GetMonitorAlreadyLocked(size_t extruder) noexcept { return filamentSensors[extruder]; }
#endif
#if SUPPORT_CAN_EXPANSION
static void UpdateRemoteFilamentStatus(CanAddress src, CanMessageFilamentMonitorsStatus& msg) noexcept;
#endif
#if SUPPORT_REMOTE_COMMANDS
// Create a new filament monitor, or replace an existing one
static GCodeResult Create(const CanMessageCreateFilamentMonitor& msg, const StringRef& reply) noexcept;
// Delete a filament monitor
static GCodeResult Delete(const CanMessageDeleteFilamentMonitor& msg, const StringRef& reply) noexcept;
// Configure a filament monitor
static GCodeResult Configure(const CanMessageGeneric& msg, const StringRef& reply) noexcept;
// Delete all filament monitors
static void DeleteAll() noexcept;
#endif
// This must be public so that the array descriptor in class RepRap can lock it
static ReadWriteLock filamentMonitorsLock;
protected:
FilamentMonitor(unsigned int drv, unsigned int monitorType, DriverId did) noexcept;
GCodeResult CommonConfigure(GCodeBuffer& gb, const StringRef& reply, InterruptMode interruptMode, bool& seen) THROWS(GCodeException);
#if SUPPORT_REMOTE_COMMANDS
GCodeResult CommonConfigure(const CanMessageGenericParser& parser, const StringRef& reply, InterruptMode interruptMode, bool& seen) noexcept;
#endif
const IoPort& GetPort() const noexcept { return port; }
bool HaveIsrStepsCommanded() const noexcept { return haveIsrStepsCommanded; }
static int32_t ConvertToPercent(float f)
{
return lrintf(100 * f);
}
bool IsLocal() const noexcept { return driverId.IsLocal(); }
private:
// Create a filament sensor returning null if not a valid sensor type
static FilamentMonitor *Create(unsigned int extruder, unsigned int monitorType, GCodeBuffer& gb, const StringRef& reply) noexcept;
static void InterruptEntry(CallbackParameter param) noexcept;
static constexpr size_t NumFilamentMonitors =
#if SUPPORT_REMOTE_COMMANDS
// When running as an expansion board, filament monitors are indexed by driver number; otherwise they are indexed by extruder number.
max<size_t>(MaxExtruders, NumDirectDrivers);
#else
MaxExtruders;
#endif
static FilamentMonitor *filamentSensors[NumFilamentMonitors];
#if SUPPORT_REMOTE_COMMANDS
static constexpr uint32_t StatusUpdateInterval = 2000; // how often we send status reports when there isn't a change
static uint32_t whenStatusLastSent;
#endif
int32_t isrExtruderStepsCommanded;
uint32_t lastIsrMillis;
unsigned int driveNumber;
unsigned int type;
IoPort port;
DriverId driverId;
bool isrWasPrinting;
bool haveIsrStepsCommanded;
FilamentSensorStatus lastStatus;
#if SUPPORT_CAN_EXPANSION
FilamentSensorStatus lastRemoteStatus;
bool hasRemote;
#endif
};
#endif /* SRC_FILAMENTSENSORS_FILAMENTMONITOR_H_ */
|