kopia lustrzana https://github.com/bristol-seds/pico-tracker
Improved RSID with new si filter profile, leave some time for si startup
rodzic
a518ed92f9
commit
5aea2ccd50
|
@ -31,6 +31,7 @@ enum rf_tests {
|
||||||
RF_TEST_APRS_HIGH_FM_TONE,
|
RF_TEST_APRS_HIGH_FM_TONE,
|
||||||
RF_TEST_APRS_TONE,
|
RF_TEST_APRS_TONE,
|
||||||
RF_TEST_TELEMETRY_TONE,
|
RF_TEST_TELEMETRY_TONE,
|
||||||
|
RF_TEST_RSID,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RF_TEST RF_TEST_NONE
|
#define RF_TEST RF_TEST_NONE
|
||||||
|
|
|
@ -27,12 +27,18 @@
|
||||||
|
|
||||||
#include "samd20.h"
|
#include "samd20.h"
|
||||||
|
|
||||||
|
enum si_filter_model {
|
||||||
|
SI_FILTER_DEFAULT,
|
||||||
|
SI_FILTER_APRS,
|
||||||
|
SI_FILTER_RSID
|
||||||
|
};
|
||||||
|
|
||||||
float si_trx_get_temperature(void);
|
float si_trx_get_temperature(void);
|
||||||
|
|
||||||
void si_trx_modem_set_deviation(uint32_t deviation);
|
void si_trx_modem_set_deviation(uint32_t deviation);
|
||||||
|
|
||||||
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
void si_trx_on(uint8_t modulation_type, uint32_t frequency,
|
||||||
uint16_t deviation, uint8_t power);
|
uint16_t deviation, uint8_t power, enum si_filter_model filter);
|
||||||
void si_trx_off(void);
|
void si_trx_off(void);
|
||||||
|
|
||||||
void si_trx_modem_set_offset(int16_t channel);
|
void si_trx_modem_set_offset(int16_t channel);
|
||||||
|
|
|
@ -39,12 +39,12 @@
|
||||||
void telemetry_tone(void)
|
void telemetry_tone(void)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 36);
|
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 36, SI_FILTER_DEFAULT);
|
||||||
for (int i = 0; i < 200*1000; i++) {
|
for (int i = 0; i < 200*1000; i++) {
|
||||||
idle(IDLE_TELEMETRY_ACTIVE);
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
}
|
}
|
||||||
si_trx_off();
|
si_trx_off();
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 0x7f);
|
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||||
for (int i = 0; i < 200*1000; i++) {
|
for (int i = 0; i < 200*1000; i++) {
|
||||||
idle(IDLE_TELEMETRY_ACTIVE);
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
@ -54,12 +54,12 @@ void telemetry_tone(void)
|
||||||
void aprs_tone(void)
|
void aprs_tone(void)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 36);
|
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 36, SI_FILTER_DEFAULT);
|
||||||
for (int i = 0; i < 200*1000; i++) {
|
for (int i = 0; i < 200*1000; i++) {
|
||||||
idle(IDLE_TELEMETRY_ACTIVE);
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
}
|
}
|
||||||
si_trx_off();
|
si_trx_off();
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 0x7f);
|
si_trx_on(SI_MODEM_MOD_TYPE_CW, APRS_TEST_FREQUENCY, 0, 0x7f, SI_FILTER_DEFAULT);
|
||||||
for (int i = 0; i < 200*1000; i++) {
|
for (int i = 0; i < 200*1000; i++) {
|
||||||
idle(IDLE_TELEMETRY_ACTIVE);
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ void aprs_high_fm_tone(void)
|
||||||
false); /* Output Pin Enable */
|
false); /* Output Pin Enable */
|
||||||
|
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, APRS_TEST_FREQUENCY,
|
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, APRS_TEST_FREQUENCY,
|
||||||
AX25_DEVIATION, APRS_POWER);
|
AX25_DEVIATION, APRS_POWER, SI_FILTER_APRS);
|
||||||
while (1) {
|
while (1) {
|
||||||
idle(IDLE_TELEMETRY_ACTIVE);
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,23 @@ void aprs_test(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSID function for use during testing. Not for flight
|
||||||
|
*/
|
||||||
|
void rsid_test(void)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
telemetry_start_rsid(RSID_CONTESTIA_32_1000);
|
||||||
|
|
||||||
|
// Sleep wait for RSID
|
||||||
|
while (telemetry_active()) {
|
||||||
|
idle(IDLE_TELEMETRY_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 3*200*1000; i; i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void rf_tests(void)
|
void rf_tests(void)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +142,9 @@ void rf_tests(void)
|
||||||
case RF_TEST_TELEMETRY_TONE:
|
case RF_TEST_TELEMETRY_TONE:
|
||||||
telemetry_tone();
|
telemetry_tone();
|
||||||
break;
|
break;
|
||||||
|
case RF_TEST_RSID:
|
||||||
|
rsid_test();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ void rsid_encode(rsid_code_t rsid_code, int8_t* rsid)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t rsid_index = 0xFE;
|
uint8_t rsid_index = 0xFE;
|
||||||
|
uint8_t rsid_subtick;
|
||||||
int8_t rsid[RSID_NSYMBOLS];
|
int8_t rsid[RSID_NSYMBOLS];
|
||||||
|
|
||||||
#define MODEM_TONE_SPACING 7.805
|
#define MODEM_TONE_SPACING 7.805
|
||||||
|
@ -118,6 +119,7 @@ void rsid_start(rsid_code_t rsid_code)
|
||||||
{
|
{
|
||||||
/* Start transmission */
|
/* Start transmission */
|
||||||
rsid_index = 0;
|
rsid_index = 0;
|
||||||
|
rsid_subtick = 0;
|
||||||
rsid_encode(rsid_code, rsid);
|
rsid_encode(rsid_code, rsid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,24 +149,35 @@ void rsid_tone(uint8_t tone)
|
||||||
deviation = tone_offset - (float)channel;
|
deviation = tone_offset - (float)channel;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float duty_cycle = 0.5 + (deviation / 2); // FSK only provides a marginal improvement in performance!
|
float duty_cycle = 0.5 + deviation;
|
||||||
|
|
||||||
si_trx_switch_channel(channel);
|
si_trx_switch_channel(channel-2); /* -2 offset to line up with contestia signal */
|
||||||
telemetry_gpio1_pwm_duty(duty_cycle);
|
telemetry_gpio1_pwm_duty(duty_cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called at the rsid baud rate
|
* Called at the rsid baud rate
|
||||||
|
*
|
||||||
|
* We mantain the first tone longer than the others to give the radio
|
||||||
|
* time to start up. Oh so hacky but hey
|
||||||
*/
|
*/
|
||||||
uint8_t rsid_tick(void)
|
uint8_t rsid_tick(void)
|
||||||
{
|
{
|
||||||
|
if (rsid_index < RSID_NSYMBOLS || rsid_subtick) {
|
||||||
|
|
||||||
if (rsid_index < RSID_NSYMBOLS) {
|
/* Actual tick */
|
||||||
|
if (rsid_subtick == 0) {
|
||||||
|
/* Transmit this tone */
|
||||||
|
rsid_tone(rsid[rsid_index]);
|
||||||
|
rsid_index++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Transmit this tone */
|
rsid_subtick++;
|
||||||
rsid_tone(rsid[rsid_index]);
|
if ((rsid_index-1 == 0 && rsid_subtick == 3) || /* First tone */
|
||||||
|
(rsid_index-1 != 0 && rsid_subtick == 2)) { /* Other tones */
|
||||||
|
rsid_subtick = 0;
|
||||||
|
}
|
||||||
|
|
||||||
rsid_index++;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,7 @@ static float si_trx_set_frequency(uint32_t frequency, uint16_t deviation)
|
||||||
* Resets the transceiver
|
* Resets the transceiver
|
||||||
*/
|
*/
|
||||||
void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
||||||
uint16_t deviation, uint8_t power)
|
uint16_t deviation, uint8_t power, enum si_filter_model filter)
|
||||||
{
|
{
|
||||||
_si_trx_sdn_enable(); /* active high shutdown = reset */
|
_si_trx_sdn_enable(); /* active high shutdown = reset */
|
||||||
|
|
||||||
|
@ -459,22 +459,40 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
||||||
si_trx_set_frequency(frequency, deviation);
|
si_trx_set_frequency(frequency, deviation);
|
||||||
si_trx_set_tx_power(power);
|
si_trx_set_tx_power(power);
|
||||||
|
|
||||||
/**
|
/* Modem tx filter coefficients */
|
||||||
* Modem tx filter coefficients for APRS
|
uint8_t rsid_si_coeff[] = {0x1, 0x4, 0x9, 0x11, 0x19, 0x22, 0x2a, 0x30, 0x31};
|
||||||
* 0dB @ 2.2kHz
|
|
||||||
* -6dB @ 1.2kHz (for pre-emphasis)
|
|
||||||
* < -30dB from 3.6KHz
|
|
||||||
*/
|
|
||||||
uint8_t p_si_coeff[] = {0x6, 0x8, 0x1, 0xf2, 0xe4, 0xe7, 0xff, 0x1d, 0x2b};
|
uint8_t p_si_coeff[] = {0x6, 0x8, 0x1, 0xf2, 0xe4, 0xe7, 0xff, 0x1d, 0x2b};
|
||||||
si_trx_modem_set_tx_datarate(1600); /* Filter sampling rate 1600*10 = 16kHz */
|
|
||||||
si_trx_modem_tx_filter_coefficients(p_si_coeff);
|
switch (filter) {
|
||||||
|
case SI_FILTER_APRS:
|
||||||
|
/**
|
||||||
|
* Modem tx filter coefficients for APRS
|
||||||
|
* 0dB @ 2.2kHz
|
||||||
|
* -6dB @ 1.2kHz (for pre-emphasis)
|
||||||
|
* < -30dB from 3.6KHz
|
||||||
|
*/
|
||||||
|
si_trx_modem_set_tx_datarate(1600); /* Filter sampling rate 1600*10 = 16kHz */
|
||||||
|
si_trx_modem_tx_filter_coefficients(p_si_coeff);
|
||||||
|
break;
|
||||||
|
case SI_FILTER_RSID:
|
||||||
|
/**
|
||||||
|
* Modem tx filter coefficients for RSID
|
||||||
|
* -6dB @ dc (for ±0.5 deviation max)
|
||||||
|
* < -50dB from 1.8KHz
|
||||||
|
*/
|
||||||
|
si_trx_modem_set_tx_datarate(1600); /* Filter sampling rate 1600*10 = 16kHz */
|
||||||
|
si_trx_modem_tx_filter_coefficients(rsid_si_coeff);
|
||||||
|
break;
|
||||||
|
default: /* Just leave the defaults from startup in place */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* RTTY from GPIO1 */
|
/* RTTY from GPIO1 */
|
||||||
si_trx_modem_set_modulation(SI_MODEM_MOD_DIRECT_MODE_SYNC, // ASYNC
|
si_trx_modem_set_modulation(SI_MODEM_MOD_DIRECT_MODE_SYNC, // ASYNC
|
||||||
SI_MODEM_MOD_GPIO_1,
|
SI_MODEM_MOD_GPIO_1,
|
||||||
SI_MODEM_MOD_SOURCE_DIRECT,
|
SI_MODEM_MOD_SOURCE_DIRECT,
|
||||||
modulation_type);
|
modulation_type);
|
||||||
|
|
||||||
si_trx_state_tx_tune();
|
si_trx_state_tx_tune();
|
||||||
}
|
}
|
||||||
|
@ -483,9 +501,9 @@ void si_trx_reset(uint8_t modulation_type, uint32_t frequency,
|
||||||
* Enables the radio and starts transmitting
|
* 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, uint32_t frequency,
|
||||||
uint16_t deviation, uint8_t power)
|
uint16_t deviation, uint8_t power, enum si_filter_model filter)
|
||||||
{
|
{
|
||||||
si_trx_reset(modulation_type, frequency, deviation, power);
|
si_trx_reset(modulation_type, frequency, deviation, power, filter);
|
||||||
si_trx_start_tx(0);
|
si_trx_start_tx(0);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -238,7 +238,8 @@ void telemetry_tick(void) {
|
||||||
|
|
||||||
if (!radio_on) {
|
if (!radio_on) {
|
||||||
/* Contestia: We use the modem offset to modulate */
|
/* 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_FREQUENCY, 1, TELEMETRY_POWER,
|
||||||
|
SI_FILTER_DEFAULT);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
contestia_preamble();
|
contestia_preamble();
|
||||||
}
|
}
|
||||||
|
@ -259,7 +260,8 @@ void telemetry_tick(void) {
|
||||||
|
|
||||||
if (!radio_on) {
|
if (!radio_on) {
|
||||||
/* RTTY: We use the modem offset to modulate */
|
/* 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_FREQUENCY, 1, TELEMETRY_POWER,
|
||||||
|
SI_FILTER_DEFAULT);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
rtty_preamble();
|
rtty_preamble();
|
||||||
}
|
}
|
||||||
|
@ -290,10 +292,9 @@ void telemetry_tick(void) {
|
||||||
/* RSID: We PWM frequencies with the external pin */
|
/* RSID: We PWM frequencies with the external pin */
|
||||||
telemetry_gpio1_pwm_init();
|
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_FREQUENCY, 1, TELEMETRY_POWER,
|
||||||
|
SI_FILTER_RSID);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do Tx */
|
/* Do Tx */
|
||||||
|
@ -304,6 +305,7 @@ void telemetry_tick(void) {
|
||||||
telemetry_gpio1_pwm_deinit();
|
telemetry_gpio1_pwm_deinit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TELEMETRY_APRS: /* ---- ---- APRS */
|
case TELEMETRY_APRS: /* ---- ---- APRS */
|
||||||
|
@ -313,8 +315,8 @@ void telemetry_tick(void) {
|
||||||
if (aprs_start() && _aprs_frequency) {
|
if (aprs_start() && _aprs_frequency) {
|
||||||
|
|
||||||
/* Radio on */
|
/* Radio on */
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, _aprs_frequency,
|
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, _aprs_frequency, AX25_DEVIATION,
|
||||||
AX25_DEVIATION, APRS_POWER);
|
APRS_POWER, SI_FILTER_APRS);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Stop immediately */
|
/* Stop immediately */
|
||||||
|
@ -333,7 +335,8 @@ void telemetry_tick(void) {
|
||||||
|
|
||||||
if (!radio_on) { /* Turn on */
|
if (!radio_on) { /* Turn on */
|
||||||
/* Pips: Cw */
|
/* Pips: Cw */
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER);
|
si_trx_on(SI_MODEM_MOD_TYPE_CW, TELEMETRY_FREQUENCY, 1, TELEMETRY_POWER,
|
||||||
|
SI_FILTER_DEFAULT);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
|
|
||||||
} else { /* Turn off */
|
} else { /* Turn off */
|
||||||
|
@ -430,7 +433,7 @@ void telemetry_init(void)
|
||||||
rtty_timer_count = timer0_get_count_value(RTTY_BITRATE);
|
rtty_timer_count = timer0_get_count_value(RTTY_BITRATE);
|
||||||
pips_timer_count = timer0_get_count_value(PIPS_FREQUENCY);
|
pips_timer_count = timer0_get_count_value(PIPS_FREQUENCY);
|
||||||
ax25_timer_count = timer0_get_count_value(AX25_TICK_RATE);
|
ax25_timer_count = timer0_get_count_value(AX25_TICK_RATE);
|
||||||
rsid_timer_count = timer0_get_count_value(RSID_SYMBOL_RATE);
|
rsid_timer_count = timer0_get_count_value(RSID_SYMBOL_RATE*2); /* 2x Subtick */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Ładowanie…
Reference in New Issue