diff options
author | David Crocker <dcrocker@eschertech.com> | 2016-06-20 01:39:25 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2016-06-20 01:39:25 +0300 |
commit | ac4794daf14578be435ef5a457466868fb1c022c (patch) | |
tree | 67fecda779ace087dbaddd7ee8f65fc18436a12e /src | |
parent | b96f710d4cda5e83bcde01d91e4b6e1f6bbb5c58 (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.h | 4 | ||||
-rw-r--r-- | src/DuetNG/Network.cpp | 1 | ||||
-rw-r--r-- | src/DuetNG/Pins_DuetNG.h | 10 | ||||
-rw-r--r-- | src/ExternalDrivers.cpp | 71 | ||||
-rw-r--r-- | src/ExternalDrivers.h | 1 | ||||
-rw-r--r-- | src/GCodes.cpp | 27 | ||||
-rw-r--r-- | src/Platform.cpp | 186 | ||||
-rw-r--r-- | src/Platform.h | 97 | ||||
-rw-r--r-- | src/Reprap.cpp | 18 |
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) { |