fn RTC0() {
    let mut reading = 0.;

    free(|cs| {
        access_global!(RTC, rtc, cs);
        rtc.reset_event(RtcInterrupt::Compare0);
        rtc.clear_counter();

        access_global!(TWIM, twim, cs);

        if SENSOR_SLEEPING.load(Ordering::Acquire) {
            SENSOR_SLEEPING.store(false, Ordering::Release);
            // todo: Swap etc
            access_global!(SDA, sda, cs);
            access_global!(SCL, scl, cs);
            access_global!(SENSOR_WAKE_TIMER, sensor_wake_timer, cs);
            sensor::wake(twim, scl, sda, sensor_wake_timer);
        }

        reading = sensor::read_temp(twim).unwrap_or(3.);
    });

    // Sometimes after sensor wake, our readings are -273.15. Unknown cause. Note that this is the same
    // reading we get if attempting to take a reading while the sensor is asleep.
    let temp_valid = (reading - 3.).abs() > 0.01 && (reading - -273.15).abs() > 0.01;

    if !temp_valid {
        return;
    }

    // If temperature is above a thresh, set the active sleep time. Otherwise,
    // command idle, which will execute power-saving steps, and us a longer sleep time,
    // after a timer expires.
    free(|cs| {
        let mode = OP_MODE.borrow(cs).get();

        access_global!(COOL_THRESH_TIMER, cool_thresh_timer, cs);

        if reading >= SHOW_READING_THRESH {
            cool_thresh_timer.stop();

            if let OpMode::Idle = mode {
                OP_MODE.borrow(cs).set(OpMode::Active);
                access_global!(RTC, rtc, cs);
                rtc.set_compare(
                    RtcCompareReg::Compare0,
                    (LFCLK_FREQ as f32 * SLEEP_TIME_ACTIVE) as u32,
                )
                .unwrap();
            }
        } else {
            match mode {
                OpMode::Active => {
                    // If we were active but are now below the thresh, and haven't already,
                    // start the cool thresh timer.
                    if !COOL_THRESH_TIMER_RUNNING.load(Ordering::Acquire) {
                        // todo: Swap etc
                        COOL_THRESH_TIMER_RUNNING.store(true, Ordering::Release);
                        cool_thresh_timer.start();
                    }
                }
                OpMode::Idle => {
                    // We just woke up the sensor, but don't need to go active; go back to sleep,
                    // and don't show anything on the display.
                    access_global!(TWIM, twim, cs);
                    access_global!(SCL, scl, cs);
                    sensor::sleep(twim, scl);
                    SENSOR_SLEEPING.store(true, Ordering::Release);
                }
                // We should never enter the RTC from the menu; only Active and Idle should show up.
                OpMode::SurfaceMenu => {} // todo: Role of SurfaceMenu on this sensor firmware?
            }
        }
    });

    transmit(reading); // `transmit` has it's own CS; don't nest.
}
/// Wake the device up, take a reading, and transmit it. Change between active and
/// idle modes based on if the reading indicates the stove it on and/or hot.
Wake the device up, take a reading, and transmit it. Change between active and
idle modes based on if the reading indicates the stove it on and/or hot.
Wake the device up take a reading and transmit it . Change between active and idle modes based on if the reading indicates the stove it on and / or hot .
fn RTC0() {
    let mut reading = 0.;
    free(|cs| {
        access_global!(RTC, rtc, cs);
        rtc.reset_event(RtcInterrupt::Compare0);
        rtc.clear_counter();
        access_global!(TWIM, twim, cs);
        if SENSOR_SLEEPING.load(Ordering::Acquire) {
            SENSOR_SLEEPING.store(false, Ordering::Release);
            // todo: Swap etc
            access_global!(SDA, sda, cs);
            access_global!(SCL, scl, cs);
            access_global!(SENSOR_WAKE_TIMER, sensor_wake_timer, cs);
            sensor::wake(twim, scl, sda, sensor_wake_timer);
        }
        reading = sensor::read_temp(twim).unwrap_or(3.);
    });
    // Sometimes after sensor wake, our readings are -273.15. Unknown cause. Note that this is the same
    // reading we get if attempting to take a reading while the sensor is asleep.
    let temp_valid = (reading - 3.).abs() > 0.01 && (reading - -273.15).abs() > 0.01;
    if !temp_valid {
        return;
    }
    // If temperature is above a thresh, set the active sleep time. Otherwise,
    // command idle, which will execute power-saving steps, and us a longer sleep time,
    // after a timer expires.
    free(|cs| {
        let mode = OP_MODE.borrow(cs).get();
        access_global!(COOL_THRESH_TIMER, cool_thresh_timer, cs);
        if reading >= SHOW_READING_THRESH {
            cool_thresh_timer.stop();
            if let OpMode::Idle = mode {
                OP_MODE.borrow(cs).set(OpMode::Active);
                access_global!(RTC, rtc, cs);
                rtc.set_compare(
                    RtcCompareReg::Compare0,
                    (LFCLK_FREQ as f32 * SLEEP_TIME_ACTIVE) as u32,
                )
                .unwrap();
            }
        } else {
            match mode {
                OpMode::Active => {
                    // If we were active but are now below the thresh, and haven't already,
                    // start the cool thresh timer.
                    if !COOL_THRESH_TIMER_RUNNING.load(Ordering::Acquire) {
                        // todo: Swap etc
                        COOL_THRESH_TIMER_RUNNING.store(true, Ordering::Release);
                        cool_thresh_timer.start();
                    }
                }
                OpMode::Idle => {
                    // We just woke up the sensor, but don't need to go active; go back to sleep,
                    // and don't show anything on the display.
                    access_global!(TWIM, twim, cs);
                    access_global!(SCL, scl, cs);
                    sensor::sleep(twim, scl);
                    SENSOR_SLEEPING.store(true, Ordering::Release);
                }
                // We should never enter the RTC from the menu; only Active and Idle should show up.
                OpMode::SurfaceMenu => {} // todo: Role of SurfaceMenu on this sensor firmware?
            }
        }
    });
    transmit(reading); // `transmit` has it's own CS; don't nest.
}
fn RTC0 ( ) { let mut reading = 0. ; free ( | cs | { access_global ! ( RTC rtc cs ) ; rtc . reset_event ( RtcInterrupt :: Compare0 ) ; rtc . clear_counter ( ) ; access_global ! ( TWIM twim cs ) ; if SENSOR_SLEEPING . load ( Ordering :: Acquire ) { SENSOR_SLEEPING . store ( false , Ordering :: Release ) ; // todo: Swap etc access_global ! ( SDA sda cs ) ; access_global ! ( SCL scl cs ) ; access_global ! ( SENSOR_WAKE_TIMER sensor_wake_timer cs ) ; sensor :: wake ( twim , scl , sda , sensor_wake_timer ) ; } reading = sensor :: read_temp ( twim ) . unwrap_or ( 3. ) ; } ) ; // Sometimes after sensor wake, our readings are -273.15. Unknown cause. Note that this is the same // reading we get if attempting to take a reading while the sensor is asleep. let temp_valid = ( reading - 3. ) . abs ( ) > 0.01 && ( reading - - 273.15 ) . abs ( ) > 0.01 ; if ! temp_valid { return ; } // If temperature is above a thresh, set the active sleep time. Otherwise, // command idle, which will execute power-saving steps, and us a longer sleep time, // after a timer expires. free ( | cs | { let mode = OP_MODE . borrow ( cs ) . get ( ) ; access_global ! ( COOL_THRESH_TIMER cool_thresh_timer cs ) ; if reading >= SHOW_READING_THRESH { cool_thresh_timer . stop ( ) ; if let OpMode :: Idle = mode { OP_MODE . borrow ( cs ) . set ( OpMode :: Active ) ; access_global ! ( RTC rtc cs ) ; rtc . set_compare ( RtcCompareReg :: Compare0 , ( LFCLK_FREQ as f32 * SLEEP_TIME_ACTIVE ) as u32 , ) . unwrap ( ) ; } } else { match mode { OpMode :: Active => { // If we were active but are now below the thresh, and haven't already, // start the cool thresh timer. if ! COOL_THRESH_TIMER_RUNNING . load ( Ordering :: Acquire ) { // todo: Swap etc COOL_THRESH_TIMER_RUNNING . store ( true , Ordering :: Release ) ; cool_thresh_timer . start ( ) ; } } OpMode :: Idle => { // We just woke up the sensor, but don't need to go active; go back to sleep, // and don't show anything on the display. access_global ! ( TWIM twim cs ) ; access_global ! ( SCL scl cs ) ; sensor :: sleep ( twim , scl ) ; SENSOR_SLEEPING . store ( true , Ordering :: Release ) ; } // We should never enter the RTC from the menu; only Active and Idle should show up. OpMode :: SurfaceMenu => { } // todo: Role of SurfaceMenu on this sensor firmware? } } } ) ; transmit ( reading ) ; // `transmit` has it's own CS; don't nest. }
Wake the device up, take a reading, and transmit it.
Wake the device up take a reading and transmit it .