diff --git a/QAPRSBase.cpp b/QAPRSBase.cpp new file mode 100644 index 0000000..53189df --- /dev/null +++ b/QAPRSBase.cpp @@ -0,0 +1,500 @@ +/* + Copyright (C) 2013 Lukasz Nidecki SQ5RWU + + This file is part of ArduinoQAPRS. + + ArduinoQAPRS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + ArduinoQAPRS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ArduinoQAPRS; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Ten plik jest częścią ArduinoQAPRS. + + ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej + i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, + wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej + Licencji lub (według twojego wyboru) którejś z późniejszych wersji. + + Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on + użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej + gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH + ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do + Powszechnej Licencji Publicznej GNU. + + Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz + Powszechnej Licencji Publicznej GNU (GNU General Public License); + jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple + Place, Fifth Floor, Boston, MA 02110-1301 USA + + */ + +/** + * @file + * @brief Implementacja klasy QAPRSBase + */ + +#include "QAPRSBase.h" + +QAPRSBase * QAPRSGlobalObject; +/** + * Czy można wysyłać dane? + * @return 1 jesli transmisja jest mozliwa, 0 w przeciwnym wypadku + */ +uint8_t QAPRSBase::canTransmit(){ + return 1; +} + +/** + * Rozpocznij nadawanie pakietu ax.25 + * Dodatkowo: + * - włącz nadawanie @see enableTransmission + * - zainicjalizuj crc i ton + * Ilosć bajtów synchronizacji okresla @see ax25HeaderFlagFieldCount + */ +void QAPRSBase::ax25SendHeaderBegin() { + this->enableTransmission(); + this->ax25CRC = 0xFFFF; + this->currentTone = QAPRSMark; + //this->currentTone = QAPRSSpace; + + + for (uint8_t i=0;iax25HeaderFlagFieldCount;i++) + { + this->ax25SendByte(this->ax25FlagFieldValue); + } +} + +/** + * Wyslij zakończenie pakietu, to jest 2 bajty sumy kontrolnej i znacznik końca pakietu @see QAPRSBase::ax25FlagFieldValue + */ +void QAPRSBase::ax25SendFooter() { + /** + * 16-bit CRC-CCITT + * MBS + LE!!! + * @see: http://www.tapr.org/pub_ax25.html#2.2.7 + * @see: http://www.tapr.org/pub_ax25.html#2.2.8 + */ + static uint8_t tmp; + tmp = (ax25CRC >> 8) ^ 0xff; + + this->ax25SendByte((this->ax25CRC) ^ 0xff); + this->ax25SendByte(tmp); + this->ax25SendByte(this->ax25FlagFieldValue); + this->disableTranssmision(); +} + +/** + * Wysyła bajt ax.25 + * @param byte Bajt do wysłania + */ +void QAPRSBase::ax25SendByte(uint8_t byte) { + static uint8_t i; + static uint8_t ls_bit; + static uint8_t is_flag; + static uint8_t bit_stuffing_counter; + + + // zapisujemy sobie czy nadawany bit nie jest aby flagą - bo ją nadajemy w specjalny sposób + is_flag = byte == this->ax25FlagFieldValue; + + for(i=0;i<8;i++){ + // nadawanie od najmniejznaczacego bitu + ls_bit = byte & 1; + + if (is_flag){ + bit_stuffing_counter = 0; + } else { + this->ax25CalcCRC(ls_bit); + } + + if (ls_bit){ + bit_stuffing_counter++; + if (bit_stuffing_counter == 5){ + // jesli mamy 5 bitow o wartosci 1 z rzedu to + delayuSeconds(this->_toneSendTime); + this->toggleTone(); + bit_stuffing_counter = 0; + } + } else { + bit_stuffing_counter = 0; + this->toggleTone(); + } + byte >>= 1; + delayuSeconds(this->_toneSendTime); + } +} + +/** + * Dodaje bit do sumy kontrolnej ramki + * @param ls_bit Bit danych + */ +void QAPRSBase::ax25CalcCRC(uint8_t ls_bit) { + static unsigned short crc_tmp; + + crc_tmp = this->ax25CRC ^ ls_bit; // XOR lsb of CRC with the latest bit + this->ax25CRC >>= 1; // Shift 16-bit CRC one bit to the right + + if (crc_tmp & 0x0001) // If XOR result from above has lsb set + { + this->ax25CRC ^= 0x8408; // Shift 16-bit CRC one bit to the right + } +} +/** + * Przełącz aktualnie generowany ton. @see QAPRSSendingTone + */ +inline void QAPRSBase::toggleTone() { + this->currentTone = (this->currentTone == QAPRSMark) ? QAPRSSpace : QAPRSMark; +} + +/** + * Inicjalizuj Timer1 który jest używany do generowania MARK i SPACE + */ +void QAPRSBase::initializeTimer1() { + noInterrupts(); + TIMSK1 |= _BV(TOIE1); + TCCR1A = 0; + TCCR1C = 0; + interrupts(); +} + +/** + * Inicjalizuj radio i piny. + */ +void QAPRSBase::initializeRadio() { + if (this->sensePin){ + pinMode(abs(this->sensePin), INPUT); + digitalWrite(abs(this->sensePin), LOW); + } + pinMode(abs(this->txEnablePin), OUTPUT); + + this->disableTranssmision(); + this->initializeTimer1(); +} + +/** + * Włącz nadawanie. Metoda dodatkowo realizuje opóźnienie nadawania jesli ustawiono. @see QAPRSBase::setTxDelay + */ +void QAPRSBase::enableTransmission() { + digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? HIGH : LOW); + this->doTxDelay(); +} + +/** + * Wyłącz nadawanie. + */ +void QAPRSBase::disableTranssmision() { + digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? LOW : HIGH); +} + +/** + * Wyslij bufor danych. @warning Ta metoda zakończy pracę na bajcie o wartosci 0 jesli wystąpi. + * @param buffer Bufor z danymi do wysłania + * @return + */ +QAPRSReturnCode QAPRSBase::send(char * buffer) { + return this->send(buffer, strlen(buffer)); +} + +/** + * Wyslij dane APRS. + * @param from_addr Adres [znak] źródłowy. Max 6 znaków! + * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' + * @param to_addr Adres [znak] docelowy. Max 6 znaków! + * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' + * @param packet_content Bufor z danymi pakietu APRS + * @return + */ +QAPRSReturnCode QAPRSBase::send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * packet_content) { + ax25BaseFrame * bf; + bf = (ax25BaseFrame *)tmpData; + memset(bf->from, ' ', 6); + strncpy(bf->from, from_addr,6); + memset(bf->to, ' ', 6); + strncpy(bf->to, to_addr, 6); + bf->to_ssid = to_ssid; + bf->from_ssid = from_ssid > '@' ? from_ssid - 6 : from_ssid;; + + strcpy(bf->packet_content, packet_content); + + bf->control_field = 0x03; + bf->protocolID = 0xf0; + + + uint8_t i; + for(i=0;i<14;i++){ + tmpData[i] = SHIFT_BYTE(tmpData[i]); + } + tmpData[13] |= 1; + + return this->send((char*)tmpData); +} + +/** + * Wysyła bufor danych o oznaczonej długosci. + * @param buffer Bufor z danymi do wysłania + * @param length Długosc bufora + * @return + */ +QAPRSReturnCode QAPRSBase::send(char* buffer, size_t length) { + int16_t timeout = this->channelFreeWaitingMS; + + while(timeout > 0){ + // jesli mozna nadawac to nadajemy + if (this->canTransmit()){ + this->ax25SendHeaderBegin(); + while(length--){ + this->ax25SendByte(*buffer); + buffer++; + } + this->ax25SendFooter(); + return QAPRSReturnOK; + } else { + // jesli nie mozna to czekamy 100ms i sprawdzamy ponownie + // maks. czas oczekiwania to channelFreeWaitingMS + delay(100); + timeout -= 100; + } + } + return QAPRSReturnErrorTimeout; +} + +/** + * Wyslij dane APRS. + * @param from_addr Adres [znak] źródłowy. Max 6 znaków! + * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' + * @param to_addr Adres [znak] docelowy. Max 6 znaków! + * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' + * @param relays Bufor z danymi przekaźników. Np. "WIDE1 1" @warning Jeżeli mają być podane 2 lub więcej pozycji to zapisujemy je BEZ przecinków itp. np. "WIDE1 1WIDE2 1" + * @param packet_content Bufor z danymi pakietu APRS + * @return + */ +QAPRSReturnCode QAPRSBase::send(char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays, char* packet_content) { + return this->send(from_addr, from_ssid, to_addr, to_ssid, relays, packet_content, strlen(packet_content)); +} + +/** + * Wyslij dane APRS. + * @param from_addr Adres [znak] źródłowy. Max 6 znaków! + * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' + * @param to_addr Adres [znak] docelowy. Max 6 znaków! + * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' + * @param relays Bufor z danymi przekaźników. Np. "WIDE1 1" @warning Jeżeli mają być podane 2 lub więcej pozycji to zapisujemy je BEZ przecinków itp. np. "WIDE1 1WIDE2 1" + * @param packet_content Bufor z danymi pakietu APRS + * @param length Długosć packet_content + * @return + */ +QAPRSReturnCode QAPRSBase::send(char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays, char* packet_content, size_t length) { + ax25CustomFrameHeader * bf; + bf = (ax25CustomFrameHeader *)tmpData; + memset(bf->from, ' ', 6); + strncpy(bf->from, from_addr,6); + memset(bf->to, ' ', 6); + strncpy(bf->to, to_addr, 6); + bf->to_ssid = to_ssid; + bf->from_ssid = from_ssid > '@' ? from_ssid - 6 : from_ssid; + + uint8_t relay_size = strlen(relays); + strcpy((char*)(tmpData+sizeof(ax25CustomFrameHeader)), relays); + + uint8_t i; + for(i=0;isend((char*)tmpData, (sizeof(ax25CustomFrameHeader)+relay_size+2+length)); +} + +/** + * Wysyła dane APRS @warning Ta metoda zakończy pracę na bajcie o wartosci 0 jesli wystąpi. + * @param buffer Bufor z częscią APRSową ramki - tzn. sam czyste dane APRS, bez SSIDów itp. + * @return Status operacji + */ +QAPRSReturnCode QAPRSBase::sendData(char* buffer) { + return this->send((char*)this->from_addr, this->from_ssid, (char*)this->to_addr, this->to_ssid, (char*)this->relays, buffer); +} + +/** + * Wysyła dane APRS + * @param buffer Bufor z częscią APRSową ramki - tzn. sam czyste dane APRS, bez SSIDów itp. + * @param length Długosć bufora + * @return Status operacji + */ +QAPRSReturnCode QAPRSBase::sendData(char* buffer, size_t length) { + return this->send((char*)this->from_addr, this->from_ssid, (char*)this->to_addr, this->to_ssid, (char*)this->relays, buffer, length); +} + +/** + * Inicjalizacja biblioteki + * @param sensePin Pin [we] Arduino na którym 0 oznacza zgodę na nadwanie a 1 jej brak. + Podanie 0 jako numeru pinu powoduje WYŁACZENIE wykrywania nadawania i zmusza programistę do samodzielnej jego obsługi! + * @param txEnablePin Pin [wy] Arduino na którym 1 oznacza nadawanie + */ +void QAPRSBase::init(int8_t sensePin, int8_t txEnablePin) { + QAPRSGlobalObject = this; + this->sensePin = sensePin; + this->txEnablePin = txEnablePin; + this->txDelay = this->defaultTxDelay; + this->setVariant(); + + this->initializeRadio(); +} + +/** + * Zainicjuj bibliotekę na potrzeby metody sendData @see QAPRSBase::sendData + * @param sensePin sensePin Pin [we] Arduino na którym 0 oznacza zgodę na nadwanie a 1 jej brak. + Podanie 0 jako numeru pinu powoduje WYŁACZENIE wykrywania nadawania i zmusza programistę do samodzielnej jego obsługi! + * @param txEnablePin Pin [wy] Arduino na którym 1 oznacza nadawanie + * @param from_addr Adres [znak] źródłowy. Max 6 znaków! + * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' + * @param to_addr Adres [znak] docelowy. Max 6 znaków! + * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' + * @param relays Ścieżki (relaye) np. "WIDE1-1,WIDE2-1". max 3 człony oddzielone przecinkami! + */ +void QAPRSBase::init(int8_t sensePin, int8_t txEnablePin, char* from_addr, uint8_t from_ssid, char* to_addr, uint8_t to_ssid, char* relays) { + this->init(sensePin, txEnablePin); + this->setFromAddress(from_addr, from_ssid); + this->setToAddress(to_addr, to_ssid); + this->setRelays(relays); +} + +/** + * Ustaw adres docelowy na potrzeby metody sendData + * @param from_addr Adres [znak] źródłowy. Max 6 znaków! + * @param from_ssid SSID stacji źródłowej: bajty od '0' do 'F' + */ +void QAPRSBase::setFromAddress(char* from_addr, uint8_t from_ssid) { + memset(this->from_addr, ' ', 6); + strcpy(this->from_addr, from_addr); + this->from_ssid = from_ssid; +} + +/** + * Ustaw adres docelowy na potrzeby metody sendData + * @param to_addr Adres [znak] docelowy. Max 6 znaków! + * @param to_ssid SSID stacji docelowej: bajty od '0' do 'F' + */ +void QAPRSBase::setToAddress(char* to_addr, uint8_t to_ssid) { + memset(this->to_addr, ' ', 6); + strcpy(this->to_addr, to_addr); + this->to_ssid = to_ssid; +} + +/** + * Przetwórz zapis scieżek (relayów) z formatu ludzkiego na format do ramki ax.25 + * @param relays np. "WIDE1-1,WIDE2-1". max 3 człony oddzielone przecinkami! @see http://www.aprs.pl/sciezka.htm + * @param dst + */ +void QAPRSBase::parseRelays(const char* relays, char* dst) { + uint8_t relays_len = strlen(relays); + uint8_t relays_ptr = 0; + uint8_t dst_ptr = 0; + uint8_t fill_length = 0; + + for(relays_ptr=0;relays_ptr 7 && dst_ptr < 7+7){ + fill_length = 7+7 - dst_ptr; + } else if(dst_ptr > 7+7 && dst_ptr < 7+7+7){ + fill_length = 7+7+7 - dst_ptr; + } + while(fill_length){ + dst[dst_ptr] = ' '; + fill_length--; + dst_ptr++; + } + } else { + dst[dst_ptr] = relays[relays_ptr] == '-' ? ' ' : relays[relays_ptr]; // zamiana ',' na ' ' + dst_ptr++; + } + } + dst[dst_ptr] = 0; +} + +/** + * Realizuje opóźnienie jeżeli zostało ustawione + */ +void QAPRSBase::doTxDelay() { + if (this->txDelay){ + delay(this->txDelay); + } +} + +void QAPRSBase::setVariant(QAPRSVariant variant) { + this->variant = variant; + switch(variant){ + case QAPRSVHF: + this->_toneSendTime = this->toneSendTime1200; + this->ax25HeaderFlagFieldCount = this->ax25HeaderFlagFieldCount1200; + break; + case QAPRSHF: + this->_toneSendTime = this->toneSendTime300; + this->ax25HeaderFlagFieldCount = this->ax25HeaderFlagFieldCount300; + break; + } +} + +/** + * Ustaw scieżki (relaye) na potrzeby metody sendData @see QAPRSBase::sendData + * @param relays + */ +void QAPRSBase::setRelays(char* relays) { + this->parseRelays(relays, (char*)this->relays); +} + + +/** + * Funkcja opóźniająca. W odróżnieniu do delayMicroseconds z Arduino ta funkcja sprawdza prawdziwy czas. + * @param us + */ +void QAPRSBase::delayuSeconds(uint16_t us) { + unsigned long time = micros(); + while(micros() - time < us){ + //asm("nop"); + } +} + + +/** + * Ustaw czas zwłoki pomiędzy włączeniem nadawania a rozpoczęciem generowania sygnału + * @param txDelay Czas w ms + */ +void QAPRSBase::setTxDelay(uint16_t txDelay) { + this->txDelay = txDelay; +} + +ISR (TIMER1_OVF_vect) // timer1 overflow interrupt +{ + QAPRSGlobalObject->timerInterruptHandler(); +} + + + + + + diff --git a/QAPRSBase.h b/QAPRSBase.h new file mode 100644 index 0000000..236e2d1 --- /dev/null +++ b/QAPRSBase.h @@ -0,0 +1,188 @@ +/* + Copyright (C) 2013 Lukasz Nidecki SQ5RWU + + This file is part of ArduinoQAPRS. + + ArduinoQAPRS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + ArduinoQAPRS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ArduinoQAPRS; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej + i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, + wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej + Licencji lub (według twojego wyboru) którejś z późniejszych wersji. + + Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on + użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej + gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH + ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do + Powszechnej Licencji Publicznej GNU. + + Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz + Powszechnej Licencji Publicznej GNU (GNU General Public License); + jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple + Place, Fifth Floor, Boston, MA 02110-1301 USA + + */ + +/** + * @file + * @brief Nagłówki dla klasy QAPRSBase + */ + +#ifndef QAPRSBASE_H_ +#define QAPRSBASE_H_ + +#include "QAPRSCommon.h" + +/** + * @brief Klasa bazowa do nadawania APRS + * @details Klasa słuzy jako baza do podimplemntacji generowania AFSK. + */ +class QAPRSBase { +private: + /** + * @brief suma kontrolna pakietu + */ + uint16_t ax25CRC; + /** + * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu + */ + static const uint8_t ax25HeaderFlagFieldCount1200 = 65; + /** + * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu + */ + static const uint8_t ax25HeaderFlagFieldCount300 = 45; + /** + * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu + */ + uint8_t ax25HeaderFlagFieldCount; + /** + * @brief Flaga + * @details + */ + static const uint8_t ax25FlagFieldValue = 0x7E; + /** + * @brief Czas wysyłania podedynczego tonu. W ms. + * @details Czas calkowity powinien wynosic 833ms. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem + * funkcji itp. + */ +#if F_CPU == 16000000L + static const uint16_t toneSendTime1200 = 815; +#elif F_CPU == 8000000UL + static const uint16_t toneSendTime1200 = 785; +#endif + /** + * @brief Czas wysyłania podedynczego tonu. W ms. + * @details Czas calkowity powinien wynosic 4*833ms. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem + * funkcji itp. + */ + static const uint16_t toneSendTime300 = 815 + 3 * 833; + /** + * @brief Czas oczekiwania na zwolnienie kanału. + * @details Co 100ms sprawdzamy czy można już nadawać @see canTransmit + */ + static const uint16_t channelFreeWaitingMS = 2000; // 2000 ms + /** + * @brief Domylslny czas pomiędzy włączeniem nadawania a rozpoczęciem generowania AFSK + */ + static const uint16_t defaultTxDelay = 300; // 300 ms + /** + * @brief Pin Arduino na którym ustawiamy logiczną 1 w momencie nadawania + */ + int8_t txEnablePin; + /** + * @brief Bufor tymczasowy + */ + uint8_t tmpData[255]; + /** + * @brief Opóźnienie w ms pomiędzy ustawieniem stanu wysokiego na wyjsciu txEnablePin a rozpoczęciem generowania AFSK + */ + uint16_t txDelay; + /** + * @brief + */ + char from_addr[6]; + /** + * @brief + */ + uint8_t from_ssid; + /** + * @brief + */ + char to_addr[6]; + /** + * @brief + */ + uint8_t to_ssid; + /** + * @brief + */ + char* relays[3*7]; + + virtual uint8_t canTransmit(); + void ax25SendHeaderBegin(); + void ax25SendByte(uint8_t byte); + void ax25SendFooter(); + void ax25CalcCRC(uint8_t ls_bit); + void parseRelays(const char * relays, char * dst); +protected: + /** + * @brief Pin Arduino [we] który musi być w stanie niskim (lub wysokim, jesli numer jest ujemny) aby rozpocząć nadawanie. + */ + int8_t sensePin; + /** + * @brief Obecnie generowany ton + */ + QAPRSSendingTone currentTone; + uint16_t _toneSendTime; + /** + * @brief Obecnie używany wariant + */ + QAPRSVariant variant; + + virtual void initializeRadio(); + virtual void enableTransmission(); + virtual void disableTranssmision(); + + virtual void toggleTone(); + virtual void initializeTimer1(); + void delayuSeconds(uint16_t us); + void doTxDelay(); +public: + QAPRSBase() {}; + QAPRSReturnCode send(char * buffer); + QAPRSReturnCode send(char * buffer, size_t length); + QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * packet_content); + QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays, char * packet_content); + QAPRSReturnCode send(char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays, char * packet_content, size_t length); + QAPRSReturnCode sendData(char * buffer); + QAPRSReturnCode sendData(char * buffer, size_t length); + + virtual void init(int8_t sensePin, int8_t txEnablePin); + virtual void init(int8_t sensePin, int8_t txEnablePin, char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays); + + void setTxDelay(uint16_t txDelay); + virtual void timerInterruptHandler() {}; + void setFromAddress(char * from_addr, uint8_t from_ssid); + void setToAddress(char * to_addr, uint8_t to_ssid); + void setRelays(char * relays); + virtual void setVariant(QAPRSVariant variant = QAPRSVHF); +}; + +/** + * @brief Przesuń bajt o 1 bit w lewo. Używane w nagłówku ax.25 + */ +#define SHIFT_BYTE(x) (x << 1) + +#endif /* QAPRSBASE_H_ */ diff --git a/QAPRSCommon.h b/QAPRSCommon.h new file mode 100644 index 0000000..4bb29d1 --- /dev/null +++ b/QAPRSCommon.h @@ -0,0 +1,100 @@ +/* + Copyright (C) 2013 Lukasz Nidecki SQ5RWU + + This file is part of ArduinoQAPRS. + + ArduinoQAPRS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + ArduinoQAPRS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ArduinoQAPRS; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Ten plik jest częścią ArduinoQAPRS. + + ArduinoQAPRS jest wolnym oprogramowaniem; możesz go rozprowadzać dalej + i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, + wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej + Licencji lub (według twojego wyboru) którejś z późniejszych wersji. + + Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on + użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej + gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH + ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do + Powszechnej Licencji Publicznej GNU. + + Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz + Powszechnej Licencji Publicznej GNU (GNU General Public License); + jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple + Place, Fifth Floor, Boston, MA 02110-1301 USA + + */ + +/** + * @file + * @brief Wspóldzielone definicje + */ + +#ifndef QAPRSCOMMON_H_ +#define QAPRSCOMMON_H_ + +#include + +/** + * @brief Wyniki zwracane przez metodę send + */ +enum QAPRSReturnCode { + QAPRSReturnOK = 0, //!< Powodzenie + QAPRSReturnError = 1, //!< Nieokreslony błąd + QAPRSReturnErrorTimeout = 2//!< Timeout w oczekiwaniu na nadawanie +}; + +/** + * @brief Generowane znaczniki + */ +enum QAPRSSendingTone { + QAPRSMark = 1, //!< Mark (1200Hz) + QAPRSSpace = 2 //!< Space (2200Hz) +}; + +/** + * @brief Generowane znaczniki + */ +enum QAPRSVariant { + QAPRSVHF = 1, //!< VHF - 1200bodów, 1200Hz/2200Hz + QAPRSHF = 2 //!< HF - 300bodów, 1600Hz/1800Hz +}; + +/** + * @brief Struktura definująca podstawową ramkę ax.25 (bez realyów) + */ +typedef struct { + char to[6]; //!< Odbiorca pakietu [znak] + uint8_t to_ssid; //!< SSID odbiorcy pakietu + char from[6]; //!< Nadawca pakietu [znak] + uint8_t from_ssid; //!< SSID nadawcy pakietu + uint8_t control_field; //!< Pole kontrolne ustawiane zawsze na 0x03 - UI @see http://www.tapr.org/pub_ax25.html#2.3.4.2 + uint8_t protocolID; //!< Id protokolu zawsze 0xf0 - bez warstwy 3 OSI @see http://www.tapr.org/pub_ax25.html#2.2.4 + char packet_content[]; //!< Zawartosć pakietu. Dane APRS +} ax25BaseFrame; + +/** + * @brief Struktura definiujaca poczatek ramki ax.25 + */ +typedef struct { + char to[6]; //!< Odbiorca pakietu [znak] + uint8_t to_ssid; //!< SSID odbiorcy pakietu + char from[6]; //!< Nadawca pakietu [znak] + uint8_t from_ssid; //!< SSID nadawcy pakietu +} ax25CustomFrameHeader; + + + +#endif /* QAPRSCOMMON_H_ */ diff --git a/rtty.coproj b/rtty.coproj index dd69aec..b6b6b1e 100644 --- a/rtty.coproj +++ b/rtty.coproj @@ -162,8 +162,8 @@ - + @@ -171,11 +171,12 @@ + - - + + @@ -187,24 +188,26 @@ + - + - + + \ No newline at end of file