[New Feature] Use an interrupt that isn't part of the M0+ core for the RTTY interrupt. This allows sleep mode

rocketry
Richard Eoin Meadows 2014-10-25 19:38:28 +01:00
rodzic 74fbfb30ad
commit bad5cc913d
3 zmienionych plików z 61 dodań i 9 usunięć

Wyświetl plik

@ -26,5 +26,6 @@
#define TELEMETRY_H
uint16_t crc_checksum(char *string);
void timer0_tick_init(uint32_t frequency);
#endif /* TELEMETRY_H */

Wyświetl plik

@ -326,15 +326,14 @@ int main(void)
SystemCoreClock = system_cpu_clock_get_hz();
/* Configure Sleep Mode */
system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_0); /* Disable CPU, AHB. APB still runs */
//system_set_sleepmode(SYSTEM_SLEEPMODE_STANDBY);
system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Disable CPU, AHB and APB */
/* Configure the Power Manager */
powermananger_init();
/* Configure the SysTick for 50Hz triggering */
SysTick_Config(SystemCoreClock / 50);
/* Timer 0 for 50Hz triggering */
timer0_tick_init(50);
/**
* System initialisation
@ -365,11 +364,13 @@ int main(void)
si4060_gpio_init();
si4060_start_tx(0);
led_on();
while (1) {
/* Watchdog */
wdt_reset_count();
/* Set the next packet */
/* Send the next packet */
output_telemetry_string();
}
}
@ -377,8 +378,11 @@ int main(void)
/**
* Called at 50Hz
*/
void SysTick_Handler(void)
void TC0_Handler(void)
{
/* Output RTTY */
rtty_tick();
if (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);
rtty_tick();
}
}

Wyświetl plik

@ -26,6 +26,10 @@
#include <string.h>
#include "samd20.h"
#include "system/gclk.h"
#include "system/interrupt.h"
#include "tc/tc_driver.h"
/**
* CRC Function for the XMODEM protocol.
@ -67,3 +71,46 @@ uint16_t crc_checksum(char *string)
return crc;
}
/**
* Initialises a timer interupt at the given frequency
*/
void timer0_tick_init(uint32_t frequency)
{
/* Calculate the wrap value for the given frequency */
uint32_t gclk0_frequency = system_gclk_chan_get_hz(0);
uint32_t count = gclk0_frequency / frequency;
/* Configure Timer 0 */
bool t0_capture_channel_enables[] = {false, false};
uint32_t t0_compare_channel_values[] = {count, 0x0000};
tc_init(TC0,
GCLK_GENERATOR_0,
TC_COUNTER_SIZE_32BIT,
TC_CLOCK_PRESCALER_DIV1,
TC_WAVE_GENERATION_MATCH_FREQ,
TC_RELOAD_ACTION_GCLK,
TC_COUNT_DIRECTION_UP,
TC_WAVEFORM_INVERT_OUTPUT_NONE,
false, /* Oneshot */
true, /* Run in standby */
0x0000, /* Initial value */
count, /* Top value */
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->COUNT32.INTENSET.reg = (1 << 4);
irq_register_handler(TC0_IRQn, 0); /* Highest Priority */
/* Enable Timer */
tc_enable(TC0);
tc_start_counter(TC0);
}