[lftimer->rtc] replace LF timer with always-running RTC timer

main-solar-only
Richard Meadows 2016-03-28 12:53:06 +01:00
rodzic 77f29a5f74
commit 17d87503b8
4 zmienionych plików z 88 dodań i 66 usunięć

Wyświetl plik

@ -125,6 +125,9 @@ void init(enum init_type init_t)
/* Configure the Power Manager */ /* Configure the Power Manager */
powermananger_init(); powermananger_init();
/* Start the RTC */
rtc_init();
/* We've done good things, kick wdt */ /* We've done good things, kick wdt */
kick_the_watchdog(); kick_the_watchdog();

Wyświetl plik

@ -42,6 +42,7 @@
#include "backlog.h" #include "backlog.h"
#include "pips.h" #include "pips.h"
#include "xosc.h" #include "xosc.h"
#include "rtc.h"
#include "sequencer.h" #include "sequencer.h"
#include "thermistor.h" #include "thermistor.h"
@ -257,9 +258,7 @@ void pips_telemetry(void)
* Timing helpers * Timing helpers
* ============================================================================= * =============================================================================
*/ */
volatile uint8_t run_flag = 1; /* run immediately after init */ 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 */ uint8_t in_cold_out = 1; /* test temperature immediately after init */
uint32_t cold_out_count = 0; uint32_t cold_out_count = 0;
@ -269,35 +268,32 @@ uint32_t cold_out_count = 0;
*/ */
void set_hibernate_time(uint8_t cold_out) void set_hibernate_time(uint8_t cold_out)
{ {
if (cold_out == 0) { /* Normal operations */ uint32_t hibernate_time_s;
if (gps_is_locked() == GPS_NO_LOCK) { /* no lock */
hibernate_time_s = 0; /* shortest hibernate */ 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) { } 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 { } else {
hibernate_time_s = 240-20; /* approx every 4 minutes */ hibernate_time_s = CYCLE_TIME_SLOW;
} }
} else { /* cold out */ } else { /* cold out */
hibernate_time_s = COLD_OUT_SECONDS; 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 */ /* Raise the run flag */
/* Called at 2Hz */ run_flag = 1;
if (tick >= 2*hibernate_time_s) {
/* Stop */
lf_tick_stop();
/* Raise the run flag */
run_flag = 1;
}
} }
/** /**
@ -344,7 +340,7 @@ int main(void)
run_sequencer(n++); /* run for the first time! */ run_sequencer(n++); /* run for the first time! */
} }
} else { } else {
run_sequencer(n++); /* Run */ run_sequencer(n++); /* Run */
} }
/* Clocks off */ /* Clocks off */
@ -359,9 +355,8 @@ int main(void)
gclk0_to_lf_clock(); gclk0_to_lf_clock();
hf_clock_disable(); hf_clock_disable();
/* LF timing */ /* Hibernate timing */
set_hibernate_time(in_cold_out); set_hibernate_time(in_cold_out);
lf_tick_start();
} }
/* Idle */ /* Idle */

Wyświetl plik

@ -54,13 +54,29 @@ void rtc_init(void)
/* Enable interrupts */ /* Enable interrupts */
RTC->MODE1.INTENSET.reg |= RTC_MODE1_INTENSET_OVF; /* Overflow interrupt */ 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 */ /* Enable */
rtc_count_enable(); rtc_count_enable();
rtc_count_set_period(0); /* overflow on every tick */ 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 * Interrupt for RTC, called at 1Hz
*/ */
@ -69,6 +85,16 @@ void RTC_Handler(void)
if (RTC->MODE1.INTFLAG.reg & RTC_MODE1_INTFLAG_OVF) { if (RTC->MODE1.INTFLAG.reg & RTC_MODE1_INTFLAG_OVF) {
RTC->MODE1.INTFLAG.reg |= RTC_MODE1_INTFLAG_OVF; /* Clear flag */ 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++;
}
} }
} }

Wyświetl plik

@ -370,9 +370,6 @@ void timepulse_extint_event_source_disable(void)
*/ */
void lftimer_event_source(void) void lftimer_event_source(void)
{ {
/* Start the RTC */
rtc_init();
/* Route the RTC PER7 event to event channel 0 */ /* Route the RTC PER7 event to event channel 0 */
events_allocate(0, events_allocate(0,
EVENTS_EDGE_DETECT_NONE, /* Don't care for async path */ EVENTS_EDGE_DETECT_NONE, /* Don't care for async path */
@ -516,49 +513,50 @@ void TC2_Handler(void)
* LF Tick ======================================================= * LF Tick =======================================================
* ============================================================================= * =============================================================================
*/ */
void lf_tick(uint32_t tick); /* All this currently runs in sleep */
uint32_t lf_tick_count; /* 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 */ /* /\* Timer 4 runs on GCLK0 *\/ */
bool t4_capture_channel_enables[] = {false, false}; /* bool t4_capture_channel_enables[] = {false, false}; */
uint32_t t4_compare_channel_values[] = {64, 0x0000}; /* uint32_t t4_compare_channel_values[] = {64, 0x0000}; */
/* Divide by 64*256 = 16384 */ /* /\* Divide by 64*256 = 16384 *\/ */
tc_init(TC4, /* tc_init(TC4, */
GCLK_GENERATOR_0, /* GCLK_GENERATOR_0, */
TC_COUNTER_SIZE_16BIT, /* TC_COUNTER_SIZE_16BIT, */
TC_CLOCK_PRESCALER_DIV256, /* TC_CLOCK_PRESCALER_DIV256, */
TC_WAVE_GENERATION_MATCH_FREQ, /* TC_WAVE_GENERATION_MATCH_FREQ, */
TC_RELOAD_ACTION_GCLK, /* TC_RELOAD_ACTION_GCLK, */
TC_COUNT_DIRECTION_UP, /* TC_COUNT_DIRECTION_UP, */
TC_WAVEFORM_INVERT_OUTPUT_NONE, /* TC_WAVEFORM_INVERT_OUTPUT_NONE, */
false, /* Oneshot */ /* false, /\* Oneshot *\/ */
true, /* Run in standby */ /* true, /\* Run in standby *\/ */
0x0000, /* Initial value */ /* 0x0000, /\* Initial value *\/ */
0x0000, /* Top value */ /* 0x0000, /\* Top value *\/ */
t4_capture_channel_enables, /* Capture Channel Enables */ /* t4_capture_channel_enables, /\* Capture Channel Enables *\/ */
t4_compare_channel_values); /* Compare Channels Values */ /* t4_compare_channel_values); /\* Compare Channels Values *\/ */
/* Enable Interrupt */ /* /\* Enable Interrupt *\/ */
TC4->COUNT16.INTENSET.reg = TC_INTENSET_MC0; /* TC4->COUNT16.INTENSET.reg = TC_INTENSET_MC0; */
irq_register_handler(TC4_IRQn, TC4_INT_PRIO); /* Low Priority */ /* irq_register_handler(TC4_IRQn, TC4_INT_PRIO); /\* Low Priority *\/ */
tc_enable(TC4); /* tc_enable(TC4); */
tc_start_counter(TC4); /* tc_start_counter(TC4); */
lf_tick_count = 1; /* lf_tick_count = 1; */
} /* } */
void lf_tick_stop(void) { /* void lf_tick_stop(void) { */
tc_stop_counter(TC4); /* tc_stop_counter(TC4); */
tc_disable(TC4); /* tc_disable(TC4); */
} /* } */
void TC4_Handler(void) /* void TC4_Handler(void) */
{ /* { */
if (tc_get_status(TC4) & TC_STATUS_CHANNEL_0_MATCH) { /* if (tc_get_status(TC4) & TC_STATUS_CHANNEL_0_MATCH) { */
tc_clear_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++); */
} /* } */
} /* } */