Working aprs test using square wave on gpio1 and 2gfsk

aprs_dev
Richard Meadows 2015-04-02 11:38:48 +01:00
rodzic e76e078914
commit 96248ed8b8
12 zmienionych plików z 451 dodań i 253 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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