kopia lustrzana https://github.com/bristol-seds/pico-tracker
[New Feature] Contestia Packet output, re-organised telemetry module
rodzic
a117d76626
commit
cbb004db7e
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Outputs contestia to the si_trx
|
||||
* Copyright (C) 2015 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 CONTESTIA_H
|
||||
#define CONTESTIA_H
|
||||
|
||||
/**
|
||||
* Contestia 32/1000
|
||||
*/
|
||||
#define CONTESTIA_NUMBER_OF_TONES 32
|
||||
#define CONTESTIA_CHARACTERS_PER_BLOCK 5
|
||||
|
||||
|
||||
void contestia_start(char* data);
|
||||
uint8_t contestia_tick(void);
|
||||
|
||||
#endif /* CONTESTIA_H */
|
|
@ -25,21 +25,7 @@
|
|||
#ifndef RTTY_H
|
||||
#define RTTY_H
|
||||
|
||||
#include "util/dbuffer.h"
|
||||
|
||||
/**
|
||||
* Output String
|
||||
*/
|
||||
#define RTTY_STRING_MAX 0x200
|
||||
/**
|
||||
* It's actually a double buffer which we swap for mid-string updates
|
||||
*/
|
||||
ARRAY_DBUFFER_T(char, RTTY_STRING_MAX) rtty_dbuffer_string;
|
||||
|
||||
int rtty_active(void);
|
||||
int rtty_start(void);
|
||||
int32_t rtty_get_index(void);
|
||||
void rtty_set_length(int32_t length);
|
||||
void rtty_tick(void);
|
||||
void rtty_start(uint8_t data);
|
||||
uint8_t rtty_tick(void);
|
||||
|
||||
#endif /* RTTY_H */
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef SI_TRX_H
|
||||
#define SI_TRX_H
|
||||
|
||||
#include "samd20.h"
|
||||
|
||||
float si_trx_get_temperature(void);
|
||||
|
||||
void si_trx_on(uint8_t modulation_type, float channel_spacing);
|
||||
|
|
|
@ -26,6 +26,29 @@
|
|||
#define TELEMETRY_H
|
||||
|
||||
uint16_t crc_checksum(char *string);
|
||||
|
||||
#include "util/dbuffer.h"
|
||||
|
||||
enum telemetry_t {
|
||||
TELEMETRY_RTTY,
|
||||
TELEMETRY_CONTESTIA
|
||||
};
|
||||
|
||||
/**
|
||||
* Output String
|
||||
*/
|
||||
#define TELEMETRY_STRING_MAX 0x1F0
|
||||
#define TELEMETRY_LARGEST_BLOCK 0x10
|
||||
/**
|
||||
* It's actually a double buffer which we swap for mid-string updates
|
||||
*/
|
||||
ARRAY_DBUFFER_T(char, TELEMETRY_STRING_MAX+TELEMETRY_LARGEST_BLOCK) telemetry_dbuffer_string;
|
||||
|
||||
int telemetry_active(void);
|
||||
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);
|
||||
|
||||
#endif /* TELEMETRY_H */
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Outputs contestia to the si_trx
|
||||
* Copyright (C) 2015 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 "si_trx.h"
|
||||
#include "contestia.h"
|
||||
|
||||
|
||||
/**
|
||||
* Current output tones
|
||||
*/
|
||||
int8_t contestia_tones[CONTESTIA_NUMBER_OF_TONES];
|
||||
/**
|
||||
* Where we are in the current output tones
|
||||
*/
|
||||
uint32_t contestia_tone_index = 0xFFFFFFFE;
|
||||
|
||||
/**
|
||||
* Starts the transmission of a contestia block
|
||||
*/
|
||||
void contestia_start(char* block) {
|
||||
/* Start transmission */
|
||||
contestia_mfsk_encode_block(block, contestia_tones);
|
||||
contestia_tone_index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the baud rate, outputs tones
|
||||
*/
|
||||
uint8_t contestia_tick(void) {
|
||||
|
||||
if (contestia_tone_index < CONTESTIA_NUMBER_OF_TONES) {
|
||||
uint8_t binary_code;
|
||||
uint8_t grey_code;
|
||||
|
||||
/* Output grey code */
|
||||
binary_code = contestia_tones[contestia_tone_index];
|
||||
grey_code = (binary_code >> 1) ^ binary_code;
|
||||
si_trx_switch_channel(grey_code);
|
||||
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
contestia_tone_index++;
|
||||
|
||||
if (contestia_tone_index < CONTESTIA_NUMBER_OF_TONES) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -43,7 +43,6 @@
|
|||
#include "si_trx_defs.h"
|
||||
#include "analogue.h"
|
||||
#include "spi_bitbang.h"
|
||||
#include "rtty.h"
|
||||
#include "system/interrupt.h"
|
||||
|
||||
#define CALLSIGN "UBSEDSx"
|
||||
|
@ -155,10 +154,14 @@ void output_telemetry_string(void)
|
|||
uint32_t altitude = 0;
|
||||
|
||||
/**
|
||||
* Callsign, Time
|
||||
* Analogue, Callsign, Time
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Analogue */
|
||||
float battery = get_battery();
|
||||
float temperature = si_trx_get_temperature(); // REENTRANCY!!!!!!
|
||||
|
||||
/* GPS Time */
|
||||
gps_update_time();
|
||||
|
||||
|
@ -166,7 +169,7 @@ void output_telemetry_string(void)
|
|||
while (gps_update_time_pending()) {
|
||||
system_sleep();
|
||||
}
|
||||
for (int i = 0; i < 100*1000; i++);
|
||||
// for (int i = 0; i < 100*1000; i++);
|
||||
|
||||
/* Time */
|
||||
struct ubx_nav_timeutc time = gps_get_nav_timeutc();
|
||||
|
@ -175,30 +178,31 @@ void output_telemetry_string(void)
|
|||
uint8_t seconds = time.payload.sec;
|
||||
|
||||
/* init double buffers */
|
||||
ARRAY_DBUFFER_INIT(&rtty_dbuffer_string);
|
||||
ARRAY_DBUFFER_INIT(&telemetry_dbuffer_string);
|
||||
|
||||
/* sprintf - initial string */
|
||||
uint16_t len = sprintf(ARRAY_DBUFFER_WRITE_PTR(&rtty_dbuffer_string),
|
||||
uint16_t len = sprintf(ARRAY_DBUFFER_WRITE_PTR(&telemetry_dbuffer_string),
|
||||
"$$%s,%02u:%02u:%02u,",
|
||||
CALLSIGN, hours, minutes, seconds);
|
||||
|
||||
/* swap buffers */
|
||||
ARRAY_DBUFFER_SWAP(&rtty_dbuffer_string);
|
||||
ARRAY_DBUFFER_SWAP(&telemetry_dbuffer_string);
|
||||
|
||||
/* start */
|
||||
rtty_start();
|
||||
/* start - SI NOW BELONGS TO TELEMETRY, WE CANNOT ACCESS */
|
||||
#ifdef RTTY
|
||||
telemetry_start(TELEMETRY_RTTY);
|
||||
#endif
|
||||
#ifdef CONTESTIA
|
||||
telemetry_start(TELEMETRY_CONTESTIA);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Position, Status, Analogue, Checksum
|
||||
* Position, Status, Checksum
|
||||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Analogue */
|
||||
float battery = get_battery();
|
||||
float temperature = si_trx_get_temperature();
|
||||
|
||||
/* Sleep Wait */
|
||||
while (rtty_get_index() < (len - 4)) {
|
||||
while (telemetry_get_index() < (len - 9)) {
|
||||
system_sleep();
|
||||
}
|
||||
|
||||
|
@ -211,7 +215,7 @@ void output_telemetry_string(void)
|
|||
}
|
||||
|
||||
/* Wait for the gps update. Move on if it's urgent */
|
||||
while (gps_update_position_pending() && rtty_get_index() < (len - 1)) {
|
||||
while (gps_update_position_pending() && telemetry_get_index() < (len - 6)) {
|
||||
system_sleep();
|
||||
}
|
||||
|
||||
|
@ -235,18 +239,18 @@ void output_telemetry_string(void)
|
|||
}
|
||||
|
||||
/* sprintf - full string */
|
||||
len = sprintf(ARRAY_DBUFFER_WRITE_PTR(&rtty_dbuffer_string),
|
||||
len = sprintf(ARRAY_DBUFFER_WRITE_PTR(&telemetry_dbuffer_string),
|
||||
"$$%s,%02u:%02u:%02u,%02.6f,%03.6f,%ld,%u,%.2f,%.1f",
|
||||
CALLSIGN, hours, minutes, seconds, lat_fmt, lon_fmt,
|
||||
altitude, satillite_count, battery, temperature);
|
||||
|
||||
/* sprintf - checksum */
|
||||
len += sprintf(ARRAY_DBUFFER_WRITE_PTR(&rtty_dbuffer_string) + len,
|
||||
"*%04X\n",
|
||||
crc_checksum(ARRAY_DBUFFER_WRITE_PTR(&rtty_dbuffer_string)));
|
||||
len += sprintf(ARRAY_DBUFFER_WRITE_PTR(&telemetry_dbuffer_string) + len,
|
||||
"*%04X\r",
|
||||
crc_checksum(ARRAY_DBUFFER_WRITE_PTR(&telemetry_dbuffer_string)));
|
||||
|
||||
/* swap buffers */
|
||||
ARRAY_DBUFFER_SWAP(&rtty_dbuffer_string);
|
||||
ARRAY_DBUFFER_SWAP(&telemetry_dbuffer_string);
|
||||
|
||||
/**
|
||||
* End
|
||||
|
@ -254,27 +258,14 @@ void output_telemetry_string(void)
|
|||
*/
|
||||
|
||||
/* Set the final length */
|
||||
rtty_set_length(len);
|
||||
telemetry_set_length(len);
|
||||
|
||||
/* Sleep Wait */
|
||||
while (rtty_active()) {
|
||||
while (telemetry_active()) {
|
||||
system_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
* =============================================================================
|
||||
|
@ -324,27 +315,6 @@ int main(void)
|
|||
/* Initialise Si4060 interface */
|
||||
si_trx_init();
|
||||
|
||||
/* Start transmitting */
|
||||
#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;
|
||||
|
||||
|
||||
/* Timer 0 clocks out data */
|
||||
#ifdef RTTY
|
||||
|
@ -364,47 +334,3 @@ int main(void)
|
|||
output_telemetry_string();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t tone_index = 0;
|
||||
uint8_t binary_code;
|
||||
uint8_t grey_code;
|
||||
|
||||
/**
|
||||
* Called at the symbol rate
|
||||
*/
|
||||
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);
|
||||
|
||||
} else if (tone_index < 64) {
|
||||
|
||||
si_trx_state_ready();
|
||||
|
||||
/* } else if (tone_index < 96) { */
|
||||
|
||||
/* si_trx_switch_channel((tone_index & 1) ? 0 : 31); */
|
||||
|
||||
}
|
||||
|
||||
tone_index++;
|
||||
if (tone_index >= 64)
|
||||
{
|
||||
tone_index = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ 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++) {
|
||||
for (uint8_t c_index = 0; c_index < bits_per_symbol; c_index++) {
|
||||
char character = block[c_index];
|
||||
|
||||
/* lowercase => UPPERCASE */
|
||||
|
|
|
@ -43,6 +43,10 @@
|
|||
#define ASCII_BITS 8
|
||||
#define BITS_PER_CHAR 11
|
||||
|
||||
/**
|
||||
* Current output data
|
||||
*/
|
||||
uint8_t rtty_data;
|
||||
/**
|
||||
* Where we currently are in the rtty output byte
|
||||
*
|
||||
|
@ -51,90 +55,49 @@
|
|||
* 10 = Stop Bit
|
||||
* 11 = Stop Bit
|
||||
*/
|
||||
uint8_t rtty_phase;
|
||||
/**
|
||||
* Where we are in the current output string
|
||||
*/
|
||||
int32_t rtty_index;
|
||||
uint8_t rtty_phase = 0xFE;
|
||||
|
||||
/**
|
||||
* Details of the string that is currently being output
|
||||
*/
|
||||
int32_t rtty_string_length = 0;
|
||||
|
||||
/**
|
||||
* Returns 1 if we're currently outputting.
|
||||
*/
|
||||
int rtty_active(void) {
|
||||
return (rtty_string_length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts RTTY output
|
||||
*
|
||||
* Returns 0 on success, 1 if already active
|
||||
*/
|
||||
int rtty_start(void) {
|
||||
if (!rtty_active()) {
|
||||
|
||||
/* Initialise */
|
||||
rtty_string_length = RTTY_STRING_MAX;
|
||||
rtty_index = 0;
|
||||
rtty_phase = 0;
|
||||
|
||||
return 0; /* Success */
|
||||
} else {
|
||||
return 1; /* Already active */
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the index of the current byte being outputted from the buffer
|
||||
*/
|
||||
int32_t rtty_get_index(void) {
|
||||
return rtty_index;
|
||||
}
|
||||
/**
|
||||
* Sets the final length of the RTTY string
|
||||
*/
|
||||
void rtty_set_length(int32_t length) {
|
||||
if (length <= RTTY_STRING_MAX) {
|
||||
rtty_string_length = length;
|
||||
}
|
||||
void rtty_start(uint8_t data) {
|
||||
/* Start transmission */
|
||||
rtty_phase = 0;
|
||||
rtty_data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the baud rate, outputs bits of rtty
|
||||
*/
|
||||
void rtty_tick(void) {
|
||||
if (rtty_active()) {
|
||||
RTTY_ACTIVATE();
|
||||
uint8_t rtty_tick(void) {
|
||||
|
||||
if (rtty_phase == 0) { // Start
|
||||
// Low
|
||||
RTTY_SET(0);
|
||||
} else if (rtty_phase < ASCII_BITS + 1) {
|
||||
// Data
|
||||
if ((ARRAY_DBUFFER_READ_PTR(&rtty_dbuffer_string)[rtty_index] >> (rtty_phase - 1)) & 1) {
|
||||
RTTY_SET(1);
|
||||
} else {
|
||||
RTTY_SET(0);
|
||||
}
|
||||
} else if (rtty_phase < BITS_PER_CHAR) { // Stop
|
||||
// High
|
||||
if (rtty_phase == 0) { /* *** Start *** */
|
||||
RTTY_SET(0);
|
||||
|
||||
} else if (rtty_phase < ASCII_BITS + 1) { /* *** Data *** */
|
||||
if ((rtty_data >> (rtty_phase - 1)) & 1) {
|
||||
RTTY_SET(1);
|
||||
} else {
|
||||
RTTY_SET(0);
|
||||
}
|
||||
|
||||
rtty_phase++;
|
||||
} else if (rtty_phase < BITS_PER_CHAR) { /* *** Stop *** */
|
||||
RTTY_SET(1);
|
||||
|
||||
if (rtty_phase >= BITS_PER_CHAR) { // Next character
|
||||
rtty_phase = 0; rtty_index++; RTTY_NEXT();
|
||||
|
||||
if (rtty_index >= rtty_string_length) { // All done, deactivate
|
||||
rtty_string_length = 0; // Deactivate
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RTTY_DEACTIVATE();
|
||||
} else { /* *** Not running *** */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
rtty_phase++;
|
||||
|
||||
if (rtty_phase < BITS_PER_CHAR) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if (rtty_phase >= BITS_PER_CHAR) { // Next character */
|
||||
/* rtty_phase = 0; rtty_index++; RTTY_NEXT(); */
|
||||
|
||||
/* if (rtty_index >= rtty_string_length) { // All done, deactivate */
|
||||
/* rtty_string_length = 0; // Deactivate */
|
||||
/* } */
|
||||
/* } */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,12 +26,21 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "samd20.h"
|
||||
#include "telemetry.h"
|
||||
#include "rtty.h"
|
||||
#include "contestia.h"
|
||||
#include "si_trx.h"
|
||||
#include "si_trx_defs.h"
|
||||
#include "system/gclk.h"
|
||||
#include "system/interrupt.h"
|
||||
#include "system/pinmux.h"
|
||||
#include "tc/tc_driver.h"
|
||||
#include "hw_config.h"
|
||||
|
||||
/**
|
||||
* CYCLIC REDUNDANCY CHECK (CRC)
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* CRC Function for the XMODEM protocol.
|
||||
|
@ -75,12 +84,143 @@ uint16_t crc_checksum(char *string)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* TELEMETRY OUTPUT
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* The type of telemetry we're currently outputting
|
||||
*/
|
||||
enum telemetry_t telemetry_type;
|
||||
/**
|
||||
* Current output
|
||||
*/
|
||||
int32_t telemetry_string_length = 0;
|
||||
/**
|
||||
* Where we are in the current output
|
||||
*/
|
||||
int32_t telemetry_index;
|
||||
/**
|
||||
* Is the radio currently on?
|
||||
*/
|
||||
uint8_t radio_on = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Returns 1 if we're currently outputting.
|
||||
*/
|
||||
int telemetry_active(void) {
|
||||
return (telemetry_string_length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts telemetry output
|
||||
*
|
||||
* Returns 0 on success, 1 if already active
|
||||
*/
|
||||
int telemetry_start(enum telemetry_t type) {
|
||||
if (!telemetry_active()) {
|
||||
|
||||
/* Initialise */
|
||||
telemetry_type = type;
|
||||
telemetry_index = 0;
|
||||
|
||||
/* Initialise first block / character */
|
||||
|
||||
|
||||
|
||||
telemetry_string_length = TELEMETRY_STRING_MAX;
|
||||
|
||||
|
||||
return 0; /* Success */
|
||||
} else {
|
||||
return 1; /* Already active */
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the index of the current byte being outputted from the buffer
|
||||
*/
|
||||
int32_t telemetry_get_index(void) {
|
||||
return telemetry_index;
|
||||
}
|
||||
/**
|
||||
* Sets the final length of the TELEMETRY string
|
||||
*/
|
||||
void telemetry_set_length(int32_t length) {
|
||||
if (length <= TELEMETRY_STRING_MAX) {
|
||||
telemetry_string_length = length;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t is_telemetry_finished(void) {
|
||||
if (telemetry_index > telemetry_string_length) {
|
||||
/* All done, deactivate */
|
||||
telemetry_string_length = 0;
|
||||
|
||||
/* Turn radio off */
|
||||
si_trx_off(); radio_on = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called at the telemetry mode's baud rate
|
||||
*/
|
||||
void telemetry_tick(void) {
|
||||
if (telemetry_active()) {
|
||||
switch (telemetry_type) {
|
||||
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);
|
||||
radio_on = 1;
|
||||
}
|
||||
|
||||
if (!contestia_tick()) {
|
||||
/* Transmission Finished */
|
||||
if (is_telemetry_finished()) return;
|
||||
|
||||
/* Let's start again */
|
||||
char* block = &ARRAY_DBUFFER_READ_PTR(&telemetry_dbuffer_string)[telemetry_index];
|
||||
telemetry_index += CONTESTIA_CHARACTERS_PER_BLOCK;
|
||||
|
||||
contestia_start(block);
|
||||
}
|
||||
|
||||
break;
|
||||
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);
|
||||
radio_on = 1;
|
||||
}
|
||||
|
||||
if (!rtty_tick()) {
|
||||
/* Transmission Finished */
|
||||
if (is_telemetry_finished()) return;
|
||||
|
||||
/* Let's start again */
|
||||
uint8_t data = ARRAY_DBUFFER_READ_PTR(&telemetry_dbuffer_string)[telemetry_index];
|
||||
telemetry_index++;
|
||||
|
||||
rtty_start(data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CLOCKING
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
void si_gclk_setup(void)
|
||||
{
|
||||
|
@ -99,10 +239,6 @@ void si_gclk_setup(void)
|
|||
system_gclk_gen_enable(SI406X_TCXO_GCLK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialises a timer interupt at the given frequency
|
||||
*/
|
||||
|
@ -149,3 +285,15 @@ void timer0_tick_init(float frequency)
|
|||
tc_enable(TC0);
|
||||
tc_start_counter(TC0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the symbol rate
|
||||
*/
|
||||
void TC0_Handler(void)
|
||||
{
|
||||
if (tc_get_status(TC0) & TC_STATUS_CHANNEL_0_MATCH) {
|
||||
tc_clear_status(TC0, TC_STATUS_CHANNEL_0_MATCH);
|
||||
|
||||
telemetry_tick();
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue