Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ad21e4e
Start hopping channels with TX/RX of SYNC_CLOCKS
LeeLeahy2 Jan 5, 2023
ab5b537
Compute the retransmit timeout (backoff) in retransmitDatagram
LeeLeahy2 Jan 5, 2023
798d309
Clear timeToHop when delaying the hop
LeeLeahy2 Jan 6, 2023
ab58f44
Don't spin forever when a channel timer value error is detected on RX
LeeLeahy2 Jan 6, 2023
e9519a7
Fix the case when both the remote and local values are negative
LeeLeahy2 Jan 6, 2023
fc83ce5
Transmit a valid value of channelTimer when the timer is not running
LeeLeahy2 Jan 7, 2023
6542a09
Stop the channel timer when the P2P link is down
LeeLeahy2 Jan 7, 2023
2be3dab
Better handle the LEDs
LeeLeahy2 Jan 7, 2023
91aca0a
Add the timestamp to link up and link down display
LeeLeahy2 Jan 9, 2023
3f2898d
Add frameAirTimeMsec parameter to syncChannelTime
LeeLeahy2 Jan 9, 2023
72e4492
Add channelTimer history
LeeLeahy2 Jan 9, 2023
ca7dde8
Add a trigger to measure the transmit time
LeeLeahy2 Jan 9, 2023
1743f9d
Compute the transmit times for SYNC_CLOCKS, HEARTBEAT and DATA_ACK
LeeLeahy2 Jan 9, 2023
d962c67
Pass in the frame air time when computing the timestamp offset
LeeLeahy2 Jan 9, 2023
c3843dc
Rename FrameTimeout to SerialDelay and move to serial settings
LeeLeahy2 Jan 9, 2023
cf5f7bf
Move overheadTime from being a radio parameter to being a debug param
LeeLeahy2 Jan 9, 2023
390c62b
Describe the steps to prevent attacks on the LoRaSerial network
LeeLeahy2 Jan 9, 2023
267b183
Output the correct channelNumber LSB on port A1 in syncChannelTimer
LeeLeahy2 Jan 9, 2023
3ba72d3
Display the ACK, HEARTBEAT and SYNC_CLOCKS transmit times with ATI10
LeeLeahy2 Jan 9, 2023
4969ce6
Update the VC HEARTBEAT diagram
LeeLeahy2 Jan 9, 2023
436d504
Properly set the VC_HEARTBEAT_BYTES value
LeeLeahy2 Jan 9, 2023
fb6f8fc
Add virtual-circuit triggers for TX and RX
LeeLeahy2 Jan 9, 2023
79da1cc
Virtual Circuit: Synchronize channel timer using the VC_HEARTBEAT frame
LeeLeahy2 Jan 9, 2023
eb033a5
Add DATA_ACK, HEARTBEAT and SYNC_CLOCKS air time in mSec to SYNC_CLOCKS
LeeLeahy2 Jan 9, 2023
2309b2b
Multipoint: Start the channelTimer synchronization
LeeLeahy2 Jan 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Firmware/LoRaSerial_Firmware/Begin.ino
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,17 @@ void channelTimerHandler()
channelTimerStart = millis(); //Record when this ISR happened. Used for calculating clock sync.
radioCallHistory[RADIO_CALL_channelTimerHandler] = channelTimerStart;

//Restore the full timer interval
channelTimer.setInterval_MS(settings.maxDwellTime, channelTimerHandler);
channelTimerMsec = settings.maxDwellTime; //ISR update
digitalWrite(pin_hop_timer, channelNumber & 1);
//If the last timer was used to sync clocks, restore full timer interval
if (reloadChannelTimer == true)
{
reloadChannelTimer = false;
channelTimer.setInterval_MS(settings.maxDwellTime, channelTimerHandler);
channelTimerMsec = settings.maxDwellTime; //ISR update
}

if (settings.frequencyHop)
{
digitalWrite(pin_hop_timer, ((channelNumber + 1) % settings.numberOfChannels) & 1);
triggerEvent(TRIGGER_CHANNEL_TIMER_ISR);
timeToHop = true;
}
Expand Down
21 changes: 10 additions & 11 deletions Firmware/LoRaSerial_Firmware/Commands.ino
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,14 @@ bool commandAT(const char * commandString)

