lupyuen.org/articles/lorawan3.html

906 lines
52 KiB
HTML
Raw Normal View History

2021-12-30 10:58:30 +08:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="rustdoc">
<title>LoRaWAN on Apache NuttX OS</title>
<!-- Begin scripts/articles/*-header.html: Article Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<meta property="og:title"
content="LoRaWAN on Apache NuttX OS"
data-rh="true">
<meta property="og:description"
content="Porting Semtech's LoRaWAN Stack to Apache NuttX OS... And testing it on PineDio Stack BL604 RISC-V Board"
data-rh="true">
<meta property="og:image"
content="https://lupyuen.github.io/images/lorawan3-title.jpg">
<meta property="og:type"
content="article" data-rh="true">
<!-- End scripts/articles/*-header.html -->
<!-- Begin scripts/rustdoc-header.html: Header for Custom Markdown files processed by rustdoc, like chip8.md -->
<link rel="alternate" type="application/rss+xml" title="RSS Feed for lupyuen" href="/rss.xml" />
<link rel="stylesheet" type="text/css" href="../normalize.css">
<link rel="stylesheet" type="text/css" href="../rustdoc.css" id="mainThemeStyle">
<link rel="stylesheet" type="text/css" href="../dark.css">
<link rel="stylesheet" type="text/css" href="../light.css" id="themeStyle">
<link rel="stylesheet" type="text/css" href="../prism.css">
<script src="../storage.js"></script><noscript>
<link rel="stylesheet" href="../noscript.css"></noscript>
<link rel="shortcut icon" href="../favicon.ico">
<style type="text/css">
#crate-search {
background-image: url("../down-arrow.svg");
}
a {
color: #77d;
}
</style>
<!-- End scripts/rustdoc-header.html -->
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<!-- Begin scripts/rustdoc-before.html: Pre-HTML for Custom Markdown files processed by rustdoc, like chip8.md -->
<!-- Begin Theme Picker -->
<div class="theme-picker" style="left: 0"><button id="theme-picker" aria-label="Pick another theme!"><img src="../brush.svg"
width="18" alt="Pick another theme!"></button>
<div id="theme-choices"></div>
</div>
<script src="../theme.js"></script>
<script src="../prism.js"></script>
<!-- Theme Picker -->
<!-- End scripts/rustdoc-before.html -->
<h1 class="title">LoRaWAN on Apache NuttX OS</h1>
<nav id="TOC"><ul>
<li><a href="#small-steps">1 Small Steps</a><ul>
<li><a href="#lorawan-support">1.1 LoRaWAN Support</a><ul></ul></li>
2021-12-30 18:14:03 +08:00
<li><a href="#dependencies">1.2 Dependencies</a><ul></ul></li></ul></li>
2021-12-31 01:42:31 +08:00
<li><a href="#lorawan-objective">2 LoRaWAN Objective</a><ul></ul></li>
2021-12-31 09:48:18 +08:00
<li><a href="#download-source-code">3 Download Source Code</a><ul></ul></li>
2021-12-31 17:52:11 +08:00
<li><a href="#device-eui-join-eui-and-app-key">4 Device EUI, Join EUI and App Key</a><ul>
<li><a href="#secure-element">4.1 Secure Element</a><ul></ul></li></ul></li>
2021-12-31 16:24:13 +08:00
<li><a href="#lorawan-frequency">5 LoRaWAN Frequency</a><ul></ul></li>
2021-12-31 19:09:25 +08:00
<li><a href="#build-the-firmware">6 Build The Firmware</a><ul></ul></li>
<li><a href="#run-the-firmware">7 Run The Firmware</a><ul></ul></li>
2021-12-31 19:55:05 +08:00
<li><a href="#join-lorawan-network">8 Join LoRaWAN Network</a><ul></ul></li>
<li><a href="#send-data-to-lorawan">9 Send Data To LoRaWAN</a><ul></ul></li>
<li><a href="#lorawan-event-loop">10 LoRaWAN Event Loop</a><ul></ul></li>
2021-12-31 19:09:25 +08:00
<li><a href="#lorawan-nonce">11 LoRaWAN Nonce</a><ul></ul></li>
2021-12-31 19:55:05 +08:00
<li><a href="#nimble-porting-layer">12 NimBLE Porting Layer</a><ul></ul></li>
<li><a href="#gpio-interrupts">13 GPIO Interrupts</a><ul></ul></li>
<li><a href="#sx1262-busy">14 SX1262 Busy</a><ul></ul></li>
<li><a href="#troubleshoot-lorawan">15 Troubleshoot LoRaWAN</a><ul>
<li><a href="#logging">15.1 Logging</a><ul></ul></li>
<li><a href="#message-size">15.2 Message Size</a><ul></ul></li></ul></li>
<li><a href="#spi-with-dma">16 SPI with DMA</a><ul></ul></li>
<li><a href="#whats-next">17 Whats Next</a><ul></ul></li>
<li><a href="#notes">18 Notes</a><ul></ul></li>
<li><a href="#appendix-posix-timers-and-message-queues">19 Appendix: POSIX Timers and Message Queues</a><ul></ul></li>
<li><a href="#appendix-random-number-generator-with-entropy-pool">20 Appendix: Random Number Generator with Entropy Pool</a><ul></ul></li>
<li><a href="#appendix-build-flash-and-run-nuttx">21 Appendix: Build, Flash and Run NuttX</a><ul>
<li><a href="#build-nuttx">21.1 Build NuttX</a><ul></ul></li>
<li><a href="#flash-nuttx">21.2 Flash NuttX</a><ul></ul></li>
<li><a href="#run-nuttx">21.3 Run NuttX</a><ul></ul></li></ul></li>
<li><a href="#appendix-gpio-issue">22 Appendix: GPIO Issue</a><ul></ul></li>
<li><a href="#appendix-callout-issue">23 Appendix: Callout Issue</a><ul></ul></li></ul></nav><p>📝 <em>7 Jan 2022</em></p>
2021-12-30 11:49:59 +08:00
<p><img src="https://lupyuen.github.io/images/lorawan3-title.jpg" alt="PineDio Stack BL604 RISC-V Board (left) talking LoRaWAN to RAKwireless WisGate LoRaWAN Gateway (right)" /></p>
<p><em>PineDio Stack BL604 RISC-V Board (left) talking LoRaWAN to RAKwireless WisGate LoRaWAN Gateway (right)</em></p>
<p>Last article we got <strong>LoRa</strong> (the long-range, low-bandwidth wireless network) running on <a href="https://lupyuen.github.io/articles/nuttx"><strong>Apache NuttX OS</strong></a></p>
2021-12-30 10:58:30 +08:00
<ul>
2021-12-30 11:49:59 +08:00
<li><a href="https://lupyuen.github.io/articles/sx1262"><strong>“LoRa SX1262 on Apache NuttX OS”</strong></a></li>
2021-12-30 10:58:30 +08:00
</ul>
2021-12-30 11:49:59 +08:00
<p>Today we shall run <strong>LoRaWAN</strong> on NuttX OS!</p>
2021-12-30 11:51:32 +08:00
<p><em>Why would we need LoRaWAN?</em></p>
2021-12-30 11:49:59 +08:00
<p>LoRa will work perfectly fine for unsecured <strong>Point-to-Point Wireless Communication</strong>.</p>
2021-12-30 10:58:30 +08:00
<p>But if we need to <strong>relay data packets</strong> securely to a Local Area Network or to the internet, we need <strong>LoRaWAN</strong>.</p>
<p><a href="https://makezine.com/2021/05/24/go-long-with-lora-radio/">(More about LoRaWAN)</a></p>
2021-12-30 11:49:59 +08:00
<p>We shall test LoRaWAN on NuttX with Bouffalo Labs <a href="https://lupyuen.github.io/articles/pinecone"><strong>BL602 and BL604 RISC-V SoCs</strong></a>.</p>
<p>(It will probably run on <strong>ESP32</strong>, since were calling standard NuttX Interfaces)</p>
<p><img src="https://lupyuen.github.io/images/sx1262-library5.jpg" alt="Porting LoRaWAN to NuttX OS" /></p>
2021-12-30 10:58:30 +08:00
<h1 id="small-steps" class="section-header"><a href="#small-steps">1 Small Steps</a></h1>
2021-12-30 18:14:03 +08:00
<p>In the last article we created a <strong>LoRa Library for NuttX</strong> (top right) that works with <strong>Semtech SX1262 Transceiver</strong></p>
2021-12-30 16:35:12 +08:00
<ul>
2021-12-30 18:14:03 +08:00
<li><a href="https://github.com/lupyuen/lora-sx1262/tree/lorawan"><strong>lupyuen/lora-sx1262 (lorawan branch)</strong></a></li>
2021-12-30 16:35:12 +08:00
</ul>
2021-12-30 18:14:03 +08:00
<p>Today well create a <strong>LoRaWAN Library for NuttX</strong> (centre right)…</p>
2021-12-30 10:58:30 +08:00
<ul>
2021-12-30 18:14:03 +08:00
<li><a href="https://github.com/lupyuen/LoRaMac-node-nuttx"><strong>lupyuen/LoRaMac-node-nuttx</strong></a></li>
</ul>
<p>Thats a near-identical fork of <strong>Semtechs LoRaWAN Stack</strong> (dated 14 Dec 2021)…</p>
<ul>
<li><a href="https://github.com/Lora-net/LoRaMac-node"><strong>Lora-net/LoRaMac-node</strong></a></li>
2021-12-30 10:58:30 +08:00
</ul>
2021-12-30 18:29:00 +08:00
<p>Well test with this <strong>LoRaWAN App</strong> on NuttX…</p>
<ul>
<li><a href="https://github.com/lupyuen/lorawan_test"><strong>lupyuen/lorawan_test</strong></a></li>
</ul>
2021-12-30 10:58:30 +08:00
<h2 id="lorawan-support" class="section-header"><a href="#lorawan-support">1.1 LoRaWAN Support</a></h2>
2021-12-30 18:14:03 +08:00
<p><em>Why did we fork Semtechs LoRaWAN Stack? Why not build it specifically for NuttX?</em></p>
2021-12-30 10:58:30 +08:00
<p>LoRaWAN works <strong>slightly differently across the world regions</strong>, to comply with Local Wireless Regulations: Radio Frequency, Maximum Airtime (Duty Cycle), <a href="https://lupyuen.github.io/articles/lorawan#appendix-lora-carrier-sensing">Listen Before Talk</a>, …</p>
<p>Thus we should port <strong>Semtechs LoRaWAN Stack</strong> to NuttX with <strong>minimal changes</strong>, in case of future updates. (Like for new regions)</p>
2021-12-30 18:14:03 +08:00
<p><em>How did we create the LoRaWAN Library?</em></p>
<p>We followed the steps below to create <strong>“nuttx/libs/liblorawan”</strong> by cloning a NuttX Library…</p>
2021-12-30 10:58:30 +08:00
<ul>
<li><a href="https://lupyuen.github.io/articles/sx1262#appendix-create-a-nuttx-library"><strong>“Create a NuttX Library”</strong></a></li>
</ul>
2021-12-30 18:14:03 +08:00
<p>Then we replaced the “liblorawan” folder by a <strong>Git Submodule</strong> that contains our LoRaWAN code… </p>
2021-12-30 10:58:30 +08:00
<div class="example-wrap"><pre class="language-bash"><code>cd nuttx/nuttx/libs
2021-12-30 18:14:03 +08:00
rm -r liblorawan
git rm -r liblorawan
git submodule add https://github.com/lupyuen/LoRaMac-node-nuttx liblorawan</code></pre></div>
<p><a href="https://github.com/lupyuen/LoRaMac-node-nuttx">(To add the LoRaWAN Library to your NuttX Project, see this)</a></p>
<h2 id="dependencies" class="section-header"><a href="#dependencies">1.2 Dependencies</a></h2>
<p>Our LoRaWAN Library should work on <strong>any NuttX platform</strong> (like ESP32), assuming that the following dependencies are installed…</p>
2021-12-30 10:58:30 +08:00
<ul>
<li>
2021-12-30 18:14:03 +08:00
<p><a href="https://github.com/lupyuen/lora-sx1262/tree/lorawan"><strong>lupyuen/lora-sx1262 (lorawan branch)</strong></a></p>
<p>LoRa Library for Semtech SX1262 Transceiver</p>
<p><a href="https://lupyuen.github.io/articles/sx1262">(See this)</a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/nimble-porting-nuttx"><strong>lupyuen/nimble-porting-nuttx</strong></a></p>
<p>NimBLE Porting Layer multithreading library</p>
<p><a href="https://lupyuen.github.io/articles/sx1262#multithreading-with-nimble-porting-layer">(See this)</a></p>
2021-12-30 10:58:30 +08:00
</li>
<li>
2021-12-30 18:14:03 +08:00
<p><a href="https://github.com/lupyuen/incubator-nuttx/tree/lorawan/drivers/rf"><strong>spi_test_driver (/dev/spitest0)</strong></a></p>
<p>SPI Test Driver</p>
<p><a href="https://lupyuen.github.io/articles/spi2">(See this)</a></p>
2021-12-30 10:58:30 +08:00
</li>
</ul>
2021-12-30 18:14:03 +08:00
<p>Our LoRa SX1262 Library assumes that the following <strong>NuttX Devices</strong> are configured…</p>
2021-12-30 10:58:30 +08:00
<ul>
<li>
2021-12-30 18:14:03 +08:00
<p><strong>/dev/gpio0</strong>: GPIO Input for SX1262 Busy Pin</p>
2021-12-30 10:58:30 +08:00
</li>
<li>
2021-12-30 18:14:03 +08:00
<p><strong>/dev/gpio1</strong>: GPIO Output for SX1262 Chip Select</p>
</li>
<li>
<p><strong>/dev/gpio2</strong>: GPIO Interrupt for SX1262 DIO1 Pin</p>
</li>
<li>
2021-12-30 20:20:16 +08:00
<p><strong>/dev/spi0</strong>: SPI Bus for SX1262</p>
</li>
<li>
2021-12-30 18:14:03 +08:00
<p><strong>/dev/spitest0</strong>: SPI Test Driver (see above)</p>
2021-12-30 10:58:30 +08:00
</li>
</ul>
2021-12-31 01:42:31 +08:00
<h1 id="lorawan-objective" class="section-header"><a href="#lorawan-objective">2 LoRaWAN Objective</a></h1>
<p><em>What shall we accomplish with LoRaWAN today?</em></p>
<p>Well do the basic LoRaWAN use case on NuttX…</p>
<ul>
<li>
2021-12-31 10:02:51 +08:00
<p>Join NuttX to the <strong>LoRaWAN Network</strong></p>
2021-12-31 01:42:31 +08:00
</li>
<li>
<p>Send a <strong>Data Packet</strong> from NuttX to LoRaWAN</p>
</li>
</ul>
<p>Which works like this…</p>
2021-12-31 09:48:18 +08:00
<p><img src="https://lupyuen.github.io/images/lorawan3-flow.jpg" alt="LoRaWAN Use Case" /></p>
2021-12-31 01:42:31 +08:00
<ol>
<li>
<p>NuttX sends a <strong>Join Network Request</strong> to the LoRaWAN Gateway.</p>
<p>Inside the Join Network Request are…</p>
2021-12-31 10:02:51 +08:00
<p><strong>Device EUI:</strong> Unique ID thats assigned to our LoRaWAN Device</p>
<p><strong>Join EUI:</strong> Identifies the LoRaWAN Network that were joining</p>
2021-12-31 10:24:15 +08:00
<p><strong>Nonce:</strong> Non-repeating number, to prevent <a href="https://en.wikipedia.org/wiki/Replay_attack">Replay Attacks</a></p>
2022-01-01 09:56:22 +08:00
<p><em>(EUI sounds like Durian on Century Egg… But it actually means Extended Unique Identifier)</em></p>
2021-12-31 01:42:31 +08:00
</li>
<li>
<p>LoRaWAN Gateway returns a <strong>Join Network Response</strong></p>
2021-12-31 14:41:03 +08:00
<p><em>(Which contains the Device Address)</em></p>
2021-12-31 01:42:31 +08:00
</li>
<li>
<p>NuttX sends a <strong>Data Packet</strong> to the LoRaWAN Network</p>
2021-12-31 14:41:03 +08:00
<p><em>(Which has the Device Address and Payload “Hi NuttX”)</em></p>
2021-12-31 01:42:31 +08:00
</li>
<li>
<p>NuttX uses an <strong>App Key</strong> to sign the Join Network Request and the Data Packet</p>
2021-12-31 14:41:03 +08:00
<p><em>(App Key is stored inside NuttX, never exposed over the airwaves)</em></p>
2021-12-31 01:42:31 +08:00
</li>
</ol>
2021-12-31 14:27:01 +08:00
<p>In a while well set the Device EUI, Join EUI and App Key in our code.</p>
2021-12-31 09:48:18 +08:00
<h1 id="download-source-code" class="section-header"><a href="#download-source-code">3 Download Source Code</a></h1>
2021-12-31 14:27:01 +08:00
<p>To run LoRaWAN on NuttX, download the modified source code for <strong>NuttX OS and NuttX Apps</strong></p>
<div class="example-wrap"><pre class="language-bash"><code>mkdir nuttx
cd nuttx
git clone --recursive --branch lorawan https://github.com/lupyuen/incubator-nuttx nuttx
git clone --recursive --branch lorawan https://github.com/lupyuen/incubator-nuttx-apps apps</code></pre></div>
<p>Or if we prefer to <strong>add the LoRaWAN Library</strong> to our NuttX Project, follow these instructions…</p>
<ol>
<li>
<p><a href="https://github.com/lupyuen/incubator-nuttx/tree/lorawan/drivers/rf"><strong>“Install SPI Test Driver”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/nimble-porting-nuttx"><strong>“Install NimBLE Porting Layer”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/lora-sx1262/tree/lorawan"><strong>“Install LoRa SX1262 Library”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/LoRaMac-node-nuttx"><strong>“Install LoRaWAN Library”</strong></a></p>
</li>
<li>
<p><a href="https://github.com/lupyuen/lorawan_test"><strong>“Install LoRaWAN Test App”</strong></a></p>
</li>
</ol>
2021-12-31 16:24:13 +08:00
<p>Lets configure our LoRaWAN code.</p>
2021-12-31 15:33:02 +08:00
<p><img src="https://lupyuen.github.io/images/wisgate-app2.png" alt="Device EUI from ChirpStack" /></p>
2021-12-31 09:48:18 +08:00
<h1 id="device-eui-join-eui-and-app-key" class="section-header"><a href="#device-eui-join-eui-and-app-key">4 Device EUI, Join EUI and App Key</a></h1>
2021-12-31 14:27:01 +08:00
<p><em>Where do we get the Device EUI, Join EUI and App Key?</em></p>
2021-12-31 15:33:02 +08:00
<p>We get the LoRaWAN Settings from our <strong>LoRaWAN Gateway</strong>, like ChirpStack (pic above)…</p>
<ul>
<li><a href="https://lupyuen.github.io/articles/wisgate#lorawan-application"><strong>“LoRaWAN Application (ChirpStack)”</strong></a></li>
</ul>
<p><em>How do we set the Device EUI, Join EUI and App Key in our code?</em></p>
<p>Edit the file…</p>
<div class="example-wrap"><pre class="language-text"><code>nuttx/libs/liblorawan/src/peripherals/soft-se/se-identity.h</code></pre></div>
2021-12-31 17:09:16 +08:00
<p>Look for these lines in <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/blob/master/src/peripherals/soft-se/se-identity.h#L65-L79"><strong>se-identity.h</strong></a></p>
2021-12-31 15:33:02 +08:00
<div class="example-wrap"><pre class="language-c"><code>/*!
* When set to 1 DevEui is LORAWAN_DEVICE_EUI
* When set to 0 DevEui is automatically set with a value provided by MCU platform
*/
#define STATIC_DEVICE_EUI 1
/*!
* end-device IEEE EUI (big endian)
*/
#define LORAWAN_DEVICE_EUI { 0x4b, 0xc1, 0x5e, 0xe7, 0x37, 0x7b, 0xb1, 0x5b }
/*!
* App/Join server IEEE EUI (big endian)
*/
#define LORAWAN_JOIN_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }</code></pre></div>
<ul>
<li>
<p><strong>STATIC_DEVICE_EUI:</strong> Must be <code>1</code></p>
</li>
<li>
<p><strong>LORAWAN_DEVICE_EUI:</strong> Change this to our <strong>LoRaWAN Device EUI</strong>.</p>
2021-12-31 17:46:40 +08:00
<p>For ChirpStack: Copy from “Applications → app → Device EUI”</p>
2021-12-31 15:33:02 +08:00
</li>
<li>
<p><strong>LORAWAN_JOIN_EUI:</strong> Change this to our <strong>LoRaWAN Join EUI</strong>.</p>
2021-12-31 16:19:00 +08:00
<p>For ChirpStack: Join EUI is not needed, we leave it as zeroes</p>
2021-12-31 15:33:02 +08:00
</li>
</ul>
2021-12-31 15:55:25 +08:00
<p><img src="https://lupyuen.github.io/images/lorawan3-secure1.png" alt="Device EUI and Join EUI" /></p>
2021-12-31 17:09:16 +08:00
<p>Next find this in the same file <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/blob/master/src/peripherals/soft-se/se-identity.h#L98-L115"><strong>se-identity.h</strong></a></p>
2021-12-31 15:33:02 +08:00
<div class="example-wrap"><pre class="language-c"><code>#define SOFT_SE_KEY_LIST \
{ \
{ \
/*! \
* Application root key \
* WARNING: FOR 1.0.x DEVICES IT IS THE \ref LORAWAN_GEN_APP_KEY \
*/ \
.KeyID = APP_KEY, \
.KeyValue = { 0xaa, 0xff, 0xad, 0x5c, 0x7e, 0x87, 0xf6, 0x4d, 0xe3, 0xf0, 0x87, 0x32, 0xfc, 0x1d, 0xd2, 0x5d }, \
}, \
{ \
/*! \
* Network root key \
* WARNING: FOR 1.0.x DEVICES IT IS THE \ref LORAWAN_APP_KEY \
*/ \
.KeyID = NWK_KEY, \
.KeyValue = { 0xaa, 0xff, 0xad, 0x5c, 0x7e, 0x87, 0xf6, 0x4d, 0xe3, 0xf0, 0x87, 0x32, 0xfc, 0x1d, 0xd2, 0x5d }, \
}, \</code></pre></div>
<ul>
<li>
<p><strong>APP_KEY:</strong> Change this to our <strong>LoRaWAN App Key</strong></p>
2021-12-31 17:46:40 +08:00
<p>For ChirpStack: Copy from “Applications → app → Devices → device_otaa_class_a → Keys (OTAA) → Application Key”</p>
2021-12-31 15:33:02 +08:00
</li>
<li>
<p><strong>NWK_KEY:</strong> Change this to our <strong>LoRaWAN App Key</strong></p>
<p>(Same as <strong>APP_KEY</strong>)</p>
</li>
</ul>
2021-12-31 15:55:25 +08:00
<p><img src="https://lupyuen.github.io/images/lorawan3-secure2a.png" alt="App Key" /></p>
2021-12-31 17:52:11 +08:00
<h2 id="secure-element" class="section-header"><a href="#secure-element">4.1 Secure Element</a></h2>
2021-12-31 15:55:25 +08:00
<p><em>Whats “soft-se”? Why are our LoRaWAN Settings there?</em></p>
2021-12-31 18:21:35 +08:00
<p>For LoRaWAN Devices that are designed to be <strong>super secure</strong>, they <strong>dont expose the LoRaWAN App Key</strong> in the firmware code…</p>
2021-12-31 16:19:00 +08:00
<p>Instead they store the App Key in the <a href="https://encyclopedia.kaspersky.com/glossary/secure-element/"><strong>Secure Element</strong></a> hardware.</p>
2021-12-31 17:46:40 +08:00
<p>Our LoRaWAN Library supports two kinds of Secure Elements: <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/tree/master/src/peripherals/atecc608a-tnglora-se"><strong>Microchip ATECC608A</strong></a> and <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/tree/master/src/peripherals/lr1110-se"><strong>Semtech LR1110</strong></a></p>
2021-12-31 16:19:00 +08:00
<p><em>But our NuttX Device doesnt have a Secure Element right?</em></p>
<p>Thats why we define the App Key in the <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/tree/master/src/peripherals/soft-se"><strong>“Software Secure Element (soft-se)”</strong></a> that simulates a Hardware Secure Element… Minus the actual hardware security.</p>
2021-12-31 18:21:35 +08:00
<p>Our App Key will be exposed if somebody dumps the firmware for our NuttX Device. But its probably OK during development.</p>
2021-12-31 16:24:13 +08:00
<h1 id="lorawan-frequency" class="section-header"><a href="#lorawan-frequency">5 LoRaWAN Frequency</a></h1>
2021-12-31 17:46:40 +08:00
<p>Lets set the LoRaWAN Frequency…</p>
2021-12-31 17:09:16 +08:00
<ol>
<li>
<p>Find the <strong>LoRaWAN Frequency</strong> for our region…</p>
<p><a href="https://www.thethingsnetwork.org/docs/lorawan/frequencies-by-country.html"><strong>“Frequency Plans by Country”</strong></a></p>
</li>
<li>
<p>Edit our <strong>LoRaWAN Test App</strong></p>
<div class="example-wrap"><pre class="language-text"><code>apps/examples/lorawan_test/lorawan_test_main.c</code></pre></div></li>
<li>
<p>Find this in <a href="https://github.com/lupyuen/lorawan_test/blob/main/lorawan_test_main.c#L34-L40"><strong>lorawan_test_main.c</strong></a></p>
<div class="example-wrap"><pre class="language-c"><code>#ifndef ACTIVE_REGION
#warning &quot;No active region defined, LORAMAC_REGION_AS923 will be used as default.&quot;
#define ACTIVE_REGION LORAMAC_REGION_AS923
#endif</code></pre></div></li>
<li>
<p>Change <strong>AS923</strong> (both occurrences) to our LoRaWAN Frequency…</p>
<p><strong>US915</strong>, <strong>CN779</strong>, <strong>EU433</strong>, <strong>AU915</strong>, <strong>AS923</strong>, <strong>CN470</strong>, <strong>KR920</strong>, <strong>IN865</strong> or <strong>RU864</strong></p>
</li>
<li>
2021-12-31 17:52:11 +08:00
<p>Do the same for the LoRaMAC Handler: <a href="https://github.com/lupyuen/LoRaMac-node-nuttx/blob/master/src/apps/LoRaMac/common/LmHandler/LmHandler.c#L41-L47"><strong>LmHandler.c</strong></a></p>
2021-12-31 17:09:16 +08:00
<div class="example-wrap"><pre class="language-text"><code>nuttx/libs/liblorawan/src/apps/LoRaMac/common/LmHandler/LmHandler.c</code></pre></div>
<p>(We ought to define this parameter in Kconfig instead)</p>
</li>
</ol>
2021-12-31 19:09:25 +08:00
<h1 id="build-the-firmware" class="section-header"><a href="#build-the-firmware">6 Build The Firmware</a></h1>
<p>Lets build the NuttX Firmware that contains our <strong>LoRaWAN Library</strong></p>
<ol>
<li>
<p>Install the build prerequisites…</p>
<p><a href="https://lupyuen.github.io/articles/nuttx#install-prerequisites"><strong>“Install Prerequisites”</strong></a></p>
</li>
<li>
2022-01-01 10:27:28 +08:00
<p>Assume that we have downloaded the <strong>NuttX Source Code</strong> and configured the <strong>LoRaWAN Settings</strong></p>
2021-12-31 19:09:25 +08:00
<p><a href="https://lupyuen.github.io/articles/lorawan3#download-source-code"><strong>“Download Source Code”</strong></a></p>
2022-01-01 10:27:28 +08:00
<p><a href="https://lupyuen.github.io/articles/lorawan3#device-eui-join-eui-and-app-key"><strong>“Device EUI, Join EUI and App Key”</strong></a></p>
<p><a href="https://lupyuen.github.io/articles/lorawan3#lorawan-frequency"><strong>“LoRaWAN Frequency”</strong></a></p>
</li>
<li>
2022-01-01 12:14:14 +08:00
<p>Edit the <strong>Pin Definitions</strong></p>
<div class="example-wrap"><pre class="language-text"><code># For BL602 and BL604:
nuttx/boards/risc-v/bl602/bl602evb/include/board.h
# For ESP32: Change &quot;esp32-devkitc&quot; to our ESP32 board
nuttx/boards/xtensa/esp32/esp32-devkitc/src/esp32_gpio.c</code></pre></div>
<p>Check that the <strong>Semtech SX1262 Pins</strong> are configured correctly in <a href="https://github.com/lupyuen/incubator-nuttx/blob/lorawan/boards/risc-v/bl602/bl602evb/include/board.h#L36-L95"><strong>board.h</strong></a> or <a href="https://github.com/lupyuen/incubator-nuttx/blob/lorawan/boards/xtensa/esp32/esp32-devkitc/src/esp32_gpio.c#L43-L67"><strong>esp32_gpio.c</strong></a></p>
<p><a href="https://lupyuen.github.io/articles/sx1262#connect-sx1262-transceiver"><strong>“Connect SX1262 Transceiver”</strong></a></p>
2021-12-31 19:09:25 +08:00
</li>
<li>
<p>Configure the build…</p>
<div class="example-wrap"><pre class="language-bash"><code>cd nuttx
# For BL602: Configure the build for BL602
./tools/configure.sh bl602evb:nsh
# For ESP32: Configure the build for ESP32.
# TODO: Change &quot;esp32-devkitc&quot; to our ESP32 board.
./tools/configure.sh esp32-devkitc:nsh
# Edit the Build Config
make menuconfig </code></pre></div></li>
<li>
<p>Enable the <strong>GPIO Driver</strong> in menuconfig…</p>
<p><a href="https://lupyuen.github.io/articles/nuttx#enable-gpio-driver"><strong>“Enable GPIO Driver”</strong></a></p>
</li>
<li>
<p>Enable the <strong>SPI Peripheral</strong>, <strong>SPI Character Driver</strong> and <strong>SPI Test Driver</strong> “/dev/spitest0”…</p>
<p><a href="https://lupyuen.github.io/articles/spi2#enable-spi"><strong>“Enable SPI”</strong></a></p>
</li>
<li>
2022-01-01 09:47:11 +08:00
<p>Enable <strong>GPIO and SPI Logging</strong> for easier troubleshooting, but uncheck <strong>“Enable Info Debug Output”</strong>, <strong>“GPIO Info Output”</strong> and <strong>“SPI Info Output”</strong></p>
2021-12-31 19:09:25 +08:00
<p><a href="https://lupyuen.github.io/articles/spi2#enable-logging"><strong>“Enable Logging”</strong></a></p>
</li>
<li>
2022-01-01 09:47:11 +08:00
<p>Enable <strong>Stack Backtrace</strong> for easier troubleshooting…</p>
<p>Check the box for <strong>“RTOS Features”</strong><strong>“Stack Backtrace”</strong></p>
<p><a href="https://lupyuen.github.io/images/lorawan3-config4.png">(See this)</a></p>
</li>
<li>
2022-01-01 10:23:28 +08:00
<p>Enable <strong>POSIX Timers and Message Queues</strong> (for NimBLE Porting Layer)…</p>
<p><a href="https://lupyuen.github.io/articles/lorawan3#appendix-posix-timers-and-message-queues"><strong>“POSIX Timers and Message Queues”</strong></a></p>
2021-12-31 19:55:05 +08:00
</li>
<li>
2022-01-01 10:23:28 +08:00
<p>Enable <strong>Random Number Generator with Entropy Pool</strong> (for LoRaWAN Nonces)…</p>
<p><a href="https://lupyuen.github.io/articles/lorawan3#appendix-random-number-generator-with-entropy-pool"><strong>“Random Number Generator with Entropy Pool”</strong></a></p>
<p>(Well talk about this in a while)</p>
2021-12-31 19:09:25 +08:00
</li>
<li>
<p>Click <strong>“Library Routines”</strong> and enable the following libraries…</p>
<p><strong>“LoRaWAN Library”</strong></p>
<p><strong>“NimBLE Porting Layer”</strong></p>
<p><strong>“Semtech SX1262 Library”</strong></p>
</li>
<li>
<p>Enable our <strong>LoRaWAN Test App</strong></p>
<p>Check the box for <strong>“Application Configuration”</strong><strong>“Examples”</strong><strong>“LoRaWAN Test App”</strong></p>
</li>
<li>
<p>Save the configuration and exit menuconfig</p>
<p><a href="https://gist.github.com/lupyuen/d0487cda965f72ed99631d168ea4f5c8">(Heres the .config for BL604)</a></p>
</li>
<li>
<p><strong>For ESP32:</strong> Edit <a href="https://github.com/lupyuen/incubator-nuttx/blob/spi_test/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c#L118-L426"><strong>esp32_bringup.c</strong></a> to register our SPI Test Driver <a href="https://lupyuen.github.io/articles/spi2#register-device-driver">(See this)</a></p>
</li>
<li>
<p>Build, flash and run the NuttX Firmware on BL602 or ESP32…</p>
<p><a href="https://lupyuen.github.io/articles/lorawan3#appendix-build-flash-and-run-nuttx"><strong>“Build, Flash and Run NuttX”</strong></a></p>
</li>
</ol>
<h1 id="run-the-firmware" class="section-header"><a href="#run-the-firmware">7 Run The Firmware</a></h1>
2021-12-31 16:24:13 +08:00
<p>TODO</p>
2021-12-31 19:09:25 +08:00
<p>Finally we run the NuttX Firmware and test our <strong>LoRaWAN Library</strong></p>
<ol>
<li>
<p>In the NuttX Shell, enter…</p>
<div class="example-wrap"><pre class="language-bash"><code>ls /dev</code></pre></div>
<p>Our SPI Test Driver should appear as <strong>“/dev/spitest0”</strong></p>
</li>
<li>
<p>In the NuttX Shell, enter…</p>
2021-12-31 19:55:05 +08:00
<div class="example-wrap"><pre class="language-bash"><code>lorawan_test</code></pre></div></li>
<li>
<p>We should see…</p>
<div class="example-wrap"><pre class="language-text"><code>TODO</code></pre></div>
<p><a href="">(TODO: See the Output Log)</a></p>
2021-12-31 19:09:25 +08:00
</li>
</ol>
2021-12-31 19:55:05 +08:00
<h1 id="join-lorawan-network" class="section-header"><a href="#join-lorawan-network">8 Join LoRaWAN Network</a></h1>
2021-12-31 18:21:35 +08:00
<p>TODO</p>
<p>Lets connect Apache #NuttX OS to a #LoRaWAN Gateway … RAKwireless WisGate D4H with ChirpStack</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-title.jpg" alt="PineDio Stack BL604 RISC-V Board (left) talking LoRaWAN to RAKwireless WisGate LoRaWAN Gateway (right)" /></p>
<p><a href="https://lupyuen.github.io/articles/wisgate">(Article)</a></p>
<p>#LoRaWAN Gateway receives the Join Request from #NuttX OS … And accepts the Join Request! 🎉</p>
<p>TODO43</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-chirpstack.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/a8e834e7b4267345f01b6629fb7f5e33">(Run Log)</a></p>
<p>#NuttX OS doesnt handle the Join Response from #LoRaWAN Gateway … Lets fix this</p>
<p>TODO56</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-run3.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/a8e834e7b4267345f01b6629fb7f5e33">(Run Log)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="send-data-to-lorawan" class="section-header"><a href="#send-data-to-lorawan">9 Send Data To LoRaWAN</a></h1>
2021-12-31 18:21:35 +08:00
<p>TODO</p>
<p>Heres how we send a #LoRaWAN Data Packet on #NuttX OS … And validate the Packet Size before sending</p>
<p>TODO68</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx6.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lorawan_test/blob/main/lorawan_test_main.c#L311-L339">(Source)</a></p>
<p>#LoRaWAN tested OK on Apache #NuttX OS … From #PineDio Stack BL604 @ThePine64 to RAKwireless WisGate … And back! 🎉</p>
<ul>
<li><a href="https://github.com/lupyuen/LoRaMac-node-nuttx"><strong>LoRaMac-node-nuttx</strong></a></li>
</ul>
2021-12-31 19:55:05 +08:00
<h1 id="lorawan-event-loop" class="section-header"><a href="#lorawan-event-loop">10 LoRaWAN Event Loop</a></h1>
2021-12-31 18:21:35 +08:00
<p>TODO</p>
<p>Heres our #LoRaWAN Event Loop for #NuttX OS … Implemented with NimBLE Porting Library … No more polling!</p>
<p>TODO54</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-npl1.png" alt="" /></p>
<p>TODO58</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-run5a.png" alt="" /></p>
2021-12-31 19:09:25 +08:00
<h1 id="lorawan-nonce" class="section-header"><a href="#lorawan-nonce">11 LoRaWAN Nonce</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-31 16:19:00 +08:00
<p>Our #NuttX App resends the same Nonce to the #LoRaWAN Gateway … Which (silently) rejects the Join Request due to Duplicate Nonce … Lets fix our Random Number Generator</p>
<p>TODO34</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-chirpstack2a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/b38434c3d27500444382bb4a066691e5">(Log)</a></p>
<p>#LoRaWAN gets the Nonce from the Secure Elements Random Number Generator … Lets simulate the Secure Element on Apache #NuttX OS</p>
<p>TODO51</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-nonce2a.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/LoRaMac-node-nuttx/blob/master/src/mac/LoRaMacCrypto.c#L980-L996">(Source)</a></p>
<p>Heres how we generate #LoRaWAN Nonces on #NuttX OS … With Strong Random Numbers thanks to Entropy Pool</p>
<p>TODO53</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-nonce6.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/LoRaMac-node-nuttx/blob/master/src/nuttx.c#L136-L153">(Source)</a></p>
<p>Our #NuttX App now sends Random #LoRaWAN Nonces to the LoRaWAN Gateway … And are happily accepted by the gateway! 🎉</p>
<p>TODO36</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-nonce7a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/8f012856b9eb6b9a762160afd83df7f8">(Log)</a></p>
2021-12-31 09:48:18 +08:00
<p><img src="https://lupyuen.github.io/images/spi2-pinedio1.jpg" alt="Inside PineDio Stack BL604" /></p>
2021-12-31 19:55:05 +08:00
<h1 id="nimble-porting-layer" class="section-header"><a href="#nimble-porting-layer">12 NimBLE Porting Layer</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>Our #NuttX App was waiting for the #LoRaWAN Join Request to be transmitted before receiving the Join Response … But because were polling SX1262, we missed the Join Response … Lets fix this with the multithreading functions from NimBLE Porting Layer</p>
<ul>
<li><a href="https://github.com/lupyuen/nimble-porting-nuttx"><strong>nimble-porting-nuttx</strong></a></li>
</ul>
<p>TODO57</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-run4a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/d3d9db37a40d7560fc211408db04a81b">(Log)</a></p>
<p>NimBLE Porting Layer is a portable library of Multithreading Functions … Weve used it for #LoRa on Linux and FreeRTOS … Now we call it from Apache #NuttX OS</p>
2021-12-31 19:55:05 +08:00
<h1 id="gpio-interrupts" class="section-header"><a href="#gpio-interrupts">13 GPIO Interrupts</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>SX1262 will trigger a GPIO Interrupt on #NuttX OS when it receives a #LoRa Packet … We wait for the GPIO Interrupt to be Signalled in a Background Thread</p>
<p>TODO46</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-gpio2.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lora-sx1262/blob/lorawan/src/sx126x-nuttx.c#L742-L778">(Source)</a></p>
<p>We handle GPIO Interrupts (SX1262 DIO1) in a #NuttX Background Thread … Awaiting the Signal for GPIO Interrupt</p>
<p>TODO47</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-gpio3.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lora-sx1262/blob/lorawan/src/sx126x-nuttx.c#L835-L861">(Source)</a></p>
<p>Our #NuttX Background Thread handles the GPIO Interrupts (SX1262 DIO1) … By adding to the #LoRaWAN Event Queue</p>
<p>TODO48</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-gpio4a.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lora-sx1262/blob/lorawan/src/sx126x-nuttx.c#L863-L892">(Source)</a></p>
<p>#LoRaWAN runs neater on Apache #NuttX OS … After implementing Timers and Multithreading with NimBLE Porting Layer … No more sleep()!</p>
<p><a href="https://gist.github.com/lupyuen/cad58115be4cabe8a8a49c0e498f1c95">(Log)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="sx1262-busy" class="section-header"><a href="#sx1262-busy">14 SX1262 Busy</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>Heres how we check the SX1262 Busy Pin on #NuttX OS … By reading the GPIO Input</p>
<p>TODO49</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-gpio1.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lora-sx1262/blob/lorawan/src/sx126x-nuttx.c#L184-L199">(Source)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="troubleshoot-lorawan" class="section-header"><a href="#troubleshoot-lorawan">15 Troubleshoot LoRaWAN</a></h1>
<p>TODO</p>
<p>Check the LoRa Frequency, Sync Word, Device EUI and Join EUI</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-run2a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/b91c1f88645eedb813cfffa2bdf7d7a0">(Run Log)</a></p>
<h2 id="logging" class="section-header"><a href="#logging">15.1 Logging</a></h2>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>Our #NuttX App was too busy to receive the #LoRaWAN Join Response … Lets disable the logging</p>
<p>TODO62</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/8f012856b9eb6b9a762160afd83df7f8">(Log)</a></p>
<p>After disabling logging, our #NuttX App successfully joins the #LoRaWAN Network! 🎉 Now we transmit some Data Packets over LoRaWAN</p>
<p>TODO63</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx3.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/0d301216bbf937147778bb57ab0ccf89">(Log)</a></p>
<p>Our #LoRaWAN Gateway receives Data Packets from #NuttX OS! 🎉 The Message Payload is empty … Lets figure out why 🤔</p>
<p>TODO44</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-chirpstack5.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/0d301216bbf937147778bb57ab0ccf89">(Log)</a></p>
2021-12-31 19:55:05 +08:00
<h2 id="message-size" class="section-header"><a href="#message-size">15.2 Message Size</a></h2>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>Our #NuttX App sent an empty #LoRaWAN Message because our message is too long for LoRaWAN Data Rate 2 (max 11 bytes) … Lets increase the Data Rate to 3</p>
<p>TODO65</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx4a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/5fc07695a6c4bb48b5e4d10eb05ca9bf">(Log)</a></p>
<p>Heres how we increase the #LoRaWAN Data Rate to 3 in our #NuttX App</p>
<p>TODO67</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx5a.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/lorawan_test/blob/main/lorawan_test_main.c#L57-L70">(Source)</a></p>
<p>#LoRaWAN Data Rate has been increased to 3 … Max Message Size is now 53 bytes for our #NuttX App</p>
<p>TODO37</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-tx7a.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/83be5da091273bb39bad6e77cc91b68d">(Log)</a></p>
<p>#LoRaWAN Gateway now receives the correct Data Packet from our #NuttX App! 🎉</p>
<p>TODO45</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-chirpstack6.png" alt="" /></p>
<p><a href="https://gist.github.com/lupyuen/83be5da091273bb39bad6e77cc91b68d">(Log)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="spi-with-dma" class="section-header"><a href="#spi-with-dma">16 SPI with DMA</a></h1>
2021-12-31 15:55:25 +08:00
<p>TODO</p>
2021-12-31 19:55:05 +08:00
<h1 id="whats-next" class="section-header"><a href="#whats-next">17 Whats Next</a></h1>
2021-12-31 01:49:00 +08:00
<p>TODO</p>
<p>CBOR, TTN, Temperature Sensor</p>
2021-12-30 10:58:30 +08:00
<p>In our next article well move on to <strong>LoRaWAN!</strong></p>
<p>(Which will be super interesting because of multithreading)</p>
<p>Well port Semtechs <strong>Reference LoRaWAN Stack</strong> to NuttX…</p>
<ul>
<li><a href="https://github.com/lupyuen/LoRaMac-node-nuttx"><strong>lupyuen/LoRaMac-node-nuttx</strong></a></li>
</ul>
<p><em>Were porting plenty of code to NuttX: LoRa, LoRaWAN and NimBLE Porting Layer. Do we expect any problems?</em></p>
<p>Yep we might have issues keeping our LoRaWAN Stack in sync with Semtechs version. <a href="https://lupyuen.github.io/articles/sx1262#notes">(But we shall minimise the changes)</a></p>
<p>Stay Tuned!</p>
<p>Many Thanks to my <a href="https://github.com/sponsors/lupyuen"><strong>GitHub Sponsors</strong></a> for supporting my work! This article wouldnt have been possible without your support.</p>
<ul>
<li>
<p><a href="https://github.com/sponsors/lupyuen">Sponsor me a coffee</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/articles/book">Read “The RISC-V BL602 / BL604 Book”</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io">Check out my articles</a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/rss.xml">RSS Feed</a></p>
</li>
</ul>
<p><em>Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…</em></p>
<p><a href="https://github.com/lupyuen/lupyuen.github.io/blob/master/src/lorawan3.md"><code>lupyuen.github.io/src/lorawan3.md</code></a></p>
2021-12-31 19:55:05 +08:00
<h1 id="notes" class="section-header"><a href="#notes">18 Notes</a></h1>
2021-12-30 10:58:30 +08:00
<ol>
<li>
<p>This article is the expanded version of <a href="https://twitter.com/MisterTechBlog/status/1473593455699841027">this Twitter Thread</a></p>
</li>
<li>
<p>Were <strong>porting plenty of code</strong> to NuttX: LoRa, LoRaWAN and NimBLE Porting Layer. Do we expect any problems?</p>
<ul>
<li>
<p>If we implement LoRa and LoRaWAN as <strong>NuttX Drivers</strong>, well have to scrub the code to comply with the <a href="https://nuttx.apache.org/docs/latest/contributing/coding_style.html"><strong>NuttX Coding Conventions</strong></a>.</p>
<p>This makes it <strong>harder to update</strong> the LoRaWAN Driver when there are changes in the LoRaWAN Spec. (Like for a new LoRaWAN Region)</p>
<p><a href="https://lupyuen.github.io/articles/lorawan#appendix-lora-carrier-sensing">(Heres an example)</a></p>
</li>
<li>
<p>Alternatively we may implement LoRa and LoRaWAN as <strong>External Libraries</strong>, similar to <a href="https://github.com/lupyuen/incubator-nuttx-apps/tree/master/wireless/bluetooth/nimble"><strong>NimBLE for NuttX</strong></a>.</p>
<p>(The <a href="https://github.com/lupyuen/incubator-nuttx-apps/blob/master/wireless/bluetooth/nimble/Makefile#L33"><strong>Makefile</strong></a> downloads the External Library during build)</p>
<p>But then we wont get a proper NuttX Driver that exposes the ioctl() interface to NuttX Apps.</p>
</li>
</ul>
<p>Conundrum. Lemme know your thoughts!</p>
</li>
<li>
<p>How do other Embedded Operating Systems implement LoRaWAN?</p>
<ul>
<li>
<p><strong>Mynewt</strong> embeds a <a href="https://github.com/apache/mynewt-core/tree/master/net/lora/node"><strong>Partial Copy</strong></a> of Semtechs LoRaWAN Stack into its source tree.</p>
</li>
<li>
<p><strong>Zephyr</strong> maintains a <a href="https://github.com/zephyrproject-rtos/loramac-node"><strong>Complete Fork</strong></a> of the entire LoRaWAN Repo by Semtech. Which gets embedded during the Zephyr build.</p>
</li>
</ul>
<p>The Zephyr approach is probably the best way to <strong>keep our LoRaWAN Stack in sync</strong> with Semtechs.</p>
</li>
<li>
<p>We have already ported LoRaWAN to <strong>BL602 IoT SDK</strong> <a href="https://lupyuen.github.io/articles/lorawan">(see this)</a>, why are we porting again to NuttX?</p>
<p>Regrettably BL602 IoT SDK has been revamped (without warning) to the <strong>new “hosal” HAL</strong> <a href="https://twitter.com/MisterTechBlog/status/1456259223323508748">(see this)</a>, and the LoRaWAN Stack will <strong>no longer work</strong> on the revamped BL602 IoT SDK.</p>
<p>For easier maintenance, we shall <strong>code our BL602 and BL604 projects with Apache NuttX OS</strong> instead.</p>
<p>(Which wont get revamped overnight!)</p>
</li>
<li>
<p>Will NuttX become the official OS for PineDio Stack BL604 when it goes on sale?</p>
<p>It might! But first lets get LoRaWAN (and ST7789) running on PineDio Stack.</p>
</li>
</ol>
2021-12-31 19:55:05 +08:00
<h1 id="appendix-posix-timers-and-message-queues" class="section-header"><a href="#appendix-posix-timers-and-message-queues">19 Appendix: POSIX Timers and Message Queues</a></h1>
2022-01-01 09:47:11 +08:00
<p>NimBLE Porting Layer needs <strong>POSIX Timers and Message Queues</strong> (plus more) to work. Follow the steps below to enable the features in <strong>menuconfig</strong></p>
<ol>
<li>
<p>Select <strong>“RTOS Features”</strong><strong>“Disable NuttX Interfaces”</strong></p>
<p>Uncheck <strong>“Disable POSIX Timers”</strong></p>
<p>Uncheck <strong>“Disable POSIX Message Queue Support”</strong></p>
</li>
<li>
<p>Select <strong>“RTOS Features”</strong><strong>“Clocks and Timers”</strong></p>
<p>Check <strong>“Support CLOCK_MONOTONIC”</strong></p>
</li>
<li>
<p>Select <strong>“RTOS Features”</strong><strong>“Work Queue Support”</strong></p>
<p>Check <strong>“High Priority (Kernel) Worker Thread”</strong></p>
</li>
<li>
<p>Select <strong>“RTOS Features”</strong><strong>“Signal Configuration”</strong></p>
<p>Check <strong>“Support SIGEV_THHREAD”</strong></p>
</li>
<li>
<p>Hit <strong>“Exit”</strong> until the Top Menu appears. (“NuttX/x64_64 Configuration”)</p>
</li>
</ol>
<p><img src="https://lupyuen.github.io/images/lorawan3-config1.png" alt="Enable POSIX Timers and Message Queues in menuconfig" /></p>
2021-12-31 19:55:05 +08:00
<h1 id="appendix-random-number-generator-with-entropy-pool" class="section-header"><a href="#appendix-random-number-generator-with-entropy-pool">20 Appendix: Random Number Generator with Entropy Pool</a></h1>
2022-01-01 09:47:11 +08:00
<p>Our LoRaWAN Library generates Nonces by calling a <strong>Random Number Generator with Entropy Pool</strong>. </p>
<p>Follow these steps to enable the <strong>Entropy Pool</strong> in <strong>menuconfig</strong></p>
<ol>
<li>
<p>Select <strong>“Crypto API”</strong></p>
</li>
<li>
<p>Check <strong>“Crypto API Support”</strong></p>
</li>
<li>
<p>Check <strong>“Entropy Pool and Strong Random Number Generator”</strong></p>
</li>
<li>
<p>Hit <strong>“Exit”</strong> until the Top Menu appears. (“NuttX/x64_64 Configuration”)</p>
</li>
</ol>
<p><img src="https://lupyuen.github.io/images/lorawan3-nonce3a.png" alt="Enable Entropy Pool in menuconfig" /></p>
<p>Then we enable the <strong>Random Number Generator</strong></p>
<ol>
<li>
<p>Select <strong>“Device Drivers”</strong></p>
</li>
<li>
<p>Check <strong>“Enable /dev/urandom”</strong></p>
</li>
<li>
<p>Select <strong>“/dev/urandom algorithm”</strong></p>
</li>
<li>
<p>Check <strong>“Entropy Pool”</strong></p>
</li>
<li>
<p>Hit <strong>“Exit”</strong> until the Top Menu appears. (“NuttX/x64_64 Configuration”)</p>
</li>
</ol>
<p><img src="https://lupyuen.github.io/images/lorawan3-nonce4a.png" alt="Select Entropy Pool in menuconfig" /></p>
2021-12-31 19:55:05 +08:00
<h1 id="appendix-build-flash-and-run-nuttx" class="section-header"><a href="#appendix-build-flash-and-run-nuttx">21 Appendix: Build, Flash and Run NuttX</a></h1>
2021-12-31 19:09:25 +08:00
<p><em>(For BL602 and ESP32)</em></p>
<p>Below are the steps to build, flash and run NuttX on BL602 and ESP32.</p>
<p>The instructions below will work on <strong>Linux (Ubuntu)</strong>, <strong>WSL (Ubuntu)</strong> and <strong>macOS</strong>.</p>
<p><a href="https://nuttx.apache.org/docs/latest/quickstart/install.html">(Instructions for other platforms)</a></p>
<p><a href="https://popolon.org/gblog3/?p=1977&amp;lang=en">(See this for Arch Linux)</a></p>
2021-12-31 19:55:05 +08:00
<h2 id="build-nuttx" class="section-header"><a href="#build-nuttx">21.1 Build NuttX</a></h2>
2021-12-31 19:09:25 +08:00
<p>Follow these steps to build NuttX for BL602 or ESP32…</p>
<ol>
<li>
<p>Install the build prerequisites…</p>
<p><a href="https://lupyuen.github.io/articles/nuttx#install-prerequisites"><strong>“Install Prerequisites”</strong></a></p>
</li>
<li>
2022-01-01 10:27:28 +08:00
<p>Assume that we have downloaded the <strong>NuttX Source Code</strong> and configured the <strong>LoRaWAN Settings</strong></p>
2021-12-31 19:09:25 +08:00
<p><a href="https://lupyuen.github.io/articles/lorawan3#download-source-code"><strong>“Download Source Code”</strong></a></p>
2022-01-01 10:27:28 +08:00
<p><a href="https://lupyuen.github.io/articles/lorawan3#device-eui-join-eui-and-app-key"><strong>“Device EUI, Join EUI and App Key”</strong></a></p>
<p><a href="https://lupyuen.github.io/articles/lorawan3#lorawan-frequency"><strong>“LoRaWAN Frequency”</strong></a></p>
2021-12-31 19:09:25 +08:00
<p><a href="https://lupyuen.github.io/articles/lorawan3#build-the-firmware"><strong>“Build the Firmware”</strong></a></p>
</li>
<li>
<p>To build NuttX, enter this command…</p>
<div class="example-wrap"><pre class="language-bash"><code>make</code></pre></div></li>
<li>
<p>We should see…</p>
<div class="example-wrap"><pre class="language-text"><code>LD: nuttx
CP: nuttx.hex
CP: nuttx.bin</code></pre></div>
<p><a href="https://gist.github.com/lupyuen/8f725c278c25e209c1654469a2855746">(See the complete log for BL602)</a></p>
</li>
<li>
<p><strong>For BL602:</strong> Copy the <strong>NuttX Firmware</strong> to the <strong>blflash</strong> directory…</p>
<div class="example-wrap"><pre class="language-bash"><code># For Linux and macOS:
# TODO: Change $HOME/blflash to the full path of blflash
cp nuttx.bin $HOME/blflash
# For WSL:
# TODO: Change /mnt/c/blflash to the full path of blflash in Windows
# /mnt/c/blflash refers to c:\blflash
cp nuttx.bin /mnt/c/blflash</code></pre></div>
<p>(Well cover <strong>blflash</strong> in the next section)</p>
<p>For WSL we need to run <strong>blflash</strong> under plain old Windows CMD (not WSL) because it needs to access the COM port.</p>
</li>
<li>
<p>In case of problems, refer to the <strong>NuttX Docs</strong></p>
<p><a href="https://nuttx.apache.org/docs/latest/platforms/risc-v/bl602/index.html"><strong>“BL602 NuttX”</strong></a></p>
<p><a href="https://nuttx.apache.org/docs/latest/platforms/xtensa/esp32/index.html"><strong>“ESP32 NuttX”</strong></a></p>
<p><a href="https://nuttx.apache.org/docs/latest/quickstart/install.html"><strong>“Installing NuttX”</strong></a></p>
</li>
</ol>
<blockquote>
<p><img src="https://lupyuen.github.io/images/nuttx-build2.png" alt="Building NuttX" /></p>
</blockquote>
2021-12-31 19:55:05 +08:00
<h2 id="flash-nuttx" class="section-header"><a href="#flash-nuttx">21.2 Flash NuttX</a></h2>
2021-12-31 19:09:25 +08:00
<p><strong>For ESP32:</strong> <a href="https://nuttx.apache.org/docs/latest/platforms/xtensa/esp32/index.html#flashing"><strong>See instructions here</strong></a> <a href="https://popolon.org/gblog3/?p=1977&amp;lang=en">(Also check out this article)</a></p>
<p><strong>For BL602:</strong> Follow these steps to install <strong>blflash</strong></p>
<ol>
<li>
<p><a href="https://lupyuen.github.io/articles/flash#install-rustup"><strong>“Install rustup”</strong></a></p>
</li>
<li>
<p><a href="https://lupyuen.github.io/articles/flash#download-and-build-blflash"><strong>“Download and build blflash”</strong></a></p>
</li>
</ol>
<p>We assume that our Firmware Binary File <strong>nuttx.bin</strong> has been copied to the <strong>blflash</strong> folder.</p>
<p>Set BL602 / BL604 to <strong>Flashing Mode</strong> and restart the board…</p>
<p><strong>For PineDio Stack BL604:</strong></p>
<ol>
<li>
<p>Set the <strong>GPIO 8 Jumper</strong> to <strong>High</strong> <a href="https://lupyuen.github.io/images/pinedio-high.jpg">(Like this)</a></p>
</li>
<li>
<p>Press the Reset Button</p>
</li>
</ol>
<p><strong>For PineCone BL602:</strong></p>
<ol>
<li>
<p>Set the <strong>PineCone Jumper (IO 8)</strong> to the <strong><code>H</code> Position</strong> <a href="https://lupyuen.github.io/images/pinecone-jumperh.jpg">(Like this)</a></p>
</li>
<li>
<p>Press the Reset Button</p>
</li>
</ol>
<p><strong>For BL10:</strong></p>
<ol>
<li>
<p>Connect BL10 to the USB port</p>
</li>
<li>
<p>Press and hold the <strong>D8 Button (GPIO 8)</strong></p>
</li>
<li>
<p>Press and release the <strong>EN Button (Reset)</strong></p>
</li>
<li>
<p>Release the D8 Button</p>
</li>
</ol>
<p><strong>For Pinenut and MagicHome BL602:</strong></p>
<ol>
<li>
<p>Disconnect the board from the USB Port</p>
</li>
<li>
<p>Connect <strong>GPIO 8</strong> to <strong>3.3V</strong></p>
</li>
<li>
<p>Reconnect the board to the USB port</p>
</li>
</ol>
<p>Enter these commands to flash <strong>nuttx.bin</strong> to BL602 / BL604 over UART…</p>
<div class="example-wrap"><pre class="language-bash"><code># TODO: Change ~/blflash to the full path of blflash
cd ~/blflash
# For Linux:
sudo cargo run flash nuttx.bin \
--port /dev/ttyUSB0
# For macOS:
cargo run flash nuttx.bin \
--port /dev/tty.usbserial-1420 \
--initial-baud-rate 230400 \
--baud-rate 230400
# For Windows: Change COM5 to the BL602 / BL604 Serial Port
cargo run flash nuttx.bin --port COM5</code></pre></div>
<p><a href="https://gist.github.com/lupyuen/9c0dbd75bb6b8e810939a36ffb5c399f">(See the Output Log)</a></p>
<p>For WSL: Do this under plain old Windows CMD (not WSL) because <strong>blflash</strong> needs to access the COM port.</p>
<p><a href="https://github.com/apache/incubator-nuttx/issues/4336">(Flashing WiFi apps to BL602 / BL604? Remember to use <strong>bl_rfbin</strong>)</a></p>
<p><a href="https://lupyuen.github.io/articles/flash#flash-the-firmware">(More details on flashing firmware)</a></p>
<p><img src="https://lupyuen.github.io/images/nuttx-flash2.png" alt="Flashing NuttX" /></p>
2021-12-31 19:55:05 +08:00
<h2 id="run-nuttx" class="section-header"><a href="#run-nuttx">21.3 Run NuttX</a></h2>
2021-12-31 19:09:25 +08:00
<p><strong>For ESP32:</strong> Use Picocom to connect to ESP32 over UART…</p>
<div class="example-wrap"><pre class="language-bash"><code>picocom -b 115200 /dev/ttyUSB0</code></pre></div>
<p><a href="https://popolon.org/gblog3/?p=1977&amp;lang=en">(More about this)</a></p>
<p><strong>For BL602:</strong> Set BL602 / BL604 to <strong>Normal Mode</strong> (Non-Flashing) and restart the board…</p>
<p><strong>For PineDio Stack BL604:</strong></p>
<ol>
<li>
<p>Set the <strong>GPIO 8 Jumper</strong> to <strong>Low</strong> <a href="https://lupyuen.github.io/images/pinedio-low.jpg">(Like this)</a></p>
</li>
<li>
<p>Press the Reset Button</p>
</li>
</ol>
<p><strong>For PineCone BL602:</strong></p>
<ol>
<li>
<p>Set the <strong>PineCone Jumper (IO 8)</strong> to the <strong><code>L</code> Position</strong> <a href="https://lupyuen.github.io/images/pinecone-jumperl.jpg">(Like this)</a></p>
</li>
<li>
<p>Press the Reset Button</p>
</li>
</ol>
<p><strong>For BL10:</strong></p>
<ol>
<li>Press and release the <strong>EN Button (Reset)</strong></li>
</ol>
<p><strong>For Pinenut and MagicHome BL602:</strong></p>
<ol>
<li>
<p>Disconnect the board from the USB Port</p>
</li>
<li>
<p>Connect <strong>GPIO 8</strong> to <strong>GND</strong></p>
</li>
<li>
<p>Reconnect the board to the USB port</p>
</li>
</ol>
<p>After restarting, connect to BL602 / BL604s UART Port at 2 Mbps like so…</p>
<p><strong>For Linux:</strong></p>
<div class="example-wrap"><pre class="language-bash"><code>sudo screen /dev/ttyUSB0 2000000</code></pre></div>
<p><strong>For macOS:</strong> Use CoolTerm (<a href="https://lupyuen.github.io/articles/flash#watch-the-firmware-run">See this</a>)</p>
<p><strong>For Windows:</strong> Use <code>putty</code> (<a href="https://lupyuen.github.io/articles/flash#watch-the-firmware-run">See this</a>)</p>
<p><strong>Alternatively:</strong> Use the Web Serial Terminal (<a href="https://lupyuen.github.io/articles/flash#watch-the-firmware-run">See this</a>)</p>
<p>Press Enter to reveal the <strong>NuttX Shell</strong></p>
<div class="example-wrap"><pre class="language-text"><code>NuttShell (NSH) NuttX-10.2.0-RC0
nsh&gt;</code></pre></div>
<p>Congratulations NuttX is now running on BL602 / BL604!</p>
<p><a href="https://lupyuen.github.io/articles/flash#watch-the-firmware-run">(More details on connecting to BL602 / BL604)</a></p>
<p><img src="https://lupyuen.github.io/images/nuttx-boot2.png" alt="Running NuttX" /></p>
<p><strong>macOS Tip:</strong> Heres the script I use to build, flash and run NuttX on macOS, all in a single step: <a href="https://gist.github.com/lupyuen/cc21385ecc66b5c02d15affd776a64af">run.sh</a></p>
<p><img src="https://lupyuen.github.io/images/spi2-script.png" alt="Script to build, flash and run NuttX on macOS" /></p>
<p><a href="https://gist.github.com/lupyuen/cc21385ecc66b5c02d15affd776a64af">(Source)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="appendix-gpio-issue" class="section-header"><a href="#appendix-gpio-issue">22 Appendix: GPIO Issue</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 14:32:20 +08:00
<p>Switching a #NuttX GPIO Interrupt Pin to Trigger On Rising Edge … Crashes with an Assertion Failure … Ill submit a NuttX Issue, meanwhile I have disabled the assertion</p>
<p>TODO50</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-int.png" alt="" /></p>
2021-12-30 16:35:12 +08:00
<p><a href="https://github.com/lupyuen/incubator-nuttx/blob/lorawan/drivers/ioexpander/gpio.c#L544-L547">(Source)</a></p>
2021-12-31 19:55:05 +08:00
<h1 id="appendix-callout-issue" class="section-header"><a href="#appendix-callout-issue">23 Appendix: Callout Issue</a></h1>
2021-12-30 16:53:54 +08:00
<p>TODO</p>
2021-12-30 16:35:12 +08:00
<p>NimBLE Porting Layer doesnt work for multiple Callout Timers on #NuttX OS, unless we loop the thread … Will submit a Pull Request to Apache NimBLE 👍</p>
<p>TODO42</p>
<p><img src="https://lupyuen.github.io/images/lorawan3-callout.png" alt="" /></p>
<p><a href="https://github.com/lupyuen/nimble-porting-nuttx/blob/master/porting/npl/nuttx/src/os_callout.c#L35-L70">(Source)</a></p>
<p><img src="https://lupyuen.github.io/images/lorawan3-title2.jpg" alt="PineDio Stack BL604 RISC-V Board (left) talking LoRaWAN to RAKwireless WisGate LoRaWAN Gateway (right)" /></p>
2021-12-30 10:58:30 +08:00
</body>
</html>