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 <ccoll...@apache.org> Authored: Mon Apr 24 19:18:10 2017 -0700 Committer: Christopher Collins <ccoll...@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 <d...@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 <d...@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__