From 17d87503b81a989c3c323db33c211bc99fc5694a Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Mon, 28 Mar 2016 12:53:06 +0100 Subject: [PATCH] [lftimer->rtc] replace LF timer with always-running RTC timer --- firmware/src/init.c | 3 ++ firmware/src/main.c | 39 ++++++++++----------- firmware/src/rtc.c | 30 +++++++++++++++-- firmware/src/xosc.c | 82 ++++++++++++++++++++++----------------------- 4 files changed, 88 insertions(+), 66 deletions(-) diff --git a/firmware/src/init.c b/firmware/src/init.c index a001dba..16410e2 100644 --- a/firmware/src/init.c +++ b/firmware/src/init.c @@ -125,6 +125,9 @@ void init(enum init_type init_t) /* Configure the Power Manager */ powermananger_init(); + /* Start the RTC */ + rtc_init(); + /* We've done good things, kick wdt */ kick_the_watchdog(); diff --git a/firmware/src/main.c b/firmware/src/main.c index 288195f..1032088 100644 --- a/firmware/src/main.c +++ b/firmware/src/main.c @@ -42,6 +42,7 @@ #include "backlog.h" #include "pips.h" #include "xosc.h" +#include "rtc.h" #include "sequencer.h" #include "thermistor.h" @@ -257,9 +258,7 @@ void pips_telemetry(void) * Timing helpers * ============================================================================= */ - volatile uint8_t run_flag = 1; /* run immediately after init */ -uint32_t hibernate_time_s = 1; uint8_t in_cold_out = 1; /* test temperature immediately after init */ uint32_t cold_out_count = 0; @@ -269,35 +268,32 @@ uint32_t cold_out_count = 0; */ void set_hibernate_time(uint8_t cold_out) { - if (cold_out == 0) { /* Normal operations */ - if (gps_is_locked() == GPS_NO_LOCK) { /* no lock */ - hibernate_time_s = 0; /* shortest hibernate */ + uint32_t hibernate_time_s; + + if (cold_out == 0) { /* Normal operations */ + if (gps_is_locked() == GPS_NO_LOCK) { /* no lock */ + hibernate_time_s = 0; /* shortest hibernate */ } else if (gps_get_flight_state() == GPS_FLIGHT_STATE_LAUNCH) { - hibernate_time_s = 60-20; /* approx every minute */ + hibernate_time_s = CYCLE_TIME_FAST; } else { - hibernate_time_s = 240-20; /* approx every 4 minutes */ + hibernate_time_s = CYCLE_TIME_SLOW; } } else { /* cold out */ hibernate_time_s = COLD_OUT_SECONDS; } + + /* set this */ + rtc_hibernate_time(hibernate_time_s); } - /** - * Called on each tick of the low frequency clock + * Called when it's time to run again */ -void lf_tick(uint32_t tick) +void run_kick(void) { - /* When we're due to run again */ - /* Called at 2Hz */ - if (tick >= 2*hibernate_time_s) { - /* Stop */ - lf_tick_stop(); - - /* Raise the run flag */ - run_flag = 1; - } + /* Raise the run flag */ + run_flag = 1; } /** @@ -344,7 +340,7 @@ int main(void) run_sequencer(n++); /* run for the first time! */ } } else { - run_sequencer(n++); /* Run */ + run_sequencer(n++); /* Run */ } /* Clocks off */ @@ -359,9 +355,8 @@ int main(void) gclk0_to_lf_clock(); hf_clock_disable(); - /* LF timing */ + /* Hibernate timing */ set_hibernate_time(in_cold_out); - lf_tick_start(); } /* Idle */ diff --git a/firmware/src/rtc.c b/firmware/src/rtc.c index 53c3d9f..4284599 100644 --- a/firmware/src/rtc.c +++ b/firmware/src/rtc.c @@ -54,13 +54,29 @@ void rtc_init(void) /* Enable interrupts */ RTC->MODE1.INTENSET.reg |= RTC_MODE1_INTENSET_OVF; /* Overflow interrupt */ - irq_register_handler(RTC_IRQn, RTC_INT_PRIO); /* Highest Priority */ + irq_register_handler(RTC_IRQn, RTC_INT_PRIO); /* Lowest Priority */ /* Enable */ rtc_count_enable(); rtc_count_set_period(0); /* overflow on every tick */ } +/** + * Tick functions + * ============================================================================= + */ + +uint32_t tick = 0; +uint32_t hibernate_time_s = 0; +void run_kick(void); + +/** + * Set hibernate time + */ +void rtc_hibernate_time(uint32_t time_s) +{ + hibernate_time_s = time_s; +} /** * Interrupt for RTC, called at 1Hz */ @@ -69,6 +85,16 @@ void RTC_Handler(void) if (RTC->MODE1.INTFLAG.reg & RTC_MODE1_INTFLAG_OVF) { RTC->MODE1.INTFLAG.reg |= RTC_MODE1_INTFLAG_OVF; /* Clear flag */ - /* Do something */ + /* Check sleep time */ + if (tick >= hibernate_time_s) { + /* Zero tick */ + tick = 0; + + /* Do something */ + + } else { + /* Increment tick */ + tick++; + } } } diff --git a/firmware/src/xosc.c b/firmware/src/xosc.c index 7de63f3..a84794f 100644 --- a/firmware/src/xosc.c +++ b/firmware/src/xosc.c @@ -370,9 +370,6 @@ void timepulse_extint_event_source_disable(void) */ void lftimer_event_source(void) { - /* Start the RTC */ - rtc_init(); - /* Route the RTC PER7 event to event channel 0 */ events_allocate(0, EVENTS_EDGE_DETECT_NONE, /* Don't care for async path */ @@ -516,49 +513,50 @@ void TC2_Handler(void) * LF Tick ======================================================= * ============================================================================= */ -void lf_tick(uint32_t tick); -uint32_t lf_tick_count; +/* All this currently runs in sleep */ +/* void lf_tick(uint32_t tick); */ +/* uint32_t lf_tick_count; */ -void lf_tick_start(void) { +/* void lf_tick_start(void) { */ - /* Timer 4 runs on GCLK0 */ - bool t4_capture_channel_enables[] = {false, false}; - uint32_t t4_compare_channel_values[] = {64, 0x0000}; - /* Divide by 64*256 = 16384 */ - tc_init(TC4, - GCLK_GENERATOR_0, - TC_COUNTER_SIZE_16BIT, - TC_CLOCK_PRESCALER_DIV256, - TC_WAVE_GENERATION_MATCH_FREQ, - TC_RELOAD_ACTION_GCLK, - TC_COUNT_DIRECTION_UP, - TC_WAVEFORM_INVERT_OUTPUT_NONE, - false, /* Oneshot */ - true, /* Run in standby */ - 0x0000, /* Initial value */ - 0x0000, /* Top value */ - t4_capture_channel_enables, /* Capture Channel Enables */ - t4_compare_channel_values); /* Compare Channels Values */ +/* /\* Timer 4 runs on GCLK0 *\/ */ +/* bool t4_capture_channel_enables[] = {false, false}; */ +/* uint32_t t4_compare_channel_values[] = {64, 0x0000}; */ +/* /\* Divide by 64*256 = 16384 *\/ */ +/* tc_init(TC4, */ +/* GCLK_GENERATOR_0, */ +/* TC_COUNTER_SIZE_16BIT, */ +/* TC_CLOCK_PRESCALER_DIV256, */ +/* TC_WAVE_GENERATION_MATCH_FREQ, */ +/* TC_RELOAD_ACTION_GCLK, */ +/* TC_COUNT_DIRECTION_UP, */ +/* TC_WAVEFORM_INVERT_OUTPUT_NONE, */ +/* false, /\* Oneshot *\/ */ +/* true, /\* Run in standby *\/ */ +/* 0x0000, /\* Initial value *\/ */ +/* 0x0000, /\* Top value *\/ */ +/* t4_capture_channel_enables, /\* Capture Channel Enables *\/ */ +/* t4_compare_channel_values); /\* Compare Channels Values *\/ */ - /* Enable Interrupt */ - TC4->COUNT16.INTENSET.reg = TC_INTENSET_MC0; - irq_register_handler(TC4_IRQn, TC4_INT_PRIO); /* Low Priority */ +/* /\* Enable Interrupt *\/ */ +/* TC4->COUNT16.INTENSET.reg = TC_INTENSET_MC0; */ +/* irq_register_handler(TC4_IRQn, TC4_INT_PRIO); /\* Low Priority *\/ */ - tc_enable(TC4); - tc_start_counter(TC4); +/* tc_enable(TC4); */ +/* tc_start_counter(TC4); */ - lf_tick_count = 1; -} -void lf_tick_stop(void) { - tc_stop_counter(TC4); - tc_disable(TC4); -} -void TC4_Handler(void) -{ - if (tc_get_status(TC4) & TC_STATUS_CHANNEL_0_MATCH) { - tc_clear_status(TC4, TC_STATUS_CHANNEL_0_MATCH); +/* lf_tick_count = 1; */ +/* } */ +/* void lf_tick_stop(void) { */ +/* tc_stop_counter(TC4); */ +/* tc_disable(TC4); */ +/* } */ +/* void TC4_Handler(void) */ +/* { */ +/* if (tc_get_status(TC4) & TC_STATUS_CHANNEL_0_MATCH) { */ +/* tc_clear_status(TC4, TC_STATUS_CHANNEL_0_MATCH); */ - lf_tick(lf_tick_count++); - } -} +/* lf_tick(lf_tick_count++); */ +/* } */ +/* } */