pkg: add Semtech LoRaMAC package
This commit is contained in:
parent
f9eabb5d69
commit
96e059d88a
16
pkg/semtech-loramac/Makefile
Normal file
16
pkg/semtech-loramac/Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
PKG_NAME=semtech-loramac
|
||||||
|
PKG_URL=git://github.com/Lora-net/LoRaMac-node.git
|
||||||
|
PKG_VERSION=f42be67be402a40b3586724800771bfe13fb18e6
|
||||||
|
PKG_LICENSE=BSD-3-Clause
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
|
||||||
|
all: git-download
|
||||||
|
cp Makefile.loramac $(PKG_BUILDDIR)/Makefile
|
||||||
|
cp Makefile.loramac_mac $(PKG_BUILDDIR)/src/mac/Makefile
|
||||||
|
cp Makefile.loramac_region $(PKG_BUILDDIR)/src/mac/region/Makefile
|
||||||
|
cp Makefile.loramac_crypto $(PKG_BUILDDIR)/src/system/crypto/Makefile
|
||||||
|
cp Makefile.loramac_arch $(PKG_BUILDDIR)/src/boards/mcu/stm32/Makefile
|
||||||
|
"$(MAKE)" -C $(PKG_BUILDDIR)
|
||||||
|
|
||||||
|
include $(RIOTBASE)/pkg/pkg.mk
|
||||||
7
pkg/semtech-loramac/Makefile.dep
Normal file
7
pkg/semtech-loramac/Makefile.dep
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
USEMODULE += random
|
||||||
|
|
||||||
|
USEMODULE += semtech_loramac_contrib
|
||||||
|
USEMODULE += semtech_loramac_mac
|
||||||
|
USEMODULE += semtech_loramac_mac_region
|
||||||
|
USEMODULE += semtech_loramac_crypto
|
||||||
|
USEMODULE += semtech_loramac_arch
|
||||||
3
pkg/semtech-loramac/Makefile.include
Normal file
3
pkg/semtech-loramac/Makefile.include
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
INCLUDES += -I$(RIOTBASE)/pkg/semtech-loramac/include
|
||||||
|
|
||||||
|
DIRS += $(RIOTBASE)/pkg/semtech-loramac/contrib
|
||||||
11
pkg/semtech-loramac/Makefile.loramac
Normal file
11
pkg/semtech-loramac/Makefile.loramac
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
DIRS += src/mac
|
||||||
|
DIRS += src/mac/region
|
||||||
|
DIRS += src/system/crypto
|
||||||
|
DIRS += src/boards/mcu/stm32
|
||||||
|
|
||||||
|
INCLUDES += -I$(PKGDIRBASE)/semtech-loramac/src/mac \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src/boards/mcu/stm32 \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src/system/crypto \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
7
pkg/semtech-loramac/Makefile.loramac_arch
Normal file
7
pkg/semtech-loramac/Makefile.loramac_arch
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
MODULE := semtech_loramac_arch
|
||||||
|
|
||||||
|
SRCS := utilities.c
|
||||||
|
|
||||||
|
CFLAGS += -Wno-sign-compare
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
3
pkg/semtech-loramac/Makefile.loramac_crypto
Normal file
3
pkg/semtech-loramac/Makefile.loramac_crypto
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
MODULE := semtech_loramac_crypto
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
5
pkg/semtech-loramac/Makefile.loramac_mac
Normal file
5
pkg/semtech-loramac/Makefile.loramac_mac
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
MODULE := semtech_loramac_mac
|
||||||
|
|
||||||
|
CFLAGS += -Wno-sign-compare
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
5
pkg/semtech-loramac/Makefile.loramac_region
Normal file
5
pkg/semtech-loramac/Makefile.loramac_region
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
MODULE := semtech_loramac_mac_region
|
||||||
|
|
||||||
|
CFLAGS += -Wno-missing-field-initializers -Wno-unused-parameter -Wno-sign-compare
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
8
pkg/semtech-loramac/contrib/Makefile
Normal file
8
pkg/semtech-loramac/contrib/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
MODULE := semtech_loramac_contrib
|
||||||
|
|
||||||
|
INCLUDES += -I$(PKGDIRBASE)/semtech-loramac/src/mac \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src/boards/mcu/stm32 \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src/system/crypto \
|
||||||
|
-I$(PKGDIRBASE)/semtech-loramac/src
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
615
pkg/semtech-loramac/contrib/semtech_loramac.c
Normal file
615
pkg/semtech-loramac/contrib/semtech_loramac.c
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Inria
|
||||||
|
* 2017 Inria Chile
|
||||||
|
*
|
||||||
|
* 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 pkg_semtech-loramac
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Implementation of public API for Semtech LoRaMAC
|
||||||
|
*
|
||||||
|
* This implementation is an adaption of the applications provided on the
|
||||||
|
* Semtech Lora-net repository.
|
||||||
|
*
|
||||||
|
* The LoRaMAC stack and the SX127x driver run in their own thread and simple
|
||||||
|
* IPC messages are exchanged to control the MAC.
|
||||||
|
*
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @author Jose Alamos <jose.alamos@inria.cl>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "msg.h"
|
||||||
|
|
||||||
|
#include "net/netdev.h"
|
||||||
|
#include "net/loramac.h"
|
||||||
|
|
||||||
|
#include "sx127x.h"
|
||||||
|
#include "sx127x_params.h"
|
||||||
|
#include "sx127x_netdev.h"
|
||||||
|
|
||||||
|
#include "semtech_loramac.h"
|
||||||
|
#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
#include "region/Region.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#define LORAWAN_MAX_JOIN_RETRIES (3U)
|
||||||
|
|
||||||
|
#if defined(REGION_EU868)
|
||||||
|
#define LORAWAN_DUTYCYCLE_ON (true)
|
||||||
|
#define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP (1)
|
||||||
|
|
||||||
|
#if (USE_SEMTECH_DEFAULT_CHANNEL_LINEUP)
|
||||||
|
#define LC4 { 867100000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||||
|
#define LC5 { 867300000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||||
|
#define LC6 { 867500000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||||
|
#define LC7 { 867700000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||||
|
#define LC8 { 867900000, 0, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
|
||||||
|
#define LC9 { 868800000, 0, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
|
||||||
|
#define LC10 { 868300000, 0, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
|
||||||
|
#endif /* USE_SEMTECH_DEFAULT_CHANNEL_LINEUP */
|
||||||
|
#endif /* REGION_EU868 */
|
||||||
|
|
||||||
|
#define SEMTECH_LORAMAC_MSG_QUEUE (16U)
|
||||||
|
#define SEMTECH_LORAMAC_LORAMAC_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
|
||||||
|
static char _semtech_loramac_stack[SEMTECH_LORAMAC_LORAMAC_STACKSIZE];
|
||||||
|
kernel_pid_t semtech_loramac_pid;
|
||||||
|
kernel_pid_t semtech_loramac_handler_pid;
|
||||||
|
|
||||||
|
RadioEvents_t semtech_loramac_radio_events;
|
||||||
|
uint8_t semtech_loramac_dev_eui[LORAMAC_DEVEUI_LEN];
|
||||||
|
uint8_t semtech_loramac_app_eui[LORAMAC_APPEUI_LEN];
|
||||||
|
uint8_t semtech_loramac_app_key[LORAMAC_APPKEY_LEN];
|
||||||
|
uint8_t semtech_loramac_nwk_skey[LORAMAC_NWKSKEY_LEN];
|
||||||
|
uint8_t semtech_loramac_app_skey[LORAMAC_APPSKEY_LEN];
|
||||||
|
uint8_t semtech_loramac_dev_addr[LORAMAC_DEVADDR_LEN];
|
||||||
|
|
||||||
|
static uint8_t _semtech_loramac_radio_payload[SX127X_RX_BUFFER_SIZE];
|
||||||
|
static semtech_loramac_rx_data_t _semtech_loramac_rx_data;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t port;
|
||||||
|
uint8_t cnf;
|
||||||
|
uint8_t dr;
|
||||||
|
uint8_t *payload;
|
||||||
|
uint8_t len;
|
||||||
|
} loramac_send_params_t;
|
||||||
|
|
||||||
|
typedef void (*semtech_loramac_func_t)(void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Struct containing a semtech loramac function call
|
||||||
|
*
|
||||||
|
* This function is called inside the semtech loramac thread context.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
semtech_loramac_func_t func; /**< the function to call. */
|
||||||
|
void *arg; /**< argument of the function **/
|
||||||
|
} semtech_loramac_call_t;
|
||||||
|
|
||||||
|
/* Prepares the payload of the frame */
|
||||||
|
static bool _semtech_loramac_send(uint8_t cnf, uint8_t port, uint8_t dr,
|
||||||
|
uint8_t *payload, uint8_t len)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] send frame %s\n", (char *)payload);
|
||||||
|
McpsReq_t mcpsReq;
|
||||||
|
LoRaMacTxInfo_t txInfo;
|
||||||
|
|
||||||
|
if (LoRaMacQueryTxPossible(len, &txInfo) != LORAMAC_STATUS_OK) {
|
||||||
|
DEBUG("[semtech-loramac] empty frame in order to flush MAC commands\n");
|
||||||
|
/* Send empty frame in order to flush MAC commands */
|
||||||
|
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||||
|
mcpsReq.Req.Unconfirmed.fBuffer = NULL;
|
||||||
|
mcpsReq.Req.Unconfirmed.fBufferSize = 0;
|
||||||
|
mcpsReq.Req.Unconfirmed.Datarate = (int8_t)dr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (cnf == LORAMAC_TX_UNCNF) {
|
||||||
|
DEBUG("[semtech-loramac] MCPS_UNCONFIRMED\n");
|
||||||
|
mcpsReq.Type = MCPS_UNCONFIRMED;
|
||||||
|
mcpsReq.Req.Unconfirmed.fPort = port;
|
||||||
|
mcpsReq.Req.Unconfirmed.fBuffer = payload;
|
||||||
|
mcpsReq.Req.Unconfirmed.fBufferSize = len;
|
||||||
|
mcpsReq.Req.Unconfirmed.Datarate = (int8_t)dr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("[semtech-loramac] MCPS_CONFIRMED\n");
|
||||||
|
mcpsReq.Type = MCPS_CONFIRMED;
|
||||||
|
mcpsReq.Req.Confirmed.fPort = port;
|
||||||
|
mcpsReq.Req.Confirmed.fBuffer = payload;
|
||||||
|
mcpsReq.Req.Confirmed.fBufferSize = len;
|
||||||
|
mcpsReq.Req.Confirmed.NbTrials = 3;
|
||||||
|
mcpsReq.Req.Confirmed.Datarate = (int8_t)dr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LoRaMacMcpsRequest(&mcpsReq) == LORAMAC_STATUS_OK) {
|
||||||
|
DEBUG("[semtech-loramac] MCPS request OK\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MCPS-Confirm event function */
|
||||||
|
static void mcps_confirm(McpsConfirm_t *confirm)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event\n");
|
||||||
|
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event OK\n");
|
||||||
|
|
||||||
|
switch (confirm->McpsRequest) {
|
||||||
|
case MCPS_UNCONFIRMED:
|
||||||
|
{
|
||||||
|
/* Check Datarate
|
||||||
|
Check TxPower */
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event UNCONFIRMED\n");
|
||||||
|
msg_t msg;
|
||||||
|
msg.type = MSG_TYPE_LORAMAC_NOTIFY;
|
||||||
|
msg.content.value = SEMTECH_LORAMAC_TX_DONE;
|
||||||
|
msg_send(&msg, semtech_loramac_handler_pid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MCPS_CONFIRMED:
|
||||||
|
/* Check Datarate
|
||||||
|
Check TxPower
|
||||||
|
Check AckReceived
|
||||||
|
Check NbTrials */
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event CONFIRMED\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCPS_PROPRIETARY:
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event PROPRIETARY\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG("[semtech-loramac] MCPS confirm event UNKNOWN\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MCPS-Indication event function */
|
||||||
|
static void mcps_indication(McpsIndication_t *indication)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication event\n");
|
||||||
|
if (indication->Status != LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication no OK\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ENABLE_DEBUG) {
|
||||||
|
switch (indication->McpsIndication) {
|
||||||
|
case MCPS_UNCONFIRMED:
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication Unconfirmed\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCPS_CONFIRMED:
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication Confirmed\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCPS_PROPRIETARY:
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication Proprietary\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MCPS_MULTICAST:
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication Multicast\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_t msg;
|
||||||
|
msg.type = MSG_TYPE_LORAMAC_NOTIFY;
|
||||||
|
if (indication->RxData) {
|
||||||
|
indication->Buffer[indication->BufferSize] = '\0';
|
||||||
|
memcpy(_semtech_loramac_rx_data.payload, indication->Buffer,
|
||||||
|
indication->BufferSize);
|
||||||
|
_semtech_loramac_rx_data.payload[indication->BufferSize] = 0;
|
||||||
|
_semtech_loramac_rx_data.payload_len = indication->BufferSize;
|
||||||
|
_semtech_loramac_rx_data.port = indication->Port;
|
||||||
|
DEBUG("[semtech-loramac] MCPS indication:\n"
|
||||||
|
" - Payload: %s\n"
|
||||||
|
" - Size: %d\n"
|
||||||
|
" - Port: %d\n",
|
||||||
|
(char *)_semtech_loramac_rx_data.payload,
|
||||||
|
_semtech_loramac_rx_data.payload_len,
|
||||||
|
_semtech_loramac_rx_data.port
|
||||||
|
);
|
||||||
|
msg.content.value = SEMTECH_LORAMAC_RX_DATA;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.content.value = SEMTECH_LORAMAC_TX_DONE;
|
||||||
|
}
|
||||||
|
msg_send(&msg, semtech_loramac_handler_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*MLME-Confirm event function */
|
||||||
|
static void mlme_confirm(MlmeConfirm_t *confirm)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] MLME confirm event\n");
|
||||||
|
switch (confirm->MlmeRequest) {
|
||||||
|
case MLME_JOIN:
|
||||||
|
if (confirm->Status == LORAMAC_EVENT_INFO_STATUS_OK) {
|
||||||
|
/* Status is OK, node has joined the network */
|
||||||
|
DEBUG("[semtech-loramac] join succeeded\n");
|
||||||
|
msg_t msg;
|
||||||
|
msg.type = MSG_TYPE_LORAMAC_NOTIFY;
|
||||||
|
msg.content.value = SEMTECH_LORAMAC_JOIN_SUCCEEDED;
|
||||||
|
msg_send(&msg, semtech_loramac_handler_pid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("[semtech-loramac] join not successful\n");
|
||||||
|
/* Join was not successful. */
|
||||||
|
msg_t msg;
|
||||||
|
msg.type = MSG_TYPE_LORAMAC_NOTIFY;
|
||||||
|
msg.content.value = SEMTECH_LORAMAC_JOIN_FAILED;
|
||||||
|
msg_send(&msg, semtech_loramac_handler_pid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loramac_set_rx2_params(uint32_t freq, uint8_t dr)
|
||||||
|
{
|
||||||
|
Rx2ChannelParams_t params;
|
||||||
|
params.Frequency = freq;
|
||||||
|
params.Datarate = dr;
|
||||||
|
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
|
||||||
|
mibReq.Param.Rx2DefaultChannel = params;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
mibReq.Type = MIB_RX2_CHANNEL;
|
||||||
|
mibReq.Param.Rx2Channel = params;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _init_loramac(LoRaMacPrimitives_t * primitives, LoRaMacCallback_t *callbacks)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] initializing loramac\n");
|
||||||
|
primitives->MacMcpsConfirm = mcps_confirm;
|
||||||
|
primitives->MacMcpsIndication = mcps_indication;
|
||||||
|
primitives->MacMlmeConfirm = mlme_confirm;
|
||||||
|
#if defined(REGION_AS923)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for AS923 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_AS923);
|
||||||
|
#elif defined(REGION_AU915)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for AU915 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_AU915);
|
||||||
|
#elif defined(REGION_CN779)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for CN779 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_CN779);
|
||||||
|
#elif defined(REGION_EU868)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for EU868 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_EU868);
|
||||||
|
#elif defined(REGION_IN865)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for IN865 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_IN865);
|
||||||
|
#elif defined(REGION_KR920)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for KR920 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_KR920);
|
||||||
|
#elif defined(REGION_US915)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for US915 region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_US915);
|
||||||
|
#elif defined(REGION_US915_HYBRID)
|
||||||
|
DEBUG("[semtech-loramac] initialize loramac for US915 hybrid region\n");
|
||||||
|
LoRaMacInitialization(&semtech_loramac_radio_events, primitives, callbacks,
|
||||||
|
LORAMAC_REGION_US915_HYBRID);
|
||||||
|
#else
|
||||||
|
#error "Please define a region in the compiler options."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(REGION_EU868) && USE_SEMTECH_DEFAULT_CHANNEL_LINEUP
|
||||||
|
DEBUG("[semtech-loramac] EU868 region: use default channels\n");
|
||||||
|
LoRaMacChannelAdd(3, (ChannelParams_t)LC4);
|
||||||
|
LoRaMacChannelAdd(4, (ChannelParams_t)LC5);
|
||||||
|
LoRaMacChannelAdd(5, (ChannelParams_t)LC6);
|
||||||
|
LoRaMacChannelAdd(6, (ChannelParams_t)LC7);
|
||||||
|
LoRaMacChannelAdd(7, (ChannelParams_t)LC8);
|
||||||
|
LoRaMacChannelAdd(8, (ChannelParams_t)LC9);
|
||||||
|
LoRaMacChannelAdd(9, (ChannelParams_t)LC10);
|
||||||
|
|
||||||
|
_loramac_set_rx2_params(LORAMAC_DEFAULT_RX2_FREQ, LORAMAC_DEFAULT_RX2_DR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _join_otaa(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] starting OTAA join\n");
|
||||||
|
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_NETWORK_JOINED;
|
||||||
|
mibReq.Param.IsNetworkJoined = false;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
MlmeReq_t mlmeReq;
|
||||||
|
mlmeReq.Type = MLME_JOIN;
|
||||||
|
mlmeReq.Req.Join.DevEui = semtech_loramac_dev_eui;
|
||||||
|
mlmeReq.Req.Join.AppEui = semtech_loramac_app_eui;
|
||||||
|
mlmeReq.Req.Join.AppKey = semtech_loramac_app_key;
|
||||||
|
mlmeReq.Req.Join.NbTrials = LORAWAN_MAX_JOIN_RETRIES;
|
||||||
|
LoRaMacMlmeRequest(&mlmeReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _join_abp(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] starting ABP join\n");
|
||||||
|
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_NETWORK_JOINED;
|
||||||
|
mibReq.Param.IsNetworkJoined = false;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
semtech_loramac_set_netid(LORAMAC_DEFAULT_NETID);
|
||||||
|
|
||||||
|
mibReq.Type = MIB_DEV_ADDR;
|
||||||
|
mibReq.Param.DevAddr = ((uint32_t)semtech_loramac_dev_addr[0] << 24 |
|
||||||
|
(uint32_t)semtech_loramac_dev_addr[1] << 16 |
|
||||||
|
(uint32_t)semtech_loramac_dev_addr[2] << 8 |
|
||||||
|
(uint32_t)semtech_loramac_dev_addr[3]);
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
mibReq.Type = MIB_NWK_SKEY;
|
||||||
|
mibReq.Param.NwkSKey = semtech_loramac_nwk_skey;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
mibReq.Type = MIB_APP_SKEY;
|
||||||
|
mibReq.Param.AppSKey = semtech_loramac_app_skey;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
mibReq.Type = MIB_NETWORK_JOINED;
|
||||||
|
mibReq.Param.IsNetworkJoined = true;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _join(void *arg)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
uint8_t join_type = *(uint8_t *)arg;
|
||||||
|
|
||||||
|
switch (join_type) {
|
||||||
|
case LORAMAC_JOIN_OTAA:
|
||||||
|
_join_otaa();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LORAMAC_JOIN_ABP:
|
||||||
|
_join_abp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _send(void *arg)
|
||||||
|
{
|
||||||
|
loramac_send_params_t params = *(loramac_send_params_t *)arg;
|
||||||
|
_semtech_loramac_send(params.cnf, params.port, params.dr,
|
||||||
|
params.payload, params.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _semtech_loramac_call(semtech_loramac_func_t func, void *arg)
|
||||||
|
{
|
||||||
|
semtech_loramac_call_t call;
|
||||||
|
call.func = func;
|
||||||
|
call.arg = arg;
|
||||||
|
|
||||||
|
msg_t msg;
|
||||||
|
msg.type = MSG_TYPE_LORAMAC_CMD;
|
||||||
|
msg.content.ptr = &call;
|
||||||
|
msg_send(&msg, semtech_loramac_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _semtech_loramac_event_cb(netdev_t *dev, netdev_event_t event)
|
||||||
|
{
|
||||||
|
netdev_sx127x_lora_packet_info_t packet_info;
|
||||||
|
|
||||||
|
msg_t msg;
|
||||||
|
msg.content.ptr = dev;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NETDEV_EVENT_ISR:
|
||||||
|
msg.type = MSG_TYPE_ISR;
|
||||||
|
if (msg_send(&msg, semtech_loramac_pid) <= 0) {
|
||||||
|
DEBUG("[semtech-loramac] possibly lost interrupt.\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_TX_COMPLETE:
|
||||||
|
sx127x_set_sleep((sx127x_t *)dev);
|
||||||
|
semtech_loramac_radio_events.TxDone();
|
||||||
|
DEBUG("[semtech-loramac] Transmission completed\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_TX_TIMEOUT:
|
||||||
|
msg.type = MSG_TYPE_TX_TIMEOUT;
|
||||||
|
if (msg_send(&msg, semtech_loramac_pid) <= 0) {
|
||||||
|
DEBUG("[semtech-loramac] TX timeout, possibly lost interrupt.\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_RX_COMPLETE:
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
len = dev->driver->recv(dev, NULL, 0, 0);
|
||||||
|
dev->driver->recv(dev, _semtech_loramac_radio_payload, len, &packet_info);
|
||||||
|
semtech_loramac_radio_events.RxDone(_semtech_loramac_radio_payload,
|
||||||
|
len,
|
||||||
|
packet_info.rssi,
|
||||||
|
packet_info.snr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NETDEV_EVENT_RX_TIMEOUT:
|
||||||
|
msg.type = MSG_TYPE_RX_TIMEOUT;
|
||||||
|
if (msg_send(&msg, semtech_loramac_pid) <= 0) {
|
||||||
|
DEBUG("[semtech-loramac] RX timeout, possibly lost interrupt.\n");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_CRC_ERROR:
|
||||||
|
DEBUG("[semtech-loramac] RX CRC error\n");
|
||||||
|
semtech_loramac_radio_events.RxError();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_FHSS_CHANGE_CHANNEL:
|
||||||
|
DEBUG("[semtech-loramac] FHSS channel change\n");
|
||||||
|
semtech_loramac_radio_events.FhssChangeChannel(((sx127x_t *)dev)->_internal.last_channel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NETDEV_EVENT_CAD_DONE:
|
||||||
|
DEBUG("[semtech-loramac] test: CAD done\n");
|
||||||
|
semtech_loramac_radio_events.CadDone(((sx127x_t *)dev)->_internal.is_last_cad_success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG("[semtech-loramac] unexpected netdev event received: %d\n",
|
||||||
|
event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *_semtech_loramac_event_loop(void *arg)
|
||||||
|
{
|
||||||
|
(void) arg;
|
||||||
|
static msg_t _msg_q[SEMTECH_LORAMAC_MSG_QUEUE];
|
||||||
|
msg_init_queue(_msg_q, SEMTECH_LORAMAC_MSG_QUEUE);
|
||||||
|
LoRaMacPrimitives_t primitives;
|
||||||
|
LoRaMacCallback_t callbacks;
|
||||||
|
|
||||||
|
_init_loramac(&primitives, &callbacks);
|
||||||
|
semtech_loramac_set_dr(LORAMAC_DEFAULT_DR);
|
||||||
|
semtech_loramac_set_adr(LORAMAC_DEFAULT_ADR);
|
||||||
|
semtech_loramac_set_public_network(LORAMAC_DEFAULT_PUBLIC_NETWORK);
|
||||||
|
semtech_loramac_set_class(LORAMAC_DEFAULT_DEVICE_CLASS);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
msg_t msg;
|
||||||
|
msg_receive(&msg);
|
||||||
|
switch (msg.type) {
|
||||||
|
case MSG_TYPE_ISR:
|
||||||
|
{
|
||||||
|
netdev_t *dev = msg.content.ptr;
|
||||||
|
dev->driver->isr(dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSG_TYPE_RX_TIMEOUT:
|
||||||
|
DEBUG("[semtech-loramac] RX timer timeout\n");
|
||||||
|
semtech_loramac_radio_events.RxTimeout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_TYPE_TX_TIMEOUT:
|
||||||
|
DEBUG("[semtech-loramac] TX timer timeout\n");
|
||||||
|
semtech_loramac_radio_events.TxTimeout();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MSG_TYPE_MAC_TIMEOUT:
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] MAC timer timeout\n");
|
||||||
|
void (*callback)(void) = msg.content.ptr;
|
||||||
|
callback();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSG_TYPE_LORAMAC_CMD:
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] loramac cmd\n");
|
||||||
|
semtech_loramac_call_t *call = msg.content.ptr;
|
||||||
|
call->func(call->arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DEBUG("[semtech-loramac] Unexpected msg type '%04x'\n", msg.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int semtech_loramac_init(sx127x_t *dev)
|
||||||
|
{
|
||||||
|
dev->netdev.driver = &sx127x_driver;
|
||||||
|
dev->netdev.event_callback = _semtech_loramac_event_cb;
|
||||||
|
|
||||||
|
semtech_loramac_handler_pid = thread_getpid();
|
||||||
|
semtech_loramac_pid = thread_create(_semtech_loramac_stack,
|
||||||
|
sizeof(_semtech_loramac_stack),
|
||||||
|
THREAD_PRIORITY_MAIN - 1,
|
||||||
|
THREAD_CREATE_STACKTEST,
|
||||||
|
_semtech_loramac_event_loop, NULL,
|
||||||
|
"recv_thread");
|
||||||
|
|
||||||
|
if (semtech_loramac_pid <= KERNEL_PID_UNDEF) {
|
||||||
|
DEBUG("Creation of receiver thread failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t semtech_loramac_join(uint8_t type)
|
||||||
|
{
|
||||||
|
_semtech_loramac_call(_join, &type);
|
||||||
|
|
||||||
|
if (type == LORAMAC_JOIN_OTAA) {
|
||||||
|
/* Wait until the OTAA join procedure is complete */
|
||||||
|
msg_t msg;
|
||||||
|
msg_receive(&msg);
|
||||||
|
return (uint8_t)msg.content.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ABP join procedure always works */
|
||||||
|
return SEMTECH_LORAMAC_JOIN_SUCCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t semtech_loramac_send(uint8_t cnf, uint8_t port,
|
||||||
|
uint8_t *tx_buf, uint8_t tx_len,
|
||||||
|
semtech_loramac_rx_data_t *rx_data)
|
||||||
|
{
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_NETWORK_JOINED;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
|
||||||
|
if (!mibReq.Param.IsNetworkJoined) {
|
||||||
|
DEBUG("[semtech-loramac] network is not joined\n");
|
||||||
|
return SEMTECH_LORAMAC_NOT_JOINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
loramac_send_params_t params;
|
||||||
|
params.cnf = cnf;
|
||||||
|
params.port = port;
|
||||||
|
params.dr = semtech_loramac_get_dr();
|
||||||
|
params.payload = tx_buf;
|
||||||
|
params.len = tx_len;
|
||||||
|
|
||||||
|
_semtech_loramac_call(_send, ¶ms);
|
||||||
|
|
||||||
|
/* Wait until sending is fully done */
|
||||||
|
msg_t msg;
|
||||||
|
msg_receive(&msg);
|
||||||
|
uint8_t status = (uint8_t)msg.content.value;
|
||||||
|
if (status == SEMTECH_LORAMAC_RX_DATA) {
|
||||||
|
memcpy(rx_data, &_semtech_loramac_rx_data,
|
||||||
|
sizeof(semtech_loramac_rx_data_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
243
pkg/semtech-loramac/contrib/semtech_loramac_getset.c
Normal file
243
pkg/semtech-loramac/contrib/semtech_loramac_getset.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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 pkg_semtech-loramac
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Get/Set functions of the public API for Semtech LoRaMAC
|
||||||
|
*
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "net/loramac.h"
|
||||||
|
|
||||||
|
#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
extern uint8_t semtech_loramac_dev_eui[LORAMAC_DEVEUI_LEN];
|
||||||
|
extern uint8_t semtech_loramac_app_eui[LORAMAC_APPEUI_LEN];
|
||||||
|
extern uint8_t semtech_loramac_app_key[LORAMAC_APPKEY_LEN];
|
||||||
|
extern uint8_t semtech_loramac_nwk_skey[LORAMAC_NWKSKEY_LEN];
|
||||||
|
extern uint8_t semtech_loramac_app_skey[LORAMAC_APPSKEY_LEN];
|
||||||
|
extern uint8_t semtech_loramac_dev_addr[LORAMAC_DEVADDR_LEN];
|
||||||
|
|
||||||
|
extern void _loramac_set_rx2_params(uint32_t freq, uint8_t dr);
|
||||||
|
|
||||||
|
void semtech_loramac_set_deveui(const uint8_t *eui)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_dev_eui, eui, LORAMAC_DEVEUI_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_deveui(uint8_t *eui)
|
||||||
|
{
|
||||||
|
memcpy(eui, semtech_loramac_dev_eui, LORAMAC_DEVEUI_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_appeui(const uint8_t *eui)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_app_eui, eui, LORAMAC_APPEUI_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_appeui(uint8_t *eui)
|
||||||
|
{
|
||||||
|
memcpy(eui, semtech_loramac_app_eui, LORAMAC_APPEUI_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_appkey(const uint8_t *key)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_app_key, key, LORAMAC_APPKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_appkey(uint8_t *key)
|
||||||
|
{
|
||||||
|
memcpy(key, semtech_loramac_app_key, LORAMAC_APPKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_appskey(const uint8_t *skey)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_app_skey, skey, LORAMAC_APPSKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_appskey(uint8_t *skey)
|
||||||
|
{
|
||||||
|
memcpy(skey, semtech_loramac_app_skey, LORAMAC_APPSKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_nwkskey(const uint8_t *skey)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_nwk_skey, skey, LORAMAC_NWKSKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_nwkskey(uint8_t *skey)
|
||||||
|
{
|
||||||
|
memcpy(skey, semtech_loramac_nwk_skey, LORAMAC_NWKSKEY_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_devaddr(const uint8_t *addr)
|
||||||
|
{
|
||||||
|
memcpy(semtech_loramac_dev_addr, addr, LORAMAC_DEVADDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_get_devaddr(uint8_t *addr)
|
||||||
|
{
|
||||||
|
memcpy(addr, semtech_loramac_dev_addr, LORAMAC_DEVADDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_class(loramac_class_t cls)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set class %d\n", cls);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_DEVICE_CLASS;
|
||||||
|
mibReq.Param.Class = (DeviceClass_t)cls;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
loramac_class_t semtech_loramac_get_class(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get device class\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_DEVICE_CLASS;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return (loramac_class_t)mibReq.Param.Class;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_dr(uint8_t dr)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set dr %d\n", dr);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_CHANNELS_DEFAULT_DATARATE;
|
||||||
|
mibReq.Param.ChannelsDatarate = dr;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t semtech_loramac_get_dr(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get dr\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_CHANNELS_DEFAULT_DATARATE;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return (uint8_t)mibReq.Param.ChannelsDatarate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_adr(bool adr)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set adr %d\n", adr);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_ADR;
|
||||||
|
mibReq.Param.AdrEnable = adr;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool semtech_loramac_get_adr(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get adr\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_ADR;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return mibReq.Param.AdrEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_public_network(bool public)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set public network %d\n", public);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_PUBLIC_NETWORK;
|
||||||
|
mibReq.Param.EnablePublicNetwork = public;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool semtech_loramac_get_public_network(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get public network\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_PUBLIC_NETWORK;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return mibReq.Param.EnablePublicNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_netid(uint32_t netid)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set NetID %lu\n", netid);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_NET_ID;
|
||||||
|
mibReq.Param.NetID = netid;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t semtech_loramac_get_netid(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get NetID\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_NET_ID;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return mibReq.Param.NetID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_tx_power(uint8_t power)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] set TX power %d\n", power);
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_CHANNELS_TX_POWER;
|
||||||
|
mibReq.Param.ChannelsTxPower = power;
|
||||||
|
LoRaMacMibSetRequestConfirm(&mibReq);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t semtech_loramac_get_tx_power(void)
|
||||||
|
{
|
||||||
|
DEBUG("[semtech-loramac] get TX power\n");
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_CHANNELS_TX_POWER;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return (uint8_t)mibReq.Param.ChannelsTxPower;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_rx2_freq(uint8_t freq)
|
||||||
|
{
|
||||||
|
Rx2ChannelParams_t params;
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
params.Frequency = freq;
|
||||||
|
params.Datarate = mibReq.Param.Rx2DefaultChannel.Datarate;
|
||||||
|
_loramac_set_rx2_params(params.Frequency, params.Datarate);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t semtech_loramac_get_rx2_freq(void)
|
||||||
|
{
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return mibReq.Param.Rx2DefaultChannel.Frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void semtech_loramac_set_rx2_dr(uint8_t dr)
|
||||||
|
{
|
||||||
|
Rx2ChannelParams_t params;
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
params.Datarate = dr;
|
||||||
|
params.Frequency = mibReq.Param.Rx2DefaultChannel.Frequency;
|
||||||
|
_loramac_set_rx2_params(params.Frequency, params.Datarate);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t semtech_loramac_get_rx2_dr(void)
|
||||||
|
{
|
||||||
|
MibRequestConfirm_t mibReq;
|
||||||
|
mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
|
||||||
|
LoRaMacMibGetRequestConfirm(&mibReq);
|
||||||
|
return mibReq.Param.Rx2DefaultChannel.Datarate;
|
||||||
|
}
|
||||||
253
pkg/semtech-loramac/contrib/semtech_loramac_radio.c
Normal file
253
pkg/semtech-loramac/contrib/semtech_loramac_radio.c
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Fundacion Inria Chile
|
||||||
|
* 2017 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 pkg_semtech-loramac
|
||||||
|
* @file
|
||||||
|
* @brief Compatibility functions for controlling the radio driver
|
||||||
|
*
|
||||||
|
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @author Francisco Molina <francisco.molina@inria.cl>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "net/lora.h"
|
||||||
|
#include "net/netdev.h"
|
||||||
|
|
||||||
|
#include "sx127x.h"
|
||||||
|
#include "sx127x_internal.h"
|
||||||
|
#include "sx127x_netdev.h"
|
||||||
|
|
||||||
|
#include "semtech-loramac/board.h"
|
||||||
|
|
||||||
|
#include "radio/radio.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
extern sx127x_t sx127x;
|
||||||
|
|
||||||
|
#define LORAMAC_RX_WINDOW_DURATION (600UL * US_PER_MS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Radio driver functions implementation wrappers, the netdev2 object
|
||||||
|
* is known within the scope of the function
|
||||||
|
*/
|
||||||
|
void SX127XInit(RadioEvents_t *events)
|
||||||
|
{
|
||||||
|
(void) events;
|
||||||
|
sx127x_init(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioState_t SX127XGetStatus(void)
|
||||||
|
{
|
||||||
|
return (RadioState_t)sx127x_get_state(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetModem(RadioModems_t modem)
|
||||||
|
{
|
||||||
|
sx127x_set_modem(&sx127x, (uint8_t)modem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetChannel(uint32_t freq)
|
||||||
|
{
|
||||||
|
sx127x_set_channel(&sx127x, freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SX127XIsChannelFree(RadioModems_t modem, uint32_t freq,
|
||||||
|
int16_t rssiThresh, uint32_t maxCarrierSenseTime )
|
||||||
|
{
|
||||||
|
(void) modem;
|
||||||
|
(void) maxCarrierSenseTime;
|
||||||
|
return sx127x_is_channel_free(&sx127x, freq, rssiThresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SX127XRandom(void)
|
||||||
|
{
|
||||||
|
return sx127x_random(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetRxConfig(RadioModems_t modem, uint32_t bandwidth,
|
||||||
|
uint32_t spreading_factor, uint8_t coding_rate,
|
||||||
|
uint32_t bandwidthAfc, uint16_t preambleLen,
|
||||||
|
uint16_t symbTimeout, bool fixLen,
|
||||||
|
uint8_t payloadLen,
|
||||||
|
bool crcOn, bool freqHopOn, uint8_t hopPeriod,
|
||||||
|
bool iqInverted, bool rxContinuous)
|
||||||
|
{
|
||||||
|
(void) bandwidthAfc;
|
||||||
|
(void) symbTimeout;
|
||||||
|
(void) fixLen;
|
||||||
|
sx127x_set_modem(&sx127x, modem);
|
||||||
|
sx127x_set_bandwidth(&sx127x, bandwidth);
|
||||||
|
sx127x_set_spreading_factor(&sx127x, spreading_factor);
|
||||||
|
sx127x_set_coding_rate(&sx127x, coding_rate);
|
||||||
|
sx127x_set_preamble_length(&sx127x, preambleLen);
|
||||||
|
sx127x_set_fixed_header_len_mode(&sx127x, false);
|
||||||
|
sx127x_set_payload_length(&sx127x, payloadLen);
|
||||||
|
sx127x_set_crc(&sx127x, crcOn);
|
||||||
|
sx127x_set_freq_hop(&sx127x, freqHopOn);
|
||||||
|
sx127x_set_hop_period(&sx127x, hopPeriod);
|
||||||
|
sx127x_set_iq_invert(&sx127x, iqInverted);
|
||||||
|
sx127x_set_rx_timeout(&sx127x, LORAMAC_RX_WINDOW_DURATION);
|
||||||
|
sx127x_set_rx_single(&sx127x, !rxContinuous);
|
||||||
|
sx127x_set_rx(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetTxConfig(RadioModems_t modem, int8_t power, uint32_t fdev,
|
||||||
|
uint32_t bandwidth, uint32_t spreading_factor,
|
||||||
|
uint8_t coding_rate, uint16_t preambleLen,
|
||||||
|
bool fixLen, bool crcOn, bool freqHopOn,
|
||||||
|
uint8_t hopPeriod, bool iqInverted, uint32_t timeout)
|
||||||
|
{
|
||||||
|
(void) fdev;
|
||||||
|
(void) fixLen;
|
||||||
|
sx127x_set_modem(&sx127x, modem);
|
||||||
|
sx127x_set_freq_hop(&sx127x, freqHopOn);
|
||||||
|
sx127x_set_bandwidth(&sx127x, bandwidth);
|
||||||
|
sx127x_set_coding_rate(&sx127x, coding_rate);
|
||||||
|
sx127x_set_spreading_factor(&sx127x, spreading_factor);
|
||||||
|
sx127x_set_crc(&sx127x, crcOn);
|
||||||
|
sx127x_set_freq_hop(&sx127x, freqHopOn);
|
||||||
|
sx127x_set_hop_period(&sx127x, hopPeriod);
|
||||||
|
sx127x_set_fixed_header_len_mode(&sx127x, false);
|
||||||
|
sx127x_set_iq_invert(&sx127x, iqInverted);
|
||||||
|
sx127x_set_payload_length(&sx127x, 0);
|
||||||
|
sx127x_set_tx_power(&sx127x, power);
|
||||||
|
sx127x_set_preamble_length(&sx127x, preambleLen);
|
||||||
|
sx127x_set_rx_single(&sx127x, false);
|
||||||
|
sx127x_set_tx_timeout(&sx127x, timeout * US_PER_MS); /* base unit us, LoRaMAC ms */
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SX127XGetTimeOnAir(RadioModems_t modem, uint8_t pktLen)
|
||||||
|
{
|
||||||
|
(void) modem;
|
||||||
|
return sx127x_get_time_on_air(&sx127x, pktLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSend(uint8_t *buffer, uint8_t size)
|
||||||
|
{
|
||||||
|
netdev_t *dev = (netdev_t *)&sx127x;
|
||||||
|
struct iovec vec[1];
|
||||||
|
vec[0].iov_base = buffer;
|
||||||
|
vec[0].iov_len = size;
|
||||||
|
dev->driver->send(dev, vec, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetSleep(void)
|
||||||
|
{
|
||||||
|
sx127x_set_sleep(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetStby(void)
|
||||||
|
{
|
||||||
|
sx127x_set_standby(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetRx(uint32_t timeout)
|
||||||
|
{
|
||||||
|
(void) timeout;
|
||||||
|
sx127x_set_rx(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XStartCad(void)
|
||||||
|
{
|
||||||
|
sx127x_start_cad(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t SX127XReadRssi(RadioModems_t modem)
|
||||||
|
{
|
||||||
|
sx127x_set_modem(&sx127x, (uint8_t)modem);
|
||||||
|
return sx127x_read_rssi(&sx127x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XWrite(uint8_t addr, uint8_t data)
|
||||||
|
{
|
||||||
|
sx127x_reg_write(&sx127x, addr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SX127XRead(uint8_t addr)
|
||||||
|
{
|
||||||
|
return sx127x_reg_read(&sx127x, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XWriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size)
|
||||||
|
{
|
||||||
|
sx127x_reg_write_burst(&sx127x, addr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XReadBuffer(uint8_t addr, uint8_t *buffer, uint8_t size)
|
||||||
|
{
|
||||||
|
sx127x_reg_read_burst(&sx127x, addr, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetMaxPayloadLength(RadioModems_t modem, uint8_t max)
|
||||||
|
{
|
||||||
|
(void) modem;
|
||||||
|
sx127x_set_max_payload_len(&sx127x, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SX127XCheckRfFrequency(uint32_t frequency)
|
||||||
|
{
|
||||||
|
(void) frequency;
|
||||||
|
/* Implement check. Currently all frequencies are supported */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetTxContinuousWave(uint32_t freq, int8_t power, uint16_t time)
|
||||||
|
{
|
||||||
|
(void) freq;
|
||||||
|
(void) power;
|
||||||
|
(void) time;
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
void SX127XSetPublicNetwork(bool enable)
|
||||||
|
{
|
||||||
|
if (enable) {
|
||||||
|
/* Use public network syncword */
|
||||||
|
sx127x_set_syncword(&sx127x, LORA_SYNCWORD_PUBLIC);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Use private network syncword */
|
||||||
|
sx127x_set_syncword(&sx127x, LORA_SYNCWORD_PRIVATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LoRa function callbacks
|
||||||
|
*/
|
||||||
|
const struct Radio_s Radio =
|
||||||
|
{
|
||||||
|
SX127XInit,
|
||||||
|
SX127XGetStatus,
|
||||||
|
SX127XSetModem,
|
||||||
|
SX127XSetChannel,
|
||||||
|
SX127XIsChannelFree,
|
||||||
|
SX127XRandom,
|
||||||
|
SX127XSetRxConfig,
|
||||||
|
SX127XSetTxConfig,
|
||||||
|
SX127XCheckRfFrequency,
|
||||||
|
SX127XGetTimeOnAir,
|
||||||
|
SX127XSend,
|
||||||
|
SX127XSetSleep,
|
||||||
|
SX127XSetStby,
|
||||||
|
SX127XSetRx,
|
||||||
|
SX127XStartCad,
|
||||||
|
SX127XSetTxContinuousWave,
|
||||||
|
SX127XReadRssi,
|
||||||
|
SX127XWrite,
|
||||||
|
SX127XRead,
|
||||||
|
SX127XWriteBuffer,
|
||||||
|
SX127XReadBuffer,
|
||||||
|
SX127XSetMaxPayloadLength,
|
||||||
|
SX127XSetPublicNetwork
|
||||||
|
};
|
||||||
87
pkg/semtech-loramac/contrib/semtech_loramac_timer.c
Normal file
87
pkg/semtech-loramac/contrib/semtech_loramac_timer.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Fundacion Inria Chile
|
||||||
|
* 2017 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 pkg_semtech-loramac
|
||||||
|
* @file
|
||||||
|
* @brief Compatibility functions for controlling the LoRaMAC timers
|
||||||
|
*
|
||||||
|
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @author Francisco Molina <francisco.molina@inria.cl>
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "semtech-loramac/board.h"
|
||||||
|
#include "xtimer.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
|
extern kernel_pid_t semtech_loramac_pid;
|
||||||
|
|
||||||
|
void TimerInit(TimerEvent_t *obj, void (*cb)(void))
|
||||||
|
{
|
||||||
|
obj->dev.target = 0;
|
||||||
|
obj->running = 0;
|
||||||
|
obj->cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerReset(TimerEvent_t *obj)
|
||||||
|
{
|
||||||
|
TimerStop(obj);
|
||||||
|
TimerStart(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerStart(TimerEvent_t *obj)
|
||||||
|
{
|
||||||
|
obj->running = 1;
|
||||||
|
xtimer_t *timer = &(obj->dev);
|
||||||
|
msg_t *msg = &(obj->msg);
|
||||||
|
msg->type = MSG_TYPE_MAC_TIMEOUT;
|
||||||
|
msg->content.ptr = obj->cb;
|
||||||
|
xtimer_set_msg(timer, obj->timeout, msg, semtech_loramac_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerStop(TimerEvent_t *obj)
|
||||||
|
{
|
||||||
|
obj->running = 0;
|
||||||
|
xtimer_remove(&(obj->dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerSetValue(TimerEvent_t *obj, uint32_t value)
|
||||||
|
{
|
||||||
|
if (obj->running) {
|
||||||
|
xtimer_remove(&(obj->dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->timeout = (value - 50) * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerTime_t TimerGetCurrentTime(void)
|
||||||
|
{
|
||||||
|
uint64_t CurrentTime = xtimer_now_usec64();
|
||||||
|
return (TimerTime_t)CurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerTime_t TimerGetElapsedTime(TimerTime_t savedTime)
|
||||||
|
{
|
||||||
|
uint64_t CurrentTime = xtimer_now_usec64();
|
||||||
|
return (TimerTime_t)(CurrentTime - savedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
TimerTime_t TimerGetFutureTime(TimerTime_t eventInFuture)
|
||||||
|
{
|
||||||
|
uint64_t CurrentTime = xtimer_now_usec64();
|
||||||
|
return (TimerTime_t)(CurrentTime + eventInFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimerLowPowerHandler( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
111
pkg/semtech-loramac/doc.txt
Normal file
111
pkg/semtech-loramac/doc.txt
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* @defgroup pkg_semtech-loramac Semtech LoRaMAC implementation
|
||||||
|
* @ingroup pkg
|
||||||
|
* @ingroup net
|
||||||
|
* @brief Provides a RIOT adaption of Semtech LoRaMAC implementation
|
||||||
|
*
|
||||||
|
* # Introduction
|
||||||
|
*
|
||||||
|
* This package provides an API built on top of the
|
||||||
|
* [Semtech LoRaMAC-node](github.com/Lora-net/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:
|
||||||
|
* ```
|
||||||
|
* CFLAGS += -DREGION_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:
|
||||||
|
* ```c
|
||||||
|
* #include "net/loramac.h" /* core loramac definitions */
|
||||||
|
* #include "semtech-loramac.h" /* package API */
|
||||||
|
* #include "sx127x.h" /* SX1272/6 device driver API */
|
||||||
|
* #include "sx127x_params.h" /* SX1272/6 device driver initialization parameters */
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Then define global variables:
|
||||||
|
* ```c
|
||||||
|
* sx127x_t sx127x; /* SX1272/6 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 uint8_t deveui[LORAMAC_DEVEUI_LEN] = { 0x00, 0x00, 0x00, 0x00, \
|
||||||
|
* 0x00, 0x00, 0x00, 0x00 }
|
||||||
|
* static uint8_t appeui[LORAMAC_APPEUI_LEN] = { 0x00, 0x00, 0x00, 0x00, \
|
||||||
|
* 0x00, 0x00, 0x00, 0x00 }
|
||||||
|
* static uint8_t appeui[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. setup the radio driver with the initialization parameters (spi bus, pins, etc)
|
||||||
|
* 2. initialize the LoRaMAC MAC layer
|
||||||
|
* 3. set the LoRa keys
|
||||||
|
* 4. join the network
|
||||||
|
* 5. send some data to the network
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* int main(void)
|
||||||
|
* {
|
||||||
|
* /* 1. setup the radio driver */
|
||||||
|
* sx127x_setup(&sx127x, &sx127x_params[0]);
|
||||||
|
*
|
||||||
|
* /* 2. initialize the LoRaMAC MAC layer */
|
||||||
|
* semtech_loramac_init(&sx127x);
|
||||||
|
*
|
||||||
|
* /* 3. set the device required keys */
|
||||||
|
* semtech_loramac_set_deveui(deveui);
|
||||||
|
* semtech_loramac_set_appeui(appeui);
|
||||||
|
* semtech_loramac_set_appkey(appkey);
|
||||||
|
*
|
||||||
|
* /* 4. join the network */
|
||||||
|
* if (semtech_loramac_join(LORAMAC_JOIN_OTAA) != SEMTECH_LORAMAC_JOIN_SUCCEEDED) {
|
||||||
|
* puts("Join procedure failed");
|
||||||
|
* }
|
||||||
|
* puts("Join procedure succeeded");
|
||||||
|
*
|
||||||
|
* /* 5. send some data using confirmable mode on port 10 and assuming no
|
||||||
|
* data is received */
|
||||||
|
* semtech_loramac_rx_data_t rx_data;
|
||||||
|
* semtech_loramac_send(LORAMAC_TX_CNF, 10,
|
||||||
|
(uint8_t *)"This is RIOT", 13, &rx_data);
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @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 github.com/Lora-net/LoRaMac-node
|
||||||
|
*/
|
||||||
54
pkg/semtech-loramac/include/semtech-loramac/board.h
Normal file
54
pkg/semtech-loramac/include/semtech-loramac/board.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Fundacion Inria Chile
|
||||||
|
* 2017 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 pkg_semtech-loramac
|
||||||
|
* @brief Internal required Semtech LoRaMAC definitions for radio
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author José Ignacio Alamos <jialamos@uc.cl>
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @author Francisco Molina <francisco.molina@inria.cl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMTECH_LORAMAC_BOARD_H
|
||||||
|
#define SEMTECH_LORAMAC_BOARD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "semtech-loramac/timer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Radio wakeup time from SLEEP mode
|
||||||
|
*/
|
||||||
|
#define RADIO_OSC_STARTUP (1U) /* [ms] */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Radio PLL lock and Mode Ready delay which can vary with the temperature
|
||||||
|
*/
|
||||||
|
#define RADIO_SLEEP_TO_RX (2U) /* [ms] */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Radio complete Wake-up Time with margin for temperature compensation
|
||||||
|
*/
|
||||||
|
#define RADIO_WAKEUP_TIME ( RADIO_OSC_STARTUP + RADIO_SLEEP_TO_RX )
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SEMTECH_LORAMAC_BOARD_H */
|
||||||
|
/** @} */
|
||||||
130
pkg/semtech-loramac/include/semtech-loramac/timer.h
Normal file
130
pkg/semtech-loramac/include/semtech-loramac/timer.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Fundacion Inria Chile
|
||||||
|
* 2017 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 pkg_semtech-loramac
|
||||||
|
* @brief Semtech LoRaMAC timer compatibility definitions
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author José Ignacio Alamos <jialamos@uc.cl>
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
* @author Francisco Molina <francisco.molina@inria.cl>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMTECH_LORAMAC_TIMER_H
|
||||||
|
#define SEMTECH_LORAMAC_TIMER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "xtimer.h"
|
||||||
|
#include "msg.h"
|
||||||
|
|
||||||
|
#include "semtech_loramac.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timer object description
|
||||||
|
*/
|
||||||
|
typedef struct TimerEvent_s {
|
||||||
|
uint32_t timeout; /**< Timer timeout in us */
|
||||||
|
uint8_t running; /**< Check if timer is running */
|
||||||
|
xtimer_t dev; /**< xtimer instance attached to this LoRaMAC timer */
|
||||||
|
msg_t msg; /**< message attacher to this LoRaMAC timer */
|
||||||
|
void (*cb)(void); /**< callback to call when timer timeout */
|
||||||
|
} TimerEvent_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timer time variable definition
|
||||||
|
*/
|
||||||
|
#ifndef TimerTime_t
|
||||||
|
typedef uint32_t TimerTime_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the timer object
|
||||||
|
*
|
||||||
|
* @remark TimerSetValue function must be called before starting the timer.
|
||||||
|
* this function initializes timestamp and reload value at 0.
|
||||||
|
*
|
||||||
|
* @param[in] obj Structure containing the timer object parameters
|
||||||
|
* @param[in] callback Function callback called at the end of the timeout
|
||||||
|
*/
|
||||||
|
void TimerInit(TimerEvent_t *obj, void (*callback)(void));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Timer IRQ event handler
|
||||||
|
*/
|
||||||
|
void TimerIrqHandler(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts and adds the timer object to the list of timer events
|
||||||
|
*
|
||||||
|
* @param[in] obj Structure containing the timer object parameters
|
||||||
|
*/
|
||||||
|
void TimerStart(TimerEvent_t *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stops and removes the timer object from the list of timer events
|
||||||
|
*
|
||||||
|
* @param[in] obj Structure containing the timer object parameters
|
||||||
|
*/
|
||||||
|
void TimerStop(TimerEvent_t *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Resets the timer object
|
||||||
|
*
|
||||||
|
* @param[in] obj Structure containing the timer object parameters
|
||||||
|
*/
|
||||||
|
void TimerReset(TimerEvent_t *obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set timer new timeout value
|
||||||
|
*
|
||||||
|
* @param[in] obj Structure containing the timer object parameters
|
||||||
|
* @param[in] value New timer timeout value
|
||||||
|
*/
|
||||||
|
void TimerSetValue(TimerEvent_t *obj, uint32_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the current time
|
||||||
|
*
|
||||||
|
* @return current time
|
||||||
|
*/
|
||||||
|
TimerTime_t TimerGetCurrentTime(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the time elapsed since a fix moment in Time
|
||||||
|
*
|
||||||
|
* @param[in] time fix moment in Time
|
||||||
|
* @return elapsed time
|
||||||
|
*/
|
||||||
|
TimerTime_t TimerGetElapsedTime(TimerTime_t time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the time elapsed since a fix moment in time
|
||||||
|
*
|
||||||
|
* @param[in] time fix moment in the future
|
||||||
|
* @returns difference between now and future event
|
||||||
|
*/
|
||||||
|
TimerTime_t TimerGetFutureTime(TimerTime_t time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Manages the entry into low power mode
|
||||||
|
*/
|
||||||
|
void TimerLowPowerHandler(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SEMTECH_LORAMAC_TIMER_H */
|
||||||
|
/** @} */
|
||||||
303
pkg/semtech-loramac/include/semtech_loramac.h
Normal file
303
pkg/semtech-loramac/include/semtech_loramac.h
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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 pkg_semtech-loramac
|
||||||
|
* @brief Public API and definitions of the Semtech LoRaMAC
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMTECH_LORAMAC_H
|
||||||
|
#define SEMTECH_LORAMAC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "net/loramac.h"
|
||||||
|
|
||||||
|
#include "sx127x.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Definitions for messages exchanged between the MAC and call threads
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define MSG_TYPE_ISR (0x3456) /**< radio device ISR */
|
||||||
|
#define MSG_TYPE_RX_TIMEOUT (0x3457) /**< radio driver RX timeout */
|
||||||
|
#define MSG_TYPE_TX_TIMEOUT (0x3458) /**< radio driver TX timeout */
|
||||||
|
#define MSG_TYPE_MAC_TIMEOUT (0x3459) /**< MAC timers timeout */
|
||||||
|
#define MSG_TYPE_LORAMAC_CMD (0x3460) /**< Command sent to the MAC */
|
||||||
|
#define MSG_TYPE_LORAMAC_NOTIFY (0x3461) /**< MAC notifications */
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum payload size of a LoRaWAN application data
|
||||||
|
*/
|
||||||
|
#define LORAWAN_APP_DATA_MAX_SIZE (242U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LoRaMAC status
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
SEMTECH_LORAMAC_JOIN_SUCCEEDED, /**< Join procedure succeeded */
|
||||||
|
SEMTECH_LORAMAC_JOIN_FAILED, /**< Join procedure failed */
|
||||||
|
SEMTECH_LORAMAC_NOT_JOINED, /**< MAC is not joined */
|
||||||
|
SEMTECH_LORAMAC_TX_DONE, /**< Transmission completed */
|
||||||
|
SEMTECH_LORAMAC_RX_DATA, /**< Data received */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t payload[LORAWAN_APP_DATA_MAX_SIZE]; /**< RX payload buffer */
|
||||||
|
uint8_t payload_len; /**< Length of the RX payload */
|
||||||
|
uint8_t port; /**< RX port */
|
||||||
|
} semtech_loramac_rx_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes semtech loramac
|
||||||
|
*
|
||||||
|
* @param[in] dev pointer to the radio device
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -1 on failure
|
||||||
|
*/
|
||||||
|
int semtech_loramac_init(sx127x_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a LoRaWAN network join procedure
|
||||||
|
*
|
||||||
|
* @param[in] type The type of join procedure (otaa or abp)
|
||||||
|
*
|
||||||
|
* @return SEMTECH_LORAMAC_JOIN_SUCCEEDED on success
|
||||||
|
* @return SEMTECH_LORAMAC_JOIN_FAILED on failure
|
||||||
|
*/
|
||||||
|
uint8_t semtech_loramac_join(uint8_t type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends data to LoRaWAN
|
||||||
|
*
|
||||||
|
* @param[in] cnf Use confirmable/unconfirmable send type
|
||||||
|
* @param[in] port The send port to use (between 1 and 223)
|
||||||
|
* @param[in] tx_buf The TX buffer
|
||||||
|
* @param[in] tx_len The length of the TX buffer
|
||||||
|
* @param[out] rx_data The RX data descriptor
|
||||||
|
*
|
||||||
|
* @return SEMTECH_LORAMAC_NOT_JOINED when the network is not joined
|
||||||
|
* @return SEMTECH_LORAMAC_TX_DONE when TX has completed, no data received
|
||||||
|
* @return SEMTECH_LORAMAC_RX_DATA when TX has completed and data is received
|
||||||
|
*/
|
||||||
|
uint8_t semtech_loramac_send(uint8_t cnf, uint8_t port,
|
||||||
|
uint8_t *tx_buf, uint8_t tx_len,
|
||||||
|
semtech_loramac_rx_data_t *rx_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the device EUI
|
||||||
|
*
|
||||||
|
* @param[in] eui The device EUI
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_deveui(const uint8_t *eui);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the device EUI
|
||||||
|
*
|
||||||
|
* @param[out] eui The device EUI
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_deveui(uint8_t *eui);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the application EUI
|
||||||
|
*
|
||||||
|
* @param[in] eui The application EUI
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_appeui(const uint8_t *eui);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the application EUI
|
||||||
|
*
|
||||||
|
* @param[out] eui The application EUI
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_appeui(uint8_t *eui);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the application key
|
||||||
|
*
|
||||||
|
* @param[in] key The application key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_appkey(const uint8_t *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the application key
|
||||||
|
*
|
||||||
|
* @param[in] key The application key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_appkey(uint8_t *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the application session key
|
||||||
|
*
|
||||||
|
* @param[in] key The application session key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_appskey(const uint8_t *skey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the application session key
|
||||||
|
*
|
||||||
|
* @param[in] key The application session key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_appskey(uint8_t *skey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the network session key
|
||||||
|
*
|
||||||
|
* @param[in] key The network session key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_nwkskey(const uint8_t *skey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the network session key
|
||||||
|
*
|
||||||
|
* @param[in] key The network session key
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_nwkskey(uint8_t *skey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the device address
|
||||||
|
*
|
||||||
|
* @param[in] addr The device address
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_devaddr(const uint8_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the device address
|
||||||
|
*
|
||||||
|
* @param[in] addr The device address
|
||||||
|
*/
|
||||||
|
void semtech_loramac_get_devaddr(uint8_t *addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the device class
|
||||||
|
*
|
||||||
|
* @param[in] cls The device class
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_class(loramac_class_t cls);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the device class
|
||||||
|
*
|
||||||
|
* @return The device class
|
||||||
|
*/
|
||||||
|
loramac_class_t semtech_loramac_get_class(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the channels datarate
|
||||||
|
*
|
||||||
|
* @param[in] dr The datarate (from 1 to 16)
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_dr(uint8_t dr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the channels datarate
|
||||||
|
*
|
||||||
|
* @return The datarate (from 1 to 16)
|
||||||
|
*/
|
||||||
|
uint8_t semtech_loramac_get_dr(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables/disable adaptive datarate
|
||||||
|
*
|
||||||
|
* @param[in] adr Adaptive datarate mode
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_adr(bool adr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if adaptive datarate is set
|
||||||
|
*
|
||||||
|
* @return true if adr is on, false otherwise
|
||||||
|
*/
|
||||||
|
bool semtech_loramac_get_adr(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable/disable the public network mode
|
||||||
|
*
|
||||||
|
* @param[in] public The public network mode
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_public_network(bool public);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if public network is set
|
||||||
|
*
|
||||||
|
* @return true if public network is on, false otherwise
|
||||||
|
*/
|
||||||
|
bool semtech_loramac_get_public_network(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the NetID (only useful with ABP join procedure)
|
||||||
|
*
|
||||||
|
* @param[in] network_id The NetID
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_netid(uint32_t netid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the NetID
|
||||||
|
*
|
||||||
|
* @return The NetID
|
||||||
|
*/
|
||||||
|
uint32_t semtech_loramac_get_netid(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the channels TX power index
|
||||||
|
*
|
||||||
|
* @param[in] dr The TX power index (from 1 to 16)
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_tx_power(uint8_t power);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the channels TX power index
|
||||||
|
*
|
||||||
|
* @return The TX power index (from 1 to 16)
|
||||||
|
*/
|
||||||
|
uint8_t semtech_loramac_get_tx_power(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the RX2 frequency
|
||||||
|
*
|
||||||
|
* @param[in] freq The RX2 frequency
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_rx2_freq(uint8_t freq);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the RX2 frequency
|
||||||
|
*
|
||||||
|
* @return The RX2 frequency
|
||||||
|
*/
|
||||||
|
uint32_t semtech_loramac_get_rx2_freq(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the RX2 datarate
|
||||||
|
*
|
||||||
|
* @param[in] freq The RX2 datarate
|
||||||
|
*/
|
||||||
|
void semtech_loramac_set_rx2_dr(uint8_t dr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the RX2 datarate
|
||||||
|
*
|
||||||
|
* @return The RX2 datarate
|
||||||
|
*/
|
||||||
|
uint8_t semtech_loramac_get_rx2_dr(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* SEMTECH_LORAMAC_H */
|
||||||
|
/** @} */
|
||||||
277
pkg/semtech-loramac/patches/0001-adapt-for-RIOT.patch
Normal file
277
pkg/semtech-loramac/patches/0001-adapt-for-RIOT.patch
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
From 829210e7e7c4c2927fb9aa8cf18ba8aff04150b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
Date: Wed, 13 Dec 2017 17:43:00 +0100
|
||||||
|
Subject: [PATCH] adapt for RIOT
|
||||||
|
|
||||||
|
---
|
||||||
|
src/mac/LoRaMac.c | 28 +++++++++++-----------------
|
||||||
|
src/mac/LoRaMac.h | 4 +++-
|
||||||
|
src/mac/region/Region.c | 2 +-
|
||||||
|
src/mac/region/RegionAS923.c | 2 +-
|
||||||
|
src/mac/region/RegionAU915.c | 2 +-
|
||||||
|
src/mac/region/RegionCN470.c | 2 +-
|
||||||
|
src/mac/region/RegionCN779.c | 2 +-
|
||||||
|
src/mac/region/RegionCommon.c | 2 +-
|
||||||
|
src/mac/region/RegionEU433.c | 2 +-
|
||||||
|
src/mac/region/RegionEU868.c | 2 +-
|
||||||
|
src/mac/region/RegionIN865.c | 2 +-
|
||||||
|
src/mac/region/RegionKR920.c | 2 +-
|
||||||
|
src/mac/region/RegionUS915-Hybrid.c | 2 +-
|
||||||
|
src/mac/region/RegionUS915.c | 2 +-
|
||||||
|
14 files changed, 26 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/mac/LoRaMac.c b/src/mac/LoRaMac.c
|
||||||
|
index 0750ee5..3b9dbdf 100644
|
||||||
|
--- a/src/mac/LoRaMac.c
|
||||||
|
+++ b/src/mac/LoRaMac.c
|
||||||
|
@@ -17,7 +17,8 @@ License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||||
|
|
||||||
|
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
|
||||||
|
*/
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
+#include "utilities.h"
|
||||||
|
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
#include "region/Region.h"
|
||||||
|
@@ -316,11 +317,6 @@ static LoRaMacPrimitives_t *LoRaMacPrimitives;
|
||||||
|
static LoRaMacCallback_t *LoRaMacCallbacks;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
- * Radio events function pointer
|
||||||
|
- */
|
||||||
|
-static RadioEvents_t RadioEvents;
|
||||||
|
-
|
||||||
|
-/*!
|
||||||
|
* LoRaMac duty cycle delayed Tx timer
|
||||||
|
*/
|
||||||
|
static TimerEvent_t TxDelayedTimer;
|
||||||
|
@@ -687,8 +683,7 @@ static void PrepareRxDoneAbort( void )
|
||||||
|
LoRaMacFlags.Bits.MacDone = 1;
|
||||||
|
|
||||||
|
// Trig OnMacCheckTimerEvent call as soon as possible
|
||||||
|
- TimerSetValue( &MacStateCheckTimer, 1 );
|
||||||
|
- TimerStart( &MacStateCheckTimer );
|
||||||
|
+ OnMacStateCheckTimerEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
|
||||||
|
@@ -1106,8 +1101,7 @@ static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t
|
||||||
|
LoRaMacFlags.Bits.MacDone = 1;
|
||||||
|
|
||||||
|
// Trig OnMacCheckTimerEvent call as soon as possible
|
||||||
|
- TimerSetValue( &MacStateCheckTimer, 1 );
|
||||||
|
- TimerStart( &MacStateCheckTimer );
|
||||||
|
+ OnMacStateCheckTimerEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnRadioTxTimeout( void )
|
||||||
|
@@ -2285,7 +2279,7 @@ LoRaMacStatus_t SetTxContinuousWave1( uint16_t timeout, uint32_t frequency, uint
|
||||||
|
return LORAMAC_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaMacRegion_t region )
|
||||||
|
+LoRaMacStatus_t LoRaMacInitialization( RadioEvents_t *radio_events, LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaMacRegion_t region )
|
||||||
|
{
|
||||||
|
GetPhyParams_t getPhy;
|
||||||
|
PhyParam_t phyParam;
|
||||||
|
@@ -2416,12 +2410,12 @@ LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacC
|
||||||
|
LoRaMacInitializationTime = TimerGetCurrentTime( );
|
||||||
|
|
||||||
|
// Initialize Radio driver
|
||||||
|
- RadioEvents.TxDone = OnRadioTxDone;
|
||||||
|
- RadioEvents.RxDone = OnRadioRxDone;
|
||||||
|
- RadioEvents.RxError = OnRadioRxError;
|
||||||
|
- RadioEvents.TxTimeout = OnRadioTxTimeout;
|
||||||
|
- RadioEvents.RxTimeout = OnRadioRxTimeout;
|
||||||
|
- Radio.Init( &RadioEvents );
|
||||||
|
+ radio_events->TxDone = OnRadioTxDone;
|
||||||
|
+ radio_events->RxDone = OnRadioRxDone;
|
||||||
|
+ radio_events->RxError = OnRadioRxError;
|
||||||
|
+ radio_events->TxTimeout = OnRadioTxTimeout;
|
||||||
|
+ radio_events->RxTimeout = OnRadioRxTimeout;
|
||||||
|
+ Radio.Init( radio_events );
|
||||||
|
|
||||||
|
// Random seed initialization
|
||||||
|
srand1( Radio.Random( ) );
|
||||||
|
diff --git a/src/mac/LoRaMac.h b/src/mac/LoRaMac.h
|
||||||
|
index 8e479d2..dde8712 100644
|
||||||
|
--- a/src/mac/LoRaMac.h
|
||||||
|
+++ b/src/mac/LoRaMac.h
|
||||||
|
@@ -82,6 +82,8 @@
|
||||||
|
#ifndef __LORAMAC_H__
|
||||||
|
#define __LORAMAC_H__
|
||||||
|
|
||||||
|
+#include "radio/radio.h"
|
||||||
|
+
|
||||||
|
/*!
|
||||||
|
* Check the Mac layer state every MAC_STATE_CHECK_TIMEOUT in ms
|
||||||
|
*/
|
||||||
|
@@ -1728,7 +1730,7 @@ static const uint8_t LoRaMacMaxEirpTable[] = { 8, 10, 12, 13, 14, 16, 18, 20, 21
|
||||||
|
* \ref LORAMAC_STATUS_PARAMETER_INVALID,
|
||||||
|
* \ref LORAMAC_STATUS_REGION_NOT_SUPPORTED.
|
||||||
|
*/
|
||||||
|
-LoRaMacStatus_t LoRaMacInitialization( LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaMacRegion_t region );
|
||||||
|
+LoRaMacStatus_t LoRaMacInitialization( RadioEvents_t *RadioEvents, LoRaMacPrimitives_t *primitives, LoRaMacCallback_t *callbacks, LoRaMacRegion_t region );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Queries the LoRaMAC if it is possible to send the next frame with
|
||||||
|
diff --git a/src/mac/region/Region.c b/src/mac/region/Region.c
|
||||||
|
index 1d0be81..f6ce9f5 100644
|
||||||
|
--- a/src/mac/region/Region.c
|
||||||
|
+++ b/src/mac/region/Region.c
|
||||||
|
@@ -21,7 +21,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
-#include "timer.h"
|
||||||
|
+#include "semtech-loramac/timer.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/mac/region/RegionAS923.c b/src/mac/region/RegionAS923.c
|
||||||
|
index 2677d0c..8312b46 100644
|
||||||
|
--- a/src/mac/region/RegionAS923.c
|
||||||
|
+++ b/src/mac/region/RegionAS923.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionAU915.c b/src/mac/region/RegionAU915.c
|
||||||
|
index 4c8fc33..6b3817b 100644
|
||||||
|
--- a/src/mac/region/RegionAU915.c
|
||||||
|
+++ b/src/mac/region/RegionAU915.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionCN470.c b/src/mac/region/RegionCN470.c
|
||||||
|
index dbbc745..2daddc9 100644
|
||||||
|
--- a/src/mac/region/RegionCN470.c
|
||||||
|
+++ b/src/mac/region/RegionCN470.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionCN779.c b/src/mac/region/RegionCN779.c
|
||||||
|
index c5d9b7b..5c55ffd 100644
|
||||||
|
--- a/src/mac/region/RegionCN779.c
|
||||||
|
+++ b/src/mac/region/RegionCN779.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionCommon.c b/src/mac/region/RegionCommon.c
|
||||||
|
index fb0b139..53e1e6c 100644
|
||||||
|
--- a/src/mac/region/RegionCommon.c
|
||||||
|
+++ b/src/mac/region/RegionCommon.c
|
||||||
|
@@ -23,7 +23,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "timer.h"
|
||||||
|
+#include "semtech-loramac/timer.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
#include "RegionCommon.h"
|
||||||
|
diff --git a/src/mac/region/RegionEU433.c b/src/mac/region/RegionEU433.c
|
||||||
|
index 5446c51..ca0fa9f 100644
|
||||||
|
--- a/src/mac/region/RegionEU433.c
|
||||||
|
+++ b/src/mac/region/RegionEU433.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionEU868.c b/src/mac/region/RegionEU868.c
|
||||||
|
index f4385a5..3a27f42 100644
|
||||||
|
--- a/src/mac/region/RegionEU868.c
|
||||||
|
+++ b/src/mac/region/RegionEU868.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionIN865.c b/src/mac/region/RegionIN865.c
|
||||||
|
index 75e2a4b..4770050 100644
|
||||||
|
--- a/src/mac/region/RegionIN865.c
|
||||||
|
+++ b/src/mac/region/RegionIN865.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionKR920.c b/src/mac/region/RegionKR920.c
|
||||||
|
index eda6652..ca689d6 100644
|
||||||
|
--- a/src/mac/region/RegionKR920.c
|
||||||
|
+++ b/src/mac/region/RegionKR920.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionUS915-Hybrid.c b/src/mac/region/RegionUS915-Hybrid.c
|
||||||
|
index 426e40d..3a3d085 100644
|
||||||
|
--- a/src/mac/region/RegionUS915-Hybrid.c
|
||||||
|
+++ b/src/mac/region/RegionUS915-Hybrid.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
diff --git a/src/mac/region/RegionUS915.c b/src/mac/region/RegionUS915.c
|
||||||
|
index 8aa788a..97c3785 100644
|
||||||
|
--- a/src/mac/region/RegionUS915.c
|
||||||
|
+++ b/src/mac/region/RegionUS915.c
|
||||||
|
@@ -22,7 +22,7 @@ Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jae
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
-#include "board.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
#include "LoRaMac.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
--
|
||||||
|
2.11.0
|
||||||
|
|
||||||
30
pkg/semtech-loramac/patches/0002-eu868-join-retries.patch
Normal file
30
pkg/semtech-loramac/patches/0002-eu868-join-retries.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 47b9fba23bedff6e28576271291a6ca7958a3caa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
Date: Mon, 8 Jan 2018 10:45:28 +0100
|
||||||
|
Subject: [PATCH] accept all join retries values in EU868
|
||||||
|
|
||||||
|
---
|
||||||
|
src/mac/region/RegionEU868.c | 7 ++-----
|
||||||
|
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/mac/region/RegionEU868.c b/src/mac/region/RegionEU868.c
|
||||||
|
index 3a27f42..e7e6f54 100644
|
||||||
|
--- a/src/mac/region/RegionEU868.c
|
||||||
|
+++ b/src/mac/region/RegionEU868.c
|
||||||
|
@@ -393,11 +393,8 @@ bool RegionEU868Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )
|
||||||
|
}
|
||||||
|
case PHY_NB_JOIN_TRIALS:
|
||||||
|
{
|
||||||
|
- if( verify->NbJoinTrials < 48 )
|
||||||
|
- {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
+ /* accept all values */
|
||||||
|
+ return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
--
|
||||||
|
2.14.1
|
||||||
|
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
From 406e1900f38e6ca43e74c98a5de0c1ec0f3e3213 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
Date: Tue, 16 Jan 2018 15:04:09 +0100
|
||||||
|
Subject: [PATCH] patch utilities functions
|
||||||
|
|
||||||
|
---
|
||||||
|
src/boards/mcu/stm32/utilities.c | 48 +++++++++++-----------------------------
|
||||||
|
1 file changed, 13 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/boards/mcu/stm32/utilities.c b/src/boards/mcu/stm32/utilities.c
|
||||||
|
index 8861235..583cae1 100644
|
||||||
|
--- a/src/boards/mcu/stm32/utilities.c
|
||||||
|
+++ b/src/boards/mcu/stm32/utilities.c
|
||||||
|
@@ -14,8 +14,10 @@ Maintainer: Miguel Luis and Gregory Cristian
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
-#include "board.h"
|
||||||
|
+#include <string.h>
|
||||||
|
#include "utilities.h"
|
||||||
|
+#include "semtech-loramac/board.h"
|
||||||
|
+#include "random.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Redefinition of rand() and srand() standard C functions.
|
||||||
|
@@ -34,52 +36,28 @@ int32_t rand1( void )
|
||||||
|
|
||||||
|
void srand1( uint32_t seed )
|
||||||
|
{
|
||||||
|
- next = seed;
|
||||||
|
-}
|
||||||
|
-// Standard random functions redefinition end
|
||||||
|
+ (void) seed;
|
||||||
|
+};
|
||||||
|
|
||||||
|
int32_t randr( int32_t min, int32_t max )
|
||||||
|
{
|
||||||
|
- return ( int32_t )rand1( ) % ( max - min + 1 ) + min;
|
||||||
|
-}
|
||||||
|
+ return random_uint32_range(min, max + 1);
|
||||||
|
+};
|
||||||
|
|
||||||
|
void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size )
|
||||||
|
{
|
||||||
|
- while( size-- )
|
||||||
|
- {
|
||||||
|
- *dst++ = *src++;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
+ memcpy(dst, src, size);
|
||||||
|
+};
|
||||||
|
|
||||||
|
void memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size )
|
||||||
|
{
|
||||||
|
- dst = dst + ( size - 1 );
|
||||||
|
- while( size-- )
|
||||||
|
- {
|
||||||
|
+ dst = dst + (size - 1);
|
||||||
|
+ while (size--) {
|
||||||
|
*dst-- = *src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void memset1( uint8_t *dst, uint8_t value, uint16_t size )
|
||||||
|
{
|
||||||
|
- while( size-- )
|
||||||
|
- {
|
||||||
|
- *dst++ = value;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int8_t Nibble2HexChar( uint8_t a )
|
||||||
|
-{
|
||||||
|
- if( a < 10 )
|
||||||
|
- {
|
||||||
|
- return '0' + a;
|
||||||
|
- }
|
||||||
|
- else if( a < 16 )
|
||||||
|
- {
|
||||||
|
- return 'A' + ( a - 10 );
|
||||||
|
- }
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- return '?';
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
+ memset(dst, value, size);
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.14.1
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user