Semtech LoRaMAC implementation

Provides a RIOT adaption of Semtech LoRaMAC implementation. More...

Detailed Description

Provides a RIOT adaption of Semtech LoRaMAC implementation.

Introduction

This package provides an API built on top of the Semtech LoRaMAC-node reference implementation of a LoRa network.

Importing this package in an application

This package only works with Semtech SX1272 and SX1276 radio devices. Thus, in order to use it properly, the application Makefile must import the corresponding device driver:

USEMODULE += sx1272 # for a SX1272 radio device
USEMODULE += sx1276 # for a SX1276 radio device

In order to use this package in an application, add the following in the application Makefile:

USEPKG += semtech-loramac

Since the LoRa radio depends on regional parameters regarding the access to the physical support, the region where the device is used needs to be set at compile time. Example for EU868:

LORA_REGION = EU868

Using the package API

The package provides a simple API for initializing the MAC, setting/getting parameters, joining a network and sending/receiving packets to/from a LoRa Network.

In your main.c, some header files must be first included:

#include "net/loramac.h" /* core loramac definitions */
#include "semtech_loramac.h" /* package API */

Then define global variables:

semtech_loramac_t loramac; /* The loramac stack device descriptor */
/* define the required keys for OTAA, e.g over-the-air activation (the
null arrays need to be updated with valid LoRa values) */
static const uint8_t deveui[LORAMAC_DEVEUI_LEN] = { 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00 };
static const uint8_t appeui[LORAMAC_APPEUI_LEN] = { 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00 };
static const uint8_t appkey[LORAMAC_APPKEY_LEN] = { 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00 };

Now in the main function:

  1. initialize the LoRaMAC MAC layer
  2. set the LoRa keys
  3. join the network
  4. send some data to the network
int main(void)
{
/* 1. initialize the LoRaMAC MAC layer */
/* 2. set the keys identifying the device */
semtech_loramac_set_deveui(&loramac, deveui);
semtech_loramac_set_appeui(&loramac, appeui);
semtech_loramac_set_appkey(&loramac, appkey);
/* 3. join the network */
puts("Join procedure failed");
return 1;
}
puts("Join procedure succeeded");
/* 4. send some data */
char *message = "This is RIOT";
if (semtech_loramac_send(&loramac,
(uint8_t *)message, strlen(message)) != SEMTECH_LORAMAC_TX_DONE) {
printf("Cannot send message '%s'\n", message);
return 1;
}
}

To receive downlink messages, enable the semtech_loramac_rx and use a dedicated receiving thread.

Persistence

If the board CPU provides an internal EEPROM, this package provides a mechanism for storing EUIs, keys and some MAC parameters (frame counter, join status). After a successful join procedure, use semtech_loramac_save function to persist this information and it will be loaded automatically at the next reboot. If the device is already joined to a network, to avoid another OTAA join procedure use semtech_loramac_is_mac_joined function to check the join status of the device.

This mechanism is especially useful when using deep sleep power modes that don't preserve RAM.

Low power considerations

The internal implementation of the required LoRaWAN timings (delay before opening RX windows, duty-cycle delays) automatically achieves the lowest possible power consumption while remaining usable when RIOT's low power modes are not blocked. All timings are managed by the ztimer high level timer abstraction layer running on the low-level RTT peripheral which allows for:

Warning
It is not possible to directly call the original LoRaMAC-node API using this package. This package should only be considered as a wrapper around the original LoRaMAC-node API and only the API provided by this package should be used.

License

The library is using the BSD 3-clause license.

See also
https://github.com/Lora-net/LoRaMac-node

Files

file  timer.h
 Semtech LoRaMAC timer compatibility definitions.
 
file  semtech_loramac.h
 Public API and definitions of the Semtech LoRaMAC.
 
thread_create
kernel_pid_t thread_create(char *stack, int stacksize, uint8_t priority, int flags, thread_task_func_t task_func, void *arg, const char *name)
Creates a new thread.
LORAMAC_APPKEY_LEN
#define LORAMAC_APPKEY_LEN
Application key length in bytes.
Definition: loramac.h:320
msg_init_queue
void msg_init_queue(msg_t *array, int num)
Initialize the current thread's message queue.
semtech_loramac.h
Public API and definitions of the Semtech LoRaMAC.
loramac.h
LoRaMAC header definitions.
THREAD_STACKSIZE_DEFAULT
#define THREAD_STACKSIZE_DEFAULT
A reasonable default stack size that will suffice most smaller tasks.
Definition: thread.h:211
SEMTECH_LORAMAC_JOIN_SUCCEEDED
@ SEMTECH_LORAMAC_JOIN_SUCCEEDED
Join procedure succeeded.
Definition: semtech_loramac.h:61
semtech_loramac_rx_data_t::payload
uint8_t payload[LORAWAN_APP_DATA_MAX_SIZE]
RX payload buffer.
Definition: semtech_loramac.h:97
semtech_loramac_set_appkey
void semtech_loramac_set_appkey(semtech_loramac_t *mac, const uint8_t *key)
Sets the application key.
semtech_loramac_rx_data_t::port
uint8_t port
RX port.
Definition: semtech_loramac.h:99
semtech_loramac_set_deveui
void semtech_loramac_set_deveui(semtech_loramac_t *mac, const uint8_t *eui)
Sets the device EUI.
LORAMAC_APPEUI_LEN
#define LORAMAC_APPEUI_LEN
Application EUI length in bytes.
Definition: loramac.h:315
semtech_loramac_t
Semtech LoRaMAC descriptor.
Definition: semtech_loramac.h:115
semtech_loramac_set_appeui
void semtech_loramac_set_appeui(semtech_loramac_t *mac, const uint8_t *eui)
Sets the application EUI.
LORAMAC_DEVEUI_LEN
#define LORAMAC_DEVEUI_LEN
Device EUI length in bytes.
Definition: loramac.h:305
semtech_loramac_rx_data_t::payload_len
uint8_t payload_len
Length of the RX payload.
Definition: semtech_loramac.h:98
SEMTECH_LORAMAC_TX_DONE
@ SEMTECH_LORAMAC_TX_DONE
Transmission completed.
Definition: semtech_loramac.h:67
msg_t
Describes a message object which can be sent between threads.
Definition: msg.h:185
semtech_loramac_t::rx_data
semtech_loramac_rx_data_t rx_data
struct handling the RX data
Definition: semtech_loramac.h:127
semtech_loramac_init
int semtech_loramac_init(semtech_loramac_t *mac)
Initializes the semtech loramac mac.
THREAD_PRIORITY_MAIN
#define THREAD_PRIORITY_MAIN
Priority of the main thread.
Definition: thread.h:303
LORAMAC_JOIN_OTAA
@ LORAMAC_JOIN_OTAA
Other-the-air activation.
Definition: loramac.h:371
semtech_loramac_recv
uint8_t semtech_loramac_recv(semtech_loramac_t *mac)
Wait for a message sent by the LoRaWAN network.
semtech_loramac_join
uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type)
Starts a LoRaWAN network join procedure.
semtech_loramac_send
uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
Sends data to the LoRaWAN network.