mirror of
https://github.com/sandeepmistry/arduino-LoRa.git
synced 2025-04-20 23:47:47 +03:00
Add initial library source
This commit is contained in:
parent
e4f8b513dd
commit
038378c139
260
src/LoRa.cpp
Normal file
260
src/LoRa.cpp
Normal file
@ -0,0 +1,260 @@
|
||||
#include <LoRa.h>
|
||||
|
||||
// registers
|
||||
#define REG_FIFO 0x00
|
||||
#define REG_OP_MODE 0x01
|
||||
#define REG_FRF_MSB 0x06
|
||||
#define REG_FRF_MID 0x07
|
||||
#define REG_FRF_LSB 0x08
|
||||
#define REG_FIFO_ADDR_PTR 0x0d
|
||||
#define REG_FIFO_TX_BASE_ADDR 0x0e
|
||||
#define REG_FIFO_RX_BASE_ADDR 0x0f
|
||||
#define REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define REG_IRQ_FLAGS 0x12
|
||||
#define REG_RX_NB_BYTES 0x13
|
||||
#define REG_PKT_RSSI_VALUE 0x1a
|
||||
#define REG_PAYLOAD_LENGTH 0x22
|
||||
#define REG_VERSION 0x42
|
||||
|
||||
// modes
|
||||
#define MODE_LONG_RANGE_MODE 0x80
|
||||
#define MODE_SLEEP 0x00
|
||||
#define MODE_STDBY 0x01
|
||||
#define MODE_TX 0x03
|
||||
#define MODE_RX_SINGLE 0x06
|
||||
|
||||
// IRQ masks
|
||||
#define IRQ_TX_DONE_MASK 0x08
|
||||
#define IRQ_RX_DONE_MASK 0x40
|
||||
|
||||
#define MAX_PKT_LENGTH 255
|
||||
|
||||
LoRaClass::LoRaClass() :
|
||||
_spiSettings(10E6, MSBFIRST, SPI_MODE0),
|
||||
_ss(10), _reset(9),
|
||||
_packetIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
int LoRaClass::begin(long frequency)
|
||||
{
|
||||
// setup pins
|
||||
pinMode(_ss, OUTPUT);
|
||||
pinMode(_reset, OUTPUT);
|
||||
|
||||
// perform reset
|
||||
digitalWrite(_reset, LOW);
|
||||
delay(10);
|
||||
digitalWrite(_reset, HIGH);
|
||||
delay(10);
|
||||
|
||||
// set SS high
|
||||
digitalWrite(_ss, HIGH);
|
||||
|
||||
// start SPI
|
||||
SPI.begin();
|
||||
|
||||
// check version
|
||||
uint8_t version = readRegister(REG_VERSION);
|
||||
if (version != 0x12) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// put in sleep mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
|
||||
|
||||
// set frequency
|
||||
uint64_t frf = ((uint64_t)frequency << 19) / 32000000;
|
||||
writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16));
|
||||
writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8));
|
||||
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
|
||||
|
||||
// set base addresses
|
||||
writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
|
||||
writeRegister(REG_FIFO_RX_BASE_ADDR, 0);
|
||||
|
||||
// put in standby mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LoRaClass::end()
|
||||
{
|
||||
// put in sleep mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
|
||||
|
||||
// stop SPI
|
||||
SPI.end();
|
||||
}
|
||||
|
||||
int LoRaClass::beginPacket()
|
||||
{
|
||||
// put in standby mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
|
||||
|
||||
// reset FIFO address and paload length
|
||||
writeRegister(REG_FIFO_ADDR_PTR, 0);
|
||||
writeRegister(REG_PAYLOAD_LENGTH, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoRaClass::endPacket()
|
||||
{
|
||||
// put in TX mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
|
||||
|
||||
// wait for TX done
|
||||
while((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0);
|
||||
|
||||
// clear IRQ's
|
||||
writeRegister(REG_IRQ_FLAGS, 0xff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoRaClass::parsePacket()
|
||||
{
|
||||
int packetLength = 0;
|
||||
int irqFlags = readRegister(REG_IRQ_FLAGS);
|
||||
|
||||
// clear IRQ's
|
||||
writeRegister(REG_IRQ_FLAGS, 0xff);
|
||||
|
||||
if (irqFlags & IRQ_RX_DONE_MASK) {
|
||||
// received a packet
|
||||
_packetIndex = 0;
|
||||
|
||||
// read packet length
|
||||
packetLength = readRegister(REG_RX_NB_BYTES);
|
||||
|
||||
// set FIFO address to current RX address
|
||||
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));
|
||||
|
||||
// put in standby mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
|
||||
} else if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE)) {
|
||||
// not currently in RX mode
|
||||
|
||||
// reset FIFO address
|
||||
writeRegister(REG_FIFO_ADDR_PTR, 0);
|
||||
|
||||
// put in single RX mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE);
|
||||
}
|
||||
|
||||
return packetLength;
|
||||
}
|
||||
|
||||
int LoRaClass::packetRSSI()
|
||||
{
|
||||
return (readRegister(REG_PKT_RSSI_VALUE) - 164);
|
||||
}
|
||||
|
||||
size_t LoRaClass::write(uint8_t byte)
|
||||
{
|
||||
return write(&byte, sizeof(byte));
|
||||
}
|
||||
|
||||
size_t LoRaClass::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
int currentLength = readRegister(REG_PAYLOAD_LENGTH);
|
||||
|
||||
// check size
|
||||
if ((currentLength + size) > MAX_PKT_LENGTH) {
|
||||
size = MAX_PKT_LENGTH - currentLength;
|
||||
}
|
||||
|
||||
// write data
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
writeRegister(REG_FIFO, buffer[i]);
|
||||
}
|
||||
|
||||
// update length
|
||||
writeRegister(REG_PAYLOAD_LENGTH, currentLength + size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int LoRaClass::available()
|
||||
{
|
||||
return (readRegister(REG_RX_NB_BYTES) - _packetIndex);
|
||||
}
|
||||
|
||||
int LoRaClass::read()
|
||||
{
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_packetIndex++;
|
||||
|
||||
return readRegister(REG_FIFO);
|
||||
}
|
||||
|
||||
int LoRaClass::peek()
|
||||
{
|
||||
if (!available()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// store current FIFO address
|
||||
int currentAddress = readRegister(REG_FIFO_ADDR_PTR);
|
||||
|
||||
// read
|
||||
uint8_t b = readRegister(REG_FIFO);
|
||||
|
||||
// restore FIFO address
|
||||
writeRegister(REG_FIFO_ADDR_PTR, currentAddress);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void LoRaClass::flush()
|
||||
{
|
||||
}
|
||||
|
||||
void LoRaClass::setPins(int ss, int reset)
|
||||
{
|
||||
_ss = ss;
|
||||
_reset = reset;
|
||||
}
|
||||
|
||||
void LoRaClass::dumpRegisters(Stream& out)
|
||||
{
|
||||
for (int i = 0; i < 128; i++) {
|
||||
out.print("0x");
|
||||
out.print(i, HEX);
|
||||
out.print(": 0x");
|
||||
out.println(readRegister(i), HEX);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t LoRaClass::readRegister(uint8_t address)
|
||||
{
|
||||
return singleTransfer(address & 0x7f, 0x00);
|
||||
}
|
||||
|
||||
void LoRaClass::writeRegister(uint8_t address, uint8_t value)
|
||||
{
|
||||
singleTransfer(address | 0x80, value);
|
||||
}
|
||||
|
||||
uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value)
|
||||
{
|
||||
uint8_t response;
|
||||
|
||||
digitalWrite(_ss, LOW);
|
||||
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(address);
|
||||
response = SPI.transfer(value);
|
||||
SPI.endTransaction();
|
||||
|
||||
digitalWrite(_ss, HIGH);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
LoRaClass LoRa;
|
48
src/LoRa.h
Normal file
48
src/LoRa.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef LORA_H
|
||||
#define LORA_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
class LoRaClass : public Stream {
|
||||
public:
|
||||
LoRaClass();
|
||||
|
||||
int begin(long frequency);
|
||||
void end();
|
||||
|
||||
int beginPacket();
|
||||
int endPacket();
|
||||
|
||||
int parsePacket();
|
||||
int packetRSSI();
|
||||
|
||||
// from Print
|
||||
virtual size_t write(uint8_t byte);
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
|
||||
// from Stream
|
||||
virtual int available();
|
||||
virtual int read();
|
||||
virtual int peek();
|
||||
virtual void flush();
|
||||
|
||||
void setPins(int ss, int reset);
|
||||
|
||||
void dumpRegisters(Stream& out);
|
||||
|
||||
private:
|
||||
uint8_t readRegister(uint8_t address);
|
||||
void writeRegister(uint8_t address, uint8_t value);
|
||||
uint8_t singleTransfer(uint8_t address, uint8_t value);
|
||||
|
||||
private:
|
||||
SPISettings _spiSettings;
|
||||
int _ss;
|
||||
int _reset;
|
||||
int _packetIndex;
|
||||
};
|
||||
|
||||
extern LoRaClass LoRa;
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user