kopia lustrzana https://github.com/bristol-seds/pico-tracker
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 momentmaster
rodzic
f7221454f0
commit
b543316b42
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue