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

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-rc1.zip (renamed from Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-b3.zip)bin816963 -> 790179 bytes
-rw-r--r--Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc2.bin (renamed from Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc1.bin)bin306276 -> 306580 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWebControl-1.13-rc1.bin (renamed from Release/Duet-WiFi/Edge/DuetWebControl-1.13-b3.bin)bin3125248 -> 3125248 bytes
-rw-r--r--Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc2.bin (renamed from Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc1.bin)bin253900 -> 254716 bytes
-rw-r--r--src/Configuration.h4
-rw-r--r--src/Duet/Webserver.cpp4
-rw-r--r--src/DuetNG/DueXn.cpp35
-rw-r--r--src/DuetNG/Pins_DuetNG.h1
-rw-r--r--src/DuetNG/TMC2660.cpp15
-rw-r--r--src/DuetNG/TMC2660.h9
-rw-r--r--src/DuetNG/Webserver.cpp2
-rw-r--r--src/Fan.cpp51
-rw-r--r--src/Fan.h2
-rw-r--r--src/GCodes/GCodes.cpp13
-rw-r--r--src/Libraries/Fatfs/fattime_rtc.c4
-rw-r--r--src/Platform.cpp47
-rw-r--r--src/Platform.h26
-rw-r--r--src/PrintMonitor.cpp14
-rw-r--r--src/PrintMonitor.h1
-rw-r--r--src/Reprap.cpp18
-rw-r--r--src/Storage/MassStorage.cpp55
-rw-r--r--src/Storage/MassStorage.h3
22 files changed, 209 insertions, 95 deletions
diff --git a/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-b3.zip b/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-rc1.zip
index 304bce7a..783d817d 100644
--- a/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-b3.zip
+++ b/Release/Duet-0.6-0.8.5/Edge/DuetWebControl-1.13-rc1.zip
Binary files differ
diff --git a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc1.bin b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc2.bin
index 32f31d6f..988f2f01 100644
--- a/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc1.bin
+++ b/Release/Duet-0.6-0.8.5/Edge/RepRapFirmware-1.16rc2.bin
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWebControl-1.13-b3.bin b/Release/Duet-WiFi/Edge/DuetWebControl-1.13-rc1.bin
index ac4d407e..4c6563e1 100644
--- a/Release/Duet-WiFi/Edge/DuetWebControl-1.13-b3.bin
+++ b/Release/Duet-WiFi/Edge/DuetWebControl-1.13-rc1.bin
Binary files differ
diff --git a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc1.bin b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc2.bin
index 3240a8a3..10471fb8 100644
--- a/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc1.bin
+++ b/Release/Duet-WiFi/Edge/DuetWiFiFirmware-1.16rc2.bin
Binary files differ
diff --git a/src/Configuration.h b/src/Configuration.h
index 9ebe291e..26982b4f 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -26,11 +26,11 @@ Licence: GPL
// Firmware name is now defined in the Pins file
#ifndef VERSION
-# define VERSION "1.16rc1"
+# define VERSION "1.16rc2"
#endif
#ifndef DATE
-# define DATE "2016-11-03"
+# define DATE "2016-11-05"
#endif
#define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman"
diff --git a/src/Duet/Webserver.cpp b/src/Duet/Webserver.cpp
index 15c21edc..8db33a5e 100644
--- a/src/Duet/Webserver.cpp
+++ b/src/Duet/Webserver.cpp
@@ -964,6 +964,7 @@ void Webserver::HttpInterpreter::GetJsonResponse(const char* request, OutputBuff
if (numQualKeys > 1 && StringEquals(qualifiers[1].key, "time") && !platform->IsDateTimeSet())
{
struct tm timeInfo;
+ memset(&timeInfo, 0, sizeof(timeInfo));
if (strptime(qualifiers[1].value, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
{
time_t newTime = mktime(&timeInfo);
@@ -1589,6 +1590,7 @@ bool Webserver::HttpInterpreter::ProcessMessage()
if (numQualKeys > 1 && StringEquals(qualifiers[1].key, "time"))
{
struct tm timeInfo;
+ memset(&timeInfo, 0, sizeof(timeInfo));
if (strptime(qualifiers[1].value, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
{
fileLastModified = mktime(&timeInfo);
@@ -2333,7 +2335,7 @@ void Webserver::FtpInterpreter::ProcessLine()
// Example for a typical UNIX-like file list:
// "drwxr-xr-x 2 ftp ftp 0 Apr 11 2013 bin\r\n"
const char dirChar = (fileInfo.isDirectory) ? 'd' : '-';
- struct tm *timeInfo = localtime(&fileInfo.lastModified);
+ const struct tm * const timeInfo = gmtime(&fileInfo.lastModified);
dataTransaction->Printf("%crw-rw-rw- 1 ftp ftp %13lu %s %02d %04d %s\r\n",
dirChar, fileInfo.size, platform->GetMassStorage()->GetMonthName(timeInfo->tm_mon + 1),
timeInfo->tm_mday, timeInfo->tm_year + 1900, fileInfo.fileName);
diff --git a/src/DuetNG/DueXn.cpp b/src/DuetNG/DueXn.cpp
index a0f1c11b..ac6f0785 100644
--- a/src/DuetNG/DueXn.cpp
+++ b/src/DuetNG/DueXn.cpp
@@ -7,12 +7,14 @@
#include "DueXn.h"
#include "SX1509.h"
+#include "Platform.h"
namespace DuetExpansion
{
static SX1509 expander;
static uint16_t inputMask;
static ExpansionBoardType boardType = ExpansionBoardType::none;
+ static uint16_t inputBits;
const uint8_t DueXnAddress = 0x3E; // address of the SX1509B on the DueX0/DueX2/DueX5
@@ -33,7 +35,8 @@ namespace DuetExpansion
const unsigned int E4StopBit = 2;
const unsigned int E5StopBit = 1;
const unsigned int E6StopBit = 13;
- const uint16_t AllStopBits = (1u << E2StopBit) | (1u << E3StopBit) | (1u << E4StopBit) | (1u << E5StopBit) | (1u << E6StopBit);
+ const uint16_t AllStopBitsX2 = (1u << E2StopBit) | (1u << E3StopBit);
+ const uint16_t AllStopBitsX5 = AllStopBitsX2 | (1u << E4StopBit) | (1u << E5StopBit) | (1u << E6StopBit);
const unsigned int Gpio1Bit = 11;
const unsigned int Gpio2Bit = 10;
@@ -64,16 +67,21 @@ namespace DuetExpansion
if (boardType != ExpansionBoardType::none)
{
+ pinMode(DueX_INT, INPUT_PULLUP);
+ pinMode(DueX_SG, INPUT_PULLUP);
+
expander.pinModeMultiple(AllFanBits, OUTPUT_PWM); // Initialise the PWM pins
- expander.pinModeMultiple(AllStopBits, INPUT); // Initialise the endstop inputs (no pullups because 5V-tolerant)
+ const uint16_t stopBits = (boardType == ExpansionBoardType::DueX5) ? AllStopBitsX5 : AllStopBitsX2; // I am assuming that the X0 has 2 endstop inputs
+ expander.pinModeMultiple(stopBits, INPUT); // Initialise the endstop inputs (no pullups because 5V-tolerant)
expander.pinModeMultiple(AllGpioBits, INPUT); // Initialise the GPIO pins as inputs
// Set up the interrupt on any input change
- inputMask = AllStopBits | AllGpioBits;
+ inputMask = stopBits | AllGpioBits;
expander.enableInterruptMultiple(inputMask, CHANGE);
// Clear any initial interrupts
- expander.interruptSource(true);
+ (void)expander.interruptSource(true);
+ inputBits = expander.digitalReadAll();
}
return boardType;
@@ -114,6 +122,10 @@ namespace DuetExpansion
case OUTPUT_PWM:
mode = OUTPUT_PWM_OPEN_DRAIN;
break;
+ case INPUT_PULLUP:
+ case INPUT_PULLDOWN:
+ mode = INPUT; // we are using 5rV-tolerant input with external pullup resistors, so don't enable internal pullup/pulldown resistors
+ break;
default:
break;
}
@@ -127,9 +139,18 @@ namespace DuetExpansion
// We need to use the SX15089 interrupt to read the data register using interrupts, and just retrieve that value here.
bool DigitalRead(Pin pin)
{
- return (boardType != ExpansionBoardType::none)
- ? expander.digitalRead(pin)
- : false;
+ if (boardType == ExpansionBoardType::none || pin >= 16)
+ {
+ return false;
+ }
+
+ if (!digitalRead(DueX_INT))
+ {
+ // Interrupt is active, so input data may have changed
+ inputBits = expander.digitalReadAll();
+ }
+
+ return (inputBits & (1 << pin)) != 0;
}
// Write a pin
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index f312eb2c..841aeb47 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -54,7 +54,6 @@ const Pin DueX_INT = 17; // DueX interrupt pin = PA17 (was E6_STOP)
// Endstops
// RepRapFirmware only has a single endstop per axis.
// Gcode defines if it is a max ("high end") or min ("low end") endstop and sets if it is active HIGH or LOW.
-//const Pin END_STOP_PINS[DRIVES] = { 46, 02, 93, 74, 48, 96, 97, 98, 99, 17 };
const Pin END_STOP_PINS[DRIVES] = { 46, 02, 93, 74, 48, 200, 203, 202, 201, 213 };
// HEATERS
diff --git a/src/DuetNG/TMC2660.cpp b/src/DuetNG/TMC2660.cpp
index 84c69e9b..fbf96771 100644
--- a/src/DuetNG/TMC2660.cpp
+++ b/src/DuetNG/TMC2660.cpp
@@ -6,6 +6,7 @@
*/
#include "RepRapFirmware.h"
+#include "TMC2660.h"
#if !defined(PROTOTYPE_1)
@@ -25,7 +26,8 @@ const Pin DriversSclkPin = 23; // PA23
#define TMC_CLOCK_CHAN 1
#define TMC_CLOCK_ID ID_TC1 // this is channel 1 on TC0
-const uint32_t DriversSpiClockFrequency = 1000000; // 1MHz SPI clock for now
+const uint32_t DriversSpiClockFrequency = 4000000; // 4MHz SPI clock
+const int StallGuardThreshold = 1; // Range is -64..63. Zero seems to be too sensitive. Higher values reduce sensitivity of stall detection.
// TMC2660 registers
const uint32_t TMC_REG_DRVCTRL = 0;
@@ -100,15 +102,6 @@ const uint32_t TMC_SMARTEN_SEDN_1 = 3 << 13;
const uint32_t TMC_SMARTEN_SEIMIN_HALF = 0 << 15;
const uint32_t TMC_SMARTEN_SEIMIN_QTR = 1 << 15;
-// Read response. The microstep counter can also be read, but we don't include that here.
-const uint32_t TMC_RR_SG = 1 << 0; // stall detected
-const uint32_t TMC_RR_OT = 1 << 1; // over temperature shutdown
-const uint32_t TMC_RR_OTPW = 1 << 2; // over temperature warning
-const uint32_t TMC_RR_S2G = 3 << 3; // short to ground counter (2 bits)
-const uint32_t TMC_RR_OLA = 1 << 5; // open load A
-const uint32_t TMC_RR_OLB = 1 << 6; // open load B
-const uint32_t TMC_RR_STST = 1 << 7; // standstill detected
-
const unsigned int NumWriteRegisters = 5;
// Chopper control register defaults
@@ -125,7 +118,7 @@ const uint32_t defaultChopConfToff = 4; // default value for TOFF when drive is
// StallGuard configuration register
const uint32_t defaultSgscConfReg =
TMC_REG_SGCSCONF
- | 0; // minimum current until user has set it
+ | TMC_SGCSCONF_SGT(StallGuardThreshold);
// Driver configuration register
const uint32_t defaultDrvConfReg =
diff --git a/src/DuetNG/TMC2660.h b/src/DuetNG/TMC2660.h
index 33510340..8fcb267b 100644
--- a/src/DuetNG/TMC2660.h
+++ b/src/DuetNG/TMC2660.h
@@ -10,6 +10,15 @@
#include "Pins.h"
+// TMC2660 Read response. The microstep counter can also be read, but we don't include that here.
+const uint32_t TMC_RR_SG = 1 << 0; // stall detected
+const uint32_t TMC_RR_OT = 1 << 1; // over temperature shutdown
+const uint32_t TMC_RR_OTPW = 1 << 2; // over temperature warning
+const uint32_t TMC_RR_S2G = 3 << 3; // short to ground counter (2 bits)
+const uint32_t TMC_RR_OLA = 1 << 5; // open load A
+const uint32_t TMC_RR_OLB = 1 << 6; // open load B
+const uint32_t TMC_RR_STST = 1 << 7; // standstill detected
+
namespace TMC2660
{
void Init(const Pin[DRIVES], size_t numTmcDrivers)
diff --git a/src/DuetNG/Webserver.cpp b/src/DuetNG/Webserver.cpp
index 0b949c1f..5f67e9f2 100644
--- a/src/DuetNG/Webserver.cpp
+++ b/src/DuetNG/Webserver.cpp
@@ -544,6 +544,7 @@ bool Webserver::ProcessFirstFragment(HttpSession& session, const char* command,
if (timeVal != nullptr && !platform->IsDateTimeSet())
{
struct tm timeInfo;
+ memset(&timeInfo, 0, sizeof(timeInfo));
if (strptime(timeVal, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
{
time_t newTime = mktime(&timeInfo);
@@ -623,6 +624,7 @@ bool Webserver::ProcessFirstFragment(HttpSession& session, const char* command,
// Try to obtain the last modified time
time_t fileLastModified = 0;
struct tm timeInfo;
+ memset(&timeInfo, 0, sizeof(timeInfo));
if (timeVal != nullptr && strptime(timeVal, "%Y-%m-%dT%H:%M:%S", &timeInfo) != nullptr)
{
fileLastModified = mktime(&timeInfo);
diff --git a/src/Fan.cpp b/src/Fan.cpp
index b4358238..89e2f972 100644
--- a/src/Fan.cpp
+++ b/src/Fan.cpp
@@ -12,13 +12,13 @@ void Fan::Init(Pin p_pin, bool hwInverted)
val = 0.0;
minVal = 0.1; // 10% minimum fan speed
blipTime = 100; // 100ms fan blip
- blipStartTime = 0;
freq = DefaultFanPwmFreq;
pin = p_pin;
hardwareInverted = hwInverted;
- inverted = false;
+ inverted = blipping = false;
heatersMonitored = 0;
triggerTemperature = HOT_END_FAN_TEMPERATURE;
+ lastPwm = -1.0;
Refresh();
}
@@ -28,10 +28,11 @@ void Fan::SetValue(float speed)
{
speed /= 255.0;
}
- const float newVal = (speed > 0.0) ? constrain<float>(speed, minVal, 1.0) : 0.0;
- if (val == 0.0 && newVal < 1.0 && blipTime != 0)
+ const float newVal = constrain<float>(speed, 0.0, 1.0);
+ if (val == 0.0 && newVal > 0.0 && newVal < 1.0 && blipTime != 0)
{
// Starting the fan from standstill, so blip the fan
+ blipping = true;
blipStartTime = millis();
}
val = newVal;
@@ -68,7 +69,17 @@ void Fan::SetHardwarePwm(float pwmVal)
{
invert = !invert;
}
- Platform::WriteAnalog(pin, (invert) ? (1.0 - pwmVal) : pwmVal, freq);
+ if (invert)
+ {
+ pwmVal = 1.0 - pwmVal;
+ }
+
+ // Only set the PWM if it has changed, to avoid a lot of I2C traffic when we have a DueX5 connected
+ if (pwmVal != lastPwm)
+ {
+ lastPwm = pwmVal;
+ Platform::WriteAnalog(pin, pwmVal, freq);
+ }
}
}
@@ -91,23 +102,31 @@ void Fan::Refresh()
: (reprap.GetPlatform()->AnyHeaterHot(heatersMonitored, triggerTemperature))
? max<float>(0.5, val) // make sure that thermostatic fans always run at 50% speed or more
: 0.0;
- if (reqVal > 0.0 && millis() - blipStartTime < blipTime)
- {
- SetHardwarePwm(1.0);
- }
- else if (reqVal > 0.0 && reqVal < minVal)
+ if (reqVal > 0.0)
{
- SetHardwarePwm(minVal);
- }
- else
- {
- SetHardwarePwm(reqVal);
+ if (reqVal < minVal)
+ {
+ reqVal = minVal;
+ }
+
+ if (blipping)
+ {
+ if (millis() - blipStartTime < blipTime)
+ {
+ reqVal = 1.0;
+ }
+ else
+ {
+ blipping = false;
+ }
+ }
}
+ SetHardwarePwm(reqVal);
}
void Fan::Check()
{
- if (heatersMonitored != 0 || blipTime != 0)
+ if (heatersMonitored != 0 || blipping)
{
Refresh();
}
diff --git a/src/Fan.h b/src/Fan.h
index 9193428b..9e31feb4 100644
--- a/src/Fan.h
+++ b/src/Fan.h
@@ -16,6 +16,7 @@ private:
float val;
float minVal;
float triggerTemperature;
+ float lastPwm;
uint32_t blipTime; // in milliseconds
uint32_t blipStartTime;
uint16_t freq;
@@ -23,6 +24,7 @@ private:
Pin pin;
bool inverted;
bool hardwareInverted;
+ bool blipping;
void Refresh();
void SetHardwarePwm(float pwmVal);
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 0b0a2a0f..c65b0d01 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -3237,7 +3237,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
const int logicalPin = gb->GetIValue();
Pin pin;
bool invert;
- if (platform->GetFirmwarePin(logicalPin, PinAccess::write, pin, invert))
+ if (platform->GetFirmwarePin(logicalPin, PinAccess::pwm, pin, invert))
{
if (gb->Seen('S'))
{
@@ -4313,7 +4313,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
}
else if (!model.IsEnabled())
{
- reply.printf("Heater %u is disabled");
+ reply.printf("Heater %u is disabled", heater);
}
else
{
@@ -5071,10 +5071,9 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
{
bool seen = false;
bool logicLevel = (gb->Seen('S')) ? (gb->GetIValue() != 0) : true;
- for (size_t axis = 0; axis <= numAxes; ++axis)
+ for (size_t axis = 0; axis < numAxes; ++axis)
{
- const char letter = (axis == numAxes) ? extrudeLetter : axisLetters[axis];
- if (gb->Seen(letter))
+ if (gb->Seen(axisLetters[axis]))
{
int ival = gb->GetIValue();
if (ival >= 0 && ival <= 3)
@@ -5096,8 +5095,6 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
(config == EndStopType::highEndStop) ? "high end" : (config == EndStopType::lowEndStop) ? "low end" : "none",
(config == EndStopType::noEndStop) ? "" : (logic) ? "high" : "low");
}
- platform->GetEndStopConfiguration(E0_AXIS, config, logic);
- reply.catf(" E (active %s)", (logic) ? "high" : "low");
}
}
break;
@@ -5634,7 +5631,7 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
case 905: // Set current RTC date and time
{
const time_t now = platform->GetDateTime();
- struct tm * const timeInfo = localtime(&now);
+ struct tm * const timeInfo = gmtime(&now);
bool seen = false;
if (gb->Seen('P'))
diff --git a/src/Libraries/Fatfs/fattime_rtc.c b/src/Libraries/Fatfs/fattime_rtc.c
index fc46396f..392e6373 100644
--- a/src/Libraries/Fatfs/fattime_rtc.c
+++ b/src/Libraries/Fatfs/fattime_rtc.c
@@ -60,7 +60,7 @@ uint32_t get_fattime(void);
*
* bit10:5 Minute (0..59)
*
- * bit4:0 Second (0..59)
+ * bit4:0 Second/2 (0..29)
*
* \return Current time.
*/
@@ -84,7 +84,7 @@ uint32_t get_fattime(void)
| (ul_day << 16)
| (ul_hour << 11)
| (ul_minute << 5)
- | (ul_second << 0);
+ | (ul_second >> 1);
return ul_time;
}
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 5a9106ce..bbbf0573 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -339,8 +339,8 @@ void Platform::Init()
// Test for presence of a DueX2 or DueX5 expansion board and work out how many TMC2660 drivers we have
// The SX1509B has an independent power on reset, so give it some time
delay(200);
- ExpansionBoardType et = DuetExpansion::Init();
- switch (et)
+ expansionBoard = DuetExpansion::Init();
+ switch (expansionBoard)
{
case ExpansionBoardType::DueX2:
numTMC2660Drivers = 7;
@@ -578,7 +578,7 @@ int Platform::ZProbe() const
}
}
- return (GetZProbeParameters().invertReading) ? 1023 - zProbeVal : zProbeVal;
+ return (GetZProbeParameters().invertReading) ? 1000 - zProbeVal : zProbeVal;
}
// Return the Z probe secondary values.
@@ -1439,11 +1439,34 @@ void Platform::Diagnostics(MessageType mtype)
AdcReadingToPowerVoltage(lowestVin), AdcReadingToPowerVoltage(currentVin), AdcReadingToPowerVoltage(highestVin),
numUnderVoltageEvents, numOverVoltageEvents);
lowestVin = highestVin = currentVin;
+
+ // Show the motor stall status
+ if (expansionBoard == ExpansionBoardType::DueX2 || expansionBoard == ExpansionBoardType::DueX5)
+ {
+ const bool stalled = digitalRead(DueX_SG);
+ MessageF(mtype, "Expansion motor(s) stall indication: %s\n", (stalled) ? "yes" : "no");
+ }
+
+ for (size_t drive = 0; drive < numTMC2660Drivers; ++drive)
+ {
+ const uint32_t stat = TMC2660::GetStatus(drive);
+ MessageF(mtype, "Driver %d:%s%s%s%s%s%s\n", drive,
+ (stat & TMC_RR_SG) ? " stalled" : "",
+ (stat & TMC_RR_OT) ? " temperature-shutdown!"
+ : (stat & TMC_RR_OTPW) ? " temperature-warning" : "",
+ (stat & TMC_RR_S2G) ? " short-to-ground" : "",
+ ((stat & TMC_RR_OLA) && !(stat & TMC_RR_STST)) ? " open-load-A" : "",
+ ((stat & TMC_RR_OLB) && !(stat & TMC_RR_STST)) ? " open-load-B" : "",
+ (stat & TMC_RR_STST) ? " standstill"
+ : (stat & (TMC_RR_SG | TMC_RR_OT | TMC_RR_OTPW | TMC_RR_S2G | TMC_RR_OLA | TMC_RR_OLB))
+ ? "" : " ok"
+ );
+ }
#endif
// Show current RTC time
const time_t timeNow = RTCDue::GetDateTime();
- const struct tm * const timeInfo = localtime(&timeNow);
+ const struct tm * const timeInfo = gmtime(&timeNow);
MessageF(mtype, "Current date and time: %04u-%02u-%02u %02u:%02u:%02u\n",
timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, timeInfo->tm_mday,
timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
@@ -2165,9 +2188,14 @@ void Platform::InitFans()
if (NUM_FANS > 1)
{
+#ifdef DUET_NG
// Set fan 1 to be thermostatic by default, monitoring all heaters except the default bed heater
fans[1].SetHeatersMonitored(0xFFFF & ~(1 << BED_HEATER));
fans[1].SetValue(1.0); // set it full on
+#else
+ // Fan 1 on the Duet 0.8.5 shares its control pin with heater 6. Set it full on to make sure the heater (if present) is off.
+ fans[1].SetValue(1.0); // set it full on
+#endif
}
coolingFanRpmPin = COOLING_FAN_RPM_PIN;
@@ -2655,9 +2683,8 @@ bool Platform::GetFirmwarePin(int logicalPin, PinAccess access, Pin& firmwarePin
firmwarePin = SpecialPinMap[logicalPin - 60];
}
#ifdef DUET_NG
- else if (logicalPin >= 100 && logicalPin <= 103) // Pins 100-103 are the GPIO pins on the DueX2/X5
+ else if (logicalPin >= 100 && logicalPin < 100 + (int)ARRAY_SIZE(DueX5GpioPinMap)) // Pins 100-103 are the GPIO pins on the DueX2/X5
{
- static const Pin DueX5GpioPinMap[] = { 211, 210, 209, 208 };
if (access != PinAccess::servo)
{
firmwarePin = DueX5GpioPinMap[logicalPin - 100];
@@ -2669,9 +2696,13 @@ bool Platform::GetFirmwarePin(int logicalPin, PinAccess access, Pin& firmwarePin
{
// Check that the pin mode has been defined suitably
PinMode desiredMode;
- if (access == PinAccess::write || access == PinAccess::servo)
+ if (access == PinAccess::write)
+ {
+ desiredMode = (invert) ? OUTPUT_HIGH : OUTPUT_LOW;
+ }
+ else if (access == PinAccess::pwm || access == PinAccess::servo)
{
- desiredMode = (firmwarePin >= 100) ? OUTPUT_PWM : OUTPUT_LOW;
+ desiredMode = OUTPUT_PWM;
}
else
{
diff --git a/src/Platform.h b/src/Platform.h
index bb274044..e80704d2 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -244,6 +244,7 @@ enum class PinAccess : int
{
read,
write,
+ pwm,
servo
};
@@ -734,6 +735,9 @@ private:
bool autoSaveEnabled;
BoardType board;
+#ifdef DUET_NG
+ ExpansionBoardType expansionBoard;
+#endif
float lastTime;
float longWait;
@@ -802,8 +806,8 @@ private:
float axisMaxima[MAX_AXES];
float axisMinima[MAX_AXES];
- EndStopType endStopType[MAX_AXES+1];
- bool endStopLogicLevel[MAX_AXES+1];
+ EndStopType endStopType[MAX_AXES];
+ bool endStopLogicLevel[MAX_AXES];
// Heaters - bed is assumed to be the first
@@ -1215,14 +1219,14 @@ inline float Platform::GetPressureAdvance(size_t extruder) const
}
inline void Platform::SetEndStopConfiguration(size_t axis, EndStopType esType, bool logicLevel)
-pre(axis < AXES)
+pre(axis < MAX_AXES)
{
endStopType[axis] = esType;
endStopLogicLevel[axis] = logicLevel;
}
inline void Platform::GetEndStopConfiguration(size_t axis, EndStopType& esType, bool& logicLevel) const
-pre(axis < AXES)
+pre(axis < MAX_AXES)
{
esType = endStopType[axis];
logicLevel = endStopLogicLevel[axis];
@@ -1241,19 +1245,21 @@ inline uint16_t Platform::GetRawZProbeReading() const
{
case 4:
{
- bool b = ReadPin(endStopPins[E0_AXIS]);
- if (!endStopLogicLevel[MAX_AXES])
- {
- b = !b;
- }
+ const bool b = ReadPin(endStopPins[E0_AXIS]);
return (b) ? 4000 : 0;
}
case 5:
return (ReadPin(zProbePin)) ? 4000 : 0;
+ case 6:
+ {
+ const bool b = ReadPin(endStopPins[E0_AXIS + 1]);
+ return (b) ? 4000 : 0;
+ }
+
default:
- return AnalogInReadChannel(zProbeAdcChannel);
+ return min<uint16_t>(AnalogInReadChannel(zProbeAdcChannel), 4000);
}
}
diff --git a/src/PrintMonitor.cpp b/src/PrintMonitor.cpp
index c6b92d9a..67dd85a7 100644
--- a/src/PrintMonitor.cpp
+++ b/src/PrintMonitor.cpp
@@ -297,6 +297,7 @@ bool PrintMonitor::GetFileInfo(const char *directory, const char *fileName, GCod
// Set up the info struct
parsedFileInfo.isValid = true;
parsedFileInfo.fileSize = fileBeingParsed->Length();
+ parsedFileInfo.lastModifiedTime = reprap.GetPlatform()->GetMassStorage()->GetLastModifiedTime(directory, fileName);
parsedFileInfo.firstLayerHeight = 0.0;
parsedFileInfo.objectHeight = 0.0;
parsedFileInfo.layerHeight = 0.0;
@@ -613,8 +614,17 @@ bool PrintMonitor::GetFileInfoResponse(const char *filename, OutputBuffer *&resp
return false;
}
- response->printf("{\"err\":0,\"size\":%lu,\"height\":%.2f,\"firstLayerHeight\":%.2f,\"layerHeight\":%.2f,\"filament\":",
- info.fileSize, info.objectHeight, info.firstLayerHeight, info.layerHeight);
+ response->printf("{\"err\":0,\"size\":%lu,",info.fileSize);
+ const struct tm * const timeInfo = gmtime(&info.lastModifiedTime);
+ if (timeInfo->tm_year > /*19*/80)
+ {
+ response->catf("\"lastModified\":\"%04u-%02u-%02uT%02u:%02u:%02u\",",
+ timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, timeInfo->tm_mday,
+ timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
+ }
+
+ response->catf("\"height\":%.2f,\"firstLayerHeight\":%.2f,\"layerHeight\":%.2f,\"filament\":",
+ info.objectHeight, info.firstLayerHeight, info.layerHeight);
char ch = '[';
if (info.numFilaments == 0)
{
diff --git a/src/PrintMonitor.h b/src/PrintMonitor.h
index 875d43eb..c71770f0 100644
--- a/src/PrintMonitor.h
+++ b/src/PrintMonitor.h
@@ -53,6 +53,7 @@ struct GCodeFileInfo
{
bool isValid;
FilePosition fileSize;
+ time_t lastModifiedTime;
float firstLayerHeight;
float objectHeight;
float filamentNeeded[DRIVES - MIN_AXES];
diff --git a/src/Reprap.cpp b/src/Reprap.cpp
index 5fd174bc..a0a9300e 100644
--- a/src/Reprap.cpp
+++ b/src/Reprap.cpp
@@ -1353,7 +1353,7 @@ OutputBuffer *RepRap::GetFilelistResponse(const char *dir)
if (fileInfo.fileName[0] != '.') // ignore Mac resource files and Linux hidden files
{
// Make sure we can end this response properly
- if (bytesLeft < strlen(fileInfo.fileName) + 80)
+ if (bytesLeft < strlen(fileInfo.fileName) + 70)
{
// No more space available - stop here
break;
@@ -1371,10 +1371,18 @@ OutputBuffer *RepRap::GetFilelistResponse(const char *dir)
bytesLeft -= response->EncodeString(fileInfo.fileName, FILENAME_LENGTH, false);
bytesLeft -= response->catf(",\"size\":%u", fileInfo.size);
- struct tm *timeInfo = localtime(&fileInfo.lastModified);
- bytesLeft -= response->catf(",\"lastModified\":\"%04u-%02u-%02uT%02u:%02u:%02u\"}",
- timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, timeInfo->tm_mday,
- timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
+ const struct tm * const timeInfo = gmtime(&fileInfo.lastModified);
+ if (timeInfo->tm_year <= /*19*/80)
+ {
+ // Don't send the last modified date if it is invalid
+ bytesLeft -= response->cat('}');
+ }
+ else
+ {
+ bytesLeft -= response->catf(",\"date\":\"%04u-%02u-%02uT%02u:%02u:%02u\"}",
+ timeInfo->tm_year + 1900, timeInfo->tm_mon + 1, timeInfo->tm_mday,
+ timeInfo->tm_hour, timeInfo->tm_min, timeInfo->tm_sec);
+ }
}
gotFile = platform->GetMassStorage()->FindNext(fileInfo);
}
diff --git a/src/Storage/MassStorage.cpp b/src/Storage/MassStorage.cpp
index 5df45663..945045c9 100644
--- a/src/Storage/MassStorage.cpp
+++ b/src/Storage/MassStorage.cpp
@@ -159,16 +159,7 @@ bool MassStorage::FindFirst(const char *directory, FileInfo &file_info)
}
file_info.size = entry.fsize;
-
- struct tm timeInfo;
- timeInfo.tm_year = (entry.fdate >> 9) + 80;
- timeInfo.tm_mon = (entry.fdate & 0x1DF) >> 5;
- timeInfo.tm_mday = max<int>(entry.fdate & 0x1F, 1);
- timeInfo.tm_hour = (entry.ftime >> 11) & 0x1F;
- timeInfo.tm_min = (entry.ftime >> 5) & 0x3F;
- timeInfo.tm_sec = entry.ftime & 0x1F;
- timeInfo.tm_isdst = -1;
- file_info.lastModified = mktime(&timeInfo);
+ file_info.lastModified = ConvertTimeStamp(entry.fdate, entry.ftime);
return true;
}
@@ -199,16 +190,7 @@ bool MassStorage::FindNext(FileInfo &file_info)
strncpy(file_info.fileName, entry.fname, ARRAY_SIZE(file_info.fileName));
}
- struct tm timeInfo;
- timeInfo.tm_year = (entry.fdate >> 9) + 80;
- timeInfo.tm_mon = (entry.fdate & 0x1DF) >> 5;
- timeInfo.tm_mday = max<int>(entry.fdate & 0x1F, 1);
- timeInfo.tm_hour = (entry.ftime >> 11) & 0x1F;
- timeInfo.tm_min = (entry.ftime >> 5) & 0x3F;
- timeInfo.tm_sec = entry.ftime & 0x1F;
- timeInfo.tm_isdst = -1;
- file_info.lastModified = mktime(&timeInfo);
-
+ file_info.lastModified = ConvertTimeStamp(entry.fdate, entry.ftime);
return true;
}
@@ -297,14 +279,28 @@ bool MassStorage::DirectoryExists(const char* directory, const char* subDirector
return DirectoryExists(CombineName(directory, subDirectory));
}
+// Return the last modified time of a file, or zero if failure
+time_t MassStorage::GetLastModifiedTime(const char* directory, const char *fileName) const
+{
+ const char *location = (directory != nullptr)
+ ? platform->GetMassStorage()->CombineName(directory, fileName)
+ : fileName;
+ FILINFO fil;
+ fil.lfname = nullptr;
+ if (f_stat(location, &fil) == FR_OK)
+ {
+ return ConvertTimeStamp(fil.fdate, fil.ftime);
+ }
+ return 0;
+}
+
bool MassStorage::SetLastModifiedTime(const char *file, time_t time)
{
FILINFO fno;
- const struct tm * const timeInfo = localtime(&time);
+ const struct tm * const timeInfo = gmtime(&time);
fno.fdate = (WORD)(((timeInfo->tm_year - 80) * 512U) | (timeInfo->tm_mon + 1) * 32U | timeInfo->tm_mday);
fno.ftime = (WORD)(timeInfo->tm_hour * 2048U | timeInfo->tm_min * 32U | timeInfo->tm_sec / 2U);
-
const bool ok = (f_utime(file, &fno) == FR_OK);
if (!ok)
{
@@ -426,4 +422,19 @@ bool MassStorage::CheckDriveMounted(const char* path)
return card < NumSdCards && isMounted[card];
}
+/*static*/ time_t MassStorage::ConvertTimeStamp(uint16_t fdate, uint16_t ftime)
+{
+ struct tm timeInfo;
+ memset(&timeInfo, 0, sizeof(timeInfo));
+ timeInfo.tm_year = (fdate >> 9) + 80;
+ const uint16_t month = (fdate >> 5) & 0x0F;
+ timeInfo.tm_mon = (month == 0) ? month : month - 1; // month is 1..12 in FAT but 0..11 in struct tm
+ timeInfo.tm_mday = max<int>(fdate & 0x1F, 1);
+ timeInfo.tm_hour = (ftime >> 11) & 0x1F;
+ timeInfo.tm_min = (ftime >> 5) & 0x3F;
+ timeInfo.tm_sec = ftime & 0x1F;
+ timeInfo.tm_isdst = 0;
+ return mktime(&timeInfo);
+}
+
// End
diff --git a/src/Storage/MassStorage.h b/src/Storage/MassStorage.h
index 0d17b439..3ccf973d 100644
--- a/src/Storage/MassStorage.h
+++ b/src/Storage/MassStorage.h
@@ -30,6 +30,7 @@ public:
bool FileExists(const char* directory, const char *fileName) const;
bool DirectoryExists(const char *path) const;
bool DirectoryExists(const char* directory, const char* subDirectory);
+ time_t GetLastModifiedTime(const char* directory, const char *fileName) const;
bool SetLastModifiedTime(const char *file, time_t time);
bool Mount(size_t card, StringRef& reply, bool reportSuccess);
bool Unmount(size_t card, StringRef& reply);
@@ -44,6 +45,8 @@ protected:
void Init();
private:
+ static time_t ConvertTimeStamp(uint16_t fdate, uint16_t ftime);
+
Platform* platform;
FATFS fileSystems[NumSdCards];
DIR findDir;