kopia lustrzana https://github.com/bristol-seds/pico-tracker
Various aprs tidy / fix. Added useful resources list. Added telemetry terminate at end of packet
rodzic
5a5772499c
commit
0e14825de9
|
@ -5,7 +5,6 @@
|
||||||
|*GLCK*|
|
|*GLCK*|
|
||||||
||gclk0|main clock, internal osc8m|4 MHz
|
||gclk0|main clock, internal osc8m|4 MHz
|
||||||
||gclk1|tcxo clock, fed from xosc OR osc8m
|
||gclk1|tcxo clock, fed from xosc OR osc8m
|
||||||
|
|
|
||||||
||gclk7|aprs clock, fed from gclk1, div 6 / 11
|
||gclk7|aprs clock, fed from gclk1, div 6 / 11
|
||||||
|
|
||||||
|*TC*||
|
|*TC*||
|
||||||
|
|
|
@ -26,6 +26,6 @@
|
||||||
#define APRS_H
|
#define APRS_H
|
||||||
|
|
||||||
void aprs_init(void);
|
void aprs_init(void);
|
||||||
void aprs_tick(void);
|
uint8_t aprs_tick(void);
|
||||||
|
|
||||||
#endif /* APRS_H */
|
#endif /* APRS_H */
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
#define AX25_MARK_FREQ 1200
|
#define AX25_MARK_FREQ 1200
|
||||||
#define AX25_SPACE_FREQ 2200
|
#define AX25_SPACE_FREQ 2200
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GCLK division factors
|
||||||
|
*/
|
||||||
|
#define AX25_DIVISION_MARK 11
|
||||||
|
#define AX25_DIVISION_SPACE 6
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How often our handler gets called
|
* How often our handler gets called
|
||||||
*/
|
*/
|
||||||
|
@ -51,11 +57,12 @@
|
||||||
*/
|
*/
|
||||||
#define AX25_CONTROL_WORD 0x03 /* Use Unnumbered Information (UI) frames */
|
#define AX25_CONTROL_WORD 0x03 /* Use Unnumbered Information (UI) frames */
|
||||||
#define AX25_PROTOCOL_ID 0xF0 /* No third level protocol */
|
#define AX25_PROTOCOL_ID 0xF0 /* No third level protocol */
|
||||||
|
#define AX25_HDLC_FLAG 0x7E
|
||||||
|
|
||||||
enum ax25_symbol_t {
|
enum ax25_symbol_t {
|
||||||
AX25_MARK,
|
AX25_MARK,
|
||||||
AX25_SPACE,
|
AX25_SPACE,
|
||||||
|
AX25_NONE,
|
||||||
};
|
};
|
||||||
struct ax25_byte_t {
|
struct ax25_byte_t {
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
|
|
|
@ -28,6 +28,14 @@
|
||||||
#include "samd20.h"
|
#include "samd20.h"
|
||||||
#include "ax25.h"
|
#include "ax25.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USEFUL RESOURCES
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* http://www.aprs.org/doc/APRS101.PDF
|
||||||
|
* http://k9dci.home.comcast.net/~k9dci/APRS%20Beginner%20Guide%20-%20K9DCI%20Ver%205-1.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
char addresses[50];
|
char addresses[50];
|
||||||
|
|
||||||
void aprs_start(void)
|
void aprs_start(void)
|
||||||
|
@ -40,7 +48,7 @@ void aprs_start(void)
|
||||||
ax25_start(addresses, 21, "testtest", 8);
|
ax25_start(addresses, 21, "testtest", 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aprs_tick(void)
|
uint8_t aprs_tick(void)
|
||||||
{
|
{
|
||||||
ax25_tick();
|
return ax25_tick();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "samd20.h"
|
#include "samd20.h"
|
||||||
#include "system/gclk.h"
|
#include "system/gclk.h"
|
||||||
|
@ -46,6 +47,19 @@ uint32_t ax25_index, ax25_frame_length;
|
||||||
|
|
||||||
void ax25_gpio1_pwm_init(void);
|
void ax25_gpio1_pwm_init(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USEFUL RESOURCES
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* http://en.wikipedia.org/wiki/AX.25
|
||||||
|
* https://www.tapr.org/pub_ax25.html#2.4.1.2
|
||||||
|
* http://owenduffy.net/blog/?p=2101
|
||||||
|
* http://n1vg.net/packet/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frame Check Sequence (FCS)
|
* Frame Check Sequence (FCS)
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
|
@ -89,7 +103,7 @@ uint16_t crc_fcs(uint8_t *string, uint32_t length)
|
||||||
void ax25_start(char* addresses, uint32_t addresses_len,
|
void ax25_start(char* addresses, uint32_t addresses_len,
|
||||||
char* information, uint32_t information_len)
|
char* information, uint32_t information_len)
|
||||||
{
|
{
|
||||||
uint32_t i, j;
|
uint32_t i;
|
||||||
uint16_t fcs;
|
uint16_t fcs;
|
||||||
|
|
||||||
/* Process addresses */
|
/* Process addresses */
|
||||||
|
@ -140,7 +154,9 @@ void ax25_gpio1_pwm_init(void)
|
||||||
{
|
{
|
||||||
float gclk1_frequency = (float)system_gclk_gen_get_hz(1);
|
float gclk1_frequency = (float)system_gclk_gen_get_hz(1);
|
||||||
|
|
||||||
uint32_t top = 38;//(uint32_t)(gclk1_frequency / 13200.0*4);// & ~0x1;
|
float divide_needed = round(gclk1_frequency / (13200*4));
|
||||||
|
|
||||||
|
uint32_t top = (uint32_t)divide_needed & ~0x1;
|
||||||
uint32_t capture = top >> 1; /* 50% duty cycle */
|
uint32_t capture = top >> 1; /* 50% duty cycle */
|
||||||
|
|
||||||
if (top > 0xFF) while (1); // It's only an 8-bit counter
|
if (top > 0xFF) while (1); // It's only an 8-bit counter
|
||||||
|
@ -149,7 +165,7 @@ void ax25_gpio1_pwm_init(void)
|
||||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||||
false, /* High When Disabled */
|
false, /* High When Disabled */
|
||||||
11, /* Division Factor */// TODO
|
AX25_DIVISION_MARK,/* Division Factor */
|
||||||
false, /* Run in standby */
|
false, /* Run in standby */
|
||||||
false); /* Output Pin Enable */
|
false); /* Output Pin Enable */
|
||||||
system_gclk_gen_enable(GCLK_GENERATOR_7);
|
system_gclk_gen_enable(GCLK_GENERATOR_7);
|
||||||
|
@ -189,14 +205,13 @@ void ax25_gpio1_pwm_init(void)
|
||||||
/**
|
/**
|
||||||
* Returns the next byte to transmit
|
* Returns the next byte to transmit
|
||||||
*/
|
*/
|
||||||
struct ax25_byte_t ax25_get_next_byte(void) {
|
uint8_t ax25_get_next_byte(struct ax25_byte_t* next) {
|
||||||
|
|
||||||
/* Return HLDC flag by default */
|
|
||||||
struct ax25_byte_t next = { .val = 0x7E, .stuff = 0 };
|
|
||||||
|
|
||||||
switch (ax25_state) {
|
switch (ax25_state) {
|
||||||
case AX25_PREAMBLE: /* Preamble */
|
case AX25_PREAMBLE: /* Preamble */
|
||||||
/* Return flag by default*/
|
/* Return flag */
|
||||||
|
next->val = AX25_HDLC_FLAG;
|
||||||
|
next->stuff = 0;
|
||||||
|
|
||||||
/* Check for next state */
|
/* Check for next state */
|
||||||
ax25_index++;
|
ax25_index++;
|
||||||
|
@ -210,8 +225,8 @@ struct ax25_byte_t ax25_get_next_byte(void) {
|
||||||
|
|
||||||
case AX25_FRAME: /* Frame */
|
case AX25_FRAME: /* Frame */
|
||||||
/* Return data */
|
/* Return data */
|
||||||
next.val = ax25_frame[ax25_index];
|
next->val = ax25_frame[ax25_index];
|
||||||
next.stuff = 1;
|
next->stuff = 1;
|
||||||
|
|
||||||
/* Check for next state */
|
/* Check for next state */
|
||||||
ax25_index++;
|
ax25_index++;
|
||||||
|
@ -224,7 +239,9 @@ struct ax25_byte_t ax25_get_next_byte(void) {
|
||||||
|
|
||||||
|
|
||||||
case AX25_POSTAMBLE: /* Postamble */
|
case AX25_POSTAMBLE: /* Postamble */
|
||||||
/* Return flag by default */
|
/* Return flag */
|
||||||
|
next->val = AX25_HDLC_FLAG;
|
||||||
|
next->stuff = 0;
|
||||||
|
|
||||||
/* Check for next state */
|
/* Check for next state */
|
||||||
ax25_index++;
|
ax25_index++;
|
||||||
|
@ -237,29 +254,31 @@ struct ax25_byte_t ax25_get_next_byte(void) {
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return next;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next symbol to transmit
|
* Returns the next symbol to transmit
|
||||||
*/
|
*/
|
||||||
enum ax25_symbol_t ax25_get_next_symbol(void) {
|
enum ax25_symbol_t ax25_get_next_symbol(void)
|
||||||
|
{
|
||||||
uint8_t bit;
|
/* Get next byte if we need to */
|
||||||
|
|
||||||
if (bit_index >= 8) {
|
if (bit_index >= 8) {
|
||||||
current_byte = ax25_get_next_byte();
|
|
||||||
|
/* Attempt to get the next byte */
|
||||||
|
if (!ax25_get_next_byte(¤t_byte)) {
|
||||||
|
return AX25_NONE; /* We're done */
|
||||||
|
}
|
||||||
bit_index = 0;
|
bit_index = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transmit bits lsb first */
|
/* transmit bits lsb first */
|
||||||
bit = current_byte.val & 0x01;
|
if (current_byte.val & 0x01) { /* One */
|
||||||
|
|
||||||
if (bit) { /* One */
|
|
||||||
|
|
||||||
one_count++;
|
one_count++;
|
||||||
|
|
||||||
|
@ -293,30 +312,28 @@ enum ax25_symbol_t ax25_get_next_symbol(void) {
|
||||||
*/
|
*/
|
||||||
uint8_t ax25_tick(void)
|
uint8_t ax25_tick(void)
|
||||||
{
|
{
|
||||||
|
if (next_symbol == AX25_NONE) {
|
||||||
|
return 0; /* We're done */
|
||||||
|
}
|
||||||
|
|
||||||
if (next_symbol == AX25_SPACE) {
|
if (next_symbol == AX25_SPACE) {
|
||||||
|
/* Space */
|
||||||
|
|
||||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||||
false, /* High When Disabled */
|
false, /* High When Disabled */
|
||||||
6, /* Division Factor */// TODO
|
AX25_DIVISION_SPACE, /* Division Factor */
|
||||||
false, /* Run in standby */
|
false, /* Run in standby */
|
||||||
false); /* Output Pin Enable */
|
false); /* Output Pin Enable */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
/* Mark */
|
||||||
|
|
||||||
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
system_gclk_gen_set_config(GCLK_GENERATOR_7,
|
||||||
GCLK_SOURCE_GCLKGEN1, /* Source */
|
GCLK_SOURCE_GCLKGEN1, /* Source */
|
||||||
false, /* High When Disabled */
|
false, /* High When Disabled */
|
||||||
11, /* Division Factor */// TODO
|
AX25_DIVISION_MARK, /* Division Factor */
|
||||||
false, /* Run in standby */
|
false, /* Run in standby */
|
||||||
false); /* Output Pin Enable */
|
false); /* Output Pin Enable */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_symbol = ax25_get_next_symbol();
|
next_symbol = ax25_get_next_symbol();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,12 +323,16 @@ int main(void)
|
||||||
led_on();
|
led_on();
|
||||||
|
|
||||||
|
|
||||||
|
while (1) {
|
||||||
telemetry_start(TELEMETRY_APRS, 0xFFFF);
|
telemetry_start(TELEMETRY_APRS, 0xFFFF);
|
||||||
|
|
||||||
while (1) {
|
while (telemetry_active()) {
|
||||||
system_sleep();
|
system_sleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 1000*1000; i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -310,10 +310,15 @@ void telemetry_tick(void) {
|
||||||
/* APRS: We use pwm to control gpio1 */
|
/* APRS: We use pwm to control gpio1 */
|
||||||
aprs_start();
|
aprs_start();
|
||||||
|
|
||||||
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 200);
|
si_trx_on(SI_MODEM_MOD_TYPE_2GFSK, 400);
|
||||||
radio_on = 1;
|
radio_on = 1;
|
||||||
}
|
}
|
||||||
aprs_tick();
|
|
||||||
|
if (!aprs_tick()) {
|
||||||
|
/* Transmission Finished */
|
||||||
|
telemetry_stop();
|
||||||
|
if (is_telemetry_finished()) return;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue