Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SX127x lib_gps lib_mma8451q lib_mpl3115a2 lib_sx9500 mbed
Fork of na_mote1 by
See wiki Page for a detailed
This is a link to the wiki page
main.cpp
- Committer:
- dudmuck
- Date:
- 2015-05-08
- Revision:
- 6:8defa260bc10
- Parent:
- 5:329557e0625c
- Child:
- 7:6d5f193b6c2f
File content as of revision 6:8defa260bc10:
#include "sx127x_lora.h"
#include "sx127x_fsk.h"
#include "mma8451q.h"
#include "mpl3115a2.h"
#include "sx9500.h"
#include "gps.h"
#define RADIO_RESET PC_2 //NorAm_Mote Reset_sx
#define RADIO_MOSI PB_15 //NorAm_Mote SPI2 Mosi
#define RADIO_MISO PB_14 //NorAm_Mote SPI2 Miso
#define RADIO_SCLK PB_13 //NorAm_Mote SPI2 Clk
#define RADIO_NSS PB_12 //NorAm_Mote SPI2 Nss
#define RADIO_DIO_0 PC_6 //NorAm_Mote DIO0
#define RADIO_DIO_1 PC_10 //NorAm_Mote DIO1
#define RADIO_DIO_2 PC_8 //NorAm_Mote DIO2
#define RADIO_DIO_3 PB_4 //NorAm_Mote DIO3
#define RADIO_DIO_4 PB_5 //NorAm_Mote DIO4
#define RADIO_DIO_5 PB_6 //NorAm_Mote DIO5
#define RFSW1 PC_4 //NorAm_Mote RFSwitch_CNTR_1
#define RFSW2 PC_13 //NorAm_Mote RFSwitch_CNTR_2
/*
*
*/
Serial pc(USBTX, USBRX);
#ifdef I2C_PIN_TEST
DigitalInOut pb8(PB_8);
DigitalInOut pb9(PB_9);
#else
I2C i2c(I2C_SDA, I2C_SCL);
DigitalIn i2c_int_pin(RADIO_DIO_3);
MMA8451Q mma8451q(i2c, i2c_int_pin);
MPL3115A2 mpl3115a2(i2c, i2c_int_pin);
SX9500 sx9500(i2c, PA_9, PA_10);
#endif /* I2C_PIN_TeST */
/* gps(tx, rx, en); */
GPS gps(PB_6, PB_7, PB_11);
DigitalOut pd2(PD_2);
DigitalOut hdr_fem_ctx(PC_7);
DigitalOut hdr_fem_csd(PC_0);
DigitalOut red_led(PB_1);
#define LED_ON 0
#define LED_OFF 1
Timeout hop_timeout;
InterruptIn dio3(PC_8);
bool clear_valid_header;
typedef enum {
HOP_TYPE_NONE = 0,
HOP_TYPE_64CH,
HOP_TYPE_4CH
} hop_type_e;
hop_type_e hop_type;
float hop_base_MHz = 902.3;
float hop_step_MHz = 0.2;
bool abort_key;
bool per_en;
int PacketRxSequencePrev;
uint32_t PacketPerKoCnt;
uint32_t PacketPerOkCnt;
uint32_t PacketNormalCnt;
Timeout per_timeout;
float per_tx_delay = 0.1;
int per_id;
uint32_t PacketTxCnt;
uint8_t tx_cnt;
char pcbuf[64];
bool rx_after_tx;
typedef enum {
APP_NONE = 0,
APP_CHAT
} app_e;
app_e app = APP_NONE;
#define FSK_LARGE_PKT_THRESHOLD 0x3f
/******************************************************************************/
// pin: 3 8 1 7 10 12 5 20 18
// mosi, miso, sclk, cs, rst, dio0, dio1
SX127x radio(RADIO_MOSI, RADIO_MISO, RADIO_SCLK, RADIO_NSS, RADIO_RESET, RADIO_DIO_0, RADIO_DIO_1);
SX127x_fsk fsk(radio);
SX127x_lora lora(radio);
DigitalOut rfsw1(RFSW1);
DigitalOut rfsw2(RFSW2);
void rfsw_callback()
{
if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER) { // start of transmission
if (radio.HF) {
if (radio.RegPaConfig.bits.PaSelect) { // if PA_BOOST
rfsw2 = 0;
rfsw1 = 1;
} else { // RFO to power amp
rfsw2 = 1;
rfsw1 = 0;
}
} else {
// todo: sx1276
}
hdr_fem_csd = 1; //debug
} else if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_CAD) { // start of reception
if (radio.HF) {
rfsw2 = 1;
rfsw1 = 1;
} else {
// todo: sx1276
}
hdr_fem_csd = 0; //debug
} else { // RF switch shutdown
rfsw2 = 0;
rfsw1 = 0;
hdr_fem_csd = 0; //debug
}
}
void printLoraIrqs_(bool clear)
{
//in radio class -- RegIrqFlags_t RegIrqFlags;
//already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
printf("\r\nIrqFlags:");
if (lora.RegIrqFlags.bits.CadDetected)
printf("CadDetected ");
if (lora.RegIrqFlags.bits.FhssChangeChannel) {
//radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
printf("FhssChangeChannel:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
}
if (lora.RegIrqFlags.bits.CadDone)
printf("CadDone ");
if (lora.RegIrqFlags.bits.TxDone)
printf("TxDone ");
if (lora.RegIrqFlags.bits.ValidHeader)
printf("[42mValidHeader[0m ");
if (lora.RegIrqFlags.bits.PayloadCrcError)
printf("[41mPayloadCrcError[0m ");
if (lora.RegIrqFlags.bits.RxDone)
printf("[42mRxDone[0m ");
if (lora.RegIrqFlags.bits.RxTimeout)
printf("RxTimeout ");
printf("\r\n");
if (clear)
radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
}
void lora_printCodingRate(bool from_rx)
{
uint8_t d = lora.getCodingRate(from_rx);
printf("CodingRate:");
switch (d) {
case 1: printf("4/5 "); break;
case 2: printf("4/6 "); break;
case 3: printf("4/7 "); break;
case 4: printf("4/8 "); break;
default:
printf("%d ", d);
break;
}
}
void lora_printHeaderMode()
{
if (lora.getHeaderMode())
printf("implicit ");
else
printf("explicit ");
}
void lora_printBw()
{
uint8_t bw = lora.getBw();
printf("Bw:");
if (radio.type == SX1276) {
switch (lora.RegModemConfig.sx1276bits.Bw) {
case 0: printf("7.8KHz "); break;
case 1: printf("10.4KHz "); break;
case 2: printf("15.6KHz "); break;
case 3: printf("20.8KHz "); break;
case 4: printf("31.25KHz "); break;
case 5: printf("41.7KHz "); break;
case 6: printf("62.5KHz "); break;
case 7: printf("125KHz "); break;
case 8: printf("250KHz "); break;
case 9: printf("500KHz "); break;
default: printf("%x ", lora.RegModemConfig.sx1276bits.Bw); break;
}
} else if (radio.type == SX1272) {
switch (lora.RegModemConfig.sx1272bits.Bw) {
case 0: printf("125KHz "); break;
case 1: printf("250KHz "); break;
case 2: printf("500KHz "); break;
case 3: printf("11b "); break;
}
}
}
void lora_printAllBw()
{
int i, s;
if (radio.type == SX1276) {
s = lora.RegModemConfig.sx1276bits.Bw;
for (i = 0; i < 10; i++ ) {
lora.RegModemConfig.sx1276bits.Bw = i;
printf("%d ", i);
lora_printBw();
printf("\r\n");
}
lora.RegModemConfig.sx1276bits.Bw = s;
} else if (radio.type == SX1272) {
s = lora.RegModemConfig.sx1272bits.Bw;
for (i = 0; i < 3; i++ ) {
lora.RegModemConfig.sx1272bits.Bw = i;
printf("%d ", i);
lora_printBw();
printf("\r\n");
}
lora.RegModemConfig.sx1272bits.Bw = s;
}
}
void lora_printSf()
{
// spreading factor same between sx127[26]
printf("sf:%d ", lora.getSf());
}
void lora_printRxPayloadCrcOn()
{
bool on = lora.getRxPayloadCrcOn();
//printf("RxPayloadCrcOn:%s ", on ? "on" : "off");
if (on)
printf("RxPayloadCrcOn:1 = Tx CRC Enabled\r\n");
else
printf("RxPayloadCrcOn:1 = no Tx CRC\r\n");
}
void lora_printTxContinuousMode()
{
printf("TxContinuousMode:%d ", lora.RegModemConfig2.sx1276bits.TxContinuousMode); // same for sx1272 and sx1276
}
void lora_printAgcAutoOn()
{
printf("AgcAutoOn:%d", lora.getAgcAutoOn());
}
void lora_print_dio()
{
radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
printf("DIO5:");
switch (radio.RegDioMapping2.bits.Dio5Mapping) {
case 0: printf("ModeReady"); break;
case 1: printf("ClkOut"); break;
case 2: printf("ClkOut"); break;
}
printf(" DIO4:");
switch (radio.RegDioMapping2.bits.Dio4Mapping) {
case 0: printf("CadDetected"); break;
case 1: printf("PllLock"); break;
case 2: printf("PllLock"); break;
}
radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
printf(" DIO3:");
switch (radio.RegDioMapping1.bits.Dio3Mapping) {
case 0: printf("CadDone"); break;
case 1: printf("ValidHeader"); break;
case 2: printf("PayloadCrcError"); break;
}
printf(" DIO2:");
switch (radio.RegDioMapping1.bits.Dio2Mapping) {
case 0:
case 1:
case 2:
printf("FhssChangeChannel");
break;
}
printf(" DIO1:");
switch (radio.RegDioMapping1.bits.Dio1Mapping) {
case 0: printf("RxTimeout"); break;
case 1: printf("FhssChangeChannel"); break;
case 2: printf("CadDetected"); break;
}
printf(" DIO0:");
switch (radio.RegDioMapping1.bits.Dio0Mapping) {
case 0: printf("RxDone"); break;
case 1: printf("TxDone"); break;
case 2: printf("CadDone"); break;
}
printf("\r\n");
}
void fsk_print_dio()
{
radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
printf("DIO5:");
switch (radio.RegDioMapping2.bits.Dio5Mapping) {
case 0: printf("ClkOut"); break;
case 1: printf("PllLock"); break;
case 2:
if (fsk.RegPktConfig2.bits.DataModePacket)
printf("data");
else {
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble");
else
printf("rssi");
}
break;
case 3: printf("ModeReady"); break;
}
printf(" DIO4:");
switch (radio.RegDioMapping2.bits.Dio4Mapping) {
case 0: printf("temp/eol"); break;
case 1: printf("PllLock"); break;
case 2: printf("TimeOut"); break;
case 3:
if (fsk.RegPktConfig2.bits.DataModePacket) {
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble");
else
printf("rssi");
} else
printf("ModeReady");
break;
}
radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
printf(" DIO3:");
switch (radio.RegDioMapping1.bits.Dio3Mapping) {
case 0: printf("Timeout"); break;
case 1:
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble");
else
printf("rssi");
break;
case 2: printf("?automode_status?"); break;
case 3: printf("TempChange/LowBat"); break;
}
printf(" DIO2:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio2Mapping) {
case 0: printf("FifoFull"); break;
case 1: printf("RxReady"); break;
case 2: printf("FifoFull/rx-timeout"); break;
case 3: printf("FifoFull/rx-syncadrs"); break;
}
} else {
printf("Data");
}
printf(" DIO1:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio1Mapping) {
case 0: printf("FifoThresh"); break;
case 1: printf("FifoEmpty"); break;
case 2: printf("FifoFull"); break;
case 3: printf("[41m-3-[0m"); break;
}
} else {
switch (radio.RegDioMapping1.bits.Dio1Mapping) {
case 0: printf("Dclk"); break;
case 1:
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble");
else
printf("rssi");
break;
case 2: printf("[41m-2-[0m"); break;
case 3: printf("[41m-3-[0m"); break;
}
}
printf(" DIO0:");
if (fsk.RegPktConfig2.bits.DataModePacket) {
switch (radio.RegDioMapping1.bits.Dio0Mapping) {
case 0: printf("PayloadReady/PacketSent"); break;
case 1: printf("CrcOk"); break;
case 2: printf("[41m-2-[0m"); break;
case 3: printf("TempChange/LowBat"); break;
}
} else {
switch (radio.RegDioMapping1.bits.Dio0Mapping) {
case 0: printf("SyncAdrs/TxReady"); break;
case 1:
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble");
else
printf("rssi");
break;
case 2: printf("RxReady"); break;
case 3: printf("[41m-3-[0m"); break;
}
}
printf("\r\n");
}
void lora_print_status()
{
uint8_t d;
if (radio.type == SX1276)
printf("\r\nSX1276 ");
else if (radio.type == SX1272)
printf("\r\nSX1272 ");
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
if (!radio.RegOpMode.bits.LongRangeMode) {
printf("FSK\r\n");
return;
}
lora_print_dio();
printf("LoRa ");
// printing LoRa registers at 0x0d -> 0x3f
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
lora_printCodingRate(false); // false: transmitted coding rate
lora_printHeaderMode();
lora_printBw();
lora_printSf();
lora_printRxPayloadCrcOn();
// RegModemStat
printf("ModemStat:0x%02x\r\n", radio.read_reg(REG_LR_MODEMSTAT));
// fifo ptrs:
lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
lora.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
radio.read_reg(REG_LR_FIFOADDRPTR),
radio.read_reg(REG_LR_FIFOTXBASEADDR),
radio.read_reg(REG_LR_FIFORXBASEADDR),
lora.RegPayloadLength,
lora.RegRxMaxPayloadLength
);
lora.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
printLoraIrqs_(false);
lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
if (lora.RegHopPeriod != 0) {
printf("\r\nHopPeriod:0x%02x\r\n", lora.RegHopPeriod);
}
printf("SymbTimeout:0x%03x ", radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
printf("PreambleLength:%d ", lora.RegPreamble);
if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
d = radio.read_reg(REG_LR_RSSIVALUE);
printf("rssi:%ddBm ", d-120);
}
lora_printTxContinuousMode();
printf("\r\n");
lora_printAgcAutoOn();
printf("\r\nHeaderCount:%d PacketCount:%d, ",
radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
printf("Lora detection threshold:%02x\r\n", radio.read_reg(REG_LR_DETECTION_THRESHOLD));
lora.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
printf("detect_trig_same_peaks_nb:%d\r\n", lora.RegTest31.bits.detect_trig_same_peaks_nb);
if (radio.type == SX1272) {
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
} else if (radio.type == SX1276) {
lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);
}
switch (hop_type) {
case HOP_TYPE_NONE:
break;
case HOP_TYPE_64CH:
printf("hop 64ch\n");
break;
case HOP_TYPE_4CH:
printf("hop 4ch\n");
break;
}
printf("\r\n");
}
uint16_t
fsk_get_PayloadLength(void)
{
fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
return fsk.RegPktConfig2.bits.PayloadLength;
}
void fsk_printAddressFiltering()
{
uint8_t FSKRegNodeAdrs, FSKRegBroadcastAdrs;
printf(" AddressFiltering:");
switch (fsk.RegPktConfig1.bits.AddressFiltering) {
case 0: printf("off"); break;
case 1: // NodeAddress
FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
printf("NodeAdrs:%02x\n", FSKRegNodeAdrs);
break;
case 2: // NodeAddress & BroadcastAddress
FSKRegNodeAdrs = radio.read_reg(REG_FSK_NODEADRS);
printf("NodeAdrs:%02x ", FSKRegNodeAdrs);
FSKRegBroadcastAdrs = radio.read_reg(REG_FSK_BROADCASTADRS);
printf("BroadcastAdrs:%02x\n", FSKRegBroadcastAdrs );
break;
default:
printf("%d", fsk.RegPktConfig1.bits.AddressFiltering);
break;
}
}
void fsk_print_IrqFlags2()
{
RegIrqFlags2_t RegIrqFlags2;
printf("IrqFlags2: ");
RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
if (RegIrqFlags2.bits.FifoFull)
printf("FifoFull ");
if (RegIrqFlags2.bits.FifoEmpty)
printf("FifoEmpty ");
if (RegIrqFlags2.bits.FifoLevel)
printf("FifoLevel ");
if (RegIrqFlags2.bits.FifoOverrun)
printf("FifoOverrun ");
if (RegIrqFlags2.bits.PacketSent)
printf("PacketSent ");
if (RegIrqFlags2.bits.PayloadReady)
printf("PayloadReady ");
if (RegIrqFlags2.bits.CrcOk)
printf("CrcOk ");
if (RegIrqFlags2.bits.LowBat)
printf("LowBat ");
printf("\r\n");
}
void
fsk_print_status()
{
//uint16_t s;
RegIrqFlags1_t RegIrqFlags1;
if (radio.RegOpMode.bits.LongRangeMode) {
printf("LoRa\r\n");
return;
}
if (radio.RegOpMode.bits.ModulationType == 0) {
printf("FSK ");
switch (radio.RegOpMode.bits.ModulationShaping) {
case 1: printf("BT1.0 "); break;
case 2: printf("BT0.5 "); break;
case 3: printf("BT0.3 "); break;
}
} else if (radio.RegOpMode.bits.ModulationType == 1) {
printf("OOK ");
}
printf("%dbps fdev:%dHz\r\n", fsk.get_bitrate(), fsk.get_tx_fdev_hz());
fsk.RegPktConfig2.word = radio.read_u16(REG_FSK_PACKETCONFIG2);
fsk_print_dio();
printf("rxbw:%dHz ", fsk.get_rx_bw_hz(REG_FSK_RXBW));
printf("afcbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW));
fsk.RegRssiConfig.octet = radio.read_reg(REG_FSK_RSSICONFIG);
printf("RssiOffset:%ddB smoothing:%dsamples\r\n", fsk.RegRssiConfig.bits.RssiOffset, 1 << (fsk.RegRssiConfig.bits.RssiSmoothing+1));
fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
if (fsk.RegPktConfig2.bits.DataModePacket) {
uint16_t len;
/* packet mode */
len = fsk_get_PayloadLength();
printf("packet RegPayloadLength:0x%03x ", len);
if (fsk.RegPktConfig2.bits.BeaconOn)
printf("BeaconOn ");
fsk.RegFifoThreshold.octet = radio.read_reg(REG_FSK_FIFOTHRESH);
printf("FifoThreshold:%d TxStartCondition:", fsk.RegFifoThreshold.bits.FifoThreshold);
if (fsk.RegFifoThreshold.bits.TxStartCondition)
printf("!FifoEmpty");
else
printf("FifoLevel");
printf("\r\nAutoRestartRxMode:");
switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
case 0: printf("off "); break;
case 1: printf("no-pll-wait "); break;
case 2: printf("pll-wait "); break;
case 3: printf("3 "); break;
}
//...todo
printf("PreambleSize:%d ", radio.read_u16(REG_FSK_PREAMBLEMSB));
fsk.RegOokPeak.octet = radio.read_reg(REG_FSK_OOKPEAK);
if (fsk.RegOokPeak.bits.barker_en)
printf("barker ");
if (!fsk.RegOokPeak.bits.BitSyncOn)
printf("BitSyncOff ");
//...todo
fsk.RegPktConfig1.octet = radio.read_reg(REG_FSK_PACKETCONFIG1);
if (fsk.RegPktConfig1.bits.PacketFormatVariable)
printf("variable");
else
printf("fixed");
printf("-length\r\ncrc");
if (fsk.RegPktConfig1.bits.CrcOn) {
printf("On");
} else
printf("Off");
printf(" crctype:");
if (fsk.RegPktConfig1.bits.CrCWhiteningType)
printf("IBM");
else
printf("CCITT");
printf(" dcFree:");
switch (fsk.RegPktConfig1.bits.DcFree) {
case 0: printf("none "); break;
case 1: printf("Manchester "); break;
case 2: printf("Whitening "); break;
case 3: printf("[41mreserved[0m "); break;
}
fsk_printAddressFiltering();
printf("\r\n");
fsk_print_IrqFlags2();
} else {
/* continuous mode */
printf("[7mcontinuous[27m ");
}
fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
printf("PreambleDetect:");
if (fsk.RegPreambleDetect.bits.PreambleDetectorOn) {
printf("size=%d,tol=%d ",
fsk.RegPreambleDetect.bits.PreambleDetectorSize,
fsk.RegPreambleDetect.bits.PreambleDetectorTol);
} else
printf("Off ");
printf(" syncsize:%d ", fsk.RegSyncConfig.bits.SyncSize);
printf(" : %02x ", radio.read_reg(REG_FSK_SYNCVALUE1));
printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE2));
printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE3));
printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE4));
printf("\r\n"); // end sync config
fsk.RegAfcFei.octet = radio.read_reg(REG_FSK_AFCFEI);
printf("afcAutoClear:");
if (fsk.RegAfcFei.bits.AfcAutoClearOn)
printf("On");
else
printf("OFF");
printf(" afc:%dHz ", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB)));
printf("fei:%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_FEIMSB)));
fsk.RegRxConfig.octet = radio.read_reg(REG_FSK_RXCONFIG);
printf("RxTrigger:");
switch (fsk.RegRxConfig.bits.RxTrigger) {
case 0: printf("none "); break;
case 1: printf("rssi "); break;
case 6: printf("preamble "); break;
case 7: printf("both "); break;
default: printf("-%d- ", fsk.RegRxConfig.bits.RxTrigger); break;
}
printf("AfcAuto:");
if (fsk.RegRxConfig.bits.AfcAutoOn)
printf("On ");
else
printf("OFF ");
if (fsk.RegRxConfig.bits.AgcAutoOn) {
printf("AgcAutoOn ");
} else {
radio.RegLna.octet = radio.read_reg(REG_LNA);
printf("AgcAutoOff:G%d ", radio.RegLna.bits.LnaGain);
}
fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
if (fsk.RegTimerResol.bits.hlm_started)
printf("[35mhlm_started[0m ");
else
printf("hlm_stopped ");
fsk.RegRssiThresh = radio.read_reg(REG_FSK_RSSITHRESH);
printf("rssiThreshold:-%.1f@%02x ", fsk.RegRssiThresh / 2.0, REG_FSK_RSSITHRESH);
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER ||
radio.RegOpMode.bits.Mode == RF_OPMODE_SYNTHESIZER_RX)
{
printf("rssi:-%.1f ", radio.read_reg(REG_FSK_RSSIVALUE) / 2.0);
}
fsk.RegSeqConfig1.octet = radio.read_reg(REG_FSK_SEQCONFIG1);
printf("\r\nsequencer: ");
printf("FromStart:");
switch (fsk.RegSeqConfig1.bits.FromStart) {
case 0:
printf("lowPowerSelection-");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("sequencerOff");
break;
case 1: printf("rx"); break;
case 2: printf("tx"); break;
case 3: printf("tx on fifolevel"); break;
}
printf(" lowPowerSelection:");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("SequencerOff");
if (fsk.RegSeqConfig1.bits.FromStart != 0 &&
fsk.RegSeqConfig1.bits.LowPowerSelection != 0)
{ // if sequencer enabled:
printf("\r\nsequencer: IdleMode:");
if (fsk.RegSeqConfig1.bits.IdleMode)
printf("Sleep");
else
printf("standby");
printf("\r\nsequencer: FromIdle to:");
if (fsk.RegSeqConfig1.bits.FromIdle)
printf("rx");
else
printf("tx");
printf("\r\nsequencer: FromTransmit to:");
if (fsk.RegSeqConfig1.bits.FromTransmit)
printf("rx-on-PacketSent");
else {
printf("lowPowerSelection-");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("SequencerOff");
printf("-on-PacketSent");
}
fsk.RegSeqConfig2.octet = radio.read_reg(REG_FSK_SEQCONFIG2);
printf("\r\nsequencer: FromReceive:");
switch (fsk.RegSeqConfig2.bits.FromReceive) {
case 1: printf("PacketRecevied on PayloadReady"); break;
case 2:
printf("lowPowerSelection-");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("SequencerOff");
printf("-on-payloadReady");
break;
case 3: printf("PacketRecevied-on-CrcOk"); break;
case 4: printf("SequencerOff-on-Rssi"); break;
case 5: printf("SequencerOff-on-SyncAddress"); break;
case 6: printf("SequencerOff-PreambleDetect"); break;
default: printf("-%d-", fsk.RegSeqConfig2.bits.FromReceive); break;
}
printf("\r\nsequencer: FromRxTimeout:");
switch (fsk.RegSeqConfig2.bits.FromRxTimeout) {
case 0: printf("rx"); break;
case 1: printf("tx"); break;
case 2:
printf("lowPowerSelection-");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("SequencerOff");
break;
case 3: printf("SequencerOff"); break;
}
printf("\r\nsequencer: FromPacketReceived to:");
switch (fsk.RegSeqConfig2.bits.FromPacketReceived) {
case 0: printf("SequencerOff"); break;
case 1: printf("tx on FifoEmpty"); break;
case 2:
printf("lowPowerSelection-");
if (fsk.RegSeqConfig1.bits.LowPowerSelection)
printf("idle");
else
printf("sequencerOff");
break;
case 3: printf("rx via fs"); break;
case 4: printf("rx"); break;
}
fsk.RegTimerResol.octet = radio.read_reg(REG_FSK_TIMERRESOL);
printf("\r\nsequencer: timer1:");
switch (fsk.RegTimerResol.bits.timer1_resol) {
case 0: printf("off"); break;
case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER1COEF) * 64); break;
case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER1COEF) * 4.1); break;
case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER1COEF) * 0.262); break;
}
printf(" timer2:");
switch (fsk.RegTimerResol.bits.timer2_resol) {
case 0: printf("off"); break;
case 1: printf("%dus", radio.read_reg(REG_FSK_TIMER2COEF) * 64); break;
case 2: printf("%.1fms", radio.read_reg(REG_FSK_TIMER2COEF) * 4.1); break;
case 3: printf("%.1fs", radio.read_reg(REG_FSK_TIMER2COEF) * 0.262); break;
}
} // ..if sequencer enabled
printf("\r\nIrqFlags1:");
RegIrqFlags1.octet = radio.read_reg(REG_FSK_IRQFLAGS1);
if (RegIrqFlags1.bits.ModeReady)
printf("ModeReady ");
if (RegIrqFlags1.bits.RxReady)
printf("RxReady ");
if (RegIrqFlags1.bits.TxReady)
printf("TxReady ");
if (RegIrqFlags1.bits.PllLock)
printf("PllLock ");
if (RegIrqFlags1.bits.Rssi)
printf("Rssi ");
if (RegIrqFlags1.bits.Timeout)
printf("Timeout ");
if (RegIrqFlags1.bits.PreambleDetect)
printf("PreambleDetect ");
if (RegIrqFlags1.bits.SyncAddressMatch)
printf("SyncAddressMatch ");
printf("\r\n");
/* TODO if (!SX1272FSK->RegPktConfig1.bits.PacketFormatVariable) { // if fixed-length packet format:
s = fsk_get_PayloadLength();
if (s > FSK_LARGE_PKT_THRESHOLD)
flags.fifo_flow_ctl = 1;
else
flags.fifo_flow_ctl = 0;
}*/
fsk.RegImageCal.octet = radio.read_reg(REG_FSK_IMAGECAL);
if (fsk.RegImageCal.bits.TempMonitorOff) {
printf("[42mTempMonitorOff[\r0m\n");
} else {
printf("TempThreshold:");
switch (fsk.RegImageCal.bits.TempThreshold) {
case 0: printf("5C"); break;
case 1: printf("10C"); break;
case 2: printf("15C"); break;
case 3: printf("20C"); break;
}
printf("\r\n");
}
if (fsk.RegImageCal.bits.ImageCalRunning)
printf("[33mImageCalRunning[\r0m\n");
/* printf("flags.fifo_flow_ctl:%d pktidx:%d rx_pktlen:%d", flags.fifo_flow_ctl, pktidx, rx_pktlen);
printf("\n");
//printf("DIO0_PIN:%d\n", digitalRead(DIO0_PIN));
printf("pkt_buf_len=%d remaining=%d\n", pk*/
}
void printOpMode()
{
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
switch (radio.RegOpMode.bits.Mode) {
case RF_OPMODE_SLEEP: printf("[7msleep[0m"); break;
case RF_OPMODE_STANDBY: printf("[7mstby[0m"); break;
case RF_OPMODE_SYNTHESIZER_TX: printf("[33mfstx[0m"); break;
case RF_OPMODE_TRANSMITTER: printf("[31mtx[0m"); break;
case RF_OPMODE_SYNTHESIZER_RX: printf("[33mfsrx[0m"); break;
case RF_OPMODE_RECEIVER: printf("[32mrx[0m"); break;
case 6:
if (radio.RegOpMode.bits.LongRangeMode)
printf("[42mrxs[0m");
else
printf("-6-");
break; // todo: different lora/fsk
case 7:
if (radio.RegOpMode.bits.LongRangeMode)
printf("[45mcad[0m");
else
printf("-7-");
break; // todo: different lora/fsk
}
}
void
printPa()
{
RegPdsTrim1_t pds_trim;
pds_trim.octet = radio.read_reg(REG_PDSTRIM1);
printf(" txdac=%.1fuA", 2.5 + (pds_trim.bits.prog_txdac * 0.625));
radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
if (radio.RegPaConfig.bits.PaSelect) {
//float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower);
float output_dBm = (pds_trim.bits.prog_txdac+13) - (15-radio.RegPaConfig.bits.OutputPower);
printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
} else {
float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8;
float output_dBm = pmax - (15-radio.RegPaConfig.bits.OutputPower);
printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
}
}
void /* things always present, whether lora or fsk */
common_print_status()
{
printf("PD2:%d version:0x%02x %.3fMHz ", pd2.read(), radio.read_reg(REG_VERSION), radio.get_frf_MHz());
printOpMode();
printPa();
radio.RegOcp.octet = radio.read_reg(REG_OCP);
if (radio.RegOcp.bits.OcpOn) {
int imax = 0;
if (radio.RegOcp.bits.OcpTrim < 16)
imax = 45 + (5 * radio.RegOcp.bits.OcpTrim);
else if (radio.RegOcp.bits.OcpTrim < 28)
imax = -30 + (10 * radio.RegOcp.bits.OcpTrim);
else
imax = 240;
printf(" OcpOn %dmA ", imax);
} else
printf(" OcpOFF ");
printf("\r\n");
if (per_en) {
printf("per_tx_delay:%f\n", per_tx_delay);
printf("PER device ID:%d\n", per_id);
}
printf("GPS enabled:%d\r\n", gps.enabled());
}
void per_cb()
{
int i;
PacketTxCnt++;
radio.tx_buf[0] = per_id;
radio.tx_buf[1] = PacketTxCnt >> 24;
radio.tx_buf[2] = PacketTxCnt >> 16;
radio.tx_buf[3] = PacketTxCnt >> 8;
radio.tx_buf[4] = PacketTxCnt;
radio.tx_buf[5] = 'P';
radio.tx_buf[6] = 'E';
radio.tx_buf[7] = 'R';
radio.tx_buf[8] = 0;
for (i = 0; i < 8; i++)
radio.tx_buf[8] += radio.tx_buf[i];
red_led = LED_ON;
lora.start_tx(lora.RegPayloadLength);
}
void dio3_cb()
{
//green_led = LED_ON;
clear_valid_header = true;
}
bool lora_sync_sweep_hi;
uint8_t lora_sync_byte;
void lora_sync_sweep()
{
if (abort_key) {
abort_key = false;
return;
}
hop_timeout.attach(&lora_sync_sweep, 0.1);
if (lora_sync_sweep_hi) {
lora_sync_byte += 0x10;
} else {
if ((lora_sync_byte & 0x0f) == 0x0f)
lora_sync_byte &= 0xf0;
else
lora_sync_byte++;
}
printf("%02x\r\n", lora_sync_byte);
radio.write_reg(REG_LR_SYNC_BYTE, lora_sync_byte);
lora.start_tx(lora.RegPayloadLength);
}
float hop_MHz;
bool new_hop;
uint8_t hop_ofs = 0;
void hop_cb()
{
static uint8_t prev_ofs;
int shift;
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
if (radio.RegOpMode.bits.Mode == RF_OPMODE_TRANSMITTER)
hop_timeout.attach(&hop_cb, 0.4);
else
return;
do {
shift = rand() & 0x1f;
if (hop_type == HOP_TYPE_64CH)
hop_ofs = (rand() >> shift) & 0x3f;
else if (hop_type == HOP_TYPE_4CH)
hop_ofs = (rand() >> shift) & 0x3;
} while (hop_ofs == prev_ofs);
prev_ofs = hop_ofs;
hop_MHz = hop_base_MHz + (hop_ofs * hop_step_MHz);
new_hop = true;
radio.set_frf_MHz(hop_MHz);
radio.set_opmode(RF_OPMODE_STANDBY);
radio.set_opmode(RF_OPMODE_TRANSMITTER);
if (hdr_fem_ctx.read())
hdr_fem_ctx = 0;
else
hdr_fem_ctx = 1;
}
void print_rx_buf(int len)
{
int i;
printf("000:");
for (i = 0; i < len; i++) {
//printf("(%d)%02x ", i % 16, rx_buf[i]);
printf("%02x ", radio.rx_buf[i]);
if (i % 16 == 15 && i != len-1)
printf("\r\n%03d:", i+1);
}
printf("\r\n");
}
void print_rx_verbose(uint8_t len)
{
float dbm;
printLoraIrqs_(false);
if (lora.RegHopPeriod > 0) {
lora.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
printf("HopCH:%d ", lora.RegHopChannel.bits.FhssPresentChannel);
}
lora_printCodingRate(true); // true: of received packet
dbm = lora.get_pkt_rssi();
printf(" crc%s %.1fdB %.1fdBm\r\n",
lora.RegHopChannel.bits.RxPayloadCrcOn ? "On" : "OFF",
lora.RegPktSnrValue / 4.0,
dbm
);
print_rx_buf(/*lora.RegRxNbBytes*/len);
}
void
service_radio()
{
service_action_e act;
if (radio.RegOpMode.bits.LongRangeMode) {
act = lora.service();
switch (act) {
case SERVICE_READ_FIFO:
//green_led = LED_OFF; // ValidHeader indication
if (app == APP_NONE) {
if (per_en) {
if (lora.RegRxNbBytes > 8 && radio.rx_buf[5] == 'P' && radio.rx_buf[6] == 'E' && radio.rx_buf[7] == 'R') {
int i;
float per;
red_led = LED_OFF;
/* this is PER packet */
uint32_t PacketRxSequence = (radio.rx_buf[1] << 24) | (radio.rx_buf[2] << 16) | (radio.rx_buf[3] << 8) | radio.rx_buf[4];
PacketPerOkCnt++;
//IntervalPerOkCnt++;
if( PacketRxSequence <= PacketRxSequencePrev )
{ // Sequence went back => resynchronization
// dont count missed packets this time
i = 0;
}
else
{
// determine number of missed packets
i = PacketRxSequence - PacketRxSequencePrev - 1;
}
// be ready for the next
PacketRxSequencePrev = PacketRxSequence;
// increment 'missed' counter for the RX session
PacketPerKoCnt += i;
//IntervalPerKoCnt += i;
printf("%d, ok=%d missed=%d normal=%d ", PacketRxSequence, PacketPerOkCnt, PacketPerKoCnt, PacketNormalCnt);
per = ( 1.0 - ( float )PacketPerOkCnt / ( float )( PacketPerOkCnt + PacketPerKoCnt ) ) * 100.0;
printf("per:%f\n", per);
} else {
PacketNormalCnt++;
print_rx_verbose(lora.RegRxNbBytes);
}
} else
print_rx_verbose(lora.RegRxNbBytes);
} else if (app == APP_CHAT) {
if (lora.RegHopChannel.bits.RxPayloadCrcOn) {
if (lora.RegIrqFlags.bits.PayloadCrcError)
printf("crcError\r\n");
else {
int n = lora.RegRxNbBytes;
radio.rx_buf[n++] = '\r';
radio.rx_buf[n++] = '\n';
radio.rx_buf[n] = 0; // null terminate
printf((char *)radio.rx_buf);
}
} else
printf("crcOff\r\n");
// clear Irq flags
radio.write_reg(REG_LR_IRQFLAGS, lora.RegIrqFlags.octet);
// should still be in receive mode
}
break;
case SERVICE_TX_DONE:
red_led = LED_OFF;
hdr_fem_csd = 0; //debug
if (app == APP_CHAT) {
lora.start_rx();
} else if (per_en)
per_timeout.attach(&per_cb, per_tx_delay); // start next TX
else if (rx_after_tx)
lora.start_rx();
break;
case SERVICE_ERROR:
printf("error\r\n");
break;
} // ...switch (act)
} else {
/* FSK: */
act = fsk.service();
switch (act) {
case SERVICE_READ_FIFO:
if (app == APP_CHAT) {
int n = fsk.rx_buf_length;
radio.rx_buf[n++] = '\r';
radio.rx_buf[n++] = '\n';
radio.rx_buf[n] = 0; // null terminate
printf((char *)radio.rx_buf);
} else {
int i;
if (fsk.RegRxConfig.bits.AfcAutoOn)
printf("%dHz ", (int)(FREQ_STEP_HZ * fsk.RegAfcValue));
printf("%d: ", fsk.rx_buf_length);
for (i = 0; i < fsk.rx_buf_length; i++)
printf("%02x ", radio.rx_buf[i]);
printf("\r\n");
}
break;
case SERVICE_TX_DONE:
if (app == APP_CHAT) {
fsk.start_rx();
}
break;
} // ...switch (act)
}
if (clear_valid_header) {
RegIrqFlags_t irqs;
irqs.octet = 0;
irqs.bits.ValidHeader = 1;
radio.write_reg(REG_LR_IRQFLAGS, irqs.octet);
clear_valid_header = false;
}
if (new_hop) {
new_hop = false;
printf("%02d %.1f\n", hop_ofs, hop_MHz);
}
}
void
gps_service()
{
gps.service();
if (gps.enabled()) {
if (gps.LatitudeBinary != 0) {
gps.LatitudeBinary = 0;
printf("gps long:%f, lat:%f\r\n", gps.Longitude, gps.Latitude);
}
}
}
int get_kbd_str(char* buf, int size)
{
char c;
int i;
static int prev_len;
for (i = 0;;) {
if (pc.readable()) {
c = pc.getc();
if (c == 8) { // backspace
if (i > 0) {
pc.putc(8);
pc.putc(' ');
pc.putc(8);
i--;
}
} else if (c == '\r') {
if (i == 0) {
return prev_len; // repeat previous
} else {
buf[i] = 0; // null terminate
prev_len = i;
return i;
}
} else if (c == 3) {
// ctrl-C abort
per_en = false;
abort_key = true;
return -1;
} else if (i < size) {
buf[i++] = c;
pc.putc(c);
}
} else {
service_radio();
gps_service();
sx9500.service();
mma8451q.service();
mpl3115a2.service();
}
} // ...for()
}
void
console_chat()
{
int i, len = get_kbd_str(pcbuf, sizeof(pcbuf));
if (len < 0) {
printf("chat abort\r\n");
app = APP_NONE;
return;
} else {
for (i = 0; i < len; i++)
radio.tx_buf[i] = pcbuf[i];
if (radio.RegOpMode.bits.LongRangeMode) {
lora.RegPayloadLength = len;
radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
red_led = LED_ON;
lora.start_tx(len);
} else {
fsk.start_tx(len);
}
printf("\r\n");
}
}
uint8_t last_RxCurrentAddr;
uint8_t last_RxNbBytes;
void
console()
{
int len, i;
uint32_t ui;
uint8_t a, d;
static uint16_t fsk_tx_length;
len = get_kbd_str(pcbuf, sizeof(pcbuf));
if (len < 0) {
printf("abort\r\n");
return;
}
printf("\r\n");
if (len == 1) {
switch (pcbuf[0]) {
case 'i':
printf("init\r\n");
radio.init();
if (!radio.RegOpMode.bits.LongRangeMode) {
fsk.init(); // put FSK modem to some functioning default
} else {
// lora configuration is more simple
}
break;
case 'h':
printf("hw_reset()\r\n");
radio.hw_reset();
break;
case 'R':
// read all registers
for (a = 1; a < 0x71; a++) {
d = radio.read_reg(a);
//update_shadow_regs(selected_radio, a, d);
printf("%02x: %02x\r\n", a, d);
}
break;
case 'T':
if (radio.RegOpMode.bits.LongRangeMode) {
lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
//printf("a %02x\r\n", lora.RegModemConfig2.octet);
lora.RegModemConfig2.sx1276bits.TxContinuousMode ^= 1; // same for sx1272 and sx1276
//printf("b %02x\r\n", lora.RegModemConfig2.octet);
radio.write_reg(REG_LR_MODEMCONFIG2, lora.RegModemConfig2.octet);
lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
//printf("c %02x\r\n", lora.RegModemConfig2.octet);
lora_printTxContinuousMode();
printf("\r\n");
} else
printf("(fsk)\n");
break;
case 'C':
if (radio.RegOpMode.bits.LongRangeMode) {
lora.setRxPayloadCrcOn(!lora.getRxPayloadCrcOn());
lora_printRxPayloadCrcOn();
} else {
printf("CrcOn:");
fsk.RegPktConfig1.bits.CrcOn ^= 1;
radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
if (fsk.RegPktConfig1.bits.CrcOn)
printf("On\r\n");
else
printf("Off\r\n");
if (fsk.RegPktConfig2.bits.DataModePacket && radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER) {
fsk.config_dio0_for_pktmode_rx();
}
}
printf("\r\n");
break;
case 'B':
radio.RegPaConfig.bits.PaSelect ^= 1;
radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
printPa();
printf("\r\n");
break;
case 'L':
if (radio.RegOpMode.bits.LongRangeMode)
fsk.enable(false);
else
lora.enable();
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
if (radio.RegOpMode.bits.LongRangeMode)
printf("LoRa\r\n");
else
printf("FSK\r\n");
break;
case 's':
if (!radio.RegOpMode.bits.LongRangeMode) {
fsk.RegFifoThreshold.bits.TxStartCondition ^= 1;
radio.write_reg(REG_FSK_FIFOTHRESH, fsk.RegFifoThreshold.octet);
printf("TxStartCondition:");
if (fsk.RegFifoThreshold.bits.TxStartCondition)
printf("!FifoEmpty\r\n");
else
printf("FifoLevel\r\n");
}
break;
case 'f':
if (!radio.RegOpMode.bits.LongRangeMode) {
printf("PacketFormat:");
fsk.RegPktConfig1.bits.PacketFormatVariable ^= 1;
radio.write_reg(REG_FSK_PACKETCONFIG1, fsk.RegPktConfig1.octet);
if (fsk.RegPktConfig1.bits.PacketFormatVariable)
printf("variable\r\n");
else
printf("fixed\r\n");
/*if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER)
reset_flow();*/
}
break;
case 'E':
if (!radio.RegOpMode.bits.LongRangeMode) {
RegIrqFlags2_t RegIrqFlags2;
RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
while (!RegIrqFlags2.bits.FifoEmpty) {
if (pc.readable())
break;
printf("%02x\r\n", radio.read_reg(REG_FIFO));
RegIrqFlags2.octet = radio.read_reg(REG_FSK_IRQFLAGS2);
}
}
break;
case 'A':
if (!radio.RegOpMode.bits.LongRangeMode) {
fsk.RegRxConfig.bits.AfcAutoOn ^= 1;
radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
printf("AfcAuto:");
if (fsk.RegRxConfig.bits.AfcAutoOn)
printf("On\r\n");
else
printf("OFF\r\n");
break;
}
break;
case '?':
printf("ge toggle GPS enable\r\n");
printf("L toggle LongRangeMode/FSK\r\n");
printf("i radio_init\r\n");
printf("h hw_reset\r\n");
printf("tx[%%d] transmit\r\n");
printf("rx receive\r\n");
printf("C toggle crcOn\r\n");
printf("op[%%d] get/set output power\r\n");
printf("d[0-5] change DIO pin assignment\r\n");
printf("frf[%%f] get/set operating frequency (MHz)\r\n");
printf("pd2 toggle PA_High_Power\r\n");
printf("bgr[%%d] get/set prog_txdac BGR bias for TXDAC (7=+20dBm)\r\n");
printf("per toggle PER enable\n");
printf("pin[%%f] get/set per_tx_delay (seconds)\n");
printf("pid[%%d] get/set PER device ID\n");
printf("hop change hop type (off, 64ch, 4ch)\n");
printf("hb[%%f] get/set hop base MHz\n");
printf("hs[%%f] get/set hop step MHz\n");
if (radio.RegOpMode.bits.LongRangeMode) {
printf("pl[%%d] LORA get/set RegPayloadLength\r\n");
printf("cr[1234] LORA set coding rate \r\n");
printf("bw[%%d] LORA get/set bandwidth\r\n");
printf("sf[%%d] LORA get/set spreading factor\r\n");
printf("T LORA toggle TxContinuousMode\r\n");
printf("hp[%%d] LORA get/set hop period\r\n");
printf("hm LORA toggle explicit/explicit header mode\r\n");
printf("ld LORA toggle LowDataRateOptimize\r\n");
} else {
printf("bw[a][%%d] FSK get-set rxbw (bwa=afcbw)\r\n");
printf("br[%%d] FSK get-set bitrate\r\n");
printf("fdev[%%d] FSK get-set TX frequency deviation (hz)\r\n");
printf("rt FSK change RxTrigger\r\n");
printf("pd FSK enable/disable preamble detector\r\n");
printf("pt FSK get-set PreambleDetectorTol\r\n");
printf("ss[%%d] FSK get-set SyncSize\r\n");
printf("S[%%x] FSK get-set sync word\r\n");
printf("s FSK toggle TxStartCondition\r\n");
printf("f FSK toggle PacketFormat fixed-variable\r\n");
printf("E FSK empty out the fifo\r\n");
printf("ac FSK AfcClear\r\n");
printf("A FSK toggle AfcAutoOn\r\n");
printf("mp FSK toggle MapPreambleDetect\r\n");
printf("ar FSK change AutoRestartRxMode\r\n");
printf("alc FSK toggle AfcAutoClearOn\r\n");
printf("ag FSK toggle AgcAutoOn\r\n");
printf("pre[%%d} FSK get-set TX preamble length\r\n");
}
break;
case '.':
if (radio.RegOpMode.bits.LongRangeMode)
lora_print_status();
else
fsk_print_status();
common_print_status();
break;
} // ...switch (pcbuf[0])
} else {
if (pcbuf[0] == 't' && pcbuf[1] == 'x') { // TX
if (radio.RegOpMode.bits.LongRangeMode) {
if (per_en) {
printf("timeout attach %f\n", per_tx_delay);
PacketTxCnt = 0;
per_timeout.attach(&per_cb, per_tx_delay);
} else {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
lora.RegPayloadLength = i;
}
tx_cnt++;
for (i = 0; i < lora.RegPayloadLength; i++)
radio.tx_buf[i] = tx_cnt;
red_led = LED_ON;
lora.start_tx(lora.RegPayloadLength);
if (pcbuf[2] == 'r')
rx_after_tx = true;
else
rx_after_tx = false;
}
} else { // FSK:
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
fsk_tx_length = i;
}
if (radio.RegOpMode.bits.Mode != RF_OPMODE_TRANSMITTER) { // if not already busy transmitting
tx_cnt++;
for (i = 0; i < fsk_tx_length; i++) {
radio.tx_buf[i] = tx_cnt;
}
fsk.start_tx(fsk_tx_length);
}
}
if (hop_type != HOP_TYPE_NONE)
hop_timeout.attach(&hop_cb, 0.4);
} else if (pcbuf[0] == 'r' && pcbuf[1] == 'n' && pcbuf[2] == 'd') {
uint8_t of = rand() & 0x3f;
printf("%02d %.2f\n", of, 902.3 + (of * 0.2));
} else if (pcbuf[0] == 'h' && pcbuf[1] == 'b') {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%f", &hop_base_MHz);
}
printf("hop_base:%f\n", hop_base_MHz);
} else if (pcbuf[0] == 'h' && pcbuf[1] == 's') {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%f", &hop_step_MHz);
}
printf("hop_step:%f\n", hop_step_MHz);
} else if (pcbuf[0] == 'h' && pcbuf[1] == 'o' && pcbuf[2] == 'p') {
switch (hop_type) {
case HOP_TYPE_NONE:
hop_type = HOP_TYPE_64CH;
printf("64ch hop\n");
break;
case HOP_TYPE_64CH:
hop_type = HOP_TYPE_4CH;
printf("4ch hop\n");
break;
case HOP_TYPE_4CH:
hop_type = HOP_TYPE_NONE;
printf("hop off\n");
break;
}
} else if (pcbuf[0] == 'h' && pcbuf[1] == 'p' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
lora.RegHopPeriod = i;
radio.write_reg(REG_LR_HOPPERIOD, lora.RegHopPeriod);
if (radio.RegDioMapping1.bits.Dio1Mapping != 1) {
radio.RegDioMapping1.bits.Dio1Mapping = 1;
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
}
}
lora.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
printf("HopPeriod:0x%02x\r\n", lora.RegHopPeriod);
} else if (pcbuf[0] == 'r' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) {
printf("RxTrigger:");
switch (fsk.RegRxConfig.bits.RxTrigger) {
case 0: fsk.RegRxConfig.bits.RxTrigger = 1;
printf("rssi\r\n");
break;
case 1: fsk.RegRxConfig.bits.RxTrigger = 6;
printf("preamble\r\n");
break;
case 6: fsk.RegRxConfig.bits.RxTrigger = 7;
printf("both\r\n");
break;
case 7: fsk.RegRxConfig.bits.RxTrigger = 0;
printf("none\r\n");
break;
default: fsk.RegRxConfig.bits.RxTrigger = 0;
printf("none\r\n");
break;
}
radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
} else if (pcbuf[0] == 'r' && pcbuf[1] == 'x') { // RX
if (per_en) {
red_led = LED_OFF;
//green_led = LED_OFF;
PacketNormalCnt = 0;
PacketRxSequencePrev = -1;
PacketPerKoCnt = 0;
PacketPerOkCnt = 0;
dio3.rise(&dio3_cb);
}
if (radio.RegOpMode.bits.LongRangeMode) {
last_RxCurrentAddr = radio.read_reg(REG_LR_FIFORXCURRENTADDR);
lora.start_rx();
} else
fsk.start_rx();
} else if (pcbuf[0] == 'r' && pcbuf[1] == ' ') { // read single register
sscanf(pcbuf+2, "%x", &i);
printf("%02x: %02x\r\n", i, radio.read_reg(i));
} else if (pcbuf[0] == 'w' && pcbuf[1] == ' ') { // write single register
sscanf(pcbuf+2, "%x %x", &i, &len);
radio.write_reg(i, len);
printf("%02x: %02x\r\n", i, radio.read_reg(i));
}
#ifdef I2C_PIN_TEST
else if (pcbuf[0] == 'b' && pcbuf[1] == '8') {
printf("SCL:");
switch (pcbuf[2]) {
case '0':
pb8.output();
pb8 = 0;
printf("lo");
break;
case '1':
pb8.output();
pb8 = 1;
printf("hi");
break;
case 'z':
pb8.input();
printf("z");
break;
}
printf("\n");
} else if (pcbuf[0] == 'b' && pcbuf[1] == '9') {
printf("SDA:");
switch (pcbuf[2]) {
case '0':
pb9.output();
pb9 = 0;
printf("lo");
break;
case '1':
pb9.output();
pb9 = 1;
printf("hi");
break;
case 'z':
pb9.input();
printf("z");
break;
}
printf("\n");
}
#else
/************************** MMA8451Q... **************************************/
else if (pcbuf[0] == 'm' && pcbuf[1] == 'm') {
if (pcbuf[2] == '?') {
printf("mm. get status\r\n");
printf("mm, print XYZ\n");
printf("mma toggle stby/active\n");
printf("mmtd configure for transient detection\n");
} else if (pcbuf[2] == '.') {
printf("active:%d\n", mma8451q.get_active());
mma8451q.print_regs();
printf("i2c_int_pin:%d\r\n", i2c_int_pin.read());
} else if (pcbuf[2] == ',') {
mma8451q.read(MMA8451_OUT_X_MSB, mma8451q.out.octets, 6);
mma8451q.out.v.x >>= 4; // 12bit data
mma8451q.out.v.y >>= 4; // 12bit data
mma8451q.out.v.z >>= 4; // 12bit data
printf("x:%d y:%d z:%d\n", mma8451q.out.v.x, mma8451q.out.v.y, mma8451q.out.v.z);
} else if (pcbuf[2] == 't' && pcbuf[3] == 'd') {
printf("transient ");
if (mma8451q.transient_cfg.bits.ELE) {
mma8451q.transient_cfg.octet = 0;
mma8451q.write(MMA8451_TRANSIENT_CFG, mma8451q.transient_cfg.octet);
mma8451q.ctrl_reg4.bits.INT_EN_TRANS = 0;
mma8451q.write(MMA8451_CTRL_REG4, mma8451q.ctrl_reg4.octet);
printf("off\n");
} else {
mma8451q.transient_detect();
//poll_timeout.attach(on_poll, 0.3);
printf("on\n");
}
} else if (pcbuf[2] == 'a') {
if (mma8451q.get_active()) {
mma8451q.set_active(0);
} else {
mma8451q.set_active(1);
}
printf("active:%d\n", mma8451q.get_active());
}
}
/************************** MPL3115... **************************************/
else if (pcbuf[0] == 'm' && pcbuf[1] == 'p') {
if (pcbuf[2] == '?') {
printf("mp. get status\r\n");
printf("mpt get temperature\r\n");
printf("mpa get altitude\r\n");
} else if (pcbuf[2] == '.') {
printf("active:%d\r\n", mpl3115a2.GetModeActive());
printf("int src:%02x\r\n", mpl3115a2.read(INT_SOURCE_REG));
/* only INT1 is connected */
printf("CTRL3 int ctl:%02x\r\n", mpl3115a2.read(CTRL_REG3)); /* TODO: PP_OD1 for open-drain operation */
printf("CTRL4 int en:%02x\r\n", mpl3115a2.read(CTRL_REG4));
printf("CTRL5 int cfg:%02x\r\n", mpl3115a2.read(CTRL_REG5));
printf("i2c_int_pin:%d\r\n", i2c_int_pin.read());
} else if (pcbuf[2] == 't') {
printf("temp:%f\r\n", mpl3115a2.ReadTemperature());
} else if (pcbuf[2] == 'a') {
printf("alt:%f\r\n", mpl3115a2.ReadAltitude());
}
}
/************************** sx9500... **************************************/
else if (pcbuf[0] == '9' && pcbuf[1] == '5') {
if (pcbuf[2] == '?') {
printf("95R reset\n");
printf("95. read status\n");
printf("95t[%%d] get/set PROXTHRESH\r\n");
printf("95s[%%d] get/set SCANPERIOD\r\n");
printf("95a toggle txen\r\n");
} else if (pcbuf[2] == '.') {
printf("(txen) active:%d\r\n", sx9500.get_active());
printf("RegStat:%02x\n", sx9500.read_single(SX9500_REG_STAT));
printf("RegProxCtrl0:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL0));
printf("RegProxCtrl1:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL1));
printf("RegProxCtrl2:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL2));
printf("RegProxCtrl3:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL3));
printf("RegProxCtrl4:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL4));
printf("RegProxCtrl5:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL5));
printf("RegProxCtrl6:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL6));
} else if (pcbuf[2] == 'a') {
if (sx9500.get_active()) {
sx9500.set_active(false);
} else {
sx9500.RegProxCtrl0.octet = sx9500.read_single(SX9500_REG_PROXCTRL0);
sx9500.RegProxCtrl0.bits.sensor_en = 3; // CS0 and CS1 on
sx9500.write(SX9500_REG_PROXCTRL0, sx9500.RegProxCtrl0.octet);
sx9500.write(SX9500_REG_PROXCTRL6, 1); // threshold to 20 for CS1 release
sx9500.write(SX9500_REG_IRQMSK, 0x60); // enable near and far interrupts
sx9500.set_active(true);
printf("RegProxCtrl0:%02x\n", sx9500.read_single(SX9500_REG_PROXCTRL0)); /* sensor-enable and scan period */
}
printf("(txen) active:%d\r\n", sx9500.get_active());
} else if (pcbuf[2] == 'R') {
sx9500.reset();
} else if (pcbuf[2] == 'i') {
if (pcbuf[3] != 0) {
sscanf(pcbuf+3, "%x", &i);
sx9500.write(SX9500_REG_IRQMSK, i);
}
printf("irqmsk:%02x\r\n", sx9500.read_single(SX9500_REG_IRQMSK));
} else if (pcbuf[2] == 't') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+3, "%d", &i);
sx9500.write(SX9500_REG_PROXCTRL6, i);
}
printf("proxthresh:0x%x\r\n", sx9500.read_single(SX9500_REG_PROXCTRL6));
} else if (pcbuf[2] == 'p') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+2, "%d", &i);
sx9500.RegProxCtrl0.bits.scan_period = i;
sx9500.write(SX9500_REG_PROXCTRL0, sx9500.RegProxCtrl0.octet);
}
sx9500.RegProxCtrl0.octet = sx9500.read_single(SX9500_REG_PROXCTRL0);
printf("scan period:%d\r\n", sx9500.RegProxCtrl0.bits.scan_period);
}
}
#endif /* !I2C_PIN_TEST */
else if (pcbuf[0] == 'm' && pcbuf[1] == 'p' && !radio.RegOpMode.bits.LongRangeMode) {
radio.RegDioMapping2.bits.MapPreambleDetect ^= 1;
radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
printf("MapPreambleDetect:");
if (radio.RegDioMapping2.bits.MapPreambleDetect)
printf("preamble\r\n");
else
printf("rssi\r\n");
} else if (pcbuf[0] == 'o' && pcbuf[1] == 'p') {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
radio.RegPaConfig.bits.OutputPower = i;
radio.write_reg(REG_PACONFIG, radio.RegPaConfig.octet);
}
radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
printf("OutputPower:%d\r\n", radio.RegPaConfig.bits.OutputPower);
} else if (pcbuf[0] == 'c' && pcbuf[1] == 'r' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9')
lora.setCodingRate(pcbuf[2] - '0');
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
lora_printCodingRate(false); // false: transmitted
printf("\r\n");
} else if (pcbuf[0] == 'h' && pcbuf[1] == 'm' && radio.RegOpMode.bits.LongRangeMode) { // toggle implicit/explicit
lora.setHeaderMode(!lora.getHeaderMode());
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
lora_printHeaderMode();
printf("\r\n");
} else if (pcbuf[0] == 'a' && pcbuf[1] == 'g' && !radio.RegOpMode.bits.LongRangeMode) {
fsk.RegRxConfig.bits.AgcAutoOn ^= 1;
radio.write_reg(REG_FSK_RXCONFIG, fsk.RegRxConfig.octet);
printf("AgcAutoOn:%d\r\n", fsk.RegRxConfig.bits.AgcAutoOn);
} else if (pcbuf[0] == 'a' && pcbuf[1] == 'l' && !radio.RegOpMode.bits.LongRangeMode) {
fsk.RegAfcFei.bits.AfcAutoClearOn ^= 1;
printf("AfcAutoClearOn: ");
radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
if (fsk.RegAfcFei.bits.AfcAutoClearOn)
printf("ON\r\n");
else
printf("off\r\n");
} else if (pcbuf[0] == 'a' && pcbuf[1] == 'r' && !radio.RegOpMode.bits.LongRangeMode) {
fsk.RegSyncConfig.bits.AutoRestartRxMode++;
radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
printf("AutoRestartRxMode:");
switch (fsk.RegSyncConfig.bits.AutoRestartRxMode) {
case 0: printf("off "); break;
case 1: printf("no-pll-wait "); break;
case 2: printf("pll-wait "); break;
case 3: printf("3 "); break;
}
printf("\r\n");
} else if (pcbuf[0] == 'a' && pcbuf[1] == 'c' && !radio.RegOpMode.bits.LongRangeMode) {
printf("clear afc: ");
fsk.RegAfcFei.bits.AfcClear = 1;
radio.write_reg(REG_FSK_AFCFEI, fsk.RegAfcFei.octet);
fsk.RegAfcFei.bits.AfcClear = 0;
printf("%dHz\r\n", (int)(FREQ_STEP_HZ * radio.read_s16(REG_FSK_AFCMSB)));
} else if (pcbuf[0] == 'b' && pcbuf[1] == 'g' && pcbuf[2] == 'r') {
RegPdsTrim1_t pds_trim;
pds_trim.octet = radio.read_reg(REG_PDSTRIM1);
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(&pcbuf[3], "%d", &i);
pds_trim.bits.prog_txdac = i;
}
radio.write_reg(REG_PDSTRIM1, pds_trim.octet);
printf("prog_txdac:%.1fuA\r\n", 2.5 + (pds_trim.bits.prog_txdac * 0.625));
} else if (pcbuf[0] == 'b' && pcbuf[1] == 'r' && !radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(&pcbuf[2], "%d", &i);
fsk.set_bitrate(i);
}
printf("%dbps\r\n", fsk.get_bitrate());
} else if (pcbuf[0] == 'b' && pcbuf[1] == 'w') {
if (radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
radio.set_opmode(RF_OPMODE_STANDBY);
sscanf(&pcbuf[2], "%d", &i);
lora.setBw(i);
} else
lora_printAllBw();
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
printf("current ");
lora_printBw();
printf("\r\n");
} else { // FSK:
if (pcbuf[2] == 'a') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
radio.set_opmode(RF_OPMODE_STANDBY);
sscanf(&pcbuf[3], "%d", &i);
fsk.set_rx_dcc_bw_hz(i, 1);
}
printf("afcbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_AFCBW));
} else {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
radio.set_opmode(RF_OPMODE_STANDBY);
sscanf(&pcbuf[2], "%d", &i);
fsk.set_rx_dcc_bw_hz(i, 0);
}
printf("rxbw:%dHz\r\n", fsk.get_rx_bw_hz(REG_FSK_RXBW));
}
}
} else if (pcbuf[0] == 'v' && pcbuf[1] == 'h') {
lora.poll_vh ^= 1;
printf("poll_vh:%d\r\n", lora.poll_vh);
} else if (pcbuf[0] == 'S' && !radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[1] == '0') {
sscanf(pcbuf+1, "%x", &ui);
if (ui < 0x100) {
fsk.RegSyncConfig.bits.SyncSize = 0;
radio.write_reg(REG_FSK_SYNCVALUE1, ui);
} else if (ui < 0x10000) {
fsk.RegSyncConfig.bits.SyncSize = 1;
radio.write_reg(REG_FSK_SYNCVALUE2, ui & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE1, ui >> 8);
} else if (ui < 0x1000000) {
fsk.RegSyncConfig.bits.SyncSize = 2;
radio.write_reg(REG_FSK_SYNCVALUE3, ui & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE2, (ui >> 8) & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE1, ui >> 16);
} else {
fsk.RegSyncConfig.bits.SyncSize = 3;
radio.write_reg(REG_FSK_SYNCVALUE4, ui & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE3, (ui >> 8) & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE2, (ui >> 16) & 0xff);
radio.write_reg(REG_FSK_SYNCVALUE1, ui >> 24);
}
radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
}
fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
printf("%d: ", fsk.RegSyncConfig.bits.SyncSize);
for (i = 0; i <= fsk.RegSyncConfig.bits.SyncSize; i++)
printf("%02x ", radio.read_reg(REG_FSK_SYNCVALUE1+i));
printf("\r\n");
} else if (pcbuf[0] == 's' && pcbuf[1] == 's') {
if (radio.RegOpMode.bits.LongRangeMode) { // sweep test on lora sync
if (pcbuf[2] == 'h') { // sweep high nibble
lora_sync_sweep_hi = 1;
} else if (pcbuf[2] == 'l') { // sweep low nibble
lora_sync_sweep_hi = 0;
}
lora_sync_byte = radio.read_reg(REG_LR_SYNC_BYTE);
hop_timeout.attach(&lora_sync_sweep, 0.1);
} else {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
fsk.RegSyncConfig.bits.SyncSize = i;
radio.write_reg(REG_FSK_SYNCCONFIG, fsk.RegSyncConfig.octet);
}
fsk.RegSyncConfig.octet = radio.read_reg(REG_FSK_SYNCCONFIG);
printf("SyncSize:%d\r\n", fsk.RegSyncConfig.bits.SyncSize);
}
} else if (pcbuf[0] == 's' && pcbuf[1] == 'f' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
lora.setSf(i);
if (i == 6 && !lora.getHeaderMode()) {
printf("SF6: to implicit header mode\r\n");
lora.setHeaderMode(true);
}
}
lora.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
lora_printSf();
printf("\r\n");
} else if (pcbuf[0] == 'f' && pcbuf[1] == 'i' && !radio.RegOpMode.bits.LongRangeMode) {
fsk.init();
printf("fsk.init\r\n");
} else if (pcbuf[0] == 'f' && pcbuf[1] == 'd' && pcbuf[2] == 'e' && !radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[4] >= '0' && pcbuf[4] <= '9') {
sscanf(pcbuf+4, "%d", &i);
fsk.set_tx_fdev_hz(i);
}
printf("fdev:%dHz\r\n", fsk.get_tx_fdev_hz());
} else if (pcbuf[0] == 'f' && pcbuf[1] == 'r' && pcbuf[2] == 'f') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
float MHz;
sscanf(pcbuf+3, "%f", &MHz);
//printf("MHz:%f\r\n", MHz);
radio.set_frf_MHz(MHz);
}
printf("%fMHz\r\n", radio.get_frf_MHz());
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'i' && pcbuf[2] == 'd') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+3, "%d", &per_id);
}
printf("PER device ID:%d\n", per_id);
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'i' && pcbuf[2] == 'n') {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+2, "%f", &per_tx_delay);
}
printf("per_tx_delay:%f\n", per_tx_delay);
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'e' && pcbuf[2] == 'r') {
per_en ^= 1;
printf("per_en:%d\n", per_en);
if (per_en && radio.RegOpMode.bits.LongRangeMode) {
if (radio.type == SX1272) {
lora.RegModemConfig.sx1272bits.LowDataRateOptimize = 1;
radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
} else if (radio.type == SX1276) {
lora.RegModemConfig3.sx1276bits.LowDataRateOptimize = 1;
radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
}
lora.RegPayloadLength = 9;
radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
radio.RegDioMapping1.bits.Dio3Mapping = 1; // to ValidHeader
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
}
PacketRxSequencePrev = -1;
//PacketRxSequence = 0;
PacketPerKoCnt = 0;
PacketPerOkCnt = 0;
PacketNormalCnt = 0;
if (!per_en) {
per_timeout.detach();
}
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'r' && pcbuf[2] == 'e') {
if (radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+3, "%d", &i);
radio.write_u16(REG_LR_PREAMBLEMSB, i);
}
lora.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
printf("lora PreambleLength:%d\r\n", lora.RegPreamble);
} else {
if (pcbuf[3] >= '0' && pcbuf[3] <= '9') {
sscanf(pcbuf+3, "%d", &i);
radio.write_u16(REG_FSK_PREAMBLEMSB, i);
}
printf("FSK TX PreambleSize:%d\r\n", radio.read_u16(REG_FSK_PREAMBLEMSB));
}
} else if (pcbuf[0] == 'p' && pcbuf[1] == 't' && !radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
fsk.RegPreambleDetect.bits.PreambleDetectorTol = i;
radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
}
fsk.RegPreambleDetect.octet = radio.read_reg(REG_FSK_PREAMBLEDETECT);
printf("PreambleDetectorTol:%d\r\n", fsk.RegPreambleDetect.bits.PreambleDetectorTol);
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'd' && pcbuf[2] == '2') {
if (pd2.read())
pd2 = 0;
else
pd2 = 1;
printf("pd2:%d\n", pd2.read());
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'd' && !radio.RegOpMode.bits.LongRangeMode) {
fsk.RegPreambleDetect.bits.PreambleDetectorOn ^= 1;
radio.write_reg(REG_FSK_PREAMBLEDETECT, fsk.RegPreambleDetect.octet);
printf("PreambleDetector:");
if (fsk.RegPreambleDetect.bits.PreambleDetectorOn)
printf("On\r\n");
else
printf("OFF\r\n");
} else if (pcbuf[0] == 'p' && pcbuf[1] == 'l' && radio.RegOpMode.bits.LongRangeMode) {
if (pcbuf[2] >= '0' && pcbuf[2] <= '9') {
sscanf(pcbuf+2, "%d", &i);
lora.RegPayloadLength = i;
radio.write_reg(REG_LR_PAYLOADLENGTH, lora.RegPayloadLength);
}
lora.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
printf("PayloadLength:%d\r\n", lora.RegPayloadLength);
} else if (pcbuf[0] == 'l' && pcbuf[1] == 'd' && radio.RegOpMode.bits.LongRangeMode) {
if (radio.type == SX1272) {
lora.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
lora.RegModemConfig.sx1272bits.LowDataRateOptimize ^= 1;
printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig.sx1272bits.LowDataRateOptimize);
radio.write_reg(REG_LR_MODEMCONFIG, lora.RegModemConfig.octet);
} else if (radio.type == SX1276) {
lora.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
lora.RegModemConfig3.sx1276bits.LowDataRateOptimize ^= 1;
printf("LowDataRateOptimize:%d\r\n", lora.RegModemConfig3.sx1276bits.LowDataRateOptimize);
radio.write_reg(REG_LR_MODEMCONFIG3, lora.RegModemConfig3.octet);
}
} else if (pcbuf[0] == 'd' && pcbuf[1] >= '0' && pcbuf[1] <= '5') {
switch (pcbuf[1]) {
case '0':
radio.RegDioMapping1.bits.Dio0Mapping++;
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
break;
case '1':
radio.RegDioMapping1.bits.Dio1Mapping++;
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
break;
case '2':
radio.RegDioMapping1.bits.Dio2Mapping++;
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
break;
case '3':
radio.RegDioMapping1.bits.Dio3Mapping++;
radio.write_reg(REG_DIOMAPPING1, radio.RegDioMapping1.octet);
break;
case '4':
radio.RegDioMapping2.bits.Dio4Mapping++;
radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
break;
case '5':
radio.RegDioMapping2.bits.Dio5Mapping++;
radio.write_reg(REG_DIOMAPPING2, radio.RegDioMapping2.octet);
break;
} // ...switch (pcbuf[1])
if (radio.RegOpMode.bits.LongRangeMode)
lora_print_dio();
else
fsk_print_dio();
} else if (pcbuf[0] == 'g') { /******* GPS... **********/
if (pcbuf[1] == 'e') {
//gps.enable(!gps.enabled());
if (gps.enabled()) {
gps.enable(false);
printf("gps disabled\r\n");
} else {
gps.enable(true);
printf("GPS enabled\r\n");
}
} else if (pcbuf[1] == 'v') {
gps.verbose ^= 1;
printf("gps.verbose:%d\r\n", gps.verbose);
}
} else if (pcbuf[0] == 's' && pcbuf[1] == 't' && pcbuf[2] == 'b') {
radio.set_opmode(RF_OPMODE_STANDBY);
//green_led = LED_OFF;
red_led = LED_OFF;
} else if (pcbuf[0] == 's' && pcbuf[1] == 'l' && pcbuf[2] == 'e') {
radio.set_opmode(RF_OPMODE_SLEEP);
//green_led = LED_OFF;
red_led = LED_OFF;
} else if (pcbuf[0] == 'c' && pcbuf[1] == 'h' && pcbuf[2] == 'a') {
app = APP_CHAT;
lora.start_rx();
printf("chat start\r\n");
}
}
printf("> ");
fflush(stdout);
}
int main()
{
pc.baud(57600);
gps.init();
printf("\nreset\n");
//green_led = LED_OFF;
red_led = LED_OFF;
radio.rf_switch.attach(rfsw_callback);
if (radio.RegOpMode.bits.LongRangeMode)
last_RxCurrentAddr = radio.read_reg(REG_LR_FIFORXCURRENTADDR);
gps.enable(false);
sx9500.RegProxCtrl0.bits.sensor_en = 3; // only CS0 and CS1 connected
sx9500.write(SX9500_REG_PROXCTRL0, sx9500.RegProxCtrl0.octet);
// set PROXTHRESH to 80 because CS1 has 48 showing always on PROXDIFF
sx9500.write(SX9500_REG_PROXCTRL6, 0x04);
mma8451q.set_active(0);
mpl3115a2.SetModeStandby();
while(1) {
switch (app) {
case APP_NONE:
console();
break;
case APP_CHAT:
console_chat();
break;
} // ...switch (app)
} // ...while(1)
}
/*
GPS, Pressure sensor, touch sensor etc
3-axis accelerometer: MMA8415IQ peripherials/mma8415..c
SX9500 SAR, peripherials/sx9500.c
altimeter & temperature: MPL3115A2. peripherials/mpl3115.c
GPS: NMEA from system/gps.c, boards/LoRaMote/gps-board.c
*
*/
