Skip to content

Commit

Permalink
examples/lorawan: add possibility to use ABP + pm
Browse files Browse the repository at this point in the history
  • Loading branch information
aabadie committed Mar 14, 2022
1 parent bec2868 commit 099833b
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 27 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

This comment has been minimized.

Copy link
@fjmolinas

fjmolinas Apr 20, 2022

Contributor

@aabadie I think this might be the reason while the release tests are failing. Since after an experiment the node EEPROM is not reset, if the device had joined previously it will not attempt to join again...

This comment has been minimized.

Copy link
@aabadie

aabadie Apr 20, 2022

Author Contributor

Indeed, we would need a call to loramac erase and then a reboot to completely reset the stored data in 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
6 changes: 3 additions & 3 deletions examples/lorawan/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
LoRaWAN
=======
LoRaWAN - OTAA
==============

Description
-----------
Expand All @@ -9,7 +9,7 @@ This application shows a simple use case of LoRaWAN 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.

This application is using the Over-The-Air Activation procedure.
This application is using the Over-The-Air Activation (OTAA) procedure.

Usage
-----
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 099833b

Please sign in to comment.