kopia lustrzana https://github.com/bristol-seds/pico-tracker
Working aprs test using square wave on gpio1 and 2gfsk
rodzic
e76e078914
commit
96248ed8b8
|
@ -4,7 +4,9 @@
|
|||
| --- | --- | --- | ---
|
||||
|*GLCK*|
|
||||
||gclk0|main clock, internal osc8m|4 MHz
|
||||
||gclk1|tcxo clock, fed from xosc
|
||||
||gclk1|tcxo clock, fed from xosc OR osc8m
|
||||
|
|
||||
||gclk7|aprs clock, fed from gclk1, div 6 / 11
|
||||
|
||||
|*TC*||
|
||||
||tc0|telemetry tick timer. 32-bit
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Outputs aprs to the si_trx
|
||||
* Outputs aprs uisng ax25
|
||||
* Copyright (C) 2015 Richard Meadows <richardeoin>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
|
@ -25,6 +25,7 @@
|
|||
#ifndef APRS_H
|
||||
#define APRS_H
|
||||
|
||||
|
||||
void aprs_init(void);
|
||||
void aprs_tick(void);
|
||||
|
||||
#endif /* APRS_H */
|
||||
|
|
|
@ -25,53 +25,56 @@
|
|||
#ifndef AX25_H
|
||||
#define AX25_H
|
||||
|
||||
#include "ax25_sintable.h"
|
||||
|
||||
/**
|
||||
* Parameters based on the size of the sintable
|
||||
*/
|
||||
#define AX25_SINTABLE_SIZE (AX25_SINTABLE_LENGTH*4)
|
||||
#define AX25_SINTABLE_LUMASK (AX25_SINTABLE_LENGTH-1)
|
||||
#define AX25_SINTABLE_MASK (AX25_SINTABLE_SIZE-1)
|
||||
#define AX25_SINTABLE_PART(phase) ((phase >> AX25_SINTABLE_ORDER) & 3)
|
||||
|
||||
/**
|
||||
* Bell-202
|
||||
*/
|
||||
#define AX25_BAUD 2200
|
||||
#define AX25_MARKFREQ 1
|
||||
#define AX25_SPACEFREQ 2
|
||||
#define AX25_BAUD 1200
|
||||
#define AX25_MARK_FREQ 1200
|
||||
#define AX25_SPACE_FREQ 2200
|
||||
|
||||
/**
|
||||
* How often our handler gets called
|
||||
*/
|
||||
#define AX25_TICK_RATE AX25_BAUD
|
||||
|
||||
/**
|
||||
* AX25 packet parameters
|
||||
*/
|
||||
#define AX25_BITSTUFFINGCOUNT 5
|
||||
|
||||
|
||||
#define AX25_PREAMBLE_FLAGS 15 /* 100 ms of flags */
|
||||
#define AX25_POSTAMBLE_FLAGS 1
|
||||
#define AX25_MAX_FRAME_LEN 0x100
|
||||
|
||||
/**
|
||||
* How many points we output in a single symbol-time
|
||||
* Hard-coded AX25 words
|
||||
*/
|
||||
#define AX25_OVERSAMPLING 2
|
||||
#define AX25_TICK_RATE (AX25_BAUD * AX25_OVERSAMPLING)
|
||||
|
||||
/**
|
||||
* Define the phase velocities for mark and space
|
||||
*
|
||||
* This is how many entries in the sin table we step by
|
||||
*/
|
||||
#define AX25_MARKPHASEVELOCITY (AX25_SINTABLE_SIZE/AX25_OVERSAMPLING)
|
||||
#define AX25_SPACEPHASEVELOCITY (AX25_MARKPHASEVELOCITY*(2.2f/1.2f))
|
||||
// TODO ^^
|
||||
|
||||
|
||||
|
||||
#define AX25_CONTROL_WORD 0x03 /* Use Unnumbered Information (UI) frames */
|
||||
#define AX25_PROTOCOL_ID 0xF0 /* No third level protocol */
|
||||
|
||||
|
||||
enum ax25_symbol_t {
|
||||
AX25_MARK,
|
||||
AX25_SPACE,
|
||||
};
|
||||
struct ax25_byte_t {
|
||||
uint8_t val;
|
||||
uint8_t stuff;
|
||||
};
|
||||
|
||||
/**
|
||||
* State machine
|
||||
*/
|
||||
enum ax25_state_t {
|
||||
AX25_PREAMBLE,
|
||||
AX25_FRAME,
|
||||
AX25_POSTAMBLE,
|
||||
AX25_IDLE,
|
||||
};
|
||||
|
||||
|
||||
void ax25_start();
|
||||
void ax25_start(char* addresses, uint32_t addresses_len,
|
||||
char* information, uint32_t information_len);
|
||||
uint8_t ax25_tick(void);
|
||||
|
||||
#endif /* AX25_H */
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/**
|
||||
* Autogenerated sine tables. See tools/ax25_lookup/ax25_lookup.py
|
||||
*/
|
||||
|
||||
#ifndef AX25_SINTABLE_H
|
||||
#define AX25_SINTABLE_H
|
||||
|
||||
|
||||
#include "samd20.h"
|
||||
|
||||
#define AX25_SINTABLE_ORDER 9
|
||||
#define AX25_SINTABLE_LENGTH 512
|
||||
|
||||
|
||||
/**
|
||||
* 1st quadrant sin lookup table for 1.5kHz deviation
|
||||
*
|
||||
* Length: 512
|
||||
* Frequency Resolution: 7.805 Hz
|
||||
*/
|
||||
uint16_t sintable_512_1500hz[512];
|
||||
|
||||
/**
|
||||
* 1st quadrant sin lookup table for 2.5kHz deviation
|
||||
*
|
||||
* Length: 512
|
||||
* Frequency Resolution: 7.805 Hz
|
||||
*/
|
||||
uint16_t sintable_512_2500hz[512];
|
||||
|
||||
#endif /* AX25_SINTABLE_H */
|
|
@ -53,8 +53,12 @@ float telemetry_si_temperature(void);
|
|||
float timer0_tick_init(float frequency);
|
||||
uint32_t timer0_tick_frequency(float frequency);
|
||||
void timer0_tick_deinit();
|
||||
|
||||
void telemetry_gpio1_pwm_init(void);
|
||||
void telemetry_gpio1_pwm_duty(float duty_cycle);
|
||||
void telemetry_gpio1_pwm_deinit(void);
|
||||
|
||||
void telemetry_gpio1_init(void);
|
||||
void telemetry_gpio1_set(uint8_t value);
|
||||
|
||||
#endif /* TELEMETRY_H */
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Outputs aprs uisng ax25
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "samd20.h"
|
||||
#include "ax25.h"
|
||||
|
||||
char addresses[50];
|
||||
|
||||
void aprs_start(void)
|
||||
{
|
||||
sprintf(addresses, "%-6s%c%-6s%c%-6s%c",
|
||||
"APRS", 0,
|
||||
"M0SBU", 0,
|
||||
"WIDE1", 1);
|
||||
|
||||
ax25_start(addresses, 21, 0, 0);
|
||||
}
|
||||
|
||||
void aprs_tick(void)
|
||||
{
|
||||
ax25_tick();
|
||||
}
|
|
@ -23,89 +23,345 @@
|
|||
*/
|
||||
|
||||
#include "samd20.h"
|
||||
#include "system/gclk.h"
|
||||
#include "system/pinmux.h"
|
||||
#include "tc/tc_driver.h"
|
||||
#include "hw_config.h"
|
||||
#include "ax25.h"
|
||||
#include "ax25_sintable.h"
|
||||
#include "telemetry.h"
|
||||
#include "si_trx.h"
|
||||
|
||||
#define AX25_MARKSINTABLE sintable_512_1500hz
|
||||
#define AX25_SPACESINTABLE sintable_512_2500hz
|
||||
enum ax25_symbol_t next_symbol;
|
||||
uint8_t bit_index;
|
||||
struct ax25_byte_t current_byte;
|
||||
uint8_t current_bit;
|
||||
uint8_t one_count;
|
||||
uint32_t byte_index;
|
||||
|
||||
enum ax25_state_t ax25_state;
|
||||
//uint8_t ax25_frame[AX25_MAX_FRAME_LEN];
|
||||
uint32_t ax25_index, ax25_frame_length;
|
||||
|
||||
|
||||
uint32_t ax25_phase;
|
||||
uint32_t ax25_phasevelocity;
|
||||
uint32_t ax25_oversampling_count;
|
||||
uint8_t ax25_frame[29] = {0x86, 0xA2, 0x40, 0x40, 0x40, 0x40, 0x60, 0xAE, 0x64, 0x8C, 0xA6,
|
||||
0x40, 0x40, 0x68, 0xA4, 0x8A, 0x98, 0x82, 0xB2, 0x40, 0x61, 0x03,
|
||||
0xF0, 0x54, 0x65, 0x73, 0x74, 0x00, 0x00 };
|
||||
|
||||
uint16_t* ax25_sintable;
|
||||
|
||||
void ax25_start()
|
||||
{
|
||||
/* Init */
|
||||
ax25_phase = 0;
|
||||
ax25_phasevelocity = AX25_MARKPHASEVELOCITY;
|
||||
ax25_sintable = AX25_MARKSINTABLE;
|
||||
ax25_oversampling_count = -1LL;
|
||||
}
|
||||
|
||||
|
||||
uint32_t toggle = 0;
|
||||
enum ax25_symbol_t ax25_get_next_symbol(void) {
|
||||
return (toggle++ & 1) ? AX25_MARK : AX25_SPACE;
|
||||
}
|
||||
|
||||
|
||||
void telemetry_gpio1_pwm_duty(float duty_cycle);
|
||||
void ax25_gpio1_pwm_init(void);
|
||||
|
||||
/**
|
||||
* Called at our tick rate, outputs tones
|
||||
* Frame Check Sequence (FCS)
|
||||
* =============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* CRC Function for the XMODEM protocol.
|
||||
* http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html#gaca726c22a1900f9bad52594c8846115f
|
||||
*/
|
||||
uint16_t crc_update(uint16_t crc, uint8_t data)
|
||||
{
|
||||
int i;
|
||||
|
||||
// crc = crc ^ ((uint16_t)data << 8);
|
||||
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
||||
if ((crc & 1) != (data & 1)) {
|
||||
|
||||
crc = (crc >> 1) ^ 0x8408;
|
||||
data = data >> 1;
|
||||
|
||||
} else {
|
||||
crc = crc >> 1;
|
||||
data = data >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
crc_ccitt_update (uint16_t crc, uint8_t data)
|
||||
{
|
||||
data ^= (crc & 0xff);
|
||||
data ^= data << 4;
|
||||
return ((((uint16_t)data << 8) | ((crc >> 8) & 0xff)) ^ (uint8_t)(data >> 4)
|
||||
^ ((uint16_t)data << 3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the Frame Check Sequence (FCS) using the CRC algorithm
|
||||
*/
|
||||
uint16_t crc_fcs(uint8_t *string, uint32_t length)
|
||||
{
|
||||
size_t i;
|
||||
uint16_t crc;
|
||||
uint8_t c;
|
||||
|
||||
crc = 0xFFFF;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
c = string[i];
|
||||
crc = crc_ccitt_update(crc, c);
|
||||
}
|
||||
|
||||
return crc ^ 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Starts the transmission of an ax25 frame
|
||||
*/
|
||||
void ax25_start(char* addresses, uint32_t addresses_len,
|
||||
char* information, uint32_t information_len)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint16_t fcs;
|
||||
|
||||
/* /\* Process addresses *\/ */
|
||||
/* for (i = 0; i < addresses_len; i++) { */
|
||||
|
||||
/* if ((i % 7) == 6) { /\* Secondary Station ID *\/ */
|
||||
/* ax25_frame[i] = ((addresses[i] << 1) & 0x1F) | 0x60; */
|
||||
/* } else { */
|
||||
/* ax25_frame[i] = (addresses[i] << 1); */
|
||||
/* } */
|
||||
/* } */
|
||||
/* ax25_frame[i-1] |= 0x1; /\* Set HLDC bit *\/ */
|
||||
|
||||
/* ax25_frame[i++] = AX25_CONTROL_WORD; */
|
||||
/* ax25_frame[i++] = AX25_PROTOCOL_ID; */
|
||||
|
||||
/* /\* Process information *\/ */
|
||||
/* for (j = 0; j < information_len; j++) { */
|
||||
/* ax25_frame[i++] = information[j]; */
|
||||
/* } */
|
||||
|
||||
/* Frame Check Sequence (FCS) */
|
||||
fcs = crc_fcs(ax25_frame, 27);
|
||||
ax25_frame[27] = (fcs >> 0) & 0xFF;
|
||||
ax25_frame[28] = (fcs >> 8) & 0xFF;
|
||||
|
||||
fcs = crc_fcs("data", 4);
|
||||
|
||||
/* Length */
|
||||
ax25_frame_length = 29;
|
||||
|
||||
/* Init */
|
||||
next_symbol = AX25_MARK;
|
||||
bit_index = 8;
|
||||
current_bit = 1;
|
||||
one_count = 0;
|
||||
|
||||
ax25_state = AX25_PREAMBLE;
|
||||
ax25_index = 0;
|
||||
|
||||
/* Hardware init */
|
||||
ax25_gpio1_pwm_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Sets up gpio1 for the afsk pwm output. Uses gclk 7
|
||||
*/
|
||||
void ax25_gpio1_pwm_init(void)
|
||||
{
|
||||
float gclk1_frequency = (float)system_gclk_gen_get_hz(1);
|
||||
|
||||
uint32_t top = 38;//(uint32_t)(gclk1_frequency / 13200.0*4);// & ~0x1;
|
||||
uint32_t capture = top >> 1; /* 50% duty cycle */
|
||||
|
||||
if (top > 0xFF) while (1); // It's only an 8-bit counter
|
||||
|
||||
/* Setup GCLK genertor 7 */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||
false, /* High When Disabled */
|
||||
11, /* Division Factor */// TODO
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
system_gclk_gen_enable(GCLK_GENERATOR_7);
|
||||
|
||||
/* Configure timer */
|
||||
bool capture_channel_enables[] = {false, true};
|
||||
uint32_t compare_channel_values[] = {0x0000, capture};
|
||||
|
||||
tc_init(TC5,
|
||||
GCLK_GENERATOR_7,
|
||||
TC_COUNTER_SIZE_8BIT,
|
||||
TC_CLOCK_PRESCALER_DIV4,
|
||||
TC_WAVE_GENERATION_NORMAL_PWM,
|
||||
TC_RELOAD_ACTION_GCLK,
|
||||
TC_COUNT_DIRECTION_UP,
|
||||
TC_WAVEFORM_INVERT_OUTPUT_NONE,
|
||||
false, /* Oneshot = false */
|
||||
false, /* Run in standby = false */
|
||||
0x0000, /* Initial value */
|
||||
top, /* Top value */
|
||||
capture_channel_enables, /* Capture Channel Enables */
|
||||
compare_channel_values); /* Compare Channels Values */
|
||||
|
||||
|
||||
/* Enable the output pin */
|
||||
system_pinmux_pin_set_config(SI406X_GPIO1_PINMUX >> 16, /* GPIO Pin */
|
||||
SI406X_GPIO1_PINMUX & 0xFFFF, /* Mux Position */
|
||||
SYSTEM_PINMUX_PIN_DIR_INPUT, /* Direction */
|
||||
SYSTEM_PINMUX_PIN_PULL_NONE, /* Pull */
|
||||
false); /* Powersave */
|
||||
|
||||
tc_enable(TC5);
|
||||
tc_start_counter(TC5);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the packet to transmit
|
||||
*/
|
||||
struct ax25_byte_t ax25_get_next_byte(void) {
|
||||
|
||||
struct ax25_byte_t next = { .stuff = 0 };
|
||||
|
||||
switch (ax25_state) {
|
||||
case AX25_PREAMBLE: /* Preamble */
|
||||
/* Return flag */
|
||||
next.val = 0x7E;
|
||||
|
||||
/* Check for next state */
|
||||
ax25_index++;
|
||||
if (ax25_index >= AX25_PREAMBLE_FLAGS) {
|
||||
/* Next state */
|
||||
ax25_state = AX25_FRAME;
|
||||
ax25_index = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AX25_FRAME: /* Frame */
|
||||
/* Return data */
|
||||
next.val = ax25_frame[ax25_index];
|
||||
next.stuff = 1;
|
||||
|
||||
/* Check for next state */
|
||||
ax25_index++;
|
||||
if (ax25_index >= ax25_frame_length) {
|
||||
/* Next state */
|
||||
ax25_state = AX25_POSTAMBLE;
|
||||
ax25_index = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AX25_POSTAMBLE: /* Postamble */
|
||||
/* Return flag */
|
||||
next.val = 0x7E;
|
||||
|
||||
/* Check for next state */
|
||||
ax25_index++;
|
||||
if (ax25_index >= AX25_POSTAMBLE_FLAGS) {
|
||||
/* Next state */
|
||||
ax25_state = AX25_PREAMBLE;
|
||||
ax25_index = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
//uint32_t toggle = 0;
|
||||
|
||||
/**
|
||||
* Returns the next symbol to transmit
|
||||
*/
|
||||
enum ax25_symbol_t ax25_get_next_symbol(void) {
|
||||
|
||||
uint8_t bit;
|
||||
|
||||
if (bit_index >= 8) {
|
||||
current_byte = ax25_get_next_byte();
|
||||
bit_index = 0;
|
||||
}
|
||||
|
||||
/* transmit bits lsb first */
|
||||
bit = current_byte.val & 0x01;
|
||||
|
||||
if (bit) { /* One */
|
||||
|
||||
one_count++;
|
||||
|
||||
/* Check if we need to stuff this bit */
|
||||
if (one_count >= AX25_BITSTUFFINGCOUNT && current_byte.stuff) {
|
||||
current_byte.val &= ~0x01;/* Next bit is zero */
|
||||
one_count = 0;
|
||||
|
||||
} else {
|
||||
current_byte.val >>= 1; /* Move along one bit */
|
||||
bit_index++;
|
||||
}
|
||||
} else { /* Zero */
|
||||
|
||||
one_count = 0; /* Clear concecutive ones */
|
||||
current_byte.val >>= 1; /* Move along one bit */
|
||||
bit_index++;
|
||||
|
||||
/* NRZI encoding */
|
||||
current_bit ^= 0x01;
|
||||
}
|
||||
|
||||
return current_bit;
|
||||
|
||||
|
||||
// return (toggle++ & 1) ? AX25_MARK : AX25_SPACE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called at our tick rate, controls the pwm gclk
|
||||
*
|
||||
* Returns 1 when more work todo, 0 when finished
|
||||
*/
|
||||
uint8_t ax25_tick(void)
|
||||
{
|
||||
int16_t deviation;
|
||||
uint32_t sintable_phase = ax25_phase & AX25_SINTABLE_LUMASK;
|
||||
|
||||
/* Set the instantaneous fm deviation based on the current phase */
|
||||
switch (AX25_SINTABLE_PART(ax25_phase)) {
|
||||
case 0: /* 0° - 90° */
|
||||
deviation = ax25_sintable[sintable_phase];
|
||||
break;
|
||||
case 1: /* 90° - 180° */
|
||||
deviation = ax25_sintable[AX25_SINTABLE_LUMASK - sintable_phase];
|
||||
break;
|
||||
case 2: /* 180° - 270° */
|
||||
deviation = -ax25_sintable[sintable_phase];
|
||||
break;
|
||||
case 3: /* 270° - 360° */
|
||||
deviation = -ax25_sintable[AX25_SINTABLE_LUMASK - sintable_phase];
|
||||
break;
|
||||
default:
|
||||
deviation = 0;
|
||||
if (next_symbol == AX25_SPACE) {
|
||||
|
||||
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||
false, /* High When Disabled */
|
||||
6, /* Division Factor */// TODO
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||
false, /* High When Disabled */
|
||||
11, /* Division Factor */// TODO
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
|
||||
}
|
||||
|
||||
// si_trx_switch_channel(deviation);
|
||||
|
||||
// float duty = 0.5 + ((float)deviation/192.0) / 2.0;
|
||||
float duty = (ax25_get_next_symbol() == AX25_SPACE) ? 1.0 : 0.0;
|
||||
|
||||
telemetry_gpio1_pwm_duty(duty);
|
||||
|
||||
/* Update with next bit */
|
||||
if (ax25_oversampling_count++ >= AX25_OVERSAMPLING) {
|
||||
ax25_oversampling_count = 0;
|
||||
|
||||
/* Set phase velocity for next symbol */
|
||||
if (0) {//ax25_get_next_symbol() == AX25_SPACE) {
|
||||
ax25_phasevelocity = AX25_SPACEPHASEVELOCITY;
|
||||
ax25_sintable = AX25_SPACESINTABLE;
|
||||
} else {
|
||||
ax25_phasevelocity = AX25_MARKPHASEVELOCITY;
|
||||
ax25_sintable = AX25_MARKSINTABLE;
|
||||
}
|
||||
}
|
||||
/* Update phase */
|
||||
ax25_phase += ax25_phasevelocity;
|
||||
|
||||
next_symbol = ax25_get_next_symbol();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* Autogenerated sine tables. See tools/ax25_lookup/ax25_lookup.py
|
||||
*/
|
||||
|
||||
#include "samd20.h"
|
||||
|
||||
/**
|
||||
* 1st quadrant sin lookup table for 1.5kHz deviation
|
||||
*
|
||||
* Length: 512
|
||||
* Frequency Resolution: 7.805 Hz
|
||||
*/
|
||||
uint16_t sintable_512_1500hz[] = {
|
||||
0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 8, 8,
|
||||
9, 9, 10, 11, 11, 12, 12, 13, 14, 14, 15, 15, 16, 16, 17,
|
||||
18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26,
|
||||
26, 27, 28, 28, 29, 29, 30, 31, 31, 32, 32, 33, 33, 34, 35,
|
||||
35, 36, 36, 37, 37, 38, 39, 39, 40, 40, 41, 42, 42, 43, 43,
|
||||
44, 44, 45, 46, 46, 47, 47, 48, 48, 49, 50, 50, 51, 51, 52,
|
||||
52, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 59, 59, 60, 60,
|
||||
61, 61, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 68, 68, 69,
|
||||
69, 70, 70, 71, 71, 72, 72, 73, 74, 74, 75, 75, 76, 76, 77,
|
||||
77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85,
|
||||
85, 86, 86, 87, 87, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93,
|
||||
93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100,
|
||||
101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108,
|
||||
108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 114, 115,
|
||||
115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 121, 122,
|
||||
122, 123, 123, 124, 124, 125, 125, 126, 126, 126, 127, 127, 128, 128, 129,
|
||||
129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 133, 134, 134, 135, 135,
|
||||
135, 136, 136, 137, 137, 138, 138, 138, 139, 139, 140, 140, 140, 141, 141,
|
||||
142, 142, 142, 143, 143, 144, 144, 144, 145, 145, 146, 146, 146, 147, 147,
|
||||
147, 148, 148, 149, 149, 149, 150, 150, 150, 151, 151, 152, 152, 152, 153,
|
||||
153, 153, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 158,
|
||||
158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 162, 162, 162, 163,
|
||||
163, 163, 164, 164, 164, 165, 165, 165, 165, 166, 166, 166, 167, 167, 167,
|
||||
167, 168, 168, 168, 169, 169, 169, 169, 170, 170, 170, 171, 171, 171, 171,
|
||||
172, 172, 172, 172, 173, 173, 173, 173, 174, 174, 174, 174, 175, 175, 175,
|
||||
175, 176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 178, 179,
|
||||
179, 179, 179, 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, 182, 182,
|
||||
182, 182, 182, 182, 183, 183, 183, 183, 183, 184, 184, 184, 184, 184, 184,
|
||||
185, 185, 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 187, 187,
|
||||
187, 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, 188, 188, 188, 189,
|
||||
189, 189, 189, 189, 189, 189, 189, 189, 190, 190, 190, 190, 190, 190, 190,
|
||||
190, 190, 190, 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
|
||||
191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
|
||||
192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
|
||||
192, 192
|
||||
};
|
||||
|
||||
/**
|
||||
* 1st quadrant sin lookup table for 2.5kHz deviation
|
||||
*
|
||||
* Length: 512
|
||||
* Frequency Resolution: 7.805 Hz
|
||||
*/
|
||||
uint16_t sintable_512_2500hz[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
|
||||
59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
|
||||
73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 84, 85, 86,
|
||||
87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 100,
|
||||
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 113, 114,
|
||||
115, 116, 117, 118, 119, 120, 121, 122, 123, 123, 124, 125, 126, 127, 128,
|
||||
129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138, 139, 140, 140, 141,
|
||||
142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151, 152, 153, 154, 154,
|
||||
155, 156, 157, 158, 159, 160, 160, 161, 162, 163, 164, 165, 166, 166, 167,
|
||||
168, 169, 170, 171, 171, 172, 173, 174, 175, 175, 176, 177, 178, 179, 180,
|
||||
180, 181, 182, 183, 184, 184, 185, 186, 187, 188, 188, 189, 190, 191, 192,
|
||||
192, 193, 194, 195, 196, 196, 197, 198, 199, 199, 200, 201, 202, 202, 203,
|
||||
204, 205, 205, 206, 207, 208, 208, 209, 210, 211, 211, 212, 213, 214, 214,
|
||||
215, 216, 217, 217, 218, 219, 219, 220, 221, 222, 222, 223, 224, 224, 225,
|
||||
226, 226, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 235,
|
||||
236, 237, 237, 238, 239, 239, 240, 241, 241, 242, 243, 243, 244, 244, 245,
|
||||
246, 246, 247, 248, 248, 249, 249, 250, 251, 251, 252, 253, 253, 254, 254,
|
||||
255, 255, 256, 257, 257, 258, 258, 259, 260, 260, 261, 261, 262, 262, 263,
|
||||
264, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 270, 270, 271, 271,
|
||||
272, 272, 273, 273, 274, 274, 275, 275, 276, 276, 277, 277, 278, 278, 279,
|
||||
279, 280, 280, 281, 281, 282, 282, 282, 283, 283, 284, 284, 285, 285, 286,
|
||||
286, 287, 287, 287, 288, 288, 289, 289, 290, 290, 290, 291, 291, 292, 292,
|
||||
292, 293, 293, 294, 294, 294, 295, 295, 296, 296, 296, 297, 297, 297, 298,
|
||||
298, 298, 299, 299, 300, 300, 300, 301, 301, 301, 302, 302, 302, 303, 303,
|
||||
303, 304, 304, 304, 304, 305, 305, 305, 306, 306, 306, 307, 307, 307, 307,
|
||||
308, 308, 308, 308, 309, 309, 309, 309, 310, 310, 310, 310, 311, 311, 311,
|
||||
311, 312, 312, 312, 312, 313, 313, 313, 313, 313, 314, 314, 314, 314, 314,
|
||||
315, 315, 315, 315, 315, 315, 316, 316, 316, 316, 316, 316, 317, 317, 317,
|
||||
317, 317, 317, 317, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319,
|
||||
319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, 320, 320, 320, 320,
|
||||
320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320,
|
||||
320, 320
|
||||
};
|
||||
|
|
@ -255,8 +255,8 @@ void init(void)
|
|||
/* Clock up to 14MHz with 0 wait states */
|
||||
system_flash_set_waitstates(SYSTEM_WAIT_STATE_1_8V_14MHZ);
|
||||
|
||||
/* Up the clock rate to 4MHz */
|
||||
system_clock_source_osc8m_set_config(SYSTEM_OSC8M_DIV_2, /* Prescaler */
|
||||
/* Up the clock rate to 8MHz */
|
||||
system_clock_source_osc8m_set_config(SYSTEM_OSC8M_DIV_1, /* Prescaler */
|
||||
false, /* Run in Standby */
|
||||
false); /* Run on Demand */
|
||||
|
||||
|
@ -285,9 +285,7 @@ void init(void)
|
|||
//wdt_reset_count();
|
||||
|
||||
/* Enables the xosc on gclk1 */
|
||||
#ifdef USE_XOSC
|
||||
xosc_init();
|
||||
#endif
|
||||
|
||||
led_init();
|
||||
gps_init();
|
||||
|
|
|
@ -430,7 +430,7 @@ void si_trx_reset(uint8_t modulation_type, uint16_t deviation)
|
|||
si_trx_set_frequency(RADIO_FREQUENCY, deviation);
|
||||
si_trx_set_tx_power(RADIO_POWER);
|
||||
|
||||
si_trx_modem_set_tx_datarate(2200);
|
||||
si_trx_modem_set_tx_datarate(3000);
|
||||
|
||||
/* RTTY from GPIO1 */
|
||||
si_trx_modem_set_modulation(SI_MODEM_MOD_DIRECT_MODE_SYNC, // ASYNC
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "rtty.h"
|
||||
#include "contestia.h"
|
||||
#include "rsid.h"
|
||||
#include "aprs.h"
|
||||
#include "ax25.h"
|
||||
#include "pips.h"
|
||||
#include "si_trx.h"
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "system/gclk.h"
|
||||
#include "system/interrupt.h"
|
||||
#include "system/pinmux.h"
|
||||
#include "system/port.h"
|
||||
#include "tc/tc_driver.h"
|
||||
#include "hw_config.h"
|
||||
|
||||
|
@ -305,17 +307,13 @@ void telemetry_tick(void) {
|
|||
case TELEMETRY_APRS: /* ---- ---- APRS */
|
||||
|
||||
if (!radio_on) {
|
||||
/* ARPS: We use the modem offset to modulate */
|
||||
|
||||
telemetry_gpio1_pwm_init();
|
||||
//telemetry_gpio1_pwm_duty(0.5);
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 400);
|
||||
/* APRS: We use pwm to control gpio1 */
|
||||
aprs_start();
|
||||
|
||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 200);
|
||||
radio_on = 1;
|
||||
ax25_start();
|
||||
}
|
||||
ax25_tick();
|
||||
aprs_tick();
|
||||
|
||||
break;
|
||||
|
||||
|
@ -351,13 +349,8 @@ void telemetry_tick(void) {
|
|||
*/
|
||||
float timer0_tick_init(float frequency)
|
||||
{
|
||||
#ifdef USE_XOSC
|
||||
const enum gclk_generator tick_gclk_gen = GCLK_GENERATOR_1;
|
||||
const uint8_t tick_gclk_gen_num = 1;
|
||||
#else
|
||||
const enum gclk_generator tick_gclk_gen = GCLK_GENERATOR_0;
|
||||
const uint8_t tick_gclk_gen_num = 0;
|
||||
#endif
|
||||
|
||||
/* Calculate the wrap value for the given frequency */
|
||||
float gclk_frequency = (float)system_gclk_gen_get_hz(tick_gclk_gen_num);
|
||||
|
@ -439,22 +432,37 @@ void TC0_Handler(void)
|
|||
|
||||
|
||||
|
||||
#define GPIO1_PWM_STEPS 208 // // ~ 2kHz on a 4 MHz clock
|
||||
#define GPIO1_PWM_STEPS 200 // ~ 2kHz on a 4 MHz clock
|
||||
|
||||
/**
|
||||
* Initialised PWM at the given duty cycle on the GPIO1 pin of the radio
|
||||
*/
|
||||
void telemetry_gpio1_pwm_init(void)
|
||||
{
|
||||
bool capture_channel_enables[] = {false, true};
|
||||
uint32_t compare_channel_values[] = {0x0000, 0x0000}; // Set duty cycle at 0% by default
|
||||
float gclk1_frequency = (float)system_gclk_gen_get_hz(1);
|
||||
|
||||
//float gclk_frequency = (float)system_gclk_gen_get_hz(0);
|
||||
uint32_t top = 38;//(uint32_t)(gclk1_frequency / 13200.0*4);// & ~0x1;
|
||||
uint32_t capture = top >> 1; /* 50% duty cycle */
|
||||
|
||||
if (top > 0xFF) while (1); // It's only an 8-bit counter
|
||||
|
||||
/* Setup GCLK genertor 7 */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||
false, /* High When Disabled */
|
||||
11, /* Division Factor */// TODO
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
system_gclk_gen_enable(GCLK_GENERATOR_7);
|
||||
|
||||
/* Configure timer */
|
||||
bool capture_channel_enables[] = {false, true};
|
||||
uint32_t compare_channel_values[] = {0x0000, capture};
|
||||
|
||||
tc_init(TC5,
|
||||
GCLK_GENERATOR_0,
|
||||
GCLK_GENERATOR_7,
|
||||
TC_COUNTER_SIZE_8BIT,
|
||||
TC_CLOCK_PRESCALER_DIV16,
|
||||
TC_CLOCK_PRESCALER_DIV4,
|
||||
TC_WAVE_GENERATION_NORMAL_PWM,
|
||||
TC_RELOAD_ACTION_GCLK,
|
||||
TC_COUNT_DIRECTION_UP,
|
||||
|
@ -462,7 +470,7 @@ void telemetry_gpio1_pwm_init(void)
|
|||
false, /* Oneshot = false */
|
||||
false, /* Run in standby = false */
|
||||
0x0000, /* Initial value */
|
||||
GPIO1_PWM_STEPS, /* Top value */
|
||||
top, /* Top value */
|
||||
capture_channel_enables, /* Capture Channel Enables */
|
||||
compare_channel_values); /* Compare Channels Values */
|
||||
|
||||
|
@ -476,7 +484,6 @@ void telemetry_gpio1_pwm_init(void)
|
|||
|
||||
tc_enable(TC5);
|
||||
tc_start_counter(TC5);
|
||||
|
||||
}
|
||||
/**
|
||||
* Sets duty cycle on PWM pin
|
||||
|
|
|
@ -48,6 +48,7 @@ measurement_result_t _callback;
|
|||
* connects it to GLCK1.
|
||||
*/
|
||||
void xosc_init(void) {
|
||||
#ifdef USE_XOSC
|
||||
system_clock_source_xosc_set_config(SYSTEM_CLOCK_EXTERNAL_CLOCK,
|
||||
SYSTEM_XOSC_STARTUP_1,
|
||||
true,
|
||||
|
@ -57,12 +58,17 @@ void xosc_init(void) {
|
|||
system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC);
|
||||
|
||||
while (!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC));
|
||||
#endif
|
||||
|
||||
/* Configure GCLK1 to XOSC */
|
||||
system_gclk_gen_set_config(GCLK_GENERATOR_1,
|
||||
GCLK_SOURCE_XOSC, /* Source */
|
||||
#ifdef USE_XOSC
|
||||
GCLK_SOURCE_XOSC, /* Source */
|
||||
#else
|
||||
GCLK_SOURCE_OSC8M, /* Source */
|
||||
#endif
|
||||
false, /* High When Disabled */
|
||||
XOSC_GCLK1_DIVIDE,/* Division Factor */
|
||||
XOSC_GCLK1_DIVIDE, /* Division Factor */
|
||||
false, /* Run in standby */
|
||||
false); /* Output Pin Enable */
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue