Interrupt on both edges of the gps timepulse to ensure we hit the hardware watchdog often enough. Also control the external WDI line as an awake/asleep trigger for debugging.

This introduces a uncertainty of ±0.5s on the internal time, but we can ignore that for the moment
master
Richard Meadows 2015-07-18 16:53:25 +01:00
rodzic f7221454f0
commit b543316b42
7 zmienionych plików z 39 dodań i 23 usunięć

Wyświetl plik

@ -30,7 +30,7 @@
*/
#define PIPS_RATE 1
#define PIPS_LENGTH_MS 250
#define PIPS_LENGTH_MS 200
#define PIPS_FREQUENCY (1000 / PIPS_LENGTH_MS)
#endif /* PIPS_H */

Wyświetl plik

@ -52,6 +52,7 @@ struct idle_counter {
uint32_t wait_for_next_telemetry;
};
void awake_do_watchdog(void);
void kick_the_watchdog(void);
void idle(idle_wait_t idle_t);
void watchdog_init(void);

Wyświetl plik

@ -48,6 +48,7 @@
#include "system/system.h"
#include "system/pinmux.h"
#include "adc/adc.h"
#include "watchdog.h"
#define Assert assert
@ -531,6 +532,8 @@ enum adc_status_code adc_init(Adc *hw,
/** Interrupt handler for the ADC module. */
void ADC_Handler(void)
{
awake_do_watchdog();
/* get interrupt flags and mask out enabled callbacks */
uint32_t flags = module_inst.hw->INTFLAG.reg;

Wyświetl plik

@ -41,7 +41,7 @@
#include "system/port.h"
#include "tc/tc_driver.h"
#include "hw_config.h"
#include "watchdog.h"
/**
* CYCLIC REDUNDANCY CHECK (CRC)
@ -418,6 +418,8 @@ void timer0_tick_deinit()
*/
void TC0_Handler(void)
{
awake_do_watchdog();
while (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);

Wyświetl plik

@ -31,8 +31,9 @@
#include "system/events.h"
#include "system/interrupt.h"
#include "system/port.h"
#include "watchdog.h"
uint32_t gps_timepulse_count = 0;
volatile uint32_t gps_timepulse_count = 0;
uint32_t timepulse_sequence = 0;
timepulse_callback_t _timer_callback;
@ -56,15 +57,15 @@ void timepulse_extint_init(void) {
struct extint_chan_conf config;
config.gpio_pin = GPS_TIMEPULSE_PIN;
config.gpio_pin_mux = GPS_TIMEPULSE_PINMUX;
config.gpio_pin_pull = EXTINT_PULL_NONE; // ???
config.wake_if_sleeping = false; // ???
config.gpio_pin_pull = EXTINT_PULL_DOWN;
config.wake_if_sleeping = true;
config.filter_input_signal = false;
config.detection_criteria = EXTINT_DETECT_RISING;
config.detection_criteria = EXTINT_DETECT_BOTH;
extint_chan_set_config(GPS_TIMEPULSE_EXTINT, &config);
/* We route this event to event channel 0 */
events_allocate(0,
EVENTS_EDGE_DETECT_NONE,
EVENTS_EDGE_DETECT_NONE, /* Don't care for async path */
EVENTS_PATH_ASYNCHRONOUS,
0xC + GPS_TIMEPULSE_EXTINT, /* External Interrupt Number */
0);
@ -83,14 +84,16 @@ void timepulse_set_callback(timepulse_callback_t callback) {
/**
* EIC Handler, triggered by the GPS at GPS_TIMEPULSE_FREQ Hz
*/
void EIC_Handler(void) {
void EIC_Handler(void)
{
awake_do_watchdog();
if (EIC->INTFLAG.reg & (1 << GPS_TIMEPULSE_EXTINT)) {
EIC->INTFLAG.reg = (1 << GPS_TIMEPULSE_EXTINT);
gps_timepulse_count++;
/* Runs at 1Hz */
if (gps_timepulse_count >= GPS_TIMEPULSE_FREQ) {
if (gps_timepulse_count >= GPS_TIMEPULSE_FREQ * 2) { /* Both */
gps_timepulse_count = 0;
/* Make the callback if we have one */

Wyświetl plik

@ -39,7 +39,7 @@ struct idle_counter idle_count, idle_count_max;
idle_wait_t last_idle_t = IDLE_NONE;
#define kick_external_watchdog() port_pin_toggle_output_level(WDT_WDI_PIN)
#define kick_external_watchdog() port_pin_toggle_output_level(WDT_WDI_PIN)
/**
* Increments the specified idle counter
@ -88,6 +88,18 @@ void clear_idle_counters(void)
memset(&idle_count, 0, sizeof(struct idle_counter));
}
/**
* To be run when we wake from sleep
*/
void awake_do_watchdog(void)
{
#ifdef DEBUG_USE_INTWATCHDOG
wdt_reset_count();
#endif
/* WDI high */
port_pin_set_output_level(WDT_WDI_PIN, 1);
}
/**
* Kick
*/
@ -130,24 +142,18 @@ void idle(idle_wait_t idle_t)
wdt_reset_count();
#endif
/* WDI low */
port_pin_set_output_level(WDT_WDI_PIN, 0);
/* And sleep */
system_sleep();
/* Same again when we wake from sleep */
#ifdef DEBUG_USE_INTWATCHDOG
wdt_reset_count();
#endif
port_pin_set_output_level(WDT_WDI_PIN, 1);
}
/**
* The internal watchdog is used to bring the processor to a halt and
* coredump to external memory.
* 0.8s < t_early_w < 0.128s
* coredump to external memory (todo)
* 0.6s < t_early_w < 0.96s
*
* The external watchdog then hard resets the MCU and GPS to bring the
* system back up in a clean state.
@ -168,12 +174,12 @@ void watchdog_init(void)
system_gclk_gen_set_config(WDT_GCLK,
GCLK_SOURCE_OSCULP32K, /* Source */
false, /* High When Disabled */
4, /* Division Factor 1 */
3, /* Division Factor */
false, /* Run in standby */
true); /* Output Pin Enable */
system_gclk_gen_enable(WDT_GCLK);
/* Set the watchdog timer. On 8kHz gclk */
/* Set the watchdog timer. On ~11kHz gclk */
wdt_set_config(false, /* Lock WDT */
true, /* Enable WDT */
WDT_GCLK, /* Clock Source */

Wyświetl plik

@ -34,7 +34,7 @@
#include "tc/tc_driver.h"
#include "hw_config.h"
#include "xosc.h"
#include "watchdog.h"
enum measure_state_t {
MEASURE_WAIT_FOR_FIRST_EVENT,
@ -235,7 +235,6 @@ void measure_xosc_disable(enum xosc_measurement_t measurement_t) {
}
}
/**
* Triggered on timer 2 capture
*/
@ -243,6 +242,8 @@ void TC2_Handler(void) {
uint32_t capture_value;
uint32_t source_freq;
awake_do_watchdog();
if (tc_get_status(TC2) & TC_STATUS_CHANNEL_0_MATCH) {
tc_clear_status(TC2, TC_STATUS_CHANNEL_0_MATCH);