first commit
This commit is contained in:
75
lib/SX12XX-LoRa/src/AFSKRTTY.h
Normal file
75
lib/SX12XX-LoRa/src/AFSKRTTY.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 12/05/20
|
||||
*/
|
||||
|
||||
void startAFSKRTTY(int8_t audiopin, uint16_t freq, uint32_t afskleadinmS)
|
||||
{
|
||||
tone(audiopin, freq); //lead in is high tone
|
||||
delay(afskleadinmS);
|
||||
}
|
||||
|
||||
|
||||
void endAFSKRTTY(int8_t audiopin)
|
||||
{
|
||||
delay(500); //500mS seconds of high tone to finish
|
||||
noTone(audiopin);
|
||||
}
|
||||
|
||||
|
||||
void sendAFSKRTTY(uint8_t chartosend, int8_t audiopin, int8_t checkpin, uint16_t tonelowHz, uint16_t tonehighHz, uint32_t perioduS)
|
||||
//send the byte in chartosend as AFSK RTTY, assumes mark condition (idle) is already present
|
||||
//Format is 7 bits, no parity and 2 stop bits
|
||||
{
|
||||
uint8_t numbits;
|
||||
uint32_t startuS;
|
||||
|
||||
startuS = micros();
|
||||
digitalWrite(checkpin, LOW);
|
||||
tone(audiopin, tonelowHz);
|
||||
|
||||
while ( (uint32_t) (micros() - startuS) < perioduS); //wait for start bit end
|
||||
|
||||
for (numbits = 1; numbits <= 7; numbits++) //send 7 bits, LSB first
|
||||
{
|
||||
startuS = micros();
|
||||
if ((chartosend & 0x01) != 0)
|
||||
{
|
||||
digitalWrite(checkpin, HIGH);
|
||||
tone(audiopin, tonehighHz);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(checkpin, LOW);
|
||||
tone(audiopin, tonelowHz); //start 0 bit low tone
|
||||
}
|
||||
chartosend = (chartosend / 2); //get the next bit
|
||||
while ( (uint32_t) (micros() - startuS) < perioduS); //wait bit period uS
|
||||
}
|
||||
perioduS = perioduS * 2;
|
||||
startuS = micros();
|
||||
digitalWrite(checkpin, HIGH); //start mark condition
|
||||
tone(audiopin, tonehighHz); //start high tone
|
||||
while ( (uint32_t) (micros() - startuS) < perioduS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
180
lib/SX12XX-LoRa/src/AFSKRTTY2.h
Normal file
180
lib/SX12XX-LoRa/src/AFSKRTTY2.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 18/12/20
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
This is the AFSK RTTY send library specifically for microcontrollers that do not have a tone() function
|
||||
such as Arduino DUE and ESP32. Tones are generated here by manually toggling the selected tone pin with
|
||||
a suitable delay between toggles.
|
||||
|
||||
The baud rate and tone frequecies used can be adjusted by usin the startAFSKRTTY() command.
|
||||
|
||||
The library has been tested and will work on an Arduion Pro Mini 8Mhz, Arduino DUE and ESP32 and when
|
||||
used with this startup command;
|
||||
|
||||
startAFSKRTTY(AUDIOOUTpin, CHECKpin, 5, 1000, 7, 714, 0, 1000);
|
||||
|
||||
This outputs AFSKRTTY at 100baud, 7bit, no parity, 1stop bit, low tone 1000hz, hightone 1400hz.
|
||||
|
||||
The audio comes out of the pin passed via AUDIOOUTpin and the bit timing can be checked by looking at
|
||||
the CHECKpin on a scope or analyser.
|
||||
|
||||
A low pass filter consiting of a 47K resistor and 470nF capacitor was used to redice the output for
|
||||
feeding into a PC soundcard.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define AFSKRTTY_UNUSED(v) (void) (v) //add AFSKRTTY_UNUSED(variable); in functions to avoid compiler warnings
|
||||
|
||||
int8_t _audiopin, _checkpin, _adjust;
|
||||
uint8_t _lowcycles, _highcycles;
|
||||
uint32_t _lowperioduS, _highperioduS;
|
||||
|
||||
void startAFSKRTTY(int8_t audiopin, int8_t checkpin, uint8_t lowcycles, uint16_t lowperioduS, uint8_t highcycles, uint16_t highperioduS, int16_t adjust, uint16_t leadinmS);
|
||||
void sendAFSKRTTY(uint8_t chartosend);
|
||||
void toneHigh();
|
||||
void toneLow();
|
||||
|
||||
|
||||
void startAFSKRTTY(int8_t audiopin, int8_t checkpin, uint8_t lowcycles, uint16_t lowperioduS, uint8_t highcycles, uint16_t highperioduS, int16_t adjust, uint16_t leadinmS)
|
||||
{
|
||||
uint32_t startmS;
|
||||
_audiopin = audiopin;
|
||||
_checkpin = checkpin;
|
||||
_lowperioduS = (lowperioduS / 2) + adjust; //period passed is equal to frequency, but delays are in two halfs
|
||||
_highperioduS = (highperioduS / 2) + adjust;
|
||||
_lowcycles = lowcycles;
|
||||
_highcycles = highcycles;
|
||||
_adjust = adjust;
|
||||
|
||||
if (audiopin > 0)
|
||||
{
|
||||
pinMode(audiopin, OUTPUT);
|
||||
}
|
||||
|
||||
if (checkpin > 0)
|
||||
{
|
||||
pinMode(checkpin, OUTPUT);
|
||||
}
|
||||
|
||||
startmS = millis();
|
||||
|
||||
while ( (uint32_t) (millis() - startmS) < leadinmS) //allows for millis() overflow
|
||||
{
|
||||
digitalWrite(audiopin, HIGH);
|
||||
delayMicroseconds(_highperioduS);
|
||||
digitalWrite(audiopin, LOW);
|
||||
delayMicroseconds(_highperioduS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void endAFSKRTTY(int8_t audiopin, int8_t checkpin, uint16_t leadoutmS)
|
||||
{
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
|
||||
while ( (uint32_t) (millis() - startmS) < leadoutmS) //allows for millis() overflow
|
||||
{
|
||||
digitalWrite(audiopin, HIGH);
|
||||
delayMicroseconds(_highperioduS);
|
||||
digitalWrite(audiopin, LOW);
|
||||
delayMicroseconds(_highperioduS);
|
||||
}
|
||||
|
||||
if (audiopin > 0)
|
||||
{
|
||||
pinMode(audiopin, INPUT);
|
||||
}
|
||||
|
||||
if (checkpin > 0)
|
||||
{
|
||||
pinMode(checkpin, INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void toneHigh()
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 1; index <= _highcycles; index++)
|
||||
{
|
||||
digitalWrite(_audiopin, HIGH);
|
||||
delayMicroseconds(_highperioduS);
|
||||
digitalWrite(_audiopin, LOW);
|
||||
delayMicroseconds(_highperioduS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void toneLow()
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 1; index <= _lowcycles; index++)
|
||||
{
|
||||
digitalWrite(_audiopin, HIGH);
|
||||
delayMicroseconds(_lowperioduS);
|
||||
digitalWrite(_audiopin, LOW);
|
||||
delayMicroseconds(_lowperioduS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sendAFSKRTTY(uint8_t chartosend)
|
||||
//send the byte in chartosend as AFSK RTTY, assumes mark condition (idle) is already present
|
||||
//Format is 7 bits, no parity and 2 stop bits
|
||||
{
|
||||
|
||||
uint8_t numbits;
|
||||
digitalWrite(_checkpin, LOW);
|
||||
toneLow();
|
||||
|
||||
for (numbits = 1; numbits <= 7; numbits++) //send 7 bits, LSB first
|
||||
{
|
||||
if ((chartosend & 0x01) != 0)
|
||||
{
|
||||
digitalWrite(_checkpin, HIGH);
|
||||
toneHigh();
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(_checkpin, LOW);
|
||||
toneLow();
|
||||
}
|
||||
chartosend = (chartosend / 2); //get the next bit
|
||||
}
|
||||
digitalWrite(_checkpin, HIGH); //start mark condition
|
||||
toneHigh();
|
||||
toneHigh();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
101
lib/SX12XX-LoRa/src/AtmelSleep.h
Normal file
101
lib/SX12XX-LoRa/src/AtmelSleep.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 24/04/20
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
|
||||
These are sleep routines for Atmel processors, tested on ATmega328. When calling the sleep routines be
|
||||
sure there are no pending interrupts such as from Serial.print(), strange things can happen otherwise.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <avr/sleep.h> //sleep library for Atmel processor
|
||||
#include <avr/wdt.h> //watchdog library for Atmel processor
|
||||
|
||||
|
||||
//Atmel watchdog sleep times
|
||||
#define sleep16mS 0x00
|
||||
#define sleep32mS 0x01
|
||||
#define sleep64mS 0x02
|
||||
#define sleep125mS 0x03
|
||||
#define sleep250mS 0x04
|
||||
#define sleep500mS 0x05
|
||||
#define sleep1000mS 0x06
|
||||
#define sleep2000mS 0x07
|
||||
#define sleep4000mS 0x20
|
||||
#define sleep8000mS 0x21
|
||||
|
||||
|
||||
void SleepSeconds(uint32_t secs);
|
||||
void SleepmS(uint32_t sleeps, uint8_t numbermS);
|
||||
void atmelSleepPermanent();
|
||||
|
||||
|
||||
void SleepSeconds(uint32_t secs)
|
||||
{
|
||||
//for Atmel processor only
|
||||
uint16_t sleeps8secs, sleeps1secs;
|
||||
|
||||
sleeps8secs = secs >> 3;
|
||||
sleeps1secs = secs - (sleeps8secs << 3);
|
||||
SleepmS(sleeps8secs, sleep8000mS);
|
||||
SleepmS(sleeps1secs, sleep1000mS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SleepmS(uint32_t sleeps, uint8_t numbermS)
|
||||
{
|
||||
//for Atmel processor only
|
||||
uint32_t index;
|
||||
|
||||
for (index = 1; index <= sleeps; index++)
|
||||
{
|
||||
ADCSRA = 0; //disable ADC
|
||||
MCUSR = 0; //clear various "reset" flags
|
||||
WDTCSR = bit (WDCE) | bit (WDE); //allow changes, disable reset
|
||||
WDTCSR = bit (WDIE) + numbermS; //set the number of mS for sleep
|
||||
wdt_reset(); //pat the pet, could be a dog
|
||||
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
|
||||
noInterrupts (); //timed sequence follows
|
||||
sleep_enable();
|
||||
MCUCR = bit (BODS) | bit (BODSE); //turn off brown-out enable in software
|
||||
MCUCR = bit (BODS);
|
||||
interrupts (); //guarantees next instruction executed
|
||||
|
||||
sleep_cpu ();
|
||||
//awake here
|
||||
sleep_disable(); //cancel sleep as a precaution
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void atmelSleepPermanent()
|
||||
{
|
||||
ADCSRA = 0; //disable ADC
|
||||
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
|
||||
noInterrupts (); //timed sequence follows
|
||||
sleep_enable();
|
||||
|
||||
// turn off brown-out enable in software
|
||||
MCUCR = bit (BODS) | bit (BODSE); //turn on brown-out enable select
|
||||
MCUCR = bit (BODS); //this must be done within 4 clock cycles of above
|
||||
interrupts (); //guarantees next instruction executed
|
||||
|
||||
sleep_cpu (); //sleep within 3 clock cycles of above
|
||||
|
||||
/* wake up here */
|
||||
|
||||
sleep_disable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ISR (WDT_vect)
|
||||
{
|
||||
//watchdog interrupt
|
||||
wdt_disable(); // disable watchdog
|
||||
}
|
||||
|
||||
|
||||
88
lib/SX12XX-LoRa/src/EEPROM_Memory.h
Normal file
88
lib/SX12XX-LoRa/src/EEPROM_Memory.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
24/04/20
|
||||
*/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Library Operation - This library is for reading from and writing to the EEPROM. These routines provide
|
||||
a funtional match to the libraries for FRAM.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <EEPROM.h>
|
||||
#define LTUNUSED(v) (void) (v) //add LTUNUSED(variable); in functions to avoid compiler warnings
|
||||
|
||||
void memoryStart(uint16_t addr) //yes I know the EEPROM does not have an address, but the other memory types do
|
||||
{
|
||||
//left empty for future use
|
||||
LTUNUSED(addr); //avoids compliler warning
|
||||
}
|
||||
|
||||
|
||||
void memoryEnd()
|
||||
{
|
||||
//left empty for future use
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint8(uint16_t addr, uint8_t x)
|
||||
{
|
||||
//write a byte to the EEPROM
|
||||
EEPROM.put(addr, x);
|
||||
}
|
||||
|
||||
|
||||
uint16_t readMemoryUint16(uint16_t addr)
|
||||
{
|
||||
uint16_t x;
|
||||
EEPROM.get(addr, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
uint32_t readMemoryUint32(uint16_t addr)
|
||||
{
|
||||
uint32_t x;
|
||||
EEPROM.get(addr, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint32(uint16_t addr, uint32_t x)
|
||||
{
|
||||
EEPROM.put(addr, x);
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint16(uint16_t addr, uint16_t x)
|
||||
{
|
||||
EEPROM.put(addr, x);
|
||||
}
|
||||
|
||||
|
||||
float readMemoryFloat(uint16_t addr)
|
||||
{
|
||||
float x;
|
||||
EEPROM.get(addr, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryFloat(uint16_t addr, float x)
|
||||
{
|
||||
EEPROM.put(addr, x);
|
||||
}
|
||||
|
||||
|
||||
void fillMemory(uint16_t startaddr, uint16_t endaddr, uint8_t lval)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = startaddr; i <= endaddr; i++)
|
||||
{
|
||||
writeMemoryUint8(i, lval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
462
lib/SX12XX-LoRa/src/FRAM_FM24CL64.h
Normal file
462
lib/SX12XX-LoRa/src/FRAM_FM24CL64.h
Normal file
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
14/04/20
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************************************
|
||||
Library Operation - This library is for reading from and writing to the 64kbit (8kbyte) I2C FRAMS.
|
||||
|
||||
Take care when writing variables to the end of the address space, the writes and reads may wrap
|
||||
around back to address 0
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
int16_t Memory_I2C_Addr = 0x50; //default I2C address of FM24CL64 FRAM
|
||||
|
||||
|
||||
void memoryStart(int16_t addr)
|
||||
{
|
||||
Memory_I2C_Addr = addr;
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
|
||||
void memorySetAddress(int16_t addr)
|
||||
{
|
||||
Memory_I2C_Addr = addr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void memoryEnd()
|
||||
{
|
||||
//left empty for future use
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Write Routines
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
void writeMemoryChar(uint16_t addr, char x)
|
||||
{
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt8(uint16_t addr, int8_t x)
|
||||
{
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint8(uint16_t addr, uint8_t x)
|
||||
{
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt16(uint16_t addr, int16_t x)
|
||||
{
|
||||
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
uint8_t msb_data = highByte(x);
|
||||
uint8_t lsb_data = lowByte(x);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(lsb_data);
|
||||
Wire.write(msb_data);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint16(uint16_t addr, uint16_t x)
|
||||
{
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
uint8_t msb_data = highByte(x);
|
||||
uint8_t lsb_data = lowByte(x);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(lsb_data);
|
||||
Wire.write(msb_data);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt32(uint16_t addr, int32_t x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint32(uint16_t addr, uint32_t x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryFloat(uint16_t addr, float x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
float f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Read Routines
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
char readMemoryChar(uint16_t addr)
|
||||
{
|
||||
char data;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
int8_t readMemoryInt8(uint16_t addr)
|
||||
{
|
||||
int8_t data;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t readMemoryUint8(uint16_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
int16_t readMemoryInt16(uint16_t addr)
|
||||
{
|
||||
|
||||
uint8_t lsb_data, msb_data;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr, 2);
|
||||
lsb_data = Wire.read();
|
||||
msb_data = Wire.read();
|
||||
|
||||
return (lsb_data + (msb_data * 256));
|
||||
}
|
||||
|
||||
|
||||
uint16_t readMemoryUint16(uint16_t addr)
|
||||
{
|
||||
|
||||
uint8_t lsb_data, msb_data;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr, 2);
|
||||
lsb_data = Wire.read();
|
||||
msb_data = Wire.read();
|
||||
|
||||
return (lsb_data + (msb_data * 256));
|
||||
}
|
||||
|
||||
|
||||
int32_t readMemoryInt32(uint16_t addr)
|
||||
{
|
||||
uint8_t val;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
unsigned long f;
|
||||
} readdata;
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
uint32_t readMemoryUint32(uint16_t addr)
|
||||
{
|
||||
uint8_t val;
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
unsigned long f;
|
||||
} readdata;
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
float readMemoryFloat(uint16_t addr)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
uint8_t msb_addr = highByte(addr);
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr);
|
||||
Wire.write(msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
float f;
|
||||
} readdata;
|
||||
|
||||
|
||||
for (int index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Start of general purpose memory routines
|
||||
***************************************************************************/
|
||||
|
||||
uint16_t CRCMemory(uint16_t startaddr, uint16_t endaddr, uint16_t startval)
|
||||
{
|
||||
uint16_t i, libraryCRC;
|
||||
uint8_t j;
|
||||
|
||||
libraryCRC = startval; //start value for CRC16, often 0xffff
|
||||
|
||||
for (i = startaddr; i <= endaddr; i++) //element 4 is first character after $$$$ at start
|
||||
{
|
||||
libraryCRC ^= ((uint16_t)readMemoryUint8(i) << 8);
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (libraryCRC & 0x8000)
|
||||
libraryCRC = (libraryCRC << 1) ^ 0x1021;
|
||||
else
|
||||
libraryCRC <<= 1;
|
||||
}
|
||||
}
|
||||
return libraryCRC;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printMemory(uint16_t start_addr, uint16_t end_addr)
|
||||
{
|
||||
//print the contents of Memory
|
||||
|
||||
uint8_t value;
|
||||
|
||||
for (uint16_t a = start_addr; a <= end_addr; a++)
|
||||
{
|
||||
value = readMemoryUint8(a);
|
||||
if ((a % 16) == 0)
|
||||
{
|
||||
Serial.println();
|
||||
Serial.print(F("0x"));
|
||||
if (a < 0x10)
|
||||
{
|
||||
Serial.print('0');
|
||||
}
|
||||
Serial.print(a, HEX);
|
||||
Serial.print(F(": "));
|
||||
}
|
||||
Serial.print(F("0x"));
|
||||
if (value < 0x10)
|
||||
Serial.print('0');
|
||||
Serial.print(value, HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void fillMemory(uint16_t startaddr, uint16_t endaddr, uint8_t lval)
|
||||
{
|
||||
uint16_t i;
|
||||
for (i = startaddr; i <= endaddr; i++)
|
||||
{
|
||||
writeMemoryUint8(i, lval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
447
lib/SX12XX-LoRa/src/FRAM_MB85RC16PNF.h
Normal file
447
lib/SX12XX-LoRa/src/FRAM_MB85RC16PNF.h
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
14/04/20
|
||||
*/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Library Operation - This library is for reading from and writing to the 16kbit (2Kbyte) I2C FRAMS.
|
||||
These FRAMS present as a series of eight 256 byte pages at I2C addresses 0X50 to 0x57. The library
|
||||
calculates from the passed address which page to write to. For variables that are larger than one
|
||||
uint8_t take care not to set the address so that a write would cross a page boundary. The library
|
||||
does not deal with writes or reads that cross the 256 byte pages of the device.
|
||||
*******************************************************************************************************/
|
||||
|
||||
#include <Wire.h>
|
||||
|
||||
int16_t Memory_I2C_Addr = 0x50; //default I2C address of MB85RC16PNF FRAM
|
||||
|
||||
|
||||
void memoryStart(int16_t addr)
|
||||
{
|
||||
Memory_I2C_Addr = addr;
|
||||
Wire.begin();
|
||||
}
|
||||
|
||||
|
||||
void memorySetAddress(int16_t addr)
|
||||
{
|
||||
Memory_I2C_Addr = addr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void memoryEnd()
|
||||
{
|
||||
//left empty for future use
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Write Routines
|
||||
**************************************************************************/
|
||||
|
||||
void writeMemoryChar(uint16_t addr, char x)
|
||||
{
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt8(uint16_t addr, int8_t x)
|
||||
{
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint8(uint16_t addr, uint8_t x)
|
||||
{
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(x);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt16(uint16_t addr, int16_t x)
|
||||
{
|
||||
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
uint8_t msb_data = highByte(x);
|
||||
uint8_t lsb_data = lowByte(x);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(lsb_data);
|
||||
Wire.write(msb_data);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryUint16(uint16_t addr, uint16_t x)
|
||||
{
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
uint8_t msb_data = highByte(x);
|
||||
uint8_t lsb_data = lowByte(x);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.write(lsb_data);
|
||||
Wire.write(msb_data);
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryInt32(uint16_t addr, int32_t x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void writeMemoryUint32(uint16_t addr, uint32_t x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
|
||||
void writeMemoryFloat(uint16_t addr, float x)
|
||||
{
|
||||
uint8_t index, val;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
float f;
|
||||
} data;
|
||||
|
||||
data.f = x;
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = data.b[index];
|
||||
Wire.write(val); //write the data
|
||||
}
|
||||
|
||||
Wire.endTransmission();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Read Routines
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
char readMemoryChar(uint16_t addr)
|
||||
{
|
||||
char data;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr + msb_addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
int8_t readMemoryInt8(uint16_t addr)
|
||||
{
|
||||
int8_t data;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr + msb_addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
uint8_t readMemoryUint8(uint16_t addr)
|
||||
{
|
||||
uint8_t data;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom((Memory_I2C_Addr + msb_addr), 1);
|
||||
data = Wire.read();
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
int16_t readMemoryInt16(uint16_t addr)
|
||||
{
|
||||
|
||||
uint8_t lsb_data, msb_data;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr + msb_addr, 2);
|
||||
lsb_data = Wire.read();
|
||||
msb_data = Wire.read();
|
||||
|
||||
return (lsb_data + (msb_data * 256));
|
||||
}
|
||||
|
||||
|
||||
uint16_t readMemoryUint16(uint16_t addr)
|
||||
{
|
||||
|
||||
uint8_t lsb_data, msb_data;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr + msb_addr, 2);
|
||||
lsb_data = Wire.read();
|
||||
msb_data = Wire.read();
|
||||
|
||||
return (lsb_data + (msb_data * 256));
|
||||
}
|
||||
|
||||
|
||||
int32_t readMemoryInt32(uint16_t addr)
|
||||
{
|
||||
uint8_t val, index;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr + msb_addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} readdata;
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
uint32_t readMemoryUint32(uint16_t addr)
|
||||
{
|
||||
uint8_t val, index;
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr + msb_addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
uint32_t f;
|
||||
} readdata;
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
float readMemoryFloat(uint16_t addr)
|
||||
{
|
||||
uint8_t val, index;
|
||||
|
||||
uint8_t msb_addr = (highByte(addr) & 0x07); //get 3 MSB bits of address
|
||||
uint8_t lsb_addr = lowByte(addr);
|
||||
|
||||
Wire.beginTransmission(Memory_I2C_Addr + msb_addr);
|
||||
Wire.write(lsb_addr);
|
||||
Wire.endTransmission();
|
||||
Wire.requestFrom(Memory_I2C_Addr + msb_addr, 4);
|
||||
|
||||
union
|
||||
{
|
||||
uint8_t b[4];
|
||||
float f;
|
||||
} readdata;
|
||||
|
||||
|
||||
for (index = 0; index < 4; index++)
|
||||
{
|
||||
val = Wire.read(); // read the uint8_t
|
||||
readdata.b[index] = val;
|
||||
}
|
||||
return readdata.f;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Start of general purpose memory routines
|
||||
***************************************************************************/
|
||||
|
||||
uint16_t CRCMemory(uint16_t startaddr, uint16_t endaddr, uint16_t startval)
|
||||
{
|
||||
uint16_t i, libraryCRC;
|
||||
uint8_t j;
|
||||
|
||||
libraryCRC = startval; //start value for CRC16, often 0xffff
|
||||
|
||||
for (i = startaddr; i <= endaddr; i++) //element 4 is first character after $$$$ at start
|
||||
{
|
||||
libraryCRC ^= ((uint16_t)readMemoryUint8(i) << 8);
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (libraryCRC & 0x8000)
|
||||
libraryCRC = (libraryCRC << 1) ^ 0x1021;
|
||||
else
|
||||
libraryCRC <<= 1;
|
||||
}
|
||||
}
|
||||
return libraryCRC;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void printMemory(uint16_t start_addr, uint16_t end_addr)
|
||||
{
|
||||
//print the contents of Memory
|
||||
|
||||
uint8_t value;
|
||||
|
||||
for (uint16_t a = start_addr; a <= end_addr; a++)
|
||||
{
|
||||
value = readMemoryUint8(a);
|
||||
if ((a % 16) == 0)
|
||||
{
|
||||
Serial.println();
|
||||
Serial.print(F("0x"));
|
||||
if (a < 0x10)
|
||||
{
|
||||
Serial.print('0');
|
||||
}
|
||||
Serial.print(a, HEX);
|
||||
Serial.print(F(": "));
|
||||
}
|
||||
Serial.print(F("0x"));
|
||||
if (value < 0x10)
|
||||
Serial.print('0');
|
||||
Serial.print(value, HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void fillMemory(uint16_t startaddr, uint16_t endaddr, uint8_t lval)
|
||||
{
|
||||
uint16_t i;
|
||||
for (i = startaddr; i <= endaddr; i++)
|
||||
{
|
||||
writeMemoryUint8(i, lval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
25
lib/SX12XX-LoRa/src/LICENSE.txt
Normal file
25
lib/SX12XX-LoRa/src/LICENSE.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
--- Revised BSD License ---
|
||||
Copyright (c) 2013, SEMTECH S.A.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Semtech corporation nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
123
lib/SX12XX-LoRa/src/ProgramLT_Definitions.h
Normal file
123
lib/SX12XX-LoRa/src/ProgramLT_Definitions.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*******************************************************************************************************
|
||||
Programs for Arduino - Copyright of the author Stuart Robinson - 17/12/19
|
||||
|
||||
This program is supplied as is, it is up to the user of the program to decide if the program is
|
||||
suitable for the intended purpose and free from errors.
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************************************
|
||||
Definitions for packet types
|
||||
******************************************************************************************************
|
||||
*/
|
||||
|
||||
const char Sensor1 = '!'; //Sensor packet1
|
||||
const char HABPacket = '$'; //HAB style CSV ASCII packet
|
||||
const char Broadcast = '*'; //Broadcast destination address
|
||||
const char RControl1 = 'D'; //Remote Control packet
|
||||
const char TestMode1 = '1'; //used to switch to Testmode1 settings
|
||||
const char TestPacket = 'T'; //Test packet
|
||||
const char TXError = 't'; //Transmitter error
|
||||
const char PowerUp = 'P'; //sent on tracker start
|
||||
const char LocationPacket = 'L'; //LT library tracker location packet in binary format
|
||||
const char LocationBinaryPacket = 's'; //short location packet in binary format
|
||||
const char NoFix = 'F'; //GPS no fix
|
||||
const char NoGPS = 'G'; //No GPS found, or GPS error.
|
||||
const char ACK = 'A'; //Acknowledge
|
||||
const char NACK = 'N'; //Not Acknowledge, error
|
||||
const char AFC = 'a'; //Packet sent for AFC purposes
|
||||
|
||||
const uint8_t Reliable = 0x80; //this packet type indicates reliable data packet
|
||||
const uint8_t ReliableACK = 0x81; //this packet type indicates reliable data packet acknowledge
|
||||
const uint8_t FTtype = 0xF0; //FTsubtype file transfer type
|
||||
const uint8_t FTstart = 0xF1; //FTsubtype file transfer start information, filename etc
|
||||
const uint8_t FTsegment = 0xF2; //FTsubtype packet contains a numbered segment
|
||||
const uint8_t FTACK = 0xF3; //FTsubtype ACK response for file transfers
|
||||
const uint8_t FTNACK = 0xF4; //FTsubtype NACK response for file transfers
|
||||
const uint8_t FTclose = 0xF5; //FTsubtype request from TX to close file, transfer finished
|
||||
const uint8_t FTrestart = 0xF6; //FTsubtype request from RX to restart current file transfer
|
||||
|
||||
//GPS Tracker Status byte settings
|
||||
const uint8_t GPSFix = 0; //flag bit set when GPS has a current fix
|
||||
const uint8_t GPSConfigError = 1; //flag bit set to indicate cannot configure GPS or wrong configuration
|
||||
const uint8_t CameraError = 2; //flag bit indicating a camera device error
|
||||
const uint8_t GPSError = 3; //flag bit set to indicate GPS error, response timeout for instance
|
||||
const uint8_t LORAError = 4; //flag bit indication a lora device error
|
||||
const uint8_t SDError = 5; //flag bit indication a SD card device error
|
||||
const uint8_t TrackerLost = 6; //flag bit indication that tracker in lost mode
|
||||
const uint8_t NoGPSTestMode = 7; //flag bit number to indicate tracker in no GPS test mode
|
||||
|
||||
/*********************************************************************
|
||||
START Stored Program data
|
||||
**********************************************************************/
|
||||
const uint16_t addr_StartMemory = 0x00; //the start of memory
|
||||
const uint16_t addr_StartProgramData = 0x100; //the start of program data in memory
|
||||
const uint16_t addr_ResetCount = 0x100; //unsigned long int 4 bytes
|
||||
const uint16_t addr_SequenceNum = 0x104; //unsigned long int 4 bytes
|
||||
const uint16_t addr_TXErrors = 0x108; //uint16_t 2 bytes
|
||||
const uint16_t addr_EndMemory = 0x3FF;
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
START GPS CoordinateData
|
||||
**********************************************************************/
|
||||
//for storing last received GPS co-ordinates from local and remote tracker GPS
|
||||
const uint16_t addr_StartCoordinateData = 0x300;
|
||||
const uint16_t addr_RemoteLat = 0x300; //float 4 bytes
|
||||
const uint16_t addr_RemoteLon = 0x304; //float 4 bytes
|
||||
const uint16_t addr_RemoteAlt = 0x308; //uint16_t 2 bytes
|
||||
const uint16_t addr_RemoteHour = 0x30C; //byte 1 byte; Note times for last tracker co-ordinates come from local GPS time
|
||||
const uint16_t addr_RemoteMin = 0x310; //byte 1 byte
|
||||
const uint16_t addr_RemoteSec = 0x311; //byte 1 byte
|
||||
const uint16_t addr_RemoteDay = 0x312; //byte 1 byte
|
||||
const uint16_t addr_RemoteMonth = 0x313; //byte 1 byte
|
||||
const uint16_t addr_RemoteYear = 0x314; //byte 1 byte
|
||||
const uint16_t addr_LocalLat = 0x318; //float 4 bytes
|
||||
const uint16_t addr_LocalLon = 0x31C; //float 4 bytes
|
||||
const uint16_t addr_LocalAlt = 0x320; //uint16_t 2 bytes
|
||||
const uint16_t addr_LocalHour = 0x322; //byte 1 byte
|
||||
const uint16_t addr_LocalMin = 0x323; //byte 1 byte
|
||||
const uint16_t addr_LocalSec = 0x324; //byte 1 byte
|
||||
const uint16_t addr_LocalDay = 0x325; //byte 1 byte
|
||||
const uint16_t addr_LocalMonth = 0x326; //byte 1 byte
|
||||
const uint16_t addr_LocalYear = 0x327; //byte 1 byte
|
||||
const uint16_t addr_EndCoordinateData = 0x327;
|
||||
|
||||
const uint16_t addr_RemotelocationCRC = 0x340; //the 16 bit CRC of the last tracker location data is saved here
|
||||
const uint16_t addr_LocallocationCRC = 0x342; //the 16 bit CRC of the last local location data is saved here
|
||||
|
||||
const uint16_t addr_TestLocation_page3 = 0x3FF; //used as a location for read\write tests
|
||||
|
||||
/*********************************************************************
|
||||
END GPS CoordinateData
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************************************
|
||||
Bit numbers for current_config byte settings end definitions for packet types
|
||||
******************************************************************************************************
|
||||
*/
|
||||
|
||||
//Bit numbers for current_config byte settings in transmitter (addr_Default_config1)
|
||||
const uint8_t SearchEnable = 0; //bit num to set in config byte to enable search mode packet
|
||||
const uint8_t TXEnable = 1; //bit num to set in config byte to enable transmissions
|
||||
const uint8_t FSKRTTYEnable = 2; //bit num to set in config byte to enable FSK RTTY
|
||||
const uint8_t DozeEnable = 4; //bit num to set in config byte to put tracker in Doze mode
|
||||
const uint8_t GPSHotFix = 7; //bit when set enables GPS Hot Fix mode.
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************************************
|
||||
Values for reliable transmit\receive errors
|
||||
******************************************************************************************************
|
||||
*/
|
||||
const uint16_t packettypeErr = 0x01;
|
||||
const uint16_t destErr = 0x02;
|
||||
const uint16_t sourceErr = 0x04;
|
||||
const uint16_t timeoutErr = 0x08;
|
||||
const uint16_t IDErr = 0x10;
|
||||
const uint16_t crcErr = 0x20;
|
||||
const uint16_t seqErr = 0x40;
|
||||
const uint16_t packetErr = 0x80;
|
||||
608
lib/SX12XX-LoRa/src/QuectelSerialGPS.h
Normal file
608
lib/SX12XX-LoRa/src/QuectelSerialGPS.h
Normal file
@@ -0,0 +1,608 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 12/05/20
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - This is a library file for the Quectel L70,L76,L80 and L86 GPSs
|
||||
|
||||
The routines assume that the GPS has been setup on GPSserial which could be either software serial or
|
||||
hardware serial. This library file has optimisations that the use of SoftwareSerial requires.
|
||||
|
||||
The calling program should include a define for the GPS baud rate as follows
|
||||
|
||||
#define GPSBaud 9600
|
||||
|
||||
If this define is missing then 9600 baud is assumed
|
||||
*******************************************************************************************************/
|
||||
|
||||
const PROGMEM uint8_t SetBalloonMode[] = {"$PMTK886,3*2B"}; //response should be $PMTK001,886,3*36
|
||||
const PROGMEM uint8_t ClearConfig[] = {"$PMTK104*37"}; //no response
|
||||
const PROGMEM uint8_t PMTK_ACK[] = {"$PMTK001,xxx,?"}; //? = 0 = invalid, 1 = unsupported, 2 = valid failed, 3 = valids succeeded
|
||||
const PROGMEM uint8_t SoftwareBackup[] = {"$PMTK161,0*28"}; //response should be $PMTK001,161,3*36
|
||||
const PROGMEM uint8_t HotStart[] = {"$PMTK101*32"};
|
||||
const PROGMEM uint8_t GGARMCOnly[] = {"$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"};
|
||||
|
||||
uint8_t GPS_GetByte();
|
||||
void GPS_OutputOn();
|
||||
void GPS_OutputOff();
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state);
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state);
|
||||
bool GPS_Setup();
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts);
|
||||
bool GPS_WaitAck(uint32_t waitms, uint8_t length);
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS);
|
||||
uint8_t GPS_GetNextChar(uint32_t waitmS);
|
||||
bool GPS_CheckAck();
|
||||
bool GPS_SetBalloonMode();
|
||||
bool GPS_CheckBalloonMode();
|
||||
bool GPS_ClearConfig();
|
||||
bool GPS_SetCyclicMode();
|
||||
bool GPS_SoftwareBackup();
|
||||
bool GPS_HotStart();
|
||||
bool GPS_PollNavigation();
|
||||
bool GPS_SaveConfig();
|
||||
|
||||
bool GPS_GLONASSOff(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GPGLLOff(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GPGLSOff(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GPGSAOff(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GPGSVOff(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GNSSmode(); //not currently implemented on Quectel GPS
|
||||
bool GPS_GGARMCOnly();
|
||||
|
||||
|
||||
const uint32_t GPS_WaitAck_mS = 2000; //number of mS to wait for an ACK response from GPS
|
||||
const uint8_t GPS_attempts = 10; //number of times the sending of GPS config will be attempted.
|
||||
const uint8_t GPS_Reply_Size = 20; //size of GPS reply buffer
|
||||
const uint16_t GPS_Clear_DelaymS = 2000; //mS to wait after a GPS Clear command is sent
|
||||
uint8_t GPS_Reply[GPS_Reply_Size]; //byte array for storing GPS reply to UBX commands
|
||||
|
||||
|
||||
#define QUECTELINUSE //so complier can know which GPS library is used //so complier can know which GPS library is used
|
||||
//#define GPSDebug
|
||||
|
||||
|
||||
#ifndef GPSBaud
|
||||
#define GPSBaud 9600
|
||||
#endif
|
||||
|
||||
|
||||
void GPS_OutputOn()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_OutputOn() "));
|
||||
#endif
|
||||
//turns on serial output from GPS
|
||||
GPSserial.begin(GPSBaud);
|
||||
while (GPSserial.available()) GPSserial.read(); //make sure input buffer is empty
|
||||
}
|
||||
|
||||
|
||||
void GPS_OutputOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_OutputOff() "));
|
||||
#endif
|
||||
//turns off serial output from GPS
|
||||
GPSserial.end();
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOn() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOff() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_Setup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Setup() "));
|
||||
#endif
|
||||
|
||||
if (!GPS_SetBalloonMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GGARMCOnly())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SendConfig() "));
|
||||
#endif
|
||||
|
||||
uint8_t byteread, index;
|
||||
uint8_t config_attempts = attempts;
|
||||
|
||||
memset(GPS_Reply, 0, sizeof(GPS_Reply)); //clear the reply buffer
|
||||
|
||||
Serial.flush(); //ensure there are no pending interrupts from serial monitor printing
|
||||
|
||||
do
|
||||
{
|
||||
if (config_attempts == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GPS_OutputOff();
|
||||
|
||||
Serial.print(F("GPSSend "));
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
Serial.write(byteread);
|
||||
}
|
||||
|
||||
Serial.flush(); //make sure serial out buffer is empty
|
||||
|
||||
GPS_OutputOn();
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
GPSserial.write(byteread);
|
||||
}
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start, in case config command retried
|
||||
|
||||
GPSserial.write(13);
|
||||
GPSserial.write(10);
|
||||
|
||||
if (replylength == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
GPSserial.flush(); //make sure all of config command has been sent
|
||||
config_attempts--;
|
||||
}
|
||||
while (!GPS_WaitAck(GPS_WaitAck_mS, replylength));
|
||||
|
||||
delay(100); //GPS can sometimes be a bit slow getting ready for next config
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
if (GPSchar == waitforchar)
|
||||
{
|
||||
GPS_Reply[0] = GPSchar;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((uint32_t) (millis() - startmS) < waitmS); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetNextChar(uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
GPS_Reply[1] = GPSchar;
|
||||
return GPSchar;
|
||||
}
|
||||
}
|
||||
while ((uint32_t) (millis() - startmS) < waitmS); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return '*';
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitAck(uint32_t waitmS, uint8_t length)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_WaitAck() "));
|
||||
Serial.print(F(" Reply length "));
|
||||
Serial.print(length);
|
||||
Serial.print(F(" "));
|
||||
#endif
|
||||
|
||||
uint8_t GPSchar;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
uint8_t ptr = 0; //used as pointer to store GPS reply
|
||||
bool found;
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Received "));
|
||||
Serial.flush();
|
||||
|
||||
found = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!GPS_WaitChar('$', waitmS))
|
||||
{
|
||||
Serial.print(F("Timeout Error"));
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(F("$"));
|
||||
|
||||
GPSchar = GPS_GetNextChar(waitmS);
|
||||
Serial.write(GPSchar);
|
||||
|
||||
if (GPSchar == 'P')
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
while ((uint32_t) (millis() - startmS) < waitmS);
|
||||
|
||||
if (found)
|
||||
{
|
||||
ptr = 2;
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
GPS_Reply[ptr++] = GPSchar;
|
||||
}
|
||||
}
|
||||
while (((uint32_t) (millis() - startmS) < waitmS) && (ptr < length)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
}
|
||||
|
||||
GPS_OutputOff();
|
||||
|
||||
|
||||
for (ptr = 2; ptr < length; ptr++)
|
||||
{
|
||||
GPSchar = GPS_Reply[ptr];
|
||||
Serial.write(GPSchar);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (GPS_CheckAck())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckBalloonMode()
|
||||
{
|
||||
//Reply to set balloon mode ought to be $PMTK886,3*2B, the 3 is for balloon mode
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckBalloonMode() "));
|
||||
#endif
|
||||
|
||||
if (GPS_SetBalloonMode())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_PollNavigation()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PollNavigation() "));
|
||||
#endif
|
||||
//empty function for compatibility reasons with other GPS libraries
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SaveConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SaveConfig() "));
|
||||
#endif
|
||||
//empty function for compatibility reasons with other GPS libraries
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckAck()
|
||||
{
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckAck() "));
|
||||
#endif
|
||||
|
||||
uint8_t response[] = {"$PMTK001,xxx,?"};
|
||||
uint8_t index;
|
||||
|
||||
for (index = 2; index <= 7; index++) //check up to the eighth ([7]) character, which is the ','
|
||||
{
|
||||
if ( GPS_Reply[index] != response[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((index == 8) && (GPS_Reply[13] == '3') ) //if we got to index 8 there was a match for $PMTK001, so check reply type
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Serial.print(index);
|
||||
Serial.print(F(" "));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
// GPS configuration commands
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
bool GPS_SetBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetBalloonMode() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SetBalloonMode "));
|
||||
size_t SIZE = sizeof(SetBalloonMode);
|
||||
|
||||
if (GPS_SendConfig(SetBalloonMode, SIZE, 17, GPS_attempts))
|
||||
{
|
||||
Serial.println(F("OK"));
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GGARMCOnly()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GGARMCOnly() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("Set GGA and RMC only "));
|
||||
size_t SIZE = sizeof(GGARMCOnly);
|
||||
|
||||
if (GPS_SendConfig(GGARMCOnly, SIZE, 17, GPS_attempts))
|
||||
{
|
||||
Serial.println(F("OK"));
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_ClearConfig()
|
||||
{
|
||||
Serial.println(F("ClearConfig()"));
|
||||
size_t SIZE = sizeof(ClearConfig);
|
||||
GPS_SendConfig(ClearConfig, SIZE, 0, GPS_attempts); //full cold start, no response is given, so replylength = 0
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("No Response given for full cold start"));
|
||||
#endif
|
||||
|
||||
Serial.println();
|
||||
Serial.println(F("Wait clear"));
|
||||
delay(GPS_Clear_DelaymS);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetCyclicMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetCyclicMode() "));
|
||||
#endif
|
||||
//no clyclic mode config for Quectel
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SoftwareBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SoftwareBackup() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SoftwareBackup);
|
||||
Serial.println(F("SoftwareBackup"));
|
||||
|
||||
if (GPS_SendConfig(SoftwareBackup, SIZE, 0, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_HotStart()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_HotStart() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(HotStart);
|
||||
Serial.println(F("HotStart"));
|
||||
|
||||
if (GPS_SendConfig(HotStart, SIZE, 0, GPS_attempts)) //reply is $PMTK010,002*2D, so not receognised by check ack
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLLOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLLOff() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLSOff() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSAOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSAOff() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSVOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSVOff() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GPS_GLONASSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GLONASSOff() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GNSSmode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GNSSmode() "));
|
||||
#endif
|
||||
|
||||
//setup to be added later
|
||||
//function included for compatibility with other GPS library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetByte() //get a byte for GPS
|
||||
{
|
||||
if (GPSserial.available() == 0)
|
||||
{
|
||||
return 0xFF; //for compatibility with I2C reading of GPS
|
||||
}
|
||||
else
|
||||
{
|
||||
return GPSserial.read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
474
lib/SX12XX-LoRa/src/Quectel_HWSerialGPS.h
Normal file
474
lib/SX12XX-LoRa/src/Quectel_HWSerialGPS.h
Normal file
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 12/05/20
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - This is a library file for the Quectel L70,L76,L80 and L86 GPSs
|
||||
|
||||
The routines assume that the GPS has been setup on GPSserial which could be either software serial or
|
||||
hardware serial. The calling program should include a define for the GPS baud rate as follows
|
||||
|
||||
#define GPSBaud 9600
|
||||
|
||||
If this define is missing then 9600 baud is assumed
|
||||
*******************************************************************************************************/
|
||||
|
||||
const PROGMEM uint8_t SetBalloonMode[] = {"$PMTK886,3*2B"}; //response should be $PMTK001,886,3*36
|
||||
const PROGMEM uint8_t ClearConfig[] = {"$PMTK104*37"}; //no response
|
||||
const PROGMEM uint8_t PMTK_ACK[] = {"$PMTK001,xxx,?"}; //? = 0 = invalid, 1 = unsupported, 2 = valid failed, 3 = valids succeeded
|
||||
const PROGMEM uint8_t SoftwareBackup[] = {"$PMTK161,0*28"}; //response should be $PMTK001,161,3*36
|
||||
const PROGMEM uint8_t HotStart[] = {"$PMTK101*32"};
|
||||
|
||||
uint8_t GPS_GetByte();
|
||||
void GPS_OutputOn();
|
||||
void GPS_OutputOff();
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state);
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state);
|
||||
bool GPS_Setup();
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts);
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS);
|
||||
uint8_t GPS_GetNextChar(uint32_t waitmS);
|
||||
bool GPS_WaitAck(uint32_t waitms, uint8_t length);
|
||||
bool GPS_CheckConfiguration();
|
||||
bool GPS_CheckAck();
|
||||
bool GPS_SetBalloonMode();
|
||||
bool GPS_ClearConfig();
|
||||
bool GPS_SetCyclicMode();
|
||||
bool GPS_SoftwareBackup();
|
||||
bool GPS_HotStart();
|
||||
|
||||
|
||||
const uint32_t GPS_WaitAck_mS = 2000; //number of mS to wait for an ACK response from GPS
|
||||
const uint8_t GPS_attempts = 5; //number of times the sending of GPS config will be attempted.
|
||||
const uint8_t GPS_Reply_Size = 20; //size of GPS reply buffer
|
||||
const uint16_t GPS_Clear_DelaymS = 2000; //mS to wait after a GPS Clear command is sent
|
||||
|
||||
uint8_t GPS_Reply[GPS_Reply_Size]; //byte array for storing GPS reply to UBX commands
|
||||
|
||||
#define QUECTELINUSE //so complier can know which GPS library is used //so complier can know which GPS library is used
|
||||
//#define GPSDebug
|
||||
|
||||
#ifndef GPSConfigSerial // if GPSDebugSerial is not defined set to Serial as default
|
||||
#define GPSConfigSerial Serial
|
||||
#endif
|
||||
|
||||
#ifndef GPSDebugSerial // if GPSDebugSerial is not defined set to Serial as default
|
||||
#define GPSDebugSerial Serial
|
||||
#endif
|
||||
|
||||
#ifndef GPSBaud
|
||||
#define GPSBaud 9600
|
||||
#endif
|
||||
|
||||
void GPS_OutputOn()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_OutputOn() "));
|
||||
#endif
|
||||
//turns on serial output from GPS
|
||||
GPSserial.begin(GPSBaud);
|
||||
}
|
||||
|
||||
|
||||
void GPS_OutputOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_OutputOff() "));
|
||||
#endif
|
||||
//turns off serial output from GPS
|
||||
GPSserial.end();
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOn() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOff() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_Setup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Setup() "));
|
||||
#endif
|
||||
|
||||
if (!GPS_SetBalloonMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SendConfig() "));
|
||||
#endif
|
||||
|
||||
uint8_t byteread, index;
|
||||
uint8_t config_attempts = attempts;
|
||||
|
||||
memset(GPS_Reply, 0, sizeof(GPS_Reply)); //clear the reply buffer
|
||||
|
||||
Serial.flush(); //ensure there are no pending interrupts from serial monitor printing
|
||||
|
||||
do
|
||||
{
|
||||
if (config_attempts == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.print(F("GPSSend "));
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
Serial.write(byteread);
|
||||
}
|
||||
|
||||
Serial.flush(); //make sure serial out buffer is empty
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
GPSserial.write(byteread);
|
||||
}
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start, in case config command retried
|
||||
|
||||
|
||||
GPSserial.write(13);
|
||||
GPSserial.write(10);
|
||||
|
||||
if (replylength == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
config_attempts--;
|
||||
}
|
||||
while (!GPS_WaitAck(GPS_WaitAck_mS, replylength));
|
||||
|
||||
delay(100); //GPS can sometimes be a bit slow getting ready for next config
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
if (GPSchar == waitforchar)
|
||||
{
|
||||
GPS_Reply[0] = GPSchar;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((millis() < waitmS)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetNextChar(uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
GPS_Reply[1] = GPSchar;
|
||||
return GPSchar;
|
||||
}
|
||||
}
|
||||
while ((millis() < waitmS)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return '*';
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitAck(uint32_t waitmS, uint8_t length)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_WaitAck() "));
|
||||
Serial.print(F(" Reply length "));
|
||||
Serial.print(length);
|
||||
Serial.print(F(" "));
|
||||
#endif
|
||||
|
||||
uint8_t GPSchar;
|
||||
|
||||
uint32_t endmS;
|
||||
endmS = millis() + waitmS;
|
||||
uint8_t ptr = 0; //used as pointer to store GPS reply
|
||||
bool found;
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Received "));
|
||||
Serial.flush();
|
||||
|
||||
endmS = millis() + GPS_WaitAck_mS;
|
||||
|
||||
found = false;
|
||||
|
||||
do
|
||||
{
|
||||
if (!GPS_WaitChar('$', endmS))
|
||||
{
|
||||
Serial.print(F("Timeout Error"));
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Serial.print(F("$"));
|
||||
|
||||
GPSchar = GPS_GetNextChar(endmS);
|
||||
Serial.write(GPSchar);
|
||||
|
||||
if (GPSchar == 'P')
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
while (millis() <= endmS);
|
||||
|
||||
if (found)
|
||||
{
|
||||
ptr = 2;
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
GPS_Reply[ptr++] = GPSchar;
|
||||
}
|
||||
}
|
||||
while ((millis() < endmS) && (ptr < length)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
}
|
||||
|
||||
|
||||
for (ptr = 2; ptr < length; ptr++)
|
||||
{
|
||||
GPSchar = GPS_Reply[ptr];
|
||||
Serial.write(GPSchar);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (GPS_CheckAck())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckConfiguration()
|
||||
{
|
||||
//Reply to set balloon mode ought to be $PMTK886,3*2B, the 3 is for balloon mode
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckConfiguration() "));
|
||||
#endif
|
||||
|
||||
if (GPS_SetBalloonMode())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_CheckAck()
|
||||
{
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckAck() "));
|
||||
#endif
|
||||
|
||||
uint8_t response[] = {"$PMTK001,xxx,?"};
|
||||
uint8_t index;
|
||||
|
||||
for (index = 2; index <= 7; index++) //check up to the eighth ([7]) character, which is the ','
|
||||
{
|
||||
if ( GPS_Reply[index] != response[index])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((index == 8) && (GPS_Reply[13] == '3') ) //if we got to index 8 there was a match for $PMTK001, so check reply type
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Serial.print(index);
|
||||
Serial.print(F(" "));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
// GPS configuration commands
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
bool GPS_SetBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetBalloonMode() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SetBalloonMode "));
|
||||
size_t SIZE = sizeof(SetBalloonMode);
|
||||
|
||||
if (GPS_SendConfig(SetBalloonMode, SIZE, 17, GPS_attempts))
|
||||
{
|
||||
Serial.println(F("OK"));
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_ClearConfig()
|
||||
{
|
||||
Serial.println(F("ClearConfig()"));
|
||||
size_t SIZE = sizeof(ClearConfig);
|
||||
GPS_SendConfig(ClearConfig, SIZE, 0, GPS_attempts); //full cold start, no response is given, so replylength = 0
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("No Response given for full cold start"));
|
||||
#endif
|
||||
|
||||
Serial.println();
|
||||
Serial.println(F("Wait clear"));
|
||||
delay(GPS_Clear_DelaymS);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetCyclicMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetCyclicMode() "));
|
||||
#endif
|
||||
//no clyclic mode config for Quectel
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SoftwareBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SoftwareBackup() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SoftwareBackup);
|
||||
|
||||
if (GPS_SendConfig(SoftwareBackup, SIZE, 0, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_HotStart()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_HotStart() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(HotStart);
|
||||
Serial.println(F("HotStart"));
|
||||
|
||||
if (GPS_SendConfig(HotStart, SIZE, 0, GPS_attempts)) //reply is $PMTK010,002*2D, so not receognised by check ack
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetByte() //get a byte for GPS
|
||||
{
|
||||
if (GPSserial.available() == 0)
|
||||
{
|
||||
return 0xFF; //for compatibility with I2C reading of GPS
|
||||
}
|
||||
else
|
||||
{
|
||||
return GPSserial.read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
3494
lib/SX12XX-LoRa/src/SX126XLT.cpp
Normal file
3494
lib/SX12XX-LoRa/src/SX126XLT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
229
lib/SX12XX-LoRa/src/SX126XLT.h
Normal file
229
lib/SX12XX-LoRa/src/SX126XLT.h
Normal file
@@ -0,0 +1,229 @@
|
||||
|
||||
#ifndef SX126XLT_h
|
||||
#define SX126XLT_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <SX126XLT_Definitions.h>
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
ToDO
|
||||
|
||||
DONE - Check setDIOIRQ is before all setTX SetRX calls
|
||||
DONE - Check for checkbusy, before all uses of SPI
|
||||
DONE - Match printlorasettings and printdevice settings with sx127x library
|
||||
DONE - Check if SX126X has AGCauto_
|
||||
DONE - Check correct setting of optimisation
|
||||
DONE - Check in addressed send txpacketL = 3 + size; //we have added 3 header bytes to size
|
||||
DONE - Investigate use of clearDeviceErrors() - Not used in Semtech sample code
|
||||
ABANDONED - Investigate if setPacketParams(savedPacketParam1, savedPacketParam2 in send routine can be avoided - TXpacketL
|
||||
DONE - Test rxEnable and txenable functionality
|
||||
DONE - Check TX power settings at 17dBm +
|
||||
|
||||
Description of how to include RxGain register in the retention memory, see Section 9.6 - manual p58
|
||||
|
||||
Add a library function for SetRxDutyCycle ?
|
||||
Add a library function to allow changing of ramptime from RADIO_RAMP_200_US ?
|
||||
Check use of RADIO_RAMP_DEFAULT
|
||||
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
class SX126XLT {
|
||||
public:
|
||||
|
||||
SX126XLT();
|
||||
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinDIO2, int8_t pinDIO3, int8_t pinRXEN, int8_t pinTXEN, int8_t pinSW, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinSW, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinRXEN, int8_t pinTXEN, uint8_t device);
|
||||
|
||||
void checkBusy();
|
||||
void writeCommand(uint8_t Opcode, uint8_t *buffer, uint16_t size );
|
||||
void readCommand( uint8_t Opcode, uint8_t *buffer, uint16_t size );
|
||||
void writeRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
|
||||
void writeRegister( uint16_t address, uint8_t value );
|
||||
void readRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
|
||||
uint8_t readRegister( uint16_t address );
|
||||
void resetDevice();
|
||||
bool checkDevice();
|
||||
void setupLoRa(uint32_t frequency, int32_t offset, uint8_t modParam1, uint8_t modParam2, uint8_t modParam3, uint8_t modParam4);
|
||||
void setMode(uint8_t modeconfig);
|
||||
void setRegulatorMode(uint8_t mode);
|
||||
|
||||
void setPaConfig(uint8_t dutycycle, uint8_t hpMax, uint8_t device);
|
||||
void setDIO3AsTCXOCtrl(uint8_t tcxoVoltage);
|
||||
void calibrateDevice(uint8_t devices);
|
||||
void calibrateImage(uint32_t freq);
|
||||
void setDIO2AsRfSwitchCtrl();
|
||||
void setPacketType(uint8_t PacketType);
|
||||
void setRfFrequency( uint32_t frequency, int32_t offset );
|
||||
void setModulationParams(uint8_t modParam1, uint8_t modParam2, uint8_t modParam3, uint8_t modParam4);
|
||||
uint8_t returnOptimisation(uint8_t SpreadingFactor, uint8_t Bandwidth);
|
||||
uint32_t returnBandwidth(uint8_t BWregvalue);
|
||||
float calcSymbolTime(float Bandwidth, uint8_t SpreadingFactor);
|
||||
void setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress);
|
||||
void setPacketParams(uint16_t packetParam1, uint8_t packetParam2, uint8_t packetParam3, uint8_t packetParam4, uint8_t packetParam5);
|
||||
void setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask );
|
||||
void setHighSensitivity();
|
||||
void setLowPowerRX();
|
||||
void setSyncWord(uint16_t syncword);
|
||||
void printModemSettings();
|
||||
void printDevice();
|
||||
uint32_t getFreqInt(); //this reads the SX126x registers to get the current frequency
|
||||
uint8_t getLoRaSF();
|
||||
|
||||
uint8_t getLoRaCodingRate();
|
||||
uint8_t getOptimisation();
|
||||
|
||||
uint16_t getSyncWord();
|
||||
uint8_t getInvertIQ();
|
||||
uint16_t getPreamble();
|
||||
void printOperatingSettings();
|
||||
uint8_t getHeaderMode();
|
||||
uint8_t getLNAgain();
|
||||
void printRegisters(uint16_t Start, uint16_t End);
|
||||
void printASCIIPacket(uint8_t *buff, uint8_t tsize);
|
||||
uint8_t transmit(uint8_t *txbuffer, uint8_t size, uint32_t txtimeout, int8_t txpower, uint8_t wait);
|
||||
void setTxParams(int8_t TXpower, uint8_t RampTime);
|
||||
void setTx(uint32_t timeout);
|
||||
void clearIrqStatus( uint16_t irq );
|
||||
uint16_t readIrqStatus();
|
||||
uint16_t CRCCCITT(uint8_t *buffer, uint8_t size, uint16_t start);
|
||||
uint8_t receive(uint8_t *rxbuffer, uint8_t size, uint32_t rxtimeout, uint8_t wait);
|
||||
uint8_t readPacketRSSI();
|
||||
uint8_t readPacketSNR();
|
||||
uint8_t readRXPacketL();
|
||||
void setRx(uint32_t timeout);
|
||||
|
||||
void printIrqStatus();
|
||||
void rxEnable();
|
||||
void txEnable();
|
||||
bool config();
|
||||
|
||||
/***************************************************************************
|
||||
//Start direct access SX buffer routines
|
||||
***************************************************************************/
|
||||
|
||||
void startWriteSXBuffer(uint8_t ptr);
|
||||
uint8_t endWriteSXBuffer();
|
||||
void startReadSXBuffer(uint8_t ptr);
|
||||
uint8_t endReadSXBuffer();
|
||||
|
||||
void writeUint8(uint8_t x);
|
||||
uint8_t readUint8();
|
||||
|
||||
void writeInt8(int8_t x);
|
||||
int8_t readInt8();
|
||||
|
||||
void writeInt16(int16_t x);
|
||||
int16_t readInt16();
|
||||
|
||||
void writeUint16(uint16_t x);
|
||||
uint16_t readUint16();
|
||||
|
||||
void writeInt32(int32_t x);
|
||||
int32_t readInt32();
|
||||
|
||||
void writeUint32(uint32_t x);
|
||||
uint32_t readUint32();
|
||||
|
||||
void writeFloat(float x);
|
||||
float readFloat();
|
||||
|
||||
uint8_t transmitSXBuffer(uint8_t startaddr, uint8_t length, uint32_t txtimeout, int8_t txpower, uint8_t wait);
|
||||
void writeBuffer(uint8_t *txbuffer, uint8_t size);
|
||||
uint8_t receiveSXBuffer(uint8_t startaddr, uint32_t rxtimeout, uint8_t wait);
|
||||
uint8_t readBuffer(uint8_t *rxbuffer);
|
||||
void setupDirect(uint32_t frequency, int32_t offset);
|
||||
void toneFM(uint16_t frequency, uint32_t length, uint32_t deviation, float adjust, uint8_t txpower);
|
||||
void setTXDirect();
|
||||
uint8_t getByteSXBuffer(uint8_t addr);
|
||||
void printSXBufferHEX(uint8_t start, uint8_t end);
|
||||
int32_t getFrequencyErrorHz();
|
||||
int32_t getFrequencyErrorRegValue();
|
||||
void printHEXByte(uint8_t temp);
|
||||
uint8_t transmitAddressed(uint8_t *txbuffer, uint8_t size, char txpackettype, char txdestination, char txsource, uint32_t txtimeout, int8_t txpower, uint8_t wait);
|
||||
uint8_t readRXPacketType();
|
||||
uint8_t readRXDestination();
|
||||
uint8_t readRXSource();
|
||||
uint8_t receiveAddressed(uint8_t *rxbuffer, uint8_t size, uint32_t rxtimeout, uint8_t wait);
|
||||
void clearDeviceErrors();
|
||||
void printDeviceErrors();
|
||||
void printHEXPacket(uint8_t *buffer, uint8_t size);
|
||||
void printHEXByte0x(uint8_t temp);
|
||||
uint8_t readsavedModParam1(); //spreading factor
|
||||
uint8_t readsavedModParam2(); //bandwidth
|
||||
uint8_t readsavedModParam3(); //code rate
|
||||
uint8_t readsavedModParam4(); //optimisation
|
||||
uint8_t readsavedPower();
|
||||
uint8_t getPacketMode();
|
||||
uint8_t readsavedPacketParam1(); //preamble
|
||||
uint8_t readsavedPacketParam2(); //header type
|
||||
uint8_t readsavedPacketParam3(); //packet length
|
||||
uint8_t readsavedPacketParam4(); //CRC
|
||||
uint8_t readsavedPacketParam5(); //IQ
|
||||
uint8_t getOpmode();
|
||||
uint8_t getCRCMode();
|
||||
void fillSXBuffer(uint8_t startaddress, uint8_t size, uint8_t character);
|
||||
uint8_t readPacket(uint8_t *rxbuffer, uint8_t size);
|
||||
void writeByteSXBuffer(uint8_t addr, uint8_t regdata);
|
||||
void printSXBufferASCII(uint8_t start, uint8_t end);
|
||||
void startFSKRTTY(uint32_t freqshift, uint8_t pips, uint16_t pipPeriodmS, uint16_t pipDelaymS, uint16_t leadinmS);
|
||||
void transmitFSKRTTY(uint8_t chartosend, uint8_t databits, uint8_t stopbits, uint8_t parity, uint16_t baudPerioduS, int8_t pin);
|
||||
void transmitFSKRTTY(uint8_t chartosend, uint16_t baudPerioduS, int8_t pin);
|
||||
void printRTTYregisters();
|
||||
void endFSKRTTY();
|
||||
void getRfFrequencyRegisters(uint8_t *buff);
|
||||
void setRfFrequencyDirect(uint8_t high, uint8_t midhigh, uint8_t midlow, uint8_t low);
|
||||
|
||||
/***************************************************************************
|
||||
//End direct access SX buffer routines
|
||||
***************************************************************************/
|
||||
|
||||
uint16_t CRCCCITTSX(uint8_t startadd, uint8_t endadd, uint16_t startvalue);
|
||||
void setSleep(uint8_t sleepconfig);
|
||||
void wake();
|
||||
|
||||
private:
|
||||
|
||||
int8_t _NSS, _NRESET, _RFBUSY, _DIO1, _DIO2, _DIO3, _SW;
|
||||
int8_t _RXEN, _TXEN;
|
||||
uint8_t _RXPacketL; //length of packet received
|
||||
uint8_t _RXPacketType; //type number of received packet
|
||||
uint8_t _RXDestination; //destination address of received packet
|
||||
uint8_t _RXSource; //source address of received packet
|
||||
int8_t _PacketRSSI; //RSSI of received packet
|
||||
int8_t _PacketSNR; //signal to noise ratio of received packet
|
||||
int8_t _TXPacketL;
|
||||
uint8_t _RXcount; //used to keep track of the bytes read from SX126X buffer during readFloat() etc
|
||||
uint8_t _TXcount; //used to keep track of the bytes written to SX126X buffer during writeFloat() etc
|
||||
uint8_t _RXBufferPointer; //pointer to first byte of packet in buffer
|
||||
uint8_t _OperatingMode; //current operating mode
|
||||
bool _rxtxpinmode = false; //set to true if RX and TX enable pin mode is used.
|
||||
uint8_t _Device; //saved device type
|
||||
uint8_t _TXDonePin; //the pin that will indicate TX done
|
||||
uint8_t _RXDonePin; //the pin that will indicate RX done
|
||||
|
||||
uint32_t savedFrequency;
|
||||
int32_t savedOffset;
|
||||
uint8_t savedPacketType;
|
||||
uint8_t savedRegulatorMode;
|
||||
|
||||
uint8_t savedModParam1, savedModParam2, savedModParam3, savedModParam4;
|
||||
uint16_t savedPacketParam1;
|
||||
uint8_t savedPacketParam2, savedPacketParam3, savedPacketParam4, savedPacketParam5;
|
||||
uint16_t savedIrqMask, savedDio1Mask, savedDio2Mask, savedDio3Mask;
|
||||
int8_t savedTXPower;
|
||||
|
||||
uint32_t savedFrequencyReg;
|
||||
uint8_t _freqregH, _freqregMH, _freqregML,_freqregL; //the registers values for the set frequency
|
||||
uint8_t _ShiftfreqregH, _ShiftfreqregMH, _ShiftfreqregML, _ShiftfreqregL; //register values for shifted frequency, used in FSK
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
305
lib/SX12XX-LoRa/src/SX126XLT_Definitions.h
Normal file
305
lib/SX12XX-LoRa/src/SX126XLT_Definitions.h
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
Copyright 2019 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
17/12/19
|
||||
*/
|
||||
|
||||
|
||||
#define XTAL_FREQ 32000000
|
||||
#define FREQ_DIV 33554432
|
||||
#define FREQ_STEP 0.95367431640625
|
||||
#define FREQ_ERR 0.47683715820312
|
||||
#define FREQ_ERROR_CORRECTION 1.55 //this was measured on SX1280 for bandwidth of 400khz
|
||||
|
||||
#define AUTO_RX_TX_OFFSET 2
|
||||
|
||||
#define CRC_IBM_SEED 0xFFFF
|
||||
#define CRC_CCITT_SEED 0x1D0F
|
||||
#define CRC_POLYNOMIAL_IBM 0x8005
|
||||
#define CRC_POLYNOMIAL_CCITT 0x1021
|
||||
|
||||
//Registers - Used, tested
|
||||
#define REG_LR_PAYLOADLENGTH 0x0702
|
||||
#define REG_IQ_POLARITY_SETUP 0x0736
|
||||
#define REG_LR_SYNCWORD 0x0740
|
||||
#define REG_RX_GAIN 0x08AC
|
||||
#define REG_TX_MODULATION 0x0889
|
||||
#define REG_RFFrequency31_24 0x088B
|
||||
#define REG_RFFrequency23_16 0x088C
|
||||
#define REG_RFFrequency15_8 0x088D
|
||||
#define REG_RFFrequency7_0 0x088E
|
||||
|
||||
//Registers - Not used, not tested
|
||||
#define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8
|
||||
#define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9
|
||||
#define REG_LR_CRCSEEDBASEADDR 0x06BC
|
||||
#define REG_LR_CRCPOLYBASEADDR 0x06BE
|
||||
#define REG_LR_PACKETPARAMS 0x0704
|
||||
#define REG_LR_SYNCWORDBASEADDRESS 0x06C0
|
||||
|
||||
#define REG_FREQUENCY_ERRORBASEADDR 0x076B
|
||||
#define RANDOM_NUMBER_GENERATORBASEADDR 0x0819
|
||||
#define REG_OCP 0x08E7
|
||||
#define REG_XTA_TRIM 0x0911
|
||||
|
||||
|
||||
#define LORA_MAC_PRIVATE_SYNCWORD 0x1424
|
||||
#define LORA_MAC_PUBLIC_SYNCWORD 0x3444
|
||||
|
||||
#define PRINT_LOW_REGISTER 0x680
|
||||
#define PRINT_HIGH_REGISTER 0x920
|
||||
|
||||
|
||||
#define POWER_SAVE_GAIN 0x94
|
||||
#define BOOSTED_GAIN 0x96
|
||||
|
||||
|
||||
//radio operatine modes
|
||||
#define MODE_SLEEP 0x07
|
||||
#define MODE_STDBY_RC 0x00 //Device running on RC13M, set STDBY_RC mode
|
||||
#define MODE_STDBY_XOSC 0x01 //Device running on XTAL 32MHz, set STDBY_XOSC mode
|
||||
#define MODE_FS 0x02 // The radio is in frequency synthesis mode
|
||||
#define MODE_TX 0x03 //TX mode
|
||||
#define MODE_RX 0x04 //RX mode
|
||||
#define MODE_RX_DC 0x05 //RX duty cycle mode
|
||||
#define MODE_CAD 0x06 //RX CAD mode
|
||||
|
||||
|
||||
//Sleep Mode Definition
|
||||
#define COLD_START 0x00
|
||||
#define WARM_START 0x04
|
||||
#define RTC_TIMEOUT_DISABLE 0x00
|
||||
#define RTC_TIMEOUT_ENABLE 0x01
|
||||
|
||||
#define USE_LDO 0x00 //default
|
||||
#define USE_DCDC 0x01
|
||||
|
||||
#define PACKET_TYPE_GFSK 0x00
|
||||
#define PACKET_TYPE_LORA 0x01
|
||||
#define PACKET_TYPE_NONE 0x0F
|
||||
|
||||
|
||||
#define RADIO_RAMP_10_US 0x00
|
||||
#define RADIO_RAMP_20_US 0x01
|
||||
#define RADIO_RAMP_40_US 0x02
|
||||
#define RADIO_RAMP_80_US 0x03
|
||||
#define RADIO_RAMP_200_US 0x04
|
||||
#define RADIO_RAMP_800_US 0x05
|
||||
#define RADIO_RAMP_1700_US 0x06
|
||||
#define RADIO_RAMP_3400_US 0x07
|
||||
|
||||
#define LORA_CAD_01_SYMBOL 0x00
|
||||
#define LORA_CAD_02_SYMBOL 0x01
|
||||
#define LORA_CAD_04_SYMBOL 0x02
|
||||
#define LORA_CAD_08_SYMBOL 0x03
|
||||
#define LORA_CAD_16_SYMBOL 0x04
|
||||
|
||||
#define LORA_CAD_ONLY 0x00
|
||||
#define LORA_CAD_RX 0x01
|
||||
#define LORA_CAD_LBT 0x10
|
||||
|
||||
#define LORA_SF5 0x05
|
||||
#define LORA_SF6 0x06
|
||||
#define LORA_SF7 0x07
|
||||
#define LORA_SF8 0x08
|
||||
#define LORA_SF9 0x09
|
||||
#define LORA_SF10 0x0A
|
||||
#define LORA_SF11 0x0B
|
||||
#define LORA_SF12 0x0C
|
||||
|
||||
#define LORA_BW_500 6 //actual 500000hz
|
||||
#define LORA_BW_250 5 //actual 250000hz
|
||||
#define LORA_BW_125 4 //actual 125000hz
|
||||
#define LORA_BW_062 3 //actual 62500hz
|
||||
#define LORA_BW_041 10 //actual 41670hz
|
||||
#define LORA_BW_031 2 //actual 31250hz
|
||||
#define LORA_BW_020 9 //actual 20830hz
|
||||
#define LORA_BW_015 1 //actual 15630hz
|
||||
#define LORA_BW_010 8 //actual 10420hz
|
||||
#define LORA_BW_007 0 //actual 7810hz
|
||||
|
||||
#define LORA_CR_4_5 0x01
|
||||
#define LORA_CR_4_6 0x02
|
||||
#define LORA_CR_4_7 0x03
|
||||
#define LORA_CR_4_8 0x04
|
||||
|
||||
#define WAIT_RX 0x01
|
||||
#define WAIT_TX 0x01
|
||||
#define NO_WAIT 0x00
|
||||
|
||||
#define RADIO_PREAMBLE_DETECTOR_OFF 0x00 //!< Preamble detection length off
|
||||
#define RADIO_PREAMBLE_DETECTOR_08_BITS 0x04 //!< Preamble detection length 8 bits
|
||||
#define RADIO_PREAMBLE_DETECTOR_16_BITS 0x05 //!< Preamble detection length 16 bits
|
||||
#define RADIO_PREAMBLE_DETECTOR_24_BITS 0x06 //!< Preamble detection length 24 bits
|
||||
#define RADIO_PREAMBLE_DETECTOR_32_BITS 0x07 //!< Preamble detection length 32 bit
|
||||
|
||||
#define RADIO_ADDRESSCOMP_FILT_OFF 0x00 //!< No correlator turned on i.e. do not search for SyncWord
|
||||
#define RADIO_ADDRESSCOMP_FILT_NODE 0x01
|
||||
#define RADIO_ADDRESSCOMP_FILT_NODE_BROAD 0x02
|
||||
|
||||
#define RADIO_PACKET_FIXED_LENGTH 0x00 //!< The packet is known on both sides no header included in the packet
|
||||
#define RADIO_PACKET_VARIABLE_LENGTH 0x01 //!< The packet is on variable size header included
|
||||
|
||||
#define RADIO_CRC_OFF 0x01 //!< No CRC in use
|
||||
#define RADIO_CRC_1_BYTES 0x00
|
||||
#define RADIO_CRC_2_BYTES 0x02
|
||||
#define RADIO_CRC_1_BYTES_INV 0x04
|
||||
#define RADIO_CRC_2_BYTES_INV 0x06
|
||||
#define RADIO_CRC_2_BYTES_IBM 0xF1
|
||||
#define RADIO_CRC_2_BYTES_CCIT 0xF2
|
||||
|
||||
#define RADIO_DC_FREE_OFF 0x00
|
||||
#define RADIO_DC_FREEWHITENING 0x01
|
||||
|
||||
#define LORA_PACKET_VARIABLE_LENGTH 0x00 //!< The packet is on variable size header included
|
||||
#define LORA_PACKET_FIXED_LENGTH 0x01 //!< The packet is known on both sides no header included in the packet
|
||||
#define LORA_PACKET_EXPLICIT LORA_PACKET_VARIABLE_LENGTH
|
||||
#define LORA_PACKET_IMPLICIT LORA_PACKET_FIXED_LENGTH
|
||||
|
||||
|
||||
#define LORA_CRC_ON 0x01 //!< CRC activated
|
||||
#define LORA_CRC_OFF 0x00 //!< CRC not used
|
||||
|
||||
#define LORA_IQ_NORMAL 0x00
|
||||
#define LORA_IQ_INVERTED 0x01
|
||||
|
||||
#define TCXO_CTRL_1_6V 0x00
|
||||
#define TCXO_CTRL_1_7V 0x01
|
||||
#define TCXO_CTRL_1_8V 0x02
|
||||
#define TCXO_CTRL_2_2V 0x03
|
||||
#define TCXO_CTRL_2_4V 0x04
|
||||
#define TCXO_CTRL_2_7V 0x05
|
||||
#define TCXO_CTRL_3_0V 0x06
|
||||
#define TCXO_CTRL_3_3V 0x07
|
||||
|
||||
#define IRQ_RADIO_NONE 0x0000
|
||||
#define IRQ_TX_DONE 0x0001
|
||||
#define IRQ_RX_DONE 0x0002
|
||||
#define IRQ_PREAMBLE_DETECTED 0x0004
|
||||
#define IRQ_SYNCWORD_VALID 0x0008
|
||||
#define IRQ_HEADER_VALID 0x0010
|
||||
#define IRQ_HEADER_ERROR 0x0020
|
||||
#define IRQ_CRC_ERROR 0x0040
|
||||
#define IRQ_CAD_DONE 0x0080
|
||||
#define IRQ_CAD_ACTIVITY_DETECTED 0x0100
|
||||
#define IRQ_RX_TX_TIMEOUT 0x0200
|
||||
#define IRQ_TX_TIMEOUT 0x0200
|
||||
#define IRQ_RX_TIMEOUT 0x0200
|
||||
#define IRQ_RADIO_ALL 0xFFFF
|
||||
|
||||
#define RADIO_GET_STATUS 0xC0
|
||||
#define RADIO_WRITE_REGISTER 0x0D
|
||||
#define RADIO_READ_REGISTER 0x1D
|
||||
#define RADIO_WRITE_BUFFER 0x0E
|
||||
#define RADIO_READ_BUFFER 0x1E
|
||||
#define RADIO_SET_SLEEP 0x84
|
||||
#define RADIO_SET_STANDBY 0x80
|
||||
#define RADIO_SET_FS 0xC1
|
||||
#define RADIO_SET_TX 0x83
|
||||
#define RADIO_SET_RX 0x82
|
||||
#define RADIO_SET_RXDUTYCYCLE 0x94
|
||||
#define RADIO_SET_CAD 0xC5
|
||||
#define RADIO_SET_TXCONTINUOUSWAVE 0xD1
|
||||
#define RADIO_SET_TXCONTINUOUSPREAMBLE 0xD2
|
||||
#define RADIO_SET_PACKETTYPE 0x8A
|
||||
#define RADIO_GET_PACKETTYPE 0x11
|
||||
#define RADIO_SET_RFFREQUENCY 0x86
|
||||
#define RADIO_SET_TXPARAMS 0x8E
|
||||
#define RADIO_SET_PACONFIG 0x95
|
||||
#define RADIO_SET_CADPARAMS 0x88
|
||||
#define RADIO_SET_BUFFERBASEADDRESS 0x8F
|
||||
#define RADIO_SET_MODULATIONPARAMS 0x8B
|
||||
#define RADIO_SET_PACKETPARAMS 0x8C
|
||||
#define RADIO_GET_RXBUFFERSTATUS 0x13
|
||||
#define RADIO_GET_PACKETSTATUS 0x14
|
||||
#define RADIO_GET_RSSIINST 0x15
|
||||
#define RADIO_GET_STATS 0x10
|
||||
#define RADIO_RESET_STATS 0x00
|
||||
#define RADIO_CFG_DIOIRQ 0x08
|
||||
#define RADIO_GET_IRQSTATUS 0x12
|
||||
#define RADIO_CLR_IRQSTATUS 0x02
|
||||
#define RADIO_CALIBRATE 0x89
|
||||
#define RADIO_CALIBRATEIMAGE 0x98
|
||||
#define RADIO_SET_REGULATORMODE 0x96
|
||||
#define RADIO_GET_ERROR 0x17
|
||||
#define RADIO_CLEAR_ERRORS 0x07
|
||||
#define RADIO_SET_TCXOMODE 0x97
|
||||
#define RADIO_SET_TXFALLBACKMODE 0x93
|
||||
#define RADIO_SET_RFSWITCHMODE 0x9D
|
||||
#define RADIO_SET_STOPRXTIMERONPREAMBLE 0x9F
|
||||
#define RADIO_SET_LORASYMBTIMEOUT 0xA0
|
||||
|
||||
|
||||
//Table 13-2 SX126X Sleep modes
|
||||
#define CONFIGURATION_RETENTION 0x04
|
||||
#define RTC_TIMEOUT_ENABLE 0x01
|
||||
|
||||
|
||||
#define LDRO_OFF 0x00
|
||||
#define LDRO_ON 0x01
|
||||
#define LDRO_AUTO 0x02 //when used causes LDRO to be automatically calculated
|
||||
|
||||
#define DEVICE_SX1261 0x01
|
||||
#define DEVICE_SX1262 0x00
|
||||
#define DEVICE_SX1268 0x02
|
||||
|
||||
#define PAAUTO 0xFF
|
||||
#define HPMAXAUTO 0xFF
|
||||
|
||||
#ifndef RAMP_TIME
|
||||
#define RAMP_TIME RADIO_RAMP_40_US
|
||||
#endif
|
||||
|
||||
#define RC64KEnable 0x01 //calibrate RC64K clock
|
||||
#define RC13MEnable 0x02 //calibrate RC13M clock
|
||||
#define PLLEnable 0x04 //calibrate PLL
|
||||
#define ADCPulseEnable 0x08 //calibrate ADC Pulse
|
||||
#define ADCBulkNEnable 0x10 //calibrate ADC bulkN
|
||||
#define ADCBulkPEnable 0x20 //calibrate ADC bulkP
|
||||
#define ImgEnable 0x40 //calibrate image
|
||||
#define ALLDevices 0x7F //calibrate all devices
|
||||
|
||||
#define RC64K_CALIB_ERR 0x0001
|
||||
#define RC13M_CALIB_ERR 0x0002
|
||||
#define PLL_CALIB_ERR 0x0004
|
||||
#define ADC_CALIB_ERR 0x0008
|
||||
#define IMG_CALIB_ERR 0x0010
|
||||
#define XOSC_START_ERR 0x0020
|
||||
#define PLL_LOCK_ERR 0x0040
|
||||
#define RFU 0x0080
|
||||
#define PA_RAMP_ERR 0x0100
|
||||
|
||||
|
||||
//SPI settings
|
||||
#define LTspeedMaximum 8000000
|
||||
#define LTdataOrder MSBFIRST
|
||||
#define LTdataMode SPI_MODE0
|
||||
|
||||
//FSKRTTY Settings
|
||||
#define ParityNone 0
|
||||
#define ParityOdd 1
|
||||
#define ParityEven 2
|
||||
#define ParityZero 0xF0
|
||||
#define ParityOne 0xF1
|
||||
|
||||
#define ToneMinuS 52 //timed constant for ATmega328P at 8Mhz with FM Tone delayus at 0, period for half loop
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
4272
lib/SX12XX-LoRa/src/SX127XLT.cpp
Normal file
4272
lib/SX12XX-LoRa/src/SX127XLT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
263
lib/SX12XX-LoRa/src/SX127XLT.h
Normal file
263
lib/SX12XX-LoRa/src/SX127XLT.h
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 17/12/19
|
||||
New version 23/12/20
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SX127XLT_h
|
||||
#define SX127XLT_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SX127XLT_Definitions.h>
|
||||
|
||||
|
||||
class SX127XLT
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
SX127XLT();
|
||||
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinDIO0, int8_t pinDIO1, int8_t pinDIO2, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinDIO0, uint8_t device);
|
||||
bool begin(int8_t pinNSS, uint8_t device);
|
||||
void resetDevice();
|
||||
void setMode(uint8_t modeconfig);
|
||||
void setSleep(uint8_t sleepconfig);
|
||||
bool checkDevice();
|
||||
void wake();
|
||||
void calibrateImage(uint8_t null);
|
||||
uint16_t CRCCCITT(uint8_t *buffer, uint16_t size, uint16_t startvalue);
|
||||
uint16_t CRCCCITTSX(uint8_t startadd, uint8_t endadd, uint16_t startvalue);
|
||||
|
||||
void setDevice(uint8_t type);
|
||||
void printDevice();
|
||||
uint8_t getOperatingMode();
|
||||
bool isReceiveDone();
|
||||
bool isTransmitDone();
|
||||
|
||||
void writeRegister( uint8_t address, uint8_t value );
|
||||
uint8_t readRegister( uint8_t address );
|
||||
void printRegisters(uint16_t start, uint16_t end);
|
||||
void printRegister(uint8_t reg);
|
||||
void printOperatingMode();
|
||||
void printOperatingSettings();
|
||||
|
||||
void setTxParams(int8_t txPower, uint8_t rampTime);
|
||||
void setPacketParams(uint16_t packetParam1, uint8_t packetParam2, uint8_t packetParam3, uint8_t packetParam4, uint8_t packetParam5);
|
||||
void setModulationParams(uint8_t modParam1, uint8_t modParam2, uint8_t modParam3, uint8_t modParam4);
|
||||
void setRfFrequency(uint64_t freq64, int32_t offset);
|
||||
uint32_t getFreqInt();
|
||||
int32_t getFrequencyErrorRegValue();
|
||||
int32_t getFrequencyErrorHz();
|
||||
|
||||
void setTx(uint32_t timeout);
|
||||
void setRx(uint32_t timeout);
|
||||
bool readTXIRQ();
|
||||
bool readRXIRQ();
|
||||
|
||||
|
||||
void setLowPowerReceive();
|
||||
void setHighSensitivity();
|
||||
void setRXGain(uint8_t config);
|
||||
|
||||
uint8_t getAGC();
|
||||
uint8_t getLNAgain();
|
||||
uint8_t getCRCMode();
|
||||
uint8_t getHeaderMode();
|
||||
uint8_t getLNAboostHF();
|
||||
uint8_t getLNAboostLF();
|
||||
uint8_t getOpmode();
|
||||
uint8_t getPacketMode();
|
||||
|
||||
uint8_t readRXPacketL();
|
||||
uint8_t readTXPacketL();
|
||||
int16_t readPacketRSSI();
|
||||
int16_t readCurrentRSSI();
|
||||
int8_t readPacketSNR();
|
||||
bool readPacketCRCError();
|
||||
bool readPacketHeaderValid();
|
||||
uint8_t packetOK();
|
||||
uint8_t readRXPacketType();
|
||||
uint8_t readRXDestination();
|
||||
uint8_t readRXSource();
|
||||
|
||||
void setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress);
|
||||
void setPacketType(uint8_t PacketType);
|
||||
|
||||
void clearIrqStatus( uint16_t irqMask );
|
||||
uint16_t readIrqStatus();
|
||||
void setDioIrqParams(uint16_t irqMask, uint16_t dio0Mask, uint16_t dio1Mask, uint16_t dio2Mask );
|
||||
void printIrqStatus();
|
||||
|
||||
|
||||
void printASCIIPacket(uint8_t *buff, uint8_t tsize);
|
||||
void printHEXPacket(uint8_t *buff, uint8_t tsize);
|
||||
void printASCIIorHEX(uint8_t temp);
|
||||
void printHEXByte(uint8_t temp);
|
||||
void printHEXByte0x(uint8_t temp);
|
||||
|
||||
bool isRXdone();
|
||||
bool isTXdone();
|
||||
bool isRXdoneIRQ();
|
||||
bool isTXdoneIRQ();
|
||||
void setTXDonePin(uint8_t pin);
|
||||
void setRXDonePin(uint8_t pin);
|
||||
|
||||
//*******************************************************************************
|
||||
//Packet Read and Write Routines
|
||||
//*******************************************************************************
|
||||
|
||||
uint8_t receive(uint8_t *rxbuffer, uint8_t size, uint32_t rxtimeout, uint8_t wait);
|
||||
uint8_t receiveAddressed(uint8_t *rxbuffer, uint8_t size, uint32_t rxtimeout, uint8_t wait);
|
||||
uint8_t readPacket(uint8_t *rxbuffer, uint8_t size);
|
||||
uint8_t readPacketAddressed(uint8_t *rxbuffer, uint8_t size);
|
||||
|
||||
uint8_t transmit(uint8_t *txbuffer, uint8_t size, uint32_t txtimeout, int8_t txPower, uint8_t wait);
|
||||
uint8_t transmitAddressed(uint8_t *txbuffer, uint8_t size, char txpackettype, char txdestination, char txsource, uint32_t txtimeout, int8_t txpower, uint8_t wait);
|
||||
|
||||
//*******************************************************************************
|
||||
//LoRa specific routines
|
||||
//*******************************************************************************
|
||||
|
||||
void setupLoRa(uint32_t Frequency, int32_t Offset, uint8_t modParam1, uint8_t modParam2, uint8_t modParam3, uint8_t modParam4);
|
||||
|
||||
uint8_t getLoRaSF();
|
||||
uint8_t getLoRaCodingRate();
|
||||
uint8_t getOptimisation();
|
||||
uint8_t getSyncWord();
|
||||
uint8_t getInvertIQ();
|
||||
uint8_t getVersion();
|
||||
uint16_t getPreamble();
|
||||
|
||||
uint32_t returnBandwidth(uint8_t BWregvalue);
|
||||
uint8_t returnOptimisation(uint8_t SpreadingFactor, uint8_t Bandwidth);
|
||||
float calcSymbolTime(float Bandwidth, uint8_t SpreadingFactor);
|
||||
void printModemSettings();
|
||||
void setSyncWord(uint8_t syncword);
|
||||
void setTXDirect();
|
||||
void setupDirect(uint32_t frequency, int32_t offset);
|
||||
void toneFM(uint16_t frequency, uint32_t length, uint32_t deviation, float adjust, int8_t txpower);
|
||||
int8_t getDeviceTemperature();
|
||||
void fskCarrierOn(int8_t txpower);
|
||||
void fskCarrierOff();
|
||||
void setRfFrequencyDirect(uint8_t high, uint8_t mid, uint8_t low);
|
||||
void getRfFrequencyRegisters(uint8_t *buff);
|
||||
void startFSKRTTY(uint32_t freqshift, uint8_t pips, uint16_t pipDelaymS, uint16_t pipPeriodmS, uint16_t leadinmS);
|
||||
void transmitFSKRTTY(uint8_t chartosend, uint8_t databits, uint8_t stopbits, uint8_t parity, uint16_t baudPerioduS, int8_t pin);
|
||||
void transmitFSKRTTY(uint8_t chartosend, uint16_t baudPerioduS, int8_t pin);
|
||||
void printRTTYregisters();
|
||||
void endFSKRTTY();
|
||||
void doAFC();
|
||||
void doAFCPPM();
|
||||
uint8_t getPPM();
|
||||
int32_t getOffset();
|
||||
void printOCPTRIM();
|
||||
uint8_t readBufferbytes(uint8_t *rxbuffer, uint8_t size);
|
||||
uint8_t writeBufferbytes(uint8_t *txbuffer, uint8_t size);
|
||||
void setDevicePABOOST();
|
||||
void setDeviceRFO();
|
||||
|
||||
//*******************************************************************************
|
||||
//Read Write SX12xxx Buffer commands, this is the buffer internal to the SX12xxxx
|
||||
//*******************************************************************************
|
||||
|
||||
uint8_t receiveSXBuffer(uint8_t startaddr, uint32_t rxtimeout, uint8_t wait);
|
||||
uint8_t transmitSXBuffer(uint8_t startaddr, uint8_t length, uint32_t txtimeout, int8_t txpower, uint8_t wait);
|
||||
|
||||
void printSXBufferHEX(uint8_t start, uint8_t end);
|
||||
void printSXBufferASCII(uint8_t start, uint8_t end);
|
||||
void fillSXBuffer(uint8_t startaddress, uint8_t size, uint8_t character);
|
||||
uint8_t getByteSXBuffer(uint8_t addr);
|
||||
void writeByteSXBuffer(uint8_t addr, uint8_t regdata);
|
||||
|
||||
void startWriteSXBuffer(uint8_t ptr);
|
||||
uint8_t endWriteSXBuffer();
|
||||
void startReadSXBuffer(uint8_t ptr);
|
||||
uint8_t endReadSXBuffer();
|
||||
|
||||
void writeUint8(uint8_t x);
|
||||
uint8_t readUint8();
|
||||
|
||||
void writeInt8(int8_t x);
|
||||
int8_t readInt8();
|
||||
|
||||
void writeChar(char x);
|
||||
char readChar();
|
||||
|
||||
void writeUint16(uint16_t x);
|
||||
uint16_t readUint16();
|
||||
|
||||
void writeInt16(int16_t x);
|
||||
int16_t readInt16();
|
||||
|
||||
void writeUint32(uint32_t x);
|
||||
uint32_t readUint32();
|
||||
|
||||
void writeInt32(int32_t x);
|
||||
int32_t readInt32();
|
||||
|
||||
void writeFloat(float x);
|
||||
float readFloat();
|
||||
|
||||
void writeBuffer(uint8_t *txbuffer, uint8_t size);
|
||||
void writeBufferChar(char *txbuffer, uint8_t size);
|
||||
void writeBufferChar(char *txbuffer);
|
||||
uint8_t readBuffer(uint8_t *rxbuffer);
|
||||
uint8_t readBuffer(uint8_t *rxbuffer, uint8_t size);
|
||||
uint8_t readBufferChar(char *rxbuffer);
|
||||
|
||||
//*******************************************************************************
|
||||
//RX\TX Enable routines - Not yet tested as of 02/12/19
|
||||
//*******************************************************************************
|
||||
|
||||
void rxtxInit(int8_t pinRXEN, int8_t pinTXEN); //not used on current SX127x modules
|
||||
void rxEnable(); //not used on current SX127x modules
|
||||
void txEnable(); //not used on current SX127x modules
|
||||
|
||||
//*******************************************************************************
|
||||
//Library variables
|
||||
//*******************************************************************************
|
||||
|
||||
private:
|
||||
|
||||
int8_t _NSS, _NRESET, _DIO0, _DIO1, _DIO2;
|
||||
uint8_t _RXPacketL; //length of packet received
|
||||
uint8_t _RXPacketType; //type number of received packet
|
||||
uint8_t _RXDestination; //destination address of received packet
|
||||
uint8_t _RXSource; //source address of received packet
|
||||
uint8_t _TXPacketL; //length of transmitted packet
|
||||
uint16_t _IRQmsb; //for setting additional flags
|
||||
uint8_t _Device; //saved device type
|
||||
int8_t _TXDonePin; //the pin that will indicate TX done
|
||||
int8_t _RXDonePin; //the pin that will indicate RX done
|
||||
uint8_t _UseCRC; //when packet parameters are set this flag is set if CRC on packets in use
|
||||
int8_t _RXEN, _TXEN; //for modules that have RX TX pin switching
|
||||
uint8_t _PACKET_TYPE; //used to save the set packet type
|
||||
uint8_t _freqregH, _freqregM, _freqregL; //the registers values for the set frequency
|
||||
uint8_t _ShiftfreqregH, _ShiftfreqregM, _ShiftfreqregL; //register values for shifted frequency, used in FSK RTTY etc
|
||||
uint32_t _savedFrequency; //when setRfFrequency() is used the set frequency is saved
|
||||
int32_t _savedOffset; //when setRfFrequency() is used the set offset is saved
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
314
lib/SX12XX-LoRa/src/SX127XLT_Definitions.h
Normal file
314
lib/SX12XX-LoRa/src/SX127XLT_Definitions.h
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
Copyright 2019 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 17/12/19
|
||||
*/
|
||||
|
||||
#define LORA_MAC_PRIVATE_SYNCWORD 0x12
|
||||
#define LORA_MAC_PUBLIC_SYNCWORD 0x34
|
||||
|
||||
//radio operatine modes - see RegOpMode in register map
|
||||
#define MODE_SLEEP 0x00
|
||||
#define MODE_STDBY 0x01
|
||||
#define MODE_STDBY_RC 0x01
|
||||
|
||||
#define MODE_FSTX 0x02 //Frequency synthesis TX mode
|
||||
#define MODE_TX 0x03 //TX mode
|
||||
#define MODE_FSRX 0x04 //Frequency synthesis RX mode
|
||||
#define MODE_RXCONTINUOUS 0x05 //RX continuous mode
|
||||
#define MODE_RXSINGLE 0x06 //RX single mode
|
||||
|
||||
#define MODE_CAD 0xFF //RX CAD mode
|
||||
|
||||
#define POWERSAVE 0xC0 //select minimum LNA gain
|
||||
#define BOOSTED 0x38 //mode for booted, max LNA gain
|
||||
|
||||
#define LNAGAING1 0x20 //maximum LNA gain
|
||||
#define LNAGAING2 0x40
|
||||
#define LNAGAING3 0x60
|
||||
#define LNAGAING4 0x80
|
||||
#define LNAGAING5 0xA0
|
||||
#define LNAGAING6 0xC0 //minimum LNA gain
|
||||
|
||||
#define PACKET_TYPE_GFSK 0x00 //regopmode setting for FSK and direct mode
|
||||
#define PACKET_TYPE_LORA 0x80 //regopmode setting for LoRa
|
||||
#define PACKET_TYPE_NONE 0x0F
|
||||
|
||||
|
||||
#define RADIO_RAMP_10_US 0x0F
|
||||
#define RADIO_RAMP_12_US 0x0E
|
||||
#define RADIO_RAMP_15_US 0x0D
|
||||
#define RADIO_RAMP_20_US 0x0C
|
||||
#define RADIO_RAMP_25_US 0x0B
|
||||
#define RADIO_RAMP_31_US 0x0A
|
||||
#define RADIO_RAMP_40_US 0x09
|
||||
#define RADIO_RAMP_50_US 0x08
|
||||
#define RADIO_RAMP_62_US 0x07
|
||||
#define RADIO_RAMP_100_US 0x06
|
||||
#define RADIO_RAMP_125_US 0x05
|
||||
#define RADIO_RAMP_250_US 0x04
|
||||
#define RADIO_RAMP_500_US 0x03
|
||||
#define RADIO_RAMP_1000_US 0x02
|
||||
#define RADIO_RAMP_2000_US 0x01
|
||||
#define RADIO_RAMP_3400_US 0x00
|
||||
#define RADIO_RAMP_DEFAULT 0x09
|
||||
|
||||
#define OCP_TRIM_ON 0x20
|
||||
#define OCP_TRIM_OFF 0x00
|
||||
#define OCP_TRIM_45MA 0x00
|
||||
#define OCP_TRIM_80MA 0x07
|
||||
#define OCP_TRIM_100MA 0x0B
|
||||
#define OCP_TRIM_110MA 0x0D
|
||||
#define OCP_TRIM_120MA 0x0F
|
||||
#define OCP_TRIM_130MA 0x10
|
||||
#define OCP_TRIM_140MA 0x11
|
||||
#define OCP_TRIM_150MA 0x12
|
||||
|
||||
//Constant names for bandwidth settings
|
||||
#define LORA_BW_500 144 //actual 500000hz
|
||||
#define LORA_BW_250 128 //actual 250000hz
|
||||
#define LORA_BW_125 112 //actual 125000hz
|
||||
#define LORA_BW_062 96 //actual 62500hz
|
||||
#define LORA_BW_041 80 //actual 41670hz
|
||||
#define LORA_BW_031 64 //actual 31250hz
|
||||
#define LORA_BW_020 48 //actual 20830hz
|
||||
#define LORA_BW_015 32 //actual 15630hz
|
||||
#define LORA_BW_010 16 //actual 10420hz
|
||||
#define LORA_BW_007 0 //actual 7810hz
|
||||
|
||||
|
||||
//for SX127x
|
||||
#define LORA_SF6 0x06
|
||||
#define LORA_SF7 0x07
|
||||
#define LORA_SF8 0x08
|
||||
#define LORA_SF9 0x09
|
||||
#define LORA_SF10 0x0A
|
||||
#define LORA_SF11 0x0B
|
||||
#define LORA_SF12 0x0C
|
||||
|
||||
|
||||
#define LORA_CR_4_5 0x02
|
||||
#define LORA_CR_4_6 0x04
|
||||
#define LORA_CR_4_7 0x06
|
||||
#define LORA_CR_4_8 0x08
|
||||
|
||||
#define LDRO_OFF 0x00
|
||||
#define LDRO_ON 0x01
|
||||
#define LDRO_AUTO 0x02 //when set causes LDRO to be automatically calculated
|
||||
|
||||
#define WAIT_RX 0x01
|
||||
#define WAIT_TX 0x01
|
||||
#define NO_WAIT 0x00
|
||||
|
||||
#define FREQ_STEP 61.03515625
|
||||
|
||||
//These are the &/AND values for reading a parameter from a register.
|
||||
//For example the Bandwidth on a SX1278 is stored in bits 7-4 and those bits are
|
||||
//in effect numbers from 0 to 9, where 0 = 7800hz and 9 = 500000hz. Thus to read
|
||||
//the bandwidth value you need to &/AND the contents of the register with a value
|
||||
//The registers and values are different for SX1272 and the rest, so they are identified
|
||||
//by _2 and _X respectivly. To read all the bits of a register, appart from the setting
|
||||
//use the &/AND value with all bits inverted.
|
||||
|
||||
#define READ_BW_AND_2 0xC0 //register 0x1D
|
||||
#define READ_BW_AND_X 0xF0 //register 0x1D
|
||||
|
||||
#define READ_CR_AND_2 0x38 //register 0x1D
|
||||
#define READ_CR_AND_X 0x0E //register 0x1D
|
||||
|
||||
#define READ_SF_AND_2 0xF0 //register 0x1E
|
||||
#define READ_SF_AND_X 0xF0 //register 0x1E
|
||||
|
||||
#define READ_HASCRC_AND_2 0x02 //register 0x1D
|
||||
#define READ_HASCRC_AND_X 0x04 //register 0x1E
|
||||
|
||||
#define READ_LDRO_AND_2 0x01 //register 0x1D
|
||||
#define READ_LDRO_AND_X 0x08 //register 0x26
|
||||
|
||||
#define READ_AGCAUTO_AND_2 0x04 //register 0x1E
|
||||
#define READ_AGCAUTO_AND_X 0x04 //register 0x26
|
||||
|
||||
#define READ_IMPLCIT_AND_2 0x04 //register 0x1D
|
||||
#define READ_IMPLCIT_AND_X 0x01 //register 0x1D
|
||||
|
||||
#define READ_LNAGAIN_AND_2 0xE0 //register 0x0C
|
||||
#define READ_LNAGAIN_AND_X 0xE0 //register 0x0C
|
||||
|
||||
#define READ_LNABOOSTHF_AND_2 0x03 //register 0x0C
|
||||
#define READ_LNABOOSTHF_AND_X 0x03 //register 0x0C
|
||||
|
||||
#define READ_LNABOOSTLF_AND_2 0x18 //register 0x0C
|
||||
#define READ_LNABOOSTLF_AND_X 0x18 //register 0x0C
|
||||
|
||||
#define READ_OPMODE_AND_2 0x18 //register 0x01
|
||||
#define READ_OPMODE_AND_X 0x18 //register 0x01
|
||||
|
||||
#define READ_RANGEMODE_AND_2 0x80 //register 0x01
|
||||
#define READ_RANGEMODE_AND_X 0x80 //register 0x01
|
||||
|
||||
|
||||
|
||||
#define LORA_PACKET_VARIABLE_LENGTH 0x00
|
||||
#define LORA_PACKET_FIXED_LENGTH 0x01
|
||||
#define LORA_PACKET_EXPLICIT LORA_PACKET_VARIABLE_LENGTH
|
||||
#define LORA_PACKET_IMPLICIT LORA_PACKET_FIXED_LENGTH
|
||||
|
||||
//for SX127x
|
||||
#define LORA_CRC_ON 0x01 //Packet CRC is activated
|
||||
#define LORA_CRC_OFF 0x00 //Packet CRC not used
|
||||
|
||||
#define LORA_IQ_NORMAL 0x00
|
||||
#define LORA_IQ_INVERTED 0x40
|
||||
|
||||
|
||||
//For SX127x - mapping of these IRQs to the SX126x and SX128x style is not easy
|
||||
//the values have been fixed to these following DIOs. For instance IRQ_RX_DONE,
|
||||
//IRQ_TX_DONE and IRQ_CAD_DONE can only be mapped to DIO0.
|
||||
//For most applications only DIO0, DIO1 and DIO2 are connected.
|
||||
|
||||
#define IRQ_RADIO_NONE 0x00
|
||||
#define IRQ_CAD_ACTIVITY_DETECTED 0x01 //active on DIO1
|
||||
#define IRQ_FSHS_CHANGE_CHANNEL 0x02 //active on DIO2
|
||||
#define IRQ_CAD_DONE 0x04 //active on DIO0
|
||||
#define IRQ_TX_DONE 0x08 //active on DIO0
|
||||
#define IRQ_HEADER_VALID 0x10 //read from IRQ register only
|
||||
#define IRQ_CRC_ERROR 0x20 //read from IRQ register only
|
||||
#define IRQ_RX_DONE 0x40 //active on DIO0
|
||||
#define IRQ_RADIO_ALL 0xFFFF
|
||||
|
||||
#define IRQ_TX_TIMEOUT 0x0100 //so that readIrqstatus can return additional detections
|
||||
#define IRQ_RX_TIMEOUT 0x0200 //so that readIrqstatus can return additional detections
|
||||
#define IRQ_NO_PACKET_CRC 0x0400 //so that readIrqstatus can return additional detections
|
||||
|
||||
|
||||
#define CONFIGURATION_RETENTION 0x04 //these have no effect in SX127x, kept for compatibility
|
||||
#define RTC_TIMEOUT_ENABLE 0x01
|
||||
|
||||
|
||||
//SX127x Register names
|
||||
const uint8_t REG_FIFO = 0x00;
|
||||
const uint8_t WREG_FIFO = 0x80; //this is the write address for the FIFO
|
||||
const uint8_t REG_OPMODE = 0x01;
|
||||
const uint8_t REG_FDEVLSB = 0x05;
|
||||
const uint8_t REG_FRMSB = 0x06;
|
||||
const uint8_t REG_FRMID = 0x07;
|
||||
const uint8_t REG_FRLSB = 0x08;
|
||||
const uint8_t REG_PACONFIG = 0x09;
|
||||
const uint8_t REG_PARAMP = 0x0A;
|
||||
const uint8_t REG_OCP = 0x0B;
|
||||
const uint8_t REG_LNA = 0x0C;
|
||||
const uint8_t REG_FIFOADDRPTR = 0x0D;
|
||||
const uint8_t REG_FIFOTXBASEADDR = 0x0E;
|
||||
const uint8_t REG_FIFORXBASEADDR = 0x0F;
|
||||
const uint8_t REG_FIFORXCURRENTADDR = 0x10;
|
||||
const uint8_t REG_IRQFLAGSMASK = 0x11;
|
||||
const uint8_t REG_IRQFLAGS = 0x12;
|
||||
const uint8_t REG_RXNBBYTES = 0x13;
|
||||
const uint8_t REG_RXHEADERCNTVALUEMSB = 0x14;
|
||||
const uint8_t REG_RXHEADERCNTVALUELSB = 0x15;
|
||||
const uint8_t REG_RXPACKETCNTVALUEMSB = 0x16;
|
||||
const uint8_t REG_RXPACKETCNTVALUELSB = 0x17;
|
||||
const uint8_t REG_PKTSNRVALUE = 0x19;
|
||||
const uint8_t REG_PKTRSSIVALUE = 0x1A;
|
||||
const uint8_t REG_RSSIVALUE = 0x1B;
|
||||
const uint8_t REG_CURRENTRSSIVALUE = 0x1B;
|
||||
const uint8_t REG_HOPCHANNEL = 0x1C;
|
||||
const uint8_t REG_MODEMCONFIG1 = 0x1D;
|
||||
const uint8_t REG_MODEMCONFIG2 = 0x1E;
|
||||
const uint8_t REG_SYMBTIMEOUTLSB = 0x1F;
|
||||
const uint8_t REG_PREAMBLEMSB = 0x20;
|
||||
const uint8_t REG_PREAMBLELSB = 0x21;
|
||||
const uint8_t REG_PAYLOADLENGTH = 0x22;
|
||||
const uint8_t REG_FIFORXBYTEADDR = 0x25;
|
||||
const uint8_t REG_MODEMCONFIG3 = 0x26;
|
||||
const uint8_t REG_PPMCORRECTION = 0x27;
|
||||
const uint8_t REG_FEIMSB = 0x28;
|
||||
const uint8_t REG_FEIMID = 0x29;
|
||||
const uint8_t REG_FEILSB = 0x2A;
|
||||
const uint8_t REG_LRRSSIWIDEBAND = 0x2C;
|
||||
const uint8_t REG_LRTEST2F = 0x2F;
|
||||
const uint8_t REG_LRTEST30 = 0x30;
|
||||
const uint8_t REG_DETECTOPTIMIZE = 0x31;
|
||||
const uint8_t REG_INVERTIQ = 0x33;
|
||||
const uint8_t REG_LRTEST36 = 0x36;
|
||||
const uint8_t REG_HIGHBWOPTIMIZE1 = 0x36;
|
||||
const uint8_t REG_LRDETECTIONTHRESHOLD = 0x37;
|
||||
const uint8_t REG_DETECTIONTHRESHOLD = 0x37;
|
||||
const uint8_t REG_SYNCWORD = 0x39;
|
||||
const uint8_t REG_LRTEST3A = 0x3A;
|
||||
const uint8_t REG_HIGHBWOPTIMIZE2 = 0x3A;
|
||||
const uint8_t REG_IMAGECAL = 0x3B;
|
||||
const uint8_t REG_INVERTIQ2 = 0x3B;
|
||||
const uint8_t REG_TEMP = 0x3C;
|
||||
const uint8_t REG_DIOMAPPING1 = 0x40;
|
||||
const uint8_t REG_DIOMAPPING2 = 0x41;
|
||||
const uint8_t REG_VERSION = 0x42;
|
||||
const uint8_t REG_PLLHOP = 0x44;
|
||||
const uint8_t REG_PADAC = 0x4D;
|
||||
|
||||
|
||||
#define PRINT_LOW_REGISTER 0x00
|
||||
#define PRINT_HIGH_REGISTER 0x4F
|
||||
|
||||
#define DEVICE_SX1272 0x10 //for modules that use the PA_BOOST pin for RF output
|
||||
#define DEVICE_SX1276 0x11 //bit 4 set indicates PA_BOOST in use
|
||||
#define DEVICE_SX1277 0x12
|
||||
#define DEVICE_SX1278 0x13
|
||||
#define DEVICE_SX1279 0x14
|
||||
|
||||
|
||||
#define DEVICE_SX1272_PABOOST 0x10 //for modules that use the RF_BOOST pin for RF output
|
||||
#define DEVICE_SX1276_PABOOST 0x11 //bit 4 set indicates PA_BOOST in use
|
||||
#define DEVICE_SX1277_PABOOST 0x12
|
||||
#define DEVICE_SX1278_PABOOST 0x13
|
||||
#define DEVICE_SX1279_PABOOST 0x14
|
||||
|
||||
//no support for SX1272 modules using RFO output, dont have one to test
|
||||
#define DEVICE_SX1276_RFO 0x01 //for modules that use the RFO LF_ANT or HF_ANT pin for RF output
|
||||
#define DEVICE_SX1277_RFO 0x02 //bit 4 clear indicates RFO in use
|
||||
#define DEVICE_SX1278_RFO 0x03
|
||||
#define DEVICE_SX1279_RFO 0x04
|
||||
|
||||
|
||||
//power settings
|
||||
#define MAXPOWER11dBm 0x00 //REG_PACONFIG = x000xxxx
|
||||
#define MAXPOWER14dBm 0x50 //REG_PACONFIG = x101xxxx
|
||||
#define MAXPOWER17dBm 0x70 //REG_PACONFIG = x111xxxx
|
||||
#define PABOOSTON 0x80
|
||||
#define PABOOSTOFF 0x00
|
||||
|
||||
|
||||
|
||||
//SPI settings
|
||||
#define LTspeedMaximum 8000000
|
||||
#define LTdataOrder MSBFIRST
|
||||
#define LTdataMode SPI_MODE0
|
||||
|
||||
#define Deviation5khz 0x52
|
||||
|
||||
|
||||
//FSKRTTY Settings
|
||||
#define ParityNone 0
|
||||
#define ParityOdd 1
|
||||
#define ParityEven 2
|
||||
#define ParityZero 0xF0
|
||||
#define ParityOne 0xF1
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
2759
lib/SX12XX-LoRa/src/SX128XLT.cpp
Normal file
2759
lib/SX12XX-LoRa/src/SX128XLT.cpp
Normal file
File diff suppressed because it is too large
Load Diff
197
lib/SX12XX-LoRa/src/SX128XLT.h
Normal file
197
lib/SX12XX-LoRa/src/SX128XLT.h
Normal file
@@ -0,0 +1,197 @@
|
||||
#ifndef SX128XLT_h
|
||||
#define SX128XLT_h
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <SX128XLT_Definitions.h>
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
ToDO
|
||||
|
||||
DONE - Why is SX1280LT.setPacketType(PACKET_TYPE_LORA) required before getFreqInt works with FLRC
|
||||
- The register addresses where the frequency is stored are different for FLRC and LORA
|
||||
DONE - Checkbusy at end of setmode ? - not needed, Checkbusy before all SPI activity
|
||||
DONE - Ranging in complement2 - warning: comparison between signed and unsigned integer
|
||||
DONE - Trap use of devices with RX\TX switching in ranging mode
|
||||
DONE - Ensure ranging distance is not negative
|
||||
|
||||
|
||||
Add routine to change period_base for RX,TX timeout
|
||||
Is there a direct register access to packet length for transmit ?
|
||||
Test RSSI and SNR are realistic for LoRa and FLRC
|
||||
Review error rate in FLRC mode
|
||||
Error packets at -99dBm due to noise ?
|
||||
Add support for printPacketStatus for FLRC
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
class SX128XLT {
|
||||
|
||||
public:
|
||||
|
||||
SX128XLT();
|
||||
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinDIO2, int8_t pinDIO3, int8_t pinRXEN, int8_t pinTXEN, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, uint8_t device);
|
||||
bool begin(int8_t pinNSS, int8_t pinNRESET, int8_t pinRFBUSY, int8_t pinDIO1, int8_t pinRXEN, int8_t pinTXEN, uint8_t device);
|
||||
|
||||
void rxEnable();
|
||||
void txEnable();
|
||||
|
||||
void checkBusy();
|
||||
bool config();
|
||||
void readRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
|
||||
uint8_t readRegister( uint16_t address );
|
||||
void writeRegisters( uint16_t address, uint8_t *buffer, uint16_t size );
|
||||
void writeRegister( uint16_t address, uint8_t value );
|
||||
void writeCommand(uint8_t Opcode, uint8_t *buffer, uint16_t size );
|
||||
void readCommand( uint8_t Opcode, uint8_t *buffer, uint16_t size );
|
||||
void resetDevice();
|
||||
bool checkDevice();
|
||||
void setupLoRa(uint32_t frequency, int32_t offset, uint8_t modParam1, uint8_t modParam2, uint8_t modParam3);
|
||||
void setMode(uint8_t modeconfig);
|
||||
void setRegulatorMode(uint8_t mode);
|
||||
void setPacketType(uint8_t PacketType);
|
||||
void setRfFrequency( uint32_t frequency, int32_t offset );
|
||||
void setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress);
|
||||
void setModulationParams(uint8_t modParam1, uint8_t modParam2, uint8_t modParam3);
|
||||
void setPacketParams(uint8_t packetParam1, uint8_t packetParam2, uint8_t packetParam3, uint8_t packetParam4, uint8_t packetParam5, uint8_t packetParam6, uint8_t packetParam7);
|
||||
void setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask );
|
||||
void setHighSensitivity();
|
||||
void setLowPowerRX();
|
||||
void printModemSettings();
|
||||
void printDevice();
|
||||
uint32_t getFreqInt();
|
||||
uint8_t getLoRaSF();
|
||||
uint32_t returnBandwidth(uint8_t data);
|
||||
uint8_t getLoRaCodingRate();
|
||||
uint8_t getInvertIQ();
|
||||
uint16_t getPreamble();
|
||||
void printOperatingSettings();
|
||||
uint8_t getLNAgain();
|
||||
void printRegisters(uint16_t Start, uint16_t End);
|
||||
void printASCIIPacket(uint8_t *buff, uint8_t tsize);
|
||||
uint8_t transmit(uint8_t *txbuffer, uint8_t size, uint16_t timeout, int8_t txpower, uint8_t wait);
|
||||
void setTxParams(int8_t TXpower, uint8_t RampTime);
|
||||
void setTx(uint16_t timeout);
|
||||
void clearIrqStatus( uint16_t irq );
|
||||
uint16_t readIrqStatus();
|
||||
void printIrqStatus();
|
||||
uint16_t CRCCCITT(uint8_t *buffer, uint8_t size, uint16_t start);
|
||||
uint8_t receive(uint8_t *rxbuffer, uint8_t size, uint16_t timeout, uint8_t wait);
|
||||
uint8_t readPacketRSSI();
|
||||
uint8_t readPacketSNR();
|
||||
uint8_t readRXPacketL();
|
||||
void setRx(uint16_t timeout);
|
||||
void setSyncWord1(uint32_t syncword);
|
||||
void setSleep(uint8_t sleepconfig);
|
||||
uint16_t CRCCCITTSX(uint8_t startadd, uint8_t endadd, uint16_t startvalue);
|
||||
uint8_t getByteSXBuffer(uint8_t addr);
|
||||
int32_t getFrequencyErrorRegValue();
|
||||
int32_t getFrequencyErrorHz();
|
||||
void printHEXByte(uint8_t temp);
|
||||
void wake() ;
|
||||
uint8_t transmitAddressed(uint8_t *txbuffer, uint8_t size, char txpackettype, char txdestination, char txsource, uint32_t timeout, int8_t txpower, uint8_t wait);
|
||||
uint8_t receiveAddressed(uint8_t *rxbuffer, uint8_t size, uint16_t timeout, uint8_t wait);
|
||||
uint8_t readRXPacketType();
|
||||
uint8_t readPacket(uint8_t *rxbuffer, uint8_t size);
|
||||
/**********************************************************
|
||||
*****************
|
||||
//Start direct access SX buffer routines
|
||||
***************************************************************************/
|
||||
|
||||
void startWriteSXBuffer(uint8_t ptr);
|
||||
uint8_t endWriteSXBuffer();
|
||||
void startReadSXBuffer(uint8_t ptr);
|
||||
uint8_t endReadSXBuffer();
|
||||
|
||||
void writeUint8(uint8_t x);
|
||||
uint8_t readUint8();
|
||||
|
||||
void writeInt8(int8_t x);
|
||||
int8_t readInt8();
|
||||
|
||||
void writeInt16(int16_t x);
|
||||
int16_t readInt16();
|
||||
|
||||
void writeUint16(uint16_t x);
|
||||
uint16_t readUint16();
|
||||
|
||||
void writeInt32(int32_t x);
|
||||
int32_t readInt32();
|
||||
|
||||
void writeUint32(uint32_t x);
|
||||
uint32_t readUint32();
|
||||
|
||||
void writeFloat(float x);
|
||||
float readFloat();
|
||||
|
||||
uint8_t transmitSXBuffer(uint8_t startaddr, uint8_t length, uint16_t timeout, int8_t txpower, uint8_t wait);
|
||||
void writeBuffer(uint8_t *txbuffer, uint8_t size);
|
||||
uint8_t receiveSXBuffer(uint8_t startaddr, uint16_t timeout, uint8_t wait);
|
||||
uint8_t readBuffer(uint8_t *rxbuffer);
|
||||
void printSXBufferHEX(uint8_t start, uint8_t end);
|
||||
uint16_t addCRC(uint8_t data, uint16_t libraryCRC);
|
||||
void writeBufferChar(char *txbuffer, uint8_t size);
|
||||
uint8_t readBufferChar(char *rxbuffer);
|
||||
/***************************************************************************
|
||||
//End direct access SX buffer routines
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
//Start ranging routines
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
void setRangingSlaveAddress(uint32_t address);
|
||||
void setRangingMasterAddress(uint32_t address);
|
||||
void setRangingCalibration(uint16_t cal);
|
||||
void setRangingRole(uint8_t role);
|
||||
double getRangingDistance(uint8_t resultType, int32_t regval, float adjust);
|
||||
uint32_t getRangingResultRegValue(uint8_t resultType);
|
||||
int32_t complement2( uint32_t num, uint8_t bitCnt );
|
||||
bool setupRanging(uint32_t frequency, int32_t offset, uint8_t modParam1, uint8_t modParam2, uint8_t modParam3, uint32_t address, uint8_t role);
|
||||
bool transmitRanging(uint32_t address, uint16_t timeout, int8_t txpower, uint8_t wait);
|
||||
uint8_t receiveRanging(uint32_t address, uint16_t timeout, int8_t txpower, uint8_t wait);
|
||||
uint16_t lookupCalibrationValue(uint8_t spreadingfactor, uint8_t bandwidth);
|
||||
uint16_t getSetCalibrationValue();
|
||||
|
||||
/***************************************************************************
|
||||
//End ranging routines
|
||||
***************************************************************************/
|
||||
|
||||
private:
|
||||
|
||||
int8_t _NSS, _NRESET, _RFBUSY, _DIO1, _DIO2, _DIO3;
|
||||
int8_t _RXEN, _TXEN;
|
||||
uint8_t _RXPacketL; //length of packet received
|
||||
uint8_t _RXPacketType; //type number of received packet
|
||||
uint8_t _RXDestination; //destination address of received packet
|
||||
uint8_t _RXSource; //source address of received packet
|
||||
int8_t _PacketRSSI; //RSSI of received packet
|
||||
int8_t _PacketSNR; //signal to noise ratio of received packet
|
||||
int8_t _TXPacketL; //transmitted packet length
|
||||
uint8_t _RXcount; //used to keep track of the bytes read from SX1280 buffer during readFloat() etc
|
||||
uint8_t _TXcount; //used to keep track of the bytes written to SX1280 buffer during writeFloat() etc
|
||||
uint8_t _OperatingMode; //current operating mode
|
||||
bool _rxtxpinmode = false; //set to true if RX and TX pin mode is used.
|
||||
|
||||
uint8_t _Device; //saved device type
|
||||
uint8_t _TXDonePin; //the pin that will indicate TX done
|
||||
uint8_t _RXDonePin; //the pin that will indicate RX done
|
||||
uint8_t _PERIODBASE = PERIODBASE_01_MS;
|
||||
|
||||
uint8_t savedRegulatorMode;
|
||||
uint8_t savedPacketType;
|
||||
uint32_t savedFrequency;
|
||||
int32_t savedOffset;
|
||||
uint8_t savedModParam1, savedModParam2, savedModParam3; //sequence is spreading factor, bandwidth, coding rate
|
||||
uint8_t savedPacketParam1, savedPacketParam2, savedPacketParam3, savedPacketParam4, savedPacketParam5, savedPacketParam6, savedPacketParam7;
|
||||
uint16_t savedIrqMask, savedDio1Mask, savedDio2Mask, savedDio3Mask;
|
||||
int8_t savedTXPower;
|
||||
uint16_t savedCalibration;
|
||||
uint32_t savedFrequencyReg;
|
||||
|
||||
};
|
||||
#endif
|
||||
388
lib/SX12XX-LoRa/src/SX128XLT_Definitions.h
Normal file
388
lib/SX12XX-LoRa/src/SX128XLT_Definitions.h
Normal file
@@ -0,0 +1,388 @@
|
||||
//SX1280LT Includes
|
||||
|
||||
|
||||
//*************************************************************
|
||||
// LoRa Modem Settings
|
||||
//*************************************************************
|
||||
//
|
||||
//LoRa spreading factors
|
||||
#define LORA_SF5 0x50
|
||||
#define LORA_SF6 0x60
|
||||
#define LORA_SF7 0x70
|
||||
#define LORA_SF8 0x80
|
||||
#define LORA_SF9 0x90
|
||||
#define LORA_SF10 0xA0
|
||||
#define LORA_SF11 0xB0
|
||||
#define LORA_SF12 0xC0
|
||||
|
||||
//LoRa bandwidths
|
||||
#define LORA_BW_0200 0x34 //actually 203125hz
|
||||
#define LORA_BW_0400 0x26 //actually 406250hz
|
||||
#define LORA_BW_0800 0x18 //actually 812500hz
|
||||
#define LORA_BW_1600 0x0A //actually 1625000hz
|
||||
|
||||
//LoRa coding rates
|
||||
#define LORA_CR_4_5 0x01
|
||||
#define LORA_CR_4_6 0x02
|
||||
#define LORA_CR_4_7 0x03
|
||||
#define LORA_CR_4_8 0x04
|
||||
|
||||
//LoRa CAD settings
|
||||
#define LORA_CAD_01_SYMBOL 0x00
|
||||
#define LORA_CAD_02_SYMBOL 0x20
|
||||
#define LORA_CAD_04_SYMBOL 0x40
|
||||
#define LORA_CAD_08_SYMBOL 0x60
|
||||
#define LORA_CAD_16_SYMBOL 0x80
|
||||
|
||||
//LoRa Header Types
|
||||
#define LORA_PACKET_VARIABLE_LENGTH 0x00
|
||||
#define LORA_PACKET_FIXED_LENGTH 0x80
|
||||
#define LORA_PACKET_EXPLICIT LORA_PACKET_VARIABLE_LENGTH
|
||||
#define LORA_PACKET_IMPLICIT LORA_PACKET_FIXED_LENGTH
|
||||
|
||||
//LoRa packet CRC settings
|
||||
#define LORA_CRC_ON 0x20
|
||||
#define LORA_CRC_OFF 0x00
|
||||
|
||||
//LoRa IQ Setings
|
||||
#define LORA_IQ_NORMAL 0x40
|
||||
#define LORA_IQ_INVERTED 0x00
|
||||
|
||||
|
||||
#define FREQ_STEP 198.364
|
||||
#define FREQ_ERROR_CORRECTION 1.55
|
||||
|
||||
|
||||
|
||||
|
||||
//*************************************************************
|
||||
// SX1280 Interrupt flags
|
||||
//*************************************************************
|
||||
|
||||
#define IRQ_RADIO_NONE 0x0000
|
||||
#define IRQ_TX_DONE 0x0001
|
||||
#define IRQ_RX_DONE 0x0002
|
||||
#define IRQ_SYNCWORD_VALID 0x0004
|
||||
#define IRQ_SYNCWORD_ERROR 0x0008
|
||||
#define IRQ_HEADER_VALID 0x0010
|
||||
#define IRQ_HEADER_ERROR 0x0020
|
||||
#define IRQ_CRC_ERROR 0x0040
|
||||
#define IRQ_RANGING_SLAVE_RESPONSE_DONE 0x0080
|
||||
|
||||
#define IRQ_RANGING_SLAVE_REQUEST_DISCARDED 0x0100
|
||||
#define IRQ_RANGING_MASTER_RESULT_VALID 0x0200
|
||||
#define IRQ_RANGING_MASTER_RESULT_TIMEOUT 0x0400
|
||||
#define IRQ_RANGING_SLAVE_REQUEST_VALID 0x0800
|
||||
#define IRQ_CAD_DONE 0x1000
|
||||
#define IRQ_CAD_ACTIVITY_DETECTED 0x2000
|
||||
#define IRQ_RX_TX_TIMEOUT 0x4000
|
||||
#define IRQ_TX_TIMEOUT 0x4000
|
||||
#define IRQ_RX_TIMEOUT 0x4000
|
||||
#define IRQ_PREAMBLE_DETECTED 0x8000
|
||||
#define IRQ_RADIO_ALL 0xFFFF
|
||||
|
||||
|
||||
//*************************************************************
|
||||
// SX1280 Commands
|
||||
//*************************************************************
|
||||
|
||||
#define RADIO_GET_PACKETTYPE 0x03
|
||||
#define RADIO_GET_IRQSTATUS 0x15
|
||||
#define RADIO_GET_RXBUFFERSTATUS 0x17
|
||||
#define RADIO_WRITE_REGISTER 0x18
|
||||
#define RADIO_READ_REGISTER 0x19
|
||||
#define RADIO_WRITE_BUFFER 0x1A
|
||||
#define RADIO_READ_BUFFER 0x1B
|
||||
#define RADIO_GET_PACKETSTATUS 0x1D
|
||||
#define RADIO_GET_RSSIINST 0x1F
|
||||
#define RADIO_SET_STANDBY 0x80
|
||||
#define RADIO_SET_RX 0x82
|
||||
#define RADIO_SET_TX 0x83
|
||||
#define RADIO_SET_SLEEP 0x84
|
||||
#define RADIO_SET_RFFREQUENCY 0x86
|
||||
#define RADIO_SET_CADPARAMS 0x88
|
||||
#define RADIO_CALIBRATE 0x89
|
||||
#define RADIO_SET_PACKETTYPE 0x8A
|
||||
#define RADIO_SET_MODULATIONPARAMS 0x8B
|
||||
#define RADIO_SET_PACKETPARAMS 0x8C
|
||||
#define RADIO_SET_DIOIRQPARAMS 0x8D
|
||||
#define RADIO_SET_TXPARAMS 0x8E
|
||||
#define RADIO_SET_BUFFERBASEADDRESS 0x8F
|
||||
#define RADIO_SET_RXDUTYCYCLE 0x94
|
||||
#define RADIO_SET_REGULATORMODE 0x96
|
||||
#define RADIO_CLR_IRQSTATUS 0x97
|
||||
#define RADIO_SET_AUTOTX 0x98
|
||||
#define RADIO_SET_LONGPREAMBLE 0x9B
|
||||
#define RADIO_SET_UARTSPEED 0x9D
|
||||
#define RADIO_SET_AUTOFS 0x9E
|
||||
#define RADIO_SET_RANGING_ROLE 0xA3
|
||||
#define RADIO_GET_STATUS 0xC0
|
||||
#define RADIO_SET_FS 0xC1
|
||||
#define RADIO_SET_CAD 0xC5
|
||||
#define RADIO_SET_TXCONTINUOUSWAVE 0xD1
|
||||
#define RADIO_SET_TXCONTINUOUSPREAMBLE 0xD2
|
||||
#define RADIO_SET_SAVECONTEXT 0xD5
|
||||
|
||||
|
||||
//*************************************************************
|
||||
// SX1280 Registers
|
||||
//*************************************************************
|
||||
|
||||
#define REG_LNA_REGIME 0x0891
|
||||
#define REG_LR_PAYLOADLENGTH 0x901
|
||||
#define REG_LR_PACKETPARAMS 0x903
|
||||
|
||||
#define REG_RFFrequency23_16 0x906
|
||||
#define REG_RFFrequency15_8 0x907
|
||||
#define REG_RFFrequency7_0 0x908
|
||||
|
||||
#define REG_FLRC_RFFrequency23_16 0x9A3 //found by experiment
|
||||
#define REG_FLRC_RFFrequency15_8 0x9A4
|
||||
#define REG_FLRC_RFFrequency7_0 0x9A5
|
||||
|
||||
#define REG_RANGING_FILTER_WINDOW_SIZE 0x091E
|
||||
#define REG_LR_DEVICERANGINGADDR 0x0916
|
||||
#define REG_LR_DEVICERANGINGADDR 0x0916
|
||||
#define REG_LR_RANGINGRESULTCONFIG 0x0924
|
||||
#define REG_LR_RANGINGRERXTXDELAYCAL 0x092C
|
||||
#define REG_LR_RANGINGIDCHECKLENGTH 0x0931
|
||||
#define REG_LR_ESTIMATED_FREQUENCY_ERROR_MSB 0x954
|
||||
#define REG_LR_ESTIMATED_FREQUENCY_ERROR_MID 0x955
|
||||
#define REG_LR_ESTIMATED_FREQUENCY_ERROR_LSB 0x956
|
||||
#define REG_LR_RANGINGRESULTBASEADDR 0x0961
|
||||
#define REG_LR_SYNCWORDTOLERANCE 0x09CD
|
||||
#define REG_LR_SYNCWORDBASEADDRESS1 0x09CE
|
||||
#define REG_FLRCSYNCWORD1_BASEADDR 0x09CF
|
||||
#define REG_LR_SYNCWORDBASEADDRESS2 0x09D3
|
||||
#define REG_FLRCSYNCWORD2_BASEADDR 0x09D4
|
||||
#define REG_LR_SYNCWORDBASEADDRESS3 0x09D8
|
||||
|
||||
#define REG_LR_ESTIMATED_FREQUENCY_ERROR_MASK 0x0FFFFF
|
||||
|
||||
//SX1280 Packet Types
|
||||
#define PACKET_TYPE_GFSK 0x00
|
||||
#define PACKET_TYPE_LORA 0x01
|
||||
#define PACKET_TYPE_RANGING 0x02
|
||||
#define PACKET_TYPE_FLRC 0x03
|
||||
#define PACKET_TYPE_BLE 0x04
|
||||
|
||||
//SX1280 Standby modes
|
||||
#define MODE_STDBY_RC 0x00
|
||||
#define MODE_STDBY_XOSC 0x01
|
||||
|
||||
//TX and RX timeout based periods
|
||||
#define PERIODBASE_15_US 0x00
|
||||
#define PERIODBASE_62_US 0x01
|
||||
#define PERIODBASE_01_MS 0x02
|
||||
#define PERIODBASE_04_MS 0x03
|
||||
|
||||
//TX ramp periods
|
||||
#define RADIO_RAMP_02_US 0x00
|
||||
#define RADIO_RAMP_04_US 0x20
|
||||
#define RADIO_RAMP_06_US 0x40
|
||||
#define RADIO_RAMP_08_US 0x60
|
||||
#define RADIO_RAMP_10_US 0x80
|
||||
#define RADIO_RAMP_12_US 0xA0
|
||||
#define RADIO_RAMP_16_US 0xC0
|
||||
#define RADIO_RAMP_20_US 0xE0
|
||||
|
||||
//SX1280 Power settings
|
||||
#define USE_LDO 0x00
|
||||
#define USE_DCDC 0x01
|
||||
|
||||
|
||||
//*************************************************************
|
||||
//SX1280 Ranging settings
|
||||
//*************************************************************
|
||||
|
||||
#define RANGING_IDCHECK_LENGTH_08_BITS 0x00
|
||||
#define RANGING_IDCHECK_LENGTH_16_BITS 0x01
|
||||
#define RANGING_IDCHECK_LENGTH_24_BITS 0x02
|
||||
#define RANGING_IDCHECK_LENGTH_32_BITS 0x03
|
||||
|
||||
#define RANGING_RESULT_RAW 0x00
|
||||
#define RANGING_RESULT_AVERAGED 0x01
|
||||
#define RANGING_RESULT_DEBIASED 0x02
|
||||
#define RANGING_RESULT_FILTERED 0x03
|
||||
|
||||
|
||||
#define MASK_RANGINGMUXSEL 0xCF
|
||||
|
||||
#define RANGING_SLAVE 0x00
|
||||
#define RANGING_MASTER 0x01
|
||||
|
||||
|
||||
//*************************************************************
|
||||
//GFSK modem settings
|
||||
//*************************************************************
|
||||
|
||||
#define GFS_BLE_BR_2_000_BW_2_4 0x04
|
||||
#define GFS_BLE_BR_1_600_BW_2_4 0x28
|
||||
#define GFS_BLE_BR_1_000_BW_2_4 0x4C
|
||||
#define GFS_BLE_BR_1_000_BW_1_2 0x45
|
||||
#define GFS_BLE_BR_0_800_BW_2_4 0x70
|
||||
#define GFS_BLE_BR_0_800_BW_1_2 0x69
|
||||
#define GFS_BLE_BR_0_500_BW_1_2 0x8D
|
||||
#define GFS_BLE_BR_0_500_BW_0_6 0x86
|
||||
#define GFS_BLE_BR_0_400_BW_1_2 0xB1
|
||||
#define GFS_BLE_BR_0_400_BW_0_6 0xAA
|
||||
#define GFS_BLE_BR_0_250_BW_0_6 0xCE
|
||||
#define GFS_BLE_BR_0_250_BW_0_3 0xC7
|
||||
#define GFS_BLE_BR_0_125_BW_0_3 0xEF
|
||||
|
||||
#define GFS_BLE_MOD_IND_0_35 0
|
||||
#define GFS_BLE_MOD_IND_0_50 1
|
||||
#define GFS_BLE_MOD_IND_0_75 2
|
||||
#define GFS_BLE_MOD_IND_1_00 3
|
||||
#define GFS_BLE_MOD_IND_1_25 4
|
||||
#define GFS_BLE_MOD_IND_1_50 5
|
||||
#define GFS_BLE_MOD_IND_1_75 6
|
||||
#define GFS_BLE_MOD_IND_2_00 7
|
||||
#define GFS_BLE_MOD_IND_2_25 8
|
||||
#define GFS_BLE_MOD_IND_2_50 9
|
||||
#define GFS_BLE_MOD_IND_2_75 10
|
||||
#define GFS_BLE_MOD_IND_3_00 11
|
||||
#define GFS_BLE_MOD_IND_3_25 12
|
||||
#define GFS_BLE_MOD_IND_3_50 13
|
||||
#define GFS_BLE_MOD_IND_3_75 14
|
||||
#define GFS_BLE_MOD_IND_4_00 15
|
||||
|
||||
#define PREAMBLE_LENGTH_04_BITS 0x00 //4 bits
|
||||
#define PREAMBLE_LENGTH_08_BITS 0x10 //8 bits
|
||||
#define PREAMBLE_LENGTH_12_BITS 0x20 //12 bits
|
||||
#define PREAMBLE_LENGTH_16_BITS 0x30 //16 bits
|
||||
#define PREAMBLE_LENGTH_20_BITS 0x40 //20 bits
|
||||
#define PREAMBLE_LENGTH_24_BITS 0x50 //24 bits
|
||||
#define PREAMBLE_LENGTH_28_BITS 0x60 //28 bits
|
||||
#define PREAMBLE_LENGTH_32_BITS 0x70 //32 bits
|
||||
|
||||
#define GFS_SYNCWORD_LENGTH_1_BYTE 0x00 //Sync word length 1 byte
|
||||
#define GFS_SYNCWORD_LENGTH_2_BYTE 0x02 //Sync word length 2 bytes
|
||||
#define GFS_SYNCWORD_LENGTH_3_BYTE 0x04 //Sync word length 3 bytes
|
||||
#define GFS_SYNCWORD_LENGTH_4_BYTE 0x06 //Sync word length 4 bytes
|
||||
#define GFS_SYNCWORD_LENGTH_5_BYTE 0x08 //Sync word length 5 bytes
|
||||
|
||||
#define RADIO_RX_MATCH_SYNCWORD_OFF 0x00 //no search for SyncWord
|
||||
#define RADIO_RX_MATCH_SYNCWORD_1 0x10
|
||||
#define RADIO_RX_MATCH_SYNCWORD_2 0x20
|
||||
#define RADIO_RX_MATCH_SYNCWORD_1_2 0x30
|
||||
#define RADIO_RX_MATCH_SYNCWORD_3 0x40
|
||||
#define RADIO_RX_MATCH_SYNCWORD_1_3 0x50
|
||||
#define RADIO_RX_MATCH_SYNCWORD_2_3 0x60
|
||||
#define RADIO_RX_MATCH_SYNCWORD_1_2_3 0x70
|
||||
|
||||
#define RADIO_PACKET_FIXED_LENGTH 0x00 //The packet is fixed length, klnown on both RX and TX, no header
|
||||
#define RADIO_PACKET_VARIABLE_LENGTH 0x20 //The packet is variable size, header included
|
||||
|
||||
#define RADIO_CRC_OFF 0x00
|
||||
#define RADIO_CRC_1_BYTES 0x10
|
||||
#define RADIO_CRC_2_BYTES 0x20
|
||||
#define RADIO_CRC_3_BYTES 0x30
|
||||
|
||||
#define RADIO_WHITENING_ON 0x00
|
||||
#define RADIO_WHITENING_OFF 0x08
|
||||
|
||||
//End GFSK ****************************************************
|
||||
|
||||
|
||||
|
||||
//*************************************************************
|
||||
//FLRC modem settings
|
||||
//*************************************************************
|
||||
|
||||
#define FLRC_SYNC_NOSYNC 0x00
|
||||
#define FLRC_SYNC_WORD_LEN_P32S 0x04
|
||||
|
||||
#define FLRC_BR_1_300_BW_1_2 0x45 //1.3Mbs
|
||||
#define FLRC_BR_1_000_BW_1_2 0x69 //1.04Mbs
|
||||
#define FLRC_BR_0_650_BW_0_6 0x86 //0.65Mbs
|
||||
#define FLRC_BR_0_520_BW_0_6 0xAA //0.52Mbs
|
||||
#define FLRC_BR_0_325_BW_0_3 0xC7 //0.325Mbs
|
||||
#define FLRC_BR_0_260_BW_0_3 0xEB //0.26Mbs
|
||||
|
||||
#define FLRC_CR_1_2 0x00 //coding rate 1:2
|
||||
#define FLRC_CR_3_4 0x02 //coding rate 3:4
|
||||
#define FLRC_CR_1_0 0x04 //coding rate 1
|
||||
|
||||
#define BT_DIS 0x00 //No filtering
|
||||
#define BT_1 0x10 //1
|
||||
#define BT_0_5 0x20 //0.5
|
||||
|
||||
#define RADIO_MOD_SHAPING_BT_OFF 0x00
|
||||
#define RADIO_MOD_SHAPING_BT_1_0 0x10
|
||||
#define RADIO_MOD_SHAPING_BT_0_5 0x20
|
||||
|
||||
|
||||
//Table 13-45: PacketStatus2 in FLRC Packet
|
||||
#define PacketCtrlBusy 0x01
|
||||
#define PacketReceived 0x02
|
||||
#define HeaderReceived 0x04
|
||||
#define AbortError 0x08
|
||||
#define CrcError 0x10
|
||||
#define LengthError 0x20
|
||||
#define SyncError 0x40
|
||||
#define Reserved 0x80
|
||||
|
||||
|
||||
//Table 13-46: PacketStatus3 in FLRC Packet
|
||||
#define PktSent 0x01
|
||||
#define rxpiderr 0x08
|
||||
#define rx_no_ack 0x10
|
||||
|
||||
//FLRC default packetparamns
|
||||
#define FLRC_Default_AGCPreambleLength PREAMBLE_LENGTH_32_BITS //packetParam1
|
||||
#define FLRC_Default_SyncWordLength FLRC_SYNC_WORD_LEN_P32S //packetParam2
|
||||
#define FLRC_Default_SyncWordMatch RADIO_RX_MATCH_SYNCWORD_1 //packetParam3
|
||||
#define FLRC_Default_PacketType RADIO_PACKET_VARIABLE_LENGTH //packetParam4
|
||||
#define FLRC_Default_PayloadLength BUFFER_SIZE_DEFAULT //packetParam5
|
||||
#define FLRC_Default_CrcLength RADIO_CRC_3_BYTES //packetParam6
|
||||
#define FLRC_Default_Whitening RADIO_WHITENING_OFF //packetParam7
|
||||
|
||||
|
||||
//Table 11-15 Sleep modes
|
||||
#define RETAIN_INSTRUCTION_RAM 0x04
|
||||
#define RETAIN_DATABUFFER 0x02
|
||||
#define RETAIN_DATA_RAM 0x01
|
||||
#define CONFIGURATION_RETENTION 0x01 //included for libray compatibility
|
||||
#define RETAIN_None 0x00
|
||||
|
||||
|
||||
#ifndef RAMP_TIME
|
||||
#define RAMP_TIME RADIO_RAMP_02_US
|
||||
#endif
|
||||
|
||||
#ifndef PERIODBASE
|
||||
#define PERIODBASE PERIOBASE_01_MS
|
||||
#endif
|
||||
|
||||
#ifndef PERIODBASE_COUNT_15_8
|
||||
#define PERIODBASE_COUNT_15_8 0
|
||||
#endif
|
||||
|
||||
#ifndef PERIODBASE_COUNT_7_0
|
||||
#define PERIODBASE_COUNT_7_0 0
|
||||
#endif
|
||||
|
||||
|
||||
#define DEVICE_SX1280 0x20
|
||||
#define DEVICE_SX1281 0x21
|
||||
|
||||
|
||||
//SPI settings
|
||||
#define LTspeedMaximum 8000000
|
||||
#define LTdataOrder MSBFIRST
|
||||
#define LTdataMode SPI_MODE0
|
||||
|
||||
#define RANGING_VALID 0x03
|
||||
#define RANGING_TIMEOUT 0x02
|
||||
#define WAIT_RX 0x01
|
||||
#define WAIT_TX 0x01
|
||||
#define NO_WAIT 0x00
|
||||
|
||||
#define CalibrationSF10BW400 10180 //calibration value for ranging, SF10, BW400
|
||||
#define CalibrationSF5BW1600 13100 //calibration value for ranging, SF5, BW1600
|
||||
|
||||
|
||||
const uint16_t RNG_CALIB_0400[] = { 10260, 10244, 10228, 10212, 10196, 10180 }; //SF5 to SF10
|
||||
const uint16_t RNG_CALIB_0800[] = { 11380, 11370, 11360, 11350, 11340, 11330 };
|
||||
const uint16_t RNG_CALIB_1600[] = { 13100, 13160, 13220, 13280, 13340, 13400 };
|
||||
569
lib/SX12XX-LoRa/src/UBLOXI2CGPS.h
Normal file
569
lib/SX12XX-LoRa/src/UBLOXI2CGPS.h
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 27/06/20
|
||||
*/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - This is a library file for the UBLOX 6,7 and 8 series GPSs.
|
||||
|
||||
This GPS library file is designed for use with the GPSs I2C interface.
|
||||
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
//For use with I2C the configurations sent must be even numbers of bytes, thus the last byte in some cases may be a 0x00 padding byte
|
||||
const PROGMEM uint8_t ClearConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x19, 0x98, 0x00}; //22
|
||||
const PROGMEM uint8_t GLONASSOff[] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2}; //20
|
||||
const PROGMEM uint8_t GPGLLOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A}; //16
|
||||
const PROGMEM uint8_t GPGLSOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46}; //16
|
||||
const PROGMEM uint8_t GPGSAOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31}; //16
|
||||
const PROGMEM uint8_t GPGSVOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38}; //16
|
||||
const PROGMEM uint8_t GNSSmode[] = {0xB5, 0x62, 0x06, 0x3E, 0x2C, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x08, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x08, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0xFC, 0x11};
|
||||
|
||||
const PROGMEM uint8_t SetBalloonMode[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27,
|
||||
0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC}; //44
|
||||
const PROGMEM uint8_t SaveConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA9, 0x00}; //22
|
||||
const PROGMEM uint8_t PollNavigation[] = {0xB5, 0x62, 0x06, 0x24, 0x00, 0x00, 0x2A, 0x84}; //8
|
||||
const PROGMEM uint8_t SetCyclicMode[] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92}; //10
|
||||
const PROGMEM uint8_t SoftwareBackup[] = {0xB5, 0x62, 0x06, 0x57, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4B, 0x43, 0x42, 0x86, 0x46}; //16
|
||||
const PROGMEM uint8_t EnableI2C[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x92}; //28
|
||||
//const PROGMEM uint8_t PMREQBackup[] = {0xB5, 0x62, 0x02, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4D, 0x3B}; //16
|
||||
|
||||
uint8_t GPS_GetByte();
|
||||
void GPS_OutputOn();
|
||||
void GPS_OutputOff();
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state);
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state);
|
||||
bool GPS_Setup();
|
||||
bool GPS_SendConfig(unsigned int Progmem_ptr, byte length, byte replylength);
|
||||
bool GPS_WaitAck(unsigned long waitms, byte length);
|
||||
//uint8_t GPS_GetNextChar(uint32_t waitmS);
|
||||
//bool GPS_CheckAck();
|
||||
bool GPS_SetBalloonMode();
|
||||
bool GPS_CheckBalloonMode();
|
||||
bool GPS_ClearConfig();
|
||||
bool GPS_SetCyclicMode();
|
||||
bool GPS_SoftwareBackup();
|
||||
//bool GPS_HotStart();
|
||||
bool GPS_PollNavigation();
|
||||
bool GPS_SaveConfig();
|
||||
bool GPS_GLONASSOff();
|
||||
bool GPS_GPGLLOff();
|
||||
bool GPS_GPGLSOff();
|
||||
bool GPS_GPGSAOff();
|
||||
bool GPS_GPGSVOff();
|
||||
bool GPS_GNSSmode();
|
||||
bool GPS_GGARMCOnly();
|
||||
//void GPS_PMREQBackup();
|
||||
//void GPS_StartRead();
|
||||
//void GPS_SetGPMode();
|
||||
//void GPS_StopMessages();
|
||||
|
||||
const int16_t GPSI2CAddress = 0x42;
|
||||
const uint32_t GPS_WaitAck_mS = 1000; //number of mS to wait for an ACK response from GPS
|
||||
const uint8_t GPS_attempts = 5; //number of times the sending of GPS config will be attempted.
|
||||
const uint8_t GPS_Reply_Size = 16; //size of GPS reply buffer
|
||||
const uint16_t GPS_Clear_DelaymS = 2000; //mS to wait after a GPS Clear command is sent
|
||||
uint8_t GPS_Reply[GPS_Reply_Size]; //byte array for storing GPS reply to UBX commands
|
||||
|
||||
|
||||
#define USING_I2CGPS //so the rest of the program knows I2C GPS is in use
|
||||
#define UBLOX //so the rest of the program knows UBLOX GPS is in use
|
||||
//#define GPSDEBUG //include define to see some debug messages
|
||||
|
||||
|
||||
|
||||
uint8_t GPS_GetByte() //get and process output from GPS
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
|
||||
Wire.requestFrom(GPSI2CAddress, 1);
|
||||
GPSchar = Wire.read();
|
||||
|
||||
return GPSchar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GPS_OutputOn()
|
||||
{
|
||||
//not used function for I2C library, included for compatibility with other libraries
|
||||
}
|
||||
|
||||
|
||||
void GPS_OutputOff()
|
||||
{
|
||||
//not used function for I2C library, included for compatibility with other libraries
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void GPS_StartRead()
|
||||
{
|
||||
Wire.beginTransmission(GPSI2CAddress);
|
||||
Wire.write(0xFF);
|
||||
}
|
||||
*/
|
||||
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOn() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOff() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitAck(uint32_t waitmS, uint8_t length)
|
||||
{
|
||||
//wait for Ack from GPS
|
||||
byte i, j;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
|
||||
byte ptr = 0; //used as pointer to store GPS reply
|
||||
|
||||
Wire.beginTransmission(GPSI2CAddress);
|
||||
Wire.write(0xFF);
|
||||
|
||||
do
|
||||
{
|
||||
Wire.requestFrom(GPSI2CAddress, 1);
|
||||
i = Wire.read();
|
||||
}
|
||||
while ((i != 0xb5) && ((uint32_t) (millis() - startmS) < waitmS));
|
||||
|
||||
if (i != 0xb5)
|
||||
{
|
||||
Serial.print(F("Timeout "));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("Ack "));
|
||||
Serial.print(i, HEX);
|
||||
|
||||
length--;
|
||||
|
||||
for (j = 1; j <= length; j++)
|
||||
{
|
||||
Serial.print(F(" "));
|
||||
|
||||
Wire.requestFrom(GPSI2CAddress, 1);
|
||||
i = Wire.read();
|
||||
|
||||
if (j < 12)
|
||||
{
|
||||
GPS_Reply[ptr++] = i; //save reply in buffer, but no more than 10 characters
|
||||
}
|
||||
|
||||
if (i < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(i, HEX);
|
||||
}
|
||||
|
||||
}
|
||||
Serial.println();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts)
|
||||
{
|
||||
uint8_t byteread1, byteread2, index, length;
|
||||
uint8_t config_attempts = attempts;
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
if (config_attempts == 0)
|
||||
{
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
length = arraysize / 2; //we are sending messages 2 bytes at a time
|
||||
|
||||
for (index = 0; index < length; index++)
|
||||
{
|
||||
byteread1 = pgm_read_byte_near(Progmem_ptr++); //we will read and write 2 bytes at a time
|
||||
byteread2 = pgm_read_byte_near(Progmem_ptr++);
|
||||
Wire.beginTransmission(GPSI2CAddress);
|
||||
Wire.write(byteread1);
|
||||
Wire.write(byteread2);
|
||||
Wire.endTransmission();
|
||||
if (byteread1 < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(byteread1, HEX);
|
||||
Serial.print(F(" "));
|
||||
if (byteread2 < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(byteread2, HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //put Progmem_ptr back to start value in case we need to re-send the config
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (replylength == 0)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("Reply not required"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
config_attempts--;
|
||||
} while (!GPS_WaitAck(GPS_WaitAck_mS, replylength));
|
||||
|
||||
delay(50); //GPS can sometimes be a bit slow getting ready for next config
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_Setup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("GPS_Setup()"));
|
||||
#endif
|
||||
/*
|
||||
Wire.begin();
|
||||
GPS_ClearConfig();
|
||||
GPS_StopMessages();
|
||||
GPS_SetBalloonMode();
|
||||
GPS_SaveConfig();
|
||||
*/
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (!GPS_ClearConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SetBalloonMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GNSSmode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGLLOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGLSOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGSAOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGSVOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SaveConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("GPS_CheckBalloonMode()"));
|
||||
#endif
|
||||
|
||||
uint8_t j;
|
||||
|
||||
GPS_Reply[7] = 0xff;
|
||||
|
||||
GPS_PollNavigation();
|
||||
|
||||
j = GPS_Reply[7];
|
||||
|
||||
Serial.print(F("Dynamic Model is "));
|
||||
Serial.println(j);
|
||||
|
||||
if (j != 6)
|
||||
{
|
||||
Serial.println(F("Dynamic Model 6 not Set !"));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GPS_ClearConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("GPS_ClearConfig()"));
|
||||
#endif
|
||||
|
||||
Serial.println(F("ClearConfig"));
|
||||
size_t SIZE = sizeof(ClearConfig);
|
||||
|
||||
if (!GPS_SendConfig(ClearConfig,SIZE,10,GPS_attempts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.println(F("Wait clear"));
|
||||
delay(GPS_Clear_DelaymS); //wait a while for GPS to clear its settings
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void GPS_StopMessages()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS GPGLLOff "));
|
||||
#endif
|
||||
|
||||
size_t SIZE;
|
||||
|
||||
SIZE = sizeof(GPGLLOff);
|
||||
GPS_SendConfig(GPGLLOff, SIZE, 10, GPS_attempts);
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS GPGLSOff "));
|
||||
#endif
|
||||
|
||||
SIZE = sizeof(GPGLSOff);
|
||||
GPS_SendConfig(GPGLSOff, SIZE, 10, GPS_attempts);
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS GPGSAOff "));
|
||||
#endif
|
||||
|
||||
SIZE = sizeof(GPGSAOff);
|
||||
GPS_SendConfig(GPGSAOff, SIZE, 10, GPS_attempts);
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS GPGSVOff "));
|
||||
#endif
|
||||
|
||||
SIZE = sizeof(GPGSVOff);
|
||||
GPS_SendConfig(GPGSVOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
*/
|
||||
|
||||
bool GPS_SetBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS SetBalloonMode "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SetBalloonMode);
|
||||
return GPS_SendConfig(SetBalloonMode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SaveConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SaveConfig()"));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SaveConfig);
|
||||
return GPS_SendConfig(SaveConfig, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_PollNavigation()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PollNavigation()"));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(PollNavigation);
|
||||
return GPS_SendConfig(PollNavigation, SIZE, 44, GPS_attempts);
|
||||
}
|
||||
|
||||
/*
|
||||
void GPS_SetGPMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetGPMode()"));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SetCyclicMode);
|
||||
GPS_SendConfig(SetCyclicMode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
*/
|
||||
|
||||
bool GPS_SetCyclicMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetCyclicMode() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SetCyclicMode"));
|
||||
size_t SIZE = sizeof(SetCyclicMode);
|
||||
|
||||
return GPS_SendConfig(SetCyclicMode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SoftwareBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SoftwareBackup()"));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(SoftwareBackup);
|
||||
return GPS_SendConfig(SoftwareBackup, SIZE, 0, GPS_attempts);
|
||||
}
|
||||
|
||||
/*
|
||||
void GPS_PMREQBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PMREQBackup()"));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(PMREQBackup);
|
||||
GPS_SendConfig(PMREQBackup, SIZE, 0, GPS_attempts);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
bool GPS_GLONASSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GLONASSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GLONASSOff);
|
||||
return GPS_SendConfig(GLONASSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLLOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLLOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLLOff);
|
||||
return GPS_SendConfig(GPGLLOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLSOff);
|
||||
return GPS_SendConfig(GPGLSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSAOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSAOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSAOff);
|
||||
return GPS_SendConfig(GPGSAOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSVOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSVOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSVOff);
|
||||
return GPS_SendConfig(GPGSVOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GNSSmode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GNSSmode() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GNSSmode);
|
||||
return GPS_SendConfig(GNSSmode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GGARMCOnly()
|
||||
{
|
||||
//null function, not used with Ublox library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
690
lib/SX12XX-LoRa/src/UBLOXSerialGPS.h
Normal file
690
lib/SX12XX-LoRa/src/UBLOXSerialGPS.h
Normal file
@@ -0,0 +1,690 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 27/06/20
|
||||
*/
|
||||
|
||||
/*******************************************************************************************************
|
||||
Program Operation - This is a library file for the UBLOX 6,7 and 8 series GPSs.
|
||||
|
||||
The routines assume that the GPS has been setup on GPSserial which could be either software serial or
|
||||
hardware serial. This library file can be used with both Hardware serial and SoftwareSerial. The
|
||||
configuration of the GPS prints debug output to the Serial console and mixing thisdebug output with
|
||||
the use of software serial has required several optimistations, in particular tha the GPS serial
|
||||
output is turned off at some points in the configuration process to allow prints to the serial monitor
|
||||
to continue without interruption or missed characters, see the post below for details on the problem;
|
||||
|
||||
https://stuartsprojects.github.io/2020/05/05/softwareserial-problems.html
|
||||
|
||||
The library assumes that the GPS is connected onto a port named GPSserial, this is achived in software
|
||||
serial with;
|
||||
|
||||
SoftwareSerial GPSserial(RXpin, TXpin);
|
||||
|
||||
And for hardware serial, assuming Serila2 is used for the GPS with;
|
||||
|
||||
#define GPSserial Serial2
|
||||
|
||||
The calling program should also include a define for the GPS baud rate as follows;
|
||||
|
||||
#define GPSBaud 9600
|
||||
|
||||
If this define is missing then 9600 baud is assumed
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
const PROGMEM uint8_t ClearConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x19, 0x98}; //21
|
||||
const PROGMEM uint8_t SetBalloonMode[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05,
|
||||
0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC
|
||||
}; //44
|
||||
const PROGMEM uint8_t SaveConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA9}; //22
|
||||
const PROGMEM uint8_t SetCyclicMode[] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92}; //10
|
||||
const PROGMEM uint8_t SoftwareBackup[] = {0xB5, 0x62, 0x02, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4D, 0x3B}; //16
|
||||
const PROGMEM uint8_t PollNavigation[] = {0xB5, 0x62, 0x06, 0x24, 0x00, 0x00, 0x2A, 0x84}; //8
|
||||
|
||||
//B5 62 06 57 08 00 01 00 00 00 50 4B 43 42 86 46
|
||||
|
||||
//these are the commands to turn off NMEA sentences
|
||||
const PROGMEM uint8_t GLONASSOff[] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2}; //20
|
||||
const PROGMEM uint8_t GPGLLOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A}; //16
|
||||
const PROGMEM uint8_t GPGLSOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46}; //16
|
||||
const PROGMEM uint8_t GPGSAOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31}; //16
|
||||
const PROGMEM uint8_t GPGSVOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38}; //16
|
||||
|
||||
const PROGMEM uint8_t GNSSmode[] = {0xB5, 0x62, 0x06, 0x3E, 0x2C, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x08, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x08, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0xFC, 0x11};
|
||||
|
||||
//response to PollNavigation should be B5 62 06 24 24 00 FF FF 06 03
|
||||
//accepted response to configuaration command should be UBX-ACK-ACK B5 62 05 01
|
||||
//fail response to configuaration command should be UBX-ACK-NAK B5 62 05 00
|
||||
|
||||
uint8_t GPS_GetByte();
|
||||
void GPS_OutputOn();
|
||||
void GPS_OutputOff();
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state);
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state);
|
||||
bool GPS_Setup();
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts);
|
||||
bool GPS_WaitAck(uint32_t waitms, uint8_t length);
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS);
|
||||
//uint8_t GPS_GetNextChar(uint32_t waitmS);
|
||||
bool GPS_CheckAck();
|
||||
bool GPS_SetBalloonMode();
|
||||
bool GPS_CheckBalloonMode();
|
||||
bool GPS_ClearConfig();
|
||||
bool GPS_SetCyclicMode();
|
||||
bool GPS_SoftwareBackup();
|
||||
bool GPS_HotStart();
|
||||
bool GPS_PollNavigation();
|
||||
bool GPS_SaveConfig();
|
||||
bool GPS_GLONASSOff();
|
||||
bool GPS_GPGLLOff();
|
||||
bool GPS_GPGLSOff();
|
||||
bool GPS_GPGSAOff();
|
||||
bool GPS_GPGSVOff();
|
||||
bool GPS_GNSSmode();
|
||||
bool GPS_GGARMCOnly();
|
||||
|
||||
const uint32_t GPS_WaitAck_mS = 1000; //number of mS to wait for an ACK response from GPS
|
||||
const uint8_t GPS_attempts = 10; //number of times the sending of GPS config will be attempted.
|
||||
const uint8_t GPS_Reply_Size = 16; //size of GPS reply buffer
|
||||
const uint16_t GPS_Clear_DelaymS = 2000; //mS to wait after a GPS Clear command is sent
|
||||
uint8_t GPS_Reply[GPS_Reply_Size]; //byte array for storing GPS reply to UBX commands
|
||||
|
||||
|
||||
#define UBLOXINUSE //so complier can know which GPS library is used
|
||||
//#define GPSDebug
|
||||
|
||||
#ifndef GPSBaud
|
||||
#define GPSBaud 9600
|
||||
#endif
|
||||
|
||||
|
||||
void GPS_OutputOn()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_On() "));
|
||||
#endif
|
||||
uint8_t GPSchar = 0;
|
||||
//turns on serial output from GPS
|
||||
GPSserial.begin(GPSBaud);
|
||||
GPSserial.write(GPSchar);
|
||||
}
|
||||
|
||||
|
||||
void GPS_OutputOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Off() "));
|
||||
#endif
|
||||
|
||||
GPSserial.end(); //turns off serial output from GPS
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOn() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOff() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_Setup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Setup() "));
|
||||
#endif
|
||||
|
||||
if (!GPS_ClearConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SetBalloonMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GNSSmode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGLLOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGLSOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGSAOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_GPGSVOff())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SaveConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckBalloonMode()
|
||||
{
|
||||
//navigation model setting for UBLOX is at GPS_Reply[8] of poll request reply.
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckBalloonMode() "));
|
||||
#endif
|
||||
|
||||
uint8_t j;
|
||||
GPS_Reply[8] = 0xff;
|
||||
|
||||
GPS_PollNavigation();
|
||||
|
||||
if ( (GPS_Reply[0] == 0xB5) && (GPS_Reply[1] == 0x62) && (GPS_Reply[2] == 0x06) && (GPS_Reply[3] == 0X24) )
|
||||
{
|
||||
j = GPS_Reply[8];
|
||||
|
||||
if (j == 6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SendConfig() "));
|
||||
#endif
|
||||
|
||||
uint8_t byteread, index;
|
||||
uint8_t config_attempts = attempts;
|
||||
|
||||
Serial.flush(); //ensure there are no pending interrupts from serial monitor printing
|
||||
|
||||
do
|
||||
{
|
||||
if (config_attempts == 0)
|
||||
{
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
GPS_OutputOff();
|
||||
|
||||
Serial.print(F("GPSSend "));
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
if (byteread < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
Serial.print(byteread, HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
|
||||
Serial.flush(); //make sure serial out buffer is empty
|
||||
|
||||
GPS_OutputOn();
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
GPSserial.write(byteread);
|
||||
}
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
if (replylength == 0)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("Reply not required"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
GPSserial.flush(); //make sure all of config command has been sent
|
||||
config_attempts--;
|
||||
}
|
||||
while (!GPS_WaitAck(GPS_WaitAck_mS, replylength));
|
||||
|
||||
Serial.println(F("OK"));
|
||||
Serial.println();
|
||||
delay(100); //GPS can sometimes be a bit slow getting ready for next config
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitAck(uint32_t waitmS, uint8_t length)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_WaitAck() "));
|
||||
Serial.print(F(" Reply length "));
|
||||
Serial.print(length);
|
||||
Serial.print(F(" "));
|
||||
#endif
|
||||
|
||||
//wait for Ack (UBX-ACK-ACK) response from GPS is 0xb5,0x62, 0x05, 0x01
|
||||
//Nack (UBX-ACK-NAK) response from GPS is 0xb5,0x62, 0x05, 0x00
|
||||
|
||||
uint8_t GPSchar;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
|
||||
uint8_t ptr = 0; //used as pointer to store GPS reply
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Received "));
|
||||
Serial.flush();
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
}
|
||||
}
|
||||
while ((GPSchar != 0xb5) && ((uint32_t) (millis() - startmS) < waitmS)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
|
||||
if (GPSchar != 0xb5)
|
||||
{
|
||||
Serial.println(F("Timeout Error"));
|
||||
return false;
|
||||
}
|
||||
|
||||
GPS_Reply[ptr++] = 0xB5; //test if a 0xB5 has been received
|
||||
|
||||
startmS = millis();
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPS_Reply[ptr++] = GPSserial.read();
|
||||
}
|
||||
}
|
||||
while ((ptr < length) && ((uint32_t) (millis() - startmS) < waitmS)); //fill buffer, stop when either ptr is (length-1) or timeout
|
||||
|
||||
|
||||
if (ptr < length)
|
||||
{
|
||||
Serial.print(F("Short Reply Error"));
|
||||
return false;
|
||||
}
|
||||
|
||||
GPS_OutputOff();
|
||||
|
||||
for (ptr = 0; ptr < length; ptr++)
|
||||
{
|
||||
GPSchar = GPS_Reply[ptr];
|
||||
|
||||
if (GPSchar < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
|
||||
Serial.print(GPSchar , HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (GPS_CheckAck())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitChar(uint8_t waitforchar, uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
uint32_t startmS;
|
||||
|
||||
startmS = millis();
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
if (GPSchar == waitforchar)
|
||||
{
|
||||
GPS_Reply[0] = GPSchar;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
while ((uint32_t) (millis() - startmS) < waitmS); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
uint8_t GPS_GetNextChar(uint32_t waitmS)
|
||||
{
|
||||
uint8_t GPSchar;
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
GPS_Reply[1] = GPSchar;
|
||||
return GPSchar;
|
||||
}
|
||||
}
|
||||
while ((millis() < waitmS)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
return '*';
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
bool GPS_PollNavigation()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PollNavigation() "));
|
||||
#endif
|
||||
//Serial.println(F("PollNavigation"));
|
||||
size_t SIZE = sizeof(PollNavigation);
|
||||
if (GPS_SendConfig(PollNavigation, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_CheckAck()
|
||||
{
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckAck() "));
|
||||
#endif
|
||||
|
||||
if ((GPS_Reply[0] == 0xB5) && (GPS_Reply[1] == 0x62))
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F(" UBX-ACK-ACK"));
|
||||
#endif
|
||||
return true; //there has been a UBX-ACK-ACK response
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F(" Not UBX-ACK-ACK "));
|
||||
#endif
|
||||
return false; //there has been a UBX-ACK-ACK response
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
// GPS configuration commands
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
bool GPS_ClearConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_ClearConfig() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("ClearConfig"));
|
||||
size_t SIZE = sizeof(ClearConfig);
|
||||
if (GPS_SendConfig(ClearConfig, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
Serial.println(F("Wait clear"));
|
||||
Serial.println();
|
||||
delay(GPS_Clear_DelaymS); //wait a while for GPS to clear its settings
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetBalloonMode() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("SetBalloonMode"));
|
||||
size_t SIZE = sizeof(SetBalloonMode);
|
||||
if (GPS_SendConfig(SetBalloonMode, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SaveConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SaveConfig() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("SaveConfig"));
|
||||
size_t SIZE = sizeof(SaveConfig);
|
||||
|
||||
if (GPS_SendConfig(SaveConfig, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetCyclicMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetCyclicMode() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("SetCyclicMode"));
|
||||
size_t SIZE = sizeof(SetCyclicMode);
|
||||
|
||||
if (GPS_SendConfig(SetCyclicMode, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SoftwareBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SoftwareBackup() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("SoftwareBackup"));
|
||||
size_t SIZE = sizeof(SoftwareBackup);
|
||||
|
||||
if (GPS_SendConfig(SoftwareBackup, SIZE, 0, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_HotStart()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_HotStart() "));
|
||||
#endif
|
||||
|
||||
//Serial.println(F("HotStart"));
|
||||
GPSserial.println();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_GLONASSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GLONASSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GLONASSOff);
|
||||
return GPS_SendConfig(GLONASSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLLOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLLOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLLOff);
|
||||
return GPS_SendConfig(GPGLLOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLSOff);
|
||||
return GPS_SendConfig(GPGLSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSAOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSAOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSAOff);
|
||||
return GPS_SendConfig(GPGSAOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSVOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSVOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSVOff);
|
||||
return GPS_SendConfig(GPGSVOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GNSSmode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GNSSmode() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GNSSmode);
|
||||
return GPS_SendConfig(GNSSmode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetByte() //get a byte for GPS
|
||||
{
|
||||
if (GPSserial.available() == 0)
|
||||
{
|
||||
return 0xFF; //for compatibility with I2C reading of GPS
|
||||
}
|
||||
else
|
||||
{
|
||||
return GPSserial.read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GGARMCOnly()
|
||||
{
|
||||
//null function, not used with Ublox library
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
580
lib/SX12XX-LoRa/src/UBLOX_HWSerialGPS.h
Normal file
580
lib/SX12XX-LoRa/src/UBLOX_HWSerialGPS.h
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
Copyright 2020 - Stuart Robinson
|
||||
Licensed under a MIT license displayed at the bottom of this document.
|
||||
Original published 07/08/20
|
||||
*/
|
||||
|
||||
const PROGMEM uint8_t ClearConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0x19, 0x98}; //21
|
||||
const PROGMEM uint8_t SetBalloonMode[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05,
|
||||
0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC
|
||||
}; //44
|
||||
const PROGMEM uint8_t SaveConfig[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA9}; //22
|
||||
const PROGMEM uint8_t SetCyclicMode[] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92}; //10
|
||||
const PROGMEM uint8_t SoftwareBackup[] = {0xB5, 0x62, 0x02, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4D, 0x3B}; //16
|
||||
const PROGMEM uint8_t PollNavigation[] = {0xB5, 0x62, 0x06, 0x24, 0x00, 0x00, 0x2A, 0x84}; //8
|
||||
|
||||
//these are the commands to turn off NMEA sentences
|
||||
const PROGMEM uint8_t GLONASSOff[] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2}; //20
|
||||
const PROGMEM uint8_t GPGLLOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A}; //16
|
||||
const PROGMEM uint8_t GPGLSOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46}; //16
|
||||
const PROGMEM uint8_t GPGSAOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31}; //16
|
||||
const PROGMEM uint8_t GPGSVOff[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38}; //16
|
||||
const PROGMEM uint8_t GNSSmode[] = {0xB5, 0x62, 0x06, 0x3E, 0x2C, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x08, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x08, 0x0E, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0xFC, 0x11};
|
||||
|
||||
//response to PollNavigation should be B5 62 06 24 24 00 FF FF 06 03
|
||||
//accepted response to configuaration command should be UBX-ACK-ACK B5 62 05 01
|
||||
//fail response to configuaration command should be UBX-ACK-NAK B5 62 05 00
|
||||
|
||||
void GPS_OutputOn();
|
||||
void GPS_OutputOff();
|
||||
void GPS_PowerOn();
|
||||
bool GPS_CheckConfiguration();
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts);
|
||||
bool GPS_WaitAck(uint32_t waitms, uint8_t length);
|
||||
bool GPS_PollNavigation();
|
||||
|
||||
bool GPS_ClearConfig();
|
||||
bool GPS_SaveConfig();
|
||||
bool GPS_SetBalloonMode();
|
||||
bool GPS_SetCyclicMode();
|
||||
bool GPS_SoftwareBackup();
|
||||
bool GPS_GLONASSOff();
|
||||
bool GPS_GPGLLOff();
|
||||
bool GPS_GPGLSOff();
|
||||
bool GPS_GPGSAOff();
|
||||
bool GPS_GPGSVOff();
|
||||
bool GPS_GNSSmode();
|
||||
bool GPS_CheckAck();
|
||||
uint8_t GPS_GetByte();
|
||||
|
||||
|
||||
const uint32_t GPS_WaitAck_mS = 1000; //number of mS to wait for an ACK response from GPS
|
||||
const uint8_t GPS_attempts = 5; //number of times the sending of GPS config will be attempted.
|
||||
const uint8_t GPS_Reply_Size = 16; //size of GPS reply buffer
|
||||
const uint16_t GPS_Clear_DelaymS = 2000; //mS to wait after a GPS Clear command is sent
|
||||
uint8_t GPS_Reply[GPS_Reply_Size]; //byte array for storing GPS reply to UBX commands
|
||||
|
||||
|
||||
#define UBLOXINUSE //so complier can know which GPS library is used
|
||||
//#define GPSDebug
|
||||
|
||||
#ifndef GPSConfigSerial // if GPSDebugSerial is not defined set to Serial as default
|
||||
#define GPSConfigSerial Serial
|
||||
#endif
|
||||
|
||||
#ifndef GPSDebugSerial // if GPSDebugSerial is not defined set to Serial as default
|
||||
#define GPSDebugSerial Serial
|
||||
#endif
|
||||
|
||||
#ifndef GPSBaud
|
||||
#define GPSBaud 9600
|
||||
#endif
|
||||
|
||||
|
||||
void GPS_OutputOn()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_On() "));
|
||||
#endif
|
||||
uint8_t GPSchar = 0;
|
||||
//turns on serial output from GPS
|
||||
GPSserial.begin(GPSBaud);
|
||||
GPSserial.write(GPSchar);
|
||||
}
|
||||
|
||||
|
||||
void GPS_OutputOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Off() "));
|
||||
#endif
|
||||
|
||||
GPSserial.end(); //turns off serial output from GPS
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOn(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOn() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GPS_PowerOff(int8_t pin, uint8_t state)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PowerOff() "));
|
||||
#endif
|
||||
|
||||
if (pin >= 0)
|
||||
{
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_Setup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_Setup() "));
|
||||
#endif
|
||||
|
||||
if (!GPS_ClearConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SetBalloonMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_CheckConfiguration())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GPS_SaveConfig())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_CheckConfiguration()
|
||||
{
|
||||
//navigation model setting for UBLOX is at GPS_Reply[8] of poll request reply.
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckConfiguration() UBLOX "));
|
||||
#endif
|
||||
|
||||
uint8_t j;
|
||||
GPS_Reply[8] = 0xff;
|
||||
|
||||
GPS_PollNavigation();
|
||||
|
||||
if ( (GPS_Reply[0] == 0xB5) && (GPS_Reply[1] == 0x62) && (GPS_Reply[2] == 0x06) && (GPS_Reply[3] == 0X24) )
|
||||
{
|
||||
j = GPS_Reply[8];
|
||||
|
||||
if (j == 6)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SendConfig(const uint8_t *Progmem_ptr, uint8_t arraysize, uint8_t replylength, uint8_t attempts)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SendConfig() "));
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
uint8_t byteread, index;
|
||||
uint8_t config_attempts = attempts;
|
||||
|
||||
Serial.flush(); //ensure there are no pending interrupts from serial monitor printing
|
||||
|
||||
do
|
||||
{
|
||||
if (config_attempts == 0)
|
||||
{
|
||||
Serial.println(F("Fail"));
|
||||
Serial.println();
|
||||
return false;
|
||||
}
|
||||
|
||||
Serial.print(F("GPSSend "));
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
Serial.print(byteread, HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
|
||||
Serial.flush(); //make sure serial out buffer is empty
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
for (index = 0; index < arraysize; index++)
|
||||
{
|
||||
byteread = pgm_read_byte_near(Progmem_ptr++);
|
||||
GPSserial.write(byteread);
|
||||
}
|
||||
|
||||
Progmem_ptr = Progmem_ptr - arraysize; //set Progmem_ptr back to start
|
||||
|
||||
if (replylength == 0)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F("Reply not required"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
config_attempts--;
|
||||
}
|
||||
while (!GPS_WaitAck(GPS_WaitAck_mS, replylength));
|
||||
|
||||
Serial.println(F("OK"));
|
||||
Serial.println();
|
||||
delay(100); //GPS can sometimes be a bit slow getting ready for next config
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_WaitAck(uint32_t waitms, uint8_t length)
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_WaitAck() "));
|
||||
Serial.print(F(" Reply length "));
|
||||
Serial.print(length);
|
||||
Serial.print(F(" "));
|
||||
#endif
|
||||
|
||||
//wait for Ack (UBX-ACK-ACK) response from GPS is 0xb5,0x62, 0x05, 0x01
|
||||
//Nack (UBX-ACK-NAK) response from GPS is 0xb5,0x62, 0x05, 0x00
|
||||
|
||||
uint8_t GPSchar;
|
||||
|
||||
uint32_t endms;
|
||||
endms = millis() + waitms;
|
||||
uint8_t ptr = 0; //used as pointer to store GPS reply
|
||||
|
||||
Serial.println();
|
||||
Serial.print(F("Received "));
|
||||
Serial.flush();
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPSchar = GPSserial.read();
|
||||
}
|
||||
}
|
||||
while ((GPSchar != 0xb5) && (millis() < endms)); //use the timeout to ensure a lack of GPS does not cause the program to hang
|
||||
|
||||
if (GPSchar != 0xb5)
|
||||
{
|
||||
Serial.println(F("Timeout Error"));
|
||||
return false;
|
||||
}
|
||||
|
||||
GPS_Reply[ptr++] = 0xB5; //test if a 0xB5 has been received
|
||||
|
||||
do
|
||||
{
|
||||
if (GPSserial.available())
|
||||
{
|
||||
GPS_Reply[ptr++] = GPSserial.read();
|
||||
}
|
||||
}
|
||||
while ((ptr < length) || (millis() >= endms)); //fill buffer, stop when either ptr is (length-1) or timeout
|
||||
|
||||
|
||||
if (millis() >= endms) //check for another timeout
|
||||
{
|
||||
Serial.print(F("NoReply Error"));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ptr = 0; ptr < length; ptr++)
|
||||
{
|
||||
GPSchar = GPS_Reply[ptr];
|
||||
|
||||
if (GPSchar < 0x10)
|
||||
{
|
||||
Serial.print(F("0"));
|
||||
}
|
||||
|
||||
Serial.print(GPSchar , HEX);
|
||||
Serial.print(F(" "));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
|
||||
if (GPS_CheckAck())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_PollNavigation()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_PollNavigation() "));
|
||||
#endif
|
||||
Serial.println(F("PollNavigation"));
|
||||
size_t SIZE = sizeof(PollNavigation);
|
||||
if (GPS_SendConfig(PollNavigation, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool GPS_CheckAck()
|
||||
{
|
||||
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_CheckAck() "));
|
||||
#endif
|
||||
|
||||
if ((GPS_Reply[0] == 0xB5) && (GPS_Reply[1] == 0x62))
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F(" UBX-ACK-ACK"));
|
||||
#endif
|
||||
return true; //there has been a UBX-ACK-ACK response
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.println(F(" Not UBX-ACK-ACK "));
|
||||
#endif
|
||||
return false; //there has been a UBX-ACK-ACK response
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
// GPS configuration commands
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
bool GPS_ClearConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_ClearConfig() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("ClearConfig"));
|
||||
size_t SIZE = sizeof(ClearConfig);
|
||||
if (GPS_SendConfig(ClearConfig, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
Serial.println(F("Wait clear"));
|
||||
Serial.println();
|
||||
delay(GPS_Clear_DelaymS); //wait a while for GPS to clear its settings
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetBalloonMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetBalloonMode() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SetBalloonMode"));
|
||||
size_t SIZE = sizeof(SetBalloonMode);
|
||||
if (GPS_SendConfig(SetBalloonMode, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SaveConfig()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SaveConfig() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SaveConfig"));
|
||||
size_t SIZE = sizeof(SaveConfig);
|
||||
|
||||
if (GPS_SendConfig(SaveConfig, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SetCyclicMode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SetCyclicMode() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SetCyclicMode"));
|
||||
size_t SIZE = sizeof(SetCyclicMode);
|
||||
|
||||
if (GPS_SendConfig(SetCyclicMode, SIZE, 10, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_SoftwareBackup()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_SoftwareBackup() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("SoftwareBackup"));
|
||||
size_t SIZE = sizeof(SoftwareBackup);
|
||||
|
||||
if (GPS_SendConfig(SoftwareBackup, SIZE, 0, GPS_attempts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool GPS_HotStart()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_HotStart() "));
|
||||
#endif
|
||||
|
||||
Serial.println(F("HotStart"));
|
||||
GPSserial.println();
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GLONASSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GLONASSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GLONASSOff);
|
||||
return GPS_SendConfig(GLONASSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLLOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLLOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLLOff);
|
||||
return GPS_SendConfig(GPGLLOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGLSOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGLSOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGLSOff);
|
||||
return GPS_SendConfig(GPGLSOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSAOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSAOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSAOff);
|
||||
return GPS_SendConfig(GPGSAOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GPGSVOff()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GPGSVOff() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GPGSVOff);
|
||||
return GPS_SendConfig(GPGSVOff, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
bool GPS_GNSSmode()
|
||||
{
|
||||
#ifdef GPSDebug
|
||||
Serial.print(F("GPS_GNSSmode() "));
|
||||
#endif
|
||||
|
||||
size_t SIZE = sizeof(GNSSmode);
|
||||
return GPS_SendConfig(GNSSmode, SIZE, 10, GPS_attempts);
|
||||
}
|
||||
|
||||
|
||||
uint8_t GPS_GetByte() //get a byte for GPS
|
||||
{
|
||||
if (GPSserial.available() == 0)
|
||||
{
|
||||
return 0xFF; //for compatibility with I2C reading of GPS
|
||||
}
|
||||
else
|
||||
{
|
||||
return GPSserial.read();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
MIT license
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user