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

master
Richard Meadows 2015-07-04 20:47:58 +01:00
rodzic 7b48a48881
commit 5d6d35d9dc
6 zmienionych plików z 34 dodań i 33 usunięć

Wyświetl plik

@ -167,7 +167,11 @@
/**
* 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
/**

Wyświetl plik

@ -34,7 +34,10 @@ void si_trx_modem_set_deviation(uint32_t deviation);
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
uint16_t deviation, uint8_t power);
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_init(void);

Wyświetl plik

@ -300,7 +300,7 @@ static void si_trx_modem_tx_filter_coefficients(uint8_t* coeff_array)
*
* 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_MODEM_FREQ_OFFSET, */
@ -489,14 +489,6 @@ void si_trx_off(void)
_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
*/

Wyświetl plik

@ -363,6 +363,8 @@ const uint8_t tick_gclk_gen_num = 1;
*/
void timer0_tick_init(uint32_t count)
{
tc_reset(TC0);
/* Configure Timer 0 */
bool t0_capture_channel_enables[] = {false, false};
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_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 */
TC0->COUNT16.INTENSET.reg = TC_INTENSET_MC0;
TC0->COUNT32.INTENSET.reg = TC_INTENSET_MC0;
irq_register_handler(TC0_IRQn, TC0_INT_PRIO); /* Highest Priority */
/* Enable Timer */
@ -420,7 +415,7 @@ void timer0_tick_deinit()
*/
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);
telemetry_tick();

Wyświetl plik

@ -30,6 +30,7 @@
#include "system/extint.h"
#include "system/events.h"
#include "system/interrupt.h"
#include "system/port.h"
uint32_t gps_timepulse_count = 0;
uint32_t timepulse_sequence = 0;
@ -48,6 +49,10 @@ void timepulse_extint_init(void) {
extint_enable_events(&events);
/* 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;
config.gpio_pin = GPS_TIMEPULSE_PIN;
config.gpio_pin_mux = GPS_TIMEPULSE_PINMUX;

Wyświetl plik

@ -93,12 +93,6 @@ void clear_idle_counters(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
@ -128,20 +122,28 @@ void idle(idle_wait_t idle_t)
check_idle_counters();
/* 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 */
system_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
* 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
* system back up in a clean state.
@ -157,30 +159,30 @@ void watchdog_init(void)
false); /* Powersave */
kick_external_watchdog(); /* Kick External */
#if DEBUG_USE_INTWATCHDOG
/* /\* 0.5s early warn. So 2^(15-1) cycles of the 32.768kHz ulposc *\/ */
system_gclk_gen_set_config(WDT_GCLK,
GCLK_SOURCE_OSCULP32K, /* Source */
false, /* High When Disabled */
128, /* Division Factor 2^7 */
4, /* Division Factor 1 */
false, /* Run in standby */
true); /* Output Pin Enable */
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 */
true, /* Enable WDT */
WDT_GCLK, /* Clock Source */
WDT_PERIOD_16384CLK, /* Timeout 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->INTFLAG.reg |= WDT_INTFLAG_EW;
irq_register_handler(WDT_IRQn, WDT_INT_PRIO);
/* Kick Watchdogs */
kick_external_watchdog();
wdt_reset_count();
#endif
}