Skip to content

Commit

Permalink
examples/lorawan_abp: add ABP example + standby pm enabled
Browse files Browse the repository at this point in the history
  • Loading branch information
aabadie committed Mar 22, 2019
1 parent f33ebe6 commit 9264d67
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 0 deletions.
45 changes: 45 additions & 0 deletions examples/lorawan_abp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# name of your application
APPLICATION = lorawan

# Use the ST B-L072Z-LRWAN1 board by default:
BOARD ?= b-l072z-lrwan1

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

BOARD_INSUFFICIENT_MEMORY := nucleo-f031k6 nucleo-f042k6 nucleo-l031k6

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

# Default radio driver is Semtech SX1276 (used by the B-L072Z-LRWAN1 board)
DRIVER ?= sx1276

# Default region is Europe and default band is 868MHz
REGION ?= EU868

# Include the Semtech-loramac package
USEPKG += semtech-loramac

USEMODULE += $(DRIVER)
USEMODULE += fmt
FEATURES_REQUIRED += periph_rtc
FEATURES_REQUIRED += periph_eeprom

CFLAGS += -DREGION_$(REGION)
CFLAGS += -DDEVADDR=\"$(DEVADDR)\" -DNWKSKEY=\"$(NWKSKEY)\" -DAPPSKEY=\"$(APPSKEY)\"
CFLAGS += -DRX2_FREQ=$(RX2_FREQ) -DRX2_DR=$(RX2_DR)
CFLAGS += -DLORAMAC_ACTIVE_REGION=LORAMAC_REGION_$(REGION)

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include
38 changes: 38 additions & 0 deletions examples/lorawan_abp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
LoRaWAN - ABP
=============

Description
-----------

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 Activation-By-Personalization (ABP) procedure.

Usage
-----

Simply build and flash the application for a ST B-L072Z-LRWAN1 board:

make flash term

Use the `BOARD`, `DRIVER` and `REGION` make variables to adapt the application
to your hardware setup and region of use:

- `BOARD` can be one of the nucleo-64 boards
- `DRIVER` can be either `sx1276` or `sx1272`
- `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/).

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

DEVADDR ?= 00000000
NWKSKEY ?= 00000000000000000000000000000000
APPSKEY ?= 00000000000000000000000000000000
161 changes: 161 additions & 0 deletions examples/lorawan_abp/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* Copyright (C) 2018 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup examples
* @{
*
* @file
* @brief Example demonstrating the use of LoRaWAN with RIOT
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include "msg.h"
#include "thread.h"
#include "fmt.h"
#ifdef MODULE_PM_LAYERED
#include "pm_layered.h"
#endif

#include "periph/rtc.h"

#include "net/loramac.h"
#include "semtech_loramac.h"

/* Messages are sent every 20s to respect the duty cycle on each channel */
#define PERIOD (20U)

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

#define SENDER_PRIO (THREAD_PRIORITY_MAIN - 1)
static kernel_pid_t sender_pid;
static char sender_stack[THREAD_STACKSIZE_MAIN / 2];

semtech_loramac_t loramac;

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

static uint8_t devaddr[LORAMAC_DEVADDR_LEN];
static uint8_t nwkskey[LORAMAC_NWKSKEY_LEN];
static uint8_t appskey[LORAMAC_APPSKEY_LEN];

static void rtc_cb(void *arg)
{
(void) arg;

#ifdef MODULE_PM_LAYERED
/* block sleep level mode until the next sending cycle has completed */
pm_block(PM_LOCK_LEVEL);
#endif

msg_t msg;
msg_send(&msg, sender_pid);
}

static void _prepare_next_alarm(void)
{
struct tm time;
rtc_get_time(&time);
/* set initial alarm */
time.tm_sec += PERIOD;
mktime(&time);
rtc_set_alarm(&time, rtc_cb, NULL);
}

static void _send_message(void)
{
printf("Sending: %s\n", message);
/* Try to send a message */
uint8_t ret = semtech_loramac_send(&loramac,
(uint8_t *)message, strlen(message));
if (ret != SEMTECH_LORAMAC_TX_OK) {
printf("Cannot send message '%s', ret code: %d\n", message, ret);
return;
}
/* The send was successfully scheduled, now wait until the send cycle has
completed and a reply is received from the MAC */
semtech_loramac_recv(&loramac);
}

static void *sender(void *arg)
{
(void)arg;

msg_t msg;
msg_t msg_queue[8];
msg_init_queue(msg_queue, 8);

while (1) {
msg_receive(&msg);

/* Trigger the message send */
_send_message();

/* Schedule the next wake-up alarm */
_prepare_next_alarm();

#ifdef MODULE_PM_LAYERED
/* go back to sleep */
pm_unblock(PM_LOCK_LEVEL);
#endif
}

/* this should never be reached */
return NULL;
}

int main(void)
{
puts("LoRaWAN Class A low-power application");
puts("=====================================");

/* Convert identifiers and application key */
fmt_hex_bytes(devaddr, DEVADDR);
fmt_hex_bytes(nwkskey, NWKSKEY);
fmt_hex_bytes(appskey, APPSKEY);

/* Initialize the loramac stack */
semtech_loramac_init(&loramac);
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, RX2_FREQ);
semtech_loramac_set_rx2_dr(&loramac, RX2_DR);

/* Store ABP parameters to EEPROM */
semtech_loramac_save_config(&loramac);

/* 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);

/* start the sender thread */
sender_pid = thread_create(sender_stack, sizeof(sender_stack),
SENDER_PRIO, 0, sender, NULL, "sender");

/* unlock the lowest possible low-power mode */
pm_unblock(0);

/* trigger the first send */
msg_t msg;
msg_send(&msg, sender_pid);
return 0;
}

0 comments on commit 9264d67

Please sign in to comment.