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
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2016-11-08 19:21:43 +0300
committerDavid Crocker <dcrocker@eschertech.com>2016-11-08 19:21:43 +0300
commit0e8056390595d0336a8e747070687427a5d464a4 (patch)
tree3f88c2d656966b19b0b35ce2c87e6544157020f0 /src
parent3177b8e19573e76d9772d69c68e025a59b101d9b (diff)
Version 1.16 release
Added I parameter in M280 command Added diagnostic test (M122 S101) for SX1509B chip on Duet WiFi expansion boards Heaters driven from TC channels on Duet WiFi no longer glitch on for a short while after reset Bug fix: M280 S-1 was ignoring inverted output status Bug fix: if there were too many files in the /gcodes folder then AJAX errors occurred (thanks chrishamm)
Diffstat (limited to 'src')
-rw-r--r--src/Configuration.h7
-rw-r--r--src/DuetNG/DueXn.cpp13
-rw-r--r--src/DuetNG/DueXn.h1
-rw-r--r--src/DuetNG/SX1509.cpp12
-rw-r--r--src/GCodes/GCodes.cpp9
-rw-r--r--src/Heating/Pid.cpp2
-rw-r--r--src/OutputMemory.cpp67
-rw-r--r--src/OutputMemory.h9
-rw-r--r--src/Platform.cpp6
-rw-r--r--src/Platform.h5
-rw-r--r--src/Reprap.cpp4
11 files changed, 77 insertions, 58 deletions
diff --git a/src/Configuration.h b/src/Configuration.h
index 9d809ed4..42e01f49 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.16rc3"
+# define VERSION "1.16"
#endif
#ifndef DATE
-# define DATE "2016-11-06"
+# define DATE "2016-11-08"
#endif
#define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman"
@@ -155,11 +155,14 @@ const size_t FILENAME_LENGTH = 100;
#ifdef DUET_NG
const uint16_t OUTPUT_BUFFER_SIZE = 256; // How many bytes does each OutputBuffer hold?
const size_t OUTPUT_BUFFER_COUNT = 32; // How many OutputBuffer instances do we have?
+const size_t RESERVED_OUTPUT_BUFFERS = 1; // Number of reserved output buffers after long responses. Must be enough for an HTTP header
#else
const uint16_t OUTPUT_BUFFER_SIZE = 128; // How many bytes does each OutputBuffer hold?
const size_t OUTPUT_BUFFER_COUNT = 32; // How many OutputBuffer instances do we have?
+const size_t RESERVED_OUTPUT_BUFFERS = 2; // Number of reserved output buffers after long responses. Must be enough for an HTTP header
#endif
+
// Move system
const float DEFAULT_FEEDRATE = 3000.0; // The initial requested feed rate after resetting the printer
diff --git a/src/DuetNG/DueXn.cpp b/src/DuetNG/DueXn.cpp
index ac6f0785..c89d50b0 100644
--- a/src/DuetNG/DueXn.cpp
+++ b/src/DuetNG/DueXn.cpp
@@ -72,8 +72,7 @@ namespace DuetExpansion
expander.pinModeMultiple(AllFanBits, OUTPUT_PWM); // Initialise the PWM pins
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
+ expander.pinModeMultiple(stopBits | AllGpioBits, INPUT); // Initialise the endstop inputs and GPIO pins (no pullups because 5V-tolerant)
// Set up the interrupt on any input change
inputMask = stopBits | AllGpioBits;
@@ -170,6 +169,16 @@ namespace DuetExpansion
expander.analogWrite(pin, (uint8_t)(constrain<float>(pwm, 0.0, 1.0) * 255));
}
}
+
+ // Diagnose the SX1509 by setting all pins as inputs and reading them
+ uint16_t DiagnosticRead()
+ {
+ expander.pinModeMultiple(AllStopBitsX5 | AllGpioBits | AllFanBits, INPUT); // Initialise the endstop inputs and GPIO pins (no pullups because 5V-tolerant)
+ delay(1);
+ const uint16_t retval = expander.digitalReadAll(); // read all inputs with pullup resistors on fans
+ Init(); // back to normal
+ return retval;
+ }
} // end namespace
// End
diff --git a/src/DuetNG/DueXn.h b/src/DuetNG/DueXn.h
index 312620ec..e943b116 100644
--- a/src/DuetNG/DueXn.h
+++ b/src/DuetNG/DueXn.h
@@ -27,6 +27,7 @@ namespace DuetExpansion
bool DigitalRead(Pin pin); // Read a pin
void DigitalWrite(Pin pin, bool high); // Write a pin
void AnalogOut(Pin pin, float pwm); // Set the PWM value on this pin
+ uint16_t DiagnosticRead(); // Diagnose the SX1509 by setting all pins as inputs and reading them
};
#endif /* SRC_DUETNG_DUEXN_H_ */
diff --git a/src/DuetNG/SX1509.cpp b/src/DuetNG/SX1509.cpp
index 7837a1d5..98035cca 100644
--- a/src/DuetNG/SX1509.cpp
+++ b/src/DuetNG/SX1509.cpp
@@ -87,24 +87,31 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
switch (inOut)
{
case INPUT:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
+ clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
break;
case INPUT_PULLUP:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
+ clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
- setBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
+ setBitsInWord(REG_PULL_UP_B, pins);
break;
case INPUT_PULLDOWN:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
+ clearBitsInWord(REG_INPUT_DISABLE_B, pins);
setBitsInWord(REG_DIR_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
setBitsInWord(REG_PULL_DOWN_B, pins);
break;
case OUTPUT_LOW:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
clearBitsInWord(REG_DATA_B, pins);
@@ -113,6 +120,7 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case OUTPUT_HIGH:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
setBitsInWord(REG_DATA_B, pins);
@@ -121,6 +129,7 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case OUTPUT_LOW_OPEN_DRAIN:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
clearBitsInWord(REG_DATA_B, pins);
@@ -129,6 +138,7 @@ void SX1509::pinModeMultiple(uint16_t pins, PinMode inOut)
break;
case OUTPUT_HIGH_OPEN_DRAIN:
+ clearBitsInWord(REG_LED_DRIVER_ENABLE_B, pins);
clearBitsInWord(REG_PULL_UP_B, pins);
clearBitsInWord(REG_PULL_DOWN_B, pins);
setBitsInWord(REG_DATA_B, pins);
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index c65b0d01..771daa2d 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -4181,13 +4181,20 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
bool invert;
if (platform->GetFirmwarePin(servoIndex, PinAccess::servo, servoPin, invert))
{
+ if (gb->Seen('I'))
+ {
+ if (gb->GetIValue() > 0)
+ {
+ invert = !invert;
+ }
+ }
if (gb->Seen('S'))
{
float angleOrWidth = gb->GetFValue();
if (angleOrWidth < 0.0)
{
// Disable the servo by setting the pulse width to zero
- Platform::WriteAnalog(servoPin, 0.0, ServoRefreshFrequency);
+ Platform::WriteAnalog(servoPin, (invert) ? 1.0 : 0.0, ServoRefreshFrequency);
}
else
{
diff --git a/src/Heating/Pid.cpp b/src/Heating/Pid.cpp
index e1a8190c..836d009f 100644
--- a/src/Heating/Pid.cpp
+++ b/src/Heating/Pid.cpp
@@ -786,7 +786,7 @@ void PID::FitCurve()
void PID::DisplayBuffer(const char *intro)
{
OutputBuffer *buf;
- if (OutputBuffer::Allocate(buf, false))
+ if (OutputBuffer::Allocate(buf))
{
buf->catf("%s: interval %.1f sec, readings", intro, tuningReadingInterval * MillisToSeconds);
for (size_t i = 0; i < tuningReadingsTaken; ++i)
diff --git a/src/OutputMemory.cpp b/src/OutputMemory.cpp
index 3e187814..b907cfa3 100644
--- a/src/OutputMemory.cpp
+++ b/src/OutputMemory.cpp
@@ -86,37 +86,34 @@ const char *OutputBuffer::Read(size_t len)
return data + offset;
}
-int OutputBuffer::printf(const char *fmt, ...)
+size_t OutputBuffer::printf(const char *fmt, ...)
{
char formatBuffer[FORMAT_STRING_LENGTH];
va_list vargs;
va_start(vargs, fmt);
- int ret = vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
+ vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
va_end(vargs);
- copy(formatBuffer);
- return ret;
+ return copy(formatBuffer);
}
-int OutputBuffer::vprintf(const char *fmt, va_list vargs)
+size_t OutputBuffer::vprintf(const char *fmt, va_list vargs)
{
char formatBuffer[FORMAT_STRING_LENGTH];
- int res = vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
+ vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
- cat(formatBuffer);
- return res;
+ return cat(formatBuffer);
}
-int OutputBuffer::catf(const char *fmt, ...)
+size_t OutputBuffer::catf(const char *fmt, ...)
{
char formatBuffer[FORMAT_STRING_LENGTH];
va_list vargs;
va_start(vargs, fmt);
- int ret = vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
+ vsnprintf(formatBuffer, ARRAY_SIZE(formatBuffer), fmt, vargs);
va_end(vargs);
- cat(formatBuffer);
- return ret;
+ return cat(formatBuffer);
}
size_t OutputBuffer::copy(const char c)
@@ -157,7 +154,7 @@ size_t OutputBuffer::copy(const char *src, size_t len)
OutputBuffer *currentBuffer;
size_t bytesCopied = OUTPUT_BUFFER_SIZE;
do {
- if (!Allocate(currentBuffer, true))
+ if (!Allocate(currentBuffer))
{
// We cannot store the whole string, stop here
break;
@@ -207,7 +204,7 @@ size_t OutputBuffer::cat(const char c)
{
// No - allocate a new item and copy the data
OutputBuffer *nextBuffer;
- if (!Allocate(nextBuffer, true))
+ if (!Allocate(nextBuffer))
{
// We cannot store any more data. Should never happen
return 0;
@@ -247,7 +244,7 @@ size_t OutputBuffer::cat(const char *src, size_t len)
{
// Yes - copy what we couldn't write into a new chain
OutputBuffer *nextBuffer;
- if (!Allocate(nextBuffer, true))
+ if (!Allocate(nextBuffer))
{
// We cannot store any more data, stop here
return copyLength;
@@ -360,7 +357,7 @@ size_t OutputBuffer::EncodeReply(OutputBuffer *src, bool allowControlChars)
}
// Allocates an output buffer instance which can be used for (large) string outputs
-/*static*/ bool OutputBuffer::Allocate(OutputBuffer *&buf, bool isAppending)
+/*static*/ bool OutputBuffer::Allocate(OutputBuffer *&buf)
{
const irqflags_t flags = cpu_irq_save();
@@ -372,18 +369,6 @@ size_t OutputBuffer::EncodeReply(OutputBuffer *src, bool allowControlChars)
buf = nullptr;
return false;
}
- else if (isAppending)
- {
- // It's a good idea to leave at least one OutputBuffer available if we're
- // writing a large chunk of data...
- if (freeOutputBuffers->next == nullptr)
- {
- cpu_irq_restore(flags);
-
- buf = nullptr;
- return false;
- }
- }
buf = freeOutputBuffers;
freeOutputBuffers = buf->next;
@@ -407,32 +392,28 @@ size_t OutputBuffer::EncodeReply(OutputBuffer *src, bool allowControlChars)
// Get the number of bytes left for continuous writing
/*static*/ size_t OutputBuffer::GetBytesLeft(const OutputBuffer *writingBuffer)
{
- // If writingBuffer is NULL, just return how much space there is left for continuous writing
+ size_t freeOutputBuffers = OUTPUT_BUFFER_COUNT - usedOutputBuffers;
if (writingBuffer == nullptr)
{
- if (usedOutputBuffers == OUTPUT_BUFFER_COUNT)
- {
- // No more instances can be allocated
- return 0;
- }
-
- return (OUTPUT_BUFFER_COUNT - usedOutputBuffers - 1) * OUTPUT_BUFFER_SIZE;
+ // Only return the total number of bytes left
+ return freeOutputBuffers * OUTPUT_BUFFER_SIZE;
}
- // Do we have any more buffers left for writing?
- if (usedOutputBuffers == OUTPUT_BUFFER_COUNT)
+ // We're doing a possibly long response like a filelist
+ size_t bytesLeft = OUTPUT_BUFFER_SIZE - writingBuffer->last->DataLength();
+
+ if (freeOutputBuffers < RESERVED_OUTPUT_BUFFERS)
{
- // No - refer to this one only
- return OUTPUT_BUFFER_SIZE - writingBuffer->last->DataLength();
+ // Keep some space left to encapsulate the respones (e.g. via an HTTP header)
+ return bytesLeft;
}
- // Yes - we know how many buffers are in use, so there is no need to work through the free list
- return (OUTPUT_BUFFER_SIZE - writingBuffer->last->DataLength() + (OUTPUT_BUFFER_COUNT - usedOutputBuffers - 1) * OUTPUT_BUFFER_SIZE);
+ return bytesLeft + (freeOutputBuffers - RESERVED_OUTPUT_BUFFERS) * OUTPUT_BUFFER_SIZE;
}
// Truncate an output buffer to free up more memory. Returns the number of released bytes.
-/*static */ size_t OutputBuffer::Truncate(OutputBuffer *buffer, size_t bytesNeeded )
+/*static */ size_t OutputBuffer::Truncate(OutputBuffer *buffer, size_t bytesNeeded)
{
// Can we free up space from this chain? Don't break it up if it's referenced anywhere else
if (buffer == nullptr || buffer->Next() == nullptr || buffer->IsReferenced())
diff --git a/src/OutputMemory.h b/src/OutputMemory.h
index 8106f974..629fbe4f 100644
--- a/src/OutputMemory.h
+++ b/src/OutputMemory.h
@@ -39,9 +39,9 @@ class OutputBuffer
const char *Read(size_t len);
size_t BytesLeft() const { return dataLength - bytesRead; } // How many bytes have not been sent yet?
- int printf(const char *fmt, ...);
- int vprintf(const char *fmt, va_list vargs);
- int catf(const char *fmt, ...);
+ size_t printf(const char *fmt, ...);
+ size_t vprintf(const char *fmt, va_list vargs);
+ size_t catf(const char *fmt, ...);
size_t copy(const char c);
size_t copy(const char *src);
@@ -61,8 +61,7 @@ class OutputBuffer
static void Init();
// Allocate an unused OutputBuffer instance. Returns true on success or false if no instance could be allocated.
- // Setting isAppending to true will guarantee that one OutputBuffer will remain available for single allocation.
- static bool Allocate(OutputBuffer *&buf, bool isAppending = false);
+ static bool Allocate(OutputBuffer *&buf);
// Get the number of bytes left for allocation. If writingBuffer is not NULL, this returns the number of free bytes for
// continuous writes, i.e. for writes that need to allocate an extra OutputBuffer instance to finish the message.
diff --git a/src/Platform.cpp b/src/Platform.cpp
index bbbf0573..20409663 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -1507,6 +1507,12 @@ void Platform::DiagnosticTest(int d)
DDA::PrintMoves();
break;
+#ifdef DUET_NG
+ case (int)DiagnosticTestType::PrintExpanderStatus:
+ MessageF(GENERIC_MESSAGE, "Expander status %04X\n", DuetExpansion::DiagnosticRead());
+ break;
+#endif
+
default:
break;
}
diff --git a/src/Platform.h b/src/Platform.h
index e5ce5480..94ea54bc 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -236,7 +236,10 @@ enum class DiagnosticTestType : int
TestWatchdog = 1001, // test that we get a watchdog reset if the tick interrupt stops
TestSpinLockup = 1002, // test that we get a software reset if a Spin() function takes too long
TestSerialBlock = 1003, // test what happens when we write a blocking message via debugPrintf()
- PrintMoves = 100 // print summary of recent moves
+ PrintMoves = 100, // print summary of recent moves
+#ifdef DUET_NG
+ PrintExpanderStatus = 101, // print DueXn expander status
+#endif
};
// Enumeration to describe what we want to do with a logical pin
diff --git a/src/Reprap.cpp b/src/Reprap.cpp
index a0a9300e..6b39b3ff 100644
--- a/src/Reprap.cpp
+++ b/src/Reprap.cpp
@@ -896,14 +896,14 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source)
if (source == ResponseSource::AUX)
{
- OutputBuffer *response = platform->GetAuxGCodeReply();
+ OutputBuffer *reply = platform->GetAuxGCodeReply();
if (response != nullptr)
{
// Send the response to the last command. Do this last
response->catf(",\"seq\":%u,\"resp\":", platform->GetAuxSeq()); // send the response sequence number
// Send the JSON response
- response->EncodeReply(response, true); // also releases the OutputBuffer chain
+ response->EncodeReply(reply, true); // also releases the OutputBuffer chain
}
}
response->cat("}");