kopia lustrzana https://github.com/bristol-seds/pico-tracker
Increase the frequency of the internal watchdog gclk so we don't get massive lag when kicking it. Also fix up varous timing issues / speed things up
rodzic
7b48a48881
commit
5d6d35d9dc
|
@ -167,7 +167,11 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watchdog Timer
|
* Watchdog Timer
|
||||||
|
*
|
||||||
|
* There is a performance penalty to using the watchdog - you must
|
||||||
|
* wait up to 1/16kHz when kicking to sync with it. Disable when not in use
|
||||||
*/
|
*/
|
||||||
|
#define DEBUG_USE_INTWATCHDOG 1
|
||||||
#define WDT_GCLK GCLK_GENERATOR_4
|
#define WDT_GCLK GCLK_GENERATOR_4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,7 +34,10 @@ void si_trx_modem_set_deviation(uint32_t deviation);
|
||||||
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
||||||
uint16_t deviation, uint8_t power);
|
uint16_t deviation, uint8_t power);
|
||||||
void si_trx_off(void);
|
void si_trx_off(void);
|
||||||
void si_trx_switch_channel(int16_t channel);
|
|
||||||
|
void si_trx_modem_set_offset(int16_t channel);
|
||||||
|
#define si_trx_switch_channel si_trx_modem_set_offset
|
||||||
|
|
||||||
|
|
||||||
void si_trx_shutdown(void);
|
void si_trx_shutdown(void);
|
||||||
void si_trx_init(void);
|
void si_trx_init(void);
|
||||||
|
|
|
@ -300,7 +300,7 @@ static void si_trx_modem_tx_filter_coefficients(uint8_t* coeff_array)
|
||||||
*
|
*
|
||||||
* This is a signed 16-bit value.
|
* This is a signed 16-bit value.
|
||||||
*/
|
*/
|
||||||
static void si_trx_modem_set_offset(int16_t offset)
|
void si_trx_modem_set_offset(int16_t offset)
|
||||||
{
|
{
|
||||||
/* _si_trx_set_property_16(SI_PROPERTY_GROUP_MODEM, */
|
/* _si_trx_set_property_16(SI_PROPERTY_GROUP_MODEM, */
|
||||||
/* SI_MODEM_FREQ_OFFSET, */
|
/* SI_MODEM_FREQ_OFFSET, */
|
||||||
|
@ -489,14 +489,6 @@ void si_trx_off(void)
|
||||||
_si_trx_sdn_enable();
|
_si_trx_sdn_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Switches the transmission to the specified channel. Signed 16-bit int
|
|
||||||
*/
|
|
||||||
void si_trx_switch_channel(int16_t channel)
|
|
||||||
{
|
|
||||||
si_trx_modem_set_offset(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the radio
|
* Resets the radio
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -363,6 +363,8 @@ const uint8_t tick_gclk_gen_num = 1;
|
||||||
*/
|
*/
|
||||||
void timer0_tick_init(uint32_t count)
|
void timer0_tick_init(uint32_t count)
|
||||||
{
|
{
|
||||||
|
tc_reset(TC0);
|
||||||
|
|
||||||
/* Configure Timer 0 */
|
/* Configure Timer 0 */
|
||||||
bool t0_capture_channel_enables[] = {false, false};
|
bool t0_capture_channel_enables[] = {false, false};
|
||||||
uint32_t t0_compare_channel_values[] = {count, 0x0000};
|
uint32_t t0_compare_channel_values[] = {count, 0x0000};
|
||||||
|
@ -381,15 +383,8 @@ void timer0_tick_init(uint32_t count)
|
||||||
t0_capture_channel_enables, /* Capture Channel Enables */
|
t0_capture_channel_enables, /* Capture Channel Enables */
|
||||||
t0_compare_channel_values); /* Compare Channels Values */
|
t0_compare_channel_values); /* Compare Channels Values */
|
||||||
|
|
||||||
/* Enable Events */
|
|
||||||
struct tc_events event;
|
|
||||||
memset(&event, 0, sizeof(struct tc_events));
|
|
||||||
event.generate_event_on_compare_channel[0] = true;
|
|
||||||
event.event_action = TC_EVENT_ACTION_RETRIGGER;
|
|
||||||
tc_enable_events(TC0, &event);
|
|
||||||
|
|
||||||
/* Enable Interrupt */
|
/* Enable Interrupt */
|
||||||
TC0->COUNT16.INTENSET.reg = TC_INTENSET_MC0;
|
TC0->COUNT32.INTENSET.reg = TC_INTENSET_MC0;
|
||||||
irq_register_handler(TC0_IRQn, TC0_INT_PRIO); /* Highest Priority */
|
irq_register_handler(TC0_IRQn, TC0_INT_PRIO); /* Highest Priority */
|
||||||
|
|
||||||
/* Enable Timer */
|
/* Enable Timer */
|
||||||
|
@ -420,7 +415,7 @@ void timer0_tick_deinit()
|
||||||
*/
|
*/
|
||||||
void TC0_Handler(void)
|
void TC0_Handler(void)
|
||||||
{
|
{
|
||||||
if (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
|
while (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
|
||||||
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);
|
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);
|
||||||
|
|
||||||
telemetry_tick();
|
telemetry_tick();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "system/extint.h"
|
#include "system/extint.h"
|
||||||
#include "system/events.h"
|
#include "system/events.h"
|
||||||
#include "system/interrupt.h"
|
#include "system/interrupt.h"
|
||||||
|
#include "system/port.h"
|
||||||
|
|
||||||
uint32_t gps_timepulse_count = 0;
|
uint32_t gps_timepulse_count = 0;
|
||||||
uint32_t timepulse_sequence = 0;
|
uint32_t timepulse_sequence = 0;
|
||||||
|
@ -48,6 +49,10 @@ void timepulse_extint_init(void) {
|
||||||
extint_enable_events(&events);
|
extint_enable_events(&events);
|
||||||
|
|
||||||
/* Configure extinit channel */
|
/* Configure extinit channel */
|
||||||
|
/**
|
||||||
|
* We trigger on both edges so that we get woken up at 2x the tick
|
||||||
|
* rate. This means we can kick the watchdog often enough.
|
||||||
|
*/
|
||||||
struct extint_chan_conf config;
|
struct extint_chan_conf config;
|
||||||
config.gpio_pin = GPS_TIMEPULSE_PIN;
|
config.gpio_pin = GPS_TIMEPULSE_PIN;
|
||||||
config.gpio_pin_mux = GPS_TIMEPULSE_PINMUX;
|
config.gpio_pin_mux = GPS_TIMEPULSE_PINMUX;
|
||||||
|
|
|
@ -93,12 +93,6 @@ void clear_idle_counters(void)
|
||||||
*/
|
*/
|
||||||
void kick_the_watchdog(void)
|
void kick_the_watchdog(void)
|
||||||
{
|
{
|
||||||
/* tc_set_count_value(TC1, 0); */
|
|
||||||
/* tc_clear_status(TC1, TC_STATUS_CHANNEL_0_MATCH); */
|
|
||||||
|
|
||||||
wdt_reset_count();
|
|
||||||
|
|
||||||
kick_external_watchdog();
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Called in idle loops. Kicks the watchdog
|
* Called in idle loops. Kicks the watchdog
|
||||||
|
@ -128,20 +122,28 @@ void idle(idle_wait_t idle_t)
|
||||||
check_idle_counters();
|
check_idle_counters();
|
||||||
|
|
||||||
/* Kick the watchdog */
|
/* Kick the watchdog */
|
||||||
kick_the_watchdog();
|
#ifdef DEBUG_USE_INTWATCHDOG
|
||||||
|
wdt_reset_count();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
port_pin_set_output_level(WDT_WDI_PIN, 0);
|
||||||
|
|
||||||
/* And sleep */
|
/* And sleep */
|
||||||
system_sleep();
|
system_sleep();
|
||||||
|
|
||||||
/* Same again when we wake from sleep */
|
/* Same again when we wake from sleep */
|
||||||
kick_the_watchdog();
|
#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
|
* The internal watchdog is used to bring the processor to a halt and
|
||||||
* coredump to external memory.
|
* coredump to external memory.
|
||||||
* 0.4s < t_early_w < 0.64s
|
* 0.8s < t_early_w < 0.128s
|
||||||
*
|
*
|
||||||
* The external watchdog then hard resets the MCU and GPS to bring the
|
* The external watchdog then hard resets the MCU and GPS to bring the
|
||||||
* system back up in a clean state.
|
* system back up in a clean state.
|
||||||
|
@ -157,30 +159,30 @@ void watchdog_init(void)
|
||||||
false); /* Powersave */
|
false); /* Powersave */
|
||||||
kick_external_watchdog(); /* Kick External */
|
kick_external_watchdog(); /* Kick External */
|
||||||
|
|
||||||
|
#if DEBUG_USE_INTWATCHDOG
|
||||||
/* /\* 0.5s early warn. So 2^(15-1) cycles of the 32.768kHz ulposc *\/ */
|
/* /\* 0.5s early warn. So 2^(15-1) cycles of the 32.768kHz ulposc *\/ */
|
||||||
system_gclk_gen_set_config(WDT_GCLK,
|
system_gclk_gen_set_config(WDT_GCLK,
|
||||||
GCLK_SOURCE_OSCULP32K, /* Source */
|
GCLK_SOURCE_OSCULP32K, /* Source */
|
||||||
false, /* High When Disabled */
|
false, /* High When Disabled */
|
||||||
128, /* Division Factor 2^7 */
|
4, /* Division Factor 1 */
|
||||||
false, /* Run in standby */
|
false, /* Run in standby */
|
||||||
true); /* Output Pin Enable */
|
true); /* Output Pin Enable */
|
||||||
system_gclk_gen_enable(WDT_GCLK);
|
system_gclk_gen_enable(WDT_GCLK);
|
||||||
|
|
||||||
/* Set the watchdog timer. On 256Hz gclk */
|
/* Set the watchdog timer. On 8kHz gclk */
|
||||||
wdt_set_config(false, /* Lock WDT */
|
wdt_set_config(false, /* Lock WDT */
|
||||||
true, /* Enable WDT */
|
true, /* Enable WDT */
|
||||||
WDT_GCLK, /* Clock Source */
|
WDT_GCLK, /* Clock Source */
|
||||||
WDT_PERIOD_16384CLK, /* Timeout Period */
|
WDT_PERIOD_16384CLK, /* Timeout Period */
|
||||||
WDT_PERIOD_NONE, /* Window Period */
|
WDT_PERIOD_NONE, /* Window Period */
|
||||||
WDT_PERIOD_128CLK); /* Early Warning Period */
|
WDT_PERIOD_8192CLK); /* Early Warning Period */
|
||||||
|
|
||||||
WDT->INTENSET.reg |= WDT_INTENSET_EW;
|
WDT->INTENSET.reg |= WDT_INTENSET_EW;
|
||||||
WDT->INTFLAG.reg |= WDT_INTFLAG_EW;
|
WDT->INTFLAG.reg |= WDT_INTFLAG_EW;
|
||||||
irq_register_handler(WDT_IRQn, WDT_INT_PRIO);
|
irq_register_handler(WDT_IRQn, WDT_INT_PRIO);
|
||||||
|
|
||||||
/* Kick Watchdogs */
|
|
||||||
kick_external_watchdog();
|
|
||||||
wdt_reset_count();
|
wdt_reset_count();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue