[New Feature] Contestia Packet output, re-organised telemetry module

geofence_dev
Richard Meadows 2015-02-27 10:55:05 +00:00
rodzic a117d76626
commit cbb004db7e
9 zmienionych plików z 353 dodań i 195 usunięć

Wyświetl plik

@ -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 */

Wyświetl plik

@ -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 */

Wyświetl plik

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

Wyświetl plik

@ -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 */

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -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 */

Wyświetl plik

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

Wyświetl plik

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