This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

lora communication with tm4c using energia

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: ENERGIA,

Hi

//in energia lora.h is not working with tm4c123 in energia

//but I develop lora tm4c123 energia code as follows
//it is fully working

//Sender

#include <SPI.h>

#define chipSelectPin PA_3
#define RDID 0x42

SPIClass mySPI(0); // 5 is SSI3 on port Q, see SPI.cpp for others
/* SSI0
PA2_CLK
PA3_FSS); NSS
PA4_RX); MISO
PA5_TX); MOSI
*/
#define REG_FIFO 0x00
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
#define REG_OP_MODE 0x01
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define REG_PA_CONFIG 0x09
#define REG_OCP 0x0b
#define REG_LNA 0x0c
#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_SNR_VALUE 0x19
#define REG_PKT_RSSI_VALUE 0x1a
#define REG_RSSI_VALUE 0x1b
#define REG_MODEM_CONFIG_1 0x1d
#define REG_MODEM_CONFIG_2 0x1e
#define REG_PREAMBLE_MSB 0x20
#define REG_PREAMBLE_LSB 0x21
#define REG_PAYLOAD_LENGTH 0x22
#define REG_MODEM_CONFIG_3 0x26
#define REG_FREQ_ERROR_MSB 0x28
#define REG_FREQ_ERROR_MID 0x29
#define REG_FREQ_ERROR_LSB 0x2a
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_INVERTIQ 0x33
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_INVERTIQ2 0x3b
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42
#define REG_PA_DAC 0x4d

// modes
#define MODE_LONG_RANGE_MODE 0x80

#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1

// PA config
#define PA_BOOST 0x80

// IRQ masks
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40

#define RF_MID_BAND_THRESHOLD 525E6
#define RSSI_OFFSET_HF_PORT 157
#define RSSI_OFFSET_LF_PORT 164
#define MAX_PKT_LENGTH 255

void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
int beginPacket(int implicitHeader = false);

int _implicitHeaderMode;
long _frequency;
#define ss 5
#define rst PF_2
#define dio0 2
int count;
uint8_t rv;
void setup()
{
Serial.begin(115200);
delay(1000); // wait a bit serial monitor to open
Serial.println("start");

if(!LoRabegin(866E6))
{
Serial.println("Starting LoRa failed!");
while (1);
}
setSyncWord(0xF3);
Serial.println("done");
}

void loop()
{
beginPacket();
Serial.println("sending ");
lora_send("Abcd");
delay(1000);
lora_send("Wxyz ");
delay(1000);
lora_send("Mnop ");
Serial.println(" done");
Serial.println(" ");
delay(5000);
}

void lora_send(char *a)
{
Serial.println(a);
int b=strlen(a); //string length
writeRegister(REG_OP_MODE, MODE_STDBY);
writeRegister(REG_FIFO_ADDR_PTR, 0x00);

for(int i=0;a[i];i++)
writeRegister(REG_FIFO, a[i] ); //massage you want to send

writeRegister(REG_PAYLOAD_LENGTH, b); //length of massage
writeRegister(MODE_STDBY, MODE_TX);
writeRegister(REG_FIFO_ADDR_PTR, 0x00);
writeRegister(REG_IRQ_FLAGS, 0x00);
}

int beginPacket(int implicitHeader)
{
if (isTransmitting())
{
return 0;
}

// put in standby mode
idle();

if (implicitHeader)
{
implicitHeaderMode();
}
else
{
explicitHeaderMode();
}
// reset FIFO address and paload length
writeRegister(REG_FIFO_ADDR_PTR, 0);
writeRegister(REG_PAYLOAD_LENGTH, 0);
return 1;
}
void explicitHeaderMode()
{
_implicitHeaderMode = 0;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
}

void implicitHeaderMode()
{
_implicitHeaderMode = 1;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | 0x01);
}

bool isTransmitting()
{
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX)
{
return true;
}
if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK)
{
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
}
return false;
}
void setSyncWord(int sw)
{
writeRegister(REG_SYNC_WORD, sw);
}
int LoRabegin(long frequency)
{
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin, HIGH);

if (rst != -1)
{
pinMode(rst, OUTPUT);
digitalWrite(rst, LOW);
delay(100);
digitalWrite(rst, HIGH);
delay(100);
}
mySPI.begin();

rv=readRegister(REG_VERSION);
if (rv != 0x12)
{
return 0;
}
sleep();
setFrequency(frequency);
// set base addresses
writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

// set LNA boost
writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);

// set auto AGC
writeRegister(REG_MODEM_CONFIG_3, 0x04);
// set output power to 17 dBm
setTxPower(17);
// put in standby mode
idle();
return 1;
}
void setTxPower(int level, int outputPin)
{
if (PA_OUTPUT_RFO_PIN == outputPin) {
// RFO
if (level < 0)
{
level = 0;
}
else if (level > 14)
{
level = 14;
}
writeRegister(REG_PA_CONFIG, 0x70 | level);
}
else
{
// PA BOOST
if (level > 17)
{
if (level > 20)
{
level = 20;
}

// subtract 3 from level, so 18 - 20 maps to 15 - 17
level -= 3;

// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
writeRegister(REG_PA_DAC, 0x87);
setOCP(140);
}
else
{
if (level < 2)
{
level = 2;
}
//Default value PA_HF/LF or +17dBm
writeRegister(REG_PA_DAC, 0x84);
setOCP(100);
}
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
}
}

void setOCP(uint8_t mA)
{
uint8_t ocpTrim = 27;
if (mA <= 120)
{
ocpTrim = (mA - 45) / 5;
}
else if (mA <=240)
{
ocpTrim = (mA + 30) / 10;
}
writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
}

void idle()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
}

void sleep()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
}

void setFrequency(long frequency)
{
_frequency = 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));
}

uint8_t readRegister(uint8_t address)
{
return singleTransfer(address & 0x7f, 0x00);
}

void writeRegister(uint8_t address, uint8_t value)
{
singleTransfer(address | 0x80, value);
}

uint8_t singleTransfer(uint8_t address, uint8_t value)
{
uint8_t rv;
mySPI.begin();
pinMode(chipSelectPin,OUTPUT);
digitalWrite(chipSelectPin,LOW);
mySPI.transfer(address);
rv = mySPI.transfer(value);
digitalWrite(chipSelectPin,HIGH);
return rv;
}

//*******************************************************************************************************************************************************************************//

//Receiver

#include <SPI.h>

#define chipSelectPin PA_3
#define RDID 0x42

SPIClass mySPI(0); // 5 is SSI3 on port Q, see SPI.cpp for others
/* SSI0
PA2_CLK
PA3_FSS); NSS
PA4_RX); MISO
PA5_TX); MOSI
*/
#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_PA_CONFIG 0x09
#define REG_OCP 0x0b
#define REG_LNA 0x0c
#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_SNR_VALUE 0x19
#define REG_PKT_RSSI_VALUE 0x1a
#define REG_RSSI_VALUE 0x1b
#define REG_MODEM_CONFIG_1 0x1d
#define REG_MODEM_CONFIG_2 0x1e
#define REG_PREAMBLE_MSB 0x20
#define REG_PREAMBLE_LSB 0x21
#define REG_PAYLOAD_LENGTH 0x22
#define REG_MODEM_CONFIG_3 0x26
#define REG_FREQ_ERROR_MSB 0x28
#define REG_FREQ_ERROR_MID 0x29
#define REG_FREQ_ERROR_LSB 0x2a
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_INVERTIQ 0x33
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_INVERTIQ2 0x3b
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42
#define REG_PA_DAC 0x4d

// modes
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1
// PA config
#define PA_BOOST 0x80

// IRQ masks
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40

#define RF_MID_BAND_THRESHOLD 525E6
#define RSSI_OFFSET_HF_PORT 157
#define RSSI_OFFSET_LF_PORT 164
#define led PF_1
#define RH_RF95_HEADER_LEN 4
#define MAX_PKT_LENGTH 255
#define RH_RF95_MAX_PAYLOAD_LEN MAX_PKT_LENGTH
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
int beginPacket(int implicitHeader = false);
int parsePacket(int size = 0);
int _implicitHeaderMode;
int _packetIndex;
long _frequency;
#define ss 5
#define rst PF_2
#define dio0 2
int count;
uint8_t rv;
volatile uint8_t _bufLen;
uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];
int i1=0;
/// True when there is a valid message in the buffer
volatile bool _rxBufValid;

void setup()
{
Serial.begin(115200);
Serial.println("RECEVER ");
while (!LoRabegin(866E6))
{
Serial.println(".");
delay(500);
}
setSyncWord(0xF3);
Serial.println("Start");
}

void loop()
{
int packetSize = parsePacket();
if (packetSize)
{
Serial.print("Received packet ");
for(i1=0;i1<packetSize;i1++)
{
char i=readRegister(REG_FIFO);
Serial.print(i);
}
Serial.println("");
}
}

int available()
{
return (readRegister(REG_RX_NB_BYTES) - _packetIndex);
}
int parsePacket(int size)
{
int packetLength = 0;
int irqFlags = readRegister(REG_IRQ_FLAGS);
if (size > 0)
{
implicitHeaderMode();
writeRegister(REG_PAYLOAD_LENGTH, size & 0xff);
}
else
{
explicitHeaderMode();
}
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, irqFlags);

if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0)
{
// received a packet
_packetIndex = 0;

// read packet length
if (_implicitHeaderMode)
{
packetLength = readRegister(REG_PAYLOAD_LENGTH);
}
else
{
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
idle();
}
else if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE))
{
// 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 beginPacket(int implicitHeader)
{
if (isTransmitting())
{
return 0;
}

// put in standby mode
idle();

if (implicitHeader)
{
implicitHeaderMode();
}
else
{
explicitHeaderMode();
}

// reset FIFO address and paload length
writeRegister(REG_FIFO_ADDR_PTR, 0);
writeRegister(REG_PAYLOAD_LENGTH, 0);
return 1;
}
void explicitHeaderMode()
{
_implicitHeaderMode = 0;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
}
void implicitHeaderMode()
{
_implicitHeaderMode = 1;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | REG_OP_MODE);
}
bool isTransmitting()
{
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX)
{
return true;
}
if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK)
{
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
}
return false;
}

void setSyncWord(int sw)
{
writeRegister(REG_SYNC_WORD, sw);
}
int LoRabegin(long frequency)
{
pinMode(chipSelectPin, OUTPUT);
digitalWrite(chipSelectPin, HIGH);
if (rst != -1)
{
pinMode(rst, OUTPUT);
digitalWrite(rst, LOW);
delay(100);
digitalWrite(rst, HIGH);
delay(100);
}
mySPI.begin();
rv=readRegister(REG_VERSION);
if (rv != 0x12)
{
return 0;
}
sleep();
setFrequency(frequency);
// set base addresses
writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

// set LNA boost
writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);

// set auto AGC
writeRegister(REG_MODEM_CONFIG_3, 0x04);
// set output power to 17 dBm
setTxPower(17);
// put in standby mode
idle();
return 1;
}
void setTxPower(int level, int outputPin)
{
if (PA_OUTPUT_RFO_PIN == outputPin)
{
// RFO
if (level < 0)
{
level = 0;
}
else if (level > 14)
{
level = 14;
}
writeRegister(REG_PA_CONFIG, 0x70 | level);
}
else
{
// PA BOOST
if (level > 17)
{
if (level > 20)
{
level = 20;
}

// subtract 3 from level, so 18 - 20 maps to 15 - 17
level -= 3;

// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
writeRegister(REG_PA_DAC, 0x87);
setOCP(140);
}
else
{
if (level < 2)
{
level = 2;
}
//Default value PA_HF/LF or +17dBm
writeRegister(REG_PA_DAC, 0x84);
setOCP(100);
}
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
}
}
void setOCP(uint8_t mA)
{
uint8_t ocpTrim = 27;

if (mA <= 120)
{
ocpTrim = (mA - 45) / 5;
}
else if (mA <=240)
{
ocpTrim = (mA + 30) / 10;
}
writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
}
void idle()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
}

