kopia lustrzana https://github.com/bristol-seds/pico-tracker
[New feature] Generally working olivia / contestia implementation. Only decodes sometimes... Maybe needs a preamble?
rodzic
5f9735805e
commit
69e1ab99ca
Plik binarny nie jest wyświetlany.
|
@ -35,56 +35,89 @@
|
|||
|
||||
/**
|
||||
* Resources:
|
||||
* http://en.wikipedia.org/wiki/Fast_Walsh%E2%80%93Hadamard_transform
|
||||
*
|
||||
*
|
||||
* The Fast Walsh-Hadamard Transform is a divide and conquer algorithm
|
||||
* with a complexity of NlogN.
|
||||
*/
|
||||
|
||||
/**
|
||||
* We might want to use this with different types in the future.
|
||||
*/
|
||||
#define T int8_t
|
||||
|
||||
/**
|
||||
* Fast Walsh-Hadamard Transform
|
||||
*
|
||||
* `data` an array that is the input vector. Modifed in-place
|
||||
* `len` is the number of elements in `data`
|
||||
* `data` an array that is the input vector. It is modifed in-place to
|
||||
* become the output vector.
|
||||
* `length` is the number of elements in `data`. This must be a power of two
|
||||
*
|
||||
* The result is returned in "hadamard" order
|
||||
*/
|
||||
void fwht(T *Data, size_t Len)
|
||||
void fwht(int8_t *data, size_t length)
|
||||
{
|
||||
size_t Step, Ptr, Ptr2; T Bit1, Bit2, NewBit1, NewBit2;
|
||||
for(Step=1; Step<Len; Step*=2)
|
||||
{ for(Ptr=0; Ptr<Len; Ptr+=2*Step)
|
||||
{ for(Ptr2=Ptr; (Ptr2-Ptr)<Step; Ptr2+=1)
|
||||
{ Bit1=Data[Ptr2]; Bit2=Data[Ptr2+Step];
|
||||
NewBit1=Bit2; NewBit1+=Bit1;
|
||||
NewBit2=Bit2; NewBit2-=Bit1;
|
||||
Data[Ptr2]=NewBit1; Data[Ptr2+Step]=NewBit2;
|
||||
size_t step, decomp_index, index;
|
||||
int8_t lvalue, rvalue;
|
||||
|
||||
/**
|
||||
* The transform is decomposed into smaller WHTs.
|
||||
* We ignore the normalisation factors.
|
||||
*/
|
||||
|
||||
/* Iterate through the decompositions of size length --> 8, 4, 2 */
|
||||
for (step = length / 2; step; step /= 2) {
|
||||
|
||||
/* Iterate through each decomposition for this step size */
|
||||
for(decomp_index = 0; decomp_index < length; decomp_index += (step*2)) {
|
||||
|
||||
/* Interate through each DFT in the decomposition */
|
||||
for(index = 0; index < step; index++) {
|
||||
|
||||
/* Compute a two-point Discrete Fourier Transform (DFT) */
|
||||
lvalue = data[decomp_index + index];
|
||||
rvalue = data[decomp_index + index + step];
|
||||
|
||||
/* Sum */
|
||||
data[decomp_index + index] = lvalue + rvalue;
|
||||
/* Difference */
|
||||
data[decomp_index + index + step] = lvalue - rvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse Fast Hadamard Transform
|
||||
* Inverse Fast Walsh-Hadamard Transform
|
||||
*
|
||||
* `data` an array that is the input vector. Modifed in-place
|
||||
* `len` is the number of elements in `data`
|
||||
* `data` an array that is the input vector. It is modifed in-place to
|
||||
* become the output vector.
|
||||
* `len` is the number of elements in `data`.
|
||||
*
|
||||
* The result is returned in "hadamard" order
|
||||
*/
|
||||
void ifwht(T *Data, size_t len)
|
||||
void ifwht(int8_t *data, size_t length)
|
||||
{
|
||||
size_t step, Ptr, Ptr2; T Bit1, Bit2, NewBit1, NewBit2;
|
||||
for(step=len/2; step; step/=2)
|
||||
{ for(Ptr=0; Ptr<len; Ptr+=2*step)
|
||||
{ for(Ptr2=Ptr; (Ptr2-Ptr)<step; Ptr2+=1)
|
||||
{ Bit1=Data[Ptr2]; Bit2=Data[Ptr2+step];
|
||||
NewBit1=Bit1; NewBit1-=Bit2;
|
||||
NewBit2=Bit1; NewBit2+=Bit2;
|
||||
Data[Ptr2]=NewBit1; Data[Ptr2+step]=NewBit2;
|
||||
size_t step, decomp_index, index;
|
||||
int8_t lvalue, rvalue;
|
||||
|
||||
/**
|
||||
* The transform is decomposed into smaller WHTs.
|
||||
* We ignore the normalisation factors.
|
||||
*/
|
||||
|
||||
/* Iterate through the decompositions of size length --> 8, 4, 2 */
|
||||
for (step = length / 2; step; step /= 2) {
|
||||
|
||||
/* Iterate through each decomposition for this step size */
|
||||
for(decomp_index = 0; decomp_index < length; decomp_index += (step*2)) {
|
||||
|
||||
/* Interate through each IDFT in the decomposition */
|
||||
for(index = 0; index < step; index++) {
|
||||
|
||||
/* Compute a two-point Inverse Discrete Fourier Transform (IDFT) */
|
||||
lvalue = data[decomp_index + index];
|
||||
rvalue = data[decomp_index + index + step];
|
||||
|
||||
/* Difference */
|
||||
data[decomp_index + index] = lvalue - rvalue;
|
||||
/* Sum */
|
||||
data[decomp_index + index + step] = lvalue + rvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +129,7 @@ void ifwht(T *Data, size_t len)
|
|||
|
||||
int main(void)
|
||||
{
|
||||
T fwht_test[] = {1,0,1,0,0,1,1,0};
|
||||
int8_t fwht_test[] = {1,0,1,0,0,1,1,0};
|
||||
const int fwht_test_len = 8;
|
||||
|
||||
fwht(fwht_test, fwht_test_len);
|
||||
|
@ -107,7 +140,7 @@ int main(void)
|
|||
|
||||
|
||||
|
||||
T ifwht_test[] = {1,0,1,0,0,1,1,0};
|
||||
int8_t ifwht_test[] = {1,0,1,0,0,1,1,0};
|
||||
const int ifwht_test_len = 8;
|
||||
|
||||
ifwht(ifwht_test, ifwht_test_len);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "samd20.h"
|
||||
|
||||
void olivia_mfsk_encode_block(char* buffer, uint8_t* tones);
|
||||
void olivia_mfsk_encode_block(char* buffer, int8_t* tones);
|
||||
void contestia_mfsk_encode_block(char* block, int8_t* tones);
|
||||
|
||||
#endif /* MFSK_H */
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
|
||||
float si_trx_get_temperature(void);
|
||||
|
||||
void si_trx_on(void);
|
||||
void si_trx_on(uint8_t modulation_type, float channel_spacing);
|
||||
void si_trx_off(void);
|
||||
void si_trx_switch_channel(uint8_t channel);
|
||||
|
||||
void si_trx_init(void);
|
||||
|
||||
|
|
|
@ -26,6 +26,6 @@
|
|||
#define TELEMETRY_H
|
||||
|
||||
uint16_t crc_checksum(char *string);
|
||||
void timer0_tick_init(uint32_t frequency);
|
||||
void timer0_tick_init(float frequency);
|
||||
|
||||
#endif /* TELEMETRY_H */
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "system/port.h"
|
||||
#include "tc/tc_driver.h"
|
||||
#include "gps.h"
|
||||
#include "mfsk.h"
|
||||
#include "ubx_messages.h"
|
||||
#include "system/wdt.h"
|
||||
#include "timepulse.h"
|
||||
|
@ -47,6 +48,10 @@
|
|||
|
||||
#define CALLSIGN "UBSEDSx"
|
||||
|
||||
/* Set the modulation mode */
|
||||
//#define RTTY
|
||||
#define CONTESTIA
|
||||
|
||||
|
||||
/**
|
||||
* Initialises the status LED
|
||||
|
@ -257,6 +262,19 @@ void output_telemetry_string(void)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t started = 0;
|
||||
/* We transmit 64 tones */
|
||||
int8_t tones[] = {
|
||||
0x1a, 0x0c, 0x07, 0x1b, 0x00, 0x13, 0x12, 0x0d,
|
||||
0x12, 0x0d, 0x1f, 0x11, 0x1c, 0x1b, 0x18, 0x1e,
|
||||
0x0e, 0x02, 0x0e, 0x0a, 0x05, 0x08, 0x13, 0x13,
|
||||
0x1f, 0x10, 0x09, 0x0d, 0x07, 0x10, 0x1a, 0x1c,
|
||||
0x0b, 0x10, 0x01, 0x0e, 0x0f, 0x19, 0x0a, 0x1d,
|
||||
0x06, 0x1b, 0x0c, 0x13, 0x02, 0x0f, 0x06, 0x0c,
|
||||
0x1d, 0x15, 0x17, 0x09, 0x15, 0x14, 0x1f, 0x00,
|
||||
0x08, 0x06, 0x05, 0x09, 0x12, 0x13, 0x1e, 0x0a
|
||||
};
|
||||
|
||||
/**
|
||||
* MAIN
|
||||
* =============================================================================
|
||||
|
@ -289,8 +307,13 @@ int main(void)
|
|||
/* Configure the Power Manager */
|
||||
//powermananger_init();
|
||||
|
||||
/* Timer 0 for 50Hz triggering */
|
||||
/* Timer 0 clocks out data */
|
||||
#ifdef RTTY
|
||||
timer0_tick_init(50);
|
||||
#endif
|
||||
#ifdef CONTESTIA
|
||||
timer0_tick_init(31.25);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* System initialisation
|
||||
|
@ -304,11 +327,29 @@ int main(void)
|
|||
led_init();
|
||||
gps_init();
|
||||
|
||||
/* Initialise Si4060 */
|
||||
/* Initialise Si4060 interface */
|
||||
si_trx_init();
|
||||
|
||||
/* Start transmitting */
|
||||
si_trx_on();
|
||||
#ifdef RTTY
|
||||
/* RTTY Mode: We modulate using the external pin */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2FSK, 0);
|
||||
#endif
|
||||
#ifdef CONTESTIA
|
||||
/* Contestia: We switch channel to modulate */
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_CW, 31.25);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/* Prepare a tone sequence */
|
||||
char hello[] = "HELLO";
|
||||
// olivia_mfsk_encode_block(hello, tones);
|
||||
contestia_mfsk_encode_block(hello, tones);
|
||||
|
||||
|
||||
started = 1;
|
||||
|
||||
led_on();
|
||||
|
||||
|
@ -321,6 +362,10 @@ int main(void)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t tone_index = 0;
|
||||
uint8_t binary_code;
|
||||
uint8_t grey_code;
|
||||
|
||||
/**
|
||||
* Called at 50Hz
|
||||
*/
|
||||
|
@ -329,6 +374,26 @@ void TC0_Handler(void)
|
|||
if (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
|
||||
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);
|
||||
|
||||
#ifdef RTTY
|
||||
rtty_tick();
|
||||
#endif
|
||||
#ifdef CONTESTIA
|
||||
if (started) {
|
||||
if (tone_index < 32) {
|
||||
|
||||
binary_code = tones[tone_index];
|
||||
grey_code = (binary_code >> 1) ^ binary_code;
|
||||
|
||||
si_trx_switch_channel(grey_code);
|
||||
tone_index++;
|
||||
} else if (tone_index > 96) {
|
||||
|
||||
tone_index = 0;
|
||||
} else {
|
||||
si_trx_state_ready();
|
||||
tone_index++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
#endif
|
||||
|
||||
|
||||
static const uint64_t ScramblingCodeOlivia = 0xE257E6D0291574ECLL;
|
||||
static const uint64_t ScramblingCodeContestia = 0xEDB88320LL;
|
||||
static const uint64_t scrambler_olivia = 0xE257E6D0291574ECLL;
|
||||
static const uint64_t scrambler_contestia = 0xEDB88320LL;
|
||||
|
||||
/**
|
||||
* USEFUL RESOURES =============================================================
|
||||
|
@ -54,121 +54,113 @@ static const uint64_t ScramblingCodeContestia = 0xEDB88320LL;
|
|||
* https://github.com/jamescoxon/dl-fldigi/blob/master/src/include/jalocha/pj_mfsk.h
|
||||
*/
|
||||
|
||||
void mfsk_encode_block(char* block, int8_t* tones,
|
||||
uint8_t symbols_per_block, /* The number of on-the-air symbols to transmit for each block */
|
||||
uint8_t bits_per_symbol, /* The number of bits encoded in each on-the-air symbol */
|
||||
uint64_t scrambler, /* Scrambler sequence */
|
||||
uint8_t scrambling_shift) /* Scrambler shift */
|
||||
{
|
||||
int8_t fwht_vector[symbols_per_block];
|
||||
memset(tones, 0, symbols_per_block * sizeof(int8_t));
|
||||
|
||||
/**
|
||||
* There is one bit in the symbol for each character in the
|
||||
* block. Iterate over each character.
|
||||
*/
|
||||
for (uint8_t character = 0; character < bits_per_symbol; character++) {
|
||||
|
||||
/* Mask off unuseds bits in the character */
|
||||
block[character] &= ((symbols_per_block * 2) - 1);
|
||||
|
||||
/* Set a deviation in the input vector */
|
||||
memset(fwht_vector, 0, symbols_per_block * sizeof(int8_t));
|
||||
if (block[character] < symbols_per_block) {
|
||||
fwht_vector[block[character] - 0] = 1; /* +ve */
|
||||
} else {
|
||||
fwht_vector[block[character] - symbols_per_block] = -1; /* -ve */
|
||||
}
|
||||
|
||||
size_t BitsPerSymbol = 5;
|
||||
size_t Symbols = 32;
|
||||
/* Perform an in-place Inverse Fast Walsh-Hadamard Transform */
|
||||
ifwht(fwht_vector, symbols_per_block);
|
||||
|
||||
size_t BitsPerCharacter = 7;
|
||||
size_t SymbolsPerBlock = 64;
|
||||
/* Iterate over each symbol in the output block */
|
||||
for (uint32_t symbol = 0, mask_index = character * scrambling_shift;
|
||||
symbol < symbols_per_block;
|
||||
symbol++, mask_index++) {
|
||||
|
||||
uint8_t bContestia = 0;
|
||||
mask_index %= symbols_per_block;
|
||||
|
||||
int8_t FHT_Buffer[64]; /* SymbolsPerBlock */
|
||||
uint8_t OutputBlock[64]; /* SymbolsPerBlock */
|
||||
/* If this bit the FWHT is significant */
|
||||
if ((scrambler & (1LL << mask_index)) ?
|
||||
(fwht_vector[symbol] > 0) : /* Scrambled: +ve is significant */
|
||||
(fwht_vector[symbol] < 0)) { /* Not Scrambled: -ve is significant */
|
||||
|
||||
static const uint64_t ScramblingCode = 0xE257E6D0291574ECLL;
|
||||
/* Find the bit index to set */
|
||||
uint8_t rotation = symbol % bits_per_symbol;
|
||||
uint8_t bit_index = (character + rotation) % bits_per_symbol;
|
||||
|
||||
void EncodeCharacter(uint8_t Char) {
|
||||
size_t TimeBit;
|
||||
uint8_t Mask = (SymbolsPerBlock << 1) - 1;
|
||||
|
||||
if (bContestia) {
|
||||
if (Char >= 'a' && Char <= 'z')
|
||||
Char += 'A' - 'a';
|
||||
if (Char == ' ')
|
||||
Char = 59;
|
||||
else if (Char == '\r')
|
||||
Char = 60;
|
||||
else if (Char == '\n')
|
||||
Char = 0;
|
||||
else if (Char >= 33 && Char <= 90)
|
||||
Char -= 32;
|
||||
else if (Char == 8)
|
||||
Char = 61;
|
||||
else if (Char == 0)
|
||||
Char = 0;
|
||||
else
|
||||
Char = '?' - 32;
|
||||
//} else if (bRTTYM) {
|
||||
} else {
|
||||
Char &= Mask;
|
||||
}
|
||||
|
||||
for (TimeBit = 0; TimeBit < SymbolsPerBlock; TimeBit++)
|
||||
FHT_Buffer[TimeBit] = 0;
|
||||
if (Char<SymbolsPerBlock)
|
||||
FHT_Buffer[Char] = 1;
|
||||
else
|
||||
FHT_Buffer[Char-SymbolsPerBlock] = (-1);
|
||||
ifwht(FHT_Buffer, SymbolsPerBlock);
|
||||
}
|
||||
|
||||
void ScrambleFHT(size_t CodeOffset)
|
||||
{ size_t TimeBit;
|
||||
size_t CodeWrap=(SymbolsPerBlock-1);
|
||||
size_t CodeBit=CodeOffset&CodeWrap;
|
||||
for (TimeBit=0; TimeBit<SymbolsPerBlock; TimeBit++)
|
||||
{ uint64_t CodeMask=1; CodeMask<<=CodeBit;
|
||||
if (ScramblingCode&CodeMask)
|
||||
FHT_Buffer[TimeBit] = (-FHT_Buffer[TimeBit]);
|
||||
CodeBit+=1; CodeBit&=CodeWrap; }
|
||||
}
|
||||
|
||||
void EncodeBlock(uint8_t *InputBlock) {
|
||||
size_t FreqBit;
|
||||
size_t TimeBit;
|
||||
size_t nShift;
|
||||
|
||||
nShift = (bContestia) ? 5 : 13; // Contestia/RTTYM or Olivia
|
||||
|
||||
for (TimeBit = 0; TimeBit < SymbolsPerBlock; TimeBit ++)
|
||||
OutputBlock[TimeBit] = 0;
|
||||
|
||||
for (FreqBit = 0; FreqBit < BitsPerSymbol; FreqBit++) {
|
||||
EncodeCharacter(InputBlock[FreqBit]);
|
||||
ScrambleFHT(FreqBit * nShift);
|
||||
size_t Rotate = 0;
|
||||
for (TimeBit = 0; TimeBit < SymbolsPerBlock; TimeBit++) {
|
||||
if (FHT_Buffer[TimeBit] < 0) {
|
||||
size_t Bit = FreqBit+Rotate;
|
||||
if (Bit >= BitsPerSymbol) Bit -= BitsPerSymbol;
|
||||
uint8_t Mask = 1;
|
||||
Mask <<= Bit;
|
||||
OutputBlock[TimeBit] |= Mask;
|
||||
/* Set this bit */
|
||||
tones[symbol] |= (1 << bit_index);
|
||||
}
|
||||
Rotate += 1;
|
||||
if (Rotate >= BitsPerSymbol)
|
||||
Rotate -= BitsPerSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This function encodes a single block of Olivia MFSK
|
||||
*
|
||||
* It takes a buffer of ASCII-encoded text and returns an array of
|
||||
* tones to transmit.
|
||||
*/
|
||||
void olivia_mfsk_encode_block(char* buffer, uint8_t* tones)
|
||||
void olivia_mfsk_encode_block(char* block, int8_t* tones)
|
||||
{
|
||||
size_t bits_per_character = 7;
|
||||
|
||||
size_t bits_per_symbol = 5; /* That is, there are 2^5=32 tones */
|
||||
size_t symbols_per_block = 64;
|
||||
|
||||
/* For the moment do this */
|
||||
EncodeBlock((uint8_t*)buffer);
|
||||
memcpy(tones, OutputBlock, symbols_per_block);
|
||||
mfsk_encode_block(block, tones, 64, bits_per_symbol, scrambler_olivia, 13);
|
||||
}
|
||||
/**
|
||||
* This function encodes a single block of Contestia MFSK
|
||||
*
|
||||
* It takes a buffer of ASCII-encoded text and returns an array of
|
||||
* tones to transmit.
|
||||
*/
|
||||
void contestia_mfsk_encode_block(char* block, int8_t* tones)
|
||||
{
|
||||
size_t bits_per_symbol = 5; /* That is, there are 2^5=32 tones */
|
||||
|
||||
for (uint8_t c_index; c_index < bits_per_symbol; c_index++) {
|
||||
char character = block[c_index];
|
||||
|
||||
/* lowercase => UPPERCASE */
|
||||
if (character >= 'a' && character <= 'z') {
|
||||
character += 'A' - 'a';
|
||||
}
|
||||
|
||||
/* Convert to contestia character set */
|
||||
if (character >= '!' && character <= 'Z') { /* Printables... */
|
||||
character -= 32;
|
||||
} else if (character == ' ') { /* Space */
|
||||
character = 59;
|
||||
} else if (character == '\r') { /* Carriage Return */
|
||||
character = 60;
|
||||
} else if (character == '\n') { /* Line Feed */
|
||||
character = 0;
|
||||
} else if (character == 8) { /* Backspace */
|
||||
character = 61;
|
||||
} else if (character == 0) { /* Null */
|
||||
character = 0;
|
||||
} else { /* ???????????? */
|
||||
character = '?' - 32;
|
||||
}
|
||||
|
||||
block[c_index] = character;
|
||||
}
|
||||
|
||||
|
||||
mfsk_encode_block(block, tones, 32, bits_per_symbol, scrambler_contestia, 5);
|
||||
}
|
||||
|
||||
|
||||
#ifdef OLIVIA_MFSK_ENCODE_TEST
|
||||
void main(void)
|
||||
|
|
|
@ -162,6 +162,20 @@ static void si_trx_set_gpio_configuration(si_gpio_t gpio0, si_gpio_t gpio1,
|
|||
|
||||
_si_trx_transfer(8, 0, buffer);
|
||||
}
|
||||
/**
|
||||
* Starts transmitting
|
||||
*/
|
||||
static void si_trx_start_tx(uint8_t channel)
|
||||
{
|
||||
uint8_t buffer[5];
|
||||
buffer[0] = SI_CMD_START_TX;
|
||||
buffer[1] = channel;
|
||||
buffer[2] = (1 << 4);
|
||||
buffer[3] = 0;
|
||||
buffer[4] = 0;
|
||||
|
||||
_si_trx_transfer(5, 0, buffer);
|
||||
}
|
||||
/**
|
||||
* Gets readings from the auxillary ADC
|
||||
*/
|
||||
|
@ -271,7 +285,7 @@ static void si_trx_set_tx_pa_duty_cycle(uint8_t pa_duty_cycle)
|
|||
/**
|
||||
* Set the synthesiser to the given frequency
|
||||
*/
|
||||
static void si_trx_set_frequency(uint32_t frequency)
|
||||
static void si_trx_set_frequency(uint32_t frequency, float channel_spacing)
|
||||
{
|
||||
uint8_t outdiv, band;
|
||||
|
||||
|
@ -300,25 +314,34 @@ static void si_trx_set_frequency(uint32_t frequency)
|
|||
|
||||
uint32_t m = (uint32_t)(rest * (float)(1 << 19));
|
||||
|
||||
/* 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 */
|
||||
si_trx_frequency_control_set_band(band);
|
||||
|
||||
/* 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 frequency deviation in the modem */
|
||||
si_trx_modem_set_deviation(dev);
|
||||
|
||||
|
||||
//const uint8_t set_frequency_control_inte[] = {0x11, 0x40, 0x08, 0x00, n, m2, m1, m0, 0x0B, 0x61, 0x20, 0xFA};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the transceiver
|
||||
*/
|
||||
void si_trx_reset(void)
|
||||
void si_trx_reset(uint8_t modulation_type, float channel_spacing)
|
||||
{
|
||||
_si_trx_sdn_enable(); /* active high shutdown = reset */
|
||||
|
||||
|
@ -345,14 +368,14 @@ void si_trx_reset(void)
|
|||
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);
|
||||
si_trx_set_frequency(RADIO_FREQUENCY, channel_spacing);
|
||||
si_trx_set_tx_power(RADIO_POWER);
|
||||
|
||||
/* RTTY from GPIO1 */
|
||||
si_trx_modem_set_modulation(SI_MODEM_MOD_DIRECT_MODE_ASYNC,
|
||||
SI_MODEM_MOD_GPIO_1,
|
||||
SI_MODEM_MOD_SOURCE_DIRECT,
|
||||
SI_MODEM_MOD_TYPE_2FSK);
|
||||
modulation_type);
|
||||
|
||||
si_trx_state_tx_tune();
|
||||
}
|
||||
|
@ -360,10 +383,10 @@ void si_trx_reset(void)
|
|||
/**
|
||||
* Enables the radio and starts transmitting
|
||||
*/
|
||||
void si_trx_on(void)
|
||||
void si_trx_on(uint8_t modulation_type, float channel_spacing)
|
||||
{
|
||||
si_trx_reset();
|
||||
si_trx_state_tx();
|
||||
si_trx_reset(modulation_type, channel_spacing);
|
||||
si_trx_start_tx(1);
|
||||
}
|
||||
/**
|
||||
* Disables the radio and places it in shutdown
|
||||
|
@ -373,6 +396,14 @@ void si_trx_off(void)
|
|||
si_trx_state_ready();
|
||||
_si_trx_sdn_enable();
|
||||
}
|
||||
/**
|
||||
* Switches the transmittion to the specified channel
|
||||
*/
|
||||
void si_trx_switch_channel(uint8_t channel)
|
||||
{
|
||||
si_trx_state_ready();
|
||||
si_trx_start_tx(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the radio interface to the radio
|
||||
|
|
|
@ -75,11 +75,11 @@ uint16_t crc_checksum(char *string)
|
|||
/**
|
||||
* Initialises a timer interupt at the given frequency
|
||||
*/
|
||||
void timer0_tick_init(uint32_t frequency)
|
||||
void timer0_tick_init(float frequency)
|
||||
{
|
||||
/* Calculate the wrap value for the given frequency */
|
||||
uint32_t gclk0_frequency = system_gclk_chan_get_hz(0);
|
||||
uint32_t count = gclk0_frequency / frequency;
|
||||
float gclk0_frequency = (float)system_gclk_chan_get_hz(0);
|
||||
uint32_t count = (uint32_t)(gclk0_frequency / frequency);
|
||||
|
||||
/* Configure Timer 0 */
|
||||
bool t0_capture_channel_enables[] = {false, false};
|
||||
|
|
Ładowanie…
Reference in New Issue