Skip to content

Commit

Permalink
Merge pull request #11237 from aabadie/pr/examples/lorawan
Browse files Browse the repository at this point in the history
examples/lorawan: add the possibility to use ABP activation procedure
  • Loading branch information
aabadie authored Mar 23, 2022
2 parents b1e3f9c + b22370a commit 20ffa92
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 44 deletions.
50 changes: 43 additions & 7 deletions examples/lorawan/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,25 @@ BOARD ?= b-l072z-lrwan1
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

DEVEUI ?= 0000000000000000
APPEUI ?= 0000000000000000
APPKEY ?= 00000000000000000000000000000000
# Change this to abp to enable Activation By Personnalization mode
ACTIVATION_MODE ?= otaa

ifeq (otaa,$(ACTIVATION_MODE))
DEVEUI ?= 0000000000000000
APPEUI ?= 0000000000000000
APPKEY ?= 00000000000000000000000000000000
else ifeq (abp,$(ACTIVATION_MODE))
DEVADDR ?= 00000000
NWKSKEY ?= 00000000000000000000000000000000
APPSKEY ?= 00000000000000000000000000000000
RX2_FREQ ?= 869525000
RX2_DR ?= 3
else
$(error Unsupported activation mode '$(ACTIVATION_MODE)')
endif

# Send a message every 20s after joining the network
SEND_PERIOD_S ?= 20

# Pass these enviroment variables to docker
DOCKER_ENV_VARS += DEVEUI
Expand All @@ -28,6 +44,18 @@ USEPKG += semtech-loramac
USEMODULE += $(DRIVER)
USEMODULE += fmt
FEATURES_OPTIONAL += periph_rtc
FEATURES_OPTIONAL += periph_eeprom

CFLAGS += -DSEND_PERIOD_S=$(SEND_PERIOD_S)
ifeq (otaa,$(ACTIVATION_MODE))
CFLAGS += -DUSE_OTAA
else ifeq (abp,$(ACTIVATION_MODE))
CFLAGS += -DUSE_ABP
endif

# Enable deep sleep power mode (e.g. STOP mode on STM32) which
# in general provides RAM retention after wake-up.
CFLAGS += -DPM_BLOCKER_INITIAL=0x00000001

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
Expand All @@ -52,8 +80,16 @@ endif
include $(RIOTBASE)/Makefile.include

ifndef CONFIG_KCONFIG_USEMODULE_LORAWAN
# OTAA compile time configuration keys
CFLAGS += -DCONFIG_LORAMAC_APP_KEY_DEFAULT=\"$(APPKEY)\"
CFLAGS += -DCONFIG_LORAMAC_APP_EUI_DEFAULT=\"$(APPEUI)\"
CFLAGS += -DCONFIG_LORAMAC_DEV_EUI_DEFAULT=\"$(DEVEUI)\"
ifeq (otaa,$(ACTIVATION_MODE))
# OTAA compile time configuration keys
CFLAGS += -DCONFIG_LORAMAC_APP_KEY_DEFAULT=\"$(APPKEY)\"
CFLAGS += -DCONFIG_LORAMAC_APP_EUI_DEFAULT=\"$(APPEUI)\"
CFLAGS += -DCONFIG_LORAMAC_DEV_EUI_DEFAULT=\"$(DEVEUI)\"
else ifeq (abp,$(ACTIVATION_MODE))
CFLAGS += -DCONFIG_LORAMAC_DEV_ADDR_DEFAULT=\"$(DEVADDR)\"
CFLAGS += -DCONFIG_LORAMAC_APP_SKEY_DEFAULT=\"$(APPSKEY)\"
CFLAGS += -DCONFIG_LORAMAC_NWK_SKEY_DEFAULT=\"$(NWKSKEY)\"
CFLAGS += -DCONFIG_LORAMAC_DEFAULT_RX2_FREQ=$(RX2_FREQ)
CFLAGS += -DCONFIG_LORAMAC_DEFAULT_RX2_DR=$(RX2_DR)
endif
endif
58 changes: 38 additions & 20 deletions examples/lorawan/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
LoRaWAN
=======
## LoRaWAN

Description
-----------
### Description

This application shows a simple use case of LoRaWAN with RIOT.
This application shows a basic LoRaWAN use-case with RIOT.

By using the real time clock and low-power capabilities of a board, this
application shows how to program a LoRaWAN Class A device using RIOT.
application also shows how to program a LoRaWAN Class A device using RIOT.

This application is using the Over-The-Air Activation procedure.
By default, the application uses the Over-The-Air Activation (OTAA) procedure.

Usage
-----
### Configuration

Simply build and flash the application for a ST B-L072Z-LRWAN1 board:
To join a LoRaWAN network using OTAA activation, edit the application
`Makefile` and set your device information:

make flash term
ACTIVATION_MODE ?= otaa
DEVEUI ?= 0000000000000000
APPEUI ?= 0000000000000000
APPKEY ?= 00000000000000000000000000000000

To join a LoRaWAN network using ABP activation, edit the application
`Makefile` and set your device and LoRaWAN application information:

ACTIVATION_MODE ?= abp
DEVADDR ?= 00000000
NWKSKEY ?= 00000000000000000000000000000000
APPSKEY ?= 00000000000000000000000000000000
RX2_FREQ ?= 869525000
RX2_DR ?= 3

Note that rx2 frequency (`RX2_FREQ`) and datarate (`RX2_DR`) variables must be
set explicitly at compile time when using ABP activation because they are
supposed to be known in advance by the network and the device. In this example,
the values used are compatible with TheThingsNetwork provider network.
They might change depending on the network provider used.

Use the `BOARD`, `DRIVER` and `LORA_REGION` make variables to adapt the application
to your hardware setup and region of use:
Expand All @@ -26,17 +43,18 @@ to your hardware setup and region of use:
- `LORA_REGION` can be `EU868`, `US915`, etc (see LoRaWAN regional parameters for
details).

ST Nucleo-64 can be used with mbed LoRa shields: there's one based on
[the sx1276 radio](https://os.mbed.com/components/SX1276MB1xAS/) and one based
on the [the sx1272 radio](https://os.mbed.com/components/SX1272MB2xAS/).
The `SEND_PERIOD_S` variable can also be adapted to change the time period (in
seconds) between each message sent by the device.

Finally, to join a LoRaWAN network using OTAA activation, use `make menuconfig`
inside the application and edit the configuration or edit the application
`Makefile` :
### Usage

DEVEUI ?= 0000000000000000
APPEUI ?= 0000000000000000
APPKEY ?= 00000000000000000000000000000000
Simply build and flash the application for a ST B-L072Z-LRWAN1 board:

make flash term

ST Nucleo-64 can be used as-is with mbed LoRa shields: there's one based on
[the sx1276 radio](https://os.mbed.com/components/SX1276MB1xAS/) and one based
on the [the sx1272 radio](https://os.mbed.com/components/SX1272MB2xAS/).

## Automatic test

Expand Down
83 changes: 66 additions & 17 deletions examples/lorawan/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,14 @@
#include "sx126x_params.h"
#endif

/* Messages are sent every 20s to respect the duty cycle on each channel */
#define PERIOD_S (20U)
/* By default, messages are sent every 20s to respect the duty cycle
on each channel */
#ifndef SEND_PERIOD_S
#define SEND_PERIOD_S (20U)
#endif

/* Low-power mode level */
#define PM_LOCK_LEVEL (1)

#define SENDER_PRIO (THREAD_PRIORITY_MAIN - 1)
static kernel_pid_t sender_pid;
Expand All @@ -69,9 +75,17 @@ static ztimer_t timer;

static const char *message = "This is RIOT!";

#ifdef USE_OTAA
static uint8_t deveui[LORAMAC_DEVEUI_LEN];
static uint8_t appeui[LORAMAC_APPEUI_LEN];
static uint8_t appkey[LORAMAC_APPKEY_LEN];
#endif

#ifdef USE_ABP
static uint8_t devaddr[LORAMAC_DEVADDR_LEN];
static uint8_t nwkskey[LORAMAC_NWKSKEY_LEN];
static uint8_t appskey[LORAMAC_APPSKEY_LEN];
#endif

static void _alarm_cb(void *arg)
{
Expand All @@ -86,12 +100,12 @@ static void _prepare_next_alarm(void)
struct tm time;
rtc_get_time(&time);
/* set initial alarm */
time.tm_sec += PERIOD_S;
time.tm_sec += SEND_PERIOD_S;
mktime(&time);
rtc_set_alarm(&time, _alarm_cb, NULL);
#else
timer.callback = _alarm_cb;
ztimer_set(ZTIMER_MSEC, &timer, PERIOD_S * MS_PER_SEC);
ztimer_set(ZTIMER_MSEC, &timer, SEND_PERIOD_S * MS_PER_SEC);
#endif
}

Expand Down Expand Up @@ -134,11 +148,6 @@ int main(void)
puts("LoRaWAN Class A low-power application");
puts("=====================================");

/* Convert identifiers and application key */
fmt_hex_bytes(deveui, CONFIG_LORAMAC_DEV_EUI_DEFAULT);
fmt_hex_bytes(appeui, CONFIG_LORAMAC_APP_EUI_DEFAULT);
fmt_hex_bytes(appkey, CONFIG_LORAMAC_APP_KEY_DEFAULT);

/* Initialize the radio driver */
#if IS_USED(MODULE_SX127X)
sx127x_setup(&sx127x, &sx127x_params[0], 0);
Expand All @@ -154,22 +163,62 @@ int main(void)

/* Initialize the loramac stack */
semtech_loramac_init(&loramac);

#ifdef USE_OTAA /* OTAA activation mode */
/* Convert identifiers and keys strings to byte arrays */
fmt_hex_bytes(deveui, CONFIG_LORAMAC_DEV_EUI_DEFAULT);
fmt_hex_bytes(appeui, CONFIG_LORAMAC_APP_EUI_DEFAULT);
fmt_hex_bytes(appkey, CONFIG_LORAMAC_APP_KEY_DEFAULT);
semtech_loramac_set_deveui(&loramac, deveui);
semtech_loramac_set_appeui(&loramac, appeui);
semtech_loramac_set_appkey(&loramac, appkey);

/* Use a fast datarate, e.g. BW125/SF7 in EU868 */
semtech_loramac_set_dr(&loramac, LORAMAC_DR_5);

/* Start the Over-The-Air Activation (OTAA) procedure to retrieve the
* generated device address and to get the network and application session
* keys.
*/
puts("Starting join procedure");
if (semtech_loramac_join(&loramac, LORAMAC_JOIN_OTAA) != SEMTECH_LORAMAC_JOIN_SUCCEEDED) {
puts("Join procedure failed");
return 1;
/* Join the network if not already joined */
if (!semtech_loramac_is_mac_joined(&loramac)) {
/* Start the Over-The-Air Activation (OTAA) procedure to retrieve the
* generated device address and to get the network and application session
* keys.
*/
puts("Starting join procedure");
if (semtech_loramac_join(&loramac, LORAMAC_JOIN_OTAA) != SEMTECH_LORAMAC_JOIN_SUCCEEDED) {
puts("Join procedure failed");
return 1;
}

#ifdef MODULE_PERIPH_EEPROM
/* Save current MAC state to EEPROM */
semtech_loramac_save_config(&loramac);
#endif
}
#endif

#ifdef USE_ABP /* ABP activation mode */
/* Convert identifiers and keys strings to byte arrays */
fmt_hex_bytes(devaddr, CONFIG_LORAMAC_DEV_ADDR_DEFAULT);
fmt_hex_bytes(nwkskey, CONFIG_LORAMAC_NWK_SKEY_DEFAULT);
fmt_hex_bytes(appskey, CONFIG_LORAMAC_APP_SKEY_DEFAULT);
semtech_loramac_set_devaddr(&loramac, devaddr);
semtech_loramac_set_nwkskey(&loramac, nwkskey);
semtech_loramac_set_appskey(&loramac, appskey);

/* Configure RX2 parameters */
semtech_loramac_set_rx2_freq(&loramac, CONFIG_LORAMAC_DEFAULT_RX2_FREQ);
semtech_loramac_set_rx2_dr(&loramac, CONFIG_LORAMAC_DEFAULT_RX2_DR);

#ifdef MODULE_PERIPH_EEPROM
/* Store ABP parameters to EEPROM */
semtech_loramac_save_config(&loramac);
#endif

/* Use a fast datarate, e.g. BW125/SF7 in EU868 */
semtech_loramac_set_dr(&loramac, LORAMAC_DR_5);

/* ABP join procedure always succeeds */
semtech_loramac_join(&loramac, LORAMAC_JOIN_ABP);
#endif
puts("Join procedure succeeded");

/* start the sender thread */
Expand Down

0 comments on commit 20ffa92

Please sign in to comment.