blob: d73c24dcf761f21a65c1dd2d799b50e90ff45f31 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../img/favicon.ico">
<title>Air-quality Sensor project - Apache Mynewt</title>
<link href="../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../css/highlight.css">
<link href="../../../css/base.css" rel="stylesheet">
<link href="../../../css/custom.css" rel="stylesheet">
<link href="../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="Air-quality Sensor project">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" selected="selected" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../tutorials/">Tutorials</a>
<ul>
<li><a href="
../arduino_zero/
">Project Blinky</a>
</li>
<li ><a href="../repo/add_repos/">Work with repositories</a>
</li>
<li >
<a href="../unit_test/">Write a Test Suite for a Package</a>
</li>
<li class="active">
<a href="./">Air-quality Sensor project</a>
</li>
<li >
<a href="../event_queue/">Add task to manage multiple events</a>
</li>
<li >
<a href="../project-slinky/">Enable remote comms on sim device</a>
</li>
<li >
<a href="../project-target-slinky/">Enable remote comms on STM32 board</a>
</li>
<li >
<a href="../bletiny_project/">BLE app to check stats via console</a>
</li>
<li ><a href="../bleprph/bleprph-intro/">BLE peripheral project</a>
</li>
<li >
<a href="../ibeacon/">BLE iBeacon</a>
</li>
<li >
<a href="../blehci_project/">BLE HCI interface</a>
</li>
</ul>
</li>
<li ><a href="../../os_user_guide/">OS User Guide</a>
</li>
<li><a href="
../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../faq/how_to_edit_docs/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Air-quality Sensor project</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 0.9.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h2 id="air-quality-sensor-project">Air quality sensor project</h2>
<h3 id="setting-up-source-tree-for-stuff-you-need">Setting up source tree for stuff you need</h3>
<p>To start with, you need to create a new project under which you will do this development. So you type in:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> $ mkdir $HOME/src
$ cd $HOME/src
$ newt new air_quality
</code></pre></div>
<p>Let's say you are using STM32F3discovery board as the platform. You know you need the board support package for that hardware. You can look up its location, add it your project, and fetch that along with the core OS components.</p>
<p>To make this happen, you'll need to modify the project.yml in your project's root directory.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> [user@IsMyLaptop:~/src/air_quality]$ emacs project.yml &amp;
[user@IsMyLaptop:~/src/air_quality]$ cat project.yml
project.name: &quot;air_quality&quot;
project.repositories:
- apache-mynewt-core
- mynewt_stm32f3
# Use github&#39;s distribution mechanism for core ASF libraries.
# This provides mirroring automatically for us.
#
repository.apache-mynewt-core:
type: github
vers: 0-latest
user: apache
repo: incubator-mynewt-core
repository.mynewt_stm32f3:
type: github
vers: 0-latest
user: runtimeinc
repo: mynewt_stm32f3
[user@IsMyLaptop:~/src/air_quality]$ newt install
apache-mynewt-core
mynewt_stm32f3
[user@IsMyLaptop:~/src/air_quality]$ ls repos/
apache-mynewt-core mynewt_stm32f3
</code></pre></div>
<p>Good. You want to make sure you have all the needed bits for supporting your board; so you decide to build the blinky project for the platform first.</p>
<p>Now create a target for it and build it. Easiest way to proceed is to copy the existing target for blinky, and modify it to build for STM32F3Discovery board.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt target copy my_blinky_sim blink_f3
Target successfully copied; targets/my_blinky_sim --&gt; targets/blink_f3
[user@IsMyLaptop:~/src/air_quality]$ newt target set blink_f3 bsp=@mynewt_stm32f3/hw/bsp/stm32f3discovery
Target targets/blink_f3 successfully set target.bsp to @mynewt_stm32f3/hw/bsp/stm32f3discovery
[user@IsMyLaptop:~/src/air_quality]$ newt build blink_f3
Compiling hal_bsp.c
...
Linking blinky.elf
App successfully built: /Users/user/src/air_quality/bin/blink_f3/apps/blinky/blinky.elf
</code></pre></div>
<p>Good.</p>
<p>You know that this platform uses bootloader, which means you have to create a target for that too.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt target create boot_f3
Target targets/boot_f3 successfully created
[user@IsMyLaptop:~/src/air_quality]$ newt target show
@apache-mynewt-core/targets/unittest
bsp=hw/bsp/native
build_profile=debug
compiler=compiler/sim
targets/blink_f3
app=apps/blinky
bsp=@mynewt_stm32f3/hw/bsp/stm32f3discovery
build_profile=debug
targets/boot_f3
targets/my_blinky_sim
app=apps/blinky
bsp=@apache-mynewt-core/hw/bsp/native
build_profile=debug
[user@IsMyLaptop:~/src/air_quality]$ newt target set boot_f3 bsp=@mynewt_stm32f3/hw/bsp/stm32f3discovery
Target targets/boot_f3 successfully set target.bsp to @mynewt_stm32f3/hw/bsp/stm32f3discovery
[user@IsMyLaptop:~/src/air_quality]$ newt target set boot_f3 app=@apache-mynewt-core/apps/boot
Target targets/boot_f3 successfully set target.app to @apache-mynewt-core/apps/boot
[user@IsMyLaptop:~/src/air_quality]$ newt target set boot_f3 build_profile=optimized
Target targets/boot_f3 successfully set target.build_profile to optimized
</code></pre></div>
<p>And then build it, and load it onto the board.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>newt build boot_f3
....
Linking boot.elf
App successfully built: /Users/user/src/air_quality/bin/boot_f3/apps/boot/boot.elf
[user@IsMyLaptop:~/src/air_quality]
$ newt load boot_f3
</code></pre></div>
<p>Next you must download the targets to board, and see that the LED actually blinks. You plug in the STM32F3 discovery board to your laptop, and say:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt load blink_f3
Downloading /Users/user/src/air_quality/bin/blink_f3/apps/blinky/blinky.img to 0x08009000
Open On-Chip Debugger 0.9.0 (2015-05-28-12:05)
....
xPSR: 0x01000000 pc: 0x0800026c msp: 0x10002000
auto erase enabled
Error: couldn&#39;t open /Users/user/src/air_quality/bin/blink_f3/apps/blinky/blinky.img
Error: exit status 1
load - Load app image to target for &lt;target-name&gt;.
Usage:
newt load [flags]
Examples:
newt load &lt;target-name&gt;
Global Flags:
-l, --loglevel string Log level, defaults to WARN. (default &quot;WARN&quot;)
-o, --outfile string Filename to tee log output to
-q, --quiet Be quiet; only display error output.
-s, --silent Be silent; don&#39;t output anything.
-v, --verbose Enable verbose output when executing commands.
exit status 1
</code></pre></div>
<p>Ah. Forgot to create an image out of the blinky binary. Note that every time you want to build and load a new firmware image to target board, you need to run 'create-image' on it.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt create-image blink_f3 0.0.1
App image successfully generated: /Users/user/src/air_quality/bin/blink_f3/apps/blinky/blinky.img
Build manifest: /Users/user/src/air_quality/bin/blink_f3/apps/blinky/manifest.json
[user@IsMyLaptop:~/src/air_quality]$ newt load blink_f3 0.0.1
</code></pre></div>
<p>And it's blinking.</p>
<p>Shortcut for doing build/create-image/load/debug steps all in one is 'newt run' command. Check out the usage from command line help.</p>
<h3 id="create-test-project">Create test project</h3>
<p>Now that you have your system setup, you can start creating your own stuff.
First you want to create a project for yourself - you can start by getting project template from blinky, as it pretty much has what you want.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> [user@IsMyLaptop:~/src/air_quality]$ mkdir apps/air_quality
[user@IsMyLaptop:~/src/air_quality]$ cp repos/apache-mynewt-core/apps/blinky/pkg.yml apps/air_quality/
[user@IsMyLaptop:~/src/air_quality]$ mkdir apps/air_quality/src
[user@IsMyLaptop:~/src/air_quality]$ cp repos/apache-mynewt-core/apps/blinky/src/main.c apps/air_quality/src/
</code></pre></div>
<p>Then you modify the apps/air_quality/pkg.yml for air_quality in order to change the <em>pkg.name</em> to be <em>apps/air_quality</em>.
You also need to point the package dependencies to point to packages in apache-mynewt-core repository.
STM32F3discovery board has limited amount of memory, so you must also switch your libc to be baselibc, instead of the standard one.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ cat apps/air_quality/pkg.yml
pkg.name: apps/air_quality
pkg.type: app
pkg.description: Air quality sensor test
pkg.keywords:
pkg.deps:
- &quot;@apache-mynewt-core/libs/console/full&quot;
- &quot;@apache-mynewt-core/libs/newtmgr&quot;
- &quot;@apache-mynewt-core/libs/os&quot;
- &quot;@apache-mynewt-core/libs/shell&quot;
- &quot;@apache-mynewt-core/sys/config&quot;
- &quot;@apache-mynewt-core/sys/log&quot;
- &quot;@apache-mynewt-core/sys/stats&quot;
- &quot;@apache-mynewt-core/libs/baselibc&quot;
</code></pre></div>
<p>And create a target for it:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt target create air_q
Target targets/air_q successfully created
[user@IsMyLaptop:~/src/air_quality]$ newt target set air_q bsp=@mynewt_stm32f3/hw/bsp/stm32f3discovery
Target targets/air_q successfully set target.bsp to @mynewt_stm32f3/hw/bsp/stm32f3discovery
[user@IsMyLaptop:~/src/air_quality]$ newt target set air_q app=apps/air_quality
Target targets/air_q successfully set target.app to apps/air_quality
[user@IsMyLaptop:~/src/air_quality]$ newt target set air_q build_profile=debug
Target targets/air_q successfully set target.build_profile to debug
[user@IsMyLaptop:~/src/air_quality]$ newt build air_q
....
Linking air_quality.elf
App successfully built: /Users/user/src/air_quality/bin/air_q/apps/air_quality/air_quality.elf
</code></pre></div>
<h3 id="create-packages-for-drivers">Create packages for drivers</h3>
<p>One of the sensors you want to enable is SenseAir K30, which will connect to the board over serial port.
To start development of the driver, you first need to create a package description for it, and add stubs for sources.</p>
<p>So you add few files. pkg.yml to describe the driver, and then header stub followed by source stub.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ cat libs/my_drivers/senseair/pkg.yml
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#</span>
<span style="color: #633820"># Licensed to the Apache Software Foundation (ASF) under one</span>
<span style="color: #633820"># or more contributor license agreements. See the NOTICE file</span>
<span style="color: #633820"># distributed with this work for additional information</span>
<span style="color: #633820"># regarding copyright ownership. The ASF licenses this file</span>
<span style="color: #633820"># to you under the Apache License, Version 2.0 (the</span>
<span style="color: #633820"># &quot;License&quot;); you may not use this file except in compliance</span>
<span style="color: #633820"># with the License. You may obtain a copy of the License at</span>
<span style="color: #633820"># </span>
<span style="color: #633820"># http:</span><span style="color: #177500">//www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #633820">#</span>
<span style="color: #633820"># Unless required by applicable law or agreed to in writing,</span>
<span style="color: #633820"># software distributed under the License is distributed on an</span>
<span style="color: #633820"># &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span>
<span style="color: #633820"># KIND, either express or implied. See the License for the</span>
<span style="color: #633820"># specific language governing permissions and limitations</span>
<span style="color: #633820"># under the License.</span>
<span style="color: #633820">#</span>
<span style="color: #000000">pkg</span>.<span style="color: #000000">name:</span> <span style="color: #000000">libs/my_drivers/senseair</span>
<span style="color: #000000">pkg</span>.<span style="color: #000000">deps:</span>
<span style="color: #000000">-</span> <span style="color: #C41A16">&quot;@apache-mynewt-core/hw/hal&quot;</span>
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ cat libs/my_drivers/senseair/include/senseair/senseair.h
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/*</span>
<span style="color: #177500"> * Licensed to the Apache Software Foundation (ASF) under one</span>
<span style="color: #177500"> * or more contributor license agreements. See the NOTICE file</span>
<span style="color: #177500"> * distributed with this work for additional information</span>
<span style="color: #177500"> * regarding copyright ownership. The ASF licenses this file</span>
<span style="color: #177500"> * to you under the Apache License, Version 2.0 (the</span>
<span style="color: #177500"> * &quot;License&quot;); you may not use this file except in compliance</span>
<span style="color: #177500"> * with the License. You may obtain a copy of the License at</span>
<span style="color: #177500"> * </span>
<span style="color: #177500"> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #177500"> *</span>
<span style="color: #177500"> * Unless required by applicable law or agreed to in writing,</span>
<span style="color: #177500"> * software distributed under the License is distributed on an</span>
<span style="color: #177500"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span>
<span style="color: #177500"> * KIND, either express or implied. See the License for the</span>
<span style="color: #177500"> * specific language governing permissions and limitations</span>
<span style="color: #177500"> * under the License.</span>
<span style="color: #177500">*/</span>
<span style="color: #633820">#ifndef _SENSEAIR_H_</span>
<span style="color: #633820">#define _SENSEAIR_H_</span>
<span style="color: #A90D91">void</span> <span style="color: #000000">senseair_init</span>(<span style="color: #A90D91">void</span>);
<span style="color: #633820">#endif </span><span style="color: #177500">/* _SENSEAIR_H_ */</span>
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ cat libs/my_drivers/senseair/src/senseair.c
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/**</span>
<span style="color: #177500"> * Licensed to the Apache Software Foundation (ASF) under one</span>
<span style="color: #177500"> * or more contributor license agreements. See the NOTICE file</span>
<span style="color: #177500"> * distributed with this work for additional information</span>
<span style="color: #177500"> * regarding copyright ownership. The ASF licenses this file</span>
<span style="color: #177500"> * to you under the Apache License, Version 2.0 (the</span>
<span style="color: #177500"> * &quot;License&quot;); you may not use this file except in compliance</span>
<span style="color: #177500"> * with the License. You may obtain a copy of the License at</span>
<span style="color: #177500"> * </span>
<span style="color: #177500"> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #177500"> *</span>
<span style="color: #177500"> * Unless required by applicable law or agreed to in writing,</span>
<span style="color: #177500"> * software distributed under the License is distributed on an</span>
<span style="color: #177500"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span>
<span style="color: #177500"> * KIND, either express or implied. See the License for the</span>
<span style="color: #177500"> * specific language governing permissions and limitations</span>
<span style="color: #177500"> * under the License.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">void</span>
<span style="color: #000000">senseair_init</span>(<span style="color: #A90D91">void</span>)
{
}
</code></pre></div>
<p>And add dependency to this package in my project yml file.</p>
<p>Here's from apps/air_quality/pkg.yml</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.name: apps/air_quality
pkg.type: app
pkg.description: Air quality sensor test
pkg.keywords:
pkg.deps:
- &quot;@apache-mynewt-core/libs/console/full&quot;
- &quot;@apache-mynewt-core/libs/newtmgr&quot;
- &quot;@apache-mynewt-core/libs/os&quot;
- &quot;@apache-mynewt-core/libs/shell&quot;
- &quot;@apache-mynewt-core/sys/config&quot;
- &quot;@apache-mynewt-core/sys/log&quot;
- &quot;@apache-mynewt-core/sys/stats&quot;
- &quot;@apache-mynewt-core/libs/baselibc&quot;
- libs/my_drivers/senseair
</code></pre></div>
<p>And add a call to your main() to initialize this driver.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> [user@IsMyLaptop:~/src/air_quality]$ diff project/blinky/src/main.c project/air_quality/src/main.c
28a29
&gt; #include &lt;senseair/senseair.h&gt;
190a192
&gt; senseair_init();
[user@IsMyLaptop:~/src/air_quality
</code></pre></div>
<p>And then build it to make sure all goes well.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt build air_q
Compiling senseair.c
Archiving senseair.a
Linking air_quality.elf
App successfully built: /Users/user/src/air_quality/bin/air_q/apps/air_quality/air_quality.elf
</code></pre></div>
<p>All looks good.</p>
<h3 id="add-cli-commands-for-testing-drivers">Add CLI commands for testing drivers</h3>
<p>While developing the driver, you want to issue operations from console asking it to do stuff. The way to do this is to register your command handler with shell. Whenever your custom command is issued, you can respond to it.</p>
<p>The way you do this is first adding a dependency to shell package for your senseair driver. So you change libs/my_drivers/senseair/pkg.yml to have the following:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>pkg.name: libs/my_drivers/senseair
pkg.deps:
- &quot;@apache-mynewt-core/hw/hal&quot;
- &quot;@apache-mynewt-core/libs/shell&quot;
</code></pre></div>
<p>And then register your shell command in <em>senseair_init()</em>.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ cat libs/my_drivers/senseair/src/senseair.c
....
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&lt;shell/shell.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;console/console.h&gt;</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span> <span style="color: #000000">senseair_shell_func</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">shell_cmd</span> <span style="color: #000000">senseair_cmd</span> <span style="color: #000000">=</span> {
.<span style="color: #000000">sc_cmd</span> <span style="color: #000000">=</span> <span style="color: #C41A16">&quot;senseair&quot;</span>,
.<span style="color: #000000">sc_cmd_func</span> <span style="color: #000000">=</span> <span style="color: #000000">senseair_shell_func</span>,
};
<span style="color: #A90D91">void</span>
<span style="color: #000000">senseair_init</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">shell_cmd_register</span>(<span style="color: #000000">&amp;senseair_cmd</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_shell_func</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;Yay! Somebody called!\n&quot;</span>);
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
</code></pre></div>
<p>Then you build this, download to target, and start minicom on your console port.</p>
<p>You'll need to wire up your Board to a Serial converter first. On the STM32F3-Discovery Board pin PA9 is TX and pin PA10 is RX so wire PA9 to RX on your serial board, and PA10 to TX on your serial board.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> [user@IsMyLaptop:~]$ minicom -D /dev/tty.usbserial-AH02MIE2
Welcome to minicom 2.7
OPTIONS:
Compiled on Oct 12 2015, 07:48:30.
Port /dev/tty.usbserial-AH02MIE2, 13:44:40
Press CTRL-X Z for help on special keys
?
141964:Unknown command ?
?
143804:config log echo ? tasks mempools
143806:stat senseair
senseair
150644:Yay! Somebody called!
</code></pre></div>
<p>Now that's great. You can connect the hardware to board and start developing code for the driver itself.</p>
<h3 id="use-of-hal-for-drivers">Use of HAL for drivers</h3>
<p>The sensor has a serial port connection, and that's how you are going to connect to it. Your original BSP, hw/bsp/stm32f3discovery, has only one UART set up (as specified in src/hal_bsp.c, include/hal/bsp.h). Therefore, you need to create your own bsp which has configuration for this added hardware.</p>
<p>So in the shell you make a copy of the original BSP, and then change the package file a little.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ mkdir hw
[user@IsMyLaptop:~/src/air_quality]$ mkdir hw/bsp
[user@IsMyLaptop:~/src/air_quality]$ cp -R repos/mynewt_stm32f3/hw/bsp/stm32f3discovery hw/bsp/stm32f3discovery_with_senseair
</code></pre></div>
<p>Then you modify the pkg.yml in the copied BSP to assign name for this package. And modify the dependency for MCU package to point to mynewt_stm32f3 repository.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code> [user@IsMyLaptop:~/src/air_quality]$ grep pkg.name hw/bsp/stm32f3discovery_with_senseair/pkg.yml
pkg.name: &quot;hw/bsp/stm32f3discovery_with_senseair&quot;
[user@IsMyLaptop:~/src/air_quality]$ tail -2 hw/bsp/stm32f3discovery_with_senseair/pkg.yml
pkg.deps:
- &quot;@mynewt_stm32f3/hw/mcu/stm/stm32f3xx&quot;
</code></pre></div>
<p>And you want to use this BSP with my target. So you change the BSP in the target definition.</p>
<p>Here's your new target.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code>[user@IsMyLaptop:~/src/air_quality]$ newt target show air_q
targets/air_q
app=apps/air_quality
bsp=hw/bsp/stm32f3discovery_with_senseair
build_profile=debug
</code></pre></div>
<p>You add the 2nd serial port to my new BSP. Go to hw/bsp/stm32f3discovery_with_senseair directory to do this.</p>
<p>Modify the include/hal/bsp.h to increase UART_CNT to 2, and add a definition of the 2nd logical UART. You will use this in your sensor driver.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">stm32f3_uart_cfg</span> <span style="color: #000000">uart_cfg</span>[<span style="color: #000000">UART_CNT</span>] <span style="color: #000000">=</span> {
[<span style="color: #1C01CE">0</span>] <span style="color: #000000">=</span> {
.<span style="color: #000000">suc_uart</span> <span style="color: #000000">=</span> <span style="color: #000000">USART1</span>,
.<span style="color: #000000">suc_rcc_cmd</span> <span style="color: #000000">=</span> <span style="color: #000000">RCC_APB2PeriphClockCmd</span>,
.<span style="color: #000000">suc_rcc_dev</span> <span style="color: #000000">=</span> <span style="color: #000000">RCC_APB2Periph_USART1</span>,
.<span style="color: #000000">suc_pin_tx</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">9</span>,
.<span style="color: #000000">suc_pin_rx</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">10</span>,
.<span style="color: #000000">suc_pin_rts</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">12</span>,
.<span style="color: #000000">suc_pin_cts</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">11</span>,
.<span style="color: #000000">suc_pin_af</span> <span style="color: #000000">=</span> <span style="color: #000000">GPIO_AF_7</span>,
.<span style="color: #000000">suc_irqn</span> <span style="color: #000000">=</span> <span style="color: #000000">USART1_IRQn</span>
},
[<span style="color: #1C01CE">1</span>] <span style="color: #000000">=</span> {
.<span style="color: #000000">suc_uart</span> <span style="color: #000000">=</span> <span style="color: #000000">USART2</span>,
.<span style="color: #000000">suc_rcc_cmd</span> <span style="color: #000000">=</span> <span style="color: #000000">RCC_APB1PeriphClockCmd</span>,
.<span style="color: #000000">suc_rcc_dev</span> <span style="color: #000000">=</span> <span style="color: #000000">RCC_APB1Periph_USART2</span>,
.<span style="color: #000000">suc_pin_tx</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">19</span>, <span style="color: #177500">/* PB3 */</span>
.<span style="color: #000000">suc_pin_rx</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">20</span>, <span style="color: #177500">/* PB4 */</span>
.<span style="color: #000000">suc_pin_rts</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">1</span>,
.<span style="color: #000000">suc_pin_cts</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">0</span>,
.<span style="color: #000000">suc_pin_af</span> <span style="color: #000000">=</span> <span style="color: #000000">GPIO_AF_7</span>,
.<span style="color: #000000">suc_irqn</span> <span style="color: #000000">=</span> <span style="color: #000000">USART2_IRQn</span>
}
};
</code></pre></div>
<p>With this in place, you can refer to serial port where your SenseAir sensor is by a logical number. This makes the code more platform independent - you could connect this sensor to another board, like Olimex. You will also use the HAL UART abstraction to do the UART port setup and data transfer. That way you don't need to have any platform dependent pieces within your little driver.</p>
<p>You will now see what the driver code ends up looking like. Here's the header file, filled in from stub you created earlier.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/*</span>
<span style="color: #177500"> * Licensed to the Apache Software Foundation (ASF) under one</span>
<span style="color: #177500"> * or more contributor license agreements. See the NOTICE file</span>
<span style="color: #177500"> * distributed with this work for additional information</span>
<span style="color: #177500"> * regarding copyright ownership. The ASF licenses this file</span>
<span style="color: #177500"> * to you under the Apache License, Version 2.0 (the</span>
<span style="color: #177500"> * &quot;License&quot;); you may not use this file except in compliance</span>
<span style="color: #177500"> * with the License. You may obtain a copy of the License at</span>
<span style="color: #177500"> * </span>
<span style="color: #177500"> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #177500"> *</span>
<span style="color: #177500"> * Unless required by applicable law or agreed to in writing,</span>
<span style="color: #177500"> * software distributed under the License is distributed on an</span>
<span style="color: #177500"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span>
<span style="color: #177500"> * KIND, either express or implied. See the License for the</span>
<span style="color: #177500"> * specific language governing permissions and limitations</span>
<span style="color: #177500"> * under the License.</span>
<span style="color: #177500">*/</span>
<span style="color: #633820">#ifndef _SENSEAIR_H_</span>
<span style="color: #633820">#define _SENSEAIR_H_</span>
<span style="color: #A90D91">enum</span> <span style="color: #000000">senseair_read_type</span> {
<span style="color: #000000">SENSEAIR_CO2</span>,
<span style="color: #000000">SENSEAIR_TEMPERATURE</span>,
<span style="color: #000000">SENSEAIR_HUMIDITY</span>
};
<span style="color: #A90D91">int</span> <span style="color: #000000">senseair_init</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">uartno</span>);
<span style="color: #A90D91">int</span> <span style="color: #000000">senseair_read</span>(<span style="color: #A90D91">enum</span> <span style="color: #000000">senseair_read_type</span>);
<span style="color: #633820">#endif </span><span style="color: #177500">/* _SENSEAIR_H_ */</span>
</code></pre></div>
<p>As you can see, logical UART number has been added to the init routine. A 'read' function has been added, which is a blocking read. If you were making a commercial product, you would probably have a callback for reporting the results.</p>
<p>And here is the source for the driver.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/**</span>
<span style="color: #177500"> * Licensed to the Apache Software Foundation (ASF) under one</span>
<span style="color: #177500"> * or more contributor license agreements. See the NOTICE file</span>
<span style="color: #177500"> * distributed with this work for additional information</span>
<span style="color: #177500"> * regarding copyright ownership. The ASF licenses this file</span>
<span style="color: #177500"> * to you under the Apache License, Version 2.0 (the</span>
<span style="color: #177500"> * &quot;License&quot;); you may not use this file except in compliance</span>
<span style="color: #177500"> * with the License. You may obtain a copy of the License at</span>
<span style="color: #177500"> *</span>
<span style="color: #177500"> * http://www.apache.org/licenses/LICENSE-2.0</span>
<span style="color: #177500"> *</span>
<span style="color: #177500"> * Unless required by applicable law or agreed to in writing,</span>
<span style="color: #177500"> * software distributed under the License is distributed on an</span>
<span style="color: #177500"> * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span>
<span style="color: #177500"> * KIND, either express or implied. See the License for the</span>
<span style="color: #177500"> * specific language governing permissions and limitations</span>
<span style="color: #177500"> * under the License.</span>
<span style="color: #177500"> */</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;string.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;shell/shell.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;console/console.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;os/os.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&lt;hal/hal_uart.h&gt;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&quot;senseair/senseair.h&quot;</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">cmd_read_co2</span>[] <span style="color: #000000">=</span> {
<span style="color: #1C01CE">0xFE</span>, <span style="color: #1C01CE">0X44</span>, <span style="color: #1C01CE">0X00</span>, <span style="color: #1C01CE">0X08</span>, <span style="color: #1C01CE">0X02</span>, <span style="color: #1C01CE">0X9F</span>, <span style="color: #1C01CE">0X25</span>
};
<span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">cmd_read_temp</span>[] <span style="color: #000000">=</span> {
<span style="color: #1C01CE">0xFE</span>, <span style="color: #1C01CE">0X44</span>, <span style="color: #1C01CE">0X00</span>, <span style="color: #1C01CE">0X12</span>, <span style="color: #1C01CE">0X02</span>, <span style="color: #1C01CE">0X94</span>, <span style="color: #1C01CE">0X45</span>
};
<span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">cmd_read_humidity</span>[] <span style="color: #000000">=</span> {
<span style="color: #1C01CE">0xFE</span>, <span style="color: #1C01CE">0x44</span>, <span style="color: #1C01CE">0x00</span>, <span style="color: #1C01CE">0x14</span>, <span style="color: #1C01CE">0x02</span>, <span style="color: #1C01CE">0x97</span>, <span style="color: #1C01CE">0xE5</span>
};
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span> <span style="color: #000000">senseair_shell_func</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>);
<span style="color: #A90D91">static</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">shell_cmd</span> <span style="color: #000000">senseair_cmd</span> <span style="color: #000000">=</span> {
.<span style="color: #000000">sc_cmd</span> <span style="color: #000000">=</span> <span style="color: #C41A16">&quot;senseair&quot;</span>,
.<span style="color: #000000">sc_cmd_func</span> <span style="color: #000000">=</span> <span style="color: #000000">senseair_shell_func</span>,
};
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> {
<span style="color: #A90D91">int</span> <span style="color: #000000">uart</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_sem</span> <span style="color: #000000">sema</span>;
<span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*tx_data</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">tx_off</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">tx_len</span>;
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">rx_data</span>[<span style="color: #1C01CE">32</span>];
<span style="color: #A90D91">int</span> <span style="color: #000000">rx_off</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">value</span>;
} <span style="color: #000000">senseair</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_tx_char</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*s</span> <span style="color: #000000">=</span> <span style="color: #000000">&amp;senseair</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">s-&gt;tx_off</span> <span style="color: #000000">&gt;=</span> <span style="color: #000000">s-&gt;tx_len</span>) {
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Command tx finished.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">s-&gt;tx_data</span> <span style="color: #000000">=</span> <span style="color: #A90D91">NULL</span>;
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-1</span>;
}
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">s-&gt;tx_data</span>[<span style="color: #000000">s-&gt;tx_off</span>];
<span style="color: #000000">s-&gt;tx_off++</span>;
<span style="color: #A90D91">return</span> <span style="color: #000000">rc</span>;
}
<span style="color: #177500">/*</span>
<span style="color: #177500"> * CRC for modbus over serial port.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">const</span> <span style="color: #A90D91">uint16_t</span> <span style="color: #000000">mb_crc_tbl</span>[] <span style="color: #000000">=</span> {
<span style="color: #1C01CE">0x0000</span>, <span style="color: #1C01CE">0xcc01</span>, <span style="color: #1C01CE">0xd801</span>, <span style="color: #1C01CE">0x1400</span>, <span style="color: #1C01CE">0xf001</span>, <span style="color: #1C01CE">0x3c00</span>, <span style="color: #1C01CE">0x2800</span>, <span style="color: #1C01CE">0xe401</span>,
<span style="color: #1C01CE">0xa001</span>, <span style="color: #1C01CE">0x6c00</span>, <span style="color: #1C01CE">0x7800</span>, <span style="color: #1C01CE">0xb401</span>, <span style="color: #1C01CE">0x5000</span>, <span style="color: #1C01CE">0x9c01</span>, <span style="color: #1C01CE">0x8801</span>, <span style="color: #1C01CE">0x4400</span>
};
<span style="color: #A90D91">static</span> <span style="color: #A90D91">uint16_t</span>
<span style="color: #000000">mb_crc</span>(<span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*data</span>, <span style="color: #A90D91">int</span> <span style="color: #000000">len</span>, <span style="color: #A90D91">uint16_t</span> <span style="color: #000000">crc</span>)
{
<span style="color: #A90D91">while</span> (<span style="color: #000000">len--</span> <span style="color: #000000">&gt;</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #000000">crc</span> <span style="color: #000000">^=</span> <span style="color: #000000">*data++</span>;
<span style="color: #000000">crc</span> <span style="color: #000000">=</span> (<span style="color: #000000">crc</span> <span style="color: #000000">&gt;&gt;</span> <span style="color: #1C01CE">4</span>) <span style="color: #000000">^</span> <span style="color: #000000">mb_crc_tbl</span>[<span style="color: #000000">crc</span> <span style="color: #000000">&amp;</span> <span style="color: #1C01CE">0xf</span>];
<span style="color: #000000">crc</span> <span style="color: #000000">=</span> (<span style="color: #000000">crc</span> <span style="color: #000000">&gt;&gt;</span> <span style="color: #1C01CE">4</span>) <span style="color: #000000">^</span> <span style="color: #000000">mb_crc_tbl</span>[<span style="color: #000000">crc</span> <span style="color: #000000">&amp;</span> <span style="color: #1C01CE">0xf</span>];
}
<span style="color: #A90D91">return</span> <span style="color: #000000">crc</span>;
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">mb_crc_check</span>(<span style="color: #A90D91">const</span> <span style="color: #A90D91">void</span> <span style="color: #000000">*pkt</span>, <span style="color: #A90D91">int</span> <span style="color: #000000">len</span>)
{
<span style="color: #A90D91">uint16_t</span> <span style="color: #000000">crc</span>, <span style="color: #000000">cmp</span>;
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*bp</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*</span>)<span style="color: #000000">pkt</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">len</span> <span style="color: #000000">&lt;</span> <span style="color: #A90D91">sizeof</span>(<span style="color: #000000">crc</span>) <span style="color: #000000">+</span> <span style="color: #1C01CE">1</span>) {
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-1</span>;
}
<span style="color: #000000">crc</span> <span style="color: #000000">=</span> <span style="color: #000000">mb_crc</span>(<span style="color: #000000">pkt</span>, <span style="color: #000000">len</span> <span style="color: #000000">-</span> <span style="color: #1C01CE">2</span>, <span style="color: #1C01CE">0xffff</span>);
<span style="color: #000000">cmp</span> <span style="color: #000000">=</span> <span style="color: #000000">bp</span>[<span style="color: #000000">len</span> <span style="color: #000000">-</span> <span style="color: #1C01CE">2</span>] <span style="color: #000000">|</span> (<span style="color: #000000">bp</span>[<span style="color: #000000">len</span> <span style="color: #000000">-</span> <span style="color: #1C01CE">1</span>] <span style="color: #000000">&lt;&lt;</span> <span style="color: #1C01CE">8</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">crc</span> <span style="color: #000000">!=</span> <span style="color: #000000">cmp</span>) {
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-1</span>;
} <span style="color: #A90D91">else</span> {
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_rx_char</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>, <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">data</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*s</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*</span>)<span style="color: #000000">arg</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">s-&gt;rx_off</span> <span style="color: #000000">&gt;=</span> <span style="color: #A90D91">sizeof</span>(<span style="color: #000000">s-&gt;rx_data</span>)) {
<span style="color: #000000">s-&gt;rx_off</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">0</span>;
}
<span style="color: #000000">s-&gt;rx_data</span>[<span style="color: #000000">s-&gt;rx_off</span>] <span style="color: #000000">=</span> <span style="color: #000000">data</span>;
<span style="color: #000000">s-&gt;rx_off++</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">s-&gt;rx_off</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">7</span>) {
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">mb_crc_check</span>(<span style="color: #000000">s-&gt;rx_data</span>, <span style="color: #000000">s-&gt;rx_off</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #000000">s-&gt;value</span> <span style="color: #000000">=</span> <span style="color: #000000">s-&gt;rx_data</span>[<span style="color: #1C01CE">3</span>] <span style="color: #000000">*</span> <span style="color: #1C01CE">256</span> <span style="color: #000000">+</span> <span style="color: #000000">s-&gt;rx_data</span>[<span style="color: #1C01CE">4</span>];
<span style="color: #000000">os_sem_release</span>(<span style="color: #000000">&amp;s-&gt;sema</span>);
}
}
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
<span style="color: #A90D91">void</span>
<span style="color: #000000">senseair_tx</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*s</span>, <span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*tx_data</span>, <span style="color: #A90D91">int</span> <span style="color: #000000">data_len</span>)
{
<span style="color: #000000">s-&gt;tx_data</span> <span style="color: #000000">=</span> <span style="color: #000000">tx_data</span>;
<span style="color: #000000">s-&gt;tx_len</span> <span style="color: #000000">=</span> <span style="color: #000000">data_len</span>;
<span style="color: #000000">s-&gt;tx_off</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">0</span>;
<span style="color: #000000">s-&gt;rx_off</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">0</span>;
<span style="color: #000000">hal_uart_start_tx</span>(<span style="color: #000000">s-&gt;uart</span>);
}
<span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_read</span>(<span style="color: #A90D91">enum</span> <span style="color: #000000">senseair_read_type</span> <span style="color: #000000">type</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*s</span> <span style="color: #000000">=</span> <span style="color: #000000">&amp;senseair</span>;
<span style="color: #A90D91">const</span> <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*cmd</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">cmd_len</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">s-&gt;tx_data</span>) {
<span style="color: #177500">/*</span>
<span style="color: #177500"> * busy</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-1</span>;
}
<span style="color: #A90D91">switch</span> (<span style="color: #000000">type</span>) {
<span style="color: #A90D91">case</span> <span style="color: #000000">SENSEAIR_CO2</span>:
<span style="color: #000000">cmd</span> <span style="color: #000000">=</span> <span style="color: #000000">cmd_read_co2</span>;
<span style="color: #000000">cmd_len</span> <span style="color: #000000">=</span> <span style="color: #A90D91">sizeof</span>(<span style="color: #000000">cmd_read_co2</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">SENSEAIR_TEMPERATURE</span>:
<span style="color: #000000">cmd</span> <span style="color: #000000">=</span> <span style="color: #000000">cmd_read_temp</span>;
<span style="color: #000000">cmd_len</span> <span style="color: #000000">=</span> <span style="color: #A90D91">sizeof</span>(<span style="color: #000000">cmd_read_temp</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">case</span> <span style="color: #000000">SENSEAIR_HUMIDITY</span>:
<span style="color: #000000">cmd</span> <span style="color: #000000">=</span> <span style="color: #000000">cmd_read_humidity</span>;
<span style="color: #000000">cmd_len</span> <span style="color: #000000">=</span> <span style="color: #A90D91">sizeof</span>(<span style="color: #000000">cmd_read_humidity</span>);
<span style="color: #A90D91">break</span>;
<span style="color: #A90D91">default</span><span style="color: #000000">:</span>
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-1</span>;
}
<span style="color: #000000">senseair_tx</span>(<span style="color: #000000">s</span>, <span style="color: #000000">cmd</span>, <span style="color: #000000">cmd_len</span>);
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sem_pend</span>(<span style="color: #000000">&amp;s-&gt;sema</span>, <span style="color: #000000">OS_TICKS_PER_SEC</span> <span style="color: #000000">/</span> <span style="color: #1C01CE">2</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #000000">OS_TIMEOUT</span>) {
<span style="color: #177500">/*</span>
<span style="color: #177500"> * timeout</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-2</span>;
}
<span style="color: #A90D91">return</span> <span style="color: #000000">s-&gt;value</span>;
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_shell_func</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #A90D91">int</span> <span style="color: #000000">value</span>;
<span style="color: #A90D91">enum</span> <span style="color: #000000">senseair_read_type</span> <span style="color: #000000">type</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">argc</span> <span style="color: #000000">&lt;</span> <span style="color: #1C01CE">2</span>) {
<span style="color: #000000">usage</span>:
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;%s &lt;co2|temp|humidity&gt;\n&quot;</span>, <span style="color: #000000">argv</span>[<span style="color: #1C01CE">0</span>]);
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
<span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;co2&quot;</span>)) {
<span style="color: #000000">type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSEAIR_CO2</span>;
} <span style="color: #A90D91">else</span> <span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;temp&quot;</span>)) {
<span style="color: #000000">type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSEAIR_TEMPERATURE</span>;
} <span style="color: #A90D91">else</span> <span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;humidity&quot;</span>)) {
<span style="color: #177500">/*</span>
<span style="color: #177500"> * timeout</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">-2</span>;
}
<span style="color: #A90D91">return</span> <span style="color: #000000">s-&gt;value</span>;
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_shell_func</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #A90D91">int</span> <span style="color: #000000">value</span>;
<span style="color: #A90D91">enum</span> <span style="color: #000000">senseair_read_type</span> <span style="color: #000000">type</span>;
<span style="color: #A90D91">if</span> (<span style="color: #000000">argc</span> <span style="color: #000000">&lt;</span> <span style="color: #1C01CE">2</span>) {
<span style="color: #000000">usage</span>:
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;%s &lt;co2|temp|humidity&gt;\n&quot;</span>, <span style="color: #000000">argv</span>[<span style="color: #1C01CE">0</span>]);
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
<span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;co2&quot;</span>)) {
<span style="color: #000000">type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSEAIR_CO2</span>;
} <span style="color: #A90D91">else</span> <span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;temp&quot;</span>)) {
<span style="color: #000000">type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSEAIR_TEMPERATURE</span>;
} <span style="color: #A90D91">else</span> <span style="color: #A90D91">if</span> (<span style="color: #000000">!strcmp</span>(<span style="color: #000000">argv</span>[<span style="color: #1C01CE">1</span>], <span style="color: #C41A16">&quot;humidity&quot;</span>)) {
<span style="color: #000000">type</span> <span style="color: #000000">=</span> <span style="color: #000000">SENSEAIR_HUMIDITY</span>;
} <span style="color: #A90D91">else</span> {
<span style="color: #A90D91">goto</span> <span style="color: #000000">usage</span>;
}
<span style="color: #000000">value</span> <span style="color: #000000">=</span> <span style="color: #000000">senseair_read</span>(<span style="color: #000000">type</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">value</span> <span style="color: #000000">&gt;=</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;Got %d\n&quot;</span>, <span style="color: #000000">value</span>);
} <span style="color: #A90D91">else</span> {
<span style="color: #000000">console_printf</span>(<span style="color: #C41A16">&quot;Error while reading: %d\n&quot;</span>, <span style="color: #000000">value</span>);
}
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
<span style="color: #A90D91">int</span>
<span style="color: #000000">senseair_init</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">uartno</span>)
{
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">senseair</span> <span style="color: #000000">*s</span> <span style="color: #000000">=</span> <span style="color: #000000">&amp;senseair</span>;
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">shell_cmd_register</span>(<span style="color: #000000">&amp;senseair_cmd</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">rc</span>;
}
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sem_init</span>(<span style="color: #000000">&amp;s-&gt;sema</span>, <span style="color: #1C01CE">1</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">rc</span>;
}
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">hal_uart_init_cbs</span>(<span style="color: #000000">uartno</span>, <span style="color: #000000">senseair_tx_char</span>, <span style="color: #A90D91">NULL</span>,
<span style="color: #000000">senseair_rx_char</span>, <span style="color: #000000">&amp;senseair</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">rc</span>;
}
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">hal_uart_config</span>(<span style="color: #000000">uartno</span>, <span style="color: #1C01CE">9600</span>, <span style="color: #1C01CE">8</span>, <span style="color: #1C01CE">1</span>, <span style="color: #000000">HAL_UART_PARITY_NONE</span>,
<span style="color: #000000">HAL_UART_FLOW_CTL_NONE</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span>) {
<span style="color: #A90D91">return</span> <span style="color: #000000">rc</span>;
}
<span style="color: #000000">s-&gt;uart</span> <span style="color: #000000">=</span> <span style="color: #000000">uartno</span>;
<span style="color: #A90D91">return</span> <span style="color: #1C01CE">0</span>;
}
</code></pre></div>
<p>And you modified your main() for senseair driver init.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
....
<span style="color: #000000">senseair_init</span>(<span style="color: #1C01CE">1</span>);
....
}
</code></pre></div>
<p>You can see from the code that you are using the HAL interface to open a UART port, and using OS semaphore as a way of blocking the task when waiting for read response to come back from the sensor.</p>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/base.js"></script>
<script src="../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>