kopia lustrzana https://github.com/DL7AD/pecanpico9
Reimplemented Base91
Changed message buffer implementation Removed error transmission Moved getFrequency implementation to radio.cDevelop
rodzic
60578aa5c4
commit
8a4d8ff5ef
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import serial,os,re,datetime
|
import serial,os,re,datetime
|
||||||
from subprocess import call
|
from subprocess import call
|
||||||
import base128
|
import base91
|
||||||
import binascii
|
import binascii
|
||||||
import urllib2
|
import urllib2
|
||||||
import io
|
import io
|
||||||
|
@ -88,7 +88,7 @@ def received_data(data):
|
||||||
m = re.search("(.*)\>APECAN(.*):\!(.*)", data)
|
m = re.search("(.*)\>APECAN(.*):\!(.*)", data)
|
||||||
try:
|
try:
|
||||||
call = m.group(1).split(' ')[-1] # transmitter callsign
|
call = m.group(1).split(' ')[-1] # transmitter callsign
|
||||||
data128 = m.group(3) # base128 encoded SSDV data (without SYNC, PacketType, Callsign, CRC, FEC)
|
data91 = m.group(3) # base91 encoded SSDV data (without SYNC, PacketType, Callsign, CRC, FEC)
|
||||||
if len(m.group(2)) > 0:
|
if len(m.group(2)) > 0:
|
||||||
receiver = m.group(2).split(',')[-1]
|
receiver = m.group(2).split(',')[-1]
|
||||||
else:
|
else:
|
||||||
|
@ -99,7 +99,7 @@ def received_data(data):
|
||||||
if args.log is not None:
|
if args.log is not None:
|
||||||
f.write(data) # Log data to file
|
f.write(data) # Log data to file
|
||||||
|
|
||||||
data = base128.decode(data128) # Decode Base128
|
data = base91.decode(data91) # Decode Base91
|
||||||
|
|
||||||
if len(data) != 214:
|
if len(data) != 214:
|
||||||
return # APRS message sampled too short
|
return # APRS message sampled too short
|
||||||
|
|
|
@ -143,8 +143,7 @@ CSRC = $(STARTUPSRC) \
|
||||||
radio.c \
|
radio.c \
|
||||||
sleep.c \
|
sleep.c \
|
||||||
threads/threads.c \
|
threads/threads.c \
|
||||||
math/base.c \
|
math/base91.c \
|
||||||
math/base128.c \
|
|
||||||
math/sgp4.c \
|
math/sgp4.c \
|
||||||
math/geofence.c \
|
math/geofence.c \
|
||||||
config.c \
|
config.c \
|
||||||
|
|
|
@ -32,10 +32,7 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ch.h"
|
#include "base91.h"
|
||||||
#include "hal.h"
|
|
||||||
#include "base.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
static char b64_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
static char b64_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||||
|
@ -84,9 +81,6 @@ void base64_encode(const uint8_t *in, uint8_t *out, uint16_t input_length) {
|
||||||
out[BASE64LEN(input_length)] = '\0';
|
out[BASE64LEN(input_length)] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void basE91_init(base91_t *b)
|
void basE91_init(base91_t *b)
|
||||||
{
|
{
|
||||||
b->queue = 0;
|
b->queue = 0;
|
||||||
|
@ -151,11 +145,3 @@ void base91_encode(const uint8_t *in, uint8_t *out, uint16_t input_length) {
|
||||||
ototal += basE91_encode_end(&handle, out + ototal);
|
ototal += basE91_encode_end(&handle, out + ototal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "base.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define METER_TO_FEET(m) (((m)*26876) / 8192)
|
#define METER_TO_FEET(m) (((m)*26876) / 8192)
|
||||||
|
|
|
@ -10,46 +10,47 @@
|
||||||
#include "padc.h"
|
#include "padc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// APRS related
|
||||||
#define PLAYBACK_RATE ((STM32_PCLK1) / 500) /* Samples per second (48Mhz / 250 = 192kHz) */
|
#define PLAYBACK_RATE ((STM32_PCLK1) / 500) /* Samples per second (48Mhz / 250 = 192kHz) */
|
||||||
#define BAUD_RATE 1200 /* APRS AFSK baudrate */
|
#define BAUD_RATE 1200 /* APRS AFSK baudrate */
|
||||||
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (192kHz / 1200baud = 160samp/baud) */
|
#define SAMPLES_PER_BAUD (PLAYBACK_RATE / BAUD_RATE) /* Samples per baud (192kHz / 1200baud = 160samp/baud) */
|
||||||
#define PHASE_DELTA_1200 (((2 * 1200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 1200Hz tone */
|
#define PHASE_DELTA_1200 (((2 * 1200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 1200Hz tone */
|
||||||
#define PHASE_DELTA_2200 (((2 * 2200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 2200Hz tone */
|
#define PHASE_DELTA_2200 (((2 * 2200) << 16) / PLAYBACK_RATE) /* Delta-phase per sample for 2200Hz tone */
|
||||||
|
|
||||||
mutex_t radio_mtx; // Radio mutex
|
|
||||||
bool radio_mtx_init = false;
|
|
||||||
|
|
||||||
mod_t active_mod = MOD_NOT_SET;
|
|
||||||
static uint32_t phase_delta; // 1200/2200 for standard AX.25
|
static uint32_t phase_delta; // 1200/2200 for standard AX.25
|
||||||
static uint32_t phase; // Fixed point 9.7 (2PI = TABLE_SIZE)
|
static uint32_t phase; // Fixed point 9.7 (2PI = TABLE_SIZE)
|
||||||
static uint32_t packet_pos; // Next bit to be sent out
|
static uint32_t packet_pos; // Next bit to be sent out
|
||||||
static uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
|
static uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
|
||||||
static uint8_t current_byte;
|
static uint8_t current_byte;
|
||||||
static radioMSG_t tim_msg;
|
|
||||||
|
|
||||||
|
// 2FSK related
|
||||||
static uint8_t txs; // Serial maschine state
|
static uint8_t txs; // Serial maschine state
|
||||||
static uint8_t txc; // Current byte
|
static uint8_t txc; // Current byte
|
||||||
static uint32_t txi; // Bitcounter of current byte
|
static uint32_t txi; // Bitcounter of current byte
|
||||||
static uint32_t txj; // Bytecounter
|
static uint32_t txj; // Bytecounter
|
||||||
|
|
||||||
|
// Radio related
|
||||||
|
static mutex_t radio_mtx; // Radio mutex
|
||||||
|
bool radio_mtx_init = false;
|
||||||
|
static mod_t active_mod = MOD_NOT_SET;
|
||||||
|
static radioMSG_t radio_msg;
|
||||||
|
static uint8_t radio_buffer[8192];
|
||||||
|
static uint32_t radio_freq;
|
||||||
|
|
||||||
static const char *getModulation(uint8_t key) {
|
static const char *getModulation(uint8_t key) {
|
||||||
const char *val[] = {"unknown", "OOK", "2FSK", "2GFSK", "AFSK"};
|
const char *val[] = {"unknown", "OOK", "2FSK", "2GFSK", "AFSK"};
|
||||||
return val[key];
|
return val[key];
|
||||||
};
|
};
|
||||||
|
|
||||||
void initAFSK(radioMSG_t *msg) {
|
static void initAFSK(void) {
|
||||||
(void)msg;
|
|
||||||
// Initialize radio
|
// Initialize radio
|
||||||
Si4464_Init();
|
Si4464_Init();
|
||||||
setModemAFSK();
|
setModemAFSK();
|
||||||
active_mod = MOD_AFSK;
|
active_mod = MOD_AFSK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendAFSK(radioMSG_t *msg) {
|
static void sendAFSK(void) {
|
||||||
(void)msg;
|
|
||||||
// Initialize variables for timer
|
// Initialize variables for timer
|
||||||
memcpy(&tim_msg, msg, sizeof(radioMSG_t));
|
|
||||||
|
|
||||||
phase_delta = PHASE_DELTA_1200;
|
phase_delta = PHASE_DELTA_1200;
|
||||||
phase = 0;
|
phase = 0;
|
||||||
packet_pos = 0;
|
packet_pos = 0;
|
||||||
|
@ -57,7 +58,7 @@ void sendAFSK(radioMSG_t *msg) {
|
||||||
current_byte = 0;
|
current_byte = 0;
|
||||||
|
|
||||||
// Tune
|
// Tune
|
||||||
radioTune(msg->freq, 0, msg->power, 0);
|
radioTune(radio_freq, 0, radio_msg.power, 0);
|
||||||
|
|
||||||
// Initialize timer
|
// Initialize timer
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;
|
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;
|
||||||
|
@ -76,34 +77,28 @@ void sendAFSK(radioMSG_t *msg) {
|
||||||
shutdownRadio();
|
shutdownRadio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init2GFSK(radioMSG_t *msg) {
|
static void init2GFSK(void) {
|
||||||
// Initialize radio
|
// Initialize radio
|
||||||
Si4464_Init();
|
Si4464_Init();
|
||||||
setModem2GFSK(msg->gfsk_conf);
|
setModem2GFSK(radio_msg.gfsk_conf);
|
||||||
active_mod = MOD_2GFSK;
|
active_mod = MOD_2GFSK;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_t *feeder_thd = NULL;
|
static thread_t *feeder_thd = NULL;
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: I'd suggest re-working the FIFO handler system.
|
|
||||||
* Will give it some thought.
|
|
||||||
* Meanwhile there are a few changes that are worth testing.
|
|
||||||
*/
|
|
||||||
static THD_WORKING_AREA(si_fifo_feeder_wa, 1024);
|
static THD_WORKING_AREA(si_fifo_feeder_wa, 1024);
|
||||||
THD_FUNCTION(si_fifo_feeder_thd, arg)
|
THD_FUNCTION(si_fifo_feeder_thd, arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
uint16_t c = 64;
|
uint16_t c = 64;
|
||||||
uint16_t all = (tim_msg.bin_len+7)/8;
|
uint16_t all = (radio_msg.bin_len+7)/8;
|
||||||
|
|
||||||
chRegSetThreadName("radio_tx_feeder");
|
chRegSetThreadName("radio_tx_feeder");
|
||||||
// Initial FIFO fill
|
// Initial FIFO fill
|
||||||
Si4464_writeFIFO(tim_msg.msg, c);
|
Si4464_writeFIFO(radio_msg.buffer, c);
|
||||||
|
|
||||||
// Start transmission
|
// Start transmission
|
||||||
radioTune(tim_msg.freq, 0, tim_msg.power, all);
|
radioTune(radio_freq, 0, radio_msg.power, all);
|
||||||
|
|
||||||
while(c < all) { // Do while bytes not written into FIFO completely
|
while(c < all) { // Do while bytes not written into FIFO completely
|
||||||
// Determine free memory in Si4464-FIFO
|
// Determine free memory in Si4464-FIFO
|
||||||
|
@ -112,7 +107,7 @@ THD_FUNCTION(si_fifo_feeder_thd, arg)
|
||||||
if((more = all-c) == 0) // Calculate remainder to send
|
if((more = all-c) == 0) // Calculate remainder to send
|
||||||
break; // End if nothing left
|
break; // End if nothing left
|
||||||
}
|
}
|
||||||
Si4464_writeFIFO(&tim_msg.msg[c], more); // Write into FIFO
|
Si4464_writeFIFO(&radio_msg.buffer[c], more); // Write into FIFO
|
||||||
c += more;
|
c += more;
|
||||||
chThdSleepMilliseconds(15); // That value is ok up to 38k4
|
chThdSleepMilliseconds(15); // That value is ok up to 38k4
|
||||||
}
|
}
|
||||||
|
@ -123,10 +118,7 @@ THD_FUNCTION(si_fifo_feeder_thd, arg)
|
||||||
chThdExit(MSG_OK);
|
chThdExit(MSG_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send2GFSK(radioMSG_t *msg) {
|
static void send2GFSK(void) {
|
||||||
// Copy data
|
|
||||||
memcpy(&tim_msg, msg, sizeof(radioMSG_t));
|
|
||||||
|
|
||||||
// Start/re-start FIFO feeder
|
// Start/re-start FIFO feeder
|
||||||
feeder_thd = chThdCreateStatic(si_fifo_feeder_wa, sizeof(si_fifo_feeder_wa), HIGHPRIO+1, si_fifo_feeder_thd, NULL);
|
feeder_thd = chThdCreateStatic(si_fifo_feeder_wa, sizeof(si_fifo_feeder_wa), HIGHPRIO+1, si_fifo_feeder_thd, NULL);
|
||||||
|
|
||||||
|
@ -144,7 +136,7 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
if(active_mod == MOD_AFSK) // AFSK
|
if(active_mod == MOD_AFSK) // AFSK
|
||||||
{
|
{
|
||||||
|
|
||||||
if(packet_pos == tim_msg.bin_len) { // Packet transmission finished
|
if(packet_pos == radio_msg.bin_len) { // Packet transmission finished
|
||||||
TIM7->CR1 &= ~STM32_TIM_CR1_CEN; // Disable timer
|
TIM7->CR1 &= ~STM32_TIM_CR1_CEN; // Disable timer
|
||||||
TIM7->SR &= ~STM32_TIM_SR_UIF; // Reset interrupt flag
|
TIM7->SR &= ~STM32_TIM_SR_UIF; // Reset interrupt flag
|
||||||
return;
|
return;
|
||||||
|
@ -152,7 +144,7 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
|
|
||||||
if(current_sample_in_baud == 0) {
|
if(current_sample_in_baud == 0) {
|
||||||
if((packet_pos & 7) == 0) { // Load up next byte
|
if((packet_pos & 7) == 0) { // Load up next byte
|
||||||
current_byte = tim_msg.msg[packet_pos >> 3];
|
current_byte = radio_msg.buffer[packet_pos >> 3];
|
||||||
} else { // Load up next bit
|
} else { // Load up next bit
|
||||||
current_byte = current_byte / 2;
|
current_byte = current_byte / 2;
|
||||||
}
|
}
|
||||||
|
@ -177,15 +169,15 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
{
|
{
|
||||||
case 6: // TX-delay
|
case 6: // TX-delay
|
||||||
txj++;
|
txj++;
|
||||||
if(txj > (uint32_t)(tim_msg.fsk_conf->predelay * tim_msg.fsk_conf->baud / 1000)) {
|
if(txj > (uint32_t)(radio_msg.fsk_conf->predelay * radio_msg.fsk_conf->baud / 1000)) {
|
||||||
txj = 0;
|
txj = 0;
|
||||||
txs = 7;
|
txs = 7;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7: // Transmit a single char
|
case 7: // Transmit a single char
|
||||||
if(txj < tim_msg.bin_len/8) {
|
if(txj < radio_msg.bin_len/8) {
|
||||||
txc = tim_msg.msg[txj]; // Select char
|
txc = radio_msg.buffer[txj]; // Select char
|
||||||
txj++;
|
txj++;
|
||||||
RADIO_WRITE_GPIO(LOW); // Start Bit (Synchronizing)
|
RADIO_WRITE_GPIO(LOW); // Start Bit (Synchronizing)
|
||||||
txi = 0;
|
txi = 0;
|
||||||
|
@ -199,7 +191,7 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
if(txi < tim_msg.fsk_conf->bits) {
|
if(txi < radio_msg.fsk_conf->bits) {
|
||||||
txi++;
|
txi++;
|
||||||
RADIO_WRITE_GPIO(txc & 1);
|
RADIO_WRITE_GPIO(txc & 1);
|
||||||
txc = txc >> 1;
|
txc = txc >> 1;
|
||||||
|
@ -211,7 +203,7 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
if(tim_msg.fsk_conf->stopbits == 2)
|
if(radio_msg.fsk_conf->stopbits == 2)
|
||||||
RADIO_WRITE_GPIO(HIGH); // Stop Bit
|
RADIO_WRITE_GPIO(HIGH); // Stop Bit
|
||||||
txs = 7;
|
txs = 7;
|
||||||
}
|
}
|
||||||
|
@ -223,8 +215,7 @@ CH_FAST_IRQ_HANDLER(STM32_TIM7_HANDLER)
|
||||||
TIM7->SR &= ~STM32_TIM_SR_UIF; // Reset interrupt flag
|
TIM7->SR &= ~STM32_TIM_SR_UIF; // Reset interrupt flag
|
||||||
}
|
}
|
||||||
|
|
||||||
void initOOK(radioMSG_t *msg) {
|
static void initOOK(void) {
|
||||||
(void)msg;
|
|
||||||
// Initialize radio
|
// Initialize radio
|
||||||
Si4464_Init();
|
Si4464_Init();
|
||||||
setModemOOK();
|
setModemOOK();
|
||||||
|
@ -234,45 +225,41 @@ void initOOK(radioMSG_t *msg) {
|
||||||
/**
|
/**
|
||||||
* Transmits binary OOK message. One bit = 20ms (1: TONE, 0: NO TONE)
|
* Transmits binary OOK message. One bit = 20ms (1: TONE, 0: NO TONE)
|
||||||
*/
|
*/
|
||||||
void sendOOK(radioMSG_t *msg) {
|
static void sendOOK(void) {
|
||||||
// Tune
|
// Tune
|
||||||
radioTune(msg->freq, 0, msg->power, 0);
|
radioTune(radio_freq, 0, radio_msg.power, 0);
|
||||||
|
|
||||||
// Transmit data
|
// Transmit data
|
||||||
uint32_t bit = 0;
|
uint32_t bit = 0;
|
||||||
systime_t time = chVTGetSystemTimeX();
|
systime_t time = chVTGetSystemTimeX();
|
||||||
while(bit < msg->bin_len) {
|
while(bit < radio_msg.bin_len) {
|
||||||
RADIO_WRITE_GPIO((msg->msg[bit/8] >> (bit%8)) & 0x1);
|
RADIO_WRITE_GPIO((radio_msg.buffer[bit/8] >> (bit%8)) & 0x1);
|
||||||
bit++;
|
bit++;
|
||||||
|
|
||||||
time = chThdSleepUntilWindowed(time, time + MS2ST(1200 / msg->ook_conf->speed));
|
time = chThdSleepUntilWindowed(time, time + MS2ST(1200 / radio_msg.ook_conf->speed));
|
||||||
}
|
}
|
||||||
shutdownRadio();
|
shutdownRadio();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init2FSK(radioMSG_t *msg) {
|
static void init2FSK(void) {
|
||||||
(void)msg;
|
|
||||||
// Initialize radio and tune
|
// Initialize radio and tune
|
||||||
Si4464_Init();
|
Si4464_Init();
|
||||||
setModem2FSK();
|
setModem2FSK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void send2FSK(radioMSG_t *msg) {
|
static void send2FSK(void) {
|
||||||
// Initialize variables for timer
|
|
||||||
memcpy(&tim_msg, msg, sizeof(radioMSG_t));
|
|
||||||
|
|
||||||
txs = 6;
|
txs = 6;
|
||||||
txc = 0;
|
txc = 0;
|
||||||
txi = 0;
|
txi = 0;
|
||||||
txj = 0;
|
txj = 0;
|
||||||
|
|
||||||
// Tune
|
// Tune
|
||||||
radioTune(msg->freq, msg->fsk_conf->shift, msg->power, 0);
|
radioTune(radio_freq, radio_msg.fsk_conf->shift, radio_msg.power, 0);
|
||||||
|
|
||||||
// Initialize timer
|
// Initialize timer
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;
|
RCC->APB1ENR |= RCC_APB1ENR_TIM7EN;
|
||||||
nvicEnableVector(TIM7_IRQn, 1);
|
nvicEnableVector(TIM7_IRQn, 1);
|
||||||
TIM7->ARR = STM32_PCLK1 / 16 / msg->fsk_conf->baud; // FIXME: 5625000 should be actually STM32_PCLK1
|
TIM7->ARR = STM32_PCLK1 / 16 / radio_msg.fsk_conf->baud;
|
||||||
TIM7->PSC = 15;
|
TIM7->PSC = 15;
|
||||||
TIM7->CR1 &= ~STM32_TIM_CR1_ARPE;
|
TIM7->CR1 &= ~STM32_TIM_CR1_ARPE;
|
||||||
TIM7->DIER |= STM32_TIM_DIER_UIE;
|
TIM7->DIER |= STM32_TIM_DIER_UIE;
|
||||||
|
@ -355,14 +342,21 @@ uint32_t getAPRSRegionFrequency(void) {
|
||||||
bool transmitOnRadio(radioMSG_t *msg, bool shutdown)
|
bool transmitOnRadio(radioMSG_t *msg, bool shutdown)
|
||||||
{
|
{
|
||||||
(void)shutdown;
|
(void)shutdown;
|
||||||
if(inRadioBand(msg->freq)) // Frequency in radio radio band
|
uint32_t freq = getFrequency(msg->freq); // Get transmission frequency
|
||||||
|
if(inRadioBand(freq)) // Frequency in radio radio band
|
||||||
{
|
{
|
||||||
if(inRadioBand(msg->freq)) // Frequency in radio radio band
|
if(msg->bin_len > 0) // Message length is not zero
|
||||||
{
|
{
|
||||||
lockRadio(); // Lock radio
|
lockRadio(); // Lock radio
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
memcpy(&radio_msg, msg, sizeof(radioMSG_t));
|
||||||
|
memcpy(&radio_buffer, msg->buffer, msg->buffer_len);
|
||||||
|
radio_msg.buffer = radio_buffer;
|
||||||
|
radio_freq = freq;
|
||||||
|
|
||||||
TRACE_INFO( "RAD > Transmit %d.%03d MHz, Pwr %d, %s, %d bits",
|
TRACE_INFO( "RAD > Transmit %d.%03d MHz, Pwr %d, %s, %d bits",
|
||||||
msg->freq/1000000, (msg->freq%1000000)/1000, msg->power,
|
freq/1000000, (freq%1000000)/1000, msg->power,
|
||||||
getModulation(msg->mod), msg->bin_len
|
getModulation(msg->mod), msg->bin_len
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -370,39 +364,35 @@ bool transmitOnRadio(radioMSG_t *msg, bool shutdown)
|
||||||
{
|
{
|
||||||
case MOD_2FSK:
|
case MOD_2FSK:
|
||||||
if(active_mod != msg->mod)
|
if(active_mod != msg->mod)
|
||||||
init2FSK(msg);
|
init2FSK();
|
||||||
send2FSK(msg);
|
send2FSK();
|
||||||
break;
|
break;
|
||||||
case MOD_2GFSK:
|
case MOD_2GFSK:
|
||||||
if(active_mod != msg->mod)
|
if(active_mod != msg->mod)
|
||||||
init2GFSK(msg);
|
init2GFSK();
|
||||||
send2GFSK(msg);
|
send2GFSK();
|
||||||
break;
|
break;
|
||||||
case MOD_AFSK:
|
case MOD_AFSK:
|
||||||
if(active_mod != msg->mod)
|
if(active_mod != msg->mod)
|
||||||
initAFSK(msg);
|
initAFSK();
|
||||||
sendAFSK(msg);
|
sendAFSK();
|
||||||
break;
|
break;
|
||||||
case MOD_OOK:
|
case MOD_OOK:
|
||||||
if(active_mod != msg->mod)
|
if(active_mod != msg->mod)
|
||||||
initOOK(msg);
|
initOOK();
|
||||||
sendOOK(msg);
|
sendOOK();
|
||||||
break;
|
break;
|
||||||
case MOD_NOT_SET:
|
case MOD_NOT_SET:
|
||||||
TRACE_ERROR("RAD > Modulation not set");
|
TRACE_ERROR("RAD > Modulation not set");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* FIXME: send2GFSK will return as soon as the radio enter TX state.
|
|
||||||
* So the radio lock will be removed and then ssdv analysis can run.
|
|
||||||
* If ssdv analysis finishes before TX is done then tim.buf gets clobbered
|
|
||||||
*/
|
|
||||||
unlockRadio(); // Unlock radio
|
unlockRadio(); // Unlock radio
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
TRACE_ERROR("RAD > It is nonsense to transmit 0 bits, %d.%03d MHz, Pwr dBm, %s, %d bits",
|
TRACE_ERROR("RAD > It is nonsense to transmit 0 bits, %d.%03d MHz, Pwr dBm, %s, %d bits",
|
||||||
msg->freq/1000000, (msg->freq%1000000)/1000, msg->power, getModulation(msg->mod), msg->bin_len
|
freq/1000000, (freq%1000000)/1000, msg->power, getModulation(msg->mod), msg->bin_len
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -410,7 +400,7 @@ bool transmitOnRadio(radioMSG_t *msg, bool shutdown)
|
||||||
} else { // Frequency out of radio band
|
} else { // Frequency out of radio band
|
||||||
|
|
||||||
TRACE_ERROR("RAD > Radio cant transmit on this frequency, %d.%03d MHz, Pwr dBm, %s, %d bits",
|
TRACE_ERROR("RAD > Radio cant transmit on this frequency, %d.%03d MHz, Pwr dBm, %s, %d bits",
|
||||||
msg->freq/1000000, (msg->freq%1000000)/1000, msg->power, getModulation(msg->mod), msg->bin_len
|
freq/1000000, (freq%1000000)/1000, msg->power, getModulation(msg->mod), msg->bin_len
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
#define APRS_FREQ_ARGENTINA 144930000
|
#define APRS_FREQ_ARGENTINA 144930000
|
||||||
#define APRS_FREQ_BRAZIL 145575000
|
#define APRS_FREQ_BRAZIL 145575000
|
||||||
|
|
||||||
extern mutex_t radio_mtx;
|
|
||||||
|
|
||||||
bool transmitOnRadio(radioMSG_t *msg, bool shutdown);
|
bool transmitOnRadio(radioMSG_t *msg, bool shutdown);
|
||||||
void shutdownRadio(void);
|
void shutdownRadio(void);
|
||||||
uint32_t getFrequency(freq_conf_t *config);
|
uint32_t getFrequency(freq_conf_t *config);
|
||||||
|
|
|
@ -1,150 +0,0 @@
|
||||||
/**
|
|
||||||
* Error Logging module
|
|
||||||
* Packets send by this module contain tracking points and error logging.
|
|
||||||
* Transmitting tracking points is not implemented yet. Error encoding is
|
|
||||||
* already implemented and encoded as described:
|
|
||||||
*
|
|
||||||
* Error log encoding
|
|
||||||
* ========================================
|
|
||||||
* Offset Size
|
|
||||||
* 0 4 Absolute time in sec
|
|
||||||
* 4 4 Error packet 1
|
|
||||||
* 8 4 Error packet 2
|
|
||||||
* 12 4 Error packet 3
|
|
||||||
* n*4 4 Error packet n
|
|
||||||
*
|
|
||||||
* n is defined by ERRORLOG_SIZE in config.h. If less errors occured than the
|
|
||||||
* size of ERRORLOG_SIZE, the error log packet may be shorter.
|
|
||||||
*
|
|
||||||
* Error packet encoding
|
|
||||||
* ========================================
|
|
||||||
* Bit
|
|
||||||
* 16...31 Time difference to last error packet (if value == 65535, then time difference 65535sec or longer)
|
|
||||||
* 10...15 File ID (see File encoding table)
|
|
||||||
* 0...9 Line Number
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ch.h"
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "threads.h"
|
|
||||||
#include "base.h"
|
|
||||||
#include "aprs.h"
|
|
||||||
|
|
||||||
// File encoding table
|
|
||||||
const char* const fileIDs[] = {
|
|
||||||
"", // 0 (no error, used for time padding, if no error occured since 2^16-1 seconds)
|
|
||||||
"" // 1 (file not listed below)
|
|
||||||
"tracking.c", // 2
|
|
||||||
"position.c", // 3
|
|
||||||
"image.c", // 4
|
|
||||||
"log.c", // 5
|
|
||||||
"ssdv.c", // 6
|
|
||||||
"pi2c.c", // 7
|
|
||||||
"padc.c", // 8
|
|
||||||
"ptime.c", // 9
|
|
||||||
"max.c", // 10
|
|
||||||
"si4464.c", // 11
|
|
||||||
"bme280.c", // 12
|
|
||||||
"pac1720.c", // 13
|
|
||||||
"ov2640.c", // 14
|
|
||||||
"sd.c", // 15
|
|
||||||
"radio.c", // 16
|
|
||||||
"sleep.c", // 17
|
|
||||||
"main.c", // 18
|
|
||||||
"error.c" // 19
|
|
||||||
};
|
|
||||||
|
|
||||||
static error_t error_log[ERRORLOG_SIZE]; // Error log ring memory
|
|
||||||
static uint8_t error_id; // Incremental ID for ring memory
|
|
||||||
|
|
||||||
void log_error(char *file, uint16_t line)
|
|
||||||
{
|
|
||||||
if(error_id == ERRORLOG_SIZE)
|
|
||||||
return; // No memory left
|
|
||||||
|
|
||||||
// Find file ID
|
|
||||||
error_log[error_id].error = 1; // Assign default error file (if file not found)
|
|
||||||
for(uint8_t i=1; i<sizeof(fileIDs); i++)
|
|
||||||
if(!strcmp(fileIDs[i], file)) {
|
|
||||||
error_log[error_id].error = ((i+1) << 10);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
error_log[error_id].time = ST2S(chVTGetSystemTimeX());
|
|
||||||
error_log[error_id].error |= (line & 0x3FF);
|
|
||||||
|
|
||||||
error_id++; // Increment counter
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t pkt[ERRORLOG_SIZE+1];
|
|
||||||
static uint8_t pkt_base91[BASE91LEN(4*ERRORLOG_SIZE+4)];
|
|
||||||
|
|
||||||
THD_FUNCTION(moduleERROR, arg)
|
|
||||||
{
|
|
||||||
module_conf_t* config = (module_conf_t*)arg;
|
|
||||||
|
|
||||||
// Execute Initial delay
|
|
||||||
if(config->init_delay)
|
|
||||||
chThdSleepMilliseconds(config->init_delay);
|
|
||||||
|
|
||||||
// Print initialization message
|
|
||||||
TRACE_INFO("ERR > Startup module %s", config->name);
|
|
||||||
|
|
||||||
systime_t time = chVTGetSystemTimeX();
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
TRACE_INFO("ERR > Do module LOG cycle");
|
|
||||||
config->last_update = chVTGetSystemTimeX(); // Update Watchdog timer
|
|
||||||
|
|
||||||
if(!p_sleep(&config->sleep_config))
|
|
||||||
{
|
|
||||||
// Encode message
|
|
||||||
pkt[0] = ST2S(chVTGetSystemTimeX());
|
|
||||||
for(uint8_t i=0; i<error_id; i++)
|
|
||||||
{
|
|
||||||
if(i > 0) // Calculate time difference
|
|
||||||
{
|
|
||||||
uint32_t tdiff = error_log[i].time-error_log[i-1].time; // Time difference to last error
|
|
||||||
if(tdiff >= 0xFFFF) // Time overflow
|
|
||||||
pkt[i+1] = 0xFFFF << 16;
|
|
||||||
else
|
|
||||||
pkt[i+1] = tdiff << 16;
|
|
||||||
}
|
|
||||||
pkt[i+1] |= error_log[i].error;
|
|
||||||
}
|
|
||||||
uint8_t size = error_id;
|
|
||||||
error_id = 0;
|
|
||||||
|
|
||||||
radioMSG_t msg;
|
|
||||||
msg.freq = getFrequency(&config->frequency);
|
|
||||||
msg.power = config->power;
|
|
||||||
|
|
||||||
switch(config->protocol) {
|
|
||||||
case PROT_APRS_2GFSK:
|
|
||||||
case PROT_APRS_AFSK:
|
|
||||||
msg.mod = config->protocol == PROT_APRS_AFSK ? MOD_AFSK : MOD_2GFSK;
|
|
||||||
msg.afsk_config = &(config->afsk_config);
|
|
||||||
msg.gfsk_config = &(config->gfsk_config);
|
|
||||||
|
|
||||||
// Deleting buffer
|
|
||||||
for(uint8_t t=0; t<sizeof(pkt_base91); t++)
|
|
||||||
pkt_base91[t] = 0;
|
|
||||||
|
|
||||||
base91_encode((uint8_t*)pkt, pkt_base91, 4*size+4);
|
|
||||||
msg.bin_len = aprs_encode_experimental('E', msg.msg, msg.mod, &config->aprs_config, pkt_base91, strlen((char*)pkt_base91));
|
|
||||||
|
|
||||||
transmitOnRadio(&msg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
TRACE_ERROR("ERR > Unsupported protocol selected for module ERR");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
time = waitForTrigger(time, &config->trigger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef __ERROR_H__
|
|
||||||
#define __ERROR_H__
|
|
||||||
|
|
||||||
THD_FUNCTION(moduleERROR, arg);
|
|
||||||
void log_error(char *file, uint16_t line);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "ssdv.h"
|
#include "ssdv.h"
|
||||||
#include "aprs.h"
|
#include "aprs.h"
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include "base128.h"
|
#include "base91.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
|
@ -283,7 +283,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
{
|
{
|
||||||
ssdv_t ssdv;
|
ssdv_t ssdv;
|
||||||
uint8_t pkt[SSDV_PKT_SIZE];
|
uint8_t pkt[SSDV_PKT_SIZE];
|
||||||
uint8_t pkt_base128[256];
|
uint8_t pkt_base91[270];
|
||||||
const uint8_t *b;
|
const uint8_t *b;
|
||||||
uint32_t bi = 0;
|
uint32_t bi = 0;
|
||||||
uint8_t c = SSDV_OK;
|
uint8_t c = SSDV_OK;
|
||||||
|
@ -296,8 +296,11 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
|
|
||||||
// Init transmission packet
|
// Init transmission packet
|
||||||
radioMSG_t msg;
|
radioMSG_t msg;
|
||||||
|
uint8_t buffer[conf->packet_spacing ? 8192 : 512];
|
||||||
|
msg.buffer = buffer;
|
||||||
|
msg.buffer_len = sizeof(buffer);
|
||||||
msg.bin_len = 0;
|
msg.bin_len = 0;
|
||||||
msg.freq = getFrequency(&conf->frequency);
|
msg.freq = &conf->frequency;
|
||||||
msg.power = conf->power;
|
msg.power = conf->power;
|
||||||
|
|
||||||
ax25_t ax25_handle;
|
ax25_t ax25_handle;
|
||||||
|
@ -306,7 +309,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
msg.mod = conf->protocol == PROT_APRS_AFSK ? MOD_AFSK : MOD_2GFSK;
|
msg.mod = conf->protocol == PROT_APRS_AFSK ? MOD_AFSK : MOD_2GFSK;
|
||||||
msg.afsk_conf = &(conf->afsk_conf);
|
msg.afsk_conf = &(conf->afsk_conf);
|
||||||
msg.gfsk_conf = &(conf->gfsk_conf);
|
msg.gfsk_conf = &(conf->gfsk_conf);
|
||||||
aprs_encode_packet_init(&ax25_handle, msg.msg, msg.mod);
|
aprs_encode_packet_init(&ax25_handle, msg.buffer, msg.mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
|
@ -326,7 +329,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
||||||
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
||||||
{
|
{
|
||||||
aprs_encode_packet_init(&ax25_handle, msg.msg, msg.mod);
|
aprs_encode_packet_init(&ax25_handle, msg.buffer, msg.mod);
|
||||||
msg.bin_len = 0;
|
msg.bin_len = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -341,7 +344,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
||||||
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
||||||
{
|
{
|
||||||
aprs_encode_packet_init(&ax25_handle, msg.msg, msg.mod);
|
aprs_encode_packet_init(&ax25_handle, msg.buffer, msg.mod);
|
||||||
msg.bin_len = 0;
|
msg.bin_len = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -351,7 +354,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
if(msg.bin_len > 0) transmitOnRadio(&msg, false); // Empty buffer
|
||||||
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
if(conf->protocol == PROT_APRS_2GFSK || conf->protocol == PROT_APRS_AFSK)
|
||||||
{
|
{
|
||||||
aprs_encode_packet_init(&ax25_handle, msg.msg, msg.mod);
|
aprs_encode_packet_init(&ax25_handle, msg.buffer, msg.mod);
|
||||||
msg.bin_len = 0;
|
msg.bin_len = 0;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -362,11 +365,11 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
case PROT_APRS_AFSK:
|
case PROT_APRS_AFSK:
|
||||||
// Encode packet
|
// Encode packet
|
||||||
TRACE_INFO("IMG > Encode APRS/SSDV packet");
|
TRACE_INFO("IMG > Encode APRS/SSDV packet");
|
||||||
b128_encode(&pkt[6], pkt_base128, sizeof(pkt)-42); // Sync byte, CRC and FEC of SSDV not transmitted (because its not neccessary inside an APRS packet)
|
base91_encode(&pkt[6], pkt_base91, sizeof(pkt)-42); // Sync byte, CRC and FEC of SSDV not transmitted (because its not neccessary inside an APRS packet)
|
||||||
|
|
||||||
msg.bin_len = aprs_encode_packet_encodePacket(&ax25_handle, '!', &conf->aprs_conf, pkt_base128, strlen((char*)pkt_base128));
|
msg.bin_len = aprs_encode_packet_encodePacket(&ax25_handle, '!', &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91));
|
||||||
if(redudantTx)
|
if(redudantTx)
|
||||||
msg.bin_len = aprs_encode_packet_encodePacket(&ax25_handle, '!', &conf->aprs_conf, pkt_base128, strlen((char*)pkt_base128));
|
msg.bin_len = aprs_encode_packet_encodePacket(&ax25_handle, '!', &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91));
|
||||||
|
|
||||||
// Transmit
|
// Transmit
|
||||||
if(msg.bin_len >= 58000 || conf->packet_spacing) // Transmit if buffer is almost full or if single packet transmission is activated (packet_spacing != 0)
|
if(msg.bin_len >= 58000 || conf->packet_spacing) // Transmit if buffer is almost full or if single packet transmission is activated (packet_spacing != 0)
|
||||||
|
@ -376,7 +379,7 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
transmitOnRadio(&msg, false);
|
transmitOnRadio(&msg, false);
|
||||||
|
|
||||||
// Initialize new packet buffer
|
// Initialize new packet buffer
|
||||||
aprs_encode_packet_init(&ax25_handle, msg.msg, msg.mod);
|
aprs_encode_packet_init(&ax25_handle, msg.buffer, msg.mod);
|
||||||
msg.bin_len = 0;
|
msg.bin_len = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -387,11 +390,11 @@ void encode_ssdv(const uint8_t *image, uint32_t image_len, module_conf_t* conf,
|
||||||
|
|
||||||
// Encode packet
|
// Encode packet
|
||||||
TRACE_INFO("IMG > Encode 2FSK/SSDV packet");
|
TRACE_INFO("IMG > Encode 2FSK/SSDV packet");
|
||||||
memcpy(&msg.msg[msg.bin_len/8], pkt, sizeof(pkt));
|
memcpy(&msg.buffer[msg.bin_len/8], pkt, sizeof(pkt));
|
||||||
msg.bin_len += 8*sizeof(pkt);
|
msg.bin_len += 8*sizeof(pkt);
|
||||||
if(redudantTx)
|
if(redudantTx)
|
||||||
{
|
{
|
||||||
memcpy(&msg.msg[msg.bin_len/8], pkt, sizeof(pkt));
|
memcpy(&msg.buffer[msg.bin_len/8], pkt, sizeof(pkt));
|
||||||
msg.bin_len += 8*sizeof(pkt);
|
msg.bin_len += 8*sizeof(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +506,7 @@ void start_image_thread(module_conf_t *conf)
|
||||||
if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay);
|
if(conf->init_delay) chThdSleepMilliseconds(conf->init_delay);
|
||||||
TRACE_INFO("IMG > Startup image thread");
|
TRACE_INFO("IMG > Startup image thread");
|
||||||
chsnprintf(conf->name, sizeof(conf->name), "IMG");
|
chsnprintf(conf->name, sizeof(conf->name), "IMG");
|
||||||
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(30*1024), "IMG", NORMALPRIO, imgThread, conf);
|
thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE(conf->packet_spacing ? 20*1024 : 5*1024), "IMG", NORMALPRIO, imgThread, conf);
|
||||||
if(!th) {
|
if(!th) {
|
||||||
// Print startup error, do not start watchdog for this thread
|
// Print startup error, do not start watchdog for this thread
|
||||||
TRACE_ERROR("IMG > Could not startup thread (not enough memory available)");
|
TRACE_ERROR("IMG > Could not startup thread (not enough memory available)");
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
#include "base.h"
|
#include "base91.h"
|
||||||
#include "aprs.h"
|
#include "aprs.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
|
@ -168,7 +168,10 @@ THD_FUNCTION(logThread, arg)
|
||||||
|
|
||||||
// Encode radio message
|
// Encode radio message
|
||||||
radioMSG_t msg;
|
radioMSG_t msg;
|
||||||
msg.freq = getFrequency(&conf->frequency);
|
uint8_t buffer[256];
|
||||||
|
msg.buffer = buffer;
|
||||||
|
msg.buffer_len = sizeof(buffer);
|
||||||
|
msg.freq = &conf->frequency;
|
||||||
msg.power = conf->power;
|
msg.power = conf->power;
|
||||||
|
|
||||||
switch(conf->protocol) {
|
switch(conf->protocol) {
|
||||||
|
@ -179,7 +182,7 @@ THD_FUNCTION(logThread, arg)
|
||||||
msg.gfsk_conf = &(conf->gfsk_conf);
|
msg.gfsk_conf = &(conf->gfsk_conf);
|
||||||
|
|
||||||
base91_encode((uint8_t*)pkt, pkt_base91, sizeof(pkt)); // Encode base 91
|
base91_encode((uint8_t*)pkt, pkt_base91, sizeof(pkt)); // Encode base 91
|
||||||
msg.bin_len = aprs_encode_experimental('L', msg.msg, msg.mod, &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91)); // Encode APRS
|
msg.bin_len = aprs_encode_experimental('L', msg.buffer, msg.mod, &conf->aprs_conf, pkt_base91, strlen((char*)pkt_base91)); // Encode APRS
|
||||||
|
|
||||||
transmitOnRadio(&msg, true); // Transmit packet
|
transmitOnRadio(&msg, true); // Transmit packet
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -125,10 +125,13 @@ THD_FUNCTION(posThread, arg) {
|
||||||
if(!p_sleep(&conf->sleep_conf))
|
if(!p_sleep(&conf->sleep_conf))
|
||||||
{
|
{
|
||||||
|
|
||||||
TRACE_INFO("POS > Transmit GPS position");
|
TRACE_INFO("POS > Transmit position");
|
||||||
|
|
||||||
radioMSG_t msg;
|
radioMSG_t msg;
|
||||||
msg.freq = getFrequency(&conf->frequency);
|
uint8_t buffer[256];
|
||||||
|
msg.buffer = buffer;
|
||||||
|
msg.buffer_len = sizeof(buffer);
|
||||||
|
msg.freq = &conf->frequency;
|
||||||
msg.power = conf->power;
|
msg.power = conf->power;
|
||||||
|
|
||||||
switch(conf->protocol) {
|
switch(conf->protocol) {
|
||||||
|
@ -140,7 +143,7 @@ THD_FUNCTION(posThread, arg) {
|
||||||
msg.gfsk_conf = &(conf->gfsk_conf);
|
msg.gfsk_conf = &(conf->gfsk_conf);
|
||||||
msg.afsk_conf = &(conf->afsk_conf);
|
msg.afsk_conf = &(conf->afsk_conf);
|
||||||
|
|
||||||
msg.bin_len = aprs_encode_position(msg.msg, msg.mod, &(conf->aprs_conf), trackPoint); // Encode packet
|
msg.bin_len = aprs_encode_position(msg.buffer, msg.mod, &(conf->aprs_conf), trackPoint); // Encode packet
|
||||||
transmitOnRadio(&msg, true);
|
transmitOnRadio(&msg, true);
|
||||||
|
|
||||||
// Telemetry encoding parameter transmission
|
// Telemetry encoding parameter transmission
|
||||||
|
@ -159,7 +162,7 @@ THD_FUNCTION(posThread, arg) {
|
||||||
chThdSleepMilliseconds(5000); // Take a litte break between the package transmissions
|
chThdSleepMilliseconds(5000); // Take a litte break between the package transmissions
|
||||||
|
|
||||||
const telemetry_conf_t tel_conf[] = {CONF_PARM, CONF_UNIT, CONF_EQNS, CONF_BITS};
|
const telemetry_conf_t tel_conf[] = {CONF_PARM, CONF_UNIT, CONF_EQNS, CONF_BITS};
|
||||||
msg.bin_len = aprs_encode_telemetry_configuration(msg.msg, msg.mod, &(conf->aprs_conf), tel_conf[current_conf_count]); // Encode packet
|
msg.bin_len = aprs_encode_telemetry_configuration(msg.buffer, msg.mod, &(conf->aprs_conf), tel_conf[current_conf_count]); // Encode packet
|
||||||
transmitOnRadio(&msg, true);
|
transmitOnRadio(&msg, true);
|
||||||
|
|
||||||
current_conf_count++;
|
current_conf_count++;
|
||||||
|
@ -177,7 +180,7 @@ THD_FUNCTION(posThread, arg) {
|
||||||
memcpy(fskmsg, conf->ukhas_conf.format, sizeof(conf->ukhas_conf.format));
|
memcpy(fskmsg, conf->ukhas_conf.format, sizeof(conf->ukhas_conf.format));
|
||||||
replace_placeholders(fskmsg, sizeof(fskmsg), trackPoint);
|
replace_placeholders(fskmsg, sizeof(fskmsg), trackPoint);
|
||||||
str_replace(fskmsg, sizeof(fskmsg), "<CALL>", conf->ukhas_conf.callsign);
|
str_replace(fskmsg, sizeof(fskmsg), "<CALL>", conf->ukhas_conf.callsign);
|
||||||
msg.bin_len = 8*chsnprintf((char*)msg.msg, sizeof(fskmsg), "$$$$$%s*%04X\n", fskmsg, crc16(fskmsg));
|
msg.bin_len = 8*chsnprintf((char*)msg.buffer, sizeof(fskmsg), "$$$$$%s*%04X\n", fskmsg, crc16(fskmsg));
|
||||||
|
|
||||||
// Transmit message
|
// Transmit message
|
||||||
transmitOnRadio(&msg, true);
|
transmitOnRadio(&msg, true);
|
||||||
|
@ -194,7 +197,7 @@ THD_FUNCTION(posThread, arg) {
|
||||||
str_replace(morse, sizeof(morse), "<CALL>", conf->morse_conf.callsign);
|
str_replace(morse, sizeof(morse), "<CALL>", conf->morse_conf.callsign);
|
||||||
|
|
||||||
// Transmit message
|
// Transmit message
|
||||||
msg.bin_len = morse_encode(msg.msg, morse); // Convert message to binary stream
|
msg.bin_len = morse_encode(msg.buffer, morse); // Convert message to binary stream
|
||||||
transmitOnRadio(&msg, true);
|
transmitOnRadio(&msg, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -86,13 +86,25 @@ typedef struct {
|
||||||
uint32_t speed;
|
uint32_t speed;
|
||||||
} gfsk_conf_t;
|
} gfsk_conf_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FREQ_STATIC, // Fixed frequency
|
||||||
|
FREQ_APRS_REGION // APRS region dependent (it changes it frequency automatically depending on which APRS frequency is used in this region)
|
||||||
|
} freq_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
freq_type_t type;
|
||||||
|
uint32_t hz;
|
||||||
|
} freq_conf_t;
|
||||||
|
|
||||||
typedef struct { // Radio message type
|
typedef struct { // Radio message type
|
||||||
uint8_t msg[8191]; // Message (data)
|
uint8_t* buffer; // Message (data)
|
||||||
uint32_t bin_len; // Binary length
|
uint16_t buffer_len; // Buffer size (in bytes)
|
||||||
uint32_t freq; // Frequency
|
uint32_t bin_len; // Binary length (it bits)
|
||||||
int8_t power; // Power in dBm
|
int8_t power; // Power in dBm
|
||||||
mod_t mod; // Modulation
|
mod_t mod; // Modulation
|
||||||
|
|
||||||
|
freq_conf_t* freq; // Frequency
|
||||||
|
|
||||||
ook_conf_t* ook_conf; // OOK config
|
ook_conf_t* ook_conf; // OOK config
|
||||||
fsk_conf_t* fsk_conf; // 2FSK config
|
fsk_conf_t* fsk_conf; // 2FSK config
|
||||||
afsk_conf_t* afsk_conf; // AFSK config
|
afsk_conf_t* afsk_conf; // AFSK config
|
||||||
|
@ -118,16 +130,6 @@ typedef struct {
|
||||||
bool redundantTx; // Redundand packet transmission (APRS only)
|
bool redundantTx; // Redundand packet transmission (APRS only)
|
||||||
} ssdv_conf_t;
|
} ssdv_conf_t;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FREQ_STATIC, // Fixed frequency
|
|
||||||
FREQ_APRS_REGION // APRS region dependent (it changes it frequency automatically depending on which APRS frequency is used in this region)
|
|
||||||
} freq_type_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
freq_type_t type;
|
|
||||||
uint32_t hz;
|
|
||||||
} freq_conf_t;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TRIG_ONCE, // Trigger once and never again (e.g. transmit specific position packet only at startup)
|
TRIG_ONCE, // Trigger once and never again (e.g. transmit specific position packet only at startup)
|
||||||
TRIG_NEW_POINT, // Triggered when new track point available
|
TRIG_NEW_POINT, // Triggered when new track point available
|
||||||
|
|
Ładowanie…
Reference in New Issue