Initial fork from MicroAPRS. Moved hardware definitions to m1284p. Implemented basic rx.

This commit is contained in:
Mark Qvist 2018-12-27 20:24:21 +01:00
parent d03564928b
commit 3fb4c30604
16 changed files with 109 additions and 4574 deletions

View File

@ -7,20 +7,15 @@
# customize the avrdude settings below first!
# Microcontroller Type
#MCU = atmega1284p
#MCU = atmega644p
MCU = atmega328p
MCU = atmega1284p
# Target file name (without extension).
TARGET = images/MicroAPRS
TARGET = images/OpenModem
# Programming hardware: type avrdude -c ?
# to get a full listing.
AVRDUDE_PROGRAMMER = arduino
AVRDUDE_PORT = /dev/usb # not really needed for usb
#AVRDUDE_PORT = /dev/parport0 # linux
# AVRDUDE_PORT = lpt1 # windows
############# Don't need to change below here for most purposes (Elliot)
@ -33,7 +28,7 @@ FORMAT = ihex
# List C source files here. (C dependencies are automatically generated.)
#SRC = $(TARGET).c
SRC = main.c hardware/Serial.c hardware/AFSK.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c protocol/SimpleSerial.c
SRC = main.c hardware/Serial.c hardware/AFSK.c util/CRC-CCIT.c protocol/AX25.c protocol/KISS.c
# If there is more than one source file, append them above, or modify and
# uncomment the following:

128
README.md
View File

