kopia lustrzana https://github.com/bristol-seds/pico-tracker
Start re-organising clocks for hf lf clock structure where the microcontroller runs on its own lf clock during sleep.
rodzic
b72a496f9f
commit
939d30ebfe
|
@ -42,22 +42,46 @@
|
|||
|
||||
## Clock Layout
|
||||
|
||||
### At startup
|
||||
|
||||
```
|
||||
[osc8m] --> [glck0] +
|
||||
|--> [tc5]
|
||||
|--> [adc]
|
||||
|--> [extint]
|
||||
|--> [cm0+, apbs etc.]
|
||||
|
||||
|
||||
|\
|
||||
[osc8m]--> 0| |
|
||||
| | --> [glck1] +--> [tc0, telemetry tick]
|
||||
tcxo --> [xosc] --> 1| | |--> [tc2, count tcxo] <-- gps timepulse
|
||||
|/ |--> [glck7] --> [tc5] --> si_gpio1
|
||||
| |--> [gps usart]
|
||||
*USE_XOSC*
|
||||
|
||||
|
||||
[osculp32k] --> [gclk4] --> [wdt]
|
||||
[osc8m] --> [glck0] -> [core]
|
||||
```
|
||||
|
||||
### Once configured
|
||||
|
||||
```
|
||||
|
||||
|\
|
||||
[osculp32k] --> 0| |
|
||||
| | ------+ (22-42kHz)
|
||||
lftimer -> [glck_io0] --> 1| | |
|
||||
|/ |
|
||||
| |
|
||||
*USE_LFTIMER* | |\
|
||||
+--> 0| |
|
||||
| | --> [gclk0] +--> [core]
|
||||
+--> 1| | |--> [tc4, wakeup, measure gclk0]
|
||||
| |/
|
||||
| |
|
||||
|\ | awake?
|
||||
[osc8m]--> 0| | |
|
||||
| | ------+ (8MHz/16.369MHz)
|
||||
tcxo --> [xosc] --> 1| |
|
||||
|/
|
||||
|
|
||||
*USE_XOSC*
|
||||
|
||||
|
||||
|
||||
|
||||
|\
|
||||
|\ 0| |
|
||||
[osc8m]--> 0| | | | ---> [glck1] +--> [tc0, telemetry tick]
|
||||
| | ---> 1| | |--> [tc2, count tcxo]
|
||||
tcxo --> [xosc] --> 1| | |/ |--> [glck7] --> [tc5, aprs carrier] --> si_gpio1
|
||||
|/ | |--> [adc]
|
||||
| awake? |--> [extint]
|
||||
*USE_XOSC* |--> [sercoms]
|
||||
|
||||
```
|
||||
|
|
|
@ -195,11 +195,17 @@
|
|||
#define RF_POWER_8dBm 36
|
||||
|
||||
/**
|
||||
* XOSC
|
||||
* LF Clock
|
||||
*/
|
||||
#define USE_LFTIMER 0
|
||||
|
||||
/**
|
||||
* HF Clock
|
||||
*/
|
||||
#define USE_XOSC 1
|
||||
#define XOSC_FREQUENCY 16369000
|
||||
#define XOSC_GCLK1_DIVIDE 2
|
||||
#define XOSC_GCLK_DIVIDE 2 /* ~8MHz on GCLK*/
|
||||
#define OSC8M_GCLK_DIVIDE 1 /* ~8MHz on GCLK */
|
||||
|
||||
/**
|
||||
* Telemetry
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "samd20.h"
|
||||
#include "hw_config.h"
|
||||
#include "system/port.h"
|
||||
#include "timer.h"
|
||||
|
||||
enum init_type {
|
||||
INIT_NORMAL,
|
||||
|
@ -57,6 +56,6 @@ static inline void led_toggle(void)
|
|||
port_pin_toggle_output_level(LED0_PIN);
|
||||
}
|
||||
|
||||
void init(timepulse_callback_t callback, enum init_type init_t);
|
||||
void init(enum init_type init_t);
|
||||
|
||||
#endif /* INIT_H */
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Functions for running system timings
|
||||
* Copyright (C) 2015 Richard Meadows <richardeoin>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
typedef void (*timepulse_callback_t)(uint32_t sequence);
|
||||
|
||||
void timepulse_extint_init(void);
|
||||
void timepulse_set_callback(timepulse_callback_t callback);
|
||||
|
||||
#endif /* TIMER_H */
|
|
@ -28,19 +28,27 @@
|
|||
#include "samd20.h"
|
||||
|
||||
enum xosc_measurement_t {
|
||||
XOSC_MEASURE_OSC8M,
|
||||
XOSC_MEASURE_GCLK0,
|
||||
XOSC_MEASURE_TIMEPULSE,
|
||||
};
|
||||
struct osc8m_calibration_t {
|
||||
uint8_t temperature;
|
||||
uint8_t process;
|
||||
};
|
||||
|
||||
typedef void (*measurement_result_t)(uint32_t result);
|
||||
|
||||
void xosc_init(void);
|
||||
struct osc8m_calibration_t osc8m_get_calibration(void);
|
||||
void osc8m_set_calibration(struct osc8m_calibration_t calib);
|
||||
|
||||
/** HF Clock */
|
||||
void hf_clock_init(void);
|
||||
void hf_clock_enable(void);
|
||||
void hf_clock_disable(void);
|
||||
|
||||
/** GCLK0 */
|
||||
void glck0_to_hf_clock(void);
|
||||
void gclk0_to_lf_clock(void);
|
||||
|
||||
/** GCLK1 */
|
||||
void gclk1_enable(void);
|
||||
void gclk1_disable(void);
|
||||
|
||||
/** Measurement */
|
||||
void measure_xosc(enum xosc_measurement_t measurement_t, measurement_result_t callback);
|
||||
|
||||
#endif /* XOSC_H */
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "si_trx.h"
|
||||
#include "watchdog.h"
|
||||
#include "xosc.h"
|
||||
#include "timer.h"
|
||||
#include "cron.h"
|
||||
#include "data.h"
|
||||
#include "memory.h"
|
||||
|
@ -68,7 +67,7 @@ void powermananger_init(void)
|
|||
* Internal initialisation
|
||||
* =============================================================================
|
||||
*/
|
||||
void init(timepulse_callback_t callback, enum init_type init_t)
|
||||
void init(enum init_type init_t)
|
||||
{
|
||||
/**
|
||||
* Reset to get the system in a safe state
|
||||
|
@ -131,10 +130,6 @@ void init(timepulse_callback_t callback, enum init_type init_t)
|
|||
|
||||
/* GPS init */
|
||||
gps_init();
|
||||
|
||||
/* Enable timer interrupt and event channel */
|
||||
timepulse_extint_init();
|
||||
timepulse_set_callback(callback);
|
||||
}
|
||||
|
||||
/* Initialise Si4060 interface */
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "mfsk.h"
|
||||
#include "watchdog.h"
|
||||
#include "telemetry.h"
|
||||
#include "timer.h"
|
||||
#include "contestia.h"
|
||||
#include "aprs.h"
|
||||
#include "location.h"
|
||||
|
@ -246,7 +245,7 @@ void gps_tick(uint32_t sequence)
|
|||
int main(void)
|
||||
{
|
||||
/* Init */
|
||||
init(gps_tick, INIT_NORMAL);
|
||||
init(INIT_NORMAL);
|
||||
|
||||
/* Maybe do some rf tests */
|
||||
rf_tests();
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Functions for running system timings
|
||||
* Copyright (C) 2015 Richard Meadows <richardeoin>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "samd20.h"
|
||||
#include "hw_config.h"
|
||||
#include "timer.h"
|
||||
#include "system/extint.h"
|
||||
#include "system/events.h"
|
||||
#include "system/interrupt.h"
|
||||
#include "system/port.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
volatile uint32_t gps_timepulse_count = 0;
|
||||
uint32_t timepulse_sequence = 0;
|
||||
|
||||
timepulse_callback_t _timer_callback;
|
||||
|
||||
/**
|
||||
* Enables an interrupt on the GPS_TIMEPULSE and routes it to event channel 0
|
||||
*/
|
||||
void timepulse_extint_init(void) {
|
||||
|
||||
/* Enable extint events for gps timepulse */
|
||||
struct extint_events events;
|
||||
memset(&events, 0, sizeof(struct extint_events));
|
||||
events.generate_event_on_detect[GPS_TIMEPULSE_EXTINT] = true;
|
||||
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;
|
||||
config.gpio_pin_pull = EXTINT_PULL_DOWN;
|
||||
config.wake_if_sleeping = true;
|
||||
config.filter_input_signal = false;
|
||||
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, /* Don't care for async path */
|
||||
EVENTS_PATH_ASYNCHRONOUS,
|
||||
0xC + GPS_TIMEPULSE_EXTINT, /* External Interrupt Number */
|
||||
0);
|
||||
|
||||
/* Interrupt handler below */
|
||||
EIC->INTENSET.reg = (1 << GPS_TIMEPULSE_EXTINT);
|
||||
irq_register_handler(EIC_IRQn, EIC_INT_PRIO);
|
||||
|
||||
extint_enable();
|
||||
}
|
||||
|
||||
void timepulse_set_callback(timepulse_callback_t callback) {
|
||||
_timer_callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* EIC Handler, triggered by the GPS at GPS_TIMEPULSE_FREQ Hz
|
||||
*/
|
||||
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 * 2) { /* Both */
|
||||
gps_timepulse_count = 0;
|
||||
|
||||
/* Make the callback if we have one */
|
||||
if (_timer_callback) {
|
||||
_timer_callback(timepulse_sequence++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
#include "system/clock.h"
|
||||
#include "system/gclk.h"
|
||||
#include "system/interrupt.h"
|
||||
#include "system/port.h"
|
||||
#include "system/pinmux.h"
|
||||
#include "system/events.h"
|
||||
#include "system/extint.h"
|
||||
|
@ -44,11 +45,37 @@ enum xosc_measurement_t _measurement_t;
|
|||
measurement_result_t _callback;
|
||||
|
||||
/**
|
||||
* Configures external oscillator, waits for it to stabilise, and
|
||||
* connects it to GLCK1.
|
||||
* =============================================================================
|
||||
* HF Clock =======================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
void xosc_init(void) {
|
||||
|
||||
/**
|
||||
* Init hf clock
|
||||
*/
|
||||
void hf_clock_init(void)
|
||||
{
|
||||
#ifdef SI4xxx_TCXO_REG_EN_PIN /* TCXO enable/disable pin */
|
||||
port_pin_set_config(SI4xxx_TCXO_REG_EN_PIN,
|
||||
PORT_PIN_DIR_OUTPUT, /* Direction */
|
||||
PORT_PIN_PULL_NONE, /* Pull */
|
||||
false); /* Powersave */
|
||||
port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 1); /* Enable by default */
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Enables a high frequency clock for the system, either XOSC or OSC8M
|
||||
*/
|
||||
void hf_clock_enable(void)
|
||||
{
|
||||
#if USE_XOSC
|
||||
|
||||
/* Enable TCXO if required */
|
||||
#ifdef SI4xxx_TCXO_REG_EN_PIN
|
||||
port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 1);
|
||||
#endif
|
||||
|
||||
/* Setup XOSC */
|
||||
system_clock_source_xosc_set_config(SYSTEM_CLOCK_EXTERNAL_CLOCK,
|
||||
SYSTEM_XOSC_STARTUP_1,
|
||||
true,
|
||||
|
@ -57,10 +84,58 @@ void xosc_init(void) {
|
|||
false);
|
||||
system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC);
|
||||
|
||||
/* Wait for it to stabilise */
|
||||
while (!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC));
|
||||
|
||||
#else
|
||||
|
||||
/* Setup OSC8M */
|
||||
system_clock_source_osc8m_set_config(SYSTEM_OSC8M_DIV_2, /* Prescaler */
|
||||
false, /* Run in Standby */
|
||||
false); /* Run on Demand */
|
||||
system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC8M);
|
||||
|
||||
/* Wait for it to stabilise */
|
||||
while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_OSC8M));
|
||||
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Disables the high frequency clock for the system, either XOSC or OSC8M
|
||||
*/
|
||||
void hf_clock_disable(void)
|
||||
{
|
||||
#if USE_XOSC
|
||||
|
||||
/* Enable XOSC */
|
||||
system_clock_source_disable(SYSTEM_CLOCK_SOURCE_XOSC);
|
||||
|
||||
/* Disable TCXO to save power */
|
||||
#ifdef SI4xxx_TCXO_REG_EN_PIN
|
||||
port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 1);
|
||||
#endif
|
||||
|
||||
/* Configure GCLK1 to XOSC */
|
||||
#else
|
||||
|
||||
/* Disable OSC8M */
|
||||
system_clock_source_disable(SYSTEM_CLOCK_SOURCE_OSC8M);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* GCLK0 =======================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Switches GLCK0 to the HF clock
|
||||
*/
|
||||
void glck0_to_hf_clock(void)
|
||||
{
|
||||
/* Configure GCLK0 to XOSC / OSC8M */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_1,
|
||||
#if USE_XOSC
|
||||
GCLK_SOURCE_XOSC, /* Source */
|
||||
|
@ -68,29 +143,80 @@ void xosc_init(void) {
|
|||
GCLK_SOURCE_OSC8M, /* Source */
|
||||
#endif
|
||||
false, /* High When Disabled */
|
||||
XOSC_GCLK1_DIVIDE, /* Division Factor */
|
||||
#if USE_XOSC
|
||||
XOSC_GCLK_DIVIDE, /* Division Factor */
|
||||
#else
|
||||
OSC8M_GCLK_DIVIDE, /* Division Factor */
|
||||
#endif
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
}
|
||||
/**
|
||||
* Switches GCLK0 to the LF clock
|
||||
*/
|
||||
void gclk0_to_lf_clock(void)
|
||||
{
|
||||
/* Configure GCLK0 to GCLK_IO[0] / OSCULP32K */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_0,
|
||||
#if USE_LFTIMER
|
||||
GCLK_SOURCE_GCLKIN, /* Source */
|
||||
#else
|
||||
GCLK_SOURCE_OSCULP32K, /* Source */
|
||||
#endif
|
||||
false, /* High When Disabled */
|
||||
1, /* Division Factor */
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
}
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* GCLK1 =======================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enables GCLK1. The appropriate source should have been disabled already
|
||||
*/
|
||||
void gclk1_enable(void)
|
||||
{
|
||||
/* Configure GCLK1 */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_1,
|
||||
#if USE_XOSC
|
||||
GCLK_SOURCE_XOSC, /* Source */
|
||||
#else
|
||||
GCLK_SOURCE_OSC8M, /* Source */
|
||||
#endif
|
||||
false, /* High When Disabled */
|
||||
#if USE_XOSC
|
||||
XOSC_GCLK_DIVIDE, /* Division Factor */
|
||||
#else
|
||||
OSC8M_GCLK_DIVIDE,/* Division Factor */
|
||||
#endif
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
|
||||
/* Enable GCLK1 */
|
||||
system_gclk_gen_enable(GCLK_GENERATOR_1);
|
||||
}
|
||||
|
||||
struct osc8m_calibration_t osc8m_get_calibration(void) {
|
||||
uint16_t calib_word = SYSCTRL->OSC8M.bit.CALIB;
|
||||
struct osc8m_calibration_t calib;
|
||||
|
||||
calib.temperature = (calib_word >> 6) & 0x3F;
|
||||
calib.process = (calib_word >> 0) & 0x3F;
|
||||
|
||||
return calib;
|
||||
/**
|
||||
* Disable GCLK1
|
||||
*/
|
||||
void gclk1_disable(void)
|
||||
{
|
||||
system_gclk_gen_disable(GCLK_GENERATOR_1);
|
||||
}
|
||||
void osc8m_set_calibration(struct osc8m_calibration_t calib) {
|
||||
uint16_t calib_word = ((calib.temperature & 0x3F) << 6) | (calib.process & 0x3F);
|
||||
|
||||
system_clock_source_write_calibration(SYSTEM_CLOCK_SOURCE_OSC8M, calib_word, 0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* =============================================================================
|
||||
* Measurement =======================================================
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -99,7 +225,7 @@ void osc8m_set_calibration(struct osc8m_calibration_t calib) {
|
|||
*/
|
||||
/* void osc8m_event_source(void) { */
|
||||
|
||||
/* /\* Timer 4 runs on GCLK0 (4MHz) *\/ */
|
||||
/* /\* Timer 4 runs on GCLK0 *\/ */
|
||||
/* bool t4_capture_channel_enables[] = {false, false}; */
|
||||
/* uint32_t t4_compare_channel_values[] = {15625, 0x0000}; */
|
||||
/* /\* Divide by 256*15625 = 1Hz events *\/ */
|
||||
|
@ -154,11 +280,35 @@ void osc8m_set_calibration(struct osc8m_calibration_t calib) {
|
|||
/**
|
||||
* Configure the timepulse extint to generate events
|
||||
*/
|
||||
void timepulse_extint_event_source(void) {
|
||||
/* Nothing to do: event should be already in place */
|
||||
void timepulse_extint_event_source(void)
|
||||
{
|
||||
/* Enable extint events for timepulse */
|
||||
struct extint_events events;
|
||||
memset(&events, 0, sizeof(struct extint_events));
|
||||
events.generate_event_on_detect[GPS_TIMEPULSE_EXTINT] = true;
|
||||
extint_enable_events(&events);
|
||||
|
||||
/* Configure extinit channel */
|
||||
struct extint_chan_conf config;
|
||||
config.gpio_pin = GPS_TIMEPULSE_PIN;
|
||||
config.gpio_pin_mux = GPS_TIMEPULSE_PINMUX;
|
||||
config.gpio_pin_pull = EXTINT_PULL_DOWN;
|
||||
config.wake_if_sleeping = true;
|
||||
config.filter_input_signal = false;
|
||||
config.detection_criteria = EXTINT_DETECT_RISING;
|
||||
extint_chan_set_config(GPS_TIMEPULSE_EXTINT, &config);
|
||||
|
||||
/* We route this event to event channel 0 */
|
||||
events_allocate(0,
|
||||
EVENTS_EDGE_DETECT_NONE, /* Don't care for async path */
|
||||
EVENTS_PATH_ASYNCHRONOUS,
|
||||
0xC + GPS_TIMEPULSE_EXTINT, /* External Interrupt Number */
|
||||
0);
|
||||
|
||||
extint_enable();
|
||||
}
|
||||
void timepulse_extint_event_source_disable(void) {
|
||||
/* Nothing to do here */
|
||||
extint_disable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +323,7 @@ void measure_xosc(enum xosc_measurement_t measurement_t,
|
|||
_measurement_t = measurement_t;
|
||||
_callback = callback;
|
||||
|
||||
/* Timer 2 runs on GLCK1: XOSC */
|
||||
/* Timer 2 runs on GLCK1 */
|
||||
bool t2_capture_channel_enables[] = {true, true};
|
||||
uint32_t t2_compare_channel_values[] = {0x0000, 0x0000};
|
||||
|
||||
|
@ -211,7 +361,7 @@ void measure_xosc(enum xosc_measurement_t measurement_t,
|
|||
|
||||
/* Configure an event source */
|
||||
switch (measurement_t) {
|
||||
case XOSC_MEASURE_OSC8M:
|
||||
case XOSC_MEASURE_GCLK0:
|
||||
// osc8m_event_source(); // osc8m issues events
|
||||
break;
|
||||
case XOSC_MEASURE_TIMEPULSE:
|
||||
|
@ -226,7 +376,7 @@ void measure_xosc_disable(enum xosc_measurement_t measurement_t) {
|
|||
tc_disable(TC2);
|
||||
|
||||
switch (measurement_t) {
|
||||
case XOSC_MEASURE_OSC8M:
|
||||
case XOSC_MEASURE_GCLK0:
|
||||
// osc8m_event_source_disable();
|
||||
break;
|
||||
case XOSC_MEASURE_TIMEPULSE:
|
||||
|
@ -235,6 +385,8 @@ void measure_xosc_disable(enum xosc_measurement_t measurement_t) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Triggered on timer 2 capture
|
||||
*/
|
||||
|
@ -242,8 +394,6 @@ 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);
|
||||
|
||||
|
@ -255,13 +405,13 @@ void TC2_Handler(void) {
|
|||
/* Measurement done. Read off data */
|
||||
capture_value = tc_get_capture_value(TC2, 0);
|
||||
|
||||
/* Calcuate the frequency of XOSC relative to this source */
|
||||
/* Calcuate the frequency of GLCK1 relative to this source */
|
||||
switch (_measurement_t) {
|
||||
case XOSC_MEASURE_OSC8M:
|
||||
source_freq = capture_value * XOSC_GCLK1_DIVIDE;
|
||||
case XOSC_MEASURE_GCLK0:
|
||||
source_freq = capture_value * XOSC_GCLK_DIVIDE;
|
||||
break;
|
||||
case XOSC_MEASURE_TIMEPULSE:
|
||||
source_freq = capture_value * XOSC_GCLK1_DIVIDE * GPS_TIMEPULSE_FREQ * 2;
|
||||
source_freq = capture_value * XOSC_GCLK_DIVIDE * GPS_TIMEPULSE_FREQ;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ void osc8m_tc_xosc_measure_callback(uint32_t result) {
|
|||
|
||||
/* Function */
|
||||
__verification__ void osc8m_calib_tc(void) {
|
||||
struct osc8m_calibration_t calib;
|
||||
/* struct osc8m_calibration_t calib; */
|
||||
|
||||
calib.process = 9;
|
||||
calib.temperature = 28;
|
||||
osc8m_set_calibration(calib);
|
||||
/* calib.process = 9; */
|
||||
/* calib.temperature = 28; */
|
||||
/* osc8m_set_calibration(calib, 0x1); */
|
||||
|
||||
_result = 0;
|
||||
measure_xosc(XOSC_MEASURE_TIMEPULSE, osc8m_tc_xosc_measure_callback);
|
||||
/* _result = 0; */
|
||||
/* measure_xosc(XOSC_MEASURE_TIMEPULSE, osc8m_tc_xosc_measure_callback); */
|
||||
|
||||
while (_result == 0);
|
||||
osc8m_calib_tc_results.result = _result;
|
||||
/* while (_result == 0); */
|
||||
/* osc8m_calib_tc_results.result = _result; */
|
||||
|
||||
calib = osc8m_get_calibration();
|
||||
osc8m_calib_tc_results.c_process = calib.process;
|
||||
osc8m_calib_tc_results.c_temp = calib.temperature;
|
||||
/* calib = osc8m_get_calibration(); */
|
||||
/* osc8m_calib_tc_results.c_process = calib.process; */
|
||||
/* osc8m_calib_tc_results.c_temp = calib.temperature; */
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue