More re-orginisation to telemetry etc, added working RSID demo run

geofence_dev
Richard Meadows 2015-03-06 19:30:33 +00:00
rodzic 7fc4421939
commit 67719ea8b5
13 zmienionych plików z 581 dodań i 58 usunięć

Wyświetl plik

@ -3,7 +3,7 @@
| Type | Peripheral | Function | Notes
| --- | --- | --- | ---
|*GLCK*|
||gclk0|main|
||gclk0|main|2MHz??
|*TC*||
||tc0|
||tc1|

Wyświetl plik

@ -30,6 +30,8 @@
*/
#define CONTESTIA_NUMBER_OF_TONES 32
#define CONTESTIA_CHARACTERS_PER_BLOCK 5
#define CONTESTIA_CHANNEL_SPACING 4 // Corresponds to 31.22 Hz
#define CONTESTIA_SYMBOL_RATE 31.25
void contestia_start(char* data);

Wyświetl plik

@ -114,6 +114,7 @@
#define SI406X_SDN_PIN PIN_PA16
#define SI406X_GPIO0_PIN PIN_PA27
#define SI406X_GPIO1_PIN PIN_PA25
#define SI406X_GPIO1_PINMUX PINMUX_PA25F_TC5_WO1
#define SI406X_TCXO_PIN PIN_PA17
#define SI406X_TCXO_PINMUX PINMUX_PA17H_GCLK_IO3

184
firmware/inc/rsid.h 100644
Wyświetl plik

@ -0,0 +1,184 @@
/*
* Reed-Solomon Identification (RSID) functions
* Copyright (C) 2014 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 RSID_H
#define RSID_H
#define RSID_NSYMBOLS 15
#define RSID_SYMBOL_RATE (11025.0 / 1024.0)
/**
* The RSID codes for all supported modes.
*
* From http://www.w1hkj.com/RSID_description.html
*/
typedef enum rsid_code_t {
RSID_BPSK31 = 1,
RSID_QPSK31 = 110,
RSID_BPSK63 = 2,
RSID_QPSK63 = 3,
RSID_BPSK125 = 4,
RSID_QPSK125 = 5,
RSID_BPSK250 = 126,
RSID_QPSK250 = 127,
RSID_BPSK500 = 173,
RSID_PSK125R = 183,
RSID_PSK250R = 186,
RSID_PSK500R = 187,
RSID_PSKFEC31 = 7,
RSID_PSK10 = 8,
RSID_MT63_500_LG = 9,
RSID_MT63_500_ST = 10,
RSID_MT63_500_VST = 11,
RSID_MT63_1000_LG = 12,
RSID_MT63_1000_ST = 13,
RSID_MT63_1000_VST = 14,
RSID_MT63_2000_LG = 15,
RSID_MT63_2000_ST = 17,
RSID_MT63_2000_VST = 18,
RSID_PSKAM10 = 19,
RSID_PSKAM31 = 20,
RSID_PSKAM50 = 21,
RSID_PSK63F = 22,
RSID_PSK220F = 23,
RSID_CHIP64 = 24,
RSID_CHIP128 = 25,
RSID_CW = 26,
RSID_CCW_OOK_12 = 27,
RSID_CCW_OOK_24 = 28,
RSID_CCW_OOK_48 = 29,
RSID_CCW_FSK_12 = 30,
RSID_CCW_FSK_24 = 31,
RSID_CCW_FSK_48 = 33,
RSID_PACTOR1_FEC = 34,
RSID_PACKET_110 = 113,
RSID_PACKET_300 = 35,
RSID_PACKET_1200 = 36,
RSID_RTTY_ASCII_7 = 37,
RSID_RTTY_ASCII_8 = 38,
RSID_RTTY_45 = 39,
RSID_RTTY_50 = 40,
RSID_RTTY_75 = 41,
RSID_AMTOR_FEC = 42,
RSID_THROB_1 = 43,
RSID_THROB_2 = 44,
RSID_THROB_4 = 45,
RSID_THROBX_1 = 46,
RSID_THROBX_2 = 47,
RSID_THROBX_4 = 146,
RSID_CONTESTIA_4_125 = 204,
RSID_CONTESTIA_4_250 = 55,
RSID_CONTESTIA_4_500 = 54,
RSID_CONTESTIA_4_1000 = 255,
RSID_CONTESTIA_4_2000 = 254,
RSID_CONTESTIA_8_125 = 169,
RSID_CONTESTIA_8_250 = 49,
RSID_CONTESTIA_8_500 = 52,
RSID_CONTESTIA_8_1000 = 117,
RSID_CONTESTIA_8_2000 = 247,
RSID_CONTESTIA_16_500 = 50,
RSID_CONTESTIA_16_1000 = 53,
RSID_CONTESTIA_16_2000 = 259,
RSID_CONTESTIA_32_1000 = 51,
RSID_CONTESTIA_32_2000 = 201,
RSID_CONTESTIA_64_500 = 194,
RSID_CONTESTIA_64_1000 = 193,
RSID_CONTESTIA_64_2000 = 191,
RSID_VOICE = 56,
RSID_MFSK8 = 60,
RSID_MFSK16 = 57,
RSID_MFSK32 = 147,
RSID_MFSK11 = 148,
RSID_MFSK22 = 152,
RSID_RTTYM_8_250 = 61,
RSID_RTTYM_16_500 = 62,
RSID_RTTYM_32_1000 = 63,
RSID_RTTYM_8_500 = 65,
RSID_RTTYM_16_1000 = 66,
RSID_RTTYM_4_500 = 67,
RSID_RTTYM_4_250 = 68,
RSID_RTTYM_8_1000 = 119,
RSID_RTTYM_8_125 = 170,
RSID_OLIVIA_4_125 = 203,
RSID_OLIVIA_4_250 = 75,
RSID_OLIVIA_4_500 = 74,
RSID_OLIVIA_4_1000 = 229,
RSID_OLIVIA_4_2000 = 238,
RSID_OLIVIA_8_125 = 163,
RSID_OLIVIA_8_250 = 69,
RSID_OLIVIA_8_500 = 72,
RSID_OLIVIA_8_1000 = 116,
RSID_OLIVIA_8_2000 = 214,
RSID_OLIVIA_16_500 = 70,
RSID_OLIVIA_16_1000 = 73,
RSID_OLIVIA_16_2000 = 234,
RSID_OLIVIA_32_1000 = 71,
RSID_OLIVIA_32_2000 = 221,
RSID_OLIVIA_64_2000 = 211,
RSID_PAX = 76,
RSID_PAX2 = 77,
RSID_DOMINOF = 78,
RSID_FAX = 79,
RSID_SSTV = 81,
RSID_DOMINOEX_4 = 84,
RSID_DOMINOEX_5 = 85,
RSID_DOMINOEX_8 = 86,
RSID_DOMINOEX_11 = 87,
RSID_DOMINOEX_16 = 88,
RSID_DOMINOEX_22 = 90,
RSID_DOMINOEX_4_FEC = 92,
RSID_DOMINOEX_5_FEC = 93,
RSID_DOMINOEX_8_FEC = 97,
RSID_DOMINOEX_11_FEC = 98,
RSID_DOMINOEX_16_FEC = 99,
RSID_DOMINOEX_22_FEC = 101,
RSID_FELD_HELL = 104,
RSID_PSK_HELL = 105,
RSID_HELL_80 = 106,
RSID_FM_HELL_105 = 107,
RSID_FM_HELL_245 = 108,
RSID_MODE_141A = 114,
RSID_DTMF = 123,
RSID_ALE400 = 125,
RSID_FDMDV = 131,
RSID_JT65_A = 132,
RSID_JT65_B = 134,
RSID_JT65_C = 135,
RSID_THOR_4 = 136,
RSID_THOR_8 = 137,
RSID_THOR_16 = 138,
RSID_THOR_5 = 139,
RSID_THOR_11 = 143,
RSID_THOR_22 = 145,
RSID_CALL_ID = 153,
RSID_PACKET_PSK1200 = 155,
RSID_PACKET_PSK250 = 156,
RSID_PACKET_PSK63 = 159,
RSID_MODE_188_110A_8N1 = 172,
} rsid_code_t;
void rsid_start(rsid_code_t rsid_code);
uint8_t rsid_tick(void);
#endif

Wyświetl plik

@ -25,6 +25,13 @@
#ifndef RTTY_H
#define RTTY_H
/**
* 50 baud RTTY
*/
#define RTTY_BITRATE 50
#define RTTY_CHANNEL_SPACING 52 // Corresponds to 405.9Hz spacing
void rtty_start(uint8_t data);
uint8_t rtty_tick(void);

Wyświetl plik

@ -29,9 +29,9 @@
float si_trx_get_temperature(void);
void si_trx_on(uint8_t modulation_type, float channel_spacing);
void si_trx_on(uint8_t modulation_type);
void si_trx_off(void);
void si_trx_switch_channel(uint8_t channel);
void si_trx_switch_channel(int16_t channel);
void si_trx_init(void);

Wyświetl plik

@ -31,7 +31,10 @@ uint16_t crc_checksum(char *string);
enum telemetry_t {
TELEMETRY_RTTY,
TELEMETRY_CONTESTIA
TELEMETRY_CONTESTIA,
TELEMETRY_RSID,
TELEMETRY_APRS,
TELEMETRY_PIPS,
};
/**
@ -49,6 +52,11 @@ int telemetry_start(enum telemetry_t type);
int32_t telemetry_get_index(void);
void telemetry_set_length(int32_t length);
void timer0_tick_init(float frequency);
float timer0_tick_init(float frequency);
void timer0_tick_deinit();
void telemetry_gpio1_pwm_init(void);
void telemetry_gpio1_pwm_duty(float duty_cycle);
void telemetry_gpio1_pwm_deinit(void);
#endif /* TELEMETRY_H */

Wyświetl plik

@ -22,9 +22,11 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "si_trx.h"
#include "samd20.h"
#include "contestia.h"
#include "telemetry.h"
#include "si_trx.h"
#include "mfsk.h"
/**
* Current output tones
@ -52,11 +54,15 @@ uint8_t contestia_tick(void) {
if (contestia_tone_index < CONTESTIA_NUMBER_OF_TONES) {
uint8_t binary_code;
uint8_t grey_code;
int16_t channel;
/* Output grey code */
binary_code = contestia_tones[contestia_tone_index];
grey_code = (binary_code >> 1) ^ binary_code;
si_trx_switch_channel(grey_code);
/* Align this to a channel */
channel = grey_code - (CONTESTIA_NUMBER_OF_TONES / 2);
si_trx_switch_channel(channel * CONTESTIA_CHANNEL_SPACING);
} else {
return 0;

Wyświetl plik

@ -39,6 +39,7 @@
#include "system/wdt.h"
#include "timepulse.h"
#include "telemetry.h"
#include "rsid.h"
#include "si_trx.h"
#include "si_trx_defs.h"
#include "analogue.h"
@ -317,11 +318,19 @@ int main(void)
led_on();
while (1) {
/* Watchdog */
//wdt_reset_count();
/* Send the next packet */
output_telemetry_string();
//output_telemetry_string();
telemetry_start_rsid(RSID_CONTESTIA_32_1000);
/* Sleep Wait */
while (telemetry_active()) {
system_sleep();
}
}
}

174
firmware/src/rsid.c 100644
Wyświetl plik

@ -0,0 +1,174 @@
/*
* Reed-Solomon Identification (RSID) functions
* Copyright (C) 2014 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 "rsid.h"
#include "telemetry.h"
#include "si_trx.h"
/**
* USEFUL RESOURCES ============================================================
*
* http://www.w1hkj.com/RSID_description.html
*
* dl-fldigi source:
* https://github.com/jamescoxon/dl-fldigi/blob/master/src/rsid/rsid.cxx#L180
*/
/**
* ENCODING
* =============================================================================
*/
/**
* Constants used in the Reed-Solomon encoding
*/
const int rsid_squares[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,
0, 2, 4, 6, 8,10,12,14, 9,11,13,15, 1, 3, 5, 7,
0, 3, 6, 5,12,15,10, 9, 1, 2, 7, 4,13,14,11, 8,
0, 4, 8,12, 9,13, 1, 5,11,15, 3, 7, 2, 6,10,14,
0, 5,10,15,13, 8, 7, 2, 3, 6, 9,12,14,11, 4, 1,
0, 6,12,10, 1, 7,13,11, 2, 4,14, 8, 3, 5,15, 9,
0, 7,14, 9, 5, 2,11,12,10,13, 4, 3,15, 8, 1, 6,
0, 8, 9, 1,11, 3, 2,10,15, 7, 6,14, 4,12,13, 5,
0, 9,11, 2,15, 6, 4,13, 7,14,12, 5, 8, 1, 3,10,
0,10,13, 7, 3, 9,14, 4, 6,12,11, 1, 5,15, 8, 2,
0,11,15, 4, 7,12, 8, 3,14, 5, 1,10, 9, 2, 6,13,
0,12, 1,13, 2,14, 3,15, 4, 8, 5, 9, 6,10, 7,11,
0,13, 3,14, 6,11, 5, 8,12, 1,15, 2,10, 7, 9, 4,
0,14, 5,11,10, 4,15, 1,13, 3, 8, 6, 7, 9, 2,12,
0,15, 7, 8,14, 1, 9, 6, 5,10, 2,13,11, 4,12, 3
};
const int rsid_indices[] = {
2, 4, 8, 9, 11, 15, 7, 14, 5, 10, 13, 3
};
/**
* This function populates the RSID_NSYMBOLS tones needed to transmit
* a RSID for the given rsid_code
*/
void rsid_encode(rsid_code_t rsid_code, int8_t* rsid)
{
memset(rsid, 0, RSID_NSYMBOLS * sizeof(int8_t));
/* Encode the 12-bit code into the first 3 nibbles */
rsid[0] = (rsid_code >> 8) & 0x0F;
rsid[1] = (rsid_code >> 4) & 0x0F;
rsid[2] = (rsid_code >> 0) & 0x0F;
for (int i = 0; i < 12; i++) {
for (int j = RSID_NSYMBOLS - 1; j > 0; j--) {
rsid[j] = rsid[j - 1] ^ rsid_squares[(rsid[j] << 4) + rsid_indices[i]];
}
rsid[0] = rsid_squares[(rsid[0] << 4) + rsid_indices[i]];
}
}
/**
* TRANSMISSION
* =============================================================================
*/
uint8_t rsid_index = 0xFE;
int8_t rsid[RSID_NSYMBOLS];
#define MODEM_TONE_SPACING 7.805
#define RSID_LOOKUP
/* Lookup tables designed for a modem tone spacing of 7.805 Hz */
int8_t rsid_tones_channels[] = { 0, 1, 3, 4, 6, 7, 8, 10, 11 };
float rsid_tones_deviations[] = {
0, 0.379, -0.241, 0.138, -0.482, -0.103, 0.276, -0.344, 0.035 };
/**
* Setup a rsid transmission
*/
void rsid_start(rsid_code_t rsid_code)
{
/* Start transmission */
rsid_index = 0;
rsid_encode(rsid_code, rsid);
}
/**
* Outputs one of the 16 RSID tones
*/
void rsid_tone(uint8_t tone)
{
int16_t channel;
float deviation;
int8_t air_tone = tone - 7;
#ifdef RSID_LOOKUP
if (air_tone >= 0) {
channel = rsid_tones_channels[air_tone];
deviation = rsid_tones_deviations[air_tone];
} else {
channel = -rsid_tones_channels[-air_tone];
deviation = -rsid_tones_deviations[-air_tone];
}
#else
/* Calcuate the offset of this tone in channels */
float tone_offset = ((float)air_tone * (float)RSID_SYMBOL_RATE) / (float)MODEM_TONE_SPACING;
/* Centre channel */
channel = (int16_t)round(tone_offset);
/* And the deviation from this we need, in channels */
deviation = tone_offset - (float)channel;
#endif
float duty_cycle = 0.5 + (deviation / 2); // FSK only provides a marginal improvement in performance!
si_trx_switch_channel(channel);
telemetry_gpio1_pwm_duty(duty_cycle);
}
/**
* Called at the rsid baud rate
*/
uint8_t rsid_tick(void)
{
if (rsid_index < RSID_NSYMBOLS) {
/* Transmit this tone */
rsid_tone(rsid[rsid_index]);
rsid_index++;
if (rsid_index < RSID_NSYMBOLS) {
return 1;
}
}
return 0;
}

Wyświetl plik

@ -27,15 +27,19 @@
#include "samd20.h"
#include "rtty.h"
#include "hw_config.h"
#include "system/port.h"
#include "si_trx.h"
/**
* Interface to the physical world.
*/
#define RTTY_ACTIVATE()
#define RTTY_DEACTIVATE()
#define RTTY_SET(b) port_pin_set_output_level(SI406X_GPIO1_PIN, !b);
#define RTTY_NEXT()
#define RTTY_CHANNEL_DEVIATION (RTTY_CHANNEL_SPACING / 2)
#define RTTY_CHANNEL(b) (b ? RTTY_CHANNEL_DEVIATION : -RTTY_CHANNEL_DEVIATION)
#define RTTY_SET(b) si_trx_switch_channel(RTTY_CHANNEL(b))
//port_pin_set_output_level(SI406X_GPIO1_PIN, !b);
/**
* Formatting 8N2

Wyświetl plik

@ -35,6 +35,13 @@
#define VCXO_FREQUENCY SI406X_TCXO_FREQUENCY
#define RF_DEVIATION 200
/**
* The LSB tuning resolution of the frac-n pll as currently
* configured.
*/
float lsb_tuning_resolution = 0;
/**
* Generic SPI Send / Receive
*/
@ -223,16 +230,6 @@ static void si_trx_frequency_control_set_divider(uint8_t integer_divider,
SI_FREQ_CONTROL_INTE,
divider);
}
/**
* Sets the step size between adjacent channels, in units of the
* resolution of the frac-n pll synthesiser.
*/
static void si_trx_frequency_control_set_channel_step_size(uint16_t step_size)
{
_si_trx_set_property_16(SI_PROPERTY_GROUP_FREQ_CONTROL,
SI_FREQ_CONTROL_CHANNEL_STEP_SIZE,
step_size);
}
/**
* Sets the output divider of the frac-n pll synthesiser
*/
@ -243,7 +240,11 @@ static void si_trx_frequency_control_set_band(uint8_t band, uint8_t sy_sel)
sy_sel | (band & 0x7));
}
/**
* Sets the frequency deviation in the modem
* Sets the modem frequency deviation. This is how much the external
* pin deviates the synthesiser from the centre frequency. In units of
* the resolution of the frac-n pll synthsiser.
*
* This is an unsigned 17-bit value.
*/
static void si_trx_modem_set_deviation(uint32_t deviation)
{
@ -251,6 +252,19 @@ static void si_trx_modem_set_deviation(uint32_t deviation)
SI_MODEM_FREQ_DEV,
deviation);
}
/**
* Sets the modem frequency offset manually. In units of the
* resolution of the frac-n pll synthsiser.
*
* This is a signed 16-bit value.
*/
static void si_trx_modem_set_offset(int16_t offset)
{
_si_trx_set_property_16(SI_PROPERTY_GROUP_MODEM,
SI_MODEM_FREQ_OFFSET,
offset);
}
/**
* Sets the modulation mode
*/
@ -283,9 +297,11 @@ static void si_trx_set_tx_pa_duty_cycle(uint8_t pa_duty_cycle)
/**
* Set the synthesiser to the given frequency
* Set the synthesiser to the given frequency.
*
* Returns the LSB tuning resolution of the frac-n pll synthesiser.
*/
static void si_trx_set_frequency(uint32_t frequency, float channel_spacing)
static float si_trx_set_frequency(uint32_t frequency)
{
uint8_t outdiv, band, nprescaler;
@ -309,25 +325,19 @@ static void si_trx_set_frequency(uint32_t frequency, float channel_spacing)
outdiv = 24; band = SI_MODEM_CLKGEN_FVCO_DIV_24;
}
uint32_t f_pfd = nprescaler * VCXO_FREQUENCY / outdiv;
float f_pfd = nprescaler * VCXO_FREQUENCY / outdiv;
uint16_t n = ((uint16_t)(frequency / f_pfd)) - 1;
float ratio = (float)frequency / (float)f_pfd;
float ratio = (float)frequency / f_pfd;
float rest = ratio - (float)n;
uint32_t m = (uint32_t)(rest * (float)(1 << 19));
/* Check n and m are in valid ranges, halt otherwise */
if (n > 0x7f || m > 0xfffff) while (1);
/* Set the modem deviation, in units of the VCO resolution */
float dev_ratio = (float)RF_DEVIATION / (float)f_pfd;
uint32_t dev = (uint32_t)(dev_ratio * (float)(1 << 19));
/* Set the channel spacing, in units of the VCO resolution */
float channel_spacing_ratio = channel_spacing / (float)f_pfd;
uint32_t channel_step = (uint32_t)(channel_spacing_ratio * (float)(1 << 19));
/* Set the frac-n PLL output divider */
if (nprescaler == 4) { /* Prescaler */
@ -336,20 +346,21 @@ static void si_trx_set_frequency(uint32_t frequency, float channel_spacing)
si_trx_frequency_control_set_band(band, SI_MODEM_CLKGEN_SY_SEL_1);
}
/* Set the frac-n PLL divisior */
si_trx_frequency_control_set_divider(n, m);
/* Set the channel step in the PLL */
si_trx_frequency_control_set_channel_step_size(channel_step);
/* Set the external pin frequency deviation to the LSB tuning resoultion */
si_trx_modem_set_deviation(1);
/* Set the frequency deviation in the modem */
si_trx_modem_set_deviation(dev);
/* 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, float channel_spacing)
void si_trx_reset(uint8_t modulation_type)
{
_si_trx_sdn_enable(); /* active high shutdown = reset */
@ -376,7 +387,7 @@ void si_trx_reset(uint8_t modulation_type, float channel_spacing)
SI_GPIO_PIN_CFG_GPIO_MODE_INPUT | SI_GPIO_PIN_CFG_PULL_ENABLE,
SI_GPIO_PIN_CFG_DRV_STRENGTH_LOW);
si_trx_set_frequency(RADIO_FREQUENCY, channel_spacing);
si_trx_set_frequency(RADIO_FREQUENCY);
si_trx_set_tx_power(RADIO_POWER);
/* RTTY from GPIO1 */
@ -391,10 +402,10 @@ void si_trx_reset(uint8_t modulation_type, float channel_spacing)
/**
* Enables the radio and starts transmitting
*/
void si_trx_on(uint8_t modulation_type, float channel_spacing)
void si_trx_on(uint8_t modulation_type)
{
si_trx_reset(modulation_type, channel_spacing);
si_trx_start_tx(1);
si_trx_reset(modulation_type);
si_trx_start_tx(0);
}
/**
* Disables the radio and places it in shutdown
@ -404,13 +415,13 @@ void si_trx_off(void)
si_trx_state_ready();
_si_trx_sdn_enable();
}
/**
* Switches the transmittion to the specified channel
* Switches the transmission to the specified channel. Signed 16-bit int
*/
void si_trx_switch_channel(uint8_t channel)
void si_trx_switch_channel(int16_t channel)
{
si_trx_state_ready();
si_trx_start_tx(channel);
si_trx_modem_set_offset(channel);
}
/**

Wyświetl plik

@ -29,6 +29,7 @@
#include "telemetry.h"
#include "rtty.h"
#include "contestia.h"
#include "rsid.h"
#include "si_trx.h"
#include "si_trx_defs.h"
#include "system/gclk.h"
@ -125,17 +126,15 @@ int telemetry_start(enum telemetry_t type) {
/* Initialise */
telemetry_type = type;
telemetry_index = 0;
/* Initialise first block / character */
telemetry_string_length = TELEMETRY_STRING_MAX;
/* Setup timer tick */
switch(telemetry_type) {
case TELEMETRY_CONTESTIA:
timer0_tick_init(31.25);
timer0_tick_init(CONTESTIA_SYMBOL_RATE);
break;
case TELEMETRY_RTTY:
timer0_tick_init(50);
timer0_tick_init(RTTY_BITRATE);
break;
}
@ -144,6 +143,32 @@ int telemetry_start(enum telemetry_t type) {
return 1; /* Already active */
}
}
/**
* Start RSID output. Argument: RSID Data
*
* Returns 0 on success, 1 if already active
*/
int telemetry_start_rsid(rsid_code_t rsid) {
if (!telemetry_active()) {
/* Initialise */
telemetry_type = TELEMETRY_RSID;
telemetry_index = 0;
telemetry_string_length = 6;
/* Start RSID */
rsid_start(rsid);
/* Setup timer tick */
timer0_tick_init(RSID_SYMBOL_RATE);
return 0; /* Success */
} else {
return 1; /* Already active */
}
}
/**
* Returns the index of the current byte being outputted from the buffer
*/
@ -185,8 +210,8 @@ void telemetry_tick(void) {
case TELEMETRY_CONTESTIA: /* ---- ---- A block mode */
if (!radio_on) {
/* Contestia: We switch channel to modulate */
si_trx_on(SI_MODEM_MOD_TYPE_CW, 31.25);
/* Contestia: We use the modem offset to modulate */
si_trx_on(SI_MODEM_MOD_TYPE_CW);
radio_on = 1;
}
@ -205,8 +230,8 @@ void telemetry_tick(void) {
case TELEMETRY_RTTY: /* ---- ---- A character mode */
if (!radio_on) {
/* RTTY Mode: We modulate using the external pin */
si_trx_on(SI_MODEM_MOD_TYPE_2FSK, 0);
/* RTTY: We use the modem offset to modulate */
si_trx_on(SI_MODEM_MOD_TYPE_CW);
radio_on = 1;
}
@ -222,10 +247,36 @@ void telemetry_tick(void) {
}
break;
case TELEMETRY_RSID: /* ---- ---- A block mode */
/* Wait for 5 bit times of silence */
if (telemetry_index < 5) {
telemetry_index++;
return;
}
if (!radio_on) {
/* RSID: We PWM frequencies with the external pin */
si_trx_on(SI_MODEM_MOD_TYPE_2FSK);
telemetry_gpio1_pwm_init();
radio_on = 1;
}
/* Do Tx */
if (!rsid_tick()) {
/* Force transmission finished */
telemetry_index++;
is_telemetry_finished(); // Returns true
telemetry_gpio1_pwm_deinit();
return;
}
}
}
}
/**
* CLOCKING
* =============================================================================
@ -250,8 +301,10 @@ void si_gclk_setup(void)
/**
* Initialises a timer interupt at the given frequency
*
* Returns the frequency we actually initialised.
*/
void timer0_tick_init(float frequency)
float timer0_tick_init(float frequency)
{
//si_gclk_setup();
@ -293,6 +346,9 @@ void timer0_tick_init(float frequency)
/* Enable Timer */
tc_enable(TC0);
tc_start_counter(TC0);
/* Return the frequency we actually initialised */
return gclk_frequency / (float)count;
}
/**
* Disables the timer
@ -315,3 +371,64 @@ void TC0_Handler(void)
telemetry_tick();
}
}
#define GPIO1_PWM_STEPS 200 // ~ 20kHz on a 4 MHz clock
/**
* Initialised PWM at the given duty cycle on the GPIO1 pin of the radio
*/
void telemetry_gpio1_pwm_init(void)
{
bool capture_channel_enables[] = {false, true};
uint32_t compare_channel_values[] = {0x0000, 0x0000}; // Set duty cycle at 0% by default
//float gclk_frequency = (float)system_gclk_chan_get_hz(0);
tc_init(TC5,
GCLK_GENERATOR_0,
TC_COUNTER_SIZE_8BIT,
TC_CLOCK_PRESCALER_DIV1,
TC_WAVE_GENERATION_NORMAL_PWM,
TC_RELOAD_ACTION_GCLK,
TC_COUNT_DIRECTION_UP,
TC_WAVEFORM_INVERT_OUTPUT_NONE,
false, /* Oneshot = false */
false, /* Run in standby = false */
0x0000, /* Initial value */
GPIO1_PWM_STEPS, /* Top value */
capture_channel_enables, /* Capture Channel Enables */
compare_channel_values); /* Compare Channels Values */
/* Enable the output pin */
system_pinmux_pin_set_config(SI406X_GPIO1_PINMUX >> 16, /* GPIO Pin */
SI406X_GPIO1_PINMUX & 0xFFFF, /* Mux Position */
SYSTEM_PINMUX_PIN_DIR_INPUT, /* Direction */
SYSTEM_PINMUX_PIN_PULL_NONE, /* Pull */
false); /* Powersave */
tc_enable(TC5);
tc_start_counter(TC5);
}
/**
* Sets duty cycle on PWM pin
*/
void telemetry_gpio1_pwm_duty(float duty_cycle)
{
uint32_t compare_value = (float)GPIO1_PWM_STEPS * duty_cycle;
tc_set_compare_value(TC5,
TC_COMPARE_CAPTURE_CHANNEL_1,
compare_value);
}
/**
* Turn the pwm off again
*/
void telemetry_gpio1_pwm_deinit(void)
{
tc_stop_counter(TC5);
tc_enable(TC5);
}