@ -1,128 +1,2 @@
MicroAPRS
OpenModem Dev Repo
==========
MicroAPRS is an APRS firmware for [MicroModem](http://unsigned.io/micromodem). It supports both normal KISS mode, and a simple serial protocol for easy communication with an Arduino, or other MCU.
You can buy a complete modem from [my shop](http://unsigned.io/shop), or you can build one yourself pretty easily. Take a look at the documentation in the [MicroModem](https://github.com/markqvist/MicroModem) repository for information and getting started guides!
## Some features
- Send and receive AX.25 APRS packets
- Full modulation and demodulation in software
- Easy configuration of callsign and path settings
- Flexibility in how received packets are output over serial connection
- Persistent configuration stored in EEPROM
- Shorthand functions for sending location updates and messages, so you don't need to manually create the packets
- Ability to send raw packets
- Support for settings APRS symbols
- Support for power/height/gain info in location updates
- Ability to automatically ACK messages adressed to the modem
- Can run with open squelch
- Supports KISS mode for use with programs on a host computer
## KISS mode
When the modem is running in KISS mode, there's really not much more to it than connecting the modem to a computer, opening whatever program you want to use with it, and off you go.
When in KISS mode, the preamble time, tail time, persistence and slot time parameters can be configured by the default KISS commands for these. See KISS.h and KISS.c for more info on the configuration command syntax.
It's important to note that some programs (Xastir, for example) will reset the modem when connecting to it, and then immediately send configuration commands. Depending on your hardware, this might have the unfortunate effect that the configuration commands are sent to the bootloader, instead of the booted firmware. If your program does not allow you to disable resetting or to set a delay for sending the configuration commands, you can manually disable the reset functionality by connecting a resistor of around 100 ohms between the VCC and DTR pins. This will ensure that the modem is not reset, even if the host program sends a reset command.
## Modem control - SimpleSerial
If you want to use the SimpleSerial protocol, here's how to control the APRS modem over a serial connection. The modem accepts a variety of commands for setting options and sending packets. Generally a command starts with one or more characters defining the command, and then whatever data is needed to set the options for that command. Here's a list of the currently available commands:
## Serial commands
Command | Description
--- | :---
__!\<data>__ | Send raw packet
__@\<cmt>__ | Send location update (cmt = optional comment)
__#\<msg>__ | Send APRS message
&nbsp; | &nbsp;
__c\<call>__ | Set your callsign
__d\<call>__ | Set destination callsign
__1\<call>__ | Set PATH1 callsign
__2\<call>__ | Set PATH2 callsign
&nbsp; | &nbsp;
__sc\<ssid>__ | Set your SSID
__sd\<ssid>__ | Set destination SSID
__s1\<ssid>__ | Set PATH1 SSID
__s2\<ssid>__ | Set PATH2 SSID
&nbsp; | &nbsp;
__lla\<LAT>__ | Set latitude (NMEA-format, eg 4903.50N)
__llo\<LON>__ | Set latitude (NMEA-format, eg 07201.75W)
__lp\<0-9>__ | Set TX power info
__lh\<0-9>__ | Set antenna height info
__lg\<0-9>__ | Set antenna gain info
__ld\<0-9>__ | Set antenna directivity info
__ls\<sym>__ | Select symbol
__lt\<s/a>__ | Select symbol table (standard/alternate)
&nbsp; | &nbsp;
__mc\<call>__ | Set message recipient callsign
__ms\<ssid>__ | Set message recipient SSID
__mr\<ssid>__ | Retry last message
__ma\<1/0>__ | Automatic message ACK on/off
&nbsp; |&nbsp;
__ps\<1/0>__ | Print SRC on/off
__pd\<1/0>__ | Print DST on/off
__pp\<1/0>__ | Print PATH on/off
__pm\<1/0>__ | Print DATA on/off
__pi\<1/0>__ | Print INFO on/off
__v\<1/0>__ | Verbose mode on/off
__V\<1/0>__ | Silent mode on/off
&nbsp; | &nbsp;
__w\<XXX>__ | Set preamble in ms
__W\<XXX>__ | Set TX tail in ms
&nbsp; | &nbsp;
__S__ | Save configuration
__L__ | Load configuration
__C__ | Clear configuration
__H__ | Print configuration
### Examples
__To set your callsign to XX1YYY-5, and then save the configuration, send these three commands:__
```
cXX1YYY
sc5
S
```
__To send an APRS message to ZZ5ABC-1 with the content "Hi there!", send these commands:__
```
mcZZ5ABC
ms1
# Hi there!
```
__To send a location update, with the comment "MicroAPRS", you can do something like this:__
```
lla5230.70N
llo01043.70E
@MicroAPRS
```
__To send an APRS message to ZZ5ABC-1 with the content "Hi there!", using a raw packet, send this command:__
```
!:ZZ5ABC-1 :Hi there!{01
```
__Here's an example of how to send a location update with power, height and gain information, using a raw packet:__
```
!=5230.70N/01043.70E-PHG2410MicroAPRS
```
### EEPROM Settings
When saving the configuration, it is written to EEPROM, so it will persist between poweroffs. If a configuration has been stored, it will automatically be loaded when the modem powers up. The configuration can be cleared by sending the "clear configuration" command (`C`).
### Serial Connection
To connect to the modem use __9600 baud, 8N1__ serial. By default, the firmware uses time-sensitive input, which means that it will buffer serial data as it comes in, and when it has received no data for a few milliseconds, it will start interpreting whatever it has received. This means you need to set your serial terminal program to not send data for every keystroke, but only on new-line, or pressing send or whatever. If you do not want this behaviour, you can compile the firmware with the DEBUG flag set, which will make the modem wait for a new-line character before interpreting the received data. I would generally advise against this though, since it means that you cannot have newline characters in whatever data you want to send!
![MicroModem](https://unsigned.io/wp-content/uploads/2014/11/A1-1024x731.jpg)
The project has been implemented in your normal C with makefile style, and uses AVR Libc. The firmware is compatible with Arduino-based products, although it was not written in the Arduino IDE.
Visit [my site](http://unsigned.io) for questions, comments and other details.

View File

@ -4,42 +4,31 @@
#define DEVICE_CONFIGURATION
// CPU settings
#define TARGET_CPU m328p
#define F_CPU 16000000
#define TARGET_CPU m1284p
#define F_CPU 16000000UL
#define FREQUENCY_CORRECTION 0
// ADC settings
#define OPEN_SQUELCH true
#define ADC_REFERENCE REF_3V3
// OR
//#define ADC_REFERENCE REF_5V
// Sampling & timer setup
#define CONFIG_AFSK_DAC_SAMPLERATE 9600
// Serial protocol settings
#define SERIAL_PROTOCOL PROTOCOL_KISS
// OR
//#define SERIAL_PROTOCOL PROTOCOL_SIMPLE_SERIAL
// AX25 settings
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
#define CUSTOM_FRAME_SIZE 330
#endif
#define CONFIG_SAMPLERATE 19200UL
//#define CONFIG_SAMPLERATE 9600
// Serial settings
#define BAUD 9600
#define BAUD 115200
#define SERIAL_DEBUG false
#define TX_MAXWAIT 2UL
// Port settings
#if TARGET_CPU == m328p
#define DAC_PORT PORTD
#define DAC_DDR DDRD
#define LED_PORT PORTB
#define LED_DDR DDRB
#define ADC_PORT PORTC
#define ADC_DDR DDRC
#if TARGET_CPU == m1284p
#define ADC_PORT PORTA
#define ADC_DDR DDRA
#define DAC_PORT PORTB
#define DAC_DDR DDRB
#define LED_PORT PORTC
#define LED_DDR DDRC
#endif
#endif

View File

@ -2,6 +2,11 @@
#include "AFSK.h"
#include "util/time.h"
// TODO: Remove testing vars
#define SAMPLES_TO_CAPTURE 128
ticks_t capturedsamples = 0;
uint8_t samplebuf[SAMPLES_TO_CAPTURE];
extern volatile ticks_t _clock;
extern unsigned long custom_preamble;
extern unsigned long custom_tail;
@ -14,43 +19,51 @@ Afsk *AFSK_modem;
int afsk_getchar(FILE *strem);
int afsk_putchar(char c, FILE *stream);
void AFSK_hw_refDetect(void) {
// This is manual for now
#if ADC_REFERENCE == REF_5V
hw_5v_ref = true;
#else
hw_5v_ref = false;
#endif
}
// ADC and clock setup
void AFSK_hw_init(void) {
// Set up ADC
AFSK_hw_refDetect();
// Set Timer1 to normal operation
TCCR1A = 0;
TCCR1B = _BV(CS10) | _BV(WGM13) | _BV(WGM12);
ICR1 = (((CPU_FREQ+FREQUENCY_CORRECTION)) / 9600) - 1;
if (hw_5v_ref) {
ADMUX = _BV(REFS0) | 0;
} else {
ADMUX = 0;
}
TCCR1B = _BV(WGM13) | // Enable Timer1 Waveform Generation Mode 12:
_BV(WGM12) | // Mode = CTC, TOP = ICR1
_BV(CS10); // Set clock source to 0b001 = System clock without prescaling
ADC_DDR &= ~_BV(0);
ADC_PORT &= ~_BV(0);
// Set ICR1 register to the amount of ticks needed between
// each sample capture/synthesis
ICR1 = TICKS_BETWEEN_SAMPLES;
// Set ADMUX register to use external AREF, channel ADC0
// and left adjust result
ADMUX = _BV(ADLAR) | 0;
// Set ADC port directions and outputs
// TODO: Check this
ADC_DDR &= ~_BV(0); // 0b11111110 - All pins are outputs, except ADC0
ADC_PORT &= 0x00; // 0b00000000 - All pins are at GND level
// Set Digital Input Disable Register mask to 0b00000001,
// which disables the input buffer on ADC0 pin to avoid
// current through the pin.
DIDR0 |= _BV(0);
ADCSRB = _BV(ADTS2) |
_BV(ADTS1) |
_BV(ADTS0);
ADCSRA = _BV(ADEN) |
_BV(ADSC) |
_BV(ADATE)|
_BV(ADIE) |
_BV(ADPS2);
_BV(ADTS0); // Set ADC Trigger Source to 0b111 = Timer1 Capture Event
ADCSRA = _BV(ADEN) | // ADC Enable
_BV(ADSC) | // ADC Start Conversion
_BV(ADATE)| // ADC Interrupt Flag
_BV(ADIE) | // ADC Interrupt Enable
_BV(ADPS0)|
_BV(ADPS2); // Set ADC prescaler bits to 0b101 = 32
// At 16MHz, this gives an ADC clock of 500 KHz
// Run DAC initialisation
AFSK_DAC_INIT();
// Run LED initialisation
LED_TX_INIT();
LED_RX_INIT();
}
@ -536,11 +549,33 @@ void AFSK_adc_isr(Afsk *afsk, int8_t currentSample) {
ISR(ADC_vect) {
TIFR1 = _BV(ICF1);
AFSK_adc_isr(AFSK_modem, ((int16_t)((ADC) >> 2) - 128));
AFSK_adc_isr(AFSK_modem, (ADCH - 128));
if (hw_afsk_dac_isr) {
DAC_PORT = (AFSK_dac_isr(AFSK_modem) & 0xF0) | _BV(3);
DAC_PORT = AFSK_dac_isr(AFSK_modem);
LED_TX_ON();
} else {
DAC_PORT = 128;
}
++_clock;
/*
// TODO: Remove these debug sample collection functions
if (capturedsamples == SAMPLES_TO_CAPTURE) {
printf("--- Dumping samples ---");
for (ticks_t i = 0; i < SAMPLES_TO_CAPTURE; i++) {
uint8_t c = samplebuf[i];
printf("%d\r\n", c);
}
printf("-------- Done ---------");
}
DAC_PORT ^= 0xFF;
if (capturedsamples < SAMPLES_TO_CAPTURE) {
samplebuf[capturedsamples++] = ADCH;
// Clear Input Capture Flag from Timer1 Interrupt Flag Register
// to allow for next capture interrupt to occur
TIFR1 = _BV(ICF1);
}
*/
}

View File

@ -47,10 +47,9 @@ inline static uint8_t sinSample(uint16_t i) {
#define CONFIG_AFSK_TRAILER_LEN 50UL
#define BIT_STUFF_LEN 5
#define SAMPLERATE 9600
#define BITRATE 1200
#define SAMPLESPERBIT (SAMPLERATE / BITRATE)
#define SAMPLESPERBIT (CONFIG_SAMPLERATE / BITRATE)
#define TICKS_BETWEEN_SAMPLES ((((CPU_FREQ+FREQUENCY_CORRECTION)) / CONFIG_SAMPLERATE) - 1)
#define PHASE_INC 1 // Nudge by an eigth of a sample each adjustment
#define DCD_MIN_COUNT 6
@ -136,12 +135,15 @@ typedef struct Afsk
} Afsk;
#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
#define MARK_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
#define SPACE_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_AFSK_DAC_SAMPLERATE))
#define MARK_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)MARK_FREQ, CONFIG_SAMPLERATE))
#define SPACE_INC (uint16_t)(DIV_ROUND(SIN_LEN * (uint32_t)SPACE_FREQ, CONFIG_SAMPLERATE))
#define AFSK_DAC_IRQ_START() do { extern bool hw_afsk_dac_isr; hw_afsk_dac_isr = true; } while (0)
#define AFSK_DAC_IRQ_STOP() do { extern bool hw_afsk_dac_isr; hw_afsk_dac_isr = false; } while (0)
#define AFSK_DAC_INIT() do { DAC_DDR |= 0xF8; } while (0)
// DAC uses all 8 pins of one port, set all pins to
// output direction
#define AFSK_DAC_INIT() do { DAC_DDR |= 0xFF; } while (0)
// Here's some macros for controlling the RX/TX LEDs
// THE _INIT() functions writes to the DDRB register

77
main.c
View File

@ -7,59 +7,33 @@
#include "hardware/AFSK.h"
#include "hardware/Serial.h"
#include "protocol/AX25.h"
#if SERIAL_PROTOCOL == PROTOCOL_KISS
#include "protocol/KISS.h"
#endif
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
#include "protocol/SimpleSerial.h"
#endif
Serial serial;
Afsk modem;
AX25Ctx AX25;
#if SERIAL_PROTOCOL == PROTOCOL_KISS
static void ax25_callback(struct AX25Ctx *ctx) {
kiss_messageCallback(ctx);
}
#endif
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
static uint8_t serialBuffer[AX25_MAX_FRAME_LEN+1];
static int sbyte;
static size_t serialLen = 0;
static bool sertx = false;
static void ax25_callback(struct AX25Msg *msg) {
ss_messageCallback(msg);
}
#endif
void init(void) {
sei();
AFSK_init(&modem);
ax25_init(&AX25, &modem, &modem.fd, ax25_callback);
// TODO: serial init was last before
serial_init(&serial);
stdout = &serial.uart0;
stdin = &serial.uart0;
#if SERIAL_PROTOCOL == PROTOCOL_KISS
kiss_init(&AX25, &modem, &serial);
#endif
AFSK_init(&modem);
ax25_init(&AX25, &modem, &modem.fd, ax25_callback);
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
ss_init(&AX25);
#endif
kiss_init(&AX25, &modem, &serial);
}
int main (void) {
init();
#if SERIAL_PROTOCOL == PROTOCOL_KISS
while (true) {
ax25_poll(&AX25);
@ -68,49 +42,6 @@ int main (void) {
kiss_serialCallback(sbyte);
}
}
#endif
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
ticks_t start = timer_clock();
while (1) {
ax25_poll(&AX25);
if (!sertx && serial_available(0)) {
sbyte = uart0_getchar_nowait();
#if SERIAL_DEBUG
if ((serialLen < AX25_MAX_FRAME_LEN) && (sbyte != 10)) {
serialBuffer[serialLen] = sbyte;
serialLen++;
} else {
sertx = true;
}
#else
if (serialLen < AX25_MAX_FRAME_LEN-1) {
serialBuffer[serialLen] = sbyte;
serialLen++;
} else {
serialBuffer[serialLen] = sbyte;
serialLen++;
sertx = true;
}
start = timer_clock();
#endif
} else {
if (!SERIAL_DEBUG && serialLen > 0 && timer_clock() - start > ms_to_ticks(TX_MAXWAIT)) {
sertx = true;
}
}
if (sertx) {
ss_serialCallback(serialBuffer, serialLen, &AX25);
sertx = false;
serialLen = 0;
}
}
#endif
return(0);
}

View File

@ -1,378 +0,0 @@
:100000000C9474010C9491010C9491010C94910145
:100010000C9491010C9491010C9491010C94910118
:100020000C9491010C9491010C9491010C94910108
:100030000C9491010C9491010C9491010C949101F8
:100040000C9491010C9491010C9491010C949101E8
:100050000C9491010C94F4060C9491010C94910170
:100060000C9491010C949101808183848687898A04
:100070008C8E8F9192949597989A9B9D9EA0A2A307
:10008000A5A6A7A9AAACADAFB0B2B3B5B6B7B9BA79
:10009000BCBDBEC0C1C2C4C5C6C8C9CACBCDCECF07
:1000A000D0D2D3D4D5D6D7D9DADBDCDDDEDFE0E1C0
:1000B000E2E3E4E5E6E7E8E9EAEAEBECEDEEEEEFB1
:1000C000F0F1F1F2F3F3F4F5F5F6F6F7F8F8F9F9E3
:1000D000FAFAFAFBFBFCFCFCFDFDFDFDFEFEFEFE5C
:1000E000FEFFFFFFFFFFFFFF0000891112239B327D
:1000F0002446AD573665BF74488CC19D5AAFD3BEF8
:100100006CCAE5DB7EE9F7F88110080193331A2207
:10011000A5562C47B7753E64C99C408DDBBF52AED7
:10012000EDDA64CBFFF976E802218B3010029913E7
:100130002667AF763444BD554AADC3BC588ED19FB7
:100140006EEBE7FA7CC8F5D983310A2091121803C7
:10015000A7772E66B5543C45CBBD42ACD99E508F97
:10016000EFFB66EAFDD874C904428D5316619F7097
:100170002004A9153227BB364CCEC5DF5EEDD7FC77
:100180006888E1997AABF3BA85520C4397711E6087
:10019000A1142805B3373A26CDDE44CFDFFD56EC57
:1001A000E9986089FBBB72AA06638F7214409D5167
:1001B0002225AB343006B9174EEFC7FE5CCCD5DD37
:1001C0006AA9E3B8788AF19B87730E6295501C4147
:1001D000A3352A24B1163807CFFF46EEDDDC54CD17
:1001E000EBB962A8F99A708B088481951AA793B627
:1001F0002CC2A5D33EE1B7F04008C919522BDB3A17
:10020000644EED5F766DFF7C899400859BB712A6E6
:10021000ADD224C3BFF136E0C1184809D33B5A2AF6
:10022000E55E6C4FF77D7E6C0AA583B418869197C6
:100230002EE3A7F23CC0B5D14229CB38500AD91BD6
:10024000666FEF7E744CFD5D8BB502A499961087A6
:10025000AFF326E2BDD034C1C3394A28D11A580BB6
:10026000E77F6E6EF55C7C4D0CC685D71EE597F476
:100270002880A1913AA3B3B2444ACD5B5669DF7896
:10028000600CE91D722FFB3E8DD604C79FF516E466
:10029000A9902081BBB332A2C55A4C4BD7795E6876
:1002A000E11C680DF33F7A2E0EE787F61CC495D546
:1002B0002AA1A3B03882B193466BCF7A5448DD5956
:1002C000622DEB3C700EF91F8FF706E69DD414C526
:1002D000ABB122A0B9923083C77B4E6AD5585C4936
:1002E000E33D6A2CF11E780F11241FBECFEFD8E03A
:1002F000DEBFCDBF11E0A0E0B1E0EAE6F7E102C069
:1003000005900D92A231B107D9F718E0A2E1B1E052
:1003100001C01D92A434B107E1F70E946E0A0C944B
:10032000B30B0C9400000C94C40878948CE294E015
:100330000E94100323E931E04CE254E0BA018CE062
:1003400095E00E948D078EEF94E00E94C701EEE3D6
:10035000F8E08EEF94E09383828391838083AC01F5
:100360006CE274E08CE095E00C94B5089091C000CC
:1003700095FFFCCF8093C60081E090E008958091C6
:10038000C00087FFFCCF8091C60090E00895CF9316
:10039000DF93CDB7DEB72E970FB6F894DEBF0FBE52
:1003A000CDBFDC018EE0FD01982F11929A95E9F7FF
:1003B0001092C50097E69093C400E0ECF0E09081C5
:1003C0009D7F908396E09093C20098E19093C10046
:1003D0009E012F5F3F4FF90111928A95E9F783E063
:1003E0008C8386EB91E09A8789878FEB91E09C87DD
:1003F0008B879EE0F90101900D929A95E1F72E9678
:100400000FB6F894DEBF0FBECDBFDF91CF91089538
:10041000811106C08091C000881F8827881F089519
:1004200080E008958091C00087FF03C08091C600DE
:1004300008958FEF08950F931F93CF93DF93182F95
:10044000C0913308D0913408FE01E659FF4F8081F6
:10045000811126C080E490E098A38F8F1E8E1D8EA0
:100460001C8E01E0008331960083299A20910901B6
:1004700030910A0140910B0150910C01A0EBB4E0C6
:100480000E948D0A6056704F8F4F9F4F20E43FE1CE
:1004900040E050E00E94980A3D8B2C8B00931301A2
:1004A0000FB7F894209105013091060140910701A2
:1004B00050910801A0EBB4E00E948D0A6056704F85
:1004C0008F4F9F4F20E43FE140E050E00E94980AA8
:1004D0003F8B2E8B0FBFE0913308F09134084FB75C
:1004E000F89426A137A182A193A12817390739F4DE
:1004F00020A531A584A195A12817390779F060A519
:1005000071A526A137A12150310991E080E0621741
:10051000730709F090E0292F382F02C021E030E066
:100520004FBF232BC1F6E0913308F09134082FB769
:10053000F894A0A5B1A51C9340A551A584A195A1AF
:100540004817590719F482A193A103C080A591A56A
:10055000019691A780A72FBF81E090E0DF91CF9116
:100560001F910F910895E0913308F09134084FB72F
:10057000F894E758FF4F24813581868197814FBFDA
:1005800028173907E9F0E0913308F09134089FB754
:10059000F894E758FF4FA481B58122813381A217D7
:1005A000B30719F42081318105C0A481B5819D0173
:1005B0002F5F3F4F358324838C919FBF90E0089538
:1005C0008FEF9FEF0895109212010895109212017B
:1005D0001092800089E18093810081E896E09093F9
:1005E00087008093860080911201882321F080E4A7
:1005F00080937C0002C010927C00389840988091D3
:100600007E00816080937E0087E080937B008CEE8B
:1006100080937A008AB1886F8AB9219A229A0895C4
:100620000F931F93CF93DF93CDB7DEB72E970FB6FF
:10063000F894DEBF0FBECDBF8C018EECD8011D92A9
:100640008A95E9F7109334080093330880E490E02A
:10065000F80190A3878F11A2C8018C589F4FE459CD
:10066000FF4F918380839783868395838483049649
:10067000938382830996D801A758BF4F11969C9304
:100680008E9317969C938E93169715969C938E93A4
:100690001497CF9613969C938E931297865991092F
:1006A000D80193969C938E93929799969C938E9350
:1006B000989797969C938E939697CF9695969C93A2
:1006C0008E93949784E090E0A681B7811C92468136
:1006D0005781228133814217530719F420813181D8
:1006E00004C0268137812F5F3F4F378326830197D0
:1006F00059F70E94E6028EE0FE013196DF01982F45
:100700001D929A95E9F793E09C832BE132E03A87BA
:10071000298723EB32E03C872B87D80101900D928B
:100720008A95E1F72E960FB6F894DEBF0FBECDBFC7
:10073000DF91CF911F910F9108950F931F93CF9346
:10074000DF93E0913308F091340820A531A537A359
:1007500026A3EC018C01060F171FC017D10731F03B
:1007600060E070E089910E941B02F7CFDF91CF918A
:100770001F910F910895DC0158968C915897811123
:10078000F8C05A968C915A978111AEC096964D91A9
:100790005C91979798962D913C91999742175307A2
:1007A00079F456962D913C915797232B49F410924A
:1007B0001301FD01E659FF4F1082A559BF4F68C0D4
:1007C0005B969C915B97911103C05C961C925C9721
:1007D00091E05B969C935B9754962D913C91559735
:1007E00021153105B9F596964D915C91979798969C
:1007F0002D913C9199974217530779F4FD01E559E2
:10080000FF4F108256962D913C91579721503109F8
:1008100057963C932E93569723C09696ED91FC9154
:10082000979794962D913C919597E217F30729F4A9
:1008300092962D913C91939707C09696ED91FC91DD
:1008400097979F012F5F3F4F97963C932E939697D4
:10085000908107C02150310955963C932E935497AF
:100860009EE759969C93599759969C9159979B311D
:1008700089F596964D915C91979798962D913C911C
:1008800099974217530739F410921301A659BF4F95
:100890001C92299808959696ED91FC9197979496BD
:1008A0008D919C919597E817F90729F492968D916F
:1008B0009C91939706C09696ED91FC919797CF01E6
:1008C000019697969C938E939697808159968C93D8
:1008D000599706C09E57923018F45B961C925B970E
:1008E00081E05A968C935A975B968C915B975F96B2
:1008F0002D913C9190978823A9F05C968C915C9700
:10090000853080F05C961C925C972034310519F09C
:1009100080E490E002C085E790E090969C938E93EF
:100920005F9723C05A968C915A9759969C915997E4
:10093000982341F05C969C915C979F5F5C969C939A
:100940005C970FC05C961C925C972034310519F0BF
:1009500020E430E002C025E730E090963C932E93EF
:100960005F97880F5A968C935A9788E058968C9385
:1009700058975F96ED91FC9190975D968D919C9123
:100980005E97E80FF91F9F0131705E963C932E939E
:100990005D9758968C915897815058968C93FF2765
:1009A000E038F10530F08FEF90E0AC014E1B5F0BAB
:1009B000FA01E859FF4F84912F3F310511F008F0FB
:1009C00080950895EF92FF920F931F93CF93DF933B
:1009D000FC018C010D531F4FD8014D915C91119773
:1009E000129711965C934E93A555B10914968D916B
:1009F0009C91159712962D913C911397821793070E
:100A000021F42D913C91119707C014968D919C91E2
:100A100015979C012F5F3F4F15963C932E9314978B
:100A2000EC012881260290011124C9019595879532
:100A300095958795E801998388837F01D7ECED0E22
:100A4000F11CE701288139818F010B531F4FE80109
:100A500039832883840F951F35952795820F931F1F
:100A6000E70199838883AF0147535F4F21E0181650
:100A700019060CF420E0EA018881880F822B888314
:100A800016968D919C911797EC01688316962D917F
:100A90003C91179712968D919C91139728173907BF
:100AA00021F48D919C91119705C016968D919C9182
:100AB0001797019617969C938E931697DA018C914F
:100AC000982F9695969589278370DF01A653BF4F7F
:100AD000833049F48C91803214F48F5F01C08150CF
:100AE0008C9311A203C081A18F5F81A38C91885F39
:100AF000803414F48C936BC18F738C93DF01A553F6
:100B0000BF4F8C91880F8C93EA01988197702BEFDF
:100B1000290F233010F0933011F481608C938C9165
:100B2000982F96958927809581709685990F892BA6
:100B300086878E3709F052C0DF01A758BF4F149641
:100B40002D913C9115978D919C91119728173907FC
:100B500059F416962D913C91179712968D919C9170
:100B6000139728173907B1F116962D913C911797D5
:100B700014968D919C91159701972817390751F17B
:100B80001696CD91DC9117978EE7888316962D9156
:100B90003C91179712968D919C91139728173907BE
:100BA00021F48D919C91119705C016968D919C9181
:100BB0001797019617969C938E93169791E0918BB9
:100BC0008389863020F4128A8F5F838B01C0928BD9
:100BD00081E0BFC0118A128A138ABAC08F778F371B
:100BE00011F4118A09C08289882311F02A9A01C060
:100BF0002A988189811103C0128A138AE8C08685E8
:100C0000982F9F739E3309F4E2C080FF03C0808950
:100C10008068808B97859F5F97878089983008F4DC
:100C20009DC0DF01A758BF4F92E8980F923018F08F
:100C30008B3109F046C014962D913C9115978D91FA
:100C40009C9111972817390759F416962D913C91CC
:100C5000179712968D919C9113972817390759F180
:100C600016962D913C91179714968D919C911597FE
:100C7000019728173907F9F01696CD91DC9117974F
:100C80008BE1888316962D913C91179712968D9142
:100C90009C9113972817390721F48D919C911197F6
:100CA00005C016968D919C911797019617969C9367
:100CB0008E93169706C0118A128A138A2A9880E0AA
:100CC00001C081E014964D915C9115972D913C9156
:100CD00011974217530759F416964D915C91179747
:100CE00012962D913C9113974217530769F116966E
:100CF0004D915C91179714962D913C911597215029
:100D000031094217530701F190891696CD91DC9174
:100D10001797988316964D915C91179712962D917F
:100D20003C9113974217530721F42D913C91119751
:100D300006C016962D913C9117972F5F3F4F17963F
:100D40003C932E93169705C0118A128A138A2A980B
:100D500080E0108A1786882321F039C08695808B21
:100D600036C0EF01C453DF4F888199818160998338
:100D70008883DF01A758BF4F14962D913C9115979A
:100D80008D919C9111972817390759F416962D913A
:100D90003C91179712968D919C91139728173907BC
:100DA00061F016962D913C91179714968D919C9118
:100DB000159701972817390751F416968D919C9134
:100DC000179715969C938E9314971982188281A178
:100DD000813618F011A2128A2A98DF91CF911F91C3
:100DE0000F91FF90EF9008951F920F920FB60F9200
:100DF00011242F933F934F935F936F937F938F9320
:100E00009F93AF93BF93EF93FF9380E286BB609174
:100E1000780070917900769567957695679560581A
:100E200080913308909134080E94E204809113016C
:100E3000882349F080913308909134080E94BB03C5
:100E4000807F886001C080E88BB98091FA0490911E
:100E5000FB04A091FC04B091FD040196A11DB11DFD
:100E60008093FA049093FB04A093FC04B093FD04D8
:100E7000FF91EF91BF91AF919F918F917F916F9172
:100E80005F914F913F912F910F900FBE0F901F9048
:100E90001895CF92DF92EF92FF920F931F93CF930B
:100EA000DF931F92CDB7DEB77C01262F82E8860F35
:100EB0008701065E1C4F823010F06B3149F4F80157
:100EC000608171818BE190E029830E94540B29811C
:100ED000D701A05EBC4F3C9111964C911197822F87
:100EE00090E0FC01E327EE0FFF1FE851FF4F259133
:100EF0003491C42ED12C2C253D252D933C93F80103
:100F0000608171810F90DF91CF911F910F91FF90C0
:100F1000EF90DF90CF900C94540BCF93DF93E7E2E8
:100F2000F3E0DC01EF011D922197E9F7FC01E65E99
:100F3000FC4F518340833297718360833A963183AB
:100F4000208332972FEF3FEF318320833297318315
:100F50002083389681E08083DF91CF9108953F927E
:100F60004F925F926F927F928F929F92AF92BF92B9
:100F7000CF92DF92EF92FF920F931F93CF93DF9365
:100F80002C013C0126EE621A2CEF720A6C014BED2B
:100F9000C41A4CEFD40AEC01CC5DDC4F8C01045E2A
:100FA0001C4F7C0182EEE81A8CEFF80A332433944C
:100FB000AA24AA94BA2C4201AEED8A1AACEF9A0A7E
:100FC000F301808191810E94160B8F3FFFEF9F07F5
:100FD00009F459C0F6012081211129C08E379105ED
:100FE000D9F4D8018D919C91429770F0F7018081DE
:100FF0009181883B904F41F42A9AD401ED91FC9164
:10100000309711F0C20109953882F701B182A082B0
:10101000D8011D921C92D4CF8F37910511F41882FC
:10102000CFCF8B31910519F4F6013082C9CF2881D9
:10103000222331F1D8012D913C912831B3E03B07B7
:10104000F0F4A9014F5F5F4FF80151834083F20133
:10105000E20FF31F8083D7012D913C91F901E8271E
:10106000FF27EE0FFF1FE851FF4F85919491232F2B
:10107000332782279327F7019183808301C0188249
:10108000D6011C929DCFDF91CF911F910F91FF90C0
:10109000EF90DF90CF90BF90AF909F908F907F9018
:1010A0006F905F904F903F9008956F927F928F92D4
:1010B0009F92AF92BF92CF92DF92EF92FF920F93E7
:1010C0001F93CF93DF93EC013B014A017C018AED32
:1010D000E81A8CEFF80AF70110825E01F0EEAF1A01
:1010E000FCEFBF0A8FEF9FEFF501918380836E01C4
:1010F000F6EECF1AFCEFDF0AF601608171818EE710
:1011000090E00E94540B8301860C971C081519056A
:1011100039F0F80161918F01CE010E944907F6CFA5
:10112000F501608111816095CE010E944907612F10
:101130006095CE010E944907F601608171818EE7BA
:1011400090E00E94540B81E0F7018083DF91CF9102
:101150001F910F91FF90EF90DF90CF90BF90AF90D5
:101160009F908F907F906F90089590933808809310
:1011700037085093FF044093FE0470933A0860933D
:101180003908109236080895EF92FF920F931F933B
:10119000CF93DF93EC016091FE047091FF0480EC2B
:1011A00090E00E94540B6091FE047091FF0480E077
:1011B00090E00E94540B8E017E0184EEE81A8CEFC1
:1011C000F80AF70120813181225031096091FE0433
:1011D0007091FF04C8018C1B9D0B8217930708F5C3
:1011E000F80181918F01803C59F48BED90E00E94D1
:1011F000540B6091FE047091FF048CED90E00EC0E2
:101200008B3D59F48BED90E00E94540B6091FE04ED
:101210007091FF048DED90E001C090E00E94540BAE
:10122000D0CF80EC90E0DF91CF911F910F91FF9094
:10123000EF900C94540B4F925F926F927F928F922B
:101240009F92AF92BF92EF92FF920F931F93CF9313
:10125000DF93EC018B017A01E0913908F0913A08B3
:101260008289811138C00E94060B90910001891774
:1012700030F4A701B801CE010E94550846C08FB7CF
:10128000F8948090FA049090FB04A090FC04B09035
:10129000FD048FBF209101013091020140910301B3
:1012A00050910401AAE0B0E00E948D0A2FB7F89493
:1012B0004090FA045090FB046090FC047090FD0490
:1012C0002FBF481859086A087B0846165706680653
:1012D000790664F3C1CFE0913908F0913A08818929
:1012E000882309F4B9CF80913708909138080E947B
:1012F000AF07E0913908F0913A08E453FF4F80813D
:101300009181892B41F311821082809136088823C4
:10131000A1F1CA5DDC4F8881811101C0FFCF6091CE
:10132000FE047091FF0480EC90E00E94540B6091E9
:10133000FE047091FF048FE090E00E94540B6091D6
:10134000FE047091FF0481E090E00E94540B6091D4
:10135000FE047091FF0480EC90E0DF91CF911F912B
:101360000F91FF90EF90BF90AF909F908F907F90E4
:101370006F905F904F900C94540BDF91CF911F9121
:101380000F91FF90EF90BF90AF909F908F907F90C4
:101390006F905F904F90089590913B089923A1F032
:1013A000803C01F580910D01811111C010923B0824
:1013B00040913C0850913D0864E171E0809137080C
:1013C000909138080C941B09803C09F086C081E09C
:1013D00080933B088EEF80930D0110923D08109290
:1013E0003C08089520913C0830913D08283193E055
:1013F000390708F072C090910D012115310531F4C3
:101400009E3F21F48F7080930D01089591111FC0AC
:101410008B3D21F481E08093350808959091350843
:10142000992349F08C3D21F08D3D19F48BED01C0DD
:1014300080EC10923508A9014F5F5F4F50933D0833
:1014400040933C08F901EC5EFE4F80830895913093
:1014500079F4282F30E0AAE0B0E00E947E0A609381
:10146000090170930A0180930B0190930C01089578
:10147000943089F42AE0829FC0011124AA2797FDA5
:10148000A095BA2F8093050190930601A0930701C0
:10149000B09308010895933089F42AE0829FC00137
:1014A0001124AA2797FDA095BA2F8093010190934C
:1014B0000201A0930301B09304010895923019F43E
:1014C0008093000108959F3041F4811103C0109270
:1014D0003608089581E08093360808950E949501AA
:1014E0008CE095E00E94AF0780E00E94080288230C
:1014F000B9F30E9412020E94CC09F2CFA29FB00160
:10150000B39FC001A39F700D811D1124911DB29F37
:10151000700D811D1124911D08950E947E0AA59FC2
:10152000900DB49F900DA49F800D911D11240895DE
:10153000A1E21A2EAA1BBB1BFD010DC0AA1FBB1FD7
:10154000EE1FFF1FA217B307E407F50720F0A21B49
:10155000B30BE40BF50B661F771F881F991F1A94B6
:1015600069F760957095809590959B01AC01BD01E0
:10157000CF0108958F929F92AF92BF92CF92DF9248
:10158000EF92FF92CF93DF93EC01688179818A819A
:101590009B81611571058105910521F464E279ED66
:1015A0008BE597E02DE133EF41E050E00E94940B92
:1015B00049015A019B01AC01A7EAB1E40E948D0ADE
:1015C0006B017C01ACEEB4EFA50194010E948F0B7E
:1015D000DC01CB018C0D9D1DAE1DBF1DB7FF03C0EF
:1015E0000197A109B04888839983AA83BB839F7719
:1015F000DF91CF91FF90EF90DF90CF90BF90AF90B1
:101600009F908F9008950E94BA0A08958EE091E00D
:101610000E94BA0A0895A0E0B0E080930E01909372
:101620000F01A0931001B09311010895CF93DF93A0
:10163000EC012B8120FF33C026FF0AC02F7B2B83B8
:101640008E819F8101969F838E838A8190E029C03D
:1016500022FF0FC0E881F9818081992787FD90954D
:10166000009719F420622B831AC03196F983E8831E
:101670000EC0EA85FB85099597FF09C02B8101966D
:1016800011F080E201C080E1822B8B8308C02E81A3
:101690003F812F5F3F4F3F832E83992702C08FEFFB
:1016A0009FEFDF91CF9108950F931F93CF93DF9317
:1016B000FB01238121FD03C08FEF9FEF28C022FF94
:1016C00016C046815781248135814217530744F45F
:1016D000A081B1819D012F5F3F4F318320838C9387
:1016E000268137812F5F3F4F3783268310C0EB0160
:1016F000092F182F0084F185E02D0995892BE1F63B
:101700008E819F8101969F838E83812F902FDF9101
:10171000CF911F910F910895B7FF0C948D0A0E94ED
:101720008D0A821B930B0895052E97FB1EF40094DF
:101730000E94AB0B57FD07D00E94980A07FC03D00C
:101740004EF40C94AB0B50954095309521953F4F3E
:101750004F4F5F4F089590958095709561957F4F9D
:0A1760008F4F9F4F0895F894FFCFBC
:10176A003FC8000000320000005E010000FE0100D8
:02177A0000006D
:00000001FF

File diff suppressed because it is too large Load Diff

View File

@ -1,378 +0,0 @@
:100000000C9474010C9491010C9491010C94910145
:100010000C9491010C9491010C9491010C94910118
:100020000C9491010C9491010C9491010C94910108
:100030000C9491010C9491010C9491010C949101F8
:100040000C9491010C9491010C9491010C949101E8
:100050000C9491010C94F6060C9491010C9491016E
:100060000C9491010C949101808183848687898A04
:100070008C8E8F9192949597989A9B9D9EA0A2A307
:10008000A5A6A7A9AAACADAFB0B2B3B5B6B7B9BA79
:10009000BCBDBEC0C1C2C4C5C6C8C9CACBCDCECF07
:1000A000D0D2D3D4D5D6D7D9DADBDCDDDEDFE0E1C0
:1000B000E2E3E4E5E6E7E8E9EAEAEBECEDEEEEEFB1
:1000C000F0F1F1F2F3F3F4F5F5F6F6F7F8F8F9F9E3
:1000D000FAFAFAFBFBFCFCFCFDFDFDFDFEFEFEFE5C
:1000E000FEFFFFFFFFFFFFFF0000891112239B327D
:1000F0002446AD573665BF74488CC19D5AAFD3BEF8
:100100006CCAE5DB7EE9F7F88110080193331A2207
:10011000A5562C47B7753E64C99C408DDBBF52AED7
:10012000EDDA64CBFFF976E802218B3010029913E7
:100130002667AF763444BD554AADC3BC588ED19FB7
:100140006EEBE7FA7CC8F5D983310A2091121803C7
:10015000A7772E66B5543C45CBBD42ACD99E508F97
:10016000EFFB66EAFDD874C904428D5316619F7097
:100170002004A9153227BB364CCEC5DF5EEDD7FC77
:100180006888E1997AABF3BA85520C4397711E6087
:10019000A1142805B3373A26CDDE44CFDFFD56EC57
:1001A000E9986089FBBB72AA06638F7214409D5167
:1001B0002225AB343006B9174EEFC7FE5CCCD5DD37
:1001C0006AA9E3B8788AF19B87730E6295501C4147
:1001D000A3352A24B1163807CFFF46EEDDDC54CD17
:1001E000EBB962A8F99A708B088481951AA793B627
:1001F0002CC2A5D33EE1B7F04008C919522BDB3A17
:10020000644EED5F766DFF7C899400859BB712A6E6
:10021000ADD224C3BFF136E0C1184809D33B5A2AF6
:10022000E55E6C4FF77D7E6C0AA583B418869197C6
:100230002EE3A7F23CC0B5D14229CB38500AD91BD6
:10024000666FEF7E744CFD5D8BB502A499961087A6
:10025000AFF326E2BDD034C1C3394A28D11A580BB6
:10026000E77F6E6EF55C7C4D0CC685D71EE597F476
:100270002880A1913AA3B3B2444ACD5B5669DF7896
:10028000600CE91D722FFB3E8DD604C79FF516E466
:10029000A9902081BBB332A2C55A4C4BD7795E6876
:1002A000E11C680DF33F7A2E0EE787F61CC495D546
:1002B0002AA1A3B03882B193466BCF7A5448DD5956
:1002C000622DEB3C700EF91F8FF706E69DD414C526
:1002D000ABB122A0B9923083C77B4E6AD5585C4936
:1002E000E33D6A2CF11E780F11241FBECFEFD8E03A
:1002F000DEBFCDBF11E0A0E0B1E0EEE6F7E102C065
:1003000005900D92A231B107D9F718E0A2E1B1E052
:1003100001C01D92A434B107E1F70E94700A0C9449
:10032000B50B0C9400000C94C60878948CE294E011
:100330000E94120323E931E04CE254E0BA018CE060
:1003400095E00E948F078EEF94E00E94C701EEE3D4
:10035000F8E08EEF94E09383828391838083AC01F5
:100360006CE274E08CE095E00C94B7089091C000CA
:1003700095FFFCCF8093C60081E090E008958091C6
:10038000C00087FFFCCF8091C60090E00895CF9316
:10039000DF93CDB7DEB72E970FB6F894DEBF0FBE52
:1003A000CDBFDC018EE0FD01982F11929A95E9F7FF
:1003B0001092C50097E69093C400E0ECF0E09081C5
:1003C0009D7F908396E09093C20098E19093C10046
:1003D0009E012F5F3F4FF90111928A95E9F783E063
:1003E0008C8386EB91E09A8789878FEB91E09C87DD
:1003F0008B879EE0F90101900D929A95E1F72E9678
:100400000FB6F894DEBF0FBECDBFDF91CF91089538
:10041000811106C08091C000881F8827881F089519
:1004200080E008958091C00087FF03C08091C600DE
:1004300008958FEF08950F931F93CF93DF93182F95
:10044000C0913308D0913408FE01E659FF4F8081F6
:10045000811126C080E490E098A38F8F1E8E1D8EA0
:100460001C8E01E0008331960083299A20910901B6
:1004700030910A0140910B0150910C01A0EBB4E0C6
:100480000E948F0A6056704F8F4F9F4F20E43FE1CC
:1004900040E050E00E949A0A3D8B2C8B00931301A0
:1004A0000FB7F894209105013091060140910701A2
:1004B00050910801A0EBB4E00E948F0A6056704F83
:1004C0008F4F9F4F20E43FE140E050E00E949A0AA6
:1004D0003F8B2E8B0FBFE0913308F09134084FB75C
:1004E000F89426A137A182A193A12817390739F4DE
:1004F00020A531A584A195A12817390779F060A519
:1005000071A526A137A12150310991E080E0621741
:10051000730709F090E0292F382F02C021E030E066
:100520004FBF232BC1F6E0913308F09134082FB769
:10053000F894A0A5B1A51C9340A551A584A195A1AF
:100540004817590719F482A193A103C080A591A56A
:10055000019691A780A72FBF81E090E0DF91CF9116
:100560001F910F910895E0913308F09134084FB72F
:10057000F894E758FF4F24813581868197814FBFDA
:1005800028173907E9F0E0913308F09134089FB754
:10059000F894E758FF4FA481B58122813381A217D7
:1005A000B30719F42081318105C0A481B5819D0173
:1005B0002F5F3F4F358324838C919FBF90E0089538
:1005C0008FEF9FEF089581E080931201089581E0FD
:1005D000809312011092800089E18093810081E86C
:1005E00096E0909387008093860080911201882383
:1005F00021F080E480937C0002C010927C00389847
:10060000409880917E00816080937E0087E0809397
:100610007B008CEE80937A008AB1886F8AB9219A28
:10062000229A08950F931F93CF93DF93CDB7DEB730
:100630002E970FB6F894DEBF0FBECDBF8C018EECA7
:10064000D8011D928A95E9F7109334080093330876
:1006500080E490E0F80190A3878F11A2C8018C5824
:100660009F4FE459FF4F91838083978386839583BF
:1006700084830496938382830996D801A758BF4F39
:1006800011969C938E9317969C938E93169715961E
:100690009C938E931497CF9613969C938E93129758
:1006A00086599109D80193969C938E939297999627
:1006B0009C938E93989797969C938E939697CF96AC
:1006C00095969C938E93949784E090E0A681B78151
:1006D0001C9246815781228133814217530719F4B6
:1006E0002081318104C0268137812F5F3F4F3783BE
:1006F0002683019759F70E94E7028EE0FE013196AA
:10070000DF01982F1D929A95E9F793E09C832BE1E6
:1007100032E03A87298723EB32E03C872B87D801E8
:1007200001900D928A95E1F72E960FB6F894DEBFF0
:100730000FBECDBFDF91CF911F910F9108950F9301
:100740001F93CF93DF93E0913308F091340820A5F5
:1007500031A537A326A3EC018C01060F171FC01784
:10076000D10731F060E070E089910E941B02F7CF61
:10077000DF91CF911F910F910895DC0158968C91D4
:1007800058978111F8C05A968C915A978111AEC032
:1007900096964D915C91979798962D913C9199974B
:1007A0004217530779F456962D913C915797232B76
:1007B00049F410921301FD01E659FF4F1082A5592B
:1007C000BF4F68C05B969C915B97911103C05C968C
:1007D0001C925C9791E05B969C935B9754962D914D
:1007E0003C91559721153105B9F596964D915C913F
:1007F000979798962D913C9199974217530779F4C2
:10080000FD01E559FF4F108256962D913C91579767
:100810002150310957963C932E93569723C09696B4
:10082000ED91FC91979794962D913C919597E217B5
:10083000F30729F492962D913C91939707C09696D1
:10084000ED91FC9197979F012F5F3F4F97963C93B7
:100850002E939697908107C02150310955963C936D
:100860002E9354979EE759969C93599759969C912D
:1008700059979B3189F596964D915C9197979896EB
:100880002D913C9199974217530739F41092130117
:10089000A659BF4F1C92299808959696ED91FC9108
:1008A000979794968D919C919597E817F90729F45D
:1008B00092968D919C91939706C09696ED91FC919E
:1008C0009797CF01019697969C938E9396978081E8
:1008D00059968C93599706C09E57923018F45B96A0
:1008E0001C925B9781E05A968C935A975B968C91F9
:1008F0005B975F962D913C9190978823A9F05C9629
:100900008C915C97853080F05C961C925C972034CB
:10091000310519F080E490E002C085E790E0909600
:100920009C938E935F9723C05A968C915A975996B1
:100930009C915997982341F05C969C915C979F5F9E
:100940005C969C935C970FC05C961C925C972034DD
:10095000310519F020E430E002C025E730E0909640
:100960003C932E935F97880F5A968C935A9788E002
:1009700058968C9358975F96ED91FC9190975D9661
:100980008D919C915E97E80FF91F9F0131705E96E3
:100990003C932E935D9758968C915897815058961A
:1009A0008C93FF27E038F10530F08FEF90E0AC0139
:1009B0004E1B5F0BFA01E859FF4F84912F3F310521
:1009C00011F008F080950895EF92FF920F931F9316
:1009D000CF93DF93FC018C010D531F4FD8014D9134
:1009E0005C911197129711965C934E93A555B1099E
:1009F00014968D919C91159712962D913C91139779
:100A00008217930721F42D913C91119707C01496FA
:100A10008D919C9115979C012F5F3F4F15963C93AC
:100A20002E931497EC012881260290011124C9010C
:100A30009595879595958795E801998388837F019A
:100A4000D7ECED0EF11CE701288139818F010B53A2
:100A50001F4FE80139832883840F951F359527950B
:100A6000820F931FE70199838883AF0147535F4F3C
:100A700021E0181619060CF420E0EA018881880F9D
:100A8000822B888316968D919C911797EC01688331
:100A900016962D913C91179712968D919C911397D4
:100AA0002817390721F48D919C91119705C016964E
:100AB0008D919C911797019617969C938E931697FC
:100AC000DA018C91982F9695969589278370DF018E
:100AD000A653BF4F833049F48C91803214F48F5F5A
:100AE00001C081508C9311A203C081A18F5F81A3AB
:100AF0008C91885F803414F48C936BC18F738C93CA
:100B0000DF01A553BF4F8C91880F8C93EA01988128
:100B100097702BEF290F233010F0933011F4816080
:100B20008C938C91982F96958927809581709685C6
:100B3000990F892B86878E3709F052C0DF01A7589D
:100B4000BF4F14962D913C9115978D919C911197C3
:100B50002817390759F416962D913C91179712963C
:100B60008D919C91139728173907B1F116962D9105
:100B70003C91179714968D919C9115970197281782
:100B8000390751F11696CD91DC9117978EE788833E
:100B900016962D913C91179712968D919C911397D3
:100BA0002817390721F48D919C91119705C016964D
:100BB0008D919C911797019617969C938E931697FB
:100BC00091E0918B8389863020F4128A8F5F838B2A
:100BD00001C0928B81E0BFC0118A128A138ABAC009
:100BE0008F778F3711F4118A09C08289882311F019
:100BF0002A9A01C02A988189811103C0128A138A16
:100C0000E8C08685982F9F739E3309F4E2C080FF69
:100C100003C080898068808B97859F5F97878089D4
:100C2000983008F49DC0DF01A758BF4F92E8980F95
:100C3000923018F08B3109F046C014962D913C91FA
:100C400015978D919C9111972817390759F416968D
:100C50002D913C91179712968D919C91139728177F
:100C6000390759F116962D913C91179714968D914D
:100C70009C911597019728173907F9F01696CD9191
:100C8000DC9117978BE1888316962D913C911797ED
:100C900012968D919C9113972817390721F48D9105
:100CA0009C91119705C016968D919C91179701966E
:100CB00017969C938E93169706C0118A128A138AF0
:100CC0002A9880E001C081E014964D915C911597BF
:100CD0002D913C9111974217530759F416964D9157
:100CE0005C91179712962D913C91139742175307D9
:100CF00069F116964D915C91179714962D913C9140
:100D00001597215031094217530701F19089169622
:100D1000CD91DC911797988316964D915C9117971A
:100D200012962D913C9113974217530721F42D9160
:100D30003C91119706C016962D913C9117972F5F05
:100D40003F4F17963C932E93169705C0118A128A2F
:100D5000138A2A9880E0108A1786882321F039C0E8
:100D60008695808B36C0EF01C453DF4F888199810F
:100D7000816099838883DF01A758BF4F14962D9116
:100D80003C9115978D919C9111972817390759F42B
:100D900016962D913C91179712968D919C911397D1
:100DA0002817390761F016962D913C9117971496E4
:100DB0008D919C91159701972817390751F4169634
:100DC0008D919C91179715969C938E9314971982E9
:100DD000188281A1813618F011A2128A2A98DF9117
:100DE000CF911F910F91FF90EF9008951F920F9256
:100DF0000FB60F9211242F933F934F935F936F93EE
:100E00007F938F939F93AF93BF93EF93FF9380E272
:100E100086BB60917800709179007695679576959C
:100E20006795605880913308909134080E94E404DB
:100E300080911301882349F0809133089091340800
:100E40000E94BD03807F886001C080E88BB98091DB
:100E5000FA049091FB04A091FC04B091FD0401966A
:100E6000A11DB11D8093FA049093FB04A093FC0490
:100E7000B093FD04FF91EF91BF91AF919F918F913E
:100E80007F916F915F914F913F912F910F900FBE86
:100E90000F901F901895CF92DF92EF92FF920F93D1
:100EA0001F93CF93DF931F92CDB7DEB77C01262F20
:100EB00082E8860F8701065E1C4F823010F06B318E
:100EC00049F4F801608171818BE190E029830E94EF
:100ED000560B2981D701A05EBC4F3C9111964C91D5
:100EE0001197822F90E0FC01E327EE0FFF1FE851DE
:100EF000FF4F25913491C42ED12C2C253D252D93C7
:100F00003C93F801608171810F90DF91CF911F9127
:100F10000F91FF90EF90DF90CF900C94560BCF93F2
:100F2000DF93E7E2F3E0DC01EF011D922197E9F79F
:100F3000FC01E65EFC4F51834083329771836083EE
:100F40003A963183208332972FEF3FEF318320830E
:100F5000329731832083389681E08083DF91CF916F
:100F600008953F924F925F926F927F928F929F92DD
:100F7000AF92BF92CF92DF92EF92FF920F931F93A7
:100F8000CF93DF932C013C0126EE621A2CEF720AFC
:100F90006C014BEDC41A4CEFD40AEC01CC5DDC4F74
:100FA0008C01045E1C4F7C0182EEE81A8CEFF80A7B
:100FB00033243394AA24AA94BA2C4201AEED8A1A9F
:100FC000ACEF9A0AF301808191810E94180B8F3F48
:100FD000FFEF9F0709F459C0F6012081211129C0B4
:100FE0008E379105D9F4D8018D919C91429770F07C
:100FF000F70180819181883B904F41F42A9AD40176
:10100000ED91FC91309711F0C20109953882F701FA
:10101000B182A082D8011D921C92D4CF8F37910546
:1010200011F41882CFCF8B31910519F4F60130827B
:10103000C9CF2881222331F1D8012D913C9128314B
:10104000B3E03B07F0F4A9014F5F5F4FF801518314
:101050004083F201E20FF31F8083D7012D913C9171
:10106000F901E827FF27EE0FFF1FE851FF4F859199
:101070009491232F332782279327F701918380832D
:1010800001C01882D6011C929DCFDF91CF911F9194
:101090000F91FF90EF90DF90CF90BF90AF909F9017
:1010A0008F907F906F905F904F903F9008956F92D8
:1010B0007F928F929F92AF92BF92CF92DF92EF92E8
:1010C000FF920F931F93CF93DF93EC013B014A01F3
:1010D0007C018AEDE81A8CEFF80AF70110825E01B4
:1010E000F0EEAF1AFCEFBF0A8FEF9FEFF50191838F
:1010F00080836E01F6EECF1AFCEFDF0AF601608105
:1011000071818EE790E00E94560B8301860C971C3C
:101110000815190539F0F80161918F01CE010E947F
:101120004B07F6CFF501608111816095CE010E94D9
:101130004B07612F6095CE010E944B07F60160813D
:1011400071818EE790E00E94560B81E0F701808369
:10115000DF91CF911F910F91FF90EF90DF90CF9093
:10116000BF90AF909F908F907F906F9008959093D5
:101170003808809337085093FF044093FE0470931F
:101180003A0860933908109236080895EF92FF925A
:101190000F931F93CF93DF93EC016091FE04709146
:1011A000FF0480EC90E00E94560B6091FE04709169
:1011B000FF0480E090E00E94560B8E017E0184EED9
:1011C000E81A8CEFF80AF7012081318122503109A9
:1011D0006091FE047091FF04C8018C1B9D0B821767
:1011E000930708F5F80181918F01803C59F48BED4C
:1011F00090E00E94560B6091FE047091FF048CED0C
:1012000090E00EC08B3D59F48BED90E00E94560BA0
:101210006091FE047091FF048DED90E001C090E0BC
:101220000E94560BD0CF80EC90E0DF91CF911F91C0
:101230000F91FF90EF900C94560B4F925F926F922C
:101240007F928F929F92AF92BF92EF92FF920F93F5
:101250001F93CF93DF93EC018B017A01E091390862
:10126000F0913A088289811138C00E94080B909150
:101270000001891730F4A701B801CE010E94570878
:1012800046C08FB7F8948090FA049090FB04A09029
:10129000FC04B090FD048FBF209101013091020148
:1012A0004091030150910401AAE0B0E00E948F0A2E
:1012B0002FB7F8944090FA045090FB046090FC041F
:1012C0007090FD042FBF481859086A087B0846161D
:1012D00057066806790664F3C1CFE0913908F091AA
:1012E0003A088189882309F4B9CF80913708909111
:1012F00038080E94B107E0913908F0913A08E453A8
:10130000FF4F80819181892B41F31182108280915E
:1013100036088823A1F1CA5DDC4F8881811101C0A4
:10132000FFCF6091FE047091FF0480EC90E00E947A
:10133000560B6091FE047091FF048FE090E00E94D4
:10134000560B6091FE047091FF0481E090E00E94D2
:10135000560B6091FE047091FF0480EC90E0DF91E9
:10136000CF911F910F91FF90EF90BF90AF909F9002
:101370008F907F906F905F904F900C94560BDF9101
:10138000CF911F910F91FF90EF90BF90AF909F90E2
:101390008F907F906F905F904F90089590913B0851
:1013A0009923A1F0803C01F580910D01811111C0BC
:1013B00010923B0840913C0850913D0864E171E077
:1013C00080913708909138080C941D09803C09F0F1
:1013D00086C081E080933B088EEF80930D011092D0
:1013E0003D0810923C08089520913C0830913D083A
:1013F000283193E0390708F072C090910D01211552
:10140000310531F49E3F21F48F7080930D010895D2
:1014100091111FC08B3D21F481E080933508089520
:1014200090913508992349F08C3D21F08D3D19F4B8
:101430008BED01C080EC10923508A9014F5F5F4F22
:1014400050933D0840933C08F901EC5EFE4F8083C9
:101450000895913079F4282F30E0AAE0B0E00E949E
:10146000800A6093090170930A0180930B019093A5
:101470000C010895943089F42AE0829FC001112460
:10148000AA2797FDA095BA2F809305019093060196
:10149000A0930701B09308010895933089F42AE0DE
:1014A000829FC0011124AA2797FDA095BA2F80938F
:1014B000010190930201A0930301B09304010895E8
:1014C000923019F48093000108959F3041F4811106
:1014D00003C010923608089581E08093360808957D
:1014E0000E9495018CE095E00E94B10780E00E9487
:1014F00008028823B9F30E9412020E94CE09F2CF9B
:10150000A29FB001B39FC001A39F700D811D112444
:10151000911DB29F700D811D1124911D08950E948F
:10152000800AA59F900DB49F900DA49F800D911DE2
:1015300011240895A1E21A2EAA1BBB1BFD010DC0A8
:10154000AA1FBB1FEE1FFF1FA217B307E407F50773
:1015500020F0A21BB30BE40BF50B661F771F881F4F
:10156000991F1A9469F760957095809590959B01E5
:10157000AC01BD01CF0108958F929F92AF92BF92AF
:10158000CF92DF92EF92FF92CF93DF93EC016881CD
:1015900079818A819B81611571058105910521F40D
:1015A00064E279ED8BE597E02DE133EF41E050E027
:1015B0000E94960B49015A019B01AC01A7EAB1E4D4
:1015C0000E948F0A6B017C01ACEEB4EFA50194017F
:1015D0000E94910BDC01CB018C0D9D1DAE1DBF1D2A
:1015E000B7FF03C00197A109B04888839983AA83F4
:1015F000BB839F77DF91CF91FF90EF90DF90CF90EB
:10160000BF90AF909F908F9008950E94BC0A08955C
:101610008EE091E00E94BC0A0895A0E0B0E08093C3
:101620000E0190930F01A0931001B0931101089542
:10163000CF93DF93EC012B8120FF33C026FF0AC03C
:101640002F7B2B838E819F8101969F838E838A813E
:1016500090E029C022FF0FC0E881F981808199279D
:1016600087FD9095009719F420622B831AC031965C
:10167000F983E8830EC0EA85FB85099597FF09C0C9
:101680002B81019611F080E201C080E1822B8B83D7
:1016900008C02E813F812F5F3F4F3F832E839927C4
:1016A00002C08FEF9FEFDF91CF9108950F931F93AB
:1016B000CF93DF93FB01238121FD03C08FEF9FEFC9
:1016C00028C022FF16C046815781248135814217E8
:1016D000530744F4A081B1819D012F5F3F4F3183B7
:1016E00020838C93268137812F5F3F4F378326835A
:1016F00010C0EB01092F182F0084F185E02D09950A
:10170000892BE1F68E819F8101969F838E83812FA5
:10171000902FDF91CF911F910F910895B7FF0C94F7
:101720008F0A0E948F0A821B930B0895052E97FB48
:101730001EF400940E94AD0B57FD07D00E949A0A38
:1017400007FC03D04EF40C94AD0B509540953095AA
:1017500021953F4F4F4F5F4F08959095809570951D
:0E17600061957F4F8F4F9F4F0895F894FFCFF4
:10176E003FC8000000320000005E010000FE0100D4
:02177E00000069
:00000001FF

File diff suppressed because it is too large Load Diff

View File

@ -22,38 +22,7 @@ void ax25_init(AX25Ctx *ctx, Afsk *modem, FILE *channel, ax25_callback_t hook) {
}
static void ax25_decode(AX25Ctx *ctx) {
#if SERIAL_PROTOCOL == PROTOCOL_KISS
if (ctx->hook) ctx->hook(ctx);
#endif
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
AX25Msg msg;
uint8_t *buf = ctx->buf;
DECODE_CALL(buf, msg.dst.call);
msg.dst.ssid = (*buf++ >> 1) & 0x0F;
DECODE_CALL(buf, msg.src.call);
msg.src.ssid = (*buf >> 1) & 0x0F;
for (msg.rpt_count = 0; !(*buf++ & 0x01) && (msg.rpt_count < countof(msg.rpt_list)); msg.rpt_count++) {
DECODE_CALL(buf, msg.rpt_list[msg.rpt_count].call);
msg.rpt_list[msg.rpt_count].ssid = (*buf >> 1) & 0x0F;
AX25_SET_REPEATED(&msg, msg.rpt_count, (*buf & 0x80));
}
msg.ctrl = *buf++;
if (msg.ctrl != AX25_CTRL_UI) { return; }
msg.pid = *buf++;
if (msg.pid != AX25_PID_NOLAYER3) { return; }
msg.len = ctx->frame_len - 2 - (buf - ctx->buf);
msg.info = buf;
if (ctx->hook) ctx->hook(&msg);
#endif
}
void ax25_poll(AX25Ctx *ctx) {
@ -121,49 +90,3 @@ void ax25_sendRaw(AX25Ctx *ctx, void *_buf, size_t len) {
ctx->ready_for_data = true;
}
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
static void ax25_sendCall(AX25Ctx *ctx, const AX25Call *addr, bool last){
unsigned len = MIN(sizeof(addr->call), strlen(addr->call));
for (unsigned i = 0; i < len; i++) {
uint8_t c = addr->call[i];
c = toupper(c);
ax25_putchar(ctx, c << 1);
}
if (len < sizeof(addr->call)) {
for (unsigned i = 0; i < sizeof(addr->call) - len; i++) {
ax25_putchar(ctx, ' ' << 1);
}
}
uint8_t ssid = 0x60 | (addr->ssid << 1) | (last ? 0x01 : 0);
ax25_putchar(ctx, ssid);
}
void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len) {
const uint8_t *buf = (const uint8_t *)_buf;
ctx->crc_out = CRC_CCIT_INIT_VAL;
fputc(HDLC_FLAG, ctx->ch);
for (size_t i = 0; i < path_len; i++) {
ax25_sendCall(ctx, &path[i], (i == path_len - 1));
}
ax25_putchar(ctx, AX25_CTRL_UI);
ax25_putchar(ctx, AX25_PID_NOLAYER3);
while (len--) {
ax25_putchar(ctx, *buf++);
}
uint8_t crcl = (ctx->crc_out & 0xff) ^ 0xff;
uint8_t crch = (ctx->crc_out >> 8) ^ 0xff;
ax25_putchar(ctx, crcl);
ax25_putchar(ctx, crch);
fputc(HDLC_FLAG, ctx->ch);
}
#endif

View File

@ -21,13 +21,7 @@
struct AX25Ctx; // Forward declarations
struct AX25Msg;
#if SERIAL_PROTOCOL == PROTOCOL_KISS
typedef void (*ax25_callback_t)(struct AX25Ctx *ctx);
#endif
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
typedef void (*ax25_callback_t)(struct AX25Msg *msg);
#endif
typedef struct AX25Ctx {
uint8_t buf[AX25_MAX_FRAME_LEN];
@ -42,33 +36,6 @@ typedef struct AX25Ctx {
bool ready_for_data;
} AX25Ctx;
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
#define AX25_CALL(str, id) {.call = (str), .ssid = (id) }
#define AX25_MAX_RPT 8
#define AX25_REPEATED(msg, n) ((msg)->rpt_flags & BV(n))
typedef struct AX25Call {
char call[6];
uint8_t ssid;
} AX25Call;
typedef struct AX25Msg {
AX25Call src;
AX25Call dst;
AX25Call rpt_list[AX25_MAX_RPT];
uint8_t rpt_count;
uint8_t rpt_flags;
uint16_t ctrl;
uint8_t pid;
const uint8_t *info;
size_t len;
} AX25Msg;
void ax25_sendVia(AX25Ctx *ctx, const AX25Call *path, size_t path_len, const void *_buf, size_t len);
#define ax25_send(ctx, dst, src, buf, len) ax25_sendVia(ctx, ({static AX25Call __path[]={dst, src}; __path;}), 2, buf, len)
#endif
void ax25_poll(AX25Ctx *ctx);
void ax25_sendRaw(AX25Ctx *ctx, void *_buf, size_t len);
void ax25_init(AX25Ctx *ctx, Afsk *modem, FILE *channel, ax25_callback_t hook);

View File

@ -1,861 +0,0 @@
#include "device.h"
#if SERIAL_PROTOCOL == PROTOCOL_SIMPLE_SERIAL
#define ENABLE_HELP true
#include <stdlib.h>
#include <string.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include "hardware/Serial.h"
#include "SimpleSerial.h"
#include "util/time.h"
#define countof(a) sizeof(a)/sizeof(a[0])
bool PRINT_SRC = true;
bool PRINT_DST = true;
bool PRINT_PATH = true;
bool PRINT_DATA = true;
bool PRINT_INFO = true;
bool VERBOSE = true;
bool SILENT = false;
bool SS_INIT = false;
bool SS_DEFAULT_CONF = false;
AX25Call src;
AX25Call dst;
AX25Call path1;
AX25Call path2;
char CALL[6] = DEFAULT_CALLSIGN;
int CALL_SSID = 0;
char DST[6] = DEFAULT_DESTINATION_CALL;
int DST_SSID = 0;
char PATH1[6] = "WIDE1";
int PATH1_SSID = 1;
char PATH2[6] = "WIDE2";
int PATH2_SSID = 2;
AX25Call path[4];
AX25Ctx *ax25ctx;
#define NV_MAGIC_BYTE 0x69
uint8_t EEMEM nvMagicByte;
uint8_t EEMEM nvCALL[6];
uint8_t EEMEM nvDST[6];
uint8_t EEMEM nvPATH1[6];
uint8_t EEMEM nvPATH2[6];
uint8_t EEMEM nvCALL_SSID;
uint8_t EEMEM nvDST_SSID;
uint8_t EEMEM nvPATH1_SSID;
uint8_t EEMEM nvPATH2_SSID;
bool EEMEM nvPRINT_SRC;
bool EEMEM nvPRINT_DST;
bool EEMEM nvPRINT_PATH;
bool EEMEM nvPRINT_DATA;
bool EEMEM nvPRINT_INFO;
bool EEMEM nvVERBOSE;
bool EEMEM nvSILENT;
uint8_t EEMEM nvPOWER;
uint8_t EEMEM nvHEIGHT;
uint8_t EEMEM nvGAIN;
uint8_t EEMEM nvDIRECTIVITY;
uint8_t EEMEM nvSYMBOL_TABLE;
uint8_t EEMEM nvSYMBOL;
uint8_t EEMEM nvAUTOACK;
int EEMEM nvPREAMBLE;
int EEMEM nvTAIL;
// Location packet assembly fields
char latitude[8];
char longtitude[9];
char symbolTable = '/';
char symbol = 'n';
uint8_t power = 10;
uint8_t height = 10;
uint8_t gain = 10;
uint8_t directivity = 10;
/////////////////////////
// Message packet assembly fields
char message_recip[6];
int message_recip_ssid = -1;
int message_seq = 0;
char lastMessage[67];
size_t lastMessageLen;
bool message_autoAck = false;
/////////////////////////
extern unsigned long custom_preamble;
extern unsigned long custom_tail;
void ss_init(AX25Ctx *ax25) {
ax25ctx = ax25;
ss_loadSettings();
SS_INIT = true;
if (VERBOSE) {
printf_P(PSTR("---------------\n"));
printf_P(PSTR("MicroAPRS v1.0b\n"));
printf_P(PSTR("unsigned.io/microaprs\n"));
if (SS_DEFAULT_CONF) printf_P(PSTR("Default configuration loaded!\n"));
printf_P(PSTR("Modem ready\n"));
printf_P(PSTR("---------------\n"));
}
}
void ss_clearSettings(void) {
eeprom_update_byte((void*)&nvMagicByte, 0xFF);
if (VERBOSE) printf_P(PSTR("Configuration cleared. Restart to load defaults.\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
void ss_loadSettings(void) {
uint8_t verification = eeprom_read_byte((void*)&nvMagicByte);
if (verification == NV_MAGIC_BYTE) {
eeprom_read_block((void*)CALL, (void*)nvCALL, 6);
eeprom_read_block((void*)DST, (void*)nvDST, 6);
eeprom_read_block((void*)PATH1, (void*)nvPATH1, 6);
eeprom_read_block((void*)PATH2, (void*)nvPATH2, 6);
CALL_SSID = eeprom_read_byte((void*)&nvCALL_SSID);
DST_SSID = eeprom_read_byte((void*)&nvDST_SSID);
PATH1_SSID = eeprom_read_byte((void*)&nvPATH1_SSID);
PATH2_SSID = eeprom_read_byte((void*)&nvPATH2_SSID);
PRINT_SRC = eeprom_read_byte((void*)&nvPRINT_SRC);
PRINT_DST = eeprom_read_byte((void*)&nvPRINT_DST);
PRINT_PATH = eeprom_read_byte((void*)&nvPRINT_PATH);
PRINT_DATA = eeprom_read_byte((void*)&nvPRINT_DATA);
PRINT_INFO = eeprom_read_byte((void*)&nvPRINT_INFO);
VERBOSE = eeprom_read_byte((void*)&nvVERBOSE);
SILENT = eeprom_read_byte((void*)&nvSILENT);
power = eeprom_read_byte((void*)&nvPOWER);
height = eeprom_read_byte((void*)&nvHEIGHT);
gain = eeprom_read_byte((void*)&nvGAIN);
directivity = eeprom_read_byte((void*)&nvDIRECTIVITY);
symbolTable = eeprom_read_byte((void*)&nvSYMBOL_TABLE);
symbol = eeprom_read_byte((void*)&nvSYMBOL);
message_autoAck = eeprom_read_byte((void*)&nvAUTOACK);
custom_preamble = eeprom_read_word((void*)&nvPREAMBLE);
custom_tail = eeprom_read_word((void*)&nvTAIL);
if (VERBOSE && SS_INIT) printf_P(PSTR("Configuration loaded\n"));
} else {
if (SS_INIT && !SILENT && VERBOSE) printf_P(PSTR("Error: No stored configuration to load!\n"));
if (SS_INIT && !SILENT && !VERBOSE) printf_P(PSTR("0\n"));
SS_DEFAULT_CONF = true;
}
}
void ss_saveSettings(void) {
eeprom_update_block((void*)CALL, (void*)nvCALL, 6);
eeprom_update_block((void*)DST, (void*)nvDST, 6);
eeprom_update_block((void*)PATH1, (void*)nvPATH1, 6);
eeprom_update_block((void*)PATH2, (void*)nvPATH2, 6);
eeprom_update_byte((void*)&nvCALL_SSID, CALL_SSID);
eeprom_update_byte((void*)&nvDST_SSID, DST_SSID);
eeprom_update_byte((void*)&nvPATH1_SSID, PATH1_SSID);
eeprom_update_byte((void*)&nvPATH2_SSID, PATH2_SSID);
eeprom_update_byte((void*)&nvPRINT_SRC, PRINT_SRC);
eeprom_update_byte((void*)&nvPRINT_DST, PRINT_DST);
eeprom_update_byte((void*)&nvPRINT_PATH, PRINT_PATH);
eeprom_update_byte((void*)&nvPRINT_DATA, PRINT_DATA);
eeprom_update_byte((void*)&nvPRINT_INFO, PRINT_INFO);
eeprom_update_byte((void*)&nvVERBOSE, VERBOSE);
eeprom_update_byte((void*)&nvSILENT, SILENT);
eeprom_update_byte((void*)&nvPOWER, power);
eeprom_update_byte((void*)&nvHEIGHT, height);
eeprom_update_byte((void*)&nvGAIN, gain);
eeprom_update_byte((void*)&nvDIRECTIVITY, directivity);
eeprom_update_byte((void*)&nvSYMBOL_TABLE, symbolTable);
eeprom_update_byte((void*)&nvSYMBOL, symbol);
eeprom_update_byte((void*)&nvAUTOACK, message_autoAck);
eeprom_update_word((void*)&nvPREAMBLE, custom_preamble);
eeprom_update_word((void*)&nvTAIL, custom_tail);
eeprom_update_byte((void*)&nvMagicByte, NV_MAGIC_BYTE);
if (VERBOSE) printf_P(PSTR("Configuration saved\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
void ss_messageCallback(struct AX25Msg *msg) {
if (PRINT_SRC) {
if (PRINT_INFO) printf_P(PSTR("SRC: "));
printf_P(PSTR("[%.6s-%d] "), msg->src.call, msg->src.ssid);
}
if (PRINT_DST) {
if (PRINT_INFO) printf_P(PSTR("DST: "));
printf_P(PSTR("[%.6s-%d] "), msg->dst.call, msg->dst.ssid);
}
if (PRINT_PATH) {
if (PRINT_INFO) printf_P(PSTR("PATH: "));
for (int i = 0; i < msg->rpt_count; i++)
printf_P(PSTR("[%.6s-%d] "), msg->rpt_list[i].call, msg->rpt_list[i].ssid);
}
if (PRINT_DATA) {
if (PRINT_INFO) printf_P(PSTR("DATA: "), msg->len);
for (int i = 0; i < msg->len; i++) {
putchar(msg->info[i]);
}
}
printf_P(PSTR("\r\n"));
if (message_autoAck && msg->len > 11) {
char mseq[6];
bool shouldAck = true;
int msl = 0;
int loc = msg->len - 1;
size_t i = 0;
while (i<7 && i < msg->len) {
if (msg->info[loc-i] == '{') {
size_t p;
for (p = 0; p <= i; p++) {
mseq[p] = msg->info[loc-i+p];
msl = i;
}
}
i++;
}
if (msl != 0) {
int pos = 1;
int ssidPos = 0;
while (pos < 7) {
if (msg->info[pos] != CALL[pos-1]) {
shouldAck = false;
pos = 7;
}
pos++;
}
while (pos < 10) {
if (msg->info[pos] == '-') ssidPos = pos;
pos++;
}
if (ssidPos != 0) {
if (msg->info[ssidPos+2] == ' ') {
if (msg->info[ssidPos+1]-48 != CALL_SSID) {
shouldAck = false;
}
} else {
int assid = 10+(msg->info[ssidPos+2]-48);
if (assid != CALL_SSID) {
shouldAck = false;
}
}
}
if (msl != 0 && shouldAck) {
int ii = 0;
char *ack = malloc(14+msl);
for (ii = 0; ii < 9; ii++) {
ack[1+ii] = ' ';
}
int calllen = 0;
for (ii = 0; ii < 6; ii++) {
if (msg->src.call[ii] != 0) {
ack[1+ii] = msg->src.call[ii];
calllen++;
}
}
if (msg->src.ssid != 0) {
ack[1+calllen] = '-';
if (msg->src.ssid < 10) {
ack[2+calllen] = msg->src.ssid+48;
} else {
ack[2+calllen] = 49;
ack[3+calllen] = msg->src.ssid-10+48;
}
}
ack[0] = ':';
ack[10] = ':';
ack[11] = 'a';
ack[12] = 'c';
ack[13] = 'k';
for (ii = 0; ii < msl; ii++) {
ack[14+ii] = mseq[ii+1];
}
delay_ms(1750);
ss_sendPkt(ack, 14+msl, ax25ctx);
free(ack);
}
}
}
}
void ss_serialCallback(void *_buffer, size_t length, AX25Ctx *ctx) {
uint8_t *buffer = (uint8_t *)_buffer;
if (length > 0) {
// ! as first char to send packet
if (buffer[0] == '!' && length > 1) {
buffer++; length--;
ss_sendPkt(buffer, length, ctx);
if (VERBOSE) printf_P(PSTR("Packet sent\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == '@') {
buffer++; length--;
ss_sendLoc(buffer, length, ctx);
if (VERBOSE) printf_P(PSTR("Location update sent\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == '#') {
buffer++; length--;
ss_sendMsg(buffer, length, ctx);
if (VERBOSE) printf_P(PSTR("Message sent\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
#if ENABLE_HELP
else if (buffer[0] == 'h') {
ss_printHelp();
}
#endif
else if (buffer[0] == 'H') {
ss_printSettings();
} else if (buffer[0] == 'S') {
ss_saveSettings();
} else if (buffer[0] == 'C') {
ss_clearSettings();
} else if (buffer[0] == 'L') {
ss_loadSettings();
} else if (buffer[0] == 'c' && length > 3) {
buffer++; length--;
int count = 0;
while (length-- && count < 6) {
char c = buffer[count];
if (c != 0 && c != 10 && c != 13) {
CALL[count] = c;
} else {
CALL[count] = 0x00;
}
count++;
}
while (count < 6) {
CALL[count] = 0x00;
count++;
}
if (VERBOSE) printf_P(PSTR("Callsign: %.6s-%d\n"), CALL, CALL_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'd' && length > 3) {
buffer++; length--;
int count = 0;
while (length-- && count < 6) {
char c = buffer[count];
if (c != 0 && c != 10 && c != 13) {
DST[count] = c;
} else {
DST[count] = 0;
}
count++;
}
while (count < 6) {
DST[count] = 0x00;
count++;
}
if (VERBOSE) printf_P(PSTR("Destination: %.6s-%d\n"), DST, DST_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == '1' && length > 1) {
buffer++; length--;
int count = 0;
while (length-- && count < 6) {
char c = buffer[count];
if (c != 0 && c != 10 && c != 13) {
PATH1[count] = c;
} else {
PATH1[count] = 0;
}
count++;
}
while (count < 6) {
PATH1[count] = 0x00;
count++;
}
if (VERBOSE) printf_P(PSTR("Path1: %.6s-%d\n"), PATH1, PATH1_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == '2' && length > 1) {
buffer++; length--;
int count = 0;
while (length-- && count < 6) {
char c = buffer[count];
if (c != 0 && c != 10 && c != 13) {
PATH2[count] = c;
} else {
PATH2[count] = 0;
}
count++;
}
while (count < 6) {
PATH2[count] = 0x00;
count++;
}
if (VERBOSE) printf_P(PSTR("Path2: %.6s-%d\n"), PATH2, PATH2_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 's' && length > 2) {
buffer++; length--;
if (buffer[0] == 'c') {
if (length > 2 && buffer[2] > 48 && buffer[2] < 58 && buffer[1] > 48) {
CALL_SSID = 10+buffer[2]-48;
} else
if ( buffer[1] > 48 && buffer[1] < 58) {
CALL_SSID = buffer[1]-48;
}
if (VERBOSE) printf_P(PSTR("Callsign: %.6s-%d\n"), CALL, CALL_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
if (buffer[0] == 'd') {
if (length > 2 && buffer[2] > 48 && buffer[2] < 58 && buffer[1] > 48) {
DST_SSID = 10+buffer[2]-48;
} else
if ( buffer[1] > 48 && buffer[1] < 58) {
DST_SSID = buffer[1]-48;
}
if (VERBOSE) printf_P(PSTR("Destination: %.6s-%d\n"), DST, DST_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
if (buffer[0] == '1' ) {
if (length > 2 && buffer[2] > 48 && buffer[2] < 58 && buffer[1] > 48) {
PATH1_SSID = 10+buffer[2]-48;
} else
if ( buffer[1] > 48 && buffer[1] < 58) {
PATH1_SSID = buffer[1]-48;
}
if (VERBOSE) printf_P(PSTR("Path1: %.6s-%d\n"), PATH1, PATH1_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
if (buffer[0] == '2' ) {
if (length > 2 && buffer[2] > 48 && buffer[2] < 58 && buffer[1] > 48) {
PATH2_SSID = 10+buffer[2]-48;
} else
if (buffer[2] > 48 && buffer[2] < 58) {
PATH2_SSID = buffer[1]-48;
}
if (VERBOSE) printf_P(PSTR("Path2: %.6s-%d\n"), PATH2, PATH2_SSID);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
} else if (buffer[0] == 'p' && length > 2) {
buffer++; length--;
if (buffer[0] == 's') {
if (buffer[1] == 49) {
PRINT_SRC = true;
if (VERBOSE) printf_P(PSTR("Print SRC enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
PRINT_SRC = false;
if (VERBOSE) printf_P(PSTR("Print SRC disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
if (buffer[0] == 'd') {
if (buffer[1] == 49) {
PRINT_DST = true;
if (VERBOSE) printf_P(PSTR("Print DST enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
PRINT_DST = false;
if (VERBOSE) printf_P(PSTR("Print DST disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
if (buffer[0] == 'p') {
if (buffer[1] == 49) {
PRINT_PATH = true;
if (VERBOSE) printf_P(PSTR("Print PATH enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
PRINT_PATH = false;
if (VERBOSE) printf_P(PSTR("Print PATH disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
if (buffer[0] == 'm') {
if (buffer[1] == 49) {
PRINT_DATA = true;
if (VERBOSE) printf_P(PSTR("Print DATA enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
PRINT_DATA = false;
if (VERBOSE) printf_P(PSTR("Print DATA disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
if (buffer[0] == 'i') {
if (buffer[1] == 49) {
PRINT_INFO = true;
if (VERBOSE) printf_P(PSTR("Print INFO enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
PRINT_INFO = false;
if (VERBOSE) printf_P(PSTR("Print INFO disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
} else if (buffer[0] == 'v') {
if (buffer[1] == 49) {
VERBOSE = true;
printf_P(PSTR("Verbose mode enabled\n"));
} else {
VERBOSE = false;
printf_P(PSTR("Verbose mode disabled\n"));
}
} else if (buffer[0] == 'V') {
if (buffer[1] == 49) {
SILENT = true;
VERBOSE = false;
printf_P(PSTR("Silent mode enabled\n"));
} else {
SILENT = false;
printf_P(PSTR("Silent mode disabled\n"));
}
} else if (buffer[0] == 'l' && length > 2) {
buffer++; length--;
if (buffer[0] == 'l' && buffer[1] == 'a' && length >= 10) {
buffer += 2;
memcpy(latitude, (void *)buffer, 8);
if (VERBOSE) printf_P(PSTR("Latitude set to %.8s\n"), latitude);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'l' && buffer[1] == 'o' && length >= 11) {
buffer += 2;
memcpy(longtitude, (void *)buffer, 9);
if (VERBOSE) printf_P(PSTR("Longtitude set to %.9s\n"), longtitude);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'p' && length >= 2 && buffer[1] >= 48 && buffer[1] <= 57) {
power = buffer[1] - 48;
if (VERBOSE) printf_P(PSTR("Power set to %dw\n"), power*power);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'h' && length >= 2 && buffer[1] >= 48 && buffer[1] <= 57) {
height = buffer[1] - 48;
if (VERBOSE) printf_P(PSTR("Antenna height set to %ldm AAT\n"), (long)(_BV(height)*1000L)/328L);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'g' && length >= 2 && buffer[1] >= 48 && buffer[1] <= 57) {
gain = buffer[1] - 48;
if (VERBOSE) printf_P(PSTR("Gain set to %ddB\n"), gain);
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'd' && length >= 2 && buffer[1] >= 48 && buffer[1] <= 57) {
directivity = buffer[1] - 48;
if (directivity == 9) directivity = 8;
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
if (VERBOSE) {
if (directivity == 0) printf_P(PSTR("Directivity set to omni\n"));
if (directivity != 0) printf_P(PSTR("Directivity set to %ddeg\n"), directivity*45);
}
} else if (buffer[0] == 's' && length >= 2) {
symbol = buffer[1];
if (VERBOSE) printf_P(PSTR("Symbol set to %c\n"), symbol);
} else if (buffer[0] == 't' && length >= 2) {
if (buffer[1] == 'a') {
symbolTable = '\\';
if (VERBOSE) printf_P(PSTR("Selected alternate symbol table\n"));
} else {
symbolTable = '/';
if (VERBOSE) printf_P(PSTR("Selected standard symbol table\n"));
}
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
} else if (buffer[0] == 'm' && length > 1) {
buffer++; length--;
if (buffer[0] == 'c' && length > 1) {
buffer++; length--;
int count = 0;
while (length-- && count < 6) {
char c = buffer[count];
if (c != 0 && c != 10 && c != 13) {
message_recip[count] = c;
} else {
message_recip[count] = 0x00;
}
count++;
}
while (count < 6) {
message_recip[count] = 0x00;
count++;
}
if (VERBOSE) {
printf_P(PSTR("Message recipient: %.6s"), message_recip);
if (message_recip_ssid != -1) {
printf_P(PSTR("-%d\n"), message_recip_ssid);
} else {
printf_P(PSTR("\n"));
}
}
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 's' && length > 1) {
if (length > 3) {
message_recip_ssid = 10+buffer[2]-48;
} else {
message_recip_ssid = buffer[1]-48;
}
if (message_recip_ssid < 0 || message_recip_ssid > 15) message_recip_ssid = -1;
if (VERBOSE) {
printf_P(PSTR("Message recipient: %.6s"), message_recip);
if (message_recip_ssid != -1) {
printf_P(PSTR("-%d\n"), message_recip_ssid);
} else {
printf_P(PSTR("\n"));
}
}
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'r') {
ss_msgRetry(ctx);
if (VERBOSE) printf_P(PSTR("Retried last message\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else if (buffer[0] == 'a') {
if (buffer[1] == 49) {
message_autoAck = true;
if (VERBOSE) printf_P(PSTR("Message auto-ack enabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
} else {
message_autoAck = false;
if (VERBOSE) printf_P(PSTR("Message auto-ack disabled\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("1\n"));
}
}
} else if (buffer[0] == 'w' && length >= 2) {
char str[4]; buffer++;
memcpy(str, buffer, length-1);
int preamble = atoi(str);
if (preamble >= 0 && preamble <= 9999) {
custom_preamble = preamble;
printf_P(PSTR("Preamble set to %lums\n"), custom_preamble);
} else {
printf_P(PSTR("Error: Invalid value for preamble\n"));
}
} else if (buffer[0] == 'W' && length >= 2) {
char str[4]; buffer++;
memcpy(str, buffer, length-1);
int tail = atoi(str);
if (tail >= 0 && tail <= 9999) {
custom_tail = tail;
printf_P(PSTR("TX Tail set to %lums\n"), custom_tail);
} else {
printf_P(PSTR("Error: Invalid value for TX tail\n"));
}
} else {
if (VERBOSE) printf_P(PSTR("Error: Invalid command\n"));
if (!VERBOSE && !SILENT) printf_P(PSTR("0\n"));
}
}
}
void ss_sendPkt(void *_buffer, size_t length, AX25Ctx *ax25) {
uint8_t *buffer = (uint8_t *)_buffer;
memcpy(dst.call, DST, 6);
dst.ssid = DST_SSID;
memcpy(src.call, CALL, 6);
src.ssid = CALL_SSID;
memcpy(path1.call, PATH1, 6);
path1.ssid = PATH1_SSID;
memcpy(path2.call, PATH2, 6);
path2.ssid = PATH2_SSID;
path[0] = dst;
path[1] = src;
path[2] = path1;
path[3] = path2;
ax25_sendVia(ax25, path, countof(path), buffer, length);
}
void ss_sendLoc(void *_buffer, size_t length, AX25Ctx *ax25) {
size_t payloadLength = 20+length;
bool usePHG = false;
if (power < 10 && height < 10 && gain < 10 && directivity < 9) {
usePHG = true;
payloadLength += 7;
}
uint8_t *packet = malloc(payloadLength);
uint8_t *ptr = packet;
packet[0] = '=';
packet[9] = symbolTable;
packet[19] = symbol;
ptr++;
memcpy(ptr, latitude, 8);
ptr += 9;
memcpy(ptr, longtitude, 9);
ptr += 10;
if (usePHG) {
packet[20] = 'P';
packet[21] = 'H';
packet[22] = 'G';
packet[23] = power+48;
packet[24] = height+48;
packet[25] = gain+48;
packet[26] = directivity+48;
ptr+=7;
}
if (length > 0) {
uint8_t *buffer = (uint8_t *)_buffer;
memcpy(ptr, buffer, length);
}
//printf_P(PSTR("Assembled packet:\n%.*s\n", payloadLength, packet);
ss_sendPkt(packet, payloadLength, ax25);
free(packet);
}
void ss_sendMsg(void *_buffer, size_t length, AX25Ctx *ax25) {
if (length > 67) length = 67;
size_t payloadLength = 11+length+4;
uint8_t *packet = malloc(payloadLength);
uint8_t *ptr = packet;
packet[0] = ':';
int callSize = 6;
int count = 0;
while (callSize--) {
if (message_recip[count] != 0) {
packet[1+count] = message_recip[count];
count++;
}
}
if (message_recip_ssid != -1) {
packet[1+count] = '-'; count++;
if (message_recip_ssid < 10) {
packet[1+count] = message_recip_ssid+48; count++;
} else {
packet[1+count] = 49; count++;
packet[1+count] = message_recip_ssid-10+48; count++;
}
}
while (count < 9) {
packet[1+count] = ' '; count++;
}
packet[1+count] = ':';
ptr += 11;
if (length > 0) {
uint8_t *buffer = (uint8_t *)_buffer;
memcpy(ptr, buffer, length);
memcpy(lastMessage, buffer, length);
lastMessageLen = length;
}
message_seq++;
if (message_seq > 999) message_seq = 0;
packet[11+length] = '{';
int n = message_seq % 10;
int d = ((message_seq % 100) - n)/10;
int h = (message_seq - d - n) / 100;
packet[12+length] = h+48;
packet[13+length] = d+48;
packet[14+length] = n+48;
//printf_P(PSTR("Assembled packet:\n%.*s\n", payloadLength, packet);
ss_sendPkt(packet, payloadLength, ax25);
free(packet);
}
void ss_msgRetry(AX25Ctx *ax25) {
message_seq--;
ss_sendMsg(lastMessage, lastMessageLen, ax25);
}
void ss_printSettings(void) {
printf_P(PSTR("Configuration:\n"));
printf_P(PSTR("Callsign: %.6s-%d\n"), CALL, CALL_SSID);
printf_P(PSTR("Destination: %.6s-%d\n"), DST, DST_SSID);
printf_P(PSTR("Path1: %.6s-%d\n"), PATH1, PATH1_SSID);
printf_P(PSTR("Path2: %.6s-%d\n"), PATH2, PATH2_SSID);
if (message_autoAck) {
printf_P(PSTR("Auto-ack messages: On\n"));
} else {
printf_P(PSTR("Auto-ack messages: Off\n"));
}
if (power != 10) printf_P(PSTR("Power: %d\n"), power);
if (height != 10) printf_P(PSTR("Height: %d\n"), height);
if (gain != 10) printf_P(PSTR("Gain: %d\n"), gain);
if (directivity != 10) printf_P(PSTR("Directivity: %d\n"), directivity);
if (symbolTable == '\\') printf_P(PSTR("Symbol table: alternate\n"));
if (symbolTable == '/') printf_P(PSTR("Symbol table: standard\n"));
printf_P(PSTR("Symbol: %c\n"), symbol);
printf_P(PSTR("TX Preamble: %lu\n"), custom_preamble);
printf_P(PSTR("TX Tail: %lu\n"), custom_tail);
}
#if ENABLE_HELP
void ss_printHelp(void) {
printf_P(PSTR("----------------------------------\n"));
printf_P(PSTR("Serial commands:\n"));
printf_P(PSTR("!<data> Send raw packet\n"));
printf_P(PSTR("@<cmt> Send location update (cmt = optional comment)\n"));
printf_P(PSTR("#<msg> Send APRS message\n\n"));
printf_P(PSTR("c<call> Set your callsign\n"));
printf_P(PSTR("d<call> Set destination callsign\n"));
printf_P(PSTR("1<call> Set PATH1 callsign\n"));
printf_P(PSTR("2<call> Set PATH2 callsign\n\n"));
printf_P(PSTR("sc<ssid> Set your SSID\n"));
printf_P(PSTR("sd<ssid> Set destination SSID\n"));
printf_P(PSTR("s1<ssid> Set PATH1 SSID\n"));
printf_P(PSTR("s2<ssid> Set PATH2 SSID\n\n"));
printf_P(PSTR("lla<LAT> Set latitude (NMEA-format, eg 4903.50N)\n"));
printf_P(PSTR("llo<LON> Set latitude (NMEA-format, eg 07201.75W)\n"));
printf_P(PSTR("lp<0-9> Set TX power info\n"));
printf_P(PSTR("lh<0-9> Set antenna height info\n"));
printf_P(PSTR("lg<0-9> Set antenna gain info\n"));
printf_P(PSTR("ld<0-9> Set antenna directivity info\n"));
printf_P(PSTR("ls<sym> Select symbol\n"));
printf_P(PSTR("lt<s/a> Select symbol table (standard/alternate)\n\n"));
printf_P(PSTR("mc<call> Set message recipient callsign\n"));
printf_P(PSTR("ms<ssid> Set message recipient SSID\n"));
printf_P(PSTR("mr<ssid> Retry last message\n"));
printf_P(PSTR("ma<1/0> Automatic message ACK on/off\n\n"));
printf_P(PSTR("ps<1/0> Print SRC on/off\n"));
printf_P(PSTR("pd<1/0> Print DST on/off\n"));
printf_P(PSTR("pp<1/0> Print PATH on/off\n"));
printf_P(PSTR("pm<1/0> Print DATA on/off\n"));
printf_P(PSTR("pi<1/0> Print INFO on/off\n\n"));
printf_P(PSTR("v<1/0> Verbose mode on/off\n"));
printf_P(PSTR("V<1/0> Silent mode on/off\n\n"));
printf_P(PSTR("w<XXX> Set preamble time in ms\n"));
printf_P(PSTR("W<XXX> Set transmission tail time in ms\n"));
printf_P(PSTR("S Save configuration\n"));
printf_P(PSTR("L Load configuration\n"));
printf_P(PSTR("C Clear configuration\n"));
printf_P(PSTR("H Print configuration\n"));
printf_P(PSTR("----------------------------------\n"));
}
#endif
#endif

View File

@ -1,25 +0,0 @@
#ifndef _PROTOCOL_SIMPLE_SERIAL
#define _PROTOCOL_SIMPLE_SERIAL 0x01
#include "AX25.h"
#define DEFAULT_CALLSIGN "NOCALL"
#define DEFAULT_DESTINATION_CALL "APZMDM"
void ss_init(AX25Ctx *ax25);
void ss_messageCallback(struct AX25Msg *msg);
void ss_serialCallback(void *_buffer, size_t length, AX25Ctx *ctx);
void ss_sendPkt(void *_buffer, size_t length, AX25Ctx *ax25);
void ss_sendLoc(void *_buffer, size_t length, AX25Ctx *ax25);
void ss_sendMsg(void *_buffer, size_t length, AX25Ctx *ax25);
void ss_msgRetry(AX25Ctx *ax25);
void ss_clearSettings(void);
void ss_loadSettings(void);
void ss_saveSettings(void);
void ss_printSettings(void);
void ss_printHelp(void);
#endif

View File

@ -1,5 +1,5 @@
#define PROTOCOL_KISS 0x01
#define PROTOCOL_SIMPLE_SERIAL 0x02
#define PROTOCOL_RAW 0x02
#define m328p 0x01
#define m1284p 0x02

View File

@ -5,7 +5,7 @@
#include "device.h"
#define DIV_ROUND(dividend, divisor) (((dividend) + (divisor) / 2) / (divisor))
#define CLOCK_TICKS_PER_SEC CONFIG_AFSK_DAC_SAMPLERATE
#define CLOCK_TICKS_PER_SEC CONFIG_SAMPLERATE
typedef int32_t ticks_t;
typedef int32_t mtime_t;