void sleep()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
}
void setFrequency(long frequency)
{
_frequency = 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));
}
uint8_t readRegister(uint8_t address)
{
return singleTransfer(address & 0x7f, 0x00);
}

void writeRegister(uint8_t address, uint8_t value)
{
singleTransfer(address | 0x80, value);
}
uint8_t singleTransfer(uint8_t address, uint8_t value)
{
uint8_t rv;
mySPI.begin();
pinMode(chipSelectPin,OUTPUT);
digitalWrite(chipSelectPin,LOW);
mySPI.transfer(address);
rv = mySPI.transfer(value);
digitalWrite(chipSelectPin,HIGH);
return rv;
}

  • Hi,

      Please refer to FAQ #5 in this FAQ link https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/695568/faq-faqs-for-tm4c-arm-cortex-m4f-microcontrollers

      Basically, we don't support Energia in this forum. Please direct questions concerning Energia to https://forum.43oh.com/forum/119-energia where the experts there can better assist you. 

  • Can we interface tm4c123 with lora in ccs

  • Hi,

      I don't see why not. Your Lora module is just an external component with interface to TM4C123 through SPI or I2C. You just use CCS or other IDE of your choice (e.g. IAR, Keil) to build your application. 

  • Part Number: TM4C123GH6PM

    I am trying to interface lora with tm4c123gh6pm in ccs

    We have to write some data in registers of lora or also have to read values stored in lora resisters 

    Which API should I use to read and write data from lora, how I mansion specific register address?  

  • I use ccs

    How I read or write data from lora register

    I trying to set frequency of lora, for that I have to write or read some data from specific registers of lora

    Which API should I use to read data from lora resisters 

  • Hi,

      CCS is only an IDE (Integrated Development Environments) with toolchains like editor, compiler and other utility tools. It does not contain any specify API for Lora, neither is TivaWare. You will need to so some Google search to see if you can find some reference code or contact the Lora vendor or create your own library. 

  • with the help of spi we can communicate with lora, but I don't have any idea about how to write data in any register of lora

  • Hi,

      If you want SPI examples, you can find them in C:\ti\TivaWare_C_Series-2.2.0.295\examples\peripherals\ssi. I suppose you have the datasheet from the vendor who supplies you the lora device. They should have protocol on how to communicate with their device. I will expect the datasheet to describe in detail on how to read/write to any registers in their device via SPI.  

  • In energia for interfacing lora with esp32 they use following library

    https://github.com/sandeepmistry/arduino-LoRa

    in lora.cpp they have mansion read register and write register, but I am not getting how to write these function in ccs for tm4c123  

  • in lora.cpp they have mansion read register and write register, but I am not getting how to write these function in ccs for tm4c123

    Obviously, you cannot just run these ESP32 code on TM4C123 because they are entirely different MCU and the SPI module will be very different. The SPI features that are used in lora.cpp will not have a one-to-one mapping to TM4C123 SPI module. I'm not sure if you are new to TM4C123 MCU. If you are, please go through the TivaWare examples I mentioned in my earlier replies. Run the TM4C123 SSI (aka SPI) module examples and have a feel on how it works. With that, you can port your ESP32 lora.cpp to TM4C123. 

    Take for example the below two lines from lora.cpp. The writeRegister() function is probably a ESP32 library function to write to a register at address REG_FIFO_TX_BASE_ADDR with a value of 0. 

    // set base addresses
    writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
    writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

    TivaWare provides its own functions to do similar thing. For example you can write below using HWREG function to an address (ui32Base + SSI_O_DR) with a value equal to ui32Data;

    //
    // Write the data to the SSI.
    //
    HWREG(ui32Base + SSI_O_DR) = ui32Data;

    Refer to C:\ti\TivaWare_C_Series-2.2.0.295\driverlib\ssi.c where are the SSI module driver functions are defined. 

  • I have interface lora with Tm4c123gh6pm in enegia

    //Sender code

    #include <SPI.h>

    #define chipSelectPin PA_3
    #define RDID 0x42

    SPIClass mySPI(0); // 5 is SSI3 on port Q, see SPI.cpp for others
    /* SSI0
    PA2_CLK
    PA3_FSS); NSS
    PA4_RX); MISO
    PA5_TX); MOSI
    */
    #define REG_FIFO 0x00
    #define MODE_SLEEP 0x00
    #define MODE_STDBY 0x01
    #define MODE_TX 0x03
    #define MODE_RX_CONTINUOUS 0x05
    #define MODE_RX_SINGLE 0x06
    #define REG_OP_MODE 0x01
    #define REG_FRF_MSB 0x06
    #define REG_FRF_MID 0x07
    #define REG_FRF_LSB 0x08
    #define REG_PA_CONFIG 0x09
    #define REG_OCP 0x0b
    #define REG_LNA 0x0c
    #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_SNR_VALUE 0x19
    #define REG_PKT_RSSI_VALUE 0x1a
    #define REG_RSSI_VALUE 0x1b
    #define REG_MODEM_CONFIG_1 0x1d
    #define REG_MODEM_CONFIG_2 0x1e
    #define REG_PREAMBLE_MSB 0x20
    #define REG_PREAMBLE_LSB 0x21
    #define REG_PAYLOAD_LENGTH 0x22
    #define REG_MODEM_CONFIG_3 0x26
    #define REG_FREQ_ERROR_MSB 0x28
    #define REG_FREQ_ERROR_MID 0x29
    #define REG_FREQ_ERROR_LSB 0x2a
    #define REG_RSSI_WIDEBAND 0x2c
    #define REG_DETECTION_OPTIMIZE 0x31
    #define REG_INVERTIQ 0x33
    #define REG_DETECTION_THRESHOLD 0x37
    #define REG_SYNC_WORD 0x39
    #define REG_INVERTIQ2 0x3b
    #define REG_DIO_MAPPING_1 0x40
    #define REG_VERSION 0x42
    #define REG_PA_DAC 0x4d

    // modes
    #define MODE_LONG_RANGE_MODE 0x80

    #define PA_OUTPUT_RFO_PIN 0
    #define PA_OUTPUT_PA_BOOST_PIN 1

    // PA config
    #define PA_BOOST 0x80

    // IRQ masks
    #define IRQ_TX_DONE_MASK 0x08
    #define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
    #define IRQ_RX_DONE_MASK 0x40

    #define RF_MID_BAND_THRESHOLD 525E6
    #define RSSI_OFFSET_HF_PORT 157
    #define RSSI_OFFSET_LF_PORT 164
    #define MAX_PKT_LENGTH 255

    void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
    int beginPacket(int implicitHeader = false);

    int _implicitHeaderMode;
    long _frequency;
    #define ss 5
    #define rst PF_2
    #define dio0 2
    int count;
    uint8_t rv;
    void setup()
    {
    Serial.begin(115200);
    delay(1000); // wait a bit serial monitor to open
    Serial.println("start");

    if(!LoRabegin(866E6))
    {
    Serial.println("Starting LoRa failed!");
    while (1);
    }
    setSyncWord(0xF3);
    Serial.println("done");
    }

    void loop()
    {
    beginPacket();
    Serial.println("sending ");
    lora_send("Abcd");
    delay(1000);
    lora_send("Wxyz ");
    delay(1000);
    lora_send("Mnop ");
    Serial.println(" done");
    Serial.println(" ");
    delay(5000);
    }

    void lora_send(char *a)
    {
    Serial.println(a);
    int b=strlen(a); //string length
    writeRegister(REG_OP_MODE, MODE_STDBY);
    writeRegister(REG_FIFO_ADDR_PTR, 0x00);

    for(int i=0;a[i];i++)
    writeRegister(REG_FIFO, a[i] ); //massage you want to send

    writeRegister(REG_PAYLOAD_LENGTH, b); //length of massage
    writeRegister(MODE_STDBY, MODE_TX);
    writeRegister(REG_FIFO_ADDR_PTR, 0x00);
    writeRegister(REG_IRQ_FLAGS, 0x00);
    }

    int beginPacket(int implicitHeader)
    {
    if (isTransmitting())
    {
    return 0;
    }

    // put in standby mode
    idle();

    if (implicitHeader)
    {
    implicitHeaderMode();
    }
    else
    {
    explicitHeaderMode();
    }
    // reset FIFO address and paload length
    writeRegister(REG_FIFO_ADDR_PTR, 0);
    writeRegister(REG_PAYLOAD_LENGTH, 0);
    return 1;
    }
    void explicitHeaderMode()
    {
    _implicitHeaderMode = 0;
    writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
    }

    void implicitHeaderMode()
    {
    _implicitHeaderMode = 1;
    writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | 0x01);
    }

    bool isTransmitting()
    {
    if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX)
    {
    return true;
    }
    if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK)
    {
    // clear IRQ's
    writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
    }
    return false;
    }
    void setSyncWord(int sw)
    {
    writeRegister(REG_SYNC_WORD, sw);
    }
    int LoRabegin(long frequency)
    {
    pinMode(chipSelectPin, OUTPUT);
    digitalWrite(chipSelectPin, HIGH);

    if (rst != -1)
    {
    pinMode(rst, OUTPUT);
    digitalWrite(rst, LOW);
    delay(100);
    digitalWrite(rst, HIGH);
    delay(100);
    }
    mySPI.begin();

    rv=readRegister(REG_VERSION);
    if (rv != 0x12)
    {
    return 0;
    }
    sleep();
    setFrequency(frequency);
    // set base addresses
    writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
    writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

    // set LNA boost
    writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);

    // set auto AGC
    writeRegister(REG_MODEM_CONFIG_3, 0x04);
    // set output power to 17 dBm
    setTxPower(17);
    // put in standby mode
    idle();
    return 1;
    }
    void setTxPower(int level, int outputPin)
    {
    if (PA_OUTPUT_RFO_PIN == outputPin) {
    // RFO
    if (level < 0)
    {
    level = 0;
    }
    else if (level > 14)
    {
    level = 14;
    }
    writeRegister(REG_PA_CONFIG, 0x70 | level);
    }
    else
    {
    // PA BOOST
    if (level > 17)
    {
    if (level > 20)
    {
    level = 20;
    }

    // subtract 3 from level, so 18 - 20 maps to 15 - 17
    level -= 3;

    // High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
    writeRegister(REG_PA_DAC, 0x87);
    setOCP(140);
    }
    else
    {
    if (level < 2)
    {
    level = 2;
    }
    //Default value PA_HF/LF or +17dBm
    writeRegister(REG_PA_DAC, 0x84);
    setOCP(100);
    }
    writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
    }
    }

    void setOCP(uint8_t mA)
    {
    uint8_t ocpTrim = 27;
    if (mA <= 120)
    {
    ocpTrim = (mA - 45) / 5;
    }
    else if (mA <=240)
    {
    ocpTrim = (mA + 30) / 10;
    }
    writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
    }

    void idle()
    {
    writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
    }

    void sleep()
    {
    writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
    }

    void setFrequency(long frequency)
    {
    _frequency = 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));
    }

    uint8_t readRegister(uint8_t address)
    {
    return singleTransfer(address & 0x7f, 0x00);
    }

    void writeRegister(uint8_t address, uint8_t value)
    {
    singleTransfer(address | 0x80, value);
    }

    uint8_t singleTransfer(uint8_t address, uint8_t value)
    {
    uint8_t rv;
    mySPI.begin();
    pinMode(chipSelectPin,OUTPUT);
    digitalWrite(chipSelectPin,LOW);
    mySPI.transfer(address);
    rv = mySPI.transfer(value);
    digitalWrite(chipSelectPin,HIGH);
    return rv;
    }

  • //Receiver code

    #include <SPI.h>

    #define chipSelectPin PA_3
    #define RDID 0x42

    SPIClass mySPI(0); // 5 is SSI3 on port Q, see SPI.cpp for others
    /* SSI0
    PA2_CLK
    PA3_FSS); NSS
    PA4_RX); MISO
    PA5_TX); MOSI
    */
    #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_PA_CONFIG 0x09
    #define REG_OCP 0x0b
    #define REG_LNA 0x0c
    #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_SNR_VALUE 0x19
    #define REG_PKT_RSSI_VALUE 0x1a
    #define REG_RSSI_VALUE 0x1b
    #define REG_MODEM_CONFIG_1 0x1d
    #define REG_MODEM_CONFIG_2 0x1e
    #define REG_PREAMBLE_MSB 0x20
    #define REG_PREAMBLE_LSB 0x21
    #define REG_PAYLOAD_LENGTH 0x22
    #define REG_MODEM_CONFIG_3 0x26
    #define REG_FREQ_ERROR_MSB 0x28
    #define REG_FREQ_ERROR_MID 0x29
    #define REG_FREQ_ERROR_LSB 0x2a
    #define REG_RSSI_WIDEBAND 0x2c
    #define REG_DETECTION_OPTIMIZE 0x31
    #define REG_INVERTIQ 0x33
    #define REG_DETECTION_THRESHOLD 0x37
    #define REG_SYNC_WORD 0x39
    #define REG_INVERTIQ2 0x3b
    #define REG_DIO_MAPPING_1 0x40
    #define REG_VERSION 0x42
    #define REG_PA_DAC 0x4d

    // modes
    #define MODE_LONG_RANGE_MODE 0x80
    #define MODE_SLEEP 0x00
    #define MODE_STDBY 0x01
    #define MODE_TX 0x03
    #define MODE_RX_CONTINUOUS 0x05
    #define MODE_RX_SINGLE 0x06
    #define PA_OUTPUT_RFO_PIN 0
    #define PA_OUTPUT_PA_BOOST_PIN 1
    // PA config
    #define PA_BOOST 0x80

    // IRQ masks
    #define IRQ_TX_DONE_MASK 0x08
    #define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
    #define IRQ_RX_DONE_MASK 0x40

    #define RF_MID_BAND_THRESHOLD 525E6
    #define RSSI_OFFSET_HF_PORT 157
    #define RSSI_OFFSET_LF_PORT 164
    #define led PF_1
    #define RH_RF95_HEADER_LEN 4
    #define MAX_PKT_LENGTH 255
    #define RH_RF95_MAX_PAYLOAD_LEN MAX_PKT_LENGTH
    void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
    int beginPacket(int implicitHeader = false);
    int parsePacket(int size = 0);
    int _implicitHeaderMode;
    int _packetIndex;
    long _frequency;
    #define ss 5
    #define rst PF_2
    #define dio0 2
    int count;
    uint8_t rv;
    volatile uint8_t _bufLen;
    uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];
    int i1=0;
    /// True when there is a valid message in the buffer
    volatile bool _rxBufValid;

    void setup()
    {
    Serial.begin(115200);
    Serial.println("RECEVER ");
    while (!LoRabegin(866E6))
    {
    Serial.println(".");
    delay(500);
    }
    setSyncWord(0xF3);
    Serial.println("Start");
    }

    void loop()
    {
    int packetSize = parsePacket();
    if (packetSize)
    {
    Serial.print("Received packet ");
    for(i1=0;i1<packetSize;i1++)
    {
    char i=readRegister(REG_FIFO);
    Serial.print(i);
    }
    Serial.println("");
    }
    }

    int available()
    {
    return (readRegister(REG_RX_NB_BYTES) - _packetIndex);
    }
    int parsePacket(int size)
    {
    int packetLength = 0;
    int irqFlags = readRegister(REG_IRQ_FLAGS);
    if (size > 0)
    {
    implicitHeaderMode();
    writeRegister(REG_PAYLOAD_LENGTH, size & 0xff);
    }
    else
    {
    explicitHeaderMode();
    }
    // clear IRQ's
    writeRegister(REG_IRQ_FLAGS, irqFlags);

    if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0)
    {
    // received a packet
    _packetIndex = 0;

    // read packet length
    if (_implicitHeaderMode)
    {
    packetLength = readRegister(REG_PAYLOAD_LENGTH);
    }
    else
    {
    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
    idle();
    }
    else if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE))
    {
    // 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 beginPacket(int implicitHeader)
    {
    if (isTransmitting())
    {
    return 0;
    }

    // put in standby mode
    idle();

    if (implicitHeader)
    {
    implicitHeaderMode();
    }
    else
    {
    explicitHeaderMode();
    }

    // reset FIFO address and paload length
    writeRegister(REG_FIFO_ADDR_PTR, 0);
    writeRegister(REG_PAYLOAD_LENGTH, 0);
    return 1;
    }
    void explicitHeaderMode()
    {
    _implicitHeaderMode = 0;
    writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
    }
    void implicitHeaderMode()
    {
    _implicitHeaderMode = 1;
    writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | REG_OP_MODE);
    }
    bool isTransmitting()
    {
    if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX)
    {
    return true;
    }
    if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK)
    {
    // clear IRQ's
    writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
    }
    return false;
    }

    void setSyncWord(int sw)
    {
    writeRegister(REG_SYNC_WORD, sw);
    }
    int LoRabegin(long frequency)
    {
    pinMode(chipSelectPin, OUTPUT);
    digitalWrite(chipSelectPin, HIGH);
    if (rst != -1)
    {
    pinMode(rst, OUTPUT);
    digitalWrite(rst, LOW);
    delay(100);
    digitalWrite(rst, HIGH);
    delay(100);
    }
    mySPI.begin();
    rv=readRegister(REG_VERSION);
    if (rv != 0x12)
    {
    return 0;
    }
    sleep();
    setFrequency(frequency);
    // set base addresses
    writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
    writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

    // set LNA boost
    writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);

    // set auto AGC
    writeRegister(REG_MODEM_CONFIG_3, 0x04);
    // set output power to 17 dBm
    setTxPower(17);
    // put in standby mode
    idle();
    return 1;
    }
    void setTxPower(int level, int outputPin)
    {
    if (PA_OUTPUT_RFO_PIN == outputPin)
    {
    // RFO
    if (level < 0)
    {
    level = 0;
    }
    else if (level > 14)
    {
    level = 14;
    }
    writeRegister(REG_PA_CONFIG, 0x70 | level);
    }
    else
    {
    // PA BOOST
    if (level > 17)
    {
    if (level > 20)
    {
    level = 20;
    }

    // subtract 3 from level, so 18 - 20 maps to 15 - 17
    level -= 3;

    // High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
    writeRegister(REG_PA_DAC, 0x87);
    setOCP(140);
    }
    else
    {
    if (level < 2)
    {
    level = 2;
    }
    //Default value PA_HF/LF or +17dBm
    writeRegister(REG_PA_DAC, 0x84);
    setOCP(100);
    }
    writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
    }
    }
    void setOCP(uint8_t mA)
    {
    uint8_t ocpTrim = 27;

    if (mA <= 120)
    {
    ocpTrim = (mA - 45) / 5;
    }
    else if (mA <=240)
    {
    ocpTrim = (mA + 30) / 10;
    }
    writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
    }
    void idle()
    {
    writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
    }

    void sleep()
    {
    writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
    }
    void setFrequency(long frequency)
    {
    _frequency = 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));
    }
    uint8_t readRegister(uint8_t address)
    {
    return singleTransfer(address & 0x7f, 0x00);
    }

    void writeRegister(uint8_t address, uint8_t value)
    {
    singleTransfer(address | 0x80, value);
    }
    uint8_t singleTransfer(uint8_t address, uint8_t value)
    {
    uint8_t rv;
    mySPI.begin();
    pinMode(chipSelectPin,OUTPUT);
    digitalWrite(chipSelectPin,LOW);
    mySPI.transfer(address);
    rv = mySPI.transfer(value);
    digitalWrite(chipSelectPin,HIGH);
    return rv;
    }