Compare commits
27 commits
master
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5cab765b8c | ||
![]() |
a84d38a93d | ||
![]() |
4f940dbdd5 | ||
![]() |
8c2375298b | ||
![]() |
2efd020ea1 | ||
![]() |
5ebf74ee2b | ||
![]() |
97136945a7 | ||
![]() |
030ea09c17 | ||
![]() |
c972587d84 | ||
![]() |
8a791d269e | ||
![]() |
43eefd4703 | ||
![]() |
f371c2d213 | ||
![]() |
1155851481 | ||
![]() |
f349fbc3f0 | ||
![]() |
ef9cd033e9 | ||
![]() |
07637feef6 | ||
![]() |
da5eb14867 | ||
![]() |
1d46b3e2ab | ||
![]() |
f9f8ad526a | ||
![]() |
8923d9b8e5 | ||
![]() |
8c1b0a72bc | ||
![]() |
59a7d8e013 | ||
![]() |
bb54239095 | ||
![]() |
7db24913cb | ||
![]() |
f9958ff83d | ||
![]() |
f85e7b2489 | ||
![]() |
05498c2598 |
15 changed files with 1527 additions and 0 deletions
|
@ -0,0 +1,16 @@
|
|||
#define RADIOLIB_GODMODE
|
||||
#include <RadioLib.h>
|
||||
|
||||
SX1268 lora = new Module(10, 2, 3, 9);
|
||||
|
||||
LoRaWANNode node(&lora, &EU868);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.println(node._band->uplinkDefault[0].freqStart);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
|
||||
}
|
78
examples/Pager/Pager_Transmit/Pager_Transmit.ino
Normal file
78
examples/Pager/Pager_Transmit/Pager_Transmit.ino
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
RadioLib Pager (POCSAG) Transmit Example
|
||||
|
||||
This example sends POCSAG messages using SX1278's
|
||||
FSK modem.
|
||||
|
||||
Other modules that can be used for POCSAG:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 module is in slot A on the shield
|
||||
SX1278 fsk = RadioShield.ModuleA;
|
||||
|
||||
// create Pager client instance using the FSK module
|
||||
PagerClient pager(&fsk);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bit rate: 48.0 kbps
|
||||
// frequency deviation: 50.0 kHz
|
||||
// Rx bandwidth: 125.0 kHz
|
||||
// output power: 13 dBm
|
||||
// current limit: 100 mA
|
||||
// sync word: 0x2D 0x01
|
||||
int state = fsk.beginFSK();
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
|
||||
// initalize Pager client
|
||||
Serial.print(F("[Pager] Initializing ... "));
|
||||
// base (center) frequency: 434.0 MHz
|
||||
// speed: 1200 bps
|
||||
state = pager.begin(434.0, 1200);
|
||||
if(state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while(true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// transmit numeric (BCD) message to the destination pager
|
||||
Serial.print(F("[Pager] Transmitting message ... "));
|
||||
int state = pager.transmit("0123456789*U -()", 0x01234567);
|
||||
// NOTE: Only characters 0123456789*U-() and space
|
||||
// can be sent in a BCD message! To send ASCII
|
||||
// characters, you have to set encoding to ASCII.
|
||||
/*
|
||||
int state = pager.transmit("Hello World!", 0x01234567, ASCII);
|
||||
*/
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
47
examples/SIM800/SIM800_SMS_Send/SIM800_SMS_Send.ino
Normal file
47
examples/SIM800/SIM800_SMS_Send/SIM800_SMS_Send.ino
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
RadioLib SIM800 Send SMS Example
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SIM800 has the following connections:
|
||||
// TX pin: 9
|
||||
// RX pin: 8
|
||||
SIM800 gsm = new Module(9, 8);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//SIM800 gsm = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SIM800 with default settings
|
||||
Serial.print(F("[SIM800] Initializing ... "));
|
||||
// baudrate: 9600 baud
|
||||
int state = gsm.begin(9600);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send SMS to number 0123456789
|
||||
Serial.print(F("[SIM800] Sending SMS ... "));
|
||||
int state = gsm.sendSMS("774313955", "Hello World!");
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait 10 seconds before sending again
|
||||
//delay(10000);
|
||||
while(true);
|
||||
}
|
12
src/modules/AX5243/AX5243.cpp
Normal file
12
src/modules/AX5243/AX5243.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "AX5243.h"
|
||||
#if !defined(RADIOLIB_EXCLUDE_AX5243)
|
||||
|
||||
AX5243::AX5243(Module* module) : PhysicalLayer(AX5243_FREQUENCY_STEP_SIZE, AX5243_MAX_PACKET_LENGTH) {
|
||||
_mod = module;
|
||||
}
|
||||
|
||||
int16_t AX5243::begin() {
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
#endif
|
263
src/modules/AX5243/AX5243.h
Normal file
263
src/modules/AX5243/AX5243.h
Normal file
|
@ -0,0 +1,263 @@
|
|||
#if !defined(_RADIOLIB_AX5243_H) && !defined(RADIOLIB_EXCLUDE_AX5243)
|
||||
#define _RADIOLIB_AX5243_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../../Module.h"
|
||||
|
||||
#include "../../protocols/PhysicalLayer/PhysicalLayer.h"
|
||||
|
||||
// AX5243 physical layer properties
|
||||
#define AX5243_FREQUENCY_STEP_SIZE (0.98)
|
||||
#define AX5243_MAX_PACKET_LENGTH (256)
|
||||
|
||||
// AX5243 register map
|
||||
#define AX5243_REG_REVISION (0x0000)
|
||||
#define AX5243_REG_SCRATCH (0x0001)
|
||||
#define AX5243_REG_PWR_MODE (0x0002)
|
||||
#define AX5243_REG_POW_STAT (0x0003)
|
||||
#define AX5243_REG_POW_STICKY_STAT (0x0004)
|
||||
#define AX5243_REG_POW_IRQ_MASK (0x0005)
|
||||
#define AX5243_REG_IRQ_MASK_1 (0x0006)
|
||||
#define AX5243_REG_IRQ_MASK_0 (0x0007)
|
||||
#define AX5243_REG_RADIO_EVENTS_MASK_1 (0x0008)
|
||||
#define AX5243_REG_RADIO_EVENTS_MASK_0 (0x0009)
|
||||
#define AX5243_REG_IRQ_INVERSION_1 (0x000A)
|
||||
#define AX5243_REG_IRQ_INVERSION_0 (0x000B)
|
||||
#define AX5243_REG_IRQ_REQUEST_1 (0x000C)
|
||||
#define AX5243_REG_IRQ_REQUEST_0 (0x000D)
|
||||
#define AX5243_REG_RADIO_EVENT_REQ_1 (0x000E)
|
||||
#define AX5243_REG_RADIO_EVENT_REQ_0 (0x000F)
|
||||
#define AX5243_REG_MODULATION (0x0010)
|
||||
#define AX5243_REG_ENCODING (0x0011)
|
||||
#define AX5243_REG_FRAMING (0x0012)
|
||||
#define AX5243_REG_CRC_INIT_3 (0x0014)
|
||||
#define AX5243_REG_CRC_INIT_2 (0x0015)
|
||||
#define AX5243_REG_CRC_INIT_1 (0x0016)
|
||||
#define AX5243_REG_CRC_INIT_0 (0x0017)
|
||||
#define AX5243_REG_FEC (0x0018)
|
||||
#define AX5243_REG_FEC_SYNC (0x0019)
|
||||
#define AX5243_REG_FEC_STATUS (0x001A)
|
||||
#define AX5243_REG_RADIO_STATE (0x001C)
|
||||
#define AX5243_REG_XTAL_STATUS (0x001D)
|
||||
#define AX5243_REG_PIN_STATE (0x0020)
|
||||
#define AX5243_REG_PIN_FUNC_SYSCLK (0x0021)
|
||||
#define AX5243_REG_PIN_FUNC_DCLK (0x0022)
|
||||
#define AX5243_REG_PIN_FUNC_DATA (0x0023)
|
||||
#define AX5243_REG_PIN_FUNC_IRQ (0x0024)
|
||||
#define AX5243_REG_PIN_FUNC_ANTSEL (0x0025)
|
||||
#define AX5243_REG_PIN_FUNC_PWRAMP (0x0026)
|
||||
#define AX5243_REG_PWRAMP (0x0027)
|
||||
#define AX5243_REG_FIFO_STAT (0x0028)
|
||||
#define AX5243_REG_FIFO_DATA (0x0029)
|
||||
#define AX5243_REG_FIFO_COUNT_1 (0x002A)
|
||||
#define AX5243_REG_FIFO_COUNT_0 (0x002B)
|
||||
#define AX5243_REG_FIFO_FREE_1 (0x002C)
|
||||
#define AX5243_REG_FIFO_FREE_0 (0x002D)
|
||||
#define AX5243_REG_FIFO_THRESH_1 (0x002E)
|
||||
#define AX5243_REG_FIFO_THRESH_0 (0x002F)
|
||||
#define AX5243_REG_PLL_LOOP (0x0030)
|
||||
#define AX5243_REG_PLL_CPI (0x0031)
|
||||
#define AX5243_REG_PLL_VCO_DIV (0x0032)
|
||||
#define AX5243_REG_PLL_RANGING_A (0x0033)
|
||||
#define AX5243_REG_FREQ_A_3 (0x0034)
|
||||
#define AX5243_REG_FREQ_A_2 (0x0035)
|
||||
#define AX5243_REG_FREQ_A_1 (0x0036)
|
||||
#define AX5243_REG_FREQ_A_0 (0x0037)
|
||||
#define AX5243_REG_PLL_LOOP_BOOST (0x0038)
|
||||
#define AX5243_REG_PLL_CPI_BOOST (0x0039)
|
||||
#define AX5243_REG_PLL_RANGING_B (0x003B)
|
||||
#define AX5243_REG_FREQ_B_3 (0x003C)
|
||||
#define AX5243_REG_FREQ_B_2 (0x003D)
|
||||
#define AX5243_REG_FREQ_B_1 (0x003E)
|
||||
#define AX5243_REG_FREQ_B_0 (0x003F)
|
||||
#define AX5243_REG_RSSI (0x0040)
|
||||
#define AX5243_REG_BGND_RSSI (0x0041)
|
||||
#define AX5243_REG_DIVERSITY (0x0042)
|
||||
#define AX5243_REG_AGC_COUNTER (0x0043)
|
||||
#define AX5243_REG_TRK_DATARATE_2 (0x0045)
|
||||
#define AX5243_REG_TRK_DATARATE_1 (0x0046)
|
||||
#define AX5243_REG_TRK_DATARATE_0 (0x0047)
|
||||
#define AX5243_REG_TRK_AMPL_1 (0x0048)
|
||||
#define AX5243_REG_TRK_AMPL_0 (0x0049)
|
||||
#define AX5243_REG_TRK_PHASE_1 (0x004A)
|
||||
#define AX5243_REG_TRK_PHASE_0 (0x004B)
|
||||
#define AX5243_REG_TRK_RF_FREQ_2 (0x004D)
|
||||
#define AX5243_REG_TRK_RF_FREQ_1 (0x004E)
|
||||
#define AX5243_REG_TRK_RF_FREQ_0 (0x004F)
|
||||
#define AX5243_REG_TRK_FREQ_2 (0x0050)
|
||||
#define AX5243_REG_TRK_FREQ_1 (0x0051)
|
||||
#define AX5243_REG_TRK_FSK_DEMOD_1 (0x0052)
|
||||
#define AX5243_REG_TRK_FSK_DEMOD_0 (0x0053)
|
||||
#define AX5243_REG_TIMER_2 (0x0059)
|
||||
#define AX5243_REG_TIMER_1 (0x005A)
|
||||
#define AX5243_REG_TIMER_0 (0x005B)
|
||||
#define AX5243_REG_WAKEUP_TIMER_1 (0x0068)
|
||||
#define AX5243_REG_WAKEUP_TIMER_0 (0x0069)
|
||||
#define AX5243_REG_WAKEUP_1 (0x006A)
|
||||
#define AX5243_REG_WAKEUP_0 (0x006B)
|
||||
#define AX5243_REG_WAKEUP_FREQ_1 (0x006C)
|
||||
#define AX5243_REG_WAKEUP_FREQ_0 (0x006D)
|
||||
#define AX5243_REG_WAKEUP_XO_EARLY (0x006E)
|
||||
#define AX5243_REG_IF_FREQ_1 (0x0100)
|
||||
#define AX5243_REG_IF_FREQ_0 (0x0101)
|
||||
#define AX5243_REG_DECIMATION (0x0102)
|
||||
#define AX5243_REG_RX_DATA_RATE_2 (0x0103)
|
||||
#define AX5243_REG_RX_DATA_RATE_1 (0x0104)
|
||||
#define AX5243_REG_RX_DATA_RATE_0 (0x0105)
|
||||
#define AX5243_REG_MAX_DR_OFFSET_2 (0x0106)
|
||||
#define AX5243_REG_MAX_DR_OFFSET_1 (0x0107)
|
||||
#define AX5243_REG_MAX_DR_OFFSET_0 (0x0108)
|
||||
#define AX5243_REG_MAX_RF_OFFSET_2 (0x0109)
|
||||
#define AX5243_REG_MAX_RF_OFFSET_1 (0x010A)
|
||||
#define AX5243_REG_MAX_RF_OFFSET_0 (0x010B)
|
||||
#define AX5243_REG_FSK_DMAX_1 (0x010C)
|
||||
#define AX5243_REG_FSK_DMAX_0 (0x010D)
|
||||
#define AX5243_REG_FSK_DMIN_1 (0x010E)
|
||||
#define AX5243_REG_FSK_DMIN_0 (0x010F)
|
||||
#define AX5243_REG_AFSK_SPACE_1 (0x0110)
|
||||
#define AX5243_REG_AFSK_SPACE_0 (0x0111)
|
||||
#define AX5243_REG_AFSK_MARK_1 (0x0112)
|
||||
#define AX5243_REG_AFSK_MARK_0 (0x0113)
|
||||
#define AX5243_REG_AFSK_CTRL (0x0114)
|
||||
#define AX5243_REG_AMPL_FILTER (0x0115)
|
||||
#define AX5243_REG_FREQUENCY_LEAK (0x0116)
|
||||
#define AX5243_REG_RX_PARAM_SETS (0x0117)
|
||||
#define AX5243_REG_RX_PARAM_CUR_SET (0x0118)
|
||||
#define AX5243_REG_RX_PARAM_SET_0 (0x0120)
|
||||
#define AX5243_REG_RX_PARAM_SET_1 (0x0130)
|
||||
#define AX5243_REG_RX_PARAM_SET_2 (0x0140)
|
||||
#define AX5243_REG_RX_PARAM_SET_3 (0x0150)
|
||||
#define AX5243_REG_RXPAR_AGC_GAIN (0x0000)
|
||||
#define AX5243_REG_RXPAR_AGC_TARGET (0x0001)
|
||||
#define AX5243_REG_RXPAR_AGC_HYST (0x0002)
|
||||
#define AX5243_REG_RXPAR_AGC_MIN_MAX (0x0003)
|
||||
#define AX5243_REG_RXPAR_TIME_GAIN (0x0004)
|
||||
#define AX5243_REG_RXPAR_DR_GAIN (0x0005)
|
||||
#define AX5243_REG_RXPAR_PHASE_GAIN (0x0006)
|
||||
#define AX5243_REG_RXPAR_FREQ_GAIN_A (0x0007)
|
||||
#define AX5243_REG_RXPAR_FREQ_GAIN_B (0x0008)
|
||||
#define AX5243_REG_RXPAR_FREQ_GAIN_C (0x0009)
|
||||
#define AX5243_REG_RXPAR_FREQ_GAIN_D (0x000A)
|
||||
#define AX5243_REG_RXPAR_AMPL_GAIN (0x000B)
|
||||
#define AX5243_REG_RXPAR_FREQ_DEV_1 (0x000C)
|
||||
#define AX5243_REG_RXPAR_FREQ_DEV_0 (0x000D)
|
||||
#define AX5243_REG_RXPAR_FOUR_FSK (0x000E)
|
||||
#define AX5243_REG_RXPAR_BB_OFFS_RES (0x000F)
|
||||
#define AX5243_REG_MOD_CFG_F (0x0160)
|
||||
#define AX5243_REG_FSK_DEV_2 (0x0161)
|
||||
#define AX5243_REG_FSK_DEV_1 (0x0162)
|
||||
#define AX5243_REG_FSK_DEV_0 (0x0163)
|
||||
#define AX5243_REG_MOD_CFG_A (0x0164)
|
||||
#define AX5243_REG_TX_RATE_2 (0x0165)
|
||||
#define AX5243_REG_TX_RATE_1 (0x0166)
|
||||
#define AX5243_REG_TX_RATE_0 (0x0167)
|
||||
#define AX5243_REG_TX_PWR_COEFF_A_1 (0x0168)
|
||||
#define AX5243_REG_TX_PWR_COEFF_A_0 (0x0169)
|
||||
#define AX5243_REG_TX_PWR_COEFF_B_1 (0x016A)
|
||||
#define AX5243_REG_TX_PWR_COEFF_B_0 (0x016B)
|
||||
#define AX5243_REG_TX_PWR_COEFF_C_1 (0x016C)
|
||||
#define AX5243_REG_TX_PWR_COEFF_C_0 (0x016D)
|
||||
#define AX5243_REG_TX_PWR_COEFF_D_1 (0x016E)
|
||||
#define AX5243_REG_TX_PWR_COEFF_D_0 (0x016F)
|
||||
#define AX5243_REG_TX_PWR_COEFF_E_1 (0x0170)
|
||||
#define AX5243_REG_TX_PWR_COEFF_E_0 (0x0171)
|
||||
#define AX5243_REG_PLL_VCO_I (0x0180)
|
||||
#define AX5243_REG_PLL_VCO_IR (0x0181)
|
||||
#define AX5243_REG_PLL_LOCK_DET (0x0182)
|
||||
#define AX5243_REG_PLL_RNG_CLK (0x0183)
|
||||
#define AX5243_REG_XTAL_CAP (0x0184)
|
||||
#define AX5243_REG_BB_TUNE (0x0188)
|
||||
#define AX5243_REG_BB_OFFS_CAP (0x0189)
|
||||
#define AX5243_REG_PKT_ADDR_CFG (0x0200)
|
||||
#define AX5243_REG_PKT_LEN_CFG (0x0201)
|
||||
#define AX5243_REG_PKT_LEN_OFFSET (0x0202)
|
||||
#define AX5243_REG_PKT_MAX_LEN (0x0203)
|
||||
#define AX5243_REG_PKT_ADDR_3 (0x0204)
|
||||
#define AX5243_REG_PKT_ADDR_2 (0x0205)
|
||||
#define AX5243_REG_PKT_ADDR_1 (0x0206)
|
||||
#define AX5243_REG_PKT_ADDR_0 (0x0207)
|
||||
#define AX5243_REG_PKT_ADDR_MASK_3 (0x0208)
|
||||
#define AX5243_REG_PKT_ADDR_MASK_2 (0x0209)
|
||||
#define AX5243_REG_PKT_ADDR_MASK_1 (0x020A)
|
||||
#define AX5243_REG_PKT_ADDR_MASK_0 (0x020B)
|
||||
#define AX5243_REG_MATCH_0_PAT_3 (0x0210)
|
||||
#define AX5243_REG_MATCH_0_PAT_2 (0x0211)
|
||||
#define AX5243_REG_MATCH_0_PAT_1 (0x0212)
|
||||
#define AX5243_REG_MATCH_0_PAT_0 (0x0213)
|
||||
#define AX5243_REG_MATCH_0_LEN (0x0214)
|
||||
#define AX5243_REG_MATCH_0_MIN (0x0215)
|
||||
#define AX5243_REG_MATCH_0_MAX (0x0216)
|
||||
#define AX5243_REG_MATCH_1_PAT_1 (0x0218)
|
||||
#define AX5243_REG_MATCH_1_PAT_0 (0x0219)
|
||||
#define AX5243_REG_MATCH_1_LEN (0x021C)
|
||||
#define AX5243_REG_MATCH_1_MIN (0x021D)
|
||||
#define AX5243_REG_MATCH_1_MAX (0x021E)
|
||||
#define AX5243_REG_TMG_TX_BOOST (0x0220)
|
||||
#define AX5243_REG_TMG_TX_SETTLE (0x0221)
|
||||
#define AX5243_REG_TMG_RX_BOOST (0x0223)
|
||||
#define AX5243_REG_TMG_RX_SETTLE (0x0224)
|
||||
#define AX5243_REG_TMG_RX_OFFS_ACQ (0x0225)
|
||||
#define AX5243_REG_TMG_RX_COARSE_ACQ (0x0226)
|
||||
#define AX5243_REG_TMG_RX_AGC (0x0227)
|
||||
#define AX5243_REG_TMG_RX_RSSI (0x0228)
|
||||
#define AX5243_REG_TMG_RX_PREAMBLE_1 (0x0229)
|
||||
#define AX5243_REG_TMG_RX_PREAMBLE_2 (0x022A)
|
||||
#define AX5243_REG_TMG_RX_PREAMBLE_3 (0x022B)
|
||||
#define AX5243_REG_RSSI_REFERENCE (0x022C)
|
||||
#define AX5243_REG_RSSI_ABS_THR (0x022D)
|
||||
#define AX5243_REG_BGND_RSSI_GAIN (0x022E)
|
||||
#define AX5243_REG_BGND_RSSI_THR (0x022F)
|
||||
#define AX5243_REG_PKT_CHUNK_SIZE (0x0230)
|
||||
#define AX5243_REG_PKT_MISC_FLAGS (0x0231)
|
||||
#define AX5243_REG_PKT_STORE_FLAGS (0x0232)
|
||||
#define AX5243_REG_PKT_ACCEPT_FLAGS (0x0233)
|
||||
#define AX5243_REG_GP_ADC_CTRL (0x0300)
|
||||
#define AX5243_REG_GP_ADC_PERIOD (0x0301)
|
||||
#define AX5243_REG_GP_ADC_13_VALUE_1 (0x0308)
|
||||
#define AX5243_REG_GP_ADC_13_VALUE_0 (0x0309)
|
||||
#define AX5243_REG_LP_OSC_CONFIG (0x0310)
|
||||
#define AX5243_REG_LP_OSC_STATUS (0x0311)
|
||||
#define AX5243_REG_LP_OSC_FILTER_1 (0x0312)
|
||||
#define AX5243_REG_LP_OSC_FILTER_0 (0x0313)
|
||||
#define AX5243_REG_LP_OSC_REF_1 (0x0314)
|
||||
#define AX5243_REG_LP_OSC_REF_0 (0x0315)
|
||||
#define AX5243_REG_LP_OSC_FREQ_1 (0x0316)
|
||||
#define AX5243_REG_LP_OSC_FREQ_0 (0x0317)
|
||||
#define AX5243_REG_LP_OSC_PER_1 (0x0318)
|
||||
#define AX5243_REG_LP_OSC_PER_0 (0x0319)
|
||||
#define AX5243_REG_DAC_VALUE_1 (0x0330)
|
||||
#define AX5243_REG_DAC_VALUE_0 (0x0331)
|
||||
#define AX5243_REG_DAC_CONFIG (0x0332)
|
||||
|
||||
/*!
|
||||
\class AX5243
|
||||
|
||||
\brief Control class for %AX5243 module.
|
||||
*/
|
||||
class AX5243: public PhysicalLayer {
|
||||
public:
|
||||
// introduce PhysicalLayer overloads
|
||||
using PhysicalLayer::transmit;
|
||||
using PhysicalLayer::receive;
|
||||
using PhysicalLayer::startTransmit;
|
||||
using PhysicalLayer::readData;
|
||||
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param mod Instance of Module that will be used to communicate with the radio.
|
||||
*/
|
||||
AX5243(Module* module);
|
||||
|
||||
// basic methods
|
||||
|
||||
int16_t begin();
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
Module* _mod;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
75
src/modules/SIM800/SIM800.cpp
Normal file
75
src/modules/SIM800/SIM800.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "SIM800.h"
|
||||
|
||||
SIM800::SIM800(Module* module) {
|
||||
_mod = module;
|
||||
}
|
||||
|
||||
int16_t SIM800::begin(long speed) {
|
||||
// set module properties
|
||||
_mod->AtLineFeed = "\r\n";
|
||||
_mod->baudrate = speed;
|
||||
_mod->init(RADIOLIB_USE_UART);
|
||||
Module::pinMode(_mod->getIrq(), INPUT);
|
||||
|
||||
// empty UART buffer (garbage data)
|
||||
_mod->ATemptyBuffer();
|
||||
|
||||
// power on
|
||||
Module::pinMode(_mod->getIrq(), OUTPUT);
|
||||
Module::digitalWrite(_mod->getIrq(), LOW);
|
||||
delay(1000);
|
||||
Module::pinMode(_mod->getIrq(), INPUT);
|
||||
|
||||
// test AT setup
|
||||
if(!_mod->ATsendCommand("AT")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// set phone functionality
|
||||
if(!_mod->ATsendCommand("AT+CFUN=1")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SIM800::shutdown() {
|
||||
// power off
|
||||
Module::pinMode(_mod->getIrq(), OUTPUT);
|
||||
Module::digitalWrite(_mod->getIrq(), LOW);
|
||||
delay(1000);
|
||||
Module::pinMode(_mod->getIrq(), INPUT);
|
||||
}
|
||||
|
||||
int16_t SIM800::sendSMS(const char* num, const char* msg) {
|
||||
// set SMS message format to text mode
|
||||
if(!_mod->ATsendCommand("AT+CMGF=1")) {
|
||||
return(ERR_AT_FAILED);
|
||||
}
|
||||
|
||||
// build SMS command and text
|
||||
size_t cmdLen = 9 + strlen(num) + 3;
|
||||
char* cmd = new char[cmdLen];
|
||||
strcpy(cmd, "AT+CMGS=\"");
|
||||
strcat(cmd, num);
|
||||
strcat(cmd, "\"\r");
|
||||
|
||||
size_t textLen = strlen(msg) + 2;
|
||||
char* text = new char[textLen];
|
||||
strcpy(text, msg);
|
||||
text[textLen - 2] = 0x1A;
|
||||
text[textLen - 1] = '\0';
|
||||
|
||||
// send the command
|
||||
_mod->ModuleSerial->print(cmd);
|
||||
|
||||
delay(50);
|
||||
|
||||
// send the text
|
||||
_mod->ModuleSerial->print(text);
|
||||
|
||||
delete[] cmd;
|
||||
delete[] text;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
20
src/modules/SIM800/SIM800.h
Normal file
20
src/modules/SIM800/SIM800.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef _RADIOLIB_SIM800_H
|
||||
#define _RADIOLIB_SIM800_H
|
||||
|
||||
#include "Module.h"
|
||||
|
||||
class SIM800 {
|
||||
public:
|
||||
// constructor
|
||||
SIM800(Module* module);
|
||||
|
||||
// basic methods
|
||||
int16_t begin(long speed);
|
||||
void shutdown();
|
||||
int16_t sendSMS(const char* num, const char* msg);
|
||||
|
||||
private:
|
||||
Module* _mod;
|
||||
};
|
||||
|
||||
#endif
|
96
src/protocols/LoRaWAN/LoRaWAN.cpp
Normal file
96
src/protocols/LoRaWAN/LoRaWAN.cpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include "LoRaWAN.h"
|
||||
|
||||
/*LoRaWANBand_t EU868 {
|
||||
.numChannelSpans = 2,
|
||||
.downlinkChannelMod = 0xFF,
|
||||
.uplinkDefault = {
|
||||
{
|
||||
.numChannels = 3,
|
||||
.freqStart = 868.1,
|
||||
.freqStep = 0.2,
|
||||
.numDataRates = 6,
|
||||
.dataRates = {
|
||||
LORAWAN_DATA_RATE_SF_12 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_11 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_10 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_9 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_8 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_7 | LORAWAN_DATA_RATE_BW_125_KHZ
|
||||
}
|
||||
}, {
|
||||
.numChannels = 0,
|
||||
.freqStart = 0,
|
||||
.freqStep = 0,
|
||||
.numDataRates = 0,
|
||||
.dataRates = { }
|
||||
}
|
||||
},
|
||||
.uplinkAvailable = {
|
||||
.numChannels = 3,
|
||||
.freqStart = 868.1,
|
||||
.freqStep = 0.2,
|
||||
.numDataRates = 6,
|
||||
.dataRates = {
|
||||
LORAWAN_DATA_RATE_SF_12 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_11 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_10 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_9 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_8 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_7 | LORAWAN_DATA_RATE_BW_125_KHZ
|
||||
}
|
||||
},
|
||||
.downlinkDefault = {
|
||||
{
|
||||
.numChannels = 3,
|
||||
.freqStart = 868.1,
|
||||
.freqStep = 0.2,
|
||||
.numDataRates = 6,
|
||||
.dataRates = {
|
||||
LORAWAN_DATA_RATE_SF_12 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_11 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_10 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_9 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_8 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_7 | LORAWAN_DATA_RATE_BW_125_KHZ
|
||||
}
|
||||
}, {
|
||||
.numChannels = 0,
|
||||
.freqStart = 0,
|
||||
.freqStep = 0,
|
||||
.numDataRates = 0,
|
||||
.dataRates = { }
|
||||
}
|
||||
},
|
||||
.downlinkAvailable = {
|
||||
.numChannels = 3,
|
||||
.freqStart = 868.1,
|
||||
.freqStep = 0.2,
|
||||
.numDataRates = 6,
|
||||
.dataRates = {
|
||||
LORAWAN_DATA_RATE_SF_12 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_11 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_10 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_9 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_8 | LORAWAN_DATA_RATE_BW_125_KHZ,
|
||||
LORAWAN_DATA_RATE_SF_7 | LORAWAN_DATA_RATE_BW_125_KHZ
|
||||
}
|
||||
},
|
||||
.downlinkBackup = {
|
||||
.numChannels = 1,
|
||||
.freqStart = 869.858,
|
||||
.freqStep = 0,
|
||||
.numDataRates = 1,
|
||||
.dataRates = {
|
||||
LORAWAN_DATA_RATE_SF_12 | LORAWAN_DATA_RATE_BW_125_KHZ
|
||||
}
|
||||
}
|
||||
};*/
|
||||
|
||||
uint8_t EU868::getDownlinkChannel(uint8_t txChan) {
|
||||
return(txChan);
|
||||
}
|
||||
|
||||
LoRaWANNode::LoRaWANNode(PhysicalLayer* phy, LoRaWANBand_t* band) {
|
||||
_phy = phy;
|
||||
_band = band;
|
||||
}
|
62
src/protocols/LoRaWAN/LoRaWAN.h
Normal file
62
src/protocols/LoRaWAN/LoRaWAN.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef _RADIOLIB_LORAWAN_H
|
||||
#define _RADIOLIB_LORAWAN_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||
|
||||
//https://github.com/Lora-net/LoRaMac-node
|
||||
|
||||
// preamble format
|
||||
#define LORAWAN_LORA_SYNC_WORD 0x34
|
||||
#define LORAWAN_LORA_PREAMBLE_LEN 8
|
||||
#define LORAWAN_GFSK_SYNC_WORD 0xC194C1
|
||||
#define LORAWAN_GFSK_PREAMBLE_LEN 5
|
||||
|
||||
// data rate field encoding MSB LSB DESCRIPTION
|
||||
#define LORAWAN_DATA_RATE_SF_12 0b00000000 // 7 4 LoRaWAN spreading factor: SF12
|
||||
#define LORAWAN_DATA_RATE_SF_11 0b00010000 // 7 4 SF11
|
||||
#define LORAWAN_DATA_RATE_SF_10 0b00100000 // 7 4 SF10
|
||||
#define LORAWAN_DATA_RATE_SF_9 0b00110000 // 7 4 SF9
|
||||
#define LORAWAN_DATA_RATE_SF_8 0b01000000 // 7 4 SF8
|
||||
#define LORAWAN_DATA_RATE_SF_7 0b01010000 // 7 4 SF7
|
||||
#define LORAWAN_DATA_RATE_FSK_50_K 0b01100000 // 7 4 FSK @ 50 kbps
|
||||
#define LORAWAN_DATA_RATE_BW_500_KHZ 0b00000000 // 3 0 LoRaWAN bandwidth: 500 kHz
|
||||
#define LORAWAN_DATA_RATE_BW_250_KHZ 0b00000001 // 3 0 250 kHz
|
||||
#define LORAWAN_DATA_RATE_BW_125_KHZ 0b00000010 // 3 0 125 kHz
|
||||
|
||||
// to save space, channels are saved in "spans"
|
||||
struct LoRaWANChannelSpan_t {
|
||||
uint8_t numChannels; // total number of channels in the span
|
||||
float freqStart; // center frequency of the first channel in span
|
||||
float freqStep; // frequency step between adjacent channels
|
||||
uint8_t numDataRates; // number of datarates supported by the all channels in the span
|
||||
uint8_t dataRates[6]; // array of datarates supported by all channels in the span (no channel span has more than 6 allowed data rates)
|
||||
};
|
||||
|
||||
struct LoRaWANBand_t {
|
||||
uint8_t numChannelSpans; // number of channel spans in the band
|
||||
LoRaWANChannelSpan_t uplinkDefault[2]; // default uplink (TX) channels (defined by LoRaWAN Regional Parameters)
|
||||
LoRaWANChannelSpan_t uplinkAvailable; // available uplink (TX) channels (not defined by LoRaWAN Regional Parameters)
|
||||
LoRaWANChannelSpan_t downlinkDefault[2]; // default downlink (RX1) channels (defined by LoRaWAN Regional Parameters)
|
||||
LoRaWANChannelSpan_t downlinkAvailable; // available downlink (RX1) channels (not defined by LoRaWAN Regional Parameters)
|
||||
LoRaWANChannelSpan_t downlinkBackup; // backup downlink (RX2) channels - just a single channel, but using the same structure for convenience
|
||||
};
|
||||
|
||||
struct EU868: public LoRaWANBand_t {
|
||||
uint8_t getDownlinkChannel(uint8_t txChan); // method that returns RX1 channel number based on TX channel
|
||||
uint8_t getDownlinkDataRate(uint8_t offset); // method that returns RX1 channel number based on TX channel
|
||||
};
|
||||
|
||||
class LoRaWANNode {
|
||||
public:
|
||||
|
||||
LoRaWANNode(PhysicalLayer* phy, LoRaWANBand_t* band);
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
PhysicalLayer* _phy;
|
||||
LoRaWANBand_t* _band;
|
||||
};
|
||||
|
||||
#endif
|
127
src/protocols/PSK/PSK.cpp
Normal file
127
src/protocols/PSK/PSK.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include "PSK.h"
|
||||
|
||||
VaricodeString::VaricodeString(char c) {
|
||||
_len = 1;
|
||||
_str = new char[1];
|
||||
_str[0] = c;
|
||||
}
|
||||
|
||||
VaricodeString::VaricodeString(const char* str) {
|
||||
_len = strlen(str);
|
||||
_str = new char[_len];
|
||||
strcpy(_str, str);
|
||||
}
|
||||
|
||||
VaricodeString::~VaricodeString() {
|
||||
delete[] _str;
|
||||
}
|
||||
|
||||
size_t VaricodeString::length() {
|
||||
return(_len);
|
||||
}
|
||||
|
||||
uint16_t* VaricodeString::byteArr() {
|
||||
uint16_t* arr = new uint16_t[_len];
|
||||
for(size_t i = 0; i < _len; i++) {
|
||||
arr[i] = VaricodeTable[(uint8_t)_str[i]];
|
||||
}
|
||||
return(arr);
|
||||
}
|
||||
|
||||
PSKClient::PSKClient(PhysicalLayer* phy) {
|
||||
_phy = phy;
|
||||
}
|
||||
|
||||
int16_t PSKClient::begin(int pin, float carrier, float rate, uint16_t audioFreq) {
|
||||
pinMode(pin, OUTPUT);
|
||||
|
||||
// save configuration
|
||||
_pin = pin;
|
||||
_audioFreq = audioFreq;
|
||||
|
||||
// calculate duration of 1 bit
|
||||
_bitDuration = (uint32_t)(1000000.0/rate);
|
||||
|
||||
// calculate 24-bit frequency
|
||||
_carrier = (carrier * 1000000.0) / _phy->getFreqStep();
|
||||
|
||||
// set FSK frequency deviation to 0
|
||||
int16_t state = _phy->setFrequencyDeviation(0);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
size_t PSKClient::write(uint16_t* buff, size_t len) {
|
||||
size_t n = 0;
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
n += PSKClient::write(buff[i]);
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
size_t PSKClient::write(uint16_t code) {
|
||||
// get number of bits in character code
|
||||
uint8_t dataBits = 10;
|
||||
for(dataBits = 10; dataBits > 0; dataBits--) {
|
||||
if(code & (0x0001 << dataBits)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// send code
|
||||
for(uint16_t mask = 0x01; mask <= (uint16_t)(0x01 << (dataBits - 1)); mask <<= 1) {
|
||||
if(code & mask) {
|
||||
mark();
|
||||
} else {
|
||||
space();
|
||||
}
|
||||
}
|
||||
|
||||
// character end
|
||||
space();
|
||||
space();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
size_t PSKClient::print(VaricodeString& var) {
|
||||
uint16_t* arr = var.byteArr();
|
||||
size_t n = PSKClient::write(arr, var.length());
|
||||
delete[] arr;
|
||||
return(n);
|
||||
}
|
||||
|
||||
size_t PSKClient::print(const char str[]) {
|
||||
VaricodeString var = str;
|
||||
return(PSKClient::print(var));
|
||||
}
|
||||
|
||||
size_t PSKClient::println() {
|
||||
VaricodeString lf = "\r\n";
|
||||
return(PSKClient::print(lf));
|
||||
}
|
||||
|
||||
size_t PSKClient::println(VaricodeString& var) {
|
||||
size_t n = PSKClient::print(var);
|
||||
n += PSKClient::println();
|
||||
return(n);
|
||||
}
|
||||
|
||||
size_t PSKClient::println(const char str[]) {
|
||||
size_t n = PSKClient::print(str);
|
||||
n += PSKClient::println();
|
||||
return(n);
|
||||
}
|
||||
|
||||
void PSKClient::mark() {
|
||||
// do not perform phase change
|
||||
uint32_t start = micros();
|
||||
while(micros() - start < _bitDuration);
|
||||
}
|
||||
|
||||
void PSKClient::space() {
|
||||
// change phase by 180 degrees
|
||||
uint32_t start = micros();
|
||||
// TODO: flip phase here
|
||||
while(micros() - start < _bitDuration);
|
||||
}
|
184
src/protocols/PSK/PSK.h
Normal file
184
src/protocols/PSK/PSK.h
Normal file
|
@ -0,0 +1,184 @@
|
|||
#ifndef _KITELIB_PSK_H
|
||||
#define _KITELIB_PSK_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||
|
||||
// Varicode character table: - position in table corresponds to ASCII code
|
||||
// - value in table corresponds to Varicode code
|
||||
// - leading zeros are not shown
|
||||
const uint16_t VaricodeTable[128] = {0b1010101011, // NUL
|
||||
0b1011011011, // SOH
|
||||
0b1011101101, // STX
|
||||
0b1101110111, // ETX
|
||||
0b1011101011, // EOT
|
||||
0b1101011111, // ENQ
|
||||
0b1011101111, // ACK
|
||||
0b1011111101, // BEL
|
||||
0b1011111111, // BS
|
||||
0b11101111, // HT
|
||||
0b11101, // LF
|
||||
0b1101101111, // VT
|
||||
0b1011011101, // FF
|
||||
0b11111, // CR
|
||||
0b1101110101, // SO
|
||||
0b1110101011, // SI
|
||||
0b1011110111, // DLE
|
||||
0b1011110101, // DC1
|
||||
0b1110101101, // DC2
|
||||
0b1110101111, // DC3
|
||||
0b1101011011, // DC4
|
||||
0b1101101011, // NAK
|
||||
0b1101101101, // SYN
|
||||
0b1101010111, // ETB
|
||||
0b1101111011, // CAN
|
||||
0b1101111101, // EM
|
||||
0b1110110111, // SUB
|
||||
0b1101010101, // ESC
|
||||
0b1101011101, // FS
|
||||
0b1101011101, // GS
|
||||
0b1011111011, // RS
|
||||
0b1101111111, // US
|
||||
0b1, // SP
|
||||
0b111111111, // !
|
||||
0b101011111, // "
|
||||
0b111110101, // #
|
||||
0b111011011, // $
|
||||
0b1011010101, // %
|
||||
0b1010111011, // &
|
||||
0b101111111, // '
|
||||
0b11111011, // (
|
||||
0b11110111, // )
|
||||
0b101101111, // *
|
||||
0b111011111, // +
|
||||
0b1110101, // ,
|
||||
0b110101, // -
|
||||
0b1010111, // .
|
||||
0b110101111, // /
|
||||
0b10110111, // 0
|
||||
0b10111101, // 1
|
||||
0b11101101, // 2
|
||||
0b11111111, // 3
|
||||
0b101110111, // 4
|
||||
0b101011011, // 5
|
||||
0b101101011, // 6
|
||||
0b110101101, // 7
|
||||
0b110101011, // 8
|
||||
0b110110111, // 9
|
||||
0b11110101, // :
|
||||
0b110111101, // ;
|
||||
0b111101101, // <
|
||||
0b1010101, // =
|
||||
0b111010111, // >
|
||||
0b1010101111, // ?
|
||||
0b1010111101, // @
|
||||
0b1111101, // A
|
||||
0b11101011, // B
|
||||
0b10101101, // C
|
||||
0b10110101, // D
|
||||
0b1110111, // E
|
||||
0b11011011, // F
|
||||
0b11111101, // G
|
||||
0b101010101, // H
|
||||
0b1111111, // I
|
||||
0b111111101, // J
|
||||
0b101111101, // K
|
||||
0b11010111, // L
|
||||
0b10111011, // M
|
||||
0b11011101, // N
|
||||
0b10101011, // O
|
||||
0b11010101, // P
|
||||
0b111011101, // Q
|
||||
0b10101111, // R
|
||||
0b1101111, // S
|
||||
0b1101101, // T
|
||||
0b101010111, // U
|
||||
0b110110101, // V
|
||||
0b101011101, // W
|
||||
0b101110101, // X
|
||||
0b101111011, // Y
|
||||
0b1010101101, // Z
|
||||
0b111110111, // [
|
||||
0b111101111, // backslash
|
||||
0b111111011, // ]
|
||||
0b1010111111, // ^
|
||||
0b101101101, // _
|
||||
0b1011011111, // `
|
||||
0b1011, // a
|
||||
0b1011111, // b
|
||||
0b101111, // c
|
||||
0b101101, // d
|
||||
0b11, // e
|
||||
0b111101, // f
|
||||
0b1011011, // g
|
||||
0b101011, // h
|
||||
0b1101, // i
|
||||
0b111101011, // j
|
||||
0b10111111, // k
|
||||
0b11011, // l
|
||||
0b111011, // m
|
||||
0b1111, // n
|
||||
0b111, // o
|
||||
0b111111, // p
|
||||
0b110111111, // q
|
||||
0b10101, // r
|
||||
0b10111, // s
|
||||
0b101, // t
|
||||
0b110111, // u
|
||||
0b1111011, // v
|
||||
0b1101011, // w
|
||||
0b11011111, // x
|
||||
0b1011101, // y
|
||||
0b111010101, // z
|
||||
0b1010110111, // {
|
||||
0b110111011, // |
|
||||
0b1010110101, // }
|
||||
0b1011010111, // ~
|
||||
0b1110110101, // DEL
|
||||
};
|
||||
|
||||
class VaricodeString {
|
||||
public:
|
||||
VaricodeString(char c);
|
||||
VaricodeString(const char* str);
|
||||
~VaricodeString();
|
||||
|
||||
size_t length();
|
||||
uint16_t* byteArr();
|
||||
|
||||
private:
|
||||
char* _str;
|
||||
size_t _len;
|
||||
|
||||
uint16_t getBits(char c);
|
||||
};
|
||||
|
||||
class PSKClient {
|
||||
public:
|
||||
PSKClient(PhysicalLayer* phy);
|
||||
|
||||
// basic methods
|
||||
int16_t begin(int pin, float base, float rate = 31.25, uint16_t audioFreq = 400);
|
||||
size_t write(uint16_t* buff, size_t len);
|
||||
size_t write(uint16_t code);
|
||||
|
||||
size_t print(VaricodeString &);
|
||||
size_t print(const char[]);
|
||||
|
||||
size_t println(void);
|
||||
size_t println(VaricodeString &);
|
||||
size_t println(const char[]);
|
||||
|
||||
private:
|
||||
PhysicalLayer* _phy;
|
||||
|
||||
int _pin;
|
||||
uint16_t _audioFreq;
|
||||
uint32_t _carrier;
|
||||
uint16_t _bitDuration;
|
||||
|
||||
void mark();
|
||||
void space();
|
||||
};
|
||||
|
||||
#endif
|
184
src/protocols/Pager/Pager.cpp
Normal file
184
src/protocols/Pager/Pager.cpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
#include "Pager.h"
|
||||
|
||||
PagerClient::PagerClient(PhysicalLayer* phy) {
|
||||
_phy = phy;
|
||||
}
|
||||
|
||||
int16_t PagerClient::begin(float base, uint16_t speed) {
|
||||
// calculate duration of 1 bit in us
|
||||
_bitDuration = (uint32_t)1000000/speed;
|
||||
|
||||
// calculate 24-bit frequency
|
||||
_base = (base * 1000000.0) / _phy->getFreqStep();
|
||||
|
||||
// calculate module carrier frequency resolution
|
||||
uint16_t step = round(_phy->getFreqStep());
|
||||
|
||||
// calculate raw frequency shift
|
||||
_shift = FREQ_SHIFT_HZ/step;
|
||||
|
||||
// set module frequency deviation to 0
|
||||
int16_t state = _phy->setFrequencyDeviation(0);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t PagerClient::transmit(String& str, uint32_t addr, uint8_t encoding) {
|
||||
return(PagerClient::transmit(str.c_str(), addr, encoding));
|
||||
}
|
||||
|
||||
int16_t PagerClient::transmit(const char* str, uint32_t addr, uint8_t encoding) {
|
||||
return(PagerClient::transmit((uint8_t*)str, strlen(str), addr, encoding));
|
||||
}
|
||||
|
||||
int16_t PagerClient::transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t encoding) {
|
||||
// get symbol bit length based on encoding
|
||||
uint8_t symbolLength = 0;
|
||||
if(encoding == BCD) {
|
||||
symbolLength = 4;
|
||||
|
||||
// replace ASCII characters with BCD representations
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
switch(data[i]) {
|
||||
case '*':
|
||||
data[i] = 0x0A;
|
||||
break;
|
||||
case 'U':
|
||||
data[i] = 0x0B;
|
||||
break;
|
||||
case ' ':
|
||||
data[i] = 0x0C;
|
||||
break;
|
||||
case '-':
|
||||
data[i] = 0x0D;
|
||||
break;
|
||||
case ')':
|
||||
data[i] = 0x0E;
|
||||
break;
|
||||
case '(':
|
||||
data[i] = 0x0F;
|
||||
break;
|
||||
default:
|
||||
data[i] -= '0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if(encoding == ASCII) {
|
||||
symbolLength = 7;
|
||||
} else {
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
// get target position in batch (3 LSB from address determine frame position in batch)
|
||||
uint8_t framePos = addr & 0b0000000000000111;
|
||||
|
||||
// get address that will be written into address frame
|
||||
uint16_t frameAddr = (addr & 0b1111111111111000) >> 3;
|
||||
|
||||
// calculate the number of 20-bit data blocks
|
||||
size_t numDataBlocks = (len * symbolLength) / MESSAGE_BITS_LENGTH;
|
||||
if((len * symbolLength) % MESSAGE_BITS_LENGTH > 0) {
|
||||
numDataBlocks += 1;
|
||||
}
|
||||
|
||||
// calculate number of batches
|
||||
size_t numBatches = (1 + framePos + numDataBlocks) / 16 + 1;
|
||||
if((1 + numDataBlocks) % 16 == 0) {
|
||||
numBatches -= 1;
|
||||
}
|
||||
|
||||
// calculate message length in 32-bit code words
|
||||
size_t msgLen = PREAMBLE_LENGTH + (1 + 16) * numBatches;
|
||||
|
||||
// build the message
|
||||
uint32_t* msg = new uint32_t[msgLen];
|
||||
// TODO: BCD padding?
|
||||
memset(msg, 0x00, msgLen);
|
||||
|
||||
// set preamble
|
||||
for(size_t i = 0; i < PREAMBLE_LENGTH; i++) {
|
||||
msg[i] = PREAMBLE_CODE_WORD;
|
||||
}
|
||||
|
||||
// set frame synchronization code words
|
||||
for(size_t i = 0; i < numBatches; i++) {
|
||||
msg[PREAMBLE_LENGTH + i*(1 + 16)] = FRAME_SYNC_CODE_WORD;
|
||||
}
|
||||
|
||||
// set unused code words to idle
|
||||
for(size_t i = 0; i < framePos; i++) {
|
||||
msg[PREAMBLE_LENGTH + 1 + i] = IDLE_CODE_WORD;
|
||||
}
|
||||
|
||||
// write address code word
|
||||
msg[PREAMBLE_LENGTH + 1 + framePos] = addParity(encodeBCH((addr << 1) | ADDRESS_CODE_WORD));
|
||||
|
||||
// split the data into 20-bit blocks
|
||||
size_t bitPos = MESSAGE_BITS_LENGTH;
|
||||
size_t blockPos = PREAMBLE_LENGTH + 1;
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
// check if the next data symbol fits into the remaining space in current 20-bit block
|
||||
if(bitPos >= symbolLength) {
|
||||
// insert the whole data symbol into current block
|
||||
msg[blockPos] |= (uint32_t)data[i] << (bitPos - symbolLength);
|
||||
bitPos -= symbolLength;
|
||||
} else {
|
||||
// split the symbol between two blocks
|
||||
uint8_t msbPart = data[i];
|
||||
size_t lsbLen = symbolLength - bitPos;
|
||||
msg[blockPos] |= msbPart >> lsbLen;
|
||||
blockPos++;
|
||||
bitPos = MESSAGE_BITS_LENGTH;
|
||||
uint8_t lsbPart = data[i] & ((1 << lsbLen) - 1);
|
||||
msg[blockPos] |= (uint32_t)lsbPart << (bitPos - lsbLen);
|
||||
bitPos -= lsbLen;
|
||||
}
|
||||
}
|
||||
|
||||
// write message code words
|
||||
|
||||
// transmit the message
|
||||
PagerClient::write(msg, msgLen);
|
||||
|
||||
delete[] msg;
|
||||
|
||||
// turn transmitter off
|
||||
_phy->standby();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void PagerClient::write(uint32_t* data, size_t len) {
|
||||
// write code words from buffer
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
PagerClient::write(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PagerClient::write(uint32_t codeWord) {
|
||||
// write single code word
|
||||
for(uint8_t i = 0; i <= 31; i++) {
|
||||
uint32_t mask = (uint32_t)0x01 << i;
|
||||
if(codeWord & mask) {
|
||||
// send 1
|
||||
uint32_t start = micros();
|
||||
_phy->transmitDirect(_base + _shift);
|
||||
while(micros() - start < _bitDuration);
|
||||
} else {
|
||||
// send 0
|
||||
uint32_t start = micros();
|
||||
_phy->transmitDirect(_base - _shift);
|
||||
while(micros() - start < _bitDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t PagerClient::encodeBCH(uint32_t data) {
|
||||
return(data);
|
||||
}
|
||||
|
||||
|
||||
uint32_t PagerClient::addParity(uint32_t msg) {
|
||||
return(msg);
|
||||
}
|
50
src/protocols/Pager/Pager.h
Normal file
50
src/protocols/Pager/Pager.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef _RADIOLIB_PAGER_H
|
||||
#define _RADIOLIB_PAGER_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||
|
||||
// supported encoding schemes
|
||||
#define ASCII 0
|
||||
#define BCD 1
|
||||
|
||||
#define PREAMBLE_LENGTH 18
|
||||
#define MESSAGE_BITS_LENGTH 20
|
||||
|
||||
#define FREQ_SHIFT_HZ 4500
|
||||
|
||||
#define PREAMBLE_CODE_WORD 0xAAAAAAAA
|
||||
#define FRAME_SYNC_CODE_WORD 0x7CD215D8
|
||||
#define IDLE_CODE_WORD 0x7A89C197
|
||||
#define ADDRESS_CODE_WORD 0
|
||||
#define MESSAGE_CODE_WORD 1
|
||||
|
||||
#define BCH_GENERATOR_POLYNOMIAL 0b11101101001 // x^10 + x^9 + x^8 + x^6 + x^5 + x^3 + 1
|
||||
|
||||
class PagerClient {
|
||||
public:
|
||||
PagerClient(PhysicalLayer* phy);
|
||||
|
||||
// basic methods
|
||||
int16_t begin(float base, uint16_t speed);
|
||||
int16_t transmit(String& str, uint32_t addr, uint8_t encoding = BCD);
|
||||
int16_t transmit(const char* str, uint32_t addr, uint8_t encoding = BCD);
|
||||
int16_t transmit(uint8_t* data, size_t len, uint32_t addr, uint8_t encoding = BCD);
|
||||
|
||||
// TODO: add receiving + option to listen to all packets
|
||||
|
||||
private:
|
||||
PhysicalLayer* _phy;
|
||||
|
||||
uint32_t _base;
|
||||
uint16_t _shift;
|
||||
uint16_t _bitDuration;
|
||||
|
||||
void write(uint32_t* data, size_t len);
|
||||
void write(uint32_t b);
|
||||
|
||||
uint32_t encodeBCH(uint32_t data);
|
||||
uint32_t addParity(uint32_t msg);
|
||||
};
|
||||
|
||||
#endif
|
189
src/protocols/SSDV/SSDV.cpp
Normal file
189
src/protocols/SSDV/SSDV.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
#include "SSDV.h"
|
||||
|
||||
SSDVClient::SSDVClient(RTTYClient* rtty) {
|
||||
_rtty = rtty;
|
||||
}
|
||||
|
||||
int16_t SSDVClient::begin(const char* callsign) {
|
||||
// check source callsign length (6 characters max)
|
||||
if(strlen(callsign) > SSDV_MAX_CALLSIGN_LENGTH) {
|
||||
return(ERR_INVALID_CALLSIGN);
|
||||
}
|
||||
|
||||
// encode callsign
|
||||
callsignEnc = encodeBase40(callsign);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SSDVClient::startTransfer(uint8_t mode, uint8_t* image, uint8_t imageID, uint16_t width, uint16_t height, uint8_t quality, uint8_t subsampling) {
|
||||
// check all parameters
|
||||
if(!((mode == SSDV_PACKET_TYPE_NORMAL) || (mode == SSDV_PACKET_TYPE_NO_FEC))) {
|
||||
return(ERR_INVALID_SSDV_MODE);
|
||||
}
|
||||
if((width % 16 != 0) || (height % 16 != 0)) {
|
||||
return(ERR_INVALID_IMAGE_SIZE);
|
||||
}
|
||||
RADIOLIB_CHECK_RANGE(quality, 0, 7, ERR_INVALID_IMAGE_QUALITY);
|
||||
RADIOLIB_CHECK_RANGE(subsampling, 0, 3, ERR_INVALID_SUBSAMPLING);
|
||||
|
||||
// save the parameters
|
||||
_mode = mode;
|
||||
_img = image;
|
||||
_imgID = imageID;
|
||||
_w = width;
|
||||
_h = height;
|
||||
_qual = (quality ^ 4) << 3;
|
||||
_sub = subsampling;
|
||||
|
||||
// initialize internal counters
|
||||
_packetID = 0;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SSDVClient::sendPacket() {
|
||||
uint8_t buff[SSDV_PACKET_LENGTH];
|
||||
uint8_t* buffPtr = buff;
|
||||
|
||||
// sync byte
|
||||
*buffPtr++ = SSDV_SYNC;
|
||||
|
||||
// mode
|
||||
*buffPtr++ = _mode;
|
||||
|
||||
// callsign
|
||||
memcpy(buffPtr, &callsignEnc, sizeof(callsignEnc));
|
||||
buffPtr += sizeof(callsignEnc);
|
||||
|
||||
// image ID
|
||||
*buffPtr++ = _imgID;
|
||||
|
||||
// packet ID
|
||||
memcpy(buffPtr, &_packetID, sizeof(_packetID));
|
||||
buffPtr += sizeof(_packetID);
|
||||
_packetID++;
|
||||
|
||||
// width and height
|
||||
*buffPtr++ = _w;
|
||||
*buffPtr++ = _h;
|
||||
|
||||
// flags - check if this is the last packet
|
||||
*buffPtr++ = _qual | _sub;
|
||||
|
||||
// MCU offset and index
|
||||
|
||||
// payload data
|
||||
|
||||
// 32-bit CRC and Reed-Solomon FEC (normal mode only)
|
||||
uint32_t crc;
|
||||
if(_mode == SSDV_PACKET_TYPE_NORMAL) {
|
||||
// normal mode, use FEC
|
||||
crc = getChecksum(buff + SSDV_PAYLOAD_POS, SSDV_PAYLOAD_LEN_NORMAL);
|
||||
memcpy(buff + SSDV_CHECKSUM_POS_NORMAL, &crc, sizeof(uint32_t));
|
||||
|
||||
encodeRS8(buff + 1, buff + SSDV_FEC_POS, 0);
|
||||
|
||||
} else {
|
||||
// no-FEC mode, CRC only
|
||||
crc = getChecksum(buff + SSDV_PAYLOAD_POS, SSDV_PAYLOAD_LEN_NO_FEC);
|
||||
memcpy(buff + SSDV_CHECKSUM_POS_NO_FEC, &crc, sizeof(uint32_t));
|
||||
|
||||
}
|
||||
|
||||
// send the packet
|
||||
_rtty->write(buff, SSDV_PACKET_LENGTH);
|
||||
}
|
||||
|
||||
/*
|
||||
Base-40 encoding implementation based on https://github.com/fsphil/ssd
|
||||
|
||||
Licensed under GNU General Public License v3.0
|
||||
https://github.com/fsphil/ssdv/blob/035f920f5c96880bfd89d4469428b934e830c7c9/COPYING
|
||||
*/
|
||||
uint32_t SSDVClient::encodeBase40(char* str) {
|
||||
// sanity checks
|
||||
uint8_t len = strlen(str);
|
||||
if(len == 0) {
|
||||
return(0x00000000);
|
||||
} else if(len > 6) {
|
||||
return(0xFFFFFFFF)
|
||||
}
|
||||
|
||||
// encode
|
||||
uint32_t enc = 0;
|
||||
for(int8_t i = len - 1; i >= 0; i--) {
|
||||
enc *= 40;
|
||||
if((str[i] >= 'A') && (str[i] <= 'Z')) {
|
||||
enc += str[i] - 'A' + 14;
|
||||
} else if((str[i] >= '0') && (str[i] <= '9')) {
|
||||
enc += str[i] - '0' + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(enc);
|
||||
}
|
||||
|
||||
/*
|
||||
SSDV CRC32 implementation from https://github.com/fsphil/ssd
|
||||
|
||||
Licensed under GNU General Public License v3.0
|
||||
https://github.com/fsphil/ssdv/blob/035f920f5c96880bfd89d4469428b934e830c7c9/COPYING
|
||||
*/
|
||||
uint32_t SSDVClient::getChecksum(uint8_t* data, size_t len) {
|
||||
uint32_t crc, x;
|
||||
uint8_t i, *d;
|
||||
|
||||
for(d = data, crc = SSDV_CRC32_INITIAL; len; len--) {
|
||||
x = (crc ^ *(d++)) & 0xFF;
|
||||
for(i = 8; i > 0; i--) {
|
||||
if(x & 1) {
|
||||
x = (x >> 1) ^ SSDV_CRC32_POLYNOMIAL;
|
||||
} else {
|
||||
x >>= 1;
|
||||
}
|
||||
}
|
||||
crc = (crc >> 8) ^ x;
|
||||
}
|
||||
|
||||
return(crc ^ SSDV_CRC32_INITIAL);
|
||||
}
|
||||
|
||||
int16_t mod255(int16_t val) {
|
||||
while(val >= 255) {
|
||||
val -= 255;
|
||||
val = (val >> 8) + (val & 255);
|
||||
}
|
||||
return(val);
|
||||
}
|
||||
|
||||
/*
|
||||
SSDV Reed-Solomon forward error correction implementation from https://github.com/fsphil/ssd
|
||||
|
||||
Licensed under GNU General Public License v3.0
|
||||
https://github.com/fsphil/ssdv/blob/035f920f5c96880bfd89d4469428b934e830c7c9/COPYING
|
||||
*/
|
||||
void SSDVClient::encodeRS8(uint8_t* data, uint8_t* parity, int16_t pad) {
|
||||
int16_t i, j;
|
||||
uint8_t feedback;
|
||||
|
||||
memset(parity, 0, SSDV_RS_FEC_NROOTS * sizeof(uint8_t));
|
||||
|
||||
for(i = 0; i < SSDV_RS_FEC_NN - SSDV_RS_FEC_NROOTS - pad; i++) {
|
||||
feedback = pgm_read_byte(&rs8_index_of[data[i] ^ parity[0]]);
|
||||
|
||||
if(feedback != SSDV_RS_FEC_A0) { /* feedback term is non-zero */
|
||||
for(j = 1; j < SSDV_RS_FEC_NROOTS; j++) {
|
||||
parity[j] ^= pgm_read_byte(&rs8_alpha_to[mod255(feedback + pgm_read_byte(&rs8_poly[SSDV_RS_FEC_NROOTS - j]))]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shift */
|
||||
memmove(&parity[0], &parity[1], sizeof(uint8_t) * (SSDV_RS_FEC_NROOTS - 1));
|
||||
if(feedback != SSDV_RS_FEC_A0) {
|
||||
parity[SSDV_RS_FEC_NROOTS - 1] = pgm_read_byte(&rs8_alpha_to[mod255(feedback + pgm_read_byte(&poly[0]))]);
|
||||
} else {
|
||||
parity[SSDV_RS_FEC_NROOTS - 1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
124
src/protocols/SSDV/SSDV.h
Normal file
124
src/protocols/SSDV/SSDV.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
#ifndef _RADIOLIB_SSDV_H
|
||||
#define _RADIOLIB_SSDV_H
|
||||
|
||||
#include "../../TypeDef.h"
|
||||
#include "../RTTY/RTTY.h"
|
||||
|
||||
#define SSDV_MAX_CALLSIGN_LENGTH 6
|
||||
#define SSDV_PACKET_LENGTH 256
|
||||
|
||||
// CRC32 definitions
|
||||
#define SSDV_CRC32_INITIAL 0xFFFFFFFF
|
||||
#define SSDV_CRC32_POLYNOMIAL 0xEDB88320
|
||||
|
||||
// Reed-Solomon FEC
|
||||
#define SSDV_RS_FEC_MM (8)
|
||||
#define SSDV_RS_FEC_NN (255)
|
||||
#define SSDV_RS_FEC_NROOTS (32)
|
||||
#define SSDV_RS_FEC_FCR (112)
|
||||
#define SSDV_RS_FEC_PRIM (11)
|
||||
#define SSDV_RS_FEC_IPRIM (116)
|
||||
#define SSDV_RS_FEC_A0 (NN)
|
||||
|
||||
// packet field positions/lengths
|
||||
#define SSDV_PAYLOAD_POS 15
|
||||
#define SSDV_PAYLOAD_LEN_NORMAL 205
|
||||
#define SSDV_PAYLOAD_LEN_NO_FEC 237
|
||||
#define SSDV_CHECKSUM_POS_NORMAL 220
|
||||
#define SSDV_CHECKSUM_POS_NO_FEC 252
|
||||
#define SSDV_FEC_POS 224
|
||||
|
||||
// packet fields MSB LSB DESCRIPTION
|
||||
#define SSDV_SYNC 0x55 // 7 0 sync byte
|
||||
#define SSDV_PACKET_TYPE_NORMAL 0x66 // 7 0 packet type: normal (224 byte payload including header, 32 byte FEC)
|
||||
#define SSDV_PACKET_TYPE_NO_FEC 0x67 // 7 0 no-FEC (256 byte payload including header)
|
||||
#define SSDV_MCU_OFFSET_NONE 0xFF // 7 0 no MCU offset in the current payload
|
||||
#define SSDV_MCU_INDEX_NONE 0xFFFF // 15 0
|
||||
|
||||
// flag field
|
||||
#define SSDV_JPEG_QUALITY 0b00111000 // 5 3 JPEG quality level (0-7 xor 4)
|
||||
#define SSDV_END_OF_IMAGE_FLAG 0b00000100 // 2 2 end of image flag
|
||||
#define SSDV_SUBSAMPLING_2X2 0b00000000 // 1 0 subsampling mode: 2x2
|
||||
#define SSDV_SUBSAMPLING_1X2 0b00000001 // 1 0 1x2
|
||||
#define SSDV_SUBSAMPLING_2X1 0b00000010 // 1 0 2x1
|
||||
#define SSDV_SUBSAMPLING_1X1 0b00000011 // 1 0 1x1
|
||||
|
||||
static const uint8_t rs8_alpha_to[] PROGMEM = {
|
||||
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x87,0x89,0x95,0xAD,0xDD,0x3D,0x7A,0xF4,
|
||||
0x6F,0xDE,0x3B,0x76,0xEC,0x5F,0xBE,0xFB,0x71,0xE2,0x43,0x86,0x8B,0x91,0xA5,0xCD,
|
||||
0x1D,0x3A,0x74,0xE8,0x57,0xAE,0xDB,0x31,0x62,0xC4,0x0F,0x1E,0x3C,0x78,0xF0,0x67,
|
||||
0xCE,0x1B,0x36,0x6C,0xD8,0x37,0x6E,0xDC,0x3F,0x7E,0xFC,0x7F,0xFE,0x7B,0xF6,0x6B,
|
||||
0xD6,0x2B,0x56,0xAC,0xDF,0x39,0x72,0xE4,0x4F,0x9E,0xBB,0xF1,0x65,0xCA,0x13,0x26,
|
||||
0x4C,0x98,0xB7,0xE9,0x55,0xAA,0xD3,0x21,0x42,0x84,0x8F,0x99,0xB5,0xED,0x5D,0xBA,
|
||||
0xF3,0x61,0xC2,0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0x07,0x0E,0x1C,0x38,0x70,0xE0,
|
||||
0x47,0x8E,0x9B,0xB1,0xE5,0x4D,0x9A,0xB3,0xE1,0x45,0x8A,0x93,0xA1,0xC5,0x0D,0x1A,
|
||||
0x34,0x68,0xD0,0x27,0x4E,0x9C,0xBF,0xF9,0x75,0xEA,0x53,0xA6,0xCB,0x11,0x22,0x44,
|
||||
0x88,0x97,0xA9,0xD5,0x2D,0x5A,0xB4,0xEF,0x59,0xB2,0xE3,0x41,0x82,0x83,0x81,0x85,
|
||||
0x8D,0x9D,0xBD,0xFD,0x7D,0xFA,0x73,0xE6,0x4B,0x96,0xAB,0xD1,0x25,0x4A,0x94,0xAF,
|
||||
0xD9,0x35,0x6A,0xD4,0x2F,0x5E,0xBC,0xFF,0x79,0xF2,0x63,0xC6,0x0B,0x16,0x2C,0x58,
|
||||
0xB0,0xE7,0x49,0x92,0xA3,0xC1,0x05,0x0A,0x14,0x28,0x50,0xA0,0xC7,0x09,0x12,0x24,
|
||||
0x48,0x90,0xA7,0xC9,0x15,0x2A,0x54,0xA8,0xD7,0x29,0x52,0xA4,0xCF,0x19,0x32,0x64,
|
||||
0xC8,0x17,0x2E,0x5C,0xB8,0xF7,0x69,0xD2,0x23,0x46,0x8C,0x9F,0xB9,0xF5,0x6D,0xDA,
|
||||
0x33,0x66,0xCC,0x1F,0x3E,0x7C,0xF8,0x77,0xEE,0x5B,0xB6,0xEB,0x51,0xA2,0xC3,0x00
|
||||
};
|
||||
|
||||
static const uint8_t rs8_index_of[] PROGMEM = {
|
||||
0xFF,0x00,0x01,0x63,0x02,0xC6,0x64,0x6A,0x03,0xCD,0xC7,0xBC,0x65,0x7E,0x6B,0x2A,
|
||||
0x04,0x8D,0xCE,0x4E,0xC8,0xD4,0xBD,0xE1,0x66,0xDD,0x7F,0x31,0x6C,0x20,0x2B,0xF3,
|
||||
0x05,0x57,0x8E,0xE8,0xCF,0xAC,0x4F,0x83,0xC9,0xD9,0xD5,0x41,0xBE,0x94,0xE2,0xB4,
|
||||
0x67,0x27,0xDE,0xF0,0x80,0xB1,0x32,0x35,0x6D,0x45,0x21,0x12,0x2C,0x0D,0xF4,0x38,
|
||||
0x06,0x9B,0x58,0x1A,0x8F,0x79,0xE9,0x70,0xD0,0xC2,0xAD,0xA8,0x50,0x75,0x84,0x48,
|
||||
0xCA,0xFC,0xDA,0x8A,0xD6,0x54,0x42,0x24,0xBF,0x98,0x95,0xF9,0xE3,0x5E,0xB5,0x15,
|
||||
0x68,0x61,0x28,0xBA,0xDF,0x4C,0xF1,0x2F,0x81,0xE6,0xB2,0x3F,0x33,0xEE,0x36,0x10,
|
||||
0x6E,0x18,0x46,0xA6,0x22,0x88,0x13,0xF7,0x2D,0xB8,0x0E,0x3D,0xF5,0xA4,0x39,0x3B,
|
||||
0x07,0x9E,0x9C,0x9D,0x59,0x9F,0x1B,0x08,0x90,0x09,0x7A,0x1C,0xEA,0xA0,0x71,0x5A,
|
||||
0xD1,0x1D,0xC3,0x7B,0xAE,0x0A,0xA9,0x91,0x51,0x5B,0x76,0x72,0x85,0xA1,0x49,0xEB,
|
||||
0xCB,0x7C,0xFD,0xC4,0xDB,0x1E,0x8B,0xD2,0xD7,0x92,0x55,0xAA,0x43,0x0B,0x25,0xAF,
|
||||
0xC0,0x73,0x99,0x77,0x96,0x5C,0xFA,0x52,0xE4,0xEC,0x5F,0x4A,0xB6,0xA2,0x16,0x86,
|
||||
0x69,0xC5,0x62,0xFE,0x29,0x7D,0xBB,0xCC,0xE0,0xD3,0x4D,0x8C,0xF2,0x1F,0x30,0xDC,
|
||||
0x82,0xAB,0xE7,0x56,0xB3,0x93,0x40,0xD8,0x34,0xB0,0xEF,0x26,0x37,0x0C,0x11,0x44,
|
||||
0x6F,0x78,0x19,0x9A,0x47,0x74,0xA7,0xC1,0x23,0x53,0x89,0xFB,0x14,0x5D,0xF8,0x97,
|
||||
0x2E,0x4B,0xB9,0x60,0x0F,0xED,0x3E,0xE5,0xF6,0x87,0xA5,0x17,0x3A,0xA3,0x3C,0xB7
|
||||
};
|
||||
|
||||
static const uint8_t rs8_poly[] PROGMEM = {
|
||||
0x00,0xF9,0x3B,0x42,0x04,0x2B,0x7E,0xFB,0x61,0x1E,0x03,0xD5,0x32,0x42,0xAA,0x05,
|
||||
0x18,0x05,0xAA,0x42,0x32,0xD5,0x03,0x1E,0x61,0xFB,0x7E,0x2B,0x04,0x42,0x3B,0xF9,
|
||||
0x00
|
||||
};
|
||||
|
||||
class SSDVClient {
|
||||
public:
|
||||
/*!
|
||||
\brief Default constructor.
|
||||
|
||||
\param rtty Pointer to the RTTY client used for transfer.
|
||||
*/
|
||||
SSTVClient(RTTYClient* rtty);
|
||||
|
||||
int16_t begin(const char* callsign);
|
||||
|
||||
int16_t startTransfer(uint8_t mode, uint8_t* image, uint8_t imageID, uint16_t width, uint16_t height, uint8_t quality = SSDV_JPEG_QUALITY, uint8_t subsampling = SSDV_SUBSAMPLING_1X1);
|
||||
|
||||
void sendPacket();
|
||||
|
||||
#ifndef RADIOLIB_GODMODE
|
||||
private:
|
||||
#endif
|
||||
RTTYClient* _rtty;
|
||||
|
||||
// Base-40 encoded callsign
|
||||
uint32_t callsignEnc;
|
||||
|
||||
// cached parameters of image currently in transfer
|
||||
uint16_t _packetID, _w, _h;
|
||||
uint8_t _mode, _imgID, _qual, _sub;
|
||||
uint8_t* _img;
|
||||
|
||||
uint32_t encodeBase40(char* str);
|
||||
uint32_t getChecksum(uint8_t* data, size_t len);
|
||||
int16_t mod255(int16_t val);
|
||||
void encodeRS8(uint8_t* data, uint8_t* parity, int16_t pad);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue