kopia lustrzana https://github.com/bristol-seds/pico-tracker
Pre-calculate si settings for each frequency. Apparently this only shaves 2 ms off the startup time but hey
rodzic
a734ffef5b
commit
2df3eaf783
|
@ -27,6 +27,12 @@
|
|||
|
||||
#include "samd20.h"
|
||||
|
||||
struct si_frequency_configuration {
|
||||
uint8_t outdiv, band, nprescaler;
|
||||
uint32_t m; uint16_t n;
|
||||
float lsb_tuning_resolution;
|
||||
};
|
||||
|
||||
enum si_filter_model {
|
||||
SI_FILTER_DEFAULT,
|
||||
SI_FILTER_APRS,
|
||||
|
@ -37,7 +43,10 @@ float si_trx_get_temperature(void);
|
|||
|
||||
void si_trx_modem_set_deviation(uint32_t deviation);
|
||||
|
||||
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
||||
void si_trx_get_frequency_configuration(struct si_frequency_configuration* config,
|
||||
uint32_t frequency);
|
||||
|
||||
void si_trx_on(uint8_t modulation_type, struct si_frequency_configuration* fconfig,
|
||||
uint16_t deviation, uint8_t power, enum si_filter_model filter);
|
||||
void si_trx_off(void);
|
||||
|
||||
|
|
|
@ -38,13 +38,16 @@
|
|||
|
||||
void telemetry_tone(void)
|
||||
{
|
||||
struct si_frequency_configuration fconfig;
|
||||
si_trx_get_frequency_configuration(&fconfig, TELEMETRY_FREQUENCY);
|
||||
|
||||
while (1) {
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 36, SI_FILTER_DEFAULT);
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &fconfig, 0, 36, SI_FILTER_DEFAULT);
|
||||
for (int i = 0; i < 200*1000; i++) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
}
|
||||
si_trx_off();
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &fconfig, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||
for (int i = 0; i < 200*1000; i++) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
}
|
||||
|
@ -53,13 +56,16 @@ void telemetry_tone(void)
|
|||
}
|
||||
void aprs_tone(void)
|
||||
{
|
||||
struct si_frequency_configuration fconfig;
|
||||
si_trx_get_frequency_configuration(&fconfig, APRS_TEST_FREQUENCY);
|
||||
|
||||
while (1) {
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 36, SI_FILTER_DEFAULT);
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &fconfig, 0, 36, SI_FILTER_DEFAULT);
|
||||
for (int i = 0; i < 200*1000; i++) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
}
|
||||
si_trx_off();
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &fconfig, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||
for (int i = 0; i < 200*1000; i++) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
}
|
||||
|
@ -72,6 +78,9 @@ void aprs_tone(void)
|
|||
*/
|
||||
void aprs_high_fm_tone(void)
|
||||
{
|
||||
struct si_frequency_configuration fconfig;
|
||||
si_trx_get_frequency_configuration(&fconfig, APRS_TEST_FREQUENCY);
|
||||
|
||||
ax25_gpio1_pwm_init();
|
||||
|
||||
/* Space */
|
||||
|
@ -82,7 +91,7 @@ void aprs_high_fm_tone(void)
|
|||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, APRS_TEST_FREQUENCY,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, &fconfig,
|
||||
AX25_DEVIATION, APRS_POWER, SI_FILTER_APRS);
|
||||
while (1) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
|
@ -123,7 +132,7 @@ void rsid_test(void)
|
|||
|
||||
telemetry_start_rsid(RSID_CONTESTIA_32_1000);
|
||||
|
||||
// Sleep wait for RSID
|
||||
// Sleep wait for RSID
|
||||
while (telemetry_active()) {
|
||||
idle(IDLE_TELEMETRY_ACTIVE);
|
||||
}
|
||||
|
|
|
@ -428,60 +428,65 @@ static void si_trx_set_tx_pa_duty_cycle(uint8_t pa_duty_cycle)
|
|||
|
||||
|
||||
/**
|
||||
* Set the synthesiser to the given frequency.
|
||||
* Pre-calculates sythesiser paramters for use with si_trx_set_frequency
|
||||
* Might be called before module is initialised, so should just contain math
|
||||
*
|
||||
* frequency: Floating-point value for the frequency
|
||||
* deviation: FSK-mode deviation, in channels. Usually 1
|
||||
*
|
||||
* Returns the LSB tuning resolution of the frac-n pll synthesiser.
|
||||
*/
|
||||
static float si_trx_set_frequency(uint32_t frequency, uint16_t deviation)
|
||||
void si_trx_get_frequency_configuration(struct si_frequency_configuration* config,
|
||||
uint32_t frequency)
|
||||
{
|
||||
uint8_t outdiv, band, nprescaler;
|
||||
|
||||
/* Higher frequency resolution, but also higher power (~+200µA) */
|
||||
nprescaler = 2;
|
||||
|
||||
config->nprescaler = 2;
|
||||
|
||||
if (frequency < 705000000UL) {
|
||||
outdiv = 6; band = SI_MODEM_CLKGEN_FVCO_DIV_6;
|
||||
config->outdiv = 6; config->band = SI_MODEM_CLKGEN_FVCO_DIV_6;
|
||||
}
|
||||
if (frequency < 525000000UL) {
|
||||
outdiv = 8; band = SI_MODEM_CLKGEN_FVCO_DIV_8;
|
||||
config->outdiv = 8; config->band = SI_MODEM_CLKGEN_FVCO_DIV_8;
|
||||
}
|
||||
if (frequency < 353000000UL) {
|
||||
outdiv = 12; band = SI_MODEM_CLKGEN_FVCO_DIV_12;
|
||||
config->outdiv = 12; config->band = SI_MODEM_CLKGEN_FVCO_DIV_12;
|
||||
}
|
||||
if (frequency < 239000000UL) {
|
||||
outdiv = 16; band = SI_MODEM_CLKGEN_FVCO_DIV_16;
|
||||
config->outdiv = 16; config->band = SI_MODEM_CLKGEN_FVCO_DIV_16;
|
||||
}
|
||||
if (frequency < 177000000UL) {
|
||||
outdiv = 24; band = SI_MODEM_CLKGEN_FVCO_DIV_24;
|
||||
config->outdiv = 24; config->band = SI_MODEM_CLKGEN_FVCO_DIV_24;
|
||||
}
|
||||
|
||||
float f_pfd = nprescaler * VCXO_FREQUENCY / outdiv;
|
||||
float f_pfd = config->nprescaler * VCXO_FREQUENCY / config->outdiv;
|
||||
|
||||
uint16_t n = ((uint16_t)(frequency / f_pfd)) - 1;
|
||||
config->n = ((uint16_t)(frequency / f_pfd)) - 1;
|
||||
|
||||
float ratio = (float)frequency / f_pfd;
|
||||
float rest = ratio - (float)n;
|
||||
|
||||
uint32_t m = (uint32_t)(rest * (float)(1 << 19));
|
||||
float rest = ratio - (float)config->n;
|
||||
|
||||
config->m = (uint32_t)(rest * (float)(1 << 19));
|
||||
|
||||
/* Check n and m are in valid ranges, halt otherwise */
|
||||
if (n > 0x7f || m > 0xfffff) while (1);
|
||||
if (config->n > 0x7f || config->m > 0xfffff) while (1);
|
||||
|
||||
/* Calculate the LSB tuning resolution of the frac-n pll synthesiser. */
|
||||
config->lsb_tuning_resolution = f_pfd / (float)(1 << 19);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a pre-calculated frequency configuration to the si
|
||||
* synthesiser. Also sets deviation
|
||||
*/
|
||||
static void si_trx_set_frequency(struct si_frequency_configuration* config,
|
||||
uint16_t deviation)
|
||||
{
|
||||
/* Set the frac-n PLL output divider */
|
||||
if (nprescaler == 4) { /* Prescaler */
|
||||
si_trx_frequency_control_set_band(band, SI_MODEM_CLKGEN_SY_SEL_0);
|
||||
if (config->nprescaler == 4) { /* Prescaler */
|
||||
si_trx_frequency_control_set_band(config->band, SI_MODEM_CLKGEN_SY_SEL_0);
|
||||
} else { /* Default Mode */
|
||||
si_trx_frequency_control_set_band(band, SI_MODEM_CLKGEN_SY_SEL_1);
|
||||
si_trx_frequency_control_set_band(config->band, SI_MODEM_CLKGEN_SY_SEL_1);
|
||||
}
|
||||
|
||||
/* Set the frac-n PLL divisior */
|
||||
si_trx_frequency_control_set_divider(n, m);
|
||||
si_trx_frequency_control_set_divider(config->n, config->m);
|
||||
|
||||
/* Set the modem dsm control word. Allow even deviation values */
|
||||
si_trx_modem_set_dsm_ctrl(SI_MODEM_DSM_CTRL_NOFORCE_DSM_LSB |
|
||||
|
@ -489,15 +494,12 @@ static float si_trx_set_frequency(uint32_t frequency, uint16_t deviation)
|
|||
|
||||
/* Set the modem frequency deviation (for the external pin)*/
|
||||
si_trx_modem_set_deviation(deviation);
|
||||
|
||||
/* Return the LSB tuning resolution of the frac-n pll synthesiser. */
|
||||
return f_pfd / (float)(1 << 19);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the transceiver
|
||||
*/
|
||||
void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
||||
void si_trx_reset(uint8_t modulation_type, struct si_frequency_configuration* fconfig,
|
||||
uint16_t deviation, uint8_t power, enum si_filter_model filter)
|
||||
{
|
||||
_si_trx_sdn_enable(); /* active high shutdown = reset */
|
||||
|
@ -506,10 +508,9 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
|||
_si_trx_sdn_disable(); /* booting */
|
||||
for (int i = 0; i < 15*1000; i++); /* Approx. 15ms */
|
||||
|
||||
|
||||
uint16_t part_number = si_trx_get_part_info();
|
||||
|
||||
while (part_number != 17512);
|
||||
/* Check part number */
|
||||
/* uint16_t part_number = si_trx_get_part_info(); */
|
||||
/* while (part_number != 17512); */
|
||||
|
||||
/* Power Up */
|
||||
si_trx_power_up(SI_POWER_UP_TCXO, VCXO_FREQUENCY);
|
||||
|
@ -527,7 +528,7 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
|||
SI_GPIO_PIN_CFG_GPIO_MODE_INPUT | SI_GPIO_PIN_CFG_PULL_ENABLE,
|
||||
SI_GPIO_PIN_CFG_DRV_STRENGTH_LOW);
|
||||
|
||||
si_trx_set_frequency(frequency, deviation);
|
||||
si_trx_set_frequency(fconfig, deviation);
|
||||
si_trx_set_tx_power(power);
|
||||
|
||||
/* Modem tx filter coefficients */
|
||||
|
@ -558,8 +559,7 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
/* RTTY from GPIO1 */
|
||||
/* Set modulation type */
|
||||
si_trx_modem_set_modulation(SI_MODEM_MOD_DIRECT_MODE_SYNC, // ASYNC
|
||||
SI_MODEM_MOD_GPIO_1,
|
||||
SI_MODEM_MOD_SOURCE_DIRECT,
|
||||
|
@ -571,10 +571,10 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
|||
/**
|
||||
* Enables the radio and starts transmitting
|
||||
*/
|
||||
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
||||
void si_trx_on(uint8_t modulation_type, struct si_frequency_configuration* fconfig,
|
||||
uint16_t deviation, uint8_t power, enum si_filter_model filter)
|
||||
{
|
||||
si_trx_reset(modulation_type, frequency, deviation, power, filter);
|
||||
si_trx_reset(modulation_type, fconfig, deviation, power, filter);
|
||||
si_trx_start_tx(0);
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -128,6 +128,9 @@ int telemetry_active(void) {
|
|||
|
||||
uint32_t contestia_timer_count, rtty_timer_count;
|
||||
uint32_t pips_timer_count, ax25_timer_count, rsid_timer_count;
|
||||
|
||||
struct si_frequency_configuration telemetry_fconfig, aprs_fconfig;
|
||||
|
||||
/**
|
||||
* Starts telemetry output
|
||||
*
|
||||
|
@ -238,7 +241,7 @@ void telemetry_tick(void) {
|
|||
|
||||
if (!radio_on) {
|
||||
/* Contestia: We use the modem offset to modulate */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &telemetry_fconfig, 1, TELEMETRY_POWER,
|
||||
SI_FILTER_DEFAULT);
|
||||
radio_on = 1;
|
||||
contestia_preamble();
|
||||
|
@ -260,7 +263,7 @@ void telemetry_tick(void) {
|
|||
|
||||
if (!radio_on) {
|
||||
/* RTTY: We use the modem offset to modulate */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &telemetry_fconfig, 1, TELEMETRY_POWER,
|
||||
SI_FILTER_DEFAULT);
|
||||
radio_on = 1;
|
||||
rtty_preamble();
|
||||
|
@ -292,7 +295,7 @@ void telemetry_tick(void) {
|
|||
/* RSID: We PWM frequencies with the external pin */
|
||||
telemetry_gpio1_pwm_init();
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, &telemetry_fconfig, 1, TELEMETRY_POWER,
|
||||
SI_FILTER_RSID);
|
||||
radio_on = 1;
|
||||
}
|
||||
|
@ -314,8 +317,10 @@ void telemetry_tick(void) {
|
|||
/* APRS: We use pwm to control gpio1 */
|
||||
if (aprs_start() && _aprs_frequency) {
|
||||
|
||||
/* Frequency config. Recalculate each time */
|
||||
si_trx_get_frequency_configuration(&aprs_fconfig, _aprs_frequency);
|
||||
/* Radio on */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, _aprs_frequency, AX25_DEVIATION,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, &aprs_fconfig, AX25_DEVIATION,
|
||||
APRS_POWER, SI_FILTER_APRS);
|
||||
radio_on = 1;
|
||||
} else {
|
||||
|
@ -335,7 +340,7 @@ void telemetry_tick(void) {
|
|||
|
||||
if (!radio_on) { /* Turn on */
|
||||
/* Pips: Cw */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER,
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, &telemetry_fconfig, 1, TELEMETRY_POWER,
|
||||
SI_FILTER_DEFAULT);
|
||||
radio_on = 1;
|
||||
|
||||
|
@ -436,6 +441,9 @@ void telemetry_init(void)
|
|||
pips_timer_count = timer0_get_count_value(PIPS_FREQUENCY);
|
||||
ax25_timer_count = timer0_get_count_value(AX25_TICK_RATE);
|
||||
rsid_timer_count = timer0_get_count_value(RSID_SYMBOL_RATE*2); /* 2x Subtick */
|
||||
|
||||
/* Setup fconfig for telemetry. This is static */
|
||||
si_trx_get_frequency_configuration(&telemetry_fconfig, TELEMETRY_FREQUENCY);
|
||||
}
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue