You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/04/29 00:28:46 UTC

[08/19] incubator-mynewt-core git commit: MYNEWT-741 Port of LoRaMac-node library

MYNEWT-741 Port of LoRaMac-node library


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/9986f68c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/9986f68c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/9986f68c

Branch: refs/heads/master
Commit: 9986f68cdf2f9a81bf67076d220e60bf64f56450
Parents: 8374b5a
Author: Christopher Collins <cc...@apache.org>
Authored: Mon Apr 24 19:18:10 2017 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Fri Apr 28 17:27:51 2017 -0700

----------------------------------------------------------------------
 apps/loraping/pkg.yml                           |   47 +
 apps/loraping/src/loraping.h                    |   27 +
 apps/loraping/src/main.c                        |  279 ++
 apps/loraping/src/rxinfo.c                      |  139 +
 apps/lorashell/pkg.yml                          |   34 +
 apps/lorashell/src/main.c                       |  453 ++
 apps/lorashell/syscfg.yml                       |   27 +
 hw/bsp/telee02/pkg.yml                          |    4 +
 hw/drivers/lora/node/board/nrf52/LICENSE.txt    |   25 +
 .../lora/node/board/nrf52/include/board/board.h |   92 +
 hw/drivers/lora/node/board/nrf52/pkg.yml        |   34 +
 .../lora/node/board/nrf52/src/lora_nrf52.c      |   44 +
 hw/drivers/lora/node/board/nrf52/syscfg.yml     |   27 +
 hw/drivers/lora/node/radio/sx1276/LICENSE.txt   |   25 +
 .../node/radio/sx1276/include/radio/radio.h     |   33 +
 hw/drivers/lora/node/radio/sx1276/pkg.yml       |   35 +
 .../lora/node/radio/sx1276/src/sx1276-board.c   |  163 +
 .../lora/node/radio/sx1276/src/sx1276-board.h   |  119 +
 hw/drivers/lora/node/radio/sx1276/src/sx1276.c  | 1826 +++++++
 hw/drivers/lora/node/radio/sx1276/src/sx1276.h  |  364 ++
 .../lora/node/radio/sx1276/src/sx1276Regs-Fsk.h | 1134 +++++
 .../node/radio/sx1276/src/sx1276Regs-LoRa.h     |  565 +++
 net/lora/node/LICENSE.txt                       |   25 +
 net/lora/node/README.md                         |   28 +
 net/lora/node/include/node/lora.h               |   34 +
 .../node/include/node/mac/LoRaMac-definitions.h |  610 +++
 net/lora/node/include/node/mac/LoRaMac.h        | 1830 ++++++++
 net/lora/node/include/node/mac/LoRaMacCrypto.h  |  111 +
 net/lora/node/include/node/mac/LoRaMacTest.h    |   81 +
 net/lora/node/include/node/radio.h              |  337 ++
 net/lora/node/include/node/timer.h              |   38 +
 net/lora/node/include/node/utilities.h          |   72 +
 net/lora/node/pkg.yml                           |   42 +
 net/lora/node/src/lora_cli.c                    |  569 +++
 net/lora/node/src/lora_node.c                   |   48 +
 net/lora/node/src/lora_priv.h                   |   44 +
 net/lora/node/src/mac/LoRaMac.c                 | 4439 ++++++++++++++++++
 net/lora/node/src/mac/LoRaMacCrypto.c           |  203 +
 net/lora/node/src/mac/aes.h                     |  160 +
 net/lora/node/src/mac/cmac.h                    |   63 +
 net/lora/node/src/misc.c                        |   45 +
 net/lora/node/src/timer.c                       |   15 +
 net/lora/node/syscfg.yml                        |   39 +
 43 files changed, 14329 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/loraping/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/loraping/pkg.yml b/apps/loraping/pkg.yml
new file mode 100644
index 0000000..07c3060
--- /dev/null
+++ b/apps/loraping/pkg.yml
@@ -0,0 +1,47 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: apps/loraping
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/boot/split"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/nmgr_shell"
+    - "@apache-mynewt-core/net/lora/node"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/test/flash_test"
+
+pkg.deps.CONFIG_NFFS:
+    - fs/nffs
+
+pkg.deps.CONFIG_FCB:
+    - fs/fcb

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/loraping/src/loraping.h
----------------------------------------------------------------------
diff --git a/apps/loraping/src/loraping.h b/apps/loraping/src/loraping.h
new file mode 100644
index 0000000..4b28e7a
--- /dev/null
+++ b/apps/loraping/src/loraping.h
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_LORAPING_
+#define H_LORAPING_
+
+void loraping_rxinfo_print(void);
+void loraping_rxinfo_timeout(void);
+void loraping_rxinfo_rxed(int8_t rssi, int8_t snr);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/loraping/src/main.c
----------------------------------------------------------------------
diff --git a/apps/loraping/src/main.c b/apps/loraping/src/main.c
new file mode 100644
index 0000000..7c5ef8e
--- /dev/null
+++ b/apps/loraping/src/main.c
@@ -0,0 +1,279 @@
+/*
+Copyright (c) 2013, SEMTECH S.A.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Semtech corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Description: Ping-Pong implementation.  Adapted to run in the MyNewt OS.
+*/
+
+#include <string.h>
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#include "os/os.h"
+#include "board/board.h"
+#include "node/radio.h"
+#include "loraping.h"
+
+#define LORAPING_SPI_BAUDRATE               500
+#define USE_BAND_915
+
+#if defined(USE_BAND_433)
+
+#define RF_FREQUENCY               434000000 /* Hz */
+
+#elif defined(USE_BAND_780)
+
+#define RF_FREQUENCY               780000000 /* Hz */
+
+#elif defined(USE_BAND_868)
+
+#define RF_FREQUENCY               868000000 /* Hz */
+
+#elif defined(USE_BAND_915)
+
+#define RF_FREQUENCY               915000000 /* Hz */
+
+#else
+    #error "Please define a frequency band in the compiler options."
+#endif
+
+#define LORAPING_TX_OUTPUT_POWER            14        /* dBm */
+
+#define LORAPING_BANDWIDTH                  0         /* [0: 125 kHz, */
+                                                  /*  1: 250 kHz, */
+                                                  /*  2: 500 kHz, */
+                                                  /*  3: Reserved] */
+#define LORAPING_SPREADING_FACTOR           7         /* [SF7..SF12] */
+#define LORAPING_CODINGRATE                 1         /* [1: 4/5, */
+                                                  /*  2: 4/6, */
+                                                  /*  3: 4/7, */
+                                                  /*  4: 4/8] */
+#define LORAPING_PREAMBLE_LENGTH            8         /* Same for Tx and Rx */
+#define LORAPING_SYMBOL_TIMEOUT             5         /* Symbols */
+#define LORAPING_FIX_LENGTH_PAYLOAD_ON      false
+#define LORAPING_IQ_INVERSION_ON            false
+
+#define LORAPING_TX_TIMEOUT_MS              3000    /* ms */
+#define LORAPING_RX_TIMEOUT_MS              1000    /* ms */
+#define LORAPING_BUFFER_SIZE                64
+
+const uint8_t loraping_ping_msg[] = "PING";
+const uint8_t loraping_pong_msg[] = "PONG";
+
+static uint8_t loraping_buffer[LORAPING_BUFFER_SIZE];
+static int loraping_rx_size;
+static int loraping_is_master = 1;
+
+struct {
+    int rx_timeout;
+    int rx_ping;
+    int rx_pong;
+    int rx_other;
+    int rx_error;
+    int tx_timeout;
+    int tx_success;
+} loraping_stats;
+
+static void loraping_tx(struct os_event *ev);
+static void loraping_rx(struct os_event *ev);
+
+static struct os_event loraping_ev_tx = {
+    .ev_cb = loraping_tx,
+};
+static struct os_event loraping_ev_rx = {
+    .ev_cb = loraping_rx,
+};
+
+static void
+send_once(int is_ping)
+{
+    int i;
+
+    if (is_ping) {
+        memcpy(loraping_buffer, loraping_ping_msg, 4);
+    } else {
+        memcpy(loraping_buffer, loraping_pong_msg, 4);
+    }
+    for (i = 4; i < sizeof loraping_buffer; i++) {
+        loraping_buffer[i] = i - 4;
+    }
+
+    Radio.Send(loraping_buffer, sizeof loraping_buffer);
+}
+
+static void
+loraping_tx(struct os_event *ev)
+{
+    /* Print information about last rx attempt. */
+    loraping_rxinfo_print();
+
+    if (loraping_rx_size == 0) {
+        /* Timeout. */
+    } else {
+        os_time_delay(1);
+        if (memcmp(loraping_buffer, loraping_pong_msg, 4) == 0) {
+            loraping_stats.rx_ping++;
+        } else if (memcmp(loraping_buffer, loraping_ping_msg, 4) == 0) {
+            loraping_stats.rx_pong++;
+
+            /* A master already exists.  Become a slave. */
+            loraping_is_master = 0;
+        } else { 
+            /* Valid reception but neither a PING nor a PONG message. */
+            loraping_stats.rx_other++;
+            /* Set device as master and start again. */
+            loraping_is_master = 1;
+        }
+    }
+
+    loraping_rx_size = 0;
+    send_once(loraping_is_master);
+}
+
+static void
+loraping_rx(struct os_event *ev)
+{
+    Radio.Rx(LORAPING_RX_TIMEOUT_MS);
+}
+
+static void
+on_tx_done(void)
+{
+    loraping_stats.tx_success++;
+    Radio.Sleep();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+}
+
+static void
+on_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    Radio.Sleep();
+
+    if (size > sizeof loraping_buffer) {
+        size = sizeof loraping_buffer;
+    }
+
+    loraping_rx_size = size;
+    memcpy(loraping_buffer, payload, size);
+
+    loraping_rxinfo_rxed(rssi, snr);
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+static void
+on_tx_timeout(void)
+{
+    Radio.Sleep();
+
+    loraping_stats.tx_timeout++;
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+}
+
+static void
+on_rx_timeout(void)
+{
+    Radio.Sleep();
+
+    loraping_stats.rx_timeout++;
+    loraping_rxinfo_timeout();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+static void
+on_rx_error(void)
+{
+    loraping_stats.rx_error++;
+    Radio.Sleep();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+int
+main(void)
+{
+    RadioEvents_t radio_events;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    /* Radio initialization. */
+    radio_events.TxDone = on_tx_done;
+    radio_events.RxDone = on_rx_done;
+    radio_events.TxTimeout = on_tx_timeout;
+    radio_events.RxTimeout = on_rx_timeout;
+    radio_events.RxError = on_rx_error;
+
+    Radio.Init(&radio_events);
+
+    Radio.SetChannel(RF_FREQUENCY);
+
+    Radio.SetTxConfig(MODEM_LORA,
+                      LORAPING_TX_OUTPUT_POWER,
+                      0,        /* Frequency deviation; unused with LoRa. */
+                      LORAPING_BANDWIDTH,
+                      LORAPING_SPREADING_FACTOR,
+                      LORAPING_CODINGRATE,
+                      LORAPING_PREAMBLE_LENGTH,
+                      LORAPING_FIX_LENGTH_PAYLOAD_ON,
+                      true,     /* CRC enabled. */
+                      0,        /* Frequency hopping disabled. */
+                      0,        /* Hop period; N/A. */
+                      LORAPING_IQ_INVERSION_ON,
+                      LORAPING_TX_TIMEOUT_MS);
+
+    Radio.SetRxConfig(MODEM_LORA,
+                      LORAPING_BANDWIDTH,
+                      LORAPING_SPREADING_FACTOR,
+                      LORAPING_CODINGRATE,
+                      0,        /* AFC bandwisth; unused with LoRa. */
+                      LORAPING_PREAMBLE_LENGTH,
+                      LORAPING_SYMBOL_TIMEOUT,
+                      LORAPING_FIX_LENGTH_PAYLOAD_ON,
+                      0,        /* Fixed payload length; N/A. */
+                      true,     /* CRC enabled. */
+                      0,        /* Frequency hopping disabled. */
+                      0,        /* Hop period; N/A. */
+                      LORAPING_IQ_INVERSION_ON,
+                      true);    /* Continuous receive mode. */
+
+    /* Immediately receive on start up. */
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/loraping/src/rxinfo.c
----------------------------------------------------------------------
diff --git a/apps/loraping/src/rxinfo.c b/apps/loraping/src/rxinfo.c
new file mode 100644
index 0000000..71c1de8
--- /dev/null
+++ b/apps/loraping/src/rxinfo.c
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This file contains code to collect and print receive statistics to the
+ * console.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "console/console.h"
+#include "loraping.h"
+
+#define LORAPING_NUM_RXINFOS                10
+
+struct loraping_rxinfo {
+    int8_t rssi;
+    int8_t snr;
+
+    uint8_t rxed:1;
+};
+
+static struct loraping_rxinfo loraping_rxinfos[LORAPING_NUM_RXINFOS];
+static int loraping_rxinfo_idx;
+static int loraping_rxinfo_rollover;
+
+static void
+loraping_rxinfo_avg(struct loraping_rxinfo *out_info, int *out_pkt_loss)
+{
+    long long rssi_sum;
+    long long snr_sum;
+    int num_rxed;
+    int count;
+    int i;
+
+    if (!loraping_rxinfo_rollover) {
+        count = loraping_rxinfo_idx;
+    } else {
+        count = LORAPING_NUM_RXINFOS;
+    }
+
+    assert(count > 0);
+
+    rssi_sum = 0;
+    snr_sum = 0;
+    num_rxed = 0;
+    for (i = 0; i < count; i++) {
+        if (loraping_rxinfos[i].rxed) {
+            num_rxed++;
+            rssi_sum += loraping_rxinfos[i].rssi;
+            snr_sum += loraping_rxinfos[i].snr;
+        }
+    }
+
+    memset(out_info, 0, sizeof *out_info);
+    if (num_rxed > 0) {
+        out_info->rssi = rssi_sum / num_rxed;
+        out_info->snr = snr_sum / num_rxed;
+    }
+
+    *out_pkt_loss = (count - num_rxed) * 10000 / count;
+}
+
+static void
+loraping_rxinfo_inc_idx(void)
+{
+    loraping_rxinfo_idx++;
+    if (loraping_rxinfo_idx >= LORAPING_NUM_RXINFOS) {
+        loraping_rxinfo_idx = 0;
+        loraping_rxinfo_rollover = 1;
+    }
+}
+
+void
+loraping_rxinfo_print(void)
+{
+    const struct loraping_rxinfo *last;
+    struct loraping_rxinfo avg;
+    int last_idx;
+    int pkt_loss;
+    int width;
+
+    last_idx = loraping_rxinfo_idx - 1;
+    if (last_idx < 0) {
+        last_idx += LORAPING_NUM_RXINFOS;
+    }
+    last = loraping_rxinfos + last_idx;
+
+    loraping_rxinfo_avg(&avg, &pkt_loss);
+
+    if (last->rxed) {
+        width = console_printf("[LAST] rssi=%-4d snr=%-4d",
+                               last->rssi, last->snr);
+    } else {
+        width = console_printf("[LAST] TIMEOUT");
+    }
+
+    for (; width < 48; width++) {
+        console_printf(" ");
+    }
+
+    console_printf("[AVG-%d] rssi=%-4d snr=%-4d pkt_loss=%d.%02d%%\n",
+                   LORAPING_NUM_RXINFOS, avg.rssi, avg.snr,
+                   pkt_loss / 100, pkt_loss % 100);
+}
+
+void
+loraping_rxinfo_timeout(void)
+{
+    loraping_rxinfos[loraping_rxinfo_idx].rxed = 0;
+    loraping_rxinfo_inc_idx();
+}
+
+void
+loraping_rxinfo_rxed(int8_t rssi, int8_t snr)
+{
+    loraping_rxinfos[loraping_rxinfo_idx].rssi = rssi;
+    loraping_rxinfos[loraping_rxinfo_idx].snr = snr;
+    loraping_rxinfos[loraping_rxinfo_idx].rxed = 1;
+    loraping_rxinfo_inc_idx();
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/lorashell/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/lorashell/pkg.yml b/apps/lorashell/pkg.yml
new file mode 100644
index 0000000..898f5d2
--- /dev/null
+++ b/apps/lorashell/pkg.yml
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: apps/lorashell
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/lora/node"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/util/parse"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/lorashell/src/main.c
----------------------------------------------------------------------
diff --git a/apps/lorashell/src/main.c b/apps/lorashell/src/main.c
new file mode 100644
index 0000000..7f12578
--- /dev/null
+++ b/apps/lorashell/src/main.c
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A simple app for LoRa phy testing.  A typical usage scenario is:
+ *
+ * ##### Receiver
+ * # Sit on a single channel.
+ * lora set_freq 915000000
+ * 
+ * # Allow 250-byte packets.
+ * lora max_payload_len 1 250
+ *
+ * # Configure LoRa receiver (specify no arguments for usage).
+ * lora rx_cfg 1 0 7 1 0 8 5 0 0 1 0 0 0 1
+ *
+ * # Print message on each receive.
+ * lora_rx_verbose 1
+ *
+ * # Keep receiving until manual stop.
+ * lora_rx_rpt
+ *
+ * # Display information about recent receives.
+ * lora_rx_info
+ *
+ * ##### Transceiver
+ * # Sit on a single channel.
+ * lora set_freq 915000000
+ *
+ * # Allow 250-byte packets.
+ * lora max_payload_len 1 250
+ *
+ * # Configure LoRa transceiver (specify no arguments for usage).
+ * lora tx_cfg 1 14 0 0 7 1 8 0 1 0 0 0 3000
+ *
+ * # Send; size=50, count=5, interval=100ms.
+ * lora_tx_rpt 50 5 100
+ */
+
+#include <string.h>
+#include <limits.h>
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#include "os/os.h"
+#include "board/board.h"
+#include "node/radio.h"
+#include "console/console.h"
+#include "shell/shell.h"
+#include "parse/parse.h"
+
+struct lorashell_rx_entry {
+    uint16_t size;
+    int16_t rssi;
+    int8_t snr;
+};
+
+static struct lorashell_rx_entry
+    lorashell_rx_entries[MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)];
+static int lorashell_rx_entry_idx;
+static int lorashell_rx_entry_cnt;
+
+static int lorashell_rx_rpt;
+static int lorashell_rx_verbose;
+static int lorashell_txes_pending;
+static uint8_t lorashell_tx_size;
+static uint32_t lorashell_tx_itvl; /* OS ticks. */
+
+static int lorashell_rx_info_cmd(int argc, char **argv);
+static int lorashell_rx_rpt_cmd(int argc, char **argv);
+static int lorashell_rx_verbose_cmd(int argc, char **argv);
+static int lorashell_tx_rpt_cmd(int argc, char **argv);
+
+static void lorashell_print_last_rx(struct os_event *ev);
+
+static struct shell_cmd lorashell_cli_cmds[] = {
+    {
+        .sc_cmd = "lora_rx_info",
+        .sc_cmd_func = lorashell_rx_info_cmd,
+    },
+    {
+        .sc_cmd = "lora_rx_rpt",
+        .sc_cmd_func = lorashell_rx_rpt_cmd,
+    },
+    {
+        .sc_cmd = "lora_rx_verbose",
+        .sc_cmd_func = lorashell_rx_verbose_cmd,
+    },
+    {
+        .sc_cmd = "lora_tx_rpt",
+        .sc_cmd_func = lorashell_tx_rpt_cmd,
+    },
+};
+#define LORASHELL_NUM_CLI_CMDS  \
+    (sizeof lorashell_cli_cmds / sizeof lorashell_cli_cmds[0])
+
+static struct os_event lorashell_print_last_rx_ev = {
+    .ev_cb = lorashell_print_last_rx,
+};
+static struct os_callout lorashell_tx_timer;
+
+static void
+lorashell_rx_rpt_begin(void)
+{
+    Radio.Rx(0);
+}
+
+static void
+lorashell_tx_timer_exp(struct os_event *ev)
+{
+    static uint8_t start_byte;
+
+    uint8_t buf[UINT8_MAX];
+    uint8_t b;
+    int i;
+
+    if (lorashell_txes_pending <= 0) {
+        Radio.Sleep();
+        return;
+    }
+    lorashell_txes_pending--;
+
+    b = start_byte++;
+    for (i = 0; i < lorashell_tx_size; i++) {
+        buf[i] = b++;
+    }
+
+    Radio.Send(buf, lorashell_tx_size);
+}
+
+static const char *
+lorashell_rx_entry_str(const struct lorashell_rx_entry *entry)
+{
+    static char buf[32];
+
+    snprintf(buf, sizeof buf, "size=%-4d rssi=%-4d snr=%-4d",
+             entry->size, entry->rssi, entry->snr);
+    return buf;
+}
+
+static void
+lorashell_tx_timer_reset(void)
+{
+    int rc;
+
+    rc = os_callout_reset(&lorashell_tx_timer, lorashell_tx_itvl);
+    assert(rc == 0);
+}
+
+static void
+on_tx_done(void)
+{
+    if (lorashell_txes_pending <= 0) {
+        Radio.Sleep();
+    } else {
+        lorashell_tx_timer_reset();
+    }
+}
+
+static void
+on_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+
+    struct lorashell_rx_entry *entry;
+
+    if (!lorashell_rx_rpt) {
+        Radio.Sleep();
+    } else {
+        lorashell_rx_rpt_begin();
+    }
+
+    entry = lorashell_rx_entries + lorashell_rx_entry_idx;
+    entry->size = size;
+    entry->rssi = rssi;
+    entry->snr = snr;
+
+    if (lorashell_rx_verbose) {
+        os_eventq_put(os_eventq_dflt_get(), &lorashell_print_last_rx_ev);
+    }
+
+    lorashell_rx_entry_idx++;
+    if (lorashell_rx_entry_idx >= MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        lorashell_rx_entry_idx = 0;
+    }
+
+    if (lorashell_rx_entry_cnt < MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        lorashell_rx_entry_cnt++;
+    }
+}
+
+static void
+on_tx_timeout(void)
+{
+    assert(0);
+    lorashell_tx_timer_reset();
+}
+
+static void
+on_rx_timeout(void)
+{
+    Radio.Sleep();
+}
+
+static void
+on_rx_error(void)
+{
+    Radio.Sleep();
+}
+
+static void
+lorashell_print_last_rx(struct os_event *ev)
+{
+    const struct lorashell_rx_entry *entry;
+    int idx;
+
+    idx = lorashell_rx_entry_idx - 1;
+    if (idx < 0) {
+        idx = lorashell_rx_entry_cnt - 1;
+    }
+
+    entry = lorashell_rx_entries + idx;
+    console_printf("rxed lora packet: %s\n", lorashell_rx_entry_str(entry));
+}
+
+static void
+lorashell_avg_rx_entry(struct lorashell_rx_entry *out_entry)
+{
+    long long rssi_sum;
+    long long size_sum;
+    long long snr_sum;
+    int i;
+
+    rssi_sum = 0;
+    size_sum = 0;
+    snr_sum = 0;
+    for (i = 0; i < lorashell_rx_entry_cnt; i++) {
+        rssi_sum += lorashell_rx_entries[i].rssi;
+        size_sum += lorashell_rx_entries[i].size;
+        snr_sum += lorashell_rx_entries[i].snr;
+    }
+
+    memset(out_entry, 0, sizeof *out_entry);
+    if (lorashell_rx_entry_cnt > 0) {
+        out_entry->size = size_sum / lorashell_rx_entry_cnt;
+        out_entry->rssi = rssi_sum / lorashell_rx_entry_cnt;
+        out_entry->snr = snr_sum / lorashell_rx_entry_cnt;
+    }
+}
+
+static int
+lorashell_rx_rpt_cmd(int argc, char **argv)
+{
+    if (argc > 1 && strcmp(argv[1], "stop") == 0) {
+        lorashell_rx_rpt = 0;
+        Radio.Sleep();
+        console_printf("lora rx stopped\n");
+        return 0;
+    }
+
+    lorashell_rx_rpt = 1;
+    lorashell_rx_rpt_begin();
+
+    return 0;
+}
+
+static int
+lorashell_rx_verbose_cmd(int argc, char **argv)
+{
+    int rc;
+
+    if (argc <= 1) {
+        console_printf("lora rx verbose: %d\n", lorashell_rx_verbose);
+        return 0;
+    }
+
+    lorashell_rx_verbose = parse_ull_bounds(argv[1], 0, 1, &rc);
+    if (rc != 0) {
+        console_printf("error: rc=%d\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+lorashell_rx_info_cmd(int argc, char **argv)
+{
+    const struct lorashell_rx_entry *entry;
+    struct lorashell_rx_entry avg;
+    int idx;
+    int i;
+
+    if (argc > 1 && argv[1][0] == 'c') {
+        lorashell_rx_entry_idx = 0;
+        lorashell_rx_entry_cnt = 0;
+        console_printf("lora rx info cleared\n");
+        return 0;
+    }
+
+    if (lorashell_rx_entry_cnt < MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        idx = 0;
+    } else {
+        idx = lorashell_rx_entry_idx;
+    }
+
+    console_printf("entries in log: %d\n", lorashell_rx_entry_cnt);
+
+    for (i = 0; i < lorashell_rx_entry_cnt; i++) {
+        entry = lorashell_rx_entries + idx;
+        console_printf("%4d: %s\n", i + 1, lorashell_rx_entry_str(entry));
+
+        idx++;
+        if (idx >= MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+            idx = 0;
+        }
+    }
+
+    if (lorashell_rx_entry_cnt > 0) {
+        lorashell_avg_rx_entry(&avg);
+        console_printf(" avg: %s\n", lorashell_rx_entry_str(&avg));
+    }
+
+    return 0;
+}
+
+static int
+lorashell_tx_rpt_cmd(int argc, char **argv)
+{
+    const char *err;
+    uint32_t itvl_ms;
+    int rc;
+
+    if (argc < 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    if (strcmp(argv[1], "stop") == 0) {
+        lorashell_txes_pending = 0;
+        Radio.Sleep();
+        console_printf("lora tx stopped\n");
+        return 0;
+    }
+
+    lorashell_tx_size = parse_ull_bounds(argv[1], 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid size";
+        goto err;
+    }
+
+    if (argc >= 2) {
+        lorashell_txes_pending = parse_ull_bounds(argv[2], 0, INT_MAX, &rc);
+        if (rc != 0) {
+            err = "invalid count";
+            goto err;
+        }
+    } else {
+        lorashell_txes_pending = 1;
+    }
+
+    if (argc >= 3) {
+        itvl_ms = parse_ull_bounds(argv[3], 0, UINT32_MAX, &rc);
+        if (rc != 0) {
+            err = "invalid interval";
+            goto err;
+        }
+    } else {
+        itvl_ms = 1000;
+    }
+
+    rc = os_time_ms_to_ticks(itvl_ms, &lorashell_tx_itvl);
+    if (rc != 0) {
+        err = "invalid interval";
+        goto err;
+    }
+
+    lorashell_tx_timer_exp(NULL);
+
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora_tx_rpt <size> [count] [interval (ms)]\n"
+"    lora_tx_rpt stop\n");
+
+    return rc;
+}
+
+int
+main(void)
+{
+    RadioEvents_t radio_events;
+    int rc;
+    int i;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    for (i = 0; i < LORASHELL_NUM_CLI_CMDS; i++) {
+        rc = shell_cmd_register(lorashell_cli_cmds + i);
+        SYSINIT_PANIC_ASSERT_MSG(
+            rc == 0, "Failed to register lorashell CLI commands");
+    }
+
+    os_callout_init(&lorashell_tx_timer, os_eventq_dflt_get(),
+                    lorashell_tx_timer_exp, NULL);
+
+    /* Radio initialization. */
+    radio_events.TxDone = on_tx_done;
+    radio_events.RxDone = on_rx_done;
+    radio_events.TxTimeout = on_tx_timeout;
+    radio_events.RxTimeout = on_rx_timeout;
+    radio_events.RxError = on_rx_error;
+
+    Radio.Init(&radio_events);
+    Radio.SetMaxPayloadLength(MODEM_LORA, 250);
+
+    console_printf("lorashell\n");
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/apps/lorashell/syscfg.yml
----------------------------------------------------------------------
diff --git a/apps/lorashell/syscfg.yml b/apps/lorashell/syscfg.yml
new file mode 100644
index 0000000..ba7ce41
--- /dev/null
+++ b/apps/lorashell/syscfg.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    LORASHELL_NUM_RX_ENTRIES:
+        description: "The size of the receive log."
+        value: 10
+
+syscfg.vals:
+    STATS_CLI: 1
+    STATS_NAMES: 1

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/bsp/telee02/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/bsp/telee02/pkg.yml b/hw/bsp/telee02/pkg.yml
index d1ceebd..0324334 100644
--- a/hw/bsp/telee02/pkg.yml
+++ b/hw/bsp/telee02/pkg.yml
@@ -89,6 +89,10 @@ pkg.deps:
 pkg.deps.BLE_DEVICE:
     - hw/drivers/nimble/nrf52
 
+pkg.deps.LORA_NODE:
+    - hw/drivers/lora/node/radio/sx1276
+    - hw/drivers/lora/node/board/nrf52
+
 pkg.deps.UART_0:
     - hw/drivers/uart/uart_hal
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/board/nrf52/LICENSE.txt
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/board/nrf52/LICENSE.txt b/hw/drivers/lora/node/board/nrf52/LICENSE.txt
new file mode 100644
index 0000000..82695a7
--- /dev/null
+++ b/hw/drivers/lora/node/board/nrf52/LICENSE.txt
@@ -0,0 +1,25 @@
+--- Revised BSD License ---
+Copyright (c) 2013, SEMTECH S.A.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Semtech corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/board/nrf52/include/board/board.h
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/board/nrf52/include/board/board.h b/hw/drivers/lora/node/board/nrf52/include/board/board.h
new file mode 100644
index 0000000..7d60c5f
--- /dev/null
+++ b/hw/drivers/lora/node/board/nrf52/include/board/board.h
@@ -0,0 +1,92 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: Target board general functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include "bsp/bsp.h"
+#include "node/utilities.h"
+
+/*!
+ * Board MCU pins definitions
+ */
+
+#define RADIO_RESET                 SX1276_NRESET
+
+#define RADIO_SPI_IDX               MYNEWT_VAL(LORA_NODE_BOARD_SPI_IDX)
+
+#if RADIO_SPI_IDX == 0
+#define RADIO_NSS                   MYNEWT_VAL(SPI_0_MASTER_SS_PIN)
+#else
+#error Invalid LORA_NODE_BOARD_SPI_IDX value
+#endif
+
+#define RADIO_DIO_0                 SX1276_DIO0
+#define RADIO_DIO_1                 SX1276_DIO1
+#define RADIO_DIO_2                 SX1276_DIO2
+#define RADIO_DIO_3                 SX1276_DIO3
+#define RADIO_DIO_4                 SX1276_DIO4
+#define RADIO_DIO_5                 SX1276_DIO5
+
+#define RADIO_ANT_SWITCH_HF         SX1276_ANT_HF_CTRL
+
+#define RF_RXTX                     SX1276_RXTX
+
+/*!
+ * Possible power sources
+ */
+enum BoardPowerSources
+{
+    USB_POWER = 0,
+    BATTERY_POWER,
+};
+
+/*!
+ * \brief Get the current battery level
+ *
+ * \retval value  battery level [  0: USB,
+ *                                 1: Min level,
+ *                                 x: level
+ *                               254: fully charged,
+ *                               255: Error]
+ */
+uint8_t BoardGetBatteryLevel( void );
+
+/*!
+ * Returns a pseudo random seed generated using the MCU Unique ID
+ *
+ * \retval seed Generated pseudo random seed
+ */
+uint32_t BoardGetRandomSeed( void );
+
+/*!
+ * \brief Gets the board 64 bits unique ID
+ *
+ * \param [IN] id Pointer to an array that will contain the Unique ID
+ */
+void BoardGetUniqueId( uint8_t *id );
+
+/*!
+ * \brief Get the board power source
+ *
+ * \retval value  power source [0: USB_POWER, 1: BATTERY_POWER]
+ */
+uint8_t GetBoardPowerSource( void );
+
+#endif // __BOARD_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/board/nrf52/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/board/nrf52/pkg.yml b/hw/drivers/lora/node/board/nrf52/pkg.yml
new file mode 100644
index 0000000..d626845
--- /dev/null
+++ b/hw/drivers/lora/node/board/nrf52/pkg.yml
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/lora/node/board/nrf52
+pkg.description: LoRaMac-node board driver for nRF52 systems.
+pkg.author: "Telenor Digital AS"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - lora
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/lora/node"
+
+pkg.apis:
+    - lora_node_board
+
+pkg.init:
+    lora_node_nrf52_init: 100

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/board/nrf52/src/lora_nrf52.c
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/board/nrf52/src/lora_nrf52.c b/hw/drivers/lora/node/board/nrf52/src/lora_nrf52.c
new file mode 100644
index 0000000..828f5bb
--- /dev/null
+++ b/hw/drivers/lora/node/board/nrf52/src/lora_nrf52.c
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "board/board.h"
+
+void
+lora_node_nrf52_init(void)
+{
+    struct hal_spi_settings spi_settings;
+    int rc;
+
+    hal_gpio_init_out(RADIO_NSS, 1);
+
+    spi_settings.data_order = HAL_SPI_MSB_FIRST;
+    spi_settings.data_mode = HAL_SPI_MODE0;
+    spi_settings.baudrate = MYNEWT_VAL(LORA_NODE_BOARD_SPI_BAUDRATE);
+    spi_settings.word_size = HAL_SPI_WORD_SIZE_8BIT;
+
+    rc = hal_spi_config(RADIO_SPI_IDX, &spi_settings);
+    SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to configure LoRa SPI");
+
+    rc = hal_spi_enable(0);
+    SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failed to enable LoRa SPI");
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/board/nrf52/syscfg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/board/nrf52/syscfg.yml b/hw/drivers/lora/node/board/nrf52/syscfg.yml
new file mode 100644
index 0000000..0babd74
--- /dev/null
+++ b/hw/drivers/lora/node/board/nrf52/syscfg.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+    LORA_NODE_BOARD_SPI_IDX:
+        description:
+        value: 0
+
+    LORA_NODE_BOARD_SPI_BAUDRATE:
+        description:
+        value: 500

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/radio/sx1276/LICENSE.txt
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/radio/sx1276/LICENSE.txt b/hw/drivers/lora/node/radio/sx1276/LICENSE.txt
new file mode 100644
index 0000000..82695a7
--- /dev/null
+++ b/hw/drivers/lora/node/radio/sx1276/LICENSE.txt
@@ -0,0 +1,25 @@
+--- Revised BSD License ---
+Copyright (c) 2013, SEMTECH S.A.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Semtech corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/radio/sx1276/include/radio/radio.h
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/radio/sx1276/include/radio/radio.h b/hw/drivers/lora/node/radio/sx1276/include/radio/radio.h
new file mode 100644
index 0000000..6f23183
--- /dev/null
+++ b/hw/drivers/lora/node/radio/sx1276/include/radio/radio.h
@@ -0,0 +1,33 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: Generic SX1276 driver implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef H_RADIO_RADIO_
+#define H_RADIO_RADIO_
+
+/*!
+ * Radio wakeup time from SLEEP mode
+ */
+#define RADIO_OSC_STARTUP                           1 // [ms]
+
+/*!
+ * Radio PLL lock and Mode Ready delay which can vary with the temperature
+ */
+#define RADIO_SLEEP_TO_RX                           2 // [ms]
+
+/*!
+ * Radio complete Wake-up Time with margin for temperature compensation
+ */
+#define RADIO_WAKEUP_TIME                           ( RADIO_OSC_STARTUP + RADIO_SLEEP_TO_RX )
+
+#endif /* H_RADIO_RADIO */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/radio/sx1276/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/radio/sx1276/pkg.yml b/hw/drivers/lora/node/radio/sx1276/pkg.yml
new file mode 100644
index 0000000..5b98cef
--- /dev/null
+++ b/hw/drivers/lora/node/radio/sx1276/pkg.yml
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/lora/node/radio/sx1276
+pkg.description: LoRaMac-node radio driver for the SX1276 modem.
+pkg.author: "Semtech"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - lora
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/lora/node"
+
+pkg.apis:
+    - lora_node_radio
+
+pkg.req_apis:
+    - lora_node_board

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.c
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.c b/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.c
new file mode 100644
index 0000000..7bebcc5
--- /dev/null
+++ b/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.c
@@ -0,0 +1,163 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: SX1276 driver specific target board functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include <assert.h>
+#include "board/board.h"
+#include "node/radio.h"
+#include "sx1276.h"
+#include "sx1276-board.h"
+
+/*!
+ * Flag used to set the RF switch control pins in low power mode when the radio is not active.
+ */
+static bool RadioIsActive = false;
+
+/*!
+ * Radio driver structure initialization
+ */
+const struct Radio_s Radio =
+{
+    .Init = SX1276Init,
+    .GetStatus = SX1276GetStatus,
+    .SetModem = SX1276SetModem,
+    .SetChannel = SX1276SetChannel,
+    .IsChannelFree = SX1276IsChannelFree,
+    .Random = SX1276Random,
+    .SetRxConfig = SX1276SetRxConfig,
+    .SetTxConfig = SX1276SetTxConfig,
+    .CheckRfFrequency = SX1276CheckRfFrequency,
+    .TimeOnAir = SX1276GetTimeOnAir,
+    .Send = SX1276Send,
+    .Sleep = SX1276SetSleep,
+    .Standby = SX1276SetStby,
+    .Rx = SX1276SetRx,
+    .StartCad = SX1276StartCad,
+    .Rssi = SX1276ReadRssi,
+    .Write = SX1276Write,
+    .Read = SX1276Read,
+    .WriteBuffer = SX1276WriteBuffer,
+    .ReadBuffer = SX1276ReadBuffer,
+    .SetMaxPayloadLength = SX1276SetMaxPayloadLength
+};
+
+void SX1276IoInit( void )
+{
+    int rc;
+
+    rc = hal_gpio_init_out(RF_RXTX, 1);
+    assert(rc == 0);
+}
+
+void SX1276IoIrqInit( DioIrqHandler **irqHandlers )
+{
+    int rc;
+
+    rc = hal_gpio_irq_init(RADIO_DIO_0, irqHandlers[0], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_0);
+
+    rc = hal_gpio_irq_init(RADIO_DIO_1, irqHandlers[1], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_1);
+
+    rc = hal_gpio_irq_init(RADIO_DIO_2, irqHandlers[2], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_2);
+
+    rc = hal_gpio_irq_init(RADIO_DIO_3, irqHandlers[3], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_3);
+
+    rc = hal_gpio_irq_init(RADIO_DIO_4, irqHandlers[4], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_4);
+
+    rc = hal_gpio_irq_init(RADIO_DIO_5, irqHandlers[5], NULL,
+                           HAL_GPIO_TRIG_RISING, HAL_GPIO_PULL_NONE);
+    assert(rc == 0);
+    hal_gpio_irq_enable(RADIO_DIO_5);
+}
+
+void SX1276IoDeInit( void )
+{
+    hal_gpio_irq_release(RADIO_DIO_0);
+    hal_gpio_irq_release(RADIO_DIO_1);
+    hal_gpio_irq_release(RADIO_DIO_2);
+    hal_gpio_irq_release(RADIO_DIO_3);
+    hal_gpio_irq_release(RADIO_DIO_4);
+    hal_gpio_irq_release(RADIO_DIO_5);
+}
+
+uint8_t SX1276GetPaSelect( uint32_t channel )
+{
+    if( channel < RF_MID_BAND_THRESH )
+    {
+        return RF_PACONFIG_PASELECT_PABOOST;
+    }
+    else
+    {
+        return RF_PACONFIG_PASELECT_RFO;
+    }
+}
+
+void SX1276SetAntSwLowPower( bool status )
+{
+    if( RadioIsActive != status )
+    {
+        RadioIsActive = status;
+
+        if( status == false )
+        {
+            SX1276AntSwInit( );
+        }
+        else
+        {
+            SX1276AntSwDeInit( );
+        }
+    }
+}
+
+void SX1276AntSwInit( void )
+{
+    // Consider turning off GPIO pins for low power. They are always on right
+    // now. GPIOTE library uses 0.5uA max when on, typical 0.1uA.
+}
+
+void SX1276AntSwDeInit( void )
+{
+    // Consider this for low power - ie turning off GPIO pins
+}
+
+void SX1276SetAntSw( uint8_t rxTx )
+{
+    if( rxTx != 0 ) // 1: TX, 0: RX
+    {
+        hal_gpio_write(SX1276_RXTX, 1);
+    }
+    else
+    {
+        hal_gpio_write(SX1276_RXTX, 0);
+    }
+}
+
+bool SX1276CheckRfFrequency( uint32_t frequency )
+{
+    // Implement check. Currently all frequencies are supported
+    return true;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/9986f68c/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.h
----------------------------------------------------------------------
diff --git a/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.h b/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.h
new file mode 100644
index 0000000..5156e8a
--- /dev/null
+++ b/hw/drivers/lora/node/radio/sx1276/src/sx1276-board.h
@@ -0,0 +1,119 @@
+/*
+ / _____)             _              | |
+( (____  _____ ____ _| |_ _____  ____| |__
+ \____ \| ___ |    (_   _) ___ |/ ___)  _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+    (C)2013 Semtech
+
+Description: SX1276 driver specific target board functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __SX1276_ARCH_H__
+#define __SX1276_ARCH_H__
+
+#include "hal/hal_gpio.h"
+
+/*!
+ * \brief Radio hardware registers initialization definition
+ *
+ * \remark Can be automatically generated by the SX1276 GUI (not yet implemented)
+ */
+#define RADIO_INIT_REGISTERS_VALUE                \
+{                                                 \
+    { MODEM_FSK , REG_LNA                , 0x23 },\
+    { MODEM_FSK , REG_RXCONFIG           , 0x1E },\
+    { MODEM_FSK , REG_RSSICONFIG         , 0xD2 },\
+    { MODEM_FSK , REG_AFCFEI             , 0x01 },\
+    { MODEM_FSK , REG_PREAMBLEDETECT     , 0xAA },\
+    { MODEM_FSK , REG_OSC                , 0x07 },\
+    { MODEM_FSK , REG_SYNCCONFIG         , 0x12 },\
+    { MODEM_FSK , REG_SYNCVALUE1         , 0xC1 },\
+    { MODEM_FSK , REG_SYNCVALUE2         , 0x94 },\
+    { MODEM_FSK , REG_SYNCVALUE3         , 0xC1 },\
+    { MODEM_FSK , REG_PACKETCONFIG1      , 0xD8 },\
+    { MODEM_FSK , REG_FIFOTHRESH         , 0x8F },\
+    { MODEM_FSK , REG_IMAGECAL           , 0x02 },\
+    { MODEM_FSK , REG_DIOMAPPING1        , 0x00 },\
+    { MODEM_FSK , REG_DIOMAPPING2        , 0x30 },\
+    { MODEM_LORA, REG_LR_PAYLOADMAXLENGTH, 0x40 },\
+}                                                 \
+
+#define RF_MID_BAND_THRESH                          525000000
+
+/*!
+ * \brief Initializes the radio I/Os pins interface
+ */
+void SX1276IoInit( void );
+
+void SX1276IoIrqInit( DioIrqHandler **irqHandlers );
+
+/*!
+ * \brief De-initializes the radio I/Os pins interface. 
+ *
+ * \remark Useful when going in MCU low power modes
+ */
+void SX1276IoDeInit( void );
+
+/*!
+ * \brief Sets the radio output power.
+ *
+ * \param [IN] power Sets the RF output power
+ */
+void SX1276SetRfTxPower( int8_t power );
+
+/*!
+ * \brief Gets the board PA selection configuration
+ *
+ * \param [IN] channel Channel frequency in Hz
+ * \retval PaSelect RegPaConfig PaSelect value
+ */
+uint8_t SX1276GetPaSelect( uint32_t channel );
+
+/*!
+ * \brief Set the RF Switch I/Os pins in Low Power mode
+ *
+ * \param [IN] status enable or disable
+ */
+void SX1276SetAntSwLowPower( bool status );
+
+/*!
+ * \brief Initializes the RF Switch I/Os pins interface
+ */
+void SX1276AntSwInit( void );
+
+/*!
+ * \brief De-initializes the RF Switch I/Os pins interface 
+ *
+ * \remark Needed to decrease the power consumption in MCU low power modes
+ */
+void SX1276AntSwDeInit( void );
+
+/*!
+ * \brief Controls the antenna switch if necessary.
+ *
+ * \remark see errata note
+ *
+ * \param [IN] opMode Current radio operating mode
+ */
+void SX1276SetAntSw( uint8_t opMode );
+
+/*!
+ * \brief Checks if the given RF frequency is supported by the hardware
+ *
+ * \param [IN] frequency RF frequency to be checked
+ * \retval isSupported [true: supported, false: unsupported]
+ */
+bool SX1276CheckRfFrequency( uint32_t frequency );
+
+void hal_pin_rxtx (int val);
+
+/*!
+ * Radio hardware and global parameters
+ */
+extern SX1276_t SX1276;
+
+#endif // __SX1276_ARCH_H__