Various aprs tidy / fix. Added useful resources list. Added telemetry terminate at end of packet

aprs_dev
Richard Meadows 2015-04-02 19:52:02 +01:00
rodzic 5a5772499c
commit 0e14825de9
7 zmienionych plików z 80 dodań i 40 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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