Pre-calculate si settings for each frequency. Apparently this only shaves 2 ms off the startup time but hey

master
Richard Meadows 2015-07-18 22:30:57 +01:00
rodzic a734ffef5b
commit 2df3eaf783
4 zmienionych plików z 75 dodań i 49 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);
}
/**

Wyświetl plik

@ -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);
}