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-06-20 01:39:25 +0300
committerDavid Crocker <dcrocker@eschertech.com>2016-06-20 01:39:25 +0300
commitac4794daf14578be435ef5a457466868fb1c022c (patch)
tree67fecda779ace087dbaddd7ee8f65fc18436a12e /src
parentb96f710d4cda5e83bcde01d91e4b6e1f6bbb5c58 (diff)
Version 1.13a
Fixed thermostatic fan bug introduced in version 1.13 Added MCU temperature monitoring Duet WiFi only: added voltage monitoring, and disable TMC2660 drivers if the voltage is too low or too high. Not tested as at time of this checkin,
Diffstat (limited to 'src')
-rw-r--r--src/Configuration.h4
-rw-r--r--src/DuetNG/Network.cpp1
-rw-r--r--src/DuetNG/Pins_DuetNG.h10
-rw-r--r--src/ExternalDrivers.cpp71
-rw-r--r--src/ExternalDrivers.h1
-rw-r--r--src/GCodes.cpp27
-rw-r--r--src/Platform.cpp186
-rw-r--r--src/Platform.h97
-rw-r--r--src/Reprap.cpp18
9 files changed, 334 insertions, 81 deletions
diff --git a/src/Configuration.h b/src/Configuration.h
index 32962045..8b314d7c 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.13"
+# define VERSION "1.13a"
#endif
#ifndef DATE
-# define DATE "2016-06-13"
+# define DATE "2016-06-19"
#endif
#define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman"
diff --git a/src/DuetNG/Network.cpp b/src/DuetNG/Network.cpp
index 1578dda2..b0868afc 100644
--- a/src/DuetNG/Network.cpp
+++ b/src/DuetNG/Network.cpp
@@ -12,6 +12,7 @@
#include "TransactionBuffer.h"
// Define exactly one of the following as 1, thje other as zero
+// The PDC seems to be too slow to work reliably without getting transmit underruns, so we use the DMAC now.
#define USE_PDC 0 // use peripheral DMA controller
#define USE_DMAC 1 // use general DMA controller
diff --git a/src/DuetNG/Pins_DuetNG.h b/src/DuetNG/Pins_DuetNG.h
index 1a80ea9d..484b235c 100644
--- a/src/DuetNG/Pins_DuetNG.h
+++ b/src/DuetNG/Pins_DuetNG.h
@@ -11,9 +11,9 @@ const size_t NumFirmwareUpdateModules = 4; // 3 modules, plus one for manual u
// Default board type
#ifdef PROTOTYPE_1
-#define DEFAULT_BOARD_TYPE BoardType::DuetNG_06
+#define DEFAULT_BOARD_TYPE BoardType::DuetWiFi_06
#else
-#define DEFAULT_BOARD_TYPE BoardType::DuetNG_10
+#define DEFAULT_BOARD_TYPE BoardType::DuetWiFi_10
#endif
#define SUPPORT_ETHERNET 0 // set nonzero to support embedded web interface over Ethernet
@@ -110,7 +110,11 @@ const Pin SpiTempSensorCsPins[MaxSpiTempSensors] = { 28, 50, 51, 52 }; // SPI0_C
const Pin ATX_POWER_PIN = 79; // Arduino Due pin number that controls the ATX power on/off
// Analogue pin numbers
-const Pin Z_PROBE_PIN = 33; // Z probe analog input
+const Pin Z_PROBE_PIN = 33; // AFE1_AD4/PC1 Z probe analog input
+const Pin PowerMonitorVinDetectPin = 36; // AFE1_AD7/PC4 Vin monitor
+const Pin PowerMonitor5vDetectPin = 29; // AFE1_AD1/PB3 Buck regulator input monitor
+
+const float PowerFailVoltageRange = 11.0 * 3.3; // we use an 11:1 voltage divider
// Digital pin number to turn the IR LED on (high) or off (low)
const Pin Z_PROBE_MOD_PIN = 34; // Digital pin number to turn the IR LED on (high) or off (low) on Duet v0.6 and v1.0 (PB21)
diff --git a/src/ExternalDrivers.cpp b/src/ExternalDrivers.cpp
index 0fb01a0d..ff8c5345 100644
--- a/src/ExternalDrivers.cpp
+++ b/src/ExternalDrivers.cpp
@@ -11,6 +11,8 @@
const size_t NumExternalDrivers = DRIVES - FIRST_EXTERNAL_DRIVE;
+static bool driversPowered = false;
+
// Connections between Duet 0.6 and TMC2660-EVAL board:
// Driver signal name Eval board pin Our signal name Duet 0.6 expansion connector pin #
@@ -204,29 +206,37 @@ const uint32_t defaultSmartEnReg =
// Private types and methods
// Send an SPI control string. The drivers need 20 bits. We send and receive 24 because the USART only supports 5 to 9 bit transfers.
+// If the drivers are not powered up, don't attempt a transaction, and return 0xFFFFFFFF
uint32_t SpiSendWord(uint32_t pin, uint32_t dataOut)
{
- USART_EXT_DRV->US_CR = US_CR_RSTRX | US_CR_RSTTX; // reset transmitter and receiver
- digitalWrite(pin, LOW); // set CS low
- delayMicroseconds(1); // allow some CS low setup time
- USART_EXT_DRV->US_CR = US_CR_RXEN | US_CR_TXEN; // enable transmitter and receiver
- uint32_t dataIn = 0;
- for (int i = 0; i < 3; ++i)
+ if (driversPowered)
{
- USART_EXT_DRV->US_THR = (dataOut >> 16) & 0x000000FFu;
- dataOut <<= 8;
- dataIn <<= 8;
- for (int j = 0; j < 10000 && (USART_EXT_DRV->US_CSR & (US_CSR_RXRDY | US_CSR_TXRDY)) != (US_CSR_RXRDY | US_CSR_TXRDY); ++j)
+ USART_EXT_DRV->US_CR = US_CR_RSTRX | US_CR_RSTTX; // reset transmitter and receiver
+ digitalWrite(pin, LOW); // set CS low
+ delayMicroseconds(1); // allow some CS low setup time
+ USART_EXT_DRV->US_CR = US_CR_RXEN | US_CR_TXEN; // enable transmitter and receiver
+ uint32_t dataIn = 0;
+ for (int i = 0; i < 3; ++i)
{
- // nothing
+ USART_EXT_DRV->US_THR = (dataOut >> 16) & 0x000000FFu;
+ dataOut <<= 8;
+ dataIn <<= 8;
+ for (int j = 0; j < 10000 && (USART_EXT_DRV->US_CSR & (US_CSR_RXRDY | US_CSR_TXRDY)) != (US_CSR_RXRDY | US_CSR_TXRDY); ++j)
+ {
+ // nothing
+ }
+ dataIn |= USART_EXT_DRV->US_RHR & 0x000000FF;
}
- dataIn |= USART_EXT_DRV->US_RHR & 0x000000FF;
+ delayMicroseconds(1);
+ digitalWrite(pin, HIGH); // set CS high again
+ USART_EXT_DRV->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS; // reset and disable transmitter and receiver
+ delayMicroseconds(1); // ensure it stays high for long enough before the next write
+ return dataIn >> 4;
+ }
+ else
+ {
+ return 0xFFFFFFFF;
}
- delayMicroseconds(1);
- digitalWrite(pin, HIGH); // set CS high again
- USART_EXT_DRV->US_CR = US_CR_RSTRX | US_CR_RSTTX | US_CR_RXDIS | US_CR_TXDIS; // reset and disable transmitter and receiver
- delayMicroseconds(1); // ensure it stays high for long enough before the next write
- return dataIn >> 4;
}
struct TmcDriverState
@@ -248,7 +258,9 @@ struct TmcDriverState
uint32_t GetStatus() const;
};
+// Initialise the state of the driver.
void TmcDriverState::Init(uint32_t p_pin)
+//pre(!driversPowered)
{
drvCtrlReg = defaultDrvCtrlReg;
chopConfReg = defaultChopConfReg;
@@ -256,7 +268,7 @@ void TmcDriverState::Init(uint32_t p_pin)
sgcsConfReg = defaultSgscConfReg;
drvConfReg = defaultDrvConfReg;
pin = p_pin;
- WriteAll();
+ // No point in calling WriteAll() here because the drivers are assumed to be not powered up.
}
void TmcDriverState::WriteAll()
@@ -358,7 +370,8 @@ static TmcDriverState driverStates[NumExternalDrivers];
namespace ExternalDrivers
{
- // Initialise the driver interface and the drivers, leaving each drive disabled
+ // Initialise the driver interface and the drivers, leaving each drive disabled.
+ // It is assumed that the drivers are not powered, so driversPowered(true) must be called after calling this before the motors can be moved.
void Init()
{
// Set up the SPI pins
@@ -424,6 +437,7 @@ namespace ExternalDrivers
// otherwise they ignore the command we send to set the microstepping to x16 and start up in full-step mode.
delay(10);
+ driversPowered = false;
for (size_t drive = 0; drive < NumExternalDrivers; ++drive)
{
driverStates[drive].Init(DriverSelectPins[drive]);
@@ -490,7 +504,24 @@ namespace ExternalDrivers
}
return 1;
}
-};
+
+ // Flag the the drivers have been powered up.
+ // Must call Init() before the first call to say the drivers have been powered uo.
+ void SetDriversPowered(bool powered)
+ {
+ bool wasPowered = driversPowered;
+ driversPowered = powered;
+ if (powered && !wasPowered)
+ {
+ // Power to the drivers has been provided or restored, so we need to re-initialise them
+ for (size_t drive = 0; drive < NumExternalDrivers; ++drive)
+ {
+ driverStates[drive].WriteAll();
+ }
+ }
+ }
+
+}; // end namespace
#endif
diff --git a/src/ExternalDrivers.h b/src/ExternalDrivers.h
index f20245ed..b966c78a 100644
--- a/src/ExternalDrivers.h
+++ b/src/ExternalDrivers.h
@@ -16,6 +16,7 @@ namespace ExternalDrivers
uint32_t GetStatus(size_t drive);
bool SetMicrostepping(size_t drive, int microsteps, int mode);
unsigned int GetMicrostepping(size_t drive, bool& interpolation);
+ void SetDriversPowered(bool powered);
};
#endif /* EXTERNALDRIVERS_H_ */
diff --git a/src/GCodes.cpp b/src/GCodes.cpp
index 908f8ead..f76db252 100644
--- a/src/GCodes.cpp
+++ b/src/GCodes.cpp
@@ -3435,18 +3435,15 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
if (!seen)
{
- reply.printf("Fan%i frequency: %dHz, inverted: %s, ",
+ reply.printf("Fan%i frequency: %dHz, speed: %d%%, inverted: %s",
fanNum,
(int)(platform->GetFanPwmFrequency(fanNum)),
+ (int)(platform->GetFanValue(fanNum) * 100.0),
(platform->GetCoolingInverted(fanNum)) ? "yes" : "no");
uint16_t hh = platform->GetHeatersMonitored(fanNum);
- if (hh == 0)
- {
- reply.catf("value: %d%%", (int)(platform->GetFanValue(fanNum) * 100.0));
- }
- else
+ if (hh != 0)
{
- reply.catf("trigger: %dC, heaters:", (int)platform->GetTriggerTemperature(fanNum));
+ reply.catf(", trigger: %dC, heaters:", (int)platform->GetTriggerTemperature(fanNum));
for (unsigned int i = 0; i < HEATERS; ++i)
{
if ((hh & (1 << i)) != 0)
@@ -5326,6 +5323,22 @@ bool GCodes::HandleMcode(GCodeBuffer* gb, StringRef& reply)
}
break;
+ case 911: // Set power monitor threshold voltages
+ reply.printf("M911 not implemented yet");
+ break;
+
+ case 912: // Set electronics temperature monitor adjustment
+ // Currently we ignore the P parameter (i.e. temperature measurement channel)
+ if (gb->Seen('S'))
+ {
+ platform->SetMcuTemperatureAdjust(gb->GetFValue());
+ }
+ else
+ {
+ reply.printf("MCU temperature calibration adjustment is %.1f" DEGREE_SYMBOL "C", platform->GetMcuTemperatureAdjust());
+ }
+ break;
+
case 997: // Perform firmware update
if (!AllMovesAreFinishedAndMoveBufferIsLoaded())
{
diff --git a/src/Platform.cpp b/src/Platform.cpp
index d5083261..cc4da3f8 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -36,6 +36,13 @@
extern char _end;
extern "C" char *sbrk(int i);
+#ifdef DUET_NG
+const uint16_t driverPowerOnAdcReading = (uint16_t)(4096 * 10.0/PowerFailVoltageRange); // minimum voltage at which we initialise the drivers
+const uint16_t driverPowerOffAdcReading = (uint16_t)(4096 * 9.5/PowerFailVoltageRange); // voltages below this flag the drivers as unusable
+const uint16_t driverOverVoltageAdcReading = (uint16_t)(4096 * 29.0/PowerFailVoltageRange); // voltages above this cause driver shutdown
+const uint16_t driverNormalVoltageAdcReading = (uint16_t)(4096 * 25.5/PowerFailVoltageRange); // voltages at or below this are normal
+#endif
+
const uint8_t memPattern = 0xA5;
static uint32_t fanInterruptCount = 0; // accessed only in ISR, so no need to declare it volatile
@@ -299,6 +306,7 @@ void Platform::Init()
}
#ifdef EXTERNAL_DRIVERS
+ driversPowered = false;
ExternalDrivers::Init();
#endif
@@ -358,6 +366,21 @@ void Platform::Init()
}
#endif
+ // MCU temperature and power monitoring
+ temperatureAdcChannel = GetTemperatureAdcChannel();
+ AnalogInEnableChannel(temperatureAdcChannel, true);
+ currentMcuTemperature = highestMcuTemperature = 0;
+ lowestMcuTemperature = 4095;
+ mcuTemperatureAdjust = 0.0;
+ mcuAlarmTemperature = 80.0; // need to set the quite high here because the sensor is not be calibrated yet
+
+#ifdef DUET_NG
+ vInMonitorAdcChannel = PinToAdcChannel(PowerMonitorVinDetectPin);
+ AnalogInEnableChannel(vInMonitorAdcChannel, true);
+ currentVin = highestVin = 0;
+ lowestVin = 4095;
+#endif
+
// Clear the spare pin configuration
memset(pinInitialised, 0, sizeof(pinInitialised));
@@ -430,7 +453,7 @@ void Platform::InitZProbe()
zProbeOnFilter.Init(0);
zProbeOffFilter.Init(0);
-#ifdef DUET_NG
+#if defined(DUET_NG) || defined(__RADDS__)
zProbeModulationPin = Z_PROBE_MOD_PIN;
#else
zProbeModulationPin = (board == BoardType::Duet_07 || board == BoardType::Duet_085) ? Z_PROBE_MOD_PIN07 : Z_PROBE_MOD_PIN;
@@ -1117,7 +1140,7 @@ void Platform::Spin()
return;
// Check if any files are supposed to be closed
- for(size_t i = 0; i < MAX_FILES; i++)
+ for (size_t i = 0; i < MAX_FILES; i++)
{
if (files[i]->closeRequested)
{
@@ -1135,12 +1158,39 @@ void Platform::Spin()
fans[fan].Check();
}
+ // Read the MCU temperature.
+ currentMcuTemperature = AnalogInReadChannel(temperatureAdcChannel);
+ if (currentMcuTemperature > highestMcuTemperature)
+ {
+ highestMcuTemperature= currentMcuTemperature;
+ }
+ if (currentMcuTemperature < lowestMcuTemperature)
+ {
+ lowestMcuTemperature = currentMcuTemperature;
+ }
+
// Diagnostics test
if (debugCode == (int)DiagnosticTestType::TestSpinLockup)
{
for (;;) {}
}
+#ifdef DUET_NG
+ // Check whether the TMC drivers need to be initialised
+ if (driversPowered)
+ {
+ if (currentVin < driverPowerOffAdcReading || currentVin > driverOverVoltageAdcReading)
+ {
+ driversPowered = false;
+ }
+ }
+ else if (currentVin >= driverPowerOnAdcReading && currentVin <= driverNormalVoltageAdcReading)
+ {
+ driversPowered = true;
+ }
+ ExternalDrivers::SetDriversPowered(driversPowered);
+#endif
+
ClassReport(longWait);
}
@@ -1344,6 +1394,15 @@ void Platform::Diagnostics(MessageType mtype)
// Show the longest SD card write time
MessageF(mtype, "SD card longest block write time: %.1fms\n", FileStore::GetAndClearLongestWriteTime());
+ // Show the MCU temperatures
+ MessageF(mtype, "MCU temperature: min %.1f, current %.1f, max %.1f\n",
+ AdcReadingToCpuTemperature(lowestMcuTemperature), AdcReadingToCpuTemperature(currentMcuTemperature), AdcReadingToCpuTemperature(highestMcuTemperature));
+#ifdef DUET_NG
+ // Show the supply voltage
+ MessageF(mtype, "Supply voltage: min %.1f, current %.1f, max %.1f\n",
+ AdcReadingToPowerVoltage(lowestVin), AdcReadingToPowerVoltage(currentVin), AdcReadingToPowerVoltage(highestVin));
+#endif
+
// Debug
//MessageF(mtype, "TC_FMR = %08x, PWM_FPE = %08x, PWM_FSR = %08x\n", TC2->TC_FMR, PWM->PWM_FPE, PWM->PWM_FSR);
//MessageF(mtype, "PWM2 period %08x, duty %08x\n", PWM->PWM_CH_NUM[2].PWM_CPRD, PWM->PWM_CH_NUM[2].PWM_CDTY);
@@ -1794,33 +1853,35 @@ void Platform::UpdateMotorCurrent(size_t drive)
}
else
{
-# ifndef DUET_NG
+# ifndef __RADDS__
+# ifndef DUET_NG
if (board == BoardType::Duet_085)
{
-# endif
+# endif
// Extruder 0 is on DAC channel 0
if (driver == 4)
{
float dacVoltage = max<float>(current * 0.008*senseResistor + stepperDacVoltageOffset, 0.0); // the voltage we want from the DAC relative to its minimum
uint32_t dac = (uint32_t)((256 * dacVoltage + 0.5 * stepperDacVoltageRange)/stepperDacVoltageRange);
-# ifdef DUET_NG
+# ifdef DUET_NG
AnalogWrite(DAC1, dac);
-# else
+# else
AnalogWrite(DAC0, dac);
-# endif
+# endif
}
else
{
mcpExpansion.setNonVolatileWiper(potWipes[driver-1], pot);
mcpExpansion.setVolatileWiper(potWipes[driver-1], pot);
}
-# ifndef DUET_NG
+# ifndef DUET_NG
}
else if (driver < 8) // on a Duet 0.6 we have a maximum of 8 drives
{
mcpExpansion.setNonVolatileWiper(potWipes[driver], pot);
mcpExpansion.setVolatileWiper(potWipes[driver], pot);
}
+# endif
# endif
}
# ifdef EXTERNAL_DRIVERS
@@ -1940,12 +2001,12 @@ int Platform::GetPhysicalDrive(size_t driverNumber) const
// Get current cooling fan speed on a scale between 0 and 1
float Platform::GetFanValue(size_t fan) const
{
- return (fan < NUM_FANS) ? fans[fan].val : -1;
+ return (fan < NUM_FANS) ? fans[fan].GetValue() : -1;
}
bool Platform::GetCoolingInverted(size_t fan) const
{
- return (fan < NUM_FANS) ? fans[fan].inverted : -1;
+ return (fan < NUM_FANS) ? fans[fan].GetInverted() : -1;
}
@@ -1953,7 +2014,7 @@ void Platform::SetCoolingInverted(size_t fan, bool inv)
{
if (fan < NUM_FANS)
{
- fans[fan].inverted = inv;
+ fans[fan].SetInverted(inv);
}
}
@@ -1987,7 +2048,7 @@ void Platform::InitFans()
for (size_t i = 0; i < NUM_FANS; ++i)
{
fans[i].Init(COOLING_FAN_PINS[i],
-#ifdef DUET_NG
+#if defined(DUET_NG) || defined(__RADDS__)
false
#else
// The cooling fan output pin gets inverted if HEAT_ON == 0 on a Duet 0.6 or 0.7
@@ -2015,7 +2076,7 @@ float Platform::GetFanPwmFrequency(size_t fan) const
{
if (fan < NUM_FANS)
{
- return (float)fans[fan].freq;
+ return (float)fans[fan].GetPwmFrequency();
}
return 0.0;
}
@@ -2032,7 +2093,7 @@ float Platform::GetTriggerTemperature(size_t fan) const
{
if (fan < NUM_FANS)
{
- return fans[fan].triggerTemperature;
+ return fans[fan].GetTriggerTemperature();
}
return ABS_ZERO;
@@ -2050,7 +2111,7 @@ uint16_t Platform::GetHeatersMonitored(size_t fan) const
{
if (fan < NUM_FANS)
{
- return fans[fan].heatersMonitored;
+ return fans[fan].GetHeatersMonitored();
}
return 0;
}
@@ -2077,22 +2138,25 @@ void Platform::Fan::Init(Pin p_pin, bool hwInverted)
void Platform::Fan::SetValue(float speed)
{
- if (heatersMonitored == 0)
+ if (speed > 1.0)
{
- if (speed > 1.0)
- {
- speed /= 255.0;
- }
- val = constrain<float>(speed, 0.0, 1.0);
- Refresh();
+ speed /= 255.0;
}
+ val = constrain<float>(speed, 0.0, 1.0);
+ Refresh();
}
-void Platform::Fan::Refresh()
+void Platform::Fan::SetInverted(bool inv)
+{
+ inverted = inv;
+ Refresh();
+}
+
+void Platform::Fan::SetHardwarePwm(float pwmVal)
{
if (pin >= 0)
{
- uint32_t p = (uint32_t)(255.0 * val);
+ uint32_t p = (uint32_t)(255.0 * pwmVal);
bool invert = hardwareInverted;
if (inverted)
{
@@ -2108,13 +2172,31 @@ void Platform::Fan::SetPwmFrequency(float p_freq)
Refresh();
}
-void Platform::Fan::Check()
+void Platform::Fan::SetHeatersMonitored(uint16_t h)
+{
+ heatersMonitored = h;
+ Refresh();
+}
+
+void Platform::Fan::Refresh()
{
if (heatersMonitored != 0)
{
- val = (reprap.GetPlatform()->AnyHeaterHot(heatersMonitored, triggerTemperature))
+ const float pwmVal = (reprap.GetPlatform()->AnyHeaterHot(heatersMonitored, triggerTemperature))
? max<float>(0.5, val) // make sure that thermostatic fans always run at 50% speed or more
: 0.0;
+ SetHardwarePwm(pwmVal);
+ }
+ else
+ {
+ SetHardwarePwm(val);
+ }
+}
+
+void Platform::Fan::Check()
+{
+ if (heatersMonitored != 0)
+ {
Refresh();
}
}
@@ -2461,10 +2543,12 @@ void Platform::SetBoardType(BoardType bt)
{
#ifdef DUET_NG
# ifdef PROTOTYPE_1
- board = BoardType::DuetNG_06;
+ board = BoardType::DuetWiFi_06;
# else
- board = BoardType::DuetNG_10;
+ board = BoardType::DuetWiFi_10;
# endif
+#elif defined(__RADDS__)
+ board = BoardType::RADDS_15;
#else
// Determine whether this is a Duet 0.6 or a Duet 0.8.5 board.
// If it is a 0.85 board then DAC0 (AKA digital pin 67) is connected to ground via a diode and a 2.15K resistor.
@@ -2494,10 +2578,12 @@ const char* Platform::GetElectronicsString() const
{
#ifdef DUET_NG
# ifdef PROTOTYPE_1
- case BoardType::DuetNG_06: return "DuetNG 0.6";
+ case BoardType::DuetWiFi_06: return "Duet WiFi 0.6";
# else
- case BoardType::DuetNG_10: return "DuetNG 1.0";
+ case BoardType::DuetWiFi_10: return "Duet WiFi 1.0";
# endif
+#elif defined(__RADDS__)
+ case BoardType::RADDS_15: return "RADDS 1.5";
#else
case BoardType::Duet_06: return "Duet 0.6";
case BoardType::Duet_07: return "Duet 0.7";
@@ -2624,6 +2710,25 @@ char Platform::ReadFromSource(const SerialSource source)
return 0;
}
+// CPU temperature
+void Platform::GetMcuTemperatures(float& minT, float& currT, float& maxT) const
+{
+ minT = AdcReadingToCpuTemperature(lowestMcuTemperature);
+ currT = AdcReadingToCpuTemperature(currentMcuTemperature);
+ maxT = AdcReadingToCpuTemperature(highestMcuTemperature);
+}
+
+#ifdef DUET_NG
+// Power in voltage
+void Platform::GetPowerVoltages(float& minV, float& currV, float& maxV) const
+{
+ minV = AdcReadingToPowerVoltage(lowestVin);
+ currV = AdcReadingToPowerVoltage(currentVin);
+ maxV = AdcReadingToPowerVoltage(highestVin);
+}
+#endif
+
+
// Pragma pop_options is not supported on this platform, so we put this time-critical code right at the end of the file
//#pragma GCC push_options
#pragma GCC optimize ("O3")
@@ -2682,6 +2787,27 @@ void Platform::Tick()
#ifdef TIME_TICK_ISR
uint32_t now = micros();
#endif
+
+#ifdef DUET_NG
+ // Read the power input voltage
+ currentVin = AnalogInReadChannel(vInMonitorAdcChannel);
+ if (currentVin > highestVin)
+ {
+ highestVin = currentVin;
+ }
+ if (currentVin < lowestVin)
+ {
+ lowestVin = currentVin;
+ }
+ if (driversPowered && currentVin > driverOverVoltageAdcReading)
+ {
+ driversPowered = false;
+ ExternalDrivers::SetDriversPowered(false);
+ //TODO set ENN high on production boards
+ }
+
+ #endif
+
switch (tickState)
{
case 1: // last conversion started was a thermistor
diff --git a/src/Platform.h b/src/Platform.h
index e8107bcb..8bd7d267 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -183,10 +183,12 @@ enum class BoardType : uint8_t
Auto = 0,
#ifdef DUET_NG
# ifdef PROTOTYPE_1
- DuetNG_06 = 1
+ DuetWiFi_06 = 1
# else
- DuetNG_10 = 1
+ DuetWiFi_10 = 1
# endif
+#elif defined(__RADDS__)
+ RADDS_15 = 1
#else
Duet_06 = 1,
Duet_07 = 2,
@@ -610,7 +612,6 @@ public:
// Fire the inkjet (if any) in the given pattern
// If there is no inkjet false is returned; if there is one this returns true
// So you can test for inkjet presence with if(platform->Inkjet(0))
-
bool Inkjet(int bitPattern);
// Direct pin operations
@@ -619,10 +620,25 @@ public:
// Error logging
void LogError(ErrorCode e) { errorCodeBits |= (uint32_t)e; }
+ // MCU temperature
+ void GetMcuTemperatures(float& minT, float& currT, float& maxT) const;
+ void SetMcuTemperatureAdjust(float v) { mcuTemperatureAdjust = v; }
+ float GetMcuTemperatureAdjust() const { return mcuTemperatureAdjust; }
+
+#ifdef DUET_NG
+ // Power in voltage
+ void GetPowerVoltages(float& minV, float& currV, float& maxV) const;
+#endif
+
//-------------------------------------------------------------------------------------------------------
private:
void ResetChannel(size_t chan); // re-initialise a serial channel
+ float AdcReadingToCpuTemperature(uint16_t reading) const;
+
+#ifdef DUET_NG
+ static float AdcReadingToPowerVoltage(uint16_t reading);
+#endif
// These are the structures used to hold out non-volatile data.
// The SAM3X doesn't have EEPROM so we save the data to flash. This unfortunately means that it gets cleared
@@ -667,23 +683,33 @@ private:
Compatibility compatibility;
};
- struct Fan
+ class Fan
{
- float val;
- float triggerTemperature;
- uint16_t freq;
- uint16_t heatersMonitored;
- Pin pin;
- bool inverted;
- bool hardwareInverted;
-
- void Init(Pin p_pin, bool hwInverted);
- void SetValue(float speed);
- void SetPwmFrequency(float p_freq);
- void Refresh();
- void SetTriggerTemperature(float t) { triggerTemperature = t; }
- void SetHeatersMonitored(uint16_t h) { heatersMonitored = h; }
- void Check();
+ private:
+ float val;
+ float triggerTemperature;
+ uint16_t freq;
+ uint16_t heatersMonitored;
+ Pin pin;
+ bool inverted;
+ bool hardwareInverted;
+ public:
+ float GetValue() const { return val; }
+ float GetPwmFrequency() const { return freq; }
+ bool GetInverted() const { return inverted; }
+ uint16_t GetHeatersMonitored() const { return heatersMonitored; }
+ float GetTriggerTemperature() const { return triggerTemperature; }
+
+ void Init(Pin p_pin, bool hwInverted);
+ void SetValue(float speed);
+ void SetInverted(bool inv);
+ void SetPwmFrequency(float p_freq);
+ void SetTriggerTemperature(float t) { triggerTemperature = t; }
+ void SetHeatersMonitored(uint16_t h);
+ void Check();
+ private:
+ void Refresh();
+ void SetHardwarePwm(float pwmVal);
};
FlashData nvData;
@@ -845,6 +871,19 @@ private:
float filamentWidth;
float nozzleDiameter;
+ // Temperature and power monitoring
+ AnalogChannelNumber temperatureAdcChannel;
+ uint16_t currentMcuTemperature, highestMcuTemperature, lowestMcuTemperature;
+ uint16_t mcuAlarmTemperature;
+ float mcuTemperatureAdjust;
+
+#ifdef DUET_NG
+ AnalogChannelNumber vInMonitorAdcChannel;
+ volatile uint16_t currentVin, highestVin, lowestVin;
+ uint16_t upperVinLimit, lowerVinLimit;
+ bool driversPowered;
+#endif
+
// Direct pin manipulation
static const uint8_t pinAccessAllowed[NUM_PINS_ALLOWED/8];
uint8_t pinInitialised[NUM_PINS_ALLOWED/8];
@@ -1290,6 +1329,26 @@ inline MassStorage* Platform::GetMassStorage() const
watchdogReset();
}
+// Inline functions
+inline float Platform::AdcReadingToCpuTemperature(uint16_t adcVal) const
+{
+ float voltage = (float)adcVal * (3.3/4096.0);
+#ifdef DUET_NG
+ return (voltage - 1.44) * (1000.0/4.7) + 27.0 + mcuTemperatureAdjust; // accuracy at 27C is +/-13C
+#else
+ return (voltage - 0.8) * (1000.0/2.65) + 27.0 + mcuTemperatureAdjust; // accuracy at 27C is +/-45C
+#endif
+}
+
+#ifdef DUET_NG
+inline float Platform::AdcReadingToPowerVoltage(uint16_t adcVal)
+{
+ return adcVal * (PowerFailVoltageRange/4096.0);
+}
+#endif
+
+
+
//***************************************************************************************
#endif
diff --git a/src/Reprap.cpp b/src/Reprap.cpp
index 9bfd555a..2fb64b56 100644
--- a/src/Reprap.cpp
+++ b/src/Reprap.cpp
@@ -800,6 +800,24 @@ OutputBuffer *RepRap::GetStatusResponse(uint8_t type, ResponseSource source)
}
response->cat("]");
}
+
+ // MCU temperatures
+ {
+ float minT, currT, maxT;
+ platform->GetMcuTemperatures(minT, currT, maxT);
+ response->catf(",\"mcutemp\":{\"min\":%.1f,\"cur\":%.1f,\"max\":%.1f}", minT, currT, maxT);
+ // TEMPORARY for DWC 1.11: send mcutemp.cur as cputemp as well
+ response->catf(",\"cputemp\":%.1f", currT);
+ }
+
+#ifdef DUET_NG
+ // Power in voltages
+ {
+ float minV, currV, maxV;
+ platform->GetPowerVoltages(minV, currV, maxV);
+ response->catf(",\"vin\":{\"min\":%.1f,\"cur\":%.1f,\"max\":%.1f}", minV, currV, maxV);
+ }
+#endif
}
else if (type == 3)
{