//Clock synchronization
systemPrintln(" Clock Synchronization");
systemPrint(" TX Time: ");
systemPrint(txTimeUsec / 1000., 4);
systemPrintln(" mSec");
systemPrint(" RX Time: ");
systemPrint(rxTimeUsec / 1000., 4);
systemPrintln(" mSec");
systemPrint(" Total Time: ");
systemPrint((txTimeUsec + rxTimeUsec) / 1000., 5);
systemPrintln(" mSec");
systemPrint(" ACK Time: ");
systemPrint(txDataAckUsec);
systemPrint(" HEARTBEAT Time: ");
systemPrint(txHeartbeatUsec);
systemPrintln(" uSec");
systemPrint(" SYNC_CLOCKS Time: ");
systemPrint(txSyncClockUsec);
systemPrintln(" uSec");
systemPrint(" Uptime: ");
deltaMillis = millis();
systemPrintTimestamp(deltaMillis);
Expand Down Expand Up @@ -1068,6 +1067,7 @@ const COMMAND_ENTRY commands[] =
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "DebugTransmit", &tempSettings.debugTransmit},
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "DebugSerial", &tempSettings.debugSerial},
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "DisplayRealMillis", &tempSettings.displayRealMillis},
{'D', 0, 1, 0, 1000, 0, TYPE_U16, valInt, "OverHeadtime", &tempSettings.overheadTime},
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "PrintAckNumbers", &tempSettings.printAckNumbers},
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "PrintChannel", &tempSettings.printChannel},
{'D', 1, 0, 0, 1, 0, TYPE_BOOL, valInt, "PrintFrequency", &tempSettings.printFrequency},
Expand Down Expand Up @@ -1102,12 +1102,10 @@ const COMMAND_ENTRY commands[] =
{'R', 0, 1, 0, 1, 0, TYPE_BOOL, valInt, "EncryptData", &tempSettings.encryptData},
{'R', 0, 1, 0, 0, 0, TYPE_KEY, valKey, "EncryptionKey", &tempSettings.encryptionKey},
{'R', 0, 0, 0, 255, 0, TYPE_U8, valInt, "FramesToYield", &tempSettings.framesToYield},
{'R', 0, 0, 10, 2000, 0, TYPE_U16, valInt, "FrameTimeout", &tempSettings.serialTimeoutBeforeSendingFrame_ms},
{'R', 0, 0, 250, 65535, 0, TYPE_U16, valInt, "HeartBeatTimeout", &tempSettings.heartbeatTimeout},
{'R', 0, 0, 0, 255, 0, TYPE_U8, valInt, "MaxResends", &tempSettings.maxResends},
{'R', 0, 1, 0, 255, 0, TYPE_U8, valInt, "NetID", &tempSettings.netID},
{'R', 0, 1, 0, 2, 0, TYPE_U8, valInt, "OperatingMode", &tempSettings.operatingMode},
{'R', 0, 1, 0, 1000, 0, TYPE_U16, valInt, "OverHeadtime", &tempSettings.overheadTime},
{'R', 0, 0, 0, 1, 0, TYPE_BOOL, valServer, "Server", &tempSettings.server},
{'R', 0, 1, 0, 1, 0, TYPE_BOOL, valInt, "VerifyRxNetID", &tempSettings.verifyRxNetID},

Expand All @@ -1118,6 +1116,7 @@ const COMMAND_ENTRY commands[] =
{'S', 0, 0, 0, 1, 0, TYPE_BOOL, valInt, "FlowControl", &tempSettings.flowControl},
{'S', 0, 0, 0, 1, 0, TYPE_BOOL, valInt, "InvertCts", &tempSettings.invertCts},
{'S', 0, 0, 0, 1, 0, TYPE_BOOL, valInt, "InvertRts", &tempSettings.invertRts},
{'S', 0, 0, 10, 2000, 0, TYPE_U16, valInt, "SerialDelay", &tempSettings.serialTimeoutBeforeSendingFrame_ms},
{'S', 0, 0, 0, 0, 0, TYPE_SPEED_SERIAL, valSpeedSerial, "SerialSpeed", &tempSettings.serialSpeed},
{'S', 0, 0, 0, 1, 0, TYPE_BOOL, valInt, "UsbSerialWait", &tempSettings.usbSerialWait},

Expand Down
37 changes: 18 additions & 19 deletions Firmware/LoRaSerial_Firmware/LoRaSerial_Firmware.ino
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ const int FIRMWARE_VERSION_MINOR = 0;
//Frame lengths
#define MP_HEARTBEAT_BYTES 0 //Number of data bytes in the MP_HEARTBEAT frame
#define P2P_FIND_PARTNER_BYTES sizeof(unsigned long) //Number of data bytes in the FIND_PARTNER frame
#define P2P_SYNC_CLOCKS_BYTES (sizeof(uint8_t) + sizeof(unsigned long)) //Number of data bytes in the SYNC_CLOCKS frame
#define P2P_SYNC_CLOCKS_BYTES (sizeof(uint8_t) + sizeof(unsigned long) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t)) //Number of data bytes in the SYNC_CLOCKS frame
#define P2P_ZERO_ACKS_BYTES sizeof(unsigned long) //Number of data bytes in the ZERO_ACKS frame
#define P2P_HEARTBEAT_BYTES sizeof(unsigned long) //Number of data bytes in the HEARTBEAT frame
#define P2P_ACK_BYTES sizeof(unsigned long) //Number of data bytes in the ACK frame
#define VC_HEARTBEAT_BYTES 0 //Number of data bytes in the VC_HEARTBEAT frame
#define VC_HEARTBEAT_BYTES 1 + 1 + 1 + 16 + 4 //Number of data bytes in the VC_HEARTBEAT frame

#define TX_TO_RX_USEC 680 //Time from TX to RX transactionComplete in microseconds

//Bit 0: Signal Detected indicates that a valid LoRa preamble has been detected
//Bit 1: Signal Synchronized indicates that the end of Preamble has been detected, the modem is in lock
Expand Down Expand Up @@ -125,14 +127,16 @@ uint8_t pin_hop_timer = PIN_UNDEFINED;
#define RADIO_USE_BAD_FRAMES_LED BLUE_LED //Blue
#define RADIO_USE_BAD_CRC_LED YELLOW_LED //Yellow

#define LED_MP_HOP_CHANNEL BLUE_LED
#define LED_MP_HEARTBEAT YELLOW_LED
#define LED_MP_HEARTBEAT BLUE_LED
#define LED_MP_HOP_CHANNEL YELLOW_LED

#define CYLON_TX_DATA_LED BLUE_LED
#define CYLON_RX_DATA_LED YELLOW_LED

#define LED_ON HIGH
#define LED_OFF LOW

#define LED_MAX_PULSE_WIDTH 24 //mSec
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//Radio Library
Expand Down Expand Up @@ -170,6 +174,7 @@ SAMDTimer channelTimer(TIMER_TCC); //Available: TC3, TC4, TC5, TCC, TCC1 or TCC2
volatile uint16_t channelTimerMsec; //Last value programmed into the channel timer
volatile unsigned long channelTimerStart = 0; //Tracks how long our timer has been running since last hop
volatile bool timeToHop = false; //Set by channelTimerHandler to indicate that hopChannel needs to be called
volatile bool reloadChannelTimer = false; //When set channel timer interval needs to be reloaded with settings.maxDwellTime

uint16_t petTimeout = 0; //A reduced amount of time before WDT triggers. Helps reduce amount of time spent petting.
unsigned long lastPet = 0; //Remebers time of last WDT pet.
Expand Down Expand Up @@ -363,10 +368,8 @@ bool writeOnCommandExit = false; //Goes true if user specifies ATW command

//Global variables - LEDs
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
int trainCylonNumber = 0b0001;
int trainCylonDirection = -1;

unsigned long lastTrainBlink = 0; //Controls LED during training
uint8_t cylonLedPattern = 0b0001;
bool cylonPatternGoingLeft;
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//Global variables - Radio (General)
Expand All @@ -389,19 +392,8 @@ float frequencyCorrection = 0; //Adjust receive freq based on the last packet re

volatile bool hop = true; //Clear the DIO1 hop ISR when possible

//RSSI must be above these negative numbers for LED to illuminate
const int rssiLevelLow = -150;
const int rssiLevelMed = -120;
const int rssiLevelHigh = -100;
const int rssiLevelMax = -70;
int rssi; //Average signal level, measured during reception of a packet

//LED control values
uint32_t ledPreviousRssiMillis;
uint32_t ledHeartbeatMillis;
int8_t ledRssiCount; //Pulse width count for LED display
int8_t ledRssiValue; //Target pulse width count for LED display

//Link quality metrics
uint32_t datagramsSent; //Total number of datagrams sent
uint32_t datagramsReceived; //Total number of datagrams received
Expand Down Expand Up @@ -439,6 +431,8 @@ unsigned long radioStateHistory[RADIO_MAX_STATE];

uint8_t packetLength = 0; //Total bytes received, used for calculating clock sync times in multi-point mode
int16_t msToNextHopRemote; //Can become negative
uint8_t clockSyncIndex;
CLOCK_SYNC_DATA clockSyncData[16];

bool requestYield = false; //Datagram sender can tell this radio to stop transmitting to enable two-way comm
unsigned long yieldTimerStart = 0;
Expand Down Expand Up @@ -585,13 +579,18 @@ char platformPrefix[25]; //Used for printing platform specific device name, ie "
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

bool clockSyncReceiver; //Receives and processes the clock synchronization
bool startChannelTimerPending; //When true, call startChannelTimer in transactionCompleteISR

//RX and TX time measurements
uint32_t rxTimeUsec;
uint32_t txTimeUsec;
uint16_t txRxTimeMsec;

uint32_t txSetChannelTimerMicros; //Timestamp when millis is read in TX routine to set channel timer value
uint32_t transactionCompleteMicros; //Timestamp at the beginning of the transactionCompleteIsr routine
uint32_t txDataAckUsec; //Time in microseconds to transmit the DATA_ACK frame
uint32_t txHeartbeatUsec; //Time in microseconds to transmit the HEARTBEAT frame
uint32_t txSyncClockUsec; //Time in microseconds to transmit the SYNC_CLOCKS frame
uint32_t txDatagramMicros; //Timestamp at the beginning of the transmitDatagram routine
uint16_t maxFrameAirTime; //Air time of the maximum sized message
unsigned long remoteSystemMillis; //Millis value contained in the received message
Expand Down
Loading