diff --git a/Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino b/Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino index d5810384..3cbdc379 100644 --- a/Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino +++ b/Arduino/hardware/REV10/REV10SecureBHR/REV10SecureBHR.ino @@ -57,6 +57,13 @@ Author(s) / Copyright (s): Damon Hart-Davis 2013--2017 // If defined, do extra checks and serial logging. Will take more code space and power. #undef DEBUG +// If defined, disable all RX message handling. +#undef V0P2_DEBUG_NO_MESSAGE_QUEUE +// If defined, disable own stats tx +#undef V0P2_DEBUG_NO_STATSTX +// If defined, disable own stats encryption and tx. +#undef V0P2_DEBUG_NO_STATSENC + // *** Global flag for REVx configuration here *** // // e.g. @@ -149,7 +156,7 @@ constexpr size_t Decode_WorkspaceSize = OTAESGCM::OTAES128GCMGenericWithWorkspac * - Scratch space for the AESGCM decode function. */ constexpr uint8_t MSG_BUF_SIZE = 1 + 64 + 1; -constexpr uint8_t bufJSONlen = OTRadioLink::ENC_BODY_SMALL_FIXED_PTEXT_MAX_SIZE + 1; // 3 = '}' + 0x0 + ? FIXME whuut? +constexpr uint8_t bufJSONlen = OTRadioLink::ENC_BODY_SMALL_FIXED_PTEXT_MAX_SIZE + 1; constexpr uint8_t ptextBuflen = bufJSONlen + 2; // 2 = valvePC + hasStats static_assert(ptextBuflen == 34, "ptextBuflen wrong"); constexpr uint8_t scratchSpaceNeededHere = MSG_BUF_SIZE + ptextBuflen; // This is the scratch space needed locally by bareStatsTX, excluding called functions. @@ -216,7 +223,6 @@ OTRadValve::BoilerLogic::OnOffBoilerDriverLogic ss1; // Configured for maximum different stats. @@ -245,7 +251,6 @@ ISR(PCINT0_vect) // Handler routine not required/expected to 'clear' this interrupt. if((changes & RFM23B_INT_MASK) && !(pins & RFM23B_INT_MASK)) { PrimaryRadio._handleInterruptNonVirtual(); } - OTV0P2BASE::MemoryChecks::fnCalled(1U); } // Previous state of port D pins to help detect changes. @@ -326,7 +331,7 @@ static void panic(const __FlashStringHelper *s) inline void stackCheck() { const int16_t minsp = OTV0P2BASE::MemoryChecks::getMinSPSpaceBelowStackToEnd(); -#if 1 //&& defined(DEBUG) +#if 1 && defined(DEBUG) // const uint8_t location = OTV0P2BASE::MemoryChecks::getLocation(); // const uint16_t progCounter = OTV0P2BASE::MemoryChecks::getPC(); // not isr safe // OTV0P2BASE::serialPrintAndFlush(F("minsp: ")); @@ -340,7 +345,7 @@ inline void stackCheck() // OTV0P2BASE::MemoryChecks::forceResetIfStackOverflow(); // XXX OTV0P2BASE::MemoryChecks::resetMinSP(); #else - if(128 > minsp) { OTV0P2BASE::serialPrintlnAndFlush(F("!SP")); } + if(64 > minsp) { OTV0P2BASE::serialPrintlnAndFlush(F("!SP")); } OTV0P2BASE::MemoryChecks::forceResetIfStackOverflow(); #endif } @@ -376,7 +381,6 @@ bool pollIO(const bool force = false) PrimaryRadio.poll(); SecondaryRadio.poll(); } - OTV0P2BASE::MemoryChecks::fnCalled(2U); return(false); } @@ -404,12 +408,15 @@ inline bool decodeAndHandleSecureFrame(volatile const uint8_t * const msg) >(msg, sW); // Reenable interrupt line. PrimaryRadio.pauseInterrupts(false); - OTV0P2BASE::MemoryChecks::fnCalled(3U); return (success); } +#ifndef V0P2_DEBUG_NO_MESSAGE_QUEUE OTRadioLink::OTMessageQueueHandler< pollIO, V0P2_UART_BAUD, decodeAndHandleSecureFrame, OTRadioLink::decodeAndHandleDummyFrame // only interested in single frame type. > messageQueue; +#else +OTRadioLink::OTMessageQueueHandlerNull messageQueue; +#endif // Do bare stats transmission. @@ -436,13 +443,9 @@ static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_ // Send JSON message. bool sendingJSONFailed = false; // Set true and stop attempting JSON send in case of error. - - // Set pointer location based on whether start of message will have preamble TODO move to OTRFM23BLink queueToSend? - uint8_t *bptr = sW.buf; - // Leave space for possible leading frame-length byte, eg for encrypted frame. - ++bptr; - // Where to write the real frame content. - uint8_t *const realTXFrameStart = bptr; + // Where to write the real frame content, leaving space for leading + // frame-length byte for encrypted frame. + uint8_t *const realTXFrameStart = sW.buf + 1; // If forcing encryption or if unconditionally suppressed // then suppress the "@" ID field entirely, @@ -460,14 +463,9 @@ static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_ ss1.put(V0p2_SENSOR_TAG_F("b"), (int) BoilerHub.isBoilerOn()); // Show reset counter. Low priority. ss1.put(V0p2_SENSOR_TAG_F("R"), resetCount, true); -// // Send current stack, divided by 4 (). Low priority. -// // FIXME How would stack recording behaviour work? Do we want max stack: -// // - this minor cycle (interesting things may happen outside this tx cycle) -// // - this tx cycle (max stack usage may be missed, will need to change stack capture behaviour) -// // - ever (redundant after it's been received once) -// // FIXME How do we deal with case where max stack > 255? + // Send minimum stack left, saturating at 255 bytes. const size_t curMinSP = OTV0P2BASE::MemoryChecks::getMinSP(); - const uint8_t txMinSP = (255 >= curMinSP) ? (uint8_t) curMinSP : 255U; + const uint8_t txMinSP = (255U >= curMinSP) ? (uint8_t) curMinSP : 255U; ss1.put(V0p2_SENSOR_TAG_F("SP"), txMinSP, true); // OPTIONAL items constexpr uint8_t privacyLevel = OTV0P2BASE::stTXalwaysAll; @@ -514,8 +512,10 @@ static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_ OTV0P2BASE::serialPrintlnAndFlush(F("!TX key")); // Know why TX failed. } } + // If doing encryption then build encrypted frame from raw JSON. if(!sendingJSONFailed) { +#ifndef V0P2_DEBUG_NO_STATSENC // Explicit-workspace version of encryption. OTV0P2BASE::ScratchSpaceL subScratch(sW, scratchSpaceNeededHere); const OTRadioLink::SimpleSecureFrame32or0BodyTXBase::fixed32BTextSize12BNonce16BTagSimpleEncWithLWorkspace_ptr_t eW = OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleEnc_DEFAULT_WITH_LWORKSPACE; @@ -532,18 +532,21 @@ static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_ sendingJSONFailed = (0 == bodylen); wrote = bodylen - offset; if (sendingJSONFailed) OTV0P2BASE::serialPrintlnAndFlush(F("!TX Enc")); // Know why TX failed. +#endif } if(!sendingJSONFailed) { +#if !defined(V0P2_DEBUG_NO_STATSTX) || !defined(V0P2_DEBUG_NO_STATSENC) // Write out unadjusted JSON or encrypted frame on secondary radio. // Assumes that framing (or not) of primary and secondary radios is the same (usually: both framed). SecondaryRadio.queueToSend(realTXFrameStart, wrote); // Send directly to the primary radio... PrimaryRadio.queueToSend(realTXFrameStart, wrote); +#endif // V0P2_DEBUG_NO_STATSTX + } } if(neededWaking) { OTV0P2BASE::flushSerialProductive(); OTV0P2BASE::powerDownSerial(); } - OTV0P2BASE::MemoryChecks::fnCalled(4U); } @@ -590,7 +593,7 @@ void pollCLI(const uint8_t maxSCT, const bool startOfMinute, const OTV0P2BASE::S Serial.print(F("Resets: ")); Serial.print(resetCount); Serial.println(); -#if 1 +#if 0 // Show stack headroom. OTV0P2BASE::serialPrintAndFlush(F("SH ")); OTV0P2BASE::serialPrintAndFlush(OTV0P2BASE::MemoryChecks::getMinSPSpaceBelowStackToEnd()); OTV0P2BASE::serialPrintlnAndFlush(); #endif @@ -640,7 +643,7 @@ void setup() const uint8_t oldResetCount = eeprom_read_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT); resetCount = oldResetCount + 1; eeprom_write_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT, 1 + oldResetCount); -#if 1 // Print reset count. Intended for testing purposes. +#if 0 // Print reset count. Intended for testing purposes. OTV0P2BASE::serialPrintAndFlush(F("\rResets: ")); OTV0P2BASE::serialPrintAndFlush(oldResetCount); OTV0P2BASE::serialPrintlnAndFlush(); @@ -795,9 +798,6 @@ void loop() // Reset and immediately re-prime the RTC-based watchdog. OTV0P2BASE::resetRTCWatchDog(); OTV0P2BASE::enableRTCWatchdog(true); - // Capture loop call in profiler - OTV0P2BASE::MemoryChecks::fnCalled(0U); - // START LOOP BODY // =============== @@ -822,7 +822,6 @@ void loop() // Note: ensure only take ambient light reading at times when all LEDs are off (or turn them off). // TODO: coordinate temperature reading with time when radio and other heat-generating items are off for more accurate readings. const bool runAll = minute0From4ForSensors || (minuteCount < 4); - switch(TIME_LSD) // With V0P2BASE_TWO_S_TICK_RTC_SUPPORT only even seconds are available. { case 0: @@ -907,11 +906,10 @@ void loop() break; } } - -// // End-of-loop processing, that may be slow. XXX -// // Ensure progress on queued messages ahead of slow work. (TODO-867) -// pollIO();; // Deal with any pending I/O. -// messageQueue.handle(true, PrimaryRadio); // Deal with any pending I/O. + // End-of-loop processing, that may be slow. + // Ensure progress on queued messages ahead of slow work. (TODO-867) + pollIO();; // Deal with any pending I/O. + messageQueue.handle(true, PrimaryRadio); // Deal with any pending I/O. // Command-Line Interface (CLI) polling. // If a reasonable chunk of the minor cycle remains after all other work is done diff --git a/Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/REV7RadValve/REV7RadValve.ino b/Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/REV7RadValve/REV7RadValve.ino index d5c42bc6..b5ac67ab 100644 --- a/Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/REV7RadValve/REV7RadValve.ino +++ b/Arduino/hardware/V0p2_Main_PCB_REV7_DORM1_and_REV8/REV7RadValve/REV7RadValve.ino @@ -39,8 +39,8 @@ Author(s) / Copyright (s): Damon Hart-Davis 2013--2017 *****************************************************************************/ ////// GLOBAL flags that alter system build and behaviour. -//// If defined, do extra checks and serial logging. Will take more code space and power. -//#undef DEBUG +// If defined, do extra checks and serial logging. Will take more code space and power. +#undef DEBUG // *** Global flag for REVx configuration here *** // #define V0p2_REV 7 @@ -114,14 +114,17 @@ constexpr uint8_t SERIALRX_INT_MASK = 0b00000001; // Serial RX constexpr uint8_t MODE_INT_MASK = (1 << (BUTTON_MODE_L&7)); constexpr uint8_t MASK_PD = (SERIALRX_INT_MASK | MODE_INT_MASK); // MODE button interrupt (et al). +// Counter containing current no. of resets. +static uint8_t resetCount; + ////// SCRATCHSPACE -// Create scratch space for secure stats TX // FIXME +// Create scratch space for secure stats TX // Buffer need be no larger than leading length byte + typical 64-byte radio module TX buffer limit + optional terminator. constexpr uint8_t MSG_BUF_SIZE = 1 + 64 + 1; -constexpr uint8_t bufEncJSONlen = OTRadioLink::ENC_BODY_SMALL_FIXED_PTEXT_MAX_SIZE + 1; // 3 = '}' + 0x0 + ? FIXME whuut? -constexpr uint8_t ptextBuflen = bufEncJSONlen + 2; // 2 = valvePC + hasStats -static_assert(ptextBuflen == 34, "ptextBuflen wrong"); // TODO make sure this is correct! +constexpr uint8_t bufEncJSONlen = OTRadioLink::ENC_BODY_SMALL_FIXED_PTEXT_MAX_SIZE + 1; +constexpr uint8_t ptextBuflen = bufEncJSONlen + 2; +static_assert(ptextBuflen == 34, "ptextBuflen wrong"); constexpr uint8_t scratchSpaceNeeded = MSG_BUF_SIZE + ptextBuflen; constexpr size_t StatsTX_WorkspaceSize = OTRadioLink::SimpleSecureFrame32or0BodyTXBase::generateSecureOFrameRawForTX_total_scratch_usage_OTAESGCM_2p0 + scratchSpaceNeeded; static_assert(StatsTX_WorkspaceSize == 384, "StatsTX workspace size wrong!"); // Correct as of 20170704 @@ -292,7 +295,7 @@ valveUI_t valveUI( ////// MESSAGING // Managed JSON stats. -OTV0P2BASE::SimpleStatsRotation<12> ss1; // Configured for maximum different stats. // FIXME REDUCE AS MUCH AS POSSIBLE +OTV0P2BASE::SimpleStatsRotation<13> ss1; // Configured for maximum different stats. /****************************************************************************** @@ -362,7 +365,7 @@ void panic(const __FlashStringHelper *s) { inline void stackCheck() { const int16_t minsp = OTV0P2BASE::MemoryChecks::getMinSPSpaceBelowStackToEnd(); -#if 1 //&& defined(DEBUG) +#if 1 && defined(DEBUG) const uint8_t location = OTV0P2BASE::MemoryChecks::getLocation(); const uint16_t progCounter = OTV0P2BASE::MemoryChecks::getPC(); // not isr safe OTV0P2BASE::serialPrintAndFlush(F("minsp: ")); @@ -375,7 +378,7 @@ inline void stackCheck() // OTV0P2BASE::MemoryChecks::forceResetIfStackOverflow(); // XXX OTV0P2BASE::MemoryChecks::resetMinSP(); #else - if(128 > minsp) { OTV0P2BASE::serialPrintlnAndFlush(F("!SP")); } + if(64 > minsp) { OTV0P2BASE::serialPrintlnAndFlush(F("!SP")); } OTV0P2BASE::MemoryChecks::forceResetIfStackOverflow(); #endif } @@ -406,7 +409,6 @@ void updateSensorsFromStats() { // * force if true then force full poll on every call (ie do not internally rate-limit) // Note that radio poll() can be for TX as well as RX activity. // Not thread-safe, eg not to be called from within an ISR. -// FIXME trying to move into utils (for the time being.) bool pollIO(const bool force = false) { static volatile uint8_t _pO_lastPoll; // Poll RX at most about every ~8ms. @@ -427,7 +429,7 @@ bool pollIO(const bool force = false) { // Will be run after all stats for the current hour have been updated. static void endOfDayTasks() { // Count down the setback lockout if not finished... (TODO-786, TODO-906) -// OTRadValve::countDownSetbackLockout(); + OTRadValve::countDownSetbackLockout(); } @@ -443,27 +445,19 @@ static void endOfDayTasks() { // as assumed supplied by security layer to remote recipent. void bareStatsTX() { - OTV0P2BASE::MemoryChecks::resetMinSP(); -// // Capture heavy stack usage from local allocations here. + // Capture heavy stack usage from local allocations here. OTV0P2BASE::MemoryChecks::recordIfMinSP(); const bool neededWaking = OTV0P2BASE::powerUpSerialIfDisabled<>(); static_assert(OTV0P2BASE::FullStatsMessageCore_MAX_BYTES_ON_WIRE <= STATS_MSG_MAX_LEN, "FullStatsMessageCore_MAX_BYTES_ON_WIRE too big"); static_assert(OTV0P2BASE::MSG_JSON_MAX_LENGTH+1 <= STATS_MSG_MAX_LEN, "MSG_JSON_MAX_LENGTH too big"); // Allow 1 for trailing CRC. OTV0P2BASE::ScratchSpaceL sW(globalWorkSpace.statsTX, sizeof(globalWorkSpace.statsTX)); - // Allow space in buffer for: - // * buffer offset/preamble - // * max binary length, or max JSON length + 1 for CRC + 1 to allow detection of oversize message - // * terminating 0xff - uint8_t * const buf = sW.buf; - // Send binary *or* JSON on each attempt so as not to overwhelm the receiver. - // Send JSON message. + bool sendingJSONFailed = false; // Set true and stop attempting JSON send in case of error. - // Set pointer location based on whether start of message will have preamble TODO move to OTRFM23BLink queueToSend? - uint8_t *bptr = buf; - // Leave space for possible leading frame-length byte, eg for encrypted frame. - ++bptr; - // Where to write the real frame content. - uint8_t *const realTXFrameStart = bptr; + + uint8_t *const buf = sW.buf; + // Where to write the real frame content, leaving space for leading + // frame-length byte for encrypted frame. + uint8_t *const realTXFrameStart = buf + 1; // If forcing encryption or if unconditionally suppressed // then suppress the "@" ID field entirely, // assuming that the encrypted commands will carry the ID, ie in the 'envelope'. @@ -488,6 +482,15 @@ void bareStatsTX() { ss1.put(NominalRadValve.cumulativeMovementSubSensor); // Show state of setback lockout. ss1.put(V0p2_SENSOR_TAG_F("gE"), OTRadValve::getSetbackLockout(), true); + + // Show reset counter. Low priority. + ss1.put(V0p2_SENSOR_TAG_F("R"), resetCount, true); + // Send minimum stack left, saturating at 255 bytes. + const size_t curMinSP = OTV0P2BASE::MemoryChecks::getMinSP(); + const uint8_t txMinSP = (255U >= curMinSP) ? (uint8_t) curMinSP : 255U; + ss1.put(V0p2_SENSOR_TAG_F("SP"), txMinSP, true); + + const uint8_t privacyLevel = OTV0P2BASE::stTXalwaysAll; // Redirect JSON output appropriately. // Part of sW, directly after the message buffer. @@ -530,7 +533,6 @@ void bareStatsTX() { // If doing encryption // then build encrypted frame from raw JSON. if(!sendingJSONFailed) { - // TODO Fold JSON // Explicit-workspace version of encryption. const OTRadioLink::SimpleSecureFrame32or0BodyTXBase::fixed32BTextSize12BNonce16BTagSimpleEncWithLWorkspace_ptr_t eW = OTAESGCM::fixed32BTextSize12BNonce16BTagSimpleEnc_DEFAULT_WITH_LWORKSPACE; // Create subscratch space for encryption functions @@ -597,19 +599,19 @@ void pollCLI(const uint8_t maxSCT, const bool startOfMinute, const OTV0P2BASE::S // Show/set generic parameter values (eg "G N [M]"). case 'G': { OTV0P2BASE::CLI::GenericParam().doCommand(buf, n); break; } // Reset or display ID. - case 'I': { OTV0P2BASE::CLI::NodeIDWithSet().doCommand(buf, n); break; } // XXX + case 'I': { OTV0P2BASE::CLI::NodeIDWithSet().doCommand(buf, n); break; } // Status line stats print and TX. - case 'S': { - Serial.print(F("Resets: ")); - const uint8_t resetCount = eeprom_read_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT); - Serial.print(resetCount); - Serial.println(); - // Show stack headroom. - OTV0P2BASE::serialPrintAndFlush(F("SH ")); OTV0P2BASE::serialPrintAndFlush(OTV0P2BASE::MemoryChecks::getMinSPSpaceBelowStackToEnd()); OTV0P2BASE::serialPrintlnAndFlush(); - // Default light-weight print and TX of stats. -// bareStatsTX(); // FIXME No way this won't overflow! - break; // Note that status is by default printed after processing input line. - } +// case 'S': { +// Serial.print(F("Resets: ")); +// const uint8_t resetCount = eeprom_read_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT); +// Serial.print(resetCount); +// Serial.println(); +// // Show stack headroom. +// OTV0P2BASE::serialPrintAndFlush(F("SH ")); OTV0P2BASE::serialPrintAndFlush(OTV0P2BASE::MemoryChecks::getMinSPSpaceBelowStackToEnd()); OTV0P2BASE::serialPrintlnAndFlush(); +// // Default light-weight print and TX of stats. +//// bareStatsTX(); // FIXME No way this won't overflow! +// break; // Note that status is by default printed after processing input line. +// } // Switch to FROST mode OR set FROST/setback temperature (even with temp pot available). // With F! force to frost and holiday (long-vacant) mode. Useful for testing and for remote CLI use. case 'F': { @@ -622,7 +624,7 @@ void pollCLI(const uint8_t maxSCT, const bool startOfMinute, const OTV0P2BASE::S * function pointer MUST be passed here to ensure safe handling of the key and the Tx message * counter. */ - case 'K': { OTV0P2BASE::CLI::SetSecretKey(OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::resetRaw3BytePersistentTXRestartCounterCond).doCommand(buf, n); break; } // XXX + case 'K': { OTV0P2BASE::CLI::SetSecretKey(OTRadioLink::SimpleSecureFrame32or0BodyTXV0p2::resetRaw3BytePersistentTXRestartCounterCond).doCommand(buf, n); break; } // Switch to WARM (not BAKE) mode OR set WARM temperature. case 'W':{ valveMode.cancelBakeDebounced(); // Ensure BAKE mode not entered. @@ -630,7 +632,7 @@ void pollCLI(const uint8_t maxSCT, const bool startOfMinute, const OTV0P2BASE::S break; } // Zap/erase learned statistics. - case 'Z': { OTV0P2BASE::CLI::ZapStats().doCommand(buf, n); break; } // XXX + case 'Z': { OTV0P2BASE::CLI::ZapStats().doCommand(buf, n); break; } } // Else show ack of command received. Serial.println(F("OK")); @@ -659,7 +661,13 @@ void setup() V0p2Base_serialPrintlnBuildVersion(); // Count resets to detect unexpected crashes/restarts. const uint8_t oldResetCount = eeprom_read_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT); + resetCount = oldResetCount + 1; eeprom_write_byte((uint8_t *)V0P2BASE_EE_START_RESET_COUNT, 1 + oldResetCount); +#if 0 // Print reset count. Intended for testing purposes. + OTV0P2BASE::serialPrintAndFlush(F("\rResets: ")); + OTV0P2BASE::serialPrintAndFlush(oldResetCount); + OTV0P2BASE::serialPrintlnAndFlush(); +#endif // Have 32678Hz clock at least running before going any further. // Check that the slow clock is running reasonably OK, and tune the fast one to it. @@ -721,23 +729,19 @@ void setup() // Initialise sensors with stats info where needed. updateSensorsFromStats(); - OTV0P2BASE::MemoryChecks::resetMinSP(); - OTV0P2BASE::MemoryChecks::recordIfMinSP(1); - stackCheck(); - // Do early 'wake-up' stats transmission if possible // XXX // when everything else is set up and ready and allowed (TODO-636) // including all set-up and inter-wiring of sensors/actuators. // Attempt to maximise chance of reception with a double TX. // Assume not in hub mode (yet). // Send all possible formats, binary first (assumed complete in one message). - bareStatsTX(); // XXX + bareStatsTX(); // Send JSON stats repeatedly (typically once or twice) // until all values pushed out (no 'changed' values unsent) // or limit reached. for(uint8_t i = 5; --i > 0; ) { ::OTV0P2BASE::nap(WDTO_120MS, false); // Sleep long enough for receiver to have a chance to process previous TX. - bareStatsTX(); // XXX + bareStatsTX(); if(!ss1.changedValue()) { break; } } // Start local counters in randomised positions to help avoid inter-unit collisions, @@ -760,11 +764,6 @@ void setup() void loop() { -#if defined(EST_CPU_DUTYCYCLE) - const unsigned long usStart = micros(); -#endif - OTV0P2BASE::MemoryChecks::resetMinSP(); - OTV0P2BASE::MemoryChecks::recordIfMinSP(2); stackCheck(); // Main loop for OpenTRV radiator control. @@ -847,7 +846,7 @@ void loop() // Tasks that must be run every minute. ++minuteCount; // Note simple roll-over to 0 at max value. // Force to user's programmed schedule(s), if any, at the correct time. - Scheduler.applyUserSchedule(&valveMode, OTV0P2BASE::getMinutesSinceMidnightLT()); // XXX + Scheduler.applyUserSchedule(&valveMode, OTV0P2BASE::getMinutesSinceMidnightLT()); // Ensure that the RTC has been persisted promptly when necessary. OTV0P2BASE::persistRTC(); // Run hourly tasks at the end of the hour. @@ -974,20 +973,5 @@ void loop() OTV0P2BASE::ScratchSpace s((uint8_t*)globalWorkSpace.cli, sizeof(globalWorkSpace.cli)); pollCLI(stopBy, 0 == TIME_LSD, s); } -#if defined(EST_CPU_DUTYCYCLE) - const unsigned long usEnd = micros(); - // Nominal loop time should be 2s x 1MHz clock, ie 2,000,000 if CPU running all the time. - // Should generally be <2000 (us) (<0.1%) for leaf, <20000 (<1%) for hub. - // Example output. - //us apparent: 4544 - //us apparent: 25280 - //us apparent: 9280 - const unsigned long usApparentTaken = usEnd - usStart; -#if 1 && defined(DEBUG) - DEBUG_SERIAL_PRINT_FLASHSTRING("us apparent: "); - DEBUG_SERIAL_PRINT(usApparentTaken); - DEBUG_SERIAL_PRINTLN(); -#endif -#endif }