<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CY8CPROTO-062-4343W &#8211; IoT Expert</title>
	<atom:link href="https://iotexpert.com/category/devkits/cy8cproto-062-4343w/feed/" rel="self" type="application/rss+xml" />
	<link>https://iotexpert.com</link>
	<description>Engineering for the Internet of Things</description>
	<lastBuildDate>Wed, 27 Jan 2021 13:07:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://iotexpert.com/wp-content/uploads/2017/01/cropped-Avatar-32x32.jpg</url>
	<title>CY8CPROTO-062-4343W &#8211; IoT Expert</title>
	<link>https://iotexpert.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 10)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 28 Dec 2020 13:00:47 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[ModusToolbox]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10250</guid>

					<description><![CDATA[Summary We have finally reached the end of the AnyCloud Bluetooth Advertising Scanner.  In this article I will add the ability to sort the database.  In addition I will add the ability to purge a device.  And finally, truly finally, a bit of commentary. Story I originally built this program to help me learn about [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>We have finally reached the end of the AnyCloud Bluetooth Advertising Scanner.  In this article I will add the ability to sort the database.  In addition I will add the ability to purge a device.  And finally, truly finally, a bit of commentary.</p>
<h1>Story</h1>
<p>I originally built this program to help me learn about the AnyCloud Bluetooth SDK.  Well, originally I built this functionality to try to find and talk to a specific device (in an upcoming series).  The problem is that there are so many devices at my house that are blasting out so much data it is hard to see what I am looking for.  What I realized would help is add the ability to sort the devices from newest to oldest.  In addition I noticed that occasionally my database would fill up&#8230; and it would be nice to purge out old entries.  So that is what we are going to do.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Fix the Database Data Structure</h1>
<p>You might remember that the database was built as an array of structures.  This mean that any moving around of the data would be a require a replacement of the whole structure.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static adb_adv_t adb_database[ADB_MAX_SIZE];</pre>
<p>To fix this problem I moved the database to a an array of pointers.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static adb_adv_t *adb_database[ADB_MAX_SIZE];</pre>
<p>To support this, when I see a new device I malloc a block of memory to hold the actual structure.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    // If it is NOT found &amp;&amp; you have room
    if(entry == -1)
    {
        adb_database[adb_db_count] = malloc(sizeof(adb_adv_t));</pre>
<p>Then I had to fix all of the references to the structure.  And there were a bunch (actually 43 of them).  But the replacement was pretty simple</p>
<p>adb_database[&#8230;].xxx is replaced by adb_database[&#8230;]-&gt; &#8230;. here are the three different cases</p>
<p>case 1: adb_database[adb_db_count].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-40-36-am/" rel="attachment wp-att-10254"><img fetchpriority="high" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM.png" alt="" class="alignnone size-full wp-image-10254" width="834" height="126" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM.png 834w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-300x45.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-768x116.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.40.36-AM-600x91.png 600w" sizes="(max-width: 834px) 100vw, 834px" /></a></p>
<p>case 2: adb_database[entry].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-32-54-am/" rel="attachment wp-att-10251"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM.png" alt="" class="alignnone size-full wp-image-10251" width="842" height="132" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM.png 842w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-300x47.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-768x120.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.32.54-AM-600x94.png 600w" sizes="(max-width: 842px) 100vw, 842px" /></a></p>
<p>case 1: adb_database[i].</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-7-33-23-am/" rel="attachment wp-att-10252"><img decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM.png" alt="" class="alignnone size-full wp-image-10252" width="838" height="132" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM.png 838w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-300x47.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-768x121.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-7.33.23-AM-600x95.png 600w" sizes="(max-width: 838px) 100vw, 838px" /></a></p>
<p>That was actually way less painful that I thought it was going to be.  Probably what would actually be best is a library of these data structures with an API that would not have changed when the key changed, but that I suppose, is for another day.</p>
<h1>Add Two New Commands</h1>
<p>Now I add the sort and purge commands to my command list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
    ADB_WATCH,
    ADB_ERASE,
    ADB_RECORD,
    ADB_FILTER,
    ADB_SORT,
    ADB_PURGE,
} adb_cmd_t;
</pre>
<h1>Create the Sort Functionality</h1>
<p>To sort, I will use the c-standard library function qsort.  It requires a function that compares two entries a/b and returns</p>
<ol>
<li>a negative number of a&lt;b</li>
<li>0 if a=b</li>
<li>a positive number if a&gt;b</li>
</ol>
<p>Here is the function.  Hey Hassane you like those pointers?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int adb_sort_cmpfunc(const void * a, const void * b) 
{
    adb_adv_t *p1 = *((adb_adv_t **)a);
    adb_adv_t *p2 = *((adb_adv_t **)b);
        
    return p2-&gt;lastSeen - p1-&gt;lastSeen;
}</pre>
<p>The sort is actually really simple now.  Just a call to sort (then I decided to print out the table)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_SORT:
                    qsort(adb_database, adb_db_count, sizeof(adb_adv_t *), adb_sort_cmpfunc);
                    adb_db_print(ADB_PRINT_METHOD_BYTES,true,-1);
                break;</pre>
<p>Now instead of this&#8230;.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-4-35-26-pm/" rel="attachment wp-att-10256"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1024x678.png" alt="" class="alignnone size-large wp-image-10256" width="1024" height="678" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1024x678.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-300x199.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-768x508.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-1536x1017.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM-600x397.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.26-PM.png 1970w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I get this&#8230;</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/screen-shot-2020-11-16-at-4-35-37-pm/" rel="attachment wp-att-10257"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1024x660.png" alt="" class="alignnone size-large wp-image-10257" width="1024" height="660" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1024x660.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-300x193.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-768x495.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-1536x990.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM-600x387.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-16-at-4.35.37-PM.png 2042w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Create the Purge Functionality</h1>
<p>The purge function needs to do two things</p>
<ol>
<li>Free all of the memory from an entry</li>
<li>Move the pointers so that the &#8220;purged&#8221; entry is gone.</li>
</ol>
<p>First I erase all of the data in the linked list with the adb_eraseEntry function.</p>
<p>Then I free the head of the list</p>
<p>Then I free the actual structure</p>
<p>Then I move all of the pointers to squeeze the able.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_purgeEntry(int entry)
{

    adb_eraseEntry(entry);
    free(adb_database[entry]-&gt;list);
    free(adb_database[entry]-&gt;result);
    free(adb_database[entry]);
    adb_db_count -= 1;
    for(int i=entry;i&lt;adb_db_count;i++)
    {
        adb_database[i] = adb_database[i+1];
    }
}
</pre>
<p>And you need to add the actual command.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_PURGE:
                    if((int)msg.data0&lt;0 || (int)msg.data0&gt;=adb_db_count)
                    {
                        printf("Purge error %d\n",(int)msg.data0);
                        break;
                    }   
                    adb_purgeEntry((int)msg.data0);
                break;</pre>
<h1>The End &amp; Commentary</h1>
<p>I would like to add and maybe will one day:</p>
<ol>
<li>A connect function with a GATT browser</li>
<li>A smarter way to deal with the fact that device change addresses</li>
</ol>
<p>Finally a couple of comments about this</p>
<ol>
<li>You might notice that I don&#8217;t check very many possible errors.  I do this in the interest of simpler to read code.  This is a tradeoff that I make for &#8220;teaching&#8221; code.  I hope that you understand that if you want to do something like this in a real product that you need to be much more careful.</li>
<li>I don&#8217;t have unit testing.  This falls into the same category as the error checking.  Really this is a bad idea as code without unit testing is obsolete the second it comes out of your fingers.  But, it is easier to read.</li>
<li>I don&#8217;t have many comments.  This is something that my colleagues bitch about all of the time with me.  And I know that it must be a personality defect.</li>
<li>I use malloc/free all over the place.  This is a religious war.  You can make a static allocation scheme, but it would be really complicated in this case.  I personally think that the tradeoff of using a battle worn and tested malloc/free is totally worthwhile against the complexity of custom static memory allocation schemes.</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 9)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 21 Dec 2020 13:00:28 +0000</pubDate>
				<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10239</guid>

					<description><![CDATA[Summary In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 9, I will fix a memory leak, add packet age, and improve the printing. Story You might be starting to wonder if this series is ever going [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 9, I will fix a memory leak, add packet age, and improve the printing.</p>
<h1>Story</h1>
<p>You might be starting to wonder if this series is ever going to end.  Well, this article and one more.  That is it.</p>
<p>This morning as I was looking at the serial console window I noticed that I had hit the limit of device in the buffer,  OK.  But that it had also crashed, gone, bye bye, so long &#8230; the long dark road.  That needs fixing.</p>
<p>I also was curious when I looked at the output, how long ago I had seen the packets/devices.  So I decided that having &#8220;age&#8221; in the database made sense.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Fix the Memory Leak</h1>
<p>I noticed that a while after I started getting the message &#8220;ADV Table Max Size&#8221; that things would crash.  But Why?  The answer is a memory leak &#8211; go figure. I originally thought when I get a new device I would just overwrite the last entry in the table.  But, when I overwrote the adb_database[adb_db_count]. record with a new scan_result and a new list, I left memory that was previously allocated, here is the code:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    if(entry == -1)
    {
        adb_database[adb_db_count].result = scan_result;
        adb_database[adb_db_count].listCount = 1;
        adb_database[adb_db_count].record = false;
        adb_database[adb_db_count].filter = true;
        adb_database[adb_db_count].numSeen = 1;

        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = 0;
        current-&gt;data = data;
        current-&gt;count = 1;

        adb_database[adb_db_count].list = current;

        adb_db_count = adb_db_count + 1;
        if(adb_db_count == ADB_MAX_SIZE)
        {
            printf("ADV Table Max Size\n");
            adb_db_count = adb_db_count - 1;
        }
        else
        {    
            adb_db_print(ADB_PRINT_METHOD_BYTES,false,adb_db_count-1);
        }
    }</pre>
<p>A cheap fix is to just stop making new entries when the database runs out of room.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    // If there is a new entry and you ran out of space
    if(entry == -1 &amp;&amp; adb_db_count &gt;= ADB_MAX_SIZE)
    {
        free(scan_result);
        free(data);
        return;
    }</pre>
<h1>Add Age</h1>
<p>As I mentioned earlier I wanted to keep track of</p>
<ol>
<li>The last time I had seen a device</li>
<li>When I saw that specific advertising packet</li>
</ol>
<p>The FreeRTOS has a free running millisecond counter that starts a 0 and counts up to 2^32.  A really cheap way to keep track of time is just to use this counter. To do this the first step is add the time to the database.  Both in the device record and the packet record.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
    uint8_t *data;
    int count;
    TickType_t lastSeen;
    struct adb_adv_data_t *next;
} adb_adv_data_t;

typedef struct {
    wiced_bt_ble_scan_results_t *result;
    bool record;
    bool filter;
    int numSeen;
    int listCount;
    TickType_t lastSeen;
    adb_adv_data_t *list;
} adb_adv_t ;</pre>
<h1>Update the Printing</h1>
<p>I am going to make the output look like this with a new column representing the seconds since I heard the packet.  In the picture below you can see that I heard 00 at 0.0 seconds ago&#8230;  Then you can see that I had a recording of device 5 where I have a bunch of packets that I heard back into time.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/screen-shot-2020-11-15-at-12-28-23-pm/" rel="attachment wp-att-10244"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-1024x326.png" alt="" class="alignnone size-large wp-image-10244" width="1024" height="326" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-1024x326.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-300x95.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-768x244.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-1536x488.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM-600x191.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-15-at-12.28.23-PM.png 1988w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>To do this I just add a time calculation like this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printEntry(adb_print_method_t method, int entry, adb_adv_data_t *adv_data)
{
    float time = ((float)xTaskGetTickCount() - (float)(adv_data-&gt;lastSeen))/1000;

    printf("%c%c%02d %05d %03d %6.1f ",adb_database[entry].watch?'W':' ',
    adb_database[entry].filter?'F':' ',
    entry,adb_database[entry].numSeen,adb_database[entry].listCount,
    time);
</pre>
<h1>Fix up the Add</h1>
<p>The next thing that I need to do is make the &#8220;add&#8221; function add the time.  The problem is that this function has gotten totally totally out of control.  It turns out that there are x different possibilities</p>
<ol>
<li>Ignore the packet (because the table is full)</li>
<li>Add a new device &amp; packet</li>
<li>Update the head of the list with a new packet</li>
<li>Insert a new packet at the head of the list</li>
<li>If you are filtering update a duplicated packet count</li>
</ol>
<p>The code for these branches all looked somewhat similar.  But, which branch to take depended on</p>
<ol>
<li>If you were &#8220;watching&#8221; that device</li>
<li>If you were &#8220;filtering&#8221; that device</li>
<li>If you were &#8220;recording&#8221;</li>
<li>If you had seen that packet before (aka it was found)</li>
</ol>
<p>I ended up making a truth table:</p>
<table width="496" cellspacing="0" cellpadding="0" border="0">
<colgroup>
<col width="87" span="4" />
<col width="148" /></colgroup>
<tbody>
<tr height="21">
<td style="text-align: center;" width="87" height="21"><strong>Watch</strong></td>
<td style="text-align: center;" width="87"><strong>Filter</strong></td>
<td style="text-align: center;" width="87"><strong>Recording</strong></td>
<td style="text-align: center;" width="87"><strong>Found</strong></td>
<td style="text-align: center;" width="148"><strong>Action</strong></td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">insert at the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">insert at the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">update the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the found</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">0</td>
<td style="text-align: center;">insert at the head</td>
</tr>
<tr height="21">
<td style="text-align: center;" height="21" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;" align="right">1</td>
<td style="text-align: center;">update the found</td>
</tr>
</tbody>
</table>
<p>The case where you</p>
<ol>
<li>Had no room</li>
<li>Saw a new device</li>
</ol>
<p>Look like this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_add(wiced_bt_ble_scan_results_t *scan_result,uint8_t *data)
{

    TickType_t timeSeen = xTaskGetTickCount();

    int entry = adb_db_find(&amp;scan_result-&gt;remote_bd_addr);

    // If there is a new entry and you ran out of space
    if(entry == -1 &amp;&amp; adb_db_count &gt;= ADB_MAX_SIZE)
    {
        free(scan_result);
        free(data);
        return;
    }
    
    // If it is NOT found &amp;&amp; you have room
    if(entry == -1)
    {
        adb_database[adb_db_count] = malloc(sizeof(adb_adv_t));
        adb_database[adb_db_count]-&gt;result = scan_result;
        adb_database[adb_db_count]-&gt;listCount = 1;
        adb_database[adb_db_count]-&gt;watch = false;
        adb_database[adb_db_count]-&gt;filter = true;
        adb_database[adb_db_count]-&gt;numSeen = 1;
        adb_database[adb_db_count]-&gt;lastSeen = timeSeen;

        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = 0;
        current-&gt;data = data;
        current-&gt;numSeen = 1;
        current-&gt;lastSeen = timeSeen;

        adb_database[adb_db_count]-&gt;list = current;

        adb_db_count = adb_db_count + 1;    
        adb_db_print(ADB_PRINT_METHOD_BYTES,false,adb_db_count-1);

        return; 
    }</pre>
<p>At this point in the code you know that you have seen this device before.  If you are filtering you should look in the linked list to see if you can find the specific packet (lines 1-15).</p>
<p>If you look at the truth table above you will see three cases where you should insert at the head of this list.  Those cases are identified with the sprawling if on lines 17-21).  Once you identify that scenario you do the needful.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    adb_adv_data_t *updateItem=0; 

    if(adb_database[entry].filter) // if filtering is on.
    {
        int len = btutil_adv_len(data); // ARH maybe a bug here
        
        for(adb_adv_data_t *list = adb_database[entry].list;list;list = (adb_adv_data_t *)list-&gt;next)
        {
            if(memcmp(list-&gt;data,data,len) == 0) // Found the data
            {
                updateItem = list;
                break;
            }
        }
    }

    // insert at the head
    if( (adb_database[entry].watch &amp;&amp; !adb_database[entry].filter &amp;&amp; adb_recording &amp;&amp; !updateItem) ||
        (adb_database[entry].watch &amp;&amp; !adb_database[entry].filter &amp;&amp; adb_recording &amp;&amp; updateItem) ||
        (adb_database[entry].watch &amp;&amp; adb_database[entry].filter &amp;&amp; adb_recording &amp;&amp; !updateItem)
    )
    {
        adb_adv_data_t *updateItem = malloc(sizeof(adb_adv_data_t)); // make new data
        updateItem-&gt;next = (struct adb_adv_data_t *)adb_database[entry].list;
        updateItem-&gt;numSeen = 1;
        updateItem-&gt;data = data;
        updateItem-&gt;lastSeen = timeSeen;

        adb_database[entry].list = updateItem;
        adb_database[entry].numSeen += 1;
        adb_database[entry].lastSeen = timeSeen;
        adb_database[entry].listCount += 1;
        free(scan_result);
        
        adb_db_print(ADB_PRINT_METHOD_BYTES,false,entry);


        adb_recording_count += 1;
        if(adb_recording_count == ADB_RECORD_MAX)
        {
            adb_recording = false;
            printf("Recording buffer full\n");
        }
        return;
    }
</pre>
<p>The final case happens when you are just going to update a found packet.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    if(updateItem == 0)
        updateItem = adb_database[entry].list;


    adb_database[entry].numSeen += 1;
    adb_database[entry].lastSeen = timeSeen;

    updateItem-&gt;lastSeen = timeSeen;

    int len = btutil_adv_len(data); // ARH maybe a bug here
    if(memcmp(updateItem-&gt;data,data,len) == 0)
    {
        updateItem-&gt;numSeen += 1;
    }
    else
    {
        updateItem-&gt;numSeen = 1;   
    }

    free(updateItem-&gt;data);
    updateItem-&gt;data = data;
    free(scan_result);

}
</pre>
<p>In the next article I will add</p>
<ol>
<li>Sort</li>
<li>Purge</li>
</ol>
<p>Then I will call it  a day.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 8)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 14 Dec 2020 13:00:23 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10220</guid>

					<description><![CDATA[Summary In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 8 I will turn on the ability to filter duplicate advertising packets. Story In the previous article I added the ability to record advertising packets.  The problem [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this series of articles I am building a Bluetooth Low Energy Scanner using the Cypress/Infineon AnyCloud SDK running on a PSoC 6 and CYW43xxx.  In Part 8 I will turn on the ability to filter duplicate advertising packets.</p>
<h1>Story</h1>
<p>In the previous article I added the ability to record advertising packets.  The problem is, of course, that many devices are blasting out advertising packets, which will quickly overwhelm you.  I suppose more importantly it will overwhelm the packet buffer.  Most of the device are just advertising their presence, so they send the same data over and over.  Some devices alternate between a small number of different advertising packets, e.g. an iBeacon then and Eddystone beacon.</p>
<p>The way that the filter will work is that I will update the &#8220;add&#8221; function to search through all of the packets that device has launched, then if I have seen the packet before (Ill use a memcmp) then I will just keep a count of how many times I have see that packet.</p>
<p>The other thing that needs to happen is for me to add a &#8220;filter&#8221; command so that I can turn on packet filtering on a device by device basis.</p>
<p>And I need to fix the printing to use the new filtered packet database.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Update the Data Structures</h1>
<p>In order to do the filters, and keep track of the data I will add</p>
<ol>
<li>A &#8220;count&#8221; field to the packet data structure</li>
<li>A &#8220;filter&#8221; boolean field to the device data structure.</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
    uint8_t *data;
    int count;
    struct adb_adv_data_t *next;
} adb_adv_data_t;

typedef struct {
    wiced_bt_ble_scan_results_t *result;
    bool record;
    bool filter;
    int numSeen;
    int listCount;
    adb_adv_data_t *list;
} adb_adv_t ;</pre>
<h1>Update the Add Function</h1>
<p>In the function &#8220;static void adb_db_add(wiced_bt_ble_scan_results_t *scan_result,uint8_t *data)&#8221; which is called every time I see a new advertising packet I will need to handle four different cases:</p>
<ol>
<li>The first time you see a device</li>
<li>A device you have seen AND you are recording AND have the filtering turned on</li>
<li>A device you are recording but not filtering</li>
<li>A device you have seen, but are not recording or filter.</li>
</ol>
<p>In the first case, a device you haven&#8217;t seen before, you need to</p>
<ol>
<li>Automatically turn on the filtering</li>
<li>Initialize the counts to 1</li>
<li>Do the other initialization (as before)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    // If it is NOT found
    if(entry == -1)
    {
        adb_database[adb_db_count].result = scan_result;
        adb_database[adb_db_count].listCount = 1;
        adb_database[adb_db_count].record = false;
        adb_database[adb_db_count].filter = true;
        adb_database[adb_db_count].numSeen = 1;

        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = 0;
        current-&gt;data = data;
        current-&gt;count = 1;</pre>
<p>In the case where you have</p>
<ol>
<li>See the device before</li>
<li>You have room in the record buffer</li>
<li>And you are in record mode</li>
</ol>
<p>You will then decide if you are filtering.</p>
<p>Then you will iterate through all of the packets and compare the data to the data you just received.  If there is a match then you update the count, free the duplicate data and return.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    else if(adb_database[entry].record &amp;&amp; adb_recording_count&lt;ADB_RECORD_MAX &amp;&amp; adb_recording)
    {
        adb_database[entry].numSeen += 1;

        if(adb_database[entry].filter) // if filtering is on.
        {
            int len = btutil_adv_len(data); 
            for(adb_adv_data_t *list = adb_database[entry].list;list;list = (adb_adv_data_t *)list-&gt;next)
            {
                if(memcmp(list-&gt;data,data,len) == 0) // Found the data
                {
                    list-&gt;count += 1;
                    printf("Count = %d\n",list-&gt;count);
                    free(data);
                    free(scan_result);
                    return;
                }
            }
        }
</pre>
<p>If you have not see the data before, then you need to add it to the linked list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">        adb_adv_data_t *current = malloc(sizeof(adb_adv_data_t));
        current-&gt;next = (struct adb_adv_data_t *)adb_database[entry].list;
        current-&gt;data = data;
        current-&gt;count = 1;</pre>
<p>If you are not recording and not filtering, just increment counts.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    else
    {
        adb_database[entry].numSeen += 1;
        adb_database[entry].list-&gt;count += 1;</pre>
<h1>Add a &#8220;filter&#8221; Command</h1>
<p>I want the ability for a user to &#8220;filter all&#8221; or &#8220;filter clear&#8221; or &#8220;filter #&#8221; &#8211; just like we did with watch.  So, add the #defines and new function to advDatabase.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define ADB_FILTER_ALL -1
#define ADB_FILTER_CLEAR -2
void adb_filter(int entry);
</pre>
<p>Then add the new filter command in advDatabase.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
    ADB_WATCH,
    ADB_ERASE,
    ADB_RECORD,
    ADB_FILTER,
} adb_cmd_t;</pre>
<p>I will use the adb_queueCmd function that I created in the last article.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">inline void adb_filter(int entry) { adb_queueCmd(ADB_FILTER,(void*)entry,(void *)0); }
</pre>
<p>The filter command has three cases</p>
<ol>
<li>All &#8211; turn the bool for all on</li>
<li>Clear &#8211; turn the bool for all off</li>
<li>Just a specific number &#8211; toggle that specific number</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_filter(int entry)
{
    if(entry == ADB_FILTER_ALL)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_database[i].filter = true;
        }
        return;
    }

    if(entry == ADB_FILTER_CLEAR)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_database[i].filter = false;
        }
        return;
    }

    if(entry &gt; adb_db_count-1 || entry &lt; ADB_WATCH_CLEAR)
    {
        printf("Record doesnt exist: %d\n",entry);
        return;      
    }
    adb_database[entry].filter = !adb_database[entry].filter; 

}
</pre>
<p>And you need to fix up the main command processor</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_FILTER:
                    adb_db_filter((int)msg.data0);
                break;</pre>
<p>Finally add the command to the usrcmd.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_filter(int argc, char **argv)
{

    if(argc == 2 &amp;&amp; !strcmp(argv[1],"all"))
    {
        adb_filter(ADB_FILTER_ALL); // all
        return 0;
    }


    if(argc == 2 &amp;&amp; !strcmp(argv[1],"clear"))
    {
        adb_filter(ADB_FILTER_CLEAR);
        return 0;
    }

    if(argc == 2)
    {
        int i;
        sscanf(argv[1],"%d",&amp;i);
        adb_filter(i);
        return 0;
    }

    return 0;
}</pre>
<h1>Fix the Printing</h1>
<p>Now we nee to fix the printing.  I want to add an indicate of the filtering to the output.  Remember from the previous article I indicated &#8220;Watch&#8221; with a &#8220;*&#8221;.  When I looked at it, I decided that I should indicate filter with an &#8220;F&#8221; and watch with a &#8220;W&#8221;.  So I fix that.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">        printf("%c%c%02d %05d %03d MAC: ",adb_database[i].record?'W':' ',
            adb_database[i].filter?'F':' ',
            i,adb_database[i].numSeen,adb_database[i].listCount);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        switch(method)
        {</pre>
<p>Then I test the &#8220;filter&#8221; command</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-9-49-32-am/" rel="attachment wp-att-10235"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1024x622.jpg" alt="" class="alignnone size-large wp-image-10235" width="1024" height="622" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1024x622.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-300x182.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-768x466.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-1536x933.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM-600x364.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-9.49.32-AM.jpg 2042w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Fix the Printing Part (2)</h1>
<p>As I noodled on how to change the printing I decide that it would be nice to sometimes print out only one packet e.g. no history and sometimes print them all out e.g. history.  So, I add a new parameter to the function called &#8220;history&#8221;</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_print(adb_print_method_t method,bool history,int entry)
</pre>
<p>As I looked at the printing code, I decided that it would be better to have a new function to print only one entry.  I suppose that I could have left the code inline, but I thought that intent was clearer.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printEntry(adb_print_method_t method, int entry, adb_adv_data_t *adv_data)
{
    printf("%c%c%02d %05d %03d MAC: ",adb_database[entry].record?'W':' ',
    adb_database[entry].filter?'F':' ',
    entry,adb_database[entry].numSeen,adb_database[entry].listCount);
    btutil_printBDaddress(adb_database[entry].result-&gt;remote_bd_addr);

    switch(method)
    {
    
    case ADB_PRINT_METHOD_BYTES:
        printf(" Data: ");
        btutil_adv_printPacketBytes(adv_data-&gt;data);
    break;

    case ADB_PRINT_METHOD_DECODE:
        printf("\n");
        btutil_adv_printPacketDecode(adv_data-&gt;data);
    break;
    } 
    printf("\n");

}
</pre>
<p>With the new function in place I now need to update the print function to call the new entry function.  Printing the history is just a matter of iterating through the linked list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_print(adb_print_method_t method,bool history,int entry)
{
    int start,end;
 
    if(entry &lt; 0)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry+1;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;end;i++)
    {
        if(history) // then iterate through the linked list print all of the packets
        {
            for(adb_adv_data_t *list = adb_database[i].list;list;list = (adb_adv_data_t *)list-&gt;next)
            {
                adb_db_printEntry(method,i,list);    
            }
        }
        else // Just print the first packet in the list
            adb_db_printEntry(method,i,adb_database[i].list);
    }
}</pre>
<p>Now, I need to update all of the calls to adb_db_print to have the new history parameter.  First, I made the decision that when you &#8220;print&#8221; from the command line that you are interested in the history.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_PRINT_RAW:
                    adb_db_print(ADB_PRINT_METHOD_BYTES,true,(int)msg.data0);
                break;
                case ADB_PRINT_DECODE:
                    adb_db_print(ADB_PRINT_METHOD_DECODE,true,(int)msg.data0);
                break;</pre>
<p>But when you are printing out the packet for a new device don&#8217;t print out the history</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">            adb_db_print(ADB_PRINT_METHOD_BYTES,false,adb_db_count-1);
</pre>
<h1>Program and Test</h1>
<p>After I program my development kit, I start by typing &#8220;watch all&#8221;.  Very quickly, at my house, you can see that a bunch of devices are discovered.  You can see that all of these have a &#8220;W&#8221; (meaning that I am watching them) and an &#8220;F&#8221; meaning they are filtering out duplicates.  Then I type &#8220;record&#8221; to turn on recording. After a minute I turn off recording then do the print you can see below.</p>
<p>A couple of things to notice.</p>
<ol>
<li>Device #4 (which I highlighted) appears to be sending out a pattern of alternating packets.  See that I have heard 3335 packets yet there are only two in the buffer</li>
<li>You can see device 11 seems to be sending out 16 different packets.  Why?  I don&#8217;t know.</li>
</ol>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-12-33-06-pm/" rel="attachment wp-att-10236"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1024x624.png" alt="" class="alignnone size-large wp-image-10236" width="1024" height="624" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1024x624.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-300x183.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-768x468.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-1536x936.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM-600x366.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.33.06-PM.png 2032w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But we can &#8220;decode 11&#8221; to try to figure it out.  You can see that it is advertising manufactures specific data with Apple&#8217;s UUID which I happen to know is 0x004C.  But why?  I don&#8217;t know.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/screen-shot-2020-11-14-at-12-37-51-pm/" rel="attachment wp-att-10237"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1024x807.jpg" alt="" class="alignnone size-large wp-image-10237" width="1024" height="807" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1024x807.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-300x236.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-768x605.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-1536x1210.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM-600x473.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-14-at-12.37.51-PM.jpg 1554w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I really want to move onto a new series of articles&#8230; but there are two functions which I will add to the program.  Stay tuned for what they do.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 6)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 30 Nov 2020 13:00:38 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10206</guid>

					<description><![CDATA[Summary In part 6 of this series I will update the AnyCloud BLE Advertising Scanner to decode advertising packets into a more human readable textual output Story We are now 6 (or maybe 7 depending on how you count) articles into this series and we are still looking at raw bytes.  I have gotten to [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In part 6 of this series I will update the AnyCloud BLE Advertising Scanner to decode advertising packets into a more human readable textual output</p>
<h1>Story</h1>
<p>We are now 6 (or maybe 7 depending on how you count) articles into this series and we are still looking at raw bytes.  I have gotten to where I am pretty good at understanding those bytes, but that is now way to roll.  You might remember from the <a href="https://iotexpert.com/anycloud-bluetooth-utilities-library/">article</a> on the IoT Expert Bluetooth Utility library that there were a some interesting functions defined in the header.  Here it is:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">wiced_bool_t btutil_isEddystone(uint8_t *data);
wiced_bool_t btutil_is_iBeacon(uint8_t *data);
wiced_bool_t btutil_isCypress(uint8_t *data);

int btutil_adv_len(uint8_t *packet);
void btutil_adv_printPacketDecode(uint8_t *packet);
void btutil_adv_printPacketBytes(uint8_t *packet);</pre>
<p>Lets transform our  project from part 6 to use these functions.  In this article I will</p>
<ul>
<li>Redo the print bytes (to be smarter) functionality and to use the built in function</li>
<li>Rework the logic for the &#8220;print&#8221; command implementation</li>
<li>Add a new command &#8220;decode&#8221; which will run the decode function</li>
</ul>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Replace two code blocks with function calls</h1>
<p>Do you remember this block of code?  It print&#8217;s out the 6-bytes of the Bluetooth Address.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    for(int i=0;i&lt;BD_ADDR_LEN;i++)
    {
        printf("%02X:",adb_database[entry].result-&gt;remote_bd_addr[i]);
    }
</pre>
<p>You might have noticed that this function already exists in the BT Utility Library.  Use it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    btutil_printBDaddress(adb_database[entry].result-&gt;remote_bd_addr);</pre>
<p>Then you remember this block of code which iterates through and advertising packet and prints out the raw bytes?</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">// Print the RAW Data of the ADV Packet
    printf(" Data: ");
    int i=0;
    while(adb_database[entry].data[i])
    {
        for(int j=0;j&lt;adb_database[entry].data[i];j++)
        {
            printf("%02X ",adb_database[entry].data[i+1+j]);
        }
        i = i + adb_database[entry].data[i]+1;
    }
</pre>
<p>Well, it exists in the library as well.  Use it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">btutil_adv_printPacketBytes(adb_database[entry].data);</pre>
<h1>Fix the &#8220;print&#8221; Command</h1>
<p>In the previous implementation I had two functions for &#8220;print&#8221;.  The first one printed one entry and the second one printed the whole table.  I decided that I didnt really like this logic, so I compressed those two functions into one function.  Specifically, it take a number &#8220;entry&#8221;.  If that number is -1 then it will print the whole table.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printRawPacket(int entry)
{
    int start,end;
 
    if(entry &lt;= -1)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {
    
        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        printf(" Data: ");
        btutil_adv_printPacketBytes(adb_database[i].data);

        printf("\n");
    }
}
</pre>
<h1>Add a new &#8220;decode&#8221; Command</h1>
<p>The next thing to do is to add a function to print out decoded packets (or the whole table).  So I wrote this:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_printDecodePacket(int entry)
{
    int start,end;
 
    if(entry == -1)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {

        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        printf("\n");
        btutil_adv_printPacketDecode(adb_database[i].data);
        printf("\n");
    }
}</pre>
<p>After finishing that block of code, I realized I had implemented almost exactly the same functionality which two different functions.  So, I decided to redo this by doing this.  Notice that it take in a adb_print_method, in other words raw bytes or decoded packet.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_PRINT_METHOD_BYTES,
    ADB_PRINT_METHOD_DECODE,
} adb_print_method_t;

static void adb_db_print(adb_print_method_t method,int entry)
{
    int start,end;
 
    if(entry &lt; 0)
    {
        start = 0;
        end = adb_db_count;
    }
    else
    {
        start = entry;
        end = entry;
    }

    if(end&gt;adb_db_count)
        end = adb_db_count; 

    for(int i=start;i&lt;=end;i++)
    {
    
        printf("%02d MAC: ",i);
        btutil_printBDaddress(adb_database[i].result-&gt;remote_bd_addr);
        switch(method)
        {
        
        case ADB_PRINT_METHOD_BYTES:
            printf(" Data: ");
            btutil_adv_printPacketBytes(adb_database[i].data);
        break;

        case ADB_PRINT_METHOD_DECODE:
            printf("\n");
            btutil_adv_printPacketDecode(adb_database[i].data);
        break;
        } 
        printf("\n");
    }
}
</pre>
<p>I don&#8217;t show it here, but after changing this I had to fix up the function calls in several places in the advDatabase.</p>
<h1>Add a new command to print decode packets</h1>
<p>Now that I have a new method to print packets, I add a command to the database to allow the user to call it:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT_RAW,
    ADB_PRINT_DECODE,
} adb_cmd_t;
</pre>
<p>Then in the queue loop:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">switch(msg.cmd)
            {
                case ADB_ADD:
                    scan_result = (wiced_bt_ble_scan_results_t *)msg.data0;
                    data = (uint8_t *)msg.data1;
                    adb_db_add(scan_result,data);
                break;
                case ADB_PRINT_RAW:
                    adb_db_print(ADB_PRINT_METHOD_BYTES,(int)msg.data0);
                break;
                case ADB_PRINT_DECODE:
                    adb_db_print(ADB_PRINT_METHOD_DECODE,(int)msg.data0);
                break;
            }</pre>
<p>Then the actual function</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_printDecode(int entry)
{
    adb_cmdMsg_t msg;
    msg.cmd = ADB_PRINT_DECODE;
    msg.data0 = (void *)entry;
    xQueueSend(adb_cmdQueue,&amp;msg,0); // If the queue is full... oh well
}</pre>
<p>Then add it to advDatabase.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_printDecode(int entry);
</pre>
<p>Finally to the usercmd.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_printDecode(int argc, char **argv)
{
    if(argc == 1)
    {
        adb_printDecode(-1);
    }

    if(argc == 2)
    {
        int val;
        sscanf(argv[1],"%d",&amp;val);
        adb_printDecode(val);
    }
    return 0;
}</pre>
<h1>Program and Test</h1>
<p>When I actually program the scanner you can see that I can print out 1 item.  OR I can decode one item.  Notice that one contains 3 fields</p>
<ul>
<li>flags</li>
<li>Tx Power Level</li>
<li>Manufacturers data.  Apparently an Apple something or the other</li>
</ul>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-53-43-am/" rel="attachment wp-att-10211"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-1024x219.png" alt="" class="alignnone size-large wp-image-10211" width="1024" height="219" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-1024x219.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-300x64.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-768x164.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM-600x128.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.53.43-AM.png 1358w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>And I can print the whole table</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-51-10-am/" rel="attachment wp-att-10213"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1024x629.jpg" alt="" class="alignnone size-large wp-image-10213" width="1024" height="629" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1024x629.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-300x184.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-768x472.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-1536x944.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-2048x1259.jpg 2048w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.10-AM-600x369.jpg 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Or decode the whole table.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/screen-shot-2020-11-09-at-7-51-33-am/" rel="attachment wp-att-10212"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1024x633.jpg" alt="" class="alignnone size-large wp-image-10212" width="1024" height="633" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1024x633.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-300x185.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-768x475.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-1536x949.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-2048x1266.jpg 2048w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-09-at-7.51.33-AM-600x371.jpg 600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 5)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 23 Nov 2020 18:03:57 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10196</guid>

					<description><![CDATA[Summary In this article I will add a new task to the AnyCloud BLE Advertising Scanning application which will save the advertising data into a database. Story There is still a boatload of mostly unintelligible advertising data coming ripping onto our screen.  It is FINALLY time to start fixing that.  In this article I will [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this article I will add a new task to the AnyCloud BLE Advertising Scanning application which will save the advertising data into a database.</p>
<h1>Story</h1>
<p>There is still a boatload of mostly unintelligible advertising data coming ripping onto our screen.  It is FINALLY time to start fixing that.  In this article I will create a new task called the advertising database task which will hold the history of advertising packets that I have seen.  I will update the Bluetooth Manager task to submit the advertising packets to a queue running in the advertising database task.</p>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Create an Advertising Data Database Task</h1>
<p>We need to create the file advertisingDatabase.h which will hold the task prototype (so that main can get going).</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

void adb_task(void *arg);
</pre>
<p>Then create the advertisingDatabase.c to hold the actual database code.  It will start with the definition of messages which can be sent to the task.  For now just &#8220;ADB_ADD&#8221;.  To make things a little bit simpler these command can have two data elements (which I call data0 and data1).  Then the main part of the task just</p>
<ol>
<li>Creates the queue to manage the messages</li>
<li>Process the message until the end of time</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "FreeRTOS.h"
#include "queue.h"

static QueueHandle_t adb_cmdQueue;
typedef enum {
    ADB_ADD,
} adb_cmd_t;

typedef struct
{
    adb_cmd_t cmd;
    void *data0;
    void *data1;
} adb_cmdMsg_t;

void adb_task(void *arg)
{
    // setup the queue
    adb_cmdMsg_t msg;

    adb_cmdQueue = xQueueCreate(10,sizeof(adb_cmdMsg_t));
    
    while(1)
    {
        BaseType_t status = xQueueReceive(adb_cmdQueue,&amp;msg,portMAX_DELAY);
        if(status == pdTRUE) 
        {
            switch(msg.cmd)
            {
                case ADB_ADD:
                break;
            }

        }
    }
}
</pre>
<p>To start the task, you need to add it to main.c.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    xTaskCreate(adb_task,"adv database",configMINIMAL_STACK_SIZE*4,0,1,0);
</pre>
<p>When I build and program this, you can now see the new task.  Good that working.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">AnyCloud&gt; Unhandled Bluetooth Management Event: BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT
Started BT Stack Succesfully

AnyCloud&gt; tasks
Name          State Priority   Stack  Num
------------------------------------------
usrcmd_ta       X       0       228     5
IDLE            R       0       115     7
Tmr Svc         B       0       223     8
CYBT_HCI_       B       5       950     3
sleep_tas       B       6       221     1
CYBT_BT_T       B       4       1371    2
blinkTask       B       0       98      4
adv datab       B       1       479     6
‘B’ – Blocked
‘R’ – Ready
‘D’ – Deleted (waiting clean up)
‘S’ – Suspended, or Blocked without a timeout
Stack = bytes free at highwater
AnyCloud&gt;</pre>
<h1>Update the Advertising Database to Accept Submitted ADV Packets</h1>
<p>If you recall our original setup was to take advertising packets in the Bluetooth Manager thread and print out the data.  The first thing that we want to fix up is the ability of the advertising database task to accept advertising packets which are pushed to its command queue.   To prepare for this I create two local variables to hold the data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_task(void *arg)
{
    // setup the queue
    adb_cmdMsg_t msg;
    wiced_bt_ble_scan_results_t *scan_result;
    uint8_t *data;</pre>
<p>Then I update the ADB_ADD command.  My first, and really simple fix, is to grab the printing code from the Bluetooth Manager task.  Obviously this won&#8217;t be an improvement from the original program as far as the users goes, but it will verify that the tasks are working properly together.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">                case ADB_ADD:
                    // Print the MAC Address
                    scan_result = (wiced_bt_ble_scan_results_t *)msg.data0;
                    data = (uint8_t *)msg.data1;

                    printf("MAC: ");
                    for(int i=0;i&lt;BD_ADDR_LEN;i++)
                    {
                        printf("%02X:",scan_result-&gt;remote_bd_addr[i]);
                    }
                    // Print the RAW Data of the ADV Packet
                    printf(" Data: ");
                    int i=0;
                    while(data[i])
                    {
                        for(int j=0;j&lt;data[i];j++)
                        {
                            printf("%02X ",data[i+1+j]);
                        }
                        i = i + data[i]+1;
                    }
                    printf("\n");
    
                    free(msg.data0);
                    free(msg.data1);
                break;
</pre>
<p>Then I add a command to the advertisingDatabase.h which the Bluetooth Manager task can call to submit advertising packets</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_addAdv(wiced_bt_ble_scan_results_t *scan_result,void *data);</pre>
<p>The actual command in advertisingDatabase.c just takes the advertising information, puts it in a command message, then submits it to the command queue.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void adb_addAdv(wiced_bt_ble_scan_results_t *scan_result,void *data)
{
    adb_cmdMsg_t msg;
    msg.cmd = ADB_ADD;
    msg.data0 = (void *)scan_result;
    msg.data1 = (void *)data;
    xQueueSend(adb_cmdQueue,&amp;msg,0); // If you loose an adv packet it is OK...
}
</pre>
<h1>Update the Bluetooth Manager to Submit Adv Packets</h1>
<p>Now I go and edit the bluetoothManager. c to submit packets rather than print them.  To do this I greatly simplify the callback.  There is one VERY important issue to deal with, which is one of those potential religious war issues.  Memory.</p>
<p>When you get the callback from the stack, it gives you POINTERS to data for the advertising packet that reside inside of buffers inside of the stack.  As soon as this callback returns this memory is purged.  To prevent this data from getting cleaned up by the stack I</p>
<ol>
<li>Malloc some memory for the wiced_bt_ble_scan_results</li>
<li>Malloc some memory for the advertising data</li>
<li>Make a copy of the data</li>
<li>Submit it to the Advertising Database</li>
</ol>
<p>I KNOW from the spec that the largest data packet is 31-bytes (actually it is 31-bytes + one more field with length 0).  So I know the maximum length is 32-bytes  This means that in many situations I will be copying GARBAGE into my buffer if the packet is less than 32 bytes long.  I think that this is simpler than calculating the length and then only copying that much data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void btm_advCallback(wiced_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data)
{
    wiced_bt_ble_scan_results_t *scan_result = malloc(sizeof(wiced_bt_ble_scan_results_t));
    uint8_t *data = malloc(32);
   
    memcpy(data,p_adv_data,32);
    memcpy(scan_result,p_scan_result-&gt;remote_bd_addr,BD_ADDR_LEN);
    adb_addAdv(scan_result,data);
}
</pre>
<p>When I run this updated program I should get the same stream of data coming out on the serial port.  Sure enough the new thread is working.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/screen-shot-2020-11-07-at-10-23-16-am/" rel="attachment wp-att-10198"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1024x577.png" alt="" width="1024" height="577" class="alignnone size-large wp-image-10198" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1024x577.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-300x169.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-768x433.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-1536x865.png 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM-600x338.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-07-at-10.23.16-AM.png 1868w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Create an Advertising Data Database</h1>
<p>Now, lets create an actual database.  To simplify things my database is just an array of structures.  One structure per bluetooth device.  The structure will contain a pointer to the information about the device it just saw and the actual raw data.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
    wiced_bt_ble_scan_results_t *result;
    uint8_t *data;
} adb_adv_t ;

#define ADB_MAX_SIZE (40)
adb_adv_t adb_database[ADB_MAX_SIZE];
int adb_db_count=0;
</pre>
<p>Then I will create several helper functions to work with the database</p>
<ol>
<li>Find devices in the database given a mac address</li>
<li>Print an entry in the database</li>
<li>Add entries to the database</li>
</ol>
<p>First, find an entry in the database.  This function will search through the database and compare the mac address against the mac address in the database.  When the memcmp ==0 meaning it found a match, it will return that entry.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int adb_db_find(wiced_bt_device_address_t *add)
{
    int rval=-1;
    for(int i=0;i&lt;adb_db_count;i++)
    {
        if(memcmp(add,&amp;adb_database[i].result-&gt;remote_bd_addr,BD_ADDR_LEN)==0)
        {
            rval = i;
            break;
        }
    }
    return rval;
}</pre>
<p>The print function will make sure that you asked for a legal entry (much must be greater than 0&#8230; and less than the max).  Then it will print out the mac address and the raw data.  In a future post I will add a smarter print out.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_printEntry(int entry)
{
    if(!(entry&gt;= 0 &amp;&amp; entry &lt;= adb_db_count))
    {
        printf("Illegal entry\n");
        return;
    }
    printf("%02d MAC: ",entry);

    for(int i=0;i&lt;BD_ADDR_LEN;i++)
    {
        printf("%02X:",adb_database[entry].result-&gt;remote_bd_addr[i]);
    }

    // Print the RAW Data of the ADV Packet
    printf(" Data: ");
    int i=0;
    while(adb_database[entry].data[i])
    {
        for(int j=0;j&lt;adb_database[entry].data[i];j++)
        {
            printf("%02X ",adb_database[entry].data[i+1+j]);
        }
        i = i + adb_database[entry].data[i]+1;
    }
    printf("\n");
}</pre>
<p>To add an entry to the database, first make sure that it isn&#8217;t already in the database.  Then when you are sure that it isn&#8217;t the database, you just add the pointers to your table.  You need to make sure and not go beyond the end of the table, and if you did, you will have effectively blown away the last entry in the table.  Oh well.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void adb_db_add(wiced_bt_ble_scan_results_t *scan_result,uint8_t *data)
{
 
    int entry = adb_db_find(&amp;scan_result-&gt;remote_bd_addr);
    if(entry == -1)
    {
        
        adb_database[adb_db_count].result = scan_result;
        adb_database[adb_db_count].data = data;
        adb_db_printEntry(adb_db_count);
        adb_db_count = adb_db_count + 1;
        if(adb_db_count == ADB_MAX_SIZE)
        {
            printf("ADV Table Max Size\n");
            adb_db_count = adb_db_count - 1;
        }
    }
    else
    {
        free(scan_result);
        free(data);
    }
}
</pre>
<h1>Add a Command to Print the Database</h1>
<p>Now we want to add the ability to print from the command line.  So add a new command message to the list of legal commands.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
    ADB_ADD,
    ADB_PRINT,
} adb_cmd_t;
</pre>
<p>Then create a new function to print.  If you send in a &#8220;-1&#8221; it will print the whole table.  Otherwise just print the individual entry.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static void adb_printTable(int entry)
{
    if(entry == -1)
    {
        for(int i=0;i&lt;adb_db_count;i++)
        {
            adb_db_printEntry(i);
        }

    }
    else
    {
        adb_db_printEntry(entry);
    }
    

}</pre>
<p>Now edit usercmd.c to have the new command line.  Notice that I use &#8220;sscanf&#8221; which obviously has some issues.  Too bad.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int usrcmd_print(int argc, char **argv)
{

    if(argc == 1)
    {
        adb_print(-1); // Print whole table
    }

    if(argc == 2)
    {
        int val;
        sscanf(argv[1],"%d",&amp;val);
        adb_print(val);
    }

    return 0;
}</pre>
<p>When I program the project it immediately prints out a bunch of devices that are at my house.  Then you can see I run the &#8220;print&#8221; command which prints the table.  Finally P do a print 0 to just print the first entry.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/screen-shot-2020-11-08-at-9-34-13-am/" rel="attachment wp-att-10201"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1024x782.jpg" alt="" width="1024" height="782" class="alignnone size-large wp-image-10201" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1024x782.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-300x229.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-768x587.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-1536x1173.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM-600x458.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-08-at-9.34.13-AM.jpg 1864w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In the next article I will add smarter diagnostics to the advertising packets.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Advertising Scanner (Part 4)</title>
		<link>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 16 Nov 2020 13:00:10 +0000</pubDate>
				<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[AnyCloud Advertising Scanner]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10185</guid>

					<description><![CDATA[Summary In this article I update the AnyCloud BLE advertising scanner to use the btutil library that was created in the previous post.  In addition, I add a command queue to the bluetoothManger and enable a new command to turn on and off scanning. Story If you have been following along until now, which I [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>In this article I update the AnyCloud BLE advertising scanner to use the btutil library that was created in the <a href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" target="_blank" rel="noopener noreferrer">previous post</a>.  In addition, I add a command queue to the bluetoothManger and enable a new command to turn on and off scanning.</p>
<h1>Story</h1>
<p>If you have been following along until now, which I imagine that you have if you are reading this,  you will have gotten a vomit of device data blasting out onto your serial console.  This isn&#8217;t very helpful.  So now what?  I am going to divide this problem into two parts</p>
<ol>
<li>Creating a new user command to turn on and off scanning (this article)</li>
<li>Creating a database to manage the data + a set of commands to dump it (next article)</li>
</ol>
<p>There are</p>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Article</th>
<th >Topic</th>
</tr>
</thead>
<tbody>
<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 1)</a></td>
<td >Introduction to AnyCloud Bluetooth Advertising</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-2/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 2)</a></td>
<td >Creating an AnyCloud Bluetooth project</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 3)</a></td>
<td >Adding Observing functionality to the project</td>
</tr>

<tr><td ><a class="row-title" href="https://iotexpert.com/anycloud-bluetooth-utilities-library/" aria-label="“AnyCloud Bluetooth Utilities Library” (Edit)" target="_blank" rel="noopener">AnyCloud Bluetooth Utilities Library</a></td>
<td >A set of APIs for enhancement of the AnyCloud Library</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 4)</a></td>
<td >Adding a command line to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-5/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 5)</a></td>
<td >Adding a history database to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-6/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 6)</a></td>
<td >Decoding advertising packets</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-7/" target="_blank" rel="noopener">AnyCloud Bluetooth Advertising Scanner (Part 7)</a></td>
<td >Adding recording commands to the command line</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-8/">AnyCloud Bluetooth Advertising Scanner (Part 8)</a></td>
<td >Adding filtering to the scanner</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-9/">AnyCloud Bluetooth Advertising Scanner (Part 9)</a></td>
<td >Improve the print and add packet age</td>
</tr>

<tr><td ><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-10/">AnyCloud Bluetooth Advertising Scanner (Part 10)</a></td>
<td >Sort the database</td>
</tr>
</tbody></table></div></p>
<p>All of the code can be found at git@github.com:iotexpert/AnyCloudBLEScanner.git and https://github.com/iotexpert/AnyCloudBLEScanner.git</p>
<p>There are git tags in place starting at part 5 so that you can look at just that version of the code.  "git tag" to list the tags.  And "git checkout part6" to look at the part 6 version of the code.</p>
<p>You can also create a new project with this is a template if you have the IoT Expert Manifest Files installed</p>
<h1>Add the IoT Expert &#8220;btutil&#8221; Library</h1>
<p>Before we actually start all of the command queue stuff, lets move to the btutil library that I talked about in the previous post.  To do this, add the library using the library manager.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/screen-shot-2020-11-02-at-1-50-08-pm/" rel="attachment wp-att-10187"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM-1024x197.png" alt="" width="1024" height="197" class="alignnone size-large wp-image-10187" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM-1024x197.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM-300x58.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM-768x148.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM-600x115.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-02-at-1.50.08-PM.png 1072w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Then delete bt_platform_cfg_settings.h and <span>bt_platform_cfg_settings.c from your project.  Finally </span>Rebuild and make sure that everything still works.  That is it.</p>
<h1>Multithreading</h1>
<p>Id like to explain that there is now some danger.  That danger comes from the fact that we have multiple tasks which are all accessing data plus functions that are talking to each other ASYNCHRONOUSLY.  Specifically we have:</p>
<ol>
<li>The Bluetooth Stack task &#8211; running the Bluetooth stack and management callback</li>
<li>The Bluetooth Stack APIs &#8211; e.g. wiced_bt_ble_observe</li>
<li>The usrcmd task &#8211; which is interacting with the user on the serial port and talking to the other tasks</li>
<li>A timer_svc task &#8211; which runs software timers</li>
<li>The advertising data (which I will start saving in the next article)</li>
</ol>
<p>When faced with this situation what I typically like to do is provide thread safe public functions for each of the tasks.  Then any other task can call these functions and know that things are not going to get corrupted by a race condition.</p>
<p>To make the design thread safe, I typically like to put an RTOS Queue between the tasks.  These queues are a safe place to send and receive data in a &#8220;thread safe&#8221; way.  There are two basic design patterns that can be used</p>
<ol>
<li>Define a message structure (that gets pushed into the queue) and make it global (via a dot-h).  Define a queue handle and make it global (via a dot-h).  Then let any task build messages and push them into the queue to be received in the task that owns the queue.</li>
<li>Define the message structure and queue.  Then define functions which are global (via a dot-h) which know how to interact with the queue.</li>
</ol>
<p>I typically think that the 2nd method is better, so that is what I am going to do here.</p>
<ol>
<li>In BluetoothManager.h I will provide a function called &#8220;btm_cmdScan&#8221;</li>
<li>The usrcmd task will call the btm_cmdScan function which will</li>
<li>Create a btm_cmdMsg_t with the &#8220;scan&#8221; command and data of true/false</li>
<li>Then push it into the Bluetooth Manager Command Queue</li>
<li>Where a timer callback in the Bluetooth Manager Task will take it out of the queue</li>
<li>Figure out that it is a &#8220;scan&#8221; command</li>
<li>Then will either turn on or off scanning</li>
</ol>
<p><a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/cmdmsg/" rel="attachment wp-att-10194"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg-1024x140.png" alt="" width="1024" height="140" class="alignnone size-large wp-image-10194" srcset="https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg-1024x140.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg-300x41.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg-768x105.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg-600x82.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/cmdMsg.png 1182w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Add a Queue to the Bluetooth Manager Thread</h1>
<p>So we need two things a message to push into a queue (just a structure) and we need a queue to push it into.  First the message which is just a structure with two elements.  The first element is a command and the second element is some data of type void.  The meaning of the void *data will be different based on the command.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct {
	btm_cmd_t cmd;
	void *data;
} btm_cmdMsg_t;</pre>
<p>But how about the command?  The command is just an enumerate list of commands which will now start with just one command.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef enum {
	BTM_SCAN,
} btm_cmd_t;
</pre>
<p>And know we need to define the queue.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "queue.h"
static QueueHandle_t btm_cmdQueue;</pre>
<p>Before you can use the queue you need to initialize it.  The best place to initialize this queue is in the management callback right after the stack gets going.  You can see that I tell FreeRTOS that there is a queue which can hold up to 10 commands.  I also tell it that each command is the sizeof the command message.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    switch (event)
    {
        case BTM_ENABLED_EVT:
            printf("Started BT Stack Succesfully\n");
            btm_cmdQueue = xQueueCreate(10,sizeof(btm_cmdMsg_t));</pre>
<p>Now we need to create a way for other tasks to create these command messages.  They will do this by calling a function which we will define in the bluetoothManager.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void btm_cmdScan(bool enable);
</pre>
<p>This function will live in bluetoothManager.c and it simply</p>
<ol>
<li>Creates a command</li>
<li>Set the actual command to scan</li>
<li>Sets the void* data to be enable &#8230; in other words start or stop scanning.  Remember that a void * can be anything.  See I cast a bool to a void *</li>
<li>Finally push the data into the command queue</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">void btm_cmdScan(bool enable)
{
    btm_cmdMsg_t msg;
    msg.cmd = BTM_SCAN;
    msg.data = (void *)enable;
  	xQueueSend(btm_cmdQueue, &amp;msg,0);
}</pre>
<h1>Add a Timer to Process the Queue</h1>
<p>So now we have a method to push items into the queue.  How do we get them out of the queue?  To do that I will use a Bluetooth Stack timer that will run every 50ms.</p>
<p>First, define the timer in bluetoothManager.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "wiced_timer.h"
static wiced_timer_ext_t btm_mgmtQueueTimer;
</pre>
<p>Then define a function which the timer will call.  This function will</p>
<ol>
<li>Try to get a message out of the queue</li>
<li>IF there is a message it will use a big switch to look at the possible messages</li>
<li>If the message is a scan</li>
<li>Then call the wiced function to either start &#8220;observing&#8221; or stop &#8220;observing&#8221;</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static void btm_processBluetoothAppQueue()
{
	btm_cmdMsg_t msg;

	 BaseType_t rval;

	 rval = xQueueReceive( btm_cmdQueue,&amp;msg,0);
	 if(rval == pdTRUE)
	 {
		 switch(msg.cmd)
		 {
		 case BTM_SCAN:
            wiced_bt_ble_observe((wiced_bool_t)msg.data,0,btm_advCallback);
			 break;
		 }
	 }
}</pre>
<p>The last thing you need to do is start the timer.  The best place to start the timer is in the management callback where you need to</p>
<ol>
<li>Create the timer</li>
<li>Tell it to start and run every 50ms</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    switch (event)
    {
        case BTM_ENABLED_EVT:
            printf("Started BT Stack Succesfully\n");
            btm_cmdQueue = xQueueCreate(10,sizeof(btm_cmdMsg_t));
            wiced_init_timer_ext (&amp;btm_mgmtQueueTimer, btm_processBluetoothAppQueue,0, WICED_TRUE);
            wiced_start_timer_ext (&amp;btm_mgmtQueueTimer, 50);
        break;</pre>
<h1>A Potential Threading Bug</h1>
<p>When I did the implementation originally I created what I thought was a threading bug.  Specifically I used the FreeRTOS timer to process the queue.  In other words instead of using a wiced_timer_ext_t I used a TimerHandle_t.  So what?</p>
<p>The wiced_timer_ext_t is run INSIDE of the BluetoothStack task where the TimerHandle_t is run inside of the Timer_SVC task.</p>
<p>So what?  I was afraid that the call to wiced_bt_ble_obsere was NOT thread safe and needed to be called inside of the same task as the stack.</p>
<p>After some digging I found out that the Bluetooth Stack is threadsafe, so I worried for no reason.  Well, actually, you can never worry enough about making these kinds of threading bugs because they are viscously difficult to debug.</p>
<h1>Add a Scan Off &amp; On Command</h1>
<p>The last thing that you need to do is add an actual command to the usercmd task to call the bluetooth manager function to turn on and off scanning.</p>
<p>First, add a new prototype for your new command in usercmd.c.  Then add it to the list of legal commands.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_scan(int argc, char **argv);


static const cmd_table_t cmdlist[] = {

.... deleted stuff

    { "scan","scan [on|off]", usrcmd_scan},

};
</pre>
<p>Then create the function to process the command line input and call the btm_scan function.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_scan(int argc, char **argv)
{

    if(argc != 2)
        return 0;

    if(strcmp(argv[1],"on") == 0)
    {
        btm_cmdScan(true);
    }
    else if(strcmp(argv[1],"off") == 0)
    {
        btm_cmdScan(false);

    }
    return 0;

}</pre>
<p>Now build it and run it.  You should still get adv packets barfing all over your screen.  But now you can turn on and off the scanning with &#8220;scan on&#8221; and &#8220;scan off&#8221;.  In the next article we will create a database to hold the scan packets.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-4/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud Bluetooth Utilities Library</title>
		<link>https://iotexpert.com/anycloud-bluetooth-utilities-library/</link>
					<comments>https://iotexpert.com/anycloud-bluetooth-utilities-library/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 09 Nov 2020 13:18:17 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CKIT-062-BLE]]></category>
		<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=10175</guid>

					<description><![CDATA[Summary This article is a discussion of a library of utilities functions that support AnyCloud Bluetooth development.  It includes settings to configure the hardware, functions to decode stack events, functions to decode advertising packets etc. Story The Cypress, now Infineon, Modus Toolbox team has been working to bring the WICED Bluetooth devices to be closer [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This article is a discussion of a library of utilities functions that support AnyCloud Bluetooth development.  It includes settings to configure the hardware, functions to decode stack events, functions to decode advertising packets etc.</p>
<h1>Story</h1>
<p>The Cypress, now Infineon, Modus Toolbox team has been working to bring the WICED Bluetooth devices to be closer and more compatible with the PSoC 6 tools.  One of the important enablement things we have done is turn on the WICED Bluetooth Host stack on the PSoC 6 so that it can effectively talk to the CYW43XXX Bluetooth / WiFi combo chips.</p>
<p>As I have been using all of the new stuff I found myself adding my own custom functionality&#8230;. and after a while I realized (finally) that I should put all of those little helper things into a library, specifically an IoT Expert library.  For now this library contains:</p>
<ul>
<li>The Bluetooth Platform Configuration Settings</li>
<li>Functions to decode stack events</li>
<li>Functions to decode advertising packets</li>
</ul>
<p>but imagine with time I will add more functions and templates.</p>
<h1><span>bt_platform_cfg_settings</span></h1>
<p>As I discussed in the article <a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-1/" target="_blank" rel="noopener noreferrer">AnyCloud Bluetooth Advertising Scanner (Part 1)</a>, every single AnyCloud BLE Stack project will require a structure of type wiced_bt_cfg_settings_t.  This structure is used to setup the hardware before getting the stack going.  Remember you need to make a call like this to initialize the Bluetooth hardware.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">    cybt_platform_config_init(&amp;bt_platform_cfg_settings);
</pre>
<p>At some point this file will be included automatically for you by the Modus Toolbox team, but for now I have added this to my library.  This file look like this.  Basically a bunch of pin definitions which are set for you automatically by the BSP.  Obviously you can make your own, but this should work on all of the Cypress development kits (I think)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include "cybt_platform_config.h"
#include "cybsp.h"
#include "wiced_bt_stack.h"

const cybt_platform_config_t bt_platform_cfg_settings =
{
    .hci_config =
    {
        .hci_transport = CYBT_HCI_UART,

        .hci =
        {
            .hci_uart =
            {
                .uart_tx_pin = CYBSP_BT_UART_TX,
                .uart_rx_pin = CYBSP_BT_UART_RX,
                .uart_rts_pin = CYBSP_BT_UART_RTS,
                .uart_cts_pin = CYBSP_BT_UART_CTS,

                .baud_rate_for_fw_download = 115200,
                .baud_rate_for_feature     = 115200,

                .data_bits = 8,
                .stop_bits = 1,
                .parity = CYHAL_UART_PARITY_NONE,
                .flow_control = WICED_TRUE
            }
        }
    },

    .controller_config =
    {
        .bt_power_pin      = CYBSP_BT_POWER,
        .sleep_mode =
        {
            #if (bt_0_power_0_ENABLED == 1) /* BT Power control is enabled in the LPA */
            #if (CYCFG_BT_LP_ENABLED == 1) /* Low power is enabled in the LPA, use the LPA configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYCFG_BT_DEV_WAKE_GPIO,
            .host_wakeup_pin = CYCFG_BT_HOST_WAKE_GPIO,
            .device_wake_polarity = CYCFG_BT_DEV_WAKE_POLARITY,
            .host_wake_polarity = CYCFG_BT_HOST_WAKE_IRQ_EVENT
            #else /* Low power is disabled in the LPA, disable low power */
            .sleep_mode_enabled = false
            #endif
            #else /* BT Power control is disabled in the LPA – default to BSP low power configuration */
            .sleep_mode_enabled = true,
            .device_wakeup_pin = CYBSP_BT_DEVICE_WAKE,
            .host_wakeup_pin = CYBSP_BT_HOST_WAKE,
            .device_wake_polarity = CYBT_WAKE_ACTIVE_LOW,
            .host_wake_polarity = CYBT_WAKE_ACTIVE_LOW
            #endif
        }
    },

    .task_mem_pool_size    = 2048
};</pre>
<h1><span>btutil_stack</span></h1>
<p>When you startup the Bluetooth Host stack you are responsible for providing a &#8220;management callback&#8221; which has the function prototype</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef wiced_result_t (wiced_bt_management_cback_t) (wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data);
</pre>
<p>The first parameter is an &#8220;event&#8221; which is  just an enumerated list of possible events by the Bluetooth Host Stack.  Here is the actual list.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">enum wiced_bt_management_evt_e {
    /* Bluetooth status events */
    BTM_ENABLED_EVT,                                /**&lt; Bluetooth controller and host stack enabled. Event data: wiced_bt_dev_enabled_t */
    BTM_DISABLED_EVT,                               /**&lt; Bluetooth controller and host stack disabled. Event data: NULL */
    BTM_POWER_MANAGEMENT_STATUS_EVT,                /**&lt; Power management status change. Event data: wiced_bt_power_mgmt_notification_t */
    BTM_RE_START_EVT,                               /**&lt; Bluetooth controller and host stack re-enabled. Event data: tBTM_ENABLED_EVT */
    /* Security events */
    BTM_PIN_REQUEST_EVT,                            /**&lt; PIN request (used only with legacy devices). Event data: #wiced_bt_dev_name_and_class_t */
    BTM_USER_CONFIRMATION_REQUEST_EVT,              /**&lt; received USER_CONFIRMATION_REQUEST event (respond using #wiced_bt_dev_confirm_req_reply). Event data: #wiced_bt_dev_user_cfm_req_t */
    BTM_PASSKEY_NOTIFICATION_EVT,                   /**&lt; received USER_PASSKEY_NOTIFY event. Event data: #wiced_bt_dev_user_key_notif_t */
    BTM_PASSKEY_REQUEST_EVT,                        /**&lt; received USER_PASSKEY_REQUEST event @cond DUAL_MODE (respond using #wiced_bt_dev_pass_key_req_reply). Event data: #wiced_bt_dev_user_key_req_t @endcond
                                                     @note  BR/EDR Only */
    BTM_KEYPRESS_NOTIFICATION_EVT,                  /**&lt; received KEYPRESS_NOTIFY event. Event data: #wiced_bt_dev_user_keypress_t */
    BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT, /**&lt; Requesting IO capabilities for BR/EDR pairing. Event data: #wiced_bt_dev_bredr_io_caps_req_t 
                                                        @note  BR/EDR Only */
    BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT,/**&lt; Received IO capabilities response for BR/EDR pairing. Event data: @cond DUAL_MODE #wiced_bt_dev_bredr_io_caps_rsp_t @endcond
                                                        @note  BR/EDR Only*/
    BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT,    /**&lt; Requesting IO capabilities for BLE pairing. Slave can check peer io capabilities in event data before updating with local io capabilities. Event data: #wiced_bt_dev_ble_io_caps_req_t */
    BTM_PAIRING_COMPLETE_EVT,                       /**&lt; received SIMPLE_PAIRING_COMPLETE event. Event data: #wiced_bt_dev_pairing_cplt_t */
    BTM_ENCRYPTION_STATUS_EVT,                      /**&lt; Encryption status change. Event data: #wiced_bt_dev_encryption_status_t */
    BTM_SECURITY_REQUEST_EVT,                       /**&lt; Security request (respond using #wiced_bt_ble_security_grant). Event data: #wiced_bt_dev_security_request_t */
    BTM_SECURITY_FAILED_EVT,                        /**&lt; Security procedure/authentication failed. Event data: #wiced_bt_dev_security_failed_t */
    BTM_SECURITY_ABORTED_EVT,                       /**&lt; Security procedure aborted locally, or unexpected link drop. Event data: #wiced_bt_dev_name_and_class_t */

    BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT,           /**&lt; Result of reading local OOB data @cond DUAL_MODE (#wiced_bt_dev_read_local_oob_data). Event data: #wiced_bt_dev_local_oob_t @endcond 
                                                        @note  BR/EDR Only */

    BTM_REMOTE_OOB_DATA_REQUEST_EVT,                /**&lt; OOB data from remote device @cond DUAL_MODE (respond using #wiced_bt_dev_remote_oob_data_reply). Event data: #wiced_bt_dev_remote_oob_t @endcond 
                                                        @note  BR/EDR Only */

    BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT,         /**&lt; Updated remote device link keys (store device_link_keys to  NV memory). This is the place to
verify that the correct link key has been generated. Event data: #wiced_bt_device_link_keys_t */
    BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT,        /**&lt; Request for stored remote device link keys (restore device_link_keys from NV memory). If successful, return WICED_BT_SUCCESS. Event data: #wiced_bt_device_link_keys_t */

    BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT,             /**&lt; Update local identity key (stored local_identity_keys NV memory). Event data: #wiced_bt_local_identity_keys_t */
    BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT,            /**&lt; Request local identity key (get local_identity_keys from NV memory). If successful, return WICED_BT_SUCCESS. Event data: #wiced_bt_local_identity_keys_t */

    BTM_BLE_SCAN_STATE_CHANGED_EVT,                 /**&lt; BLE scan state change. Event data: #wiced_bt_ble_scan_type_t */
    BTM_BLE_ADVERT_STATE_CHANGED_EVT,               /**&lt; BLE advertisement state change. Event data: #wiced_bt_ble_advert_mode_t */

    /* BLE Secure Connection events */
    BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT,            /**&lt; SMP remote oob data request. Reply using wiced_bt_smp_oob_data_reply. Event data: #wiced_bt_smp_remote_oob_req_t  */
    BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT,         /**&lt; LE secure connection remote oob data request. Reply using wiced_bt_smp_sc_oob_reply. Event data: #wiced_bt_smp_sc_remote_oob_req_t 
                                                        @note  BR/EDR Only */
    BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT,     /**&lt; LE secure connection local OOB data (wiced_bt_smp_create_local_sc_oob_data). Event data: #wiced_bt_smp_sc_local_oob_t */

    BTM_SCO_CONNECTED_EVT,                          /**&lt; SCO connected event. Event data: @cond DUAL_MODE #wiced_bt_sco_connected_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_DISCONNECTED_EVT,                       /**&lt; SCO disconnected event. Event data: @cond #wiced_bt_sco_disconnected_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_CONNECTION_REQUEST_EVT,                 /**&lt; SCO connection request event. Event data: @cond #wiced_bt_sco_connection_request_t @endcond
                                                        @note  BR/EDR Only */
    BTM_SCO_CONNECTION_CHANGE_EVT,                  /**&lt; SCO connection change event. Event data: @cond #wiced_bt_sco_connection_change_t @endcond
                                                        @note  BR/EDR Only */
    BTM_BLE_CONNECTION_PARAM_UPDATE,                /**&lt; BLE connection parameter update. Event data: #wiced_bt_ble_connection_param_update_t */
    BTM_BLE_PHY_UPDATE_EVT,                         /**&lt; BLE Physical link update. Event data: wiced_bt_ble_phy_update_t */
    BTM_LPM_STATE_LOW_POWER,                        /**&lt; BT device wake has been deasserted. Used for Host Stack Use Case. */
    BTM_MULTI_ADVERT_RESP_EVENT,                    /**&lt; Multi adv command status event Used for the status of the command sent */
#if SMP_CATB_CONFORMANCE_TESTER == TRUE
    BTM_SMP_SC_PEER_INFO_EVT                        /** The Secure Connections support information of the peer device */
#endif

};</pre>
<p>While you are trying to figure out what is going on during the development, it is very useful to be able to print out the name of the events (instead of the numbers).  In other words instead of doing</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">printf("Event = %02X\n",event);</pre>
<p>it is way better to do</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">printf("Event Name=%s\n",btutil_getBTEventName(event));</pre>
<p>While I was looking at an example project I found this function which I thought was awesome.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">const char *btutil_getBTEventName(wiced_bt_management_evt_t event)
{
    switch ( (int)event )
    {
    CASE_RETURN_STR(BTM_ENABLED_EVT)
    CASE_RETURN_STR(BTM_DISABLED_EVT)
    CASE_RETURN_STR(BTM_POWER_MANAGEMENT_STATUS_EVT)
    CASE_RETURN_STR(BTM_PIN_REQUEST_EVT)
    CASE_RETURN_STR(BTM_USER_CONFIRMATION_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PASSKEY_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_PASSKEY_REQUEST_EVT)
    CASE_RETURN_STR(BTM_KEYPRESS_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT)
    CASE_RETURN_STR(BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRING_COMPLETE_EVT)
    CASE_RETURN_STR(BTM_ENCRYPTION_STATUS_EVT)
    CASE_RETURN_STR(BTM_SECURITY_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SECURITY_FAILED_EVT)
    CASE_RETURN_STR(BTM_SECURITY_ABORTED_EVT)
    CASE_RETURN_STR(BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT)
    CASE_RETURN_STR(BTM_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT)
    CASE_RETURN_STR(BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT)
    CASE_RETURN_STR(BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT)
    CASE_RETURN_STR(BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT)
    CASE_RETURN_STR(BTM_BLE_SCAN_STATE_CHANGED_EVT)
    CASE_RETURN_STR(BTM_BLE_ADVERT_STATE_CHANGED_EVT)
    CASE_RETURN_STR(BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTED_EVT)
    CASE_RETURN_STR(BTM_SCO_DISCONNECTED_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTION_REQUEST_EVT)
    CASE_RETURN_STR(BTM_SCO_CONNECTION_CHANGE_EVT)
    CASE_RETURN_STR(BTM_BLE_CONNECTION_PARAM_UPDATE)
#ifdef CYW20819A1
    CASE_RETURN_STR(BTM_BLE_PHY_UPDATE_EVT)
#endif
    }

    return NULL;
}</pre>
<p>And then I learned something new when I looked at the &#8220;function&#8221; CASE_RETURN_STR which used compiler trick to turn an enumerated value into a string.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define CASE_RETURN_STR(enum_val)          case enum_val: return #enum_val;</pre>
<p>This allows you to do this in your management callback (notice line 16 where the string is printed out)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">wiced_result_t app_bt_management_callback(wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data)
{
    wiced_result_t result = WICED_BT_SUCCESS;

    switch (event)
    {
        case BTM_ENABLED_EVT:
            if (WICED_BT_SUCCESS == p_event_data-&gt;enabled.status)
            {
                printf("Started BT Stack Succesfully\n");
                wiced_bt_ble_observe(WICED_TRUE,0,obv_callback);
            }
            break;

        default:
            printf("Unhandled Bluetooth Management Event: %s\n", btutil_getBTEventName(event));
            break;
    }

    return result;
}</pre>
<p>It turns out that there are several other places where the stack gives you an event-ish thing.  So these functions were created as well</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

const char *btutil_getBTEventName(wiced_bt_management_evt_t event);
const char *btutil_getBLEAdvertModeName(wiced_bt_ble_advert_mode_t mode);
const char *btutil_getBLEGattDisconnReasonName(wiced_bt_gatt_disconn_reason_t reason);
const char *btutil_getBLEGattStatusName(wiced_bt_gatt_status_t status);</pre>
<h1><span>btutil_adv_decode</span></h1>
<p>In <a href="https://iotexpert.com/anycloud-bluetooth-advertising-scanner-part-3/" target="_blank" rel="noopener noreferrer">AnyCloud Bluetooth Advertising Scanner (Part 3)</a> I discussed the format of the advertising packet.  So I created functions which will decode the data in the advertising packets.  More on the future article AnyCloud Bluetooth Advertising Scanner (Part 4 or maybe 5 or maybe 6).  Here are the functions:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

wiced_bool_t btutil_isEddystone(uint8_t *data);
wiced_bool_t btutil_is_iBeacon(uint8_t *data);
wiced_bool_t btutil_isCypress(uint8_t *data);

int btutil_adv_len(uint8_t *packet);
void btutil_adv_printPacketDecode(uint8_t *packet);
void btutil_adv_printPacketBytes(uint8_t *packet);</pre>
<h1>btutil</h1>
<p>And because I like to have just one include to get access to all of the function I created &#8220;btutil.h&#8221; which just includes all of the headers in one place.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#pragma once

#include "btutil_adv_decode.h"
#include "btutil_stack.h"
#include "btutil_general.h"
#include "bt_platform_cfg_settings.h"
</pre>
<h1>Add to the IoT Expert Manifest</h1>
<p>In order to set it up for my library to live in the library manager I updated the IoT Expert Manifest file to have a link to the GitHub repository</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">&lt;middleware&gt;
  
    &lt;name&gt;Bluetooth Utilities&lt;/name&gt;
    &lt;id&gt;btutil&lt;/id&gt;
    &lt;uri&gt;https://github.com/iotexpert/btutil&lt;/uri&gt;
    &lt;desc&gt;A library of Bluetooth Debugging Utilties for Cypress PSoC6 Anycloud&lt;/desc&gt;
    &lt;category&gt;IoT Expert&lt;/category&gt;
    &lt;req_capabilities&gt;psoc6&lt;/req_capabilities&gt;
    &lt;versions&gt;
      &lt;version flow_version="1.0,2.0"&gt;
        &lt;num&gt;master&lt;/num&gt;
        &lt;commit&gt;master&lt;/commit&gt;
        &lt;desc&gt;master&lt;/desc&gt;
      &lt;/version&gt;
    &lt;/versions&gt;
  &lt;/middleware&gt;
</pre>
<p>And now the library manager has the IoT Expert Bluetooth Utilities.</p>
<p><a href="https://iotexpert.com/anycloud-bluetooth-utilities-library/screen-shot-2020-11-01-at-10-43-31-am/" rel="attachment wp-att-10180"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-1024x815.png" alt="" class="alignnone size-large wp-image-10180" width="1024" height="815" srcset="https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-1024x815.png 1024w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-300x239.png 300w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-768x611.png 768w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM-600x477.png 600w, https://iotexpert.com/wp-content/uploads/2020/11/Screen-Shot-2020-11-01-at-10.43.31-AM.png 1116w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1></h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-bluetooth-utilities-library/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud &#8211; Wireless Connection Manager (Part 2)</title>
		<link>https://iotexpert.com/anycloud-wireless-connection-manager-part-2/</link>
					<comments>https://iotexpert.com/anycloud-wireless-connection-manager-part-2/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 11 May 2020 12:53:12 +0000</pubDate>
				<category><![CDATA[CY8CKIT-062-WiFi-BT]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9041</guid>

					<description><![CDATA[Summary Part 2 of the discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>Part 2 of the discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use with PSoC6 and 43xxx WiFi combos.</p>
<h1>The Story</h1>
<p>In the last article I walked you through creating a project using the wireless connection manager (WCM) which is one of the libraries that is part of the Infineon/Cypress AnyCloud SDK.  I introduced the wifi-mw-core, wifi-connection-manager and ntshell libraries.  In this article I will update the program to include commands to</p>
<ul>
<li>connect (to an Access Point)</li>
<li>disconnect (from an Access Point)</li>
<li>print (mac address and ip address)</li>
</ul>
<h1>Add the Connect</h1>
<p>I want to add a command that will let me issue a command line like</p>
<ul>
<li>connect SSID (if it doesn&#8217;t have a passphrase)</li>
<li>connect SSID passphrase</li>
</ul>
<p>In order to connect to an Access Point you need to call the WCM API, cy_wcm_connect_ap.  Here is the function prototype:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">cy_rslt_t cy_wcm_connect_ap(const cy_wcm_connect_params_t *connect_params, cy_wcm_ip_address_t *ip_addr)</pre>
<p>This function requires that you give it two arguments</p>
<ol>
<li>A pointer for a place to store the IP address (that comes from the DHCP server)</li>
<li>A pointer to a structure of connection parameters.  That structure is as follows:</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct
{
    cy_wcm_ap_credentials_t  ap_credentials;       /**&lt; Access point credentials */
    cy_wcm_mac_t             BSSID;                /**&lt; Specifies the MAC address of Access Point (optional) */
    cy_wcm_ip_setting_t      *static_ip_settings;  /**&lt; Specifies the static IP settings of the device (optional) */
    cy_wcm_wifi_band_t       band;                 /**&lt; Specifies the Radio band to be connected (optional) */
} cy_wcm_connect_params_t;</pre>
<p>Typically you would setup the &#8220;ap_credentials&#8221; part of the structure (unless you happen to know the MAC address of the AP you want to connect to).  Those credentials include the SSID and password as well as the security (WPA2 PSK etc&#8230;)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct
{
    cy_wcm_ssid_t        SSID;                /**&lt; SSID of the Wi-Fi network to join, SSID should be a null terminated string. */
    cy_wcm_passphrase_t  password;            /**&lt; Password needed to join the AP, password should be a null terminated string. */
    cy_wcm_security_t    security;            /**&lt; Wi-Fi Security. @see cy_wcm_security_t. */
} cy_wcm_ap_credentials_t;</pre>
<p>Security is an enumeration of possible security types.</p>
<pre class="start-line:181 EnlighterJSRAW" data-enlighter-language="c" ">typedef enum
{
    WHD_SECURITY_OPEN             = 0,                                                                 /**&lt; Open security                                         */
    WHD_SECURITY_WEP_PSK          = WEP_ENABLED,                                                       /**&lt; WEP PSK Security with open authentication             */
    WHD_SECURITY_WEP_SHARED       = (WEP_ENABLED | SHARED_ENABLED),                                    /**&lt; WEP PSK Security with shared authentication           */
    WHD_SECURITY_WPA_TKIP_PSK     = (WPA_SECURITY | TKIP_ENABLED),                                     /**&lt; WPA PSK Security with TKIP                            */
    WHD_SECURITY_WPA_AES_PSK      = (WPA_SECURITY | AES_ENABLED),                                      /**&lt; WPA PSK Security with AES                             */
    WHD_SECURITY_WPA_MIXED_PSK    = (WPA_SECURITY | AES_ENABLED | TKIP_ENABLED),                       /**&lt; WPA PSK Security with AES &amp; TKIP                      */
    WHD_SECURITY_WPA2_AES_PSK     = (WPA2_SECURITY | AES_ENABLED),                                     /**&lt; WPA2 PSK Security with AES                            */
    WHD_SECURITY_WPA2_TKIP_PSK    = (WPA2_SECURITY | TKIP_ENABLED),                                    /**&lt; WPA2 PSK Security with TKIP                           */
    WHD_SECURITY_WPA2_MIXED_PSK   = (WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED),                      /**&lt; WPA2 PSK Security with AES &amp; TKIP                     */
    WHD_SECURITY_WPA2_FBT_PSK     = (WPA2_SECURITY | AES_ENABLED | FBT_ENABLED),                       /**&lt; WPA2 FBT PSK Security with AES &amp; TKIP */
    WHD_SECURITY_WPA3_SAE         = (WPA3_SECURITY | AES_ENABLED),                                     /**&lt; WPA3 Security with AES */
    WHD_SECURITY_WPA3_WPA2_PSK    = (WPA3_SECURITY | WPA2_SECURITY | AES_ENABLED),                     /**&lt; WPA3 WPA2 PSK Security with AES */

    WHD_SECURITY_WPA_TKIP_ENT     = (ENTERPRISE_ENABLED | WPA_SECURITY | TKIP_ENABLED),                /**&lt; WPA Enterprise Security with TKIP                     */
    WHD_SECURITY_WPA_AES_ENT      = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED),                 /**&lt; WPA Enterprise Security with AES                      */
    WHD_SECURITY_WPA_MIXED_ENT    = (ENTERPRISE_ENABLED | WPA_SECURITY | AES_ENABLED | TKIP_ENABLED),  /**&lt; WPA Enterprise Security with AES &amp; TKIP               */
    WHD_SECURITY_WPA2_TKIP_ENT    = (ENTERPRISE_ENABLED | WPA2_SECURITY | TKIP_ENABLED),               /**&lt; WPA2 Enterprise Security with TKIP                    */
    WHD_SECURITY_WPA2_AES_ENT     = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED),                /**&lt; WPA2 Enterprise Security with AES                     */
    WHD_SECURITY_WPA2_MIXED_ENT   = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED), /**&lt; WPA2 Enterprise Security with AES &amp; TKIP              */
    WHD_SECURITY_WPA2_FBT_ENT     = (ENTERPRISE_ENABLED | WPA2_SECURITY | AES_ENABLED | FBT_ENABLED),  /**&lt; WPA2 Enterprise Security with AES &amp; FBT               */

    WHD_SECURITY_IBSS_OPEN        = (IBSS_ENABLED),                                                    /**&lt; Open security on IBSS ad-hoc network                  */
    WHD_SECURITY_WPS_SECURE       = AES_ENABLED,                                                       /**&lt; WPS with AES security                                 */

    WHD_SECURITY_UNKNOWN          = -1,                                                                /**&lt; May be returned by scan function if security is unknown. Do not pass this to the join function! */

    WHD_SECURITY_FORCE_32_BIT     = 0x7fffffff                                                         /**&lt; Exists only to force whd_security_t type to 32 bits */
} whd_security_t;</pre>
<p>Having to know the security of the AP is a total pain in the neck.  Where do you find the security from?  It turns out that when an AP beacons, the security of that SSID is one of the things that is broadcast.  What this means is that my program will need to</p>
<ol>
<li>When the connect command is called it should scan for the SSID that is part of the connect command &amp; wait</li>
<li>When the scan finds that SSID it will put the security type into the correct datastructure</li>
<li>Then call the connect.</li>
</ol>
<p>The way that I will do this is to</p>
<ol>
<li>Build a filter (that looks only for the user specified SSID)</li>
<li>Provides a pointer for a place to store the security type.</li>
</ol>
<p>I use the cy_wcm_scan function to do this.  Here is the function prototype:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">cy_rslt_t cy_wcm_start_scan(cy_wcm_scan_result_callback_t callback, void *user_data, cy_wcm_scan_filter_t *scan_filter)</pre>
<p>The scan filter is just a structure that specified</p>
<ol>
<li>A mode (which type of filter you want)</li>
<li>The specific thing that you are looking for.</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef struct
{
    cy_wcm_scan_filter_type_t      mode;        /**&lt; Scan filter mode */
    union
    {
        cy_wcm_ssid_t              SSID;        /**&lt; Service Set Identification */
        cy_wcm_mac_t               BSSID;       /**&lt; MAC address of Access Point */
        cy_wcm_wifi_band_t         band;        /**&lt; Radio band */
        cy_wcm_scan_rssi_range_t   rssi_range;  /**&lt; RSSI range */
    } param;                                    /**&lt; Scan filter mode specific paramter */
} cy_wcm_scan_filter_t;</pre>
<p>The mode is simply an enumeration of the types of filters:</p>
<pre class="start-line:331 EnlighterJSRAW" data-enlighter-language="c"">typedef enum
{
   CY_WCM_SCAN_FILTER_TYPE_SSID = 0,   /**&lt; Denotes SSID based scan filtering */
   CY_WCM_SCAN_FILTER_TYPE_MAC,        /**&lt; Denotes MAC  based scan filtering */
   CY_WCM_SCAN_FILTER_TYPE_BAND,       /**&lt; Denotes BAND based scan filtering */
   CY_WCM_SCAN_FILTER_TYPE_RSSI,       /**&lt; Denotes RSSI based scan filtering */
}cy_wcm_scan_filter_type_t;</pre>
<p>What I want to do is start the scan and then wait for a semaphore.  To do this I will create a semaphore variable at the top of the netTask.c</p>
<pre class="start-line:16 EnlighterJSRAW" data-enlighter-language="c"">SemaphoreHandle_t scanApSempahore = NULL;</pre>
<p>Inside of the switch I will</p>
<ol>
<li>Create a connection parameters structure (line 226-227)</li>
<li>setup the scan filter (line 231-232)</li>
<li>create the semaphore (line 235)</li>
<li>run the scan (line 236)</li>
<li>wait for the semaphore to be set or timeout (line 239) notice that I hardcoded it to 10 seconds</li>
</ol>
<pre class="start-line:226 EnlighterJSRAW" data-enlighter-language="c"">				cy_wcm_connect_params_t connect_params;
				memset(&amp;connect_params, 0, sizeof(cy_wcm_connect_params_t));

				// setup scan filter - In order to connect to an SSID you need to know the security type
				// To find the security I scan for JUST that SSID which will tell me the security type
				scanFilter.mode = CY_WCM_SCAN_FILTER_TYPE_SSID;
				strcpy((char *)scanFilter.param.SSID,(char *)msg.val0);

				// The scan callback will either 1) unlock the semaphore or 2) timeout (meaning it didnt find it)
				scanApSempahore = xSemaphoreCreateBinary();
				cy_wcm_start_scan(findApCallback,&amp;connect_params.ap_credentials.security,&amp;scanFilter);
				
				// The semaphore will return pdFALSE if it TIMES out or pdTrue IF it got unlocked by the scan
				if(xSemaphoreTake( scanApSempahore, pdMS_TO_TICKS(10000)) == pdTRUE)</pre>
<p>In the scan callback I will check to see if I have real data (in other words the scan is not complete).  In the setup above I made the user data be a pointer to the place to store the security.  On line 54 I will store the security type that came back from the scan in the place pointed to by the user data pointer.  Then I will stop the scan and give the semaphore.</p>
<pre class="start-line:46 EnlighterJSRAW" data-enlighter-language="c"">// This callback is used to find a specific SSID and then store the security type into the user data
// When I want to connect it will scan with a "filter" and the user data will be a pointer to the
// place to store the security
void findApCallback( cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status )
{
	if(status == CY_WCM_SCAN_INCOMPLETE)
	{
		whd_security_t *mySecurity = (whd_security_t *)user_data;
	 	*mySecurity = result_ptr-&gt;security;
		cy_wcm_stop_scan();
		xSemaphoreGive(scanApSempahore);
	}
}</pre>
<p>Now back in the switch statement you can actually connect because you know the security type (line 244)  The else clause on line 253 handles the case where the timeout of the semaphore occurred, meaning that the scan didn&#8217;t find the AP.</p>
<pre class="start-line:238 EnlighterJSRAW" data-enlighter-language="c"">				// The semaphore will return pdFALSE if it TIMES out or pdTrue IF it got unlocked by the scan
				if(xSemaphoreTake( scanApSempahore, pdMS_TO_TICKS(10000)) == pdTRUE)
				{
					strcpy((char *)connect_params.ap_credentials.SSID,(char *)msg.val0);
					strcpy((char *)connect_params.ap_credentials.password,(char *)msg.val1);

					result = cy_wcm_connect_ap(&amp;connect_params,&amp;ip_addr);
					if(result == CY_RSLT_SUCCESS)
						printf("Connect Succeeded SSID=%s\n",(char *)msg.val0);
					else
					{
						printf("Connect to %s failed\n",(char *)msg.val0);
					}	
				}
				else
				{
					printf("Scan semaphore failed - couldnt find AP\n");
				}
				free((void *)msg.val0); // Free the SSID and PW that was passed by the caller
				free((void *)msg.val1);

			}
			break;</pre>
<p>With all of the connection work done, you can add the scan command to &#8220;usrcmd.c&#8221;.  It just looks at the number of arguments (either 2 or 3), then sets up the message to send to the network task, the queues the message.</p>
<pre class="start-line:187 EnlighterJSRAW" data-enlighter-language="c" ">static int usrcmd_connect(int argc, char **argv)
{
    networkQueueMsg_t msg;

    if(argc == 2)
    {
        msg.val0 = (uint32_t)malloc(strlen(argv[1])+1);
        msg.val1 = (uint32_t)malloc(sizeof(""));
        strcpy((char *)msg.val0,argv[1]);
        strcpy((char *)msg.val1,"");
        msg.cmd = net_connect;
        xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    }
    
    if(argc == 3)
    {
        msg.val0 = (uint32_t)malloc(strlen(argv[1])+1);
        msg.val1 = (uint32_t)malloc(strlen(argv[2])+1);
        strcpy((char *)msg.val0,argv[1]);
        strcpy((char *)msg.val1,argv[2]);
        msg.cmd = net_connect;
        xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    }

    
    return 0;

}</pre>
<h1>Add the Disconnect Command</h1>
<p>The disconnect command is trivial.  Just call the disconnect api.</p>
<pre class="start-line:262 EnlighterJSRAW" data-enlighter-language="c"">			case net_disconnect:
				cy_wcm_disconnect_ap();
			break;</pre>
<p>Which you also need to add to the usercmd.c</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">static int usrcmd_disconnect(int argc, char **argv)
{
    networkQueueMsg_t msg;
    msg.cmd = net_disconnect;
    xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    
    return 0;
}</pre>
<h1>Add the Print Command</h1>
<p>The print command will have two optional parameters, IP (to print the current IP address) and MAC (to print our MAC address).  The first command is print ip.</p>
<pre class="start-line:266 EnlighterJSRAW" data-enlighter-language="c"">			case net_printip:
			result = cy_wcm_get_ip_addr(CY_WCM_INTERFACE_TYPE_STA,&amp;ip_addr,1);
			if(result == CY_RSLT_SUCCESS)
			{
				printf("IP Address=");
				printIp(&amp;ip_addr);
				printf("\n");
			}
			else if(result == CY_RSLT_WCM_NETWORK_DOWN)
				printf("Network disconnected\n");
			else 
				printf("IP Address call return unknown %d\n",(int)result);
			break;</pre>
<p>The MAC address command is also simple:</p>
<pre class="start-line:280 EnlighterJSRAW" data-enlighter-language="c"">			case net_printmac:
				result = cy_wcm_get_mac_addr(CY_WCM_INTERFACE_TYPE_STA,&amp;mac_addr,1);
				if(result == CY_RSLT_SUCCESS)
				{
					printf("MAC Address =");
					printMac(mac_addr);
					printf("\n");
				}
				else
					printf("MAC Address = Unknown\n");
			break;
		}</pre>
<p>And you need to add the print command to usrcmd.c</p>
<pre class="start-line:226 EnlighterJSRAW" data-enlighter-language="c"">static int usrcmd_print(int argc, char **argv)
{
    networkQueueMsg_t msg;
    if(argc == 2 &amp;&amp; strcmp(argv[1],"ip")==0)
    {
        msg.cmd = net_printip;
        xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    }
    if(argc == 2 &amp;&amp; strcmp(argv[1],"mac")==0)
    {
        msg.cmd = net_printmac;
        xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    }
    return 0;

}</pre>
<p>All of this code is available on github at</p>
<ul>
<li>git@github.com:iotexpert/wcm_example</li>
<li>https://github.com/iotexpert/wcm_example</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-wireless-connection-manager-part-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AnyCloud &#8211; Wireless Connection Manager (Part 1)</title>
		<link>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/</link>
					<comments>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 04 May 2020 12:00:44 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[AnyCloud]]></category>
		<category><![CDATA[CY8CKIT-062S2-43012]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=9019</guid>

					<description><![CDATA[Summary A discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>A discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use with PSoC6 and 43xxx WiFi combos.</p>
<h1>The Story</h1>
<p>In the WICED WiFI SDK there is an example program called &#8220;test.console&#8221; which allows you to use a UART command line to do networking &#8220;stuff&#8221;.  With the release of the new AnyCloud SDK I decided that I should rebuild some of that program using the PSoC and WiFi.  Basically a set of commands like &#8220;scan&#8221; to interact with the Radio World!  In the picture you below you can see that I use the command &#8220;scan&#8221; to list out the networks at my house.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-36-pm/" rel="attachment wp-att-9021"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png" alt="" width="1024" height="623" class="alignnone size-large wp-image-9021" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-600x365.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-768x467.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1536x934.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM.png 1950w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>You can also use the command &#8220;help&#8221; to list out the commands.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-58-pm/" rel="attachment wp-att-9022"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1024x299.png" alt="" width="1024" height="299" class="alignnone size-large wp-image-9022" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1024x299.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-600x175.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-300x88.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-768x224.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM-1536x449.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.58-PM.png 1732w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-58-pm/" rel="attachment wp-att-9022"></a></p>
<h1>Architecture</h1>
<p>My implementation will have three tasks</p>
<ol>
<li>A Blinking LED Task (which doesn&#8217;t interact with any other tasks)</li>
<li>The NT Shell &#8211; which will send commands to the network queue.</li>
<li>The Network Task which will receive commands from the NT Shell task and trigger the Wireless Connection Manager to do something</li>
<li>The Wireless Connection Manager which will interact with the WiFI Radio via the Wireless Host driver.</li>
</ol>
<p><a href="https://iotexpert.com/?attachment_id=9131" rel="attachment wp-att-9131"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/05/arch-1-1024x569.png" alt="" width="1024" height="569" class="alignnone size-large wp-image-9131" srcset="https://iotexpert.com/wp-content/uploads/2020/05/arch-1-1024x569.png 1024w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-600x333.png 600w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-300x167.png 300w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1-768x426.png 768w, https://iotexpert.com/wp-content/uploads/2020/05/arch-1.png 1358w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Make the Basic Project</h1>
<p>To build this project start by creating a new project.  The development board that I had plugged into my computer when I began this project is a CY8CPROTO-062-4343W so this is the one I will select.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/img_1741/" rel="attachment wp-att-9045"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-9045" srcset="https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-scaled-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-768x576.jpg 768w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-1536x1152.jpg 1536w, https://iotexpert.com/wp-content/uploads/2020/04/IMG_1741-2048x1536.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In the new project creator pick the &#8220;CY8CPROTO-062-4343W&#8221;</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-52-43-pm/" rel="attachment wp-att-9031"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1024x757.png" alt="" width="1024" height="757" class="alignnone size-large wp-image-9031" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1024x757.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-600x443.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-300x222.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-768x567.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-1536x1135.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.52.43-PM-2048x1513.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I created a FreeRTOS template project that does all of the right stuff.  I wrote an article about how to use the IoT Expert Manifestt <a href="https://iotexpert.com/2020/03/30/modustoolbox-2-0-libraries-an-example-for-emwin-super-manifests/">here</a>, and until you add the IoT Manifest to your setup you will not get the FreeRTOS Template project.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-53-09-pm/" rel="attachment wp-att-9032"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1024x756.png" alt="" width="1024" height="756" class="alignnone size-large wp-image-9032" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1024x756.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-600x443.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-300x222.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-768x567.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-1536x1134.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.09-PM-2048x1512.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>After the new project work is done you should see</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-53-33-pm/" rel="attachment wp-att-9033"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1024x228.png" alt="" width="1024" height="228" class="alignnone size-large wp-image-9033" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1024x228.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-600x134.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-300x67.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-768x171.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-1536x342.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.53.33-PM-2048x456.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Add the nt-shell, which comes from my IoT Expert library (read about how to add the IoT Expert library <a href="https://iotexpert.com/2020/03/30/modustoolbox-2-0-libraries-an-example-for-emwin-super-manifests/">here</a>).</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-57-07-pm/" rel="attachment wp-att-9034"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1024x889.png" alt="" width="1024" height="889" class="alignnone size-large wp-image-9034" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1024x889.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-600x521.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-300x261.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-768x667.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM-1536x1334.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.07-PM.png 1976w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I have been on a kick of using Visual Studio code.  So, run &#8220;make vscode&#8221; to setup the project for Visual Studio Code.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-57-32-pm/" rel="attachment wp-att-9035"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-870x1024.png" alt="" width="870" height="1024" class="alignnone size-large wp-image-9035" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-870x1024.png 870w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-600x706.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-255x300.png 255w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-768x904.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM-1305x1536.png 1305w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.57.32-PM.png 1704w" sizes="auto, (max-width: 870px) 100vw, 870px" /></a></p>
<p>In the finder, copy the template files from nt-shell into your project.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-23-34-pm/" rel="attachment wp-att-9027"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM.png" alt="" width="1012" height="604" class="alignnone size-full wp-image-9027" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM.png 1012w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-600x358.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-300x179.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.23.34-PM-768x458.png 768w" sizes="auto, (max-width: 1012px) 100vw, 1012px" /></a></p>
<p>You can also do it with the command line.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-58-45-pm/" rel="attachment wp-att-9036"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-1024x139.png" alt="" width="1024" height="139" class="alignnone size-large wp-image-9036" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-1024x139.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-600x81.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-300x41.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM-768x104.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.58.45-PM.png 1168w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Edit main.c to include the configuration.</p>
<pre class="start-line:9 EnlighterJSRAW" data-enlighter-language="c"">#include "ntshell.h"
#include "psoc6_ntshell_port.h"</pre>
<p>Update the main.c to have the ntShellThread</p>
<pre class="start-line:18 EnlighterJSRAW" data-enlighter-language="c"">// Global variable with a handle to the shell
ntshell_t ntshell;

void ntShellTask()
{

  printf("Started ntshell\n");
  setvbuf(stdin, NULL, _IONBF, 0);
  ntshell_init(
               &amp;ntshell,
               ntshell_read,
               ntshell_write,
               ntshell_callback,
               (void *)&amp;ntshell);
  ntshell_set_prompt(&amp;ntshell, "AnyCloud&gt; ");
  vtsend_erase_display(&amp;ntshell.vtsend);
  ntshell_execute(&amp;ntshell);
}</pre>
<p>And start the ntshell task.</p>
<pre class="start-line:71 EnlighterJSRAW" data-enlighter-language="c"">    xTaskCreate(ntShellTask, "nt shell task", configMINIMAL_STACK_SIZE*2,0 /* args */ ,4 /* priority */, 0);</pre>
<p>When you want to add a command to the shell you need to do three things</p>
<ol>
<li>Add a function prototype for the command</li>
<li>Add the command to the command list</li>
<li>Write the function</li>
</ol>
<pre class="start-line:54 EnlighterJSRAW" data-enlighter-language="c"">static int usrcmd_help(int argc, char **argv);
static int usrcmd_info(int argc, char **argv);
static int usrcmd_clear(int argc, char **argv);
static int usrcmd_printargs(int argc, char **argv);
static const cmd_table_t cmdlist[] = {
    { "help", "This is a description text string for help command.", usrcmd_help },
    { "info", "This is a description text string for info command.", usrcmd_info },
    { "clear", "Clear the screen", usrcmd_clear },
    { "printargs","print the list of arguments", usrcmd_printargs},
};</pre>
<p>Here is an example of of the printargs command.  The shell will call your function with a ARGC=number of arguments and ARGV[] an array of the pointers to the actual arguments.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">static int usrcmd_printargs(int argc, char **argv)
{
    printf("ARGC = %d\n",argc);

    for(int i =0;i&lt;argc;i++)
    {
        printf("argv[%d] = %s\n",i,argv[i]);
    }
    return 0;

}</pre>
<p>Build and test your program.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-28-29-pm/" rel="attachment wp-att-9029"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1024x288.png" alt="" width="1024" height="288" class="alignnone size-large wp-image-9029" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1024x288.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-600x169.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-300x84.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-768x216.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM-1536x431.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.28.29-PM.png 1666w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Turn on the Connection Manager and Core Middleware Library</h1>
<p>Now, add the wifi-mw-core library &amp; Connection Manager using the library manager.  You can start it with &#8220;make modlibs&#8221;.  These two libraries are in the &#8220;WiFi Middleware&#8221; category.</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-3-04-40-pm/" rel="attachment wp-att-9037"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1024x787.png" alt="" width="1024" height="787" class="alignnone size-large wp-image-9037" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1024x787.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-600x461.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-300x231.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-768x591.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-1536x1181.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-3.04.40-PM-2048x1575.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Copy the FreeRTOSConfig.h from the libs/wifi-mw-core/configs directory into your project (so you can modify it)</p>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-2-13-57-pm/" rel="attachment wp-att-9026"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1024x677.png" alt="" width="1024" height="677" class="alignnone size-large wp-image-9026" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1024x677.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-600x396.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-300x198.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-768x507.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM-1536x1015.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-2.13.57-PM.png 1562w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Update the Makefile to include the WiFi components (line 71) and the MBED TLS configuration (line 86)</p>
<pre class="start-line:70 EnlighterJSRAW" data-enlighter-language="c"">COMPONENTS=FREERTOS PSOC6HAL LWIP MBEDTLS 4343W
# Like COMPONENTS, but disable optional code that was enabled by default.
DISABLE_COMPONENTS=

# By default the build system automatically looks in the Makefile's directory
# tree for source code and builds it. The SOURCES variable can be used to
# manually add source code to the build process from a location not searched
# by default, or otherwise not found by the build system.
SOURCES=

# Like SOURCES, but for include directories. Value should be paths to
# directories (without a leading -I).
INCLUDES=

# Add additional defines to the build process (without a leading -D).
DEFINES=MBEDTLS_USER_CONFIG_FILE='"configs/mbedtls_user_config.h"' CYBSP_WIFI_CAPABLE</pre>
<h1>Create networkTask.h/.c &amp; Start the Task in main.c</h1>
<p>Now let&#8217;s create the networkTask.  This task will control all of the networking functions in the system.  The first file, networkTask.h, is the public interface.  It declares a Queue where you can push messages (line 5) an enumeration of the messages (lines 7-14), a definition of the message data (lines 17-22) and finally the network task declaration (line 24).</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">#pragma once
#include "FreeRTOS.h"
#include "queue.h"

extern QueueHandle_t networkQueue;

typedef enum {
    net_scan,
    net_connect,
    net_disconnect,
    net_printip,
    net_printmac,

} networkCmd_t;


typedef struct {
    networkCmd_t cmd;
    uint32_t val0;
    uint32_t val1;

} networkQueueMsg_t;

void networkTask(void *arg);</pre>
<p>Ill go ahead and modify main.c to start the yet to be written network task.  You need to include the header file for the task and define a handle for the task.</p>
<pre class="start-line:11 EnlighterJSRAW" data-enlighter-language="c"">#include "networkTask.h"

TaskHandle_t networkTaskHandle;</pre>
<p>Finally in main function, start the task.</p>
<pre class="start-line:60 EnlighterJSRAW" data-enlighter-language="c"">    xTaskCreate(networkTask, "networkTask", configMINIMAL_STACK_SIZE*8,0 /* args */ ,4/* priority */, &amp;networkTaskHandle);</pre>
<p>Create the file networkTask.c.  Make a bunch of includes.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include "FreeRTOS.h"
#include "task.h"
#include "cy_wcm.h"
#include "cy_wcm_error.h"
#include "whd_types.h"
#include "queue.h"
#include "semphr.h"
#include "networkTask.h"</pre>
<p>Now let&#8217;s define the actual task function.  This function will</p>
<ol>
<li>Call the wcm_init function to make a WiFi Station (lines 201-203)</li>
<li>Tell the task that you would like to be called back when things happen (line 205)</li>
<li>Initialize the Queue to receive command messages from other tasks.</li>
<li>Make an infinite loop to receive the commands and process the messages.  Notice that I dont do anything with the message for now.  Ill add the code later.</li>
</ol>
<pre class="start-line:190 EnlighterJSRAW" data-enlighter-language="c"">// The networkTask will:
// - startup the wireless connection manager
// - sit waiting on the rtos queue... getting messages from other tasks
// - and do ( net_scan, net_connect, net_disconnect, net_printip, net_printmac,)

void networkTask(void *arg)
{
	cy_rslt_t result;
	cy_wcm_config_t config;
	cy_wcm_scan_filter_t scanFilter;

	memset(&amp;config, 0, sizeof(cy_wcm_config_t));
    config.interface = CY_WCM_INTERFACE_TYPE_STA;
	cy_wcm_init	(&amp;config);

	cy_wcm_register_event_callback(	wcmCallback	);

	networkQueue = xQueueCreate( 5, sizeof(networkQueueMsg_t));

	while(1)
	{
		networkQueueMsg_t msg;

		xQueueReceive(networkQueue,(void *)&amp;msg,portMAX_DELAY);  // Wait for commands from other tasks

		switch(msg.cmd)
		{
			case net_scan: // 0=stop scan !0=start scan
			break;

			case net_connect:
			break;

			case net_disconnect:
			break;

			case net_printip:
			break;

			case net_printmac:
			break;
		}
	}

}</pre>
<h1>Create Utilities for Printing out the IP and MAC Address</h1>
<p>It the network task I want to be able to print out IP address (both IPV4 and IPV6).  I also want to be able to print out 6-byte MAC address.  In the Cypress drivers, an IP address is a structure that holds either a IPV4 or and IPV6 address.  It then contains the 4 or 6 bytes of the address.  Here is the type definition.</p>
<pre class="start-line:387 EnlighterJSRAW" data-enlighter-language="c"">/**
 * IP Address Structure
 */
typedef struct
{
    cy_wcm_ip_version_t version;  /**&lt; IP version */
    union
    {
        uint32_t v4;     /**&lt; IPv4 address bytes */
        uint32_t v6[4];  /**&lt; IPv6 address bytes */
    } ip;                /**&lt; IP address bytes */
} cy_wcm_ip_address_t;</pre>
<p>The IP v ersion is just an enumeration.</p>
<pre class="start-line:164 EnlighterJSRAW" data-enlighter-language="c"">/**
 * IP Version
 */
typedef enum
{
    CY_WCM_IP_VER_V4 = 4,      /**&lt; Denotes IPv4 version */
    CY_WCM_IP_VER_V6 = 6       /**&lt; Denotes IPv6 version */
} cy_wcm_ip_version_t;</pre>
<p>To print an address, figure out which version you are working on.  Then dump the raw bytes.  Notice in the IPV4 case it is encoded into a uint32_t as 4 continuous bytes.</p>
<pre class="start-line:18 EnlighterJSRAW" data-enlighter-language="c"">void printIp(cy_wcm_ip_address_t *ipad)
{
	if(ip_addr.version == CY_WCM_IP_VER_V4)
	{
		printf("%d.%d.%d.%d",(int)ipad-&gt;ip.v4&gt;&gt;0&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;8&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;16&amp;0xFF,(int)ipad-&gt;ip.v4&gt;&gt;24&amp;0xFF);
	}
	else if (ip_addr.version == CY_WCM_IP_VER_V6)
	{
		for(int i=0;i&lt;4;i++)
		{
			printf("%0X:",(unsigned int)ip_addr.ip.v6[i]);
		}
	}
	else
	{
		printf("IP ERROR %d",ipad-&gt;version);
	}			
}</pre>
<p>A MAC address is just an array of uint8_t of length CY_WCM_MAC_ADDR_LEN  (which we pound defined to 6)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">typedef uint8_t cy_wcm_mac_t[CY_WCM_MAC_ADDR_LEN];                   /**&lt; Unique 6-byte MAC address */</pre>
<p>So, the print is just a loop. (probably should have done something slightly better so I dont end up with the trailing : &#8211; oh well)</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">void printMac(cy_wcm_mac_t mac)
{
	for(int i=0;i&lt;CY_WCM_MAC_ADDR_LEN;i++)
	{
		uint8_t val = mac[i];
		printf("%02X:",val);
	}
}</pre>
<h1>Add the Scan Command</h1>
<p>For the scan I want to print out the:</p>
<ol>
<li>SSID</li>
<li>RSSI (in dBM)</li>
<li>Channel</li>
<li>Band</li>
<li>Speed</li>
<li>Type of Ap</li>
<li>Country Code</li>
<li>MAC address of the Access Point (AKA BSSID)</li>
<li>Type of Security</li>
</ol>
<p><a href="https://iotexpert.com/2020/05/04/anycloud-wireless-connection-manager-part-1/screen-shot-2020-04-27-at-1-04-36-pm/" rel="attachment wp-att-9021"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png" alt="" width="1024" height="623" class="alignnone size-large wp-image-9021" srcset="https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1024x623.png 1024w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-600x365.png 600w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-300x182.png 300w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-768x467.png 768w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM-1536x934.png 1536w, https://iotexpert.com/wp-content/uploads/2020/04/Screen-Shot-2020-04-27-at-1.04.36-PM.png 1950w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>In order to have the WCM run a scan you need to call the function cy_wcm_start_scan.  What this will do is tell the 4343W to scan all the channels on the 2.4GHZ band and listen for access point beacons.  This function has three arguments</p>
<ol>
<li>A function pointer to call back when you find an AP</li>
<li>A user settable data pointer</li>
<li>A filter (which can limit to an SSID, BSSID or RSSI)</li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="c">cy_rslt_t cy_wcm_start_scan(cy_wcm_scan_result_callback_t callback, void *user_data, cy_wcm_scan_filter_t *scan_filter)</pre>
<p>Here is my version of the scanCallback which I put in the networkTask.c file.</p>
<pre class="start-line:60 EnlighterJSRAW" data-enlighter-language="c"">// This function is called back when the user asks for an overall scan.
// It just prints out the information about the networks that it hears about
void scanCallback( cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status )</pre>
<p>The result_ptr is a pointer to a structure that contains the data for the found access point.</p>
<pre class="start-line:460 EnlighterJSRAW" data-enlighter-language="c" ">/**
 * Structure for storing scan results
 */
typedef struct
{
    cy_wcm_ssid_t                SSID;             /**&lt; Service Set Identification (i.e. Name of Access Point)                    */
    cy_wcm_mac_t                 BSSID;            /**&lt; Basic Service Set Identification (i.e. MAC address of Access Point)       */
    int16_t                      signal_strength;  /**&lt; Receive Signal Strength Indication in dBm. &lt;-90=Very poor, &gt;-30=Excellent */
    uint32_t                     max_data_rate;    /**&lt; Maximum data rate in kilobits/s                                           */
    cy_wcm_bss_type_t            bss_type;         /**&lt; Network type                                                              */
    cy_wcm_security_t            security;         /**&lt; Security type                                                             */
    uint8_t                      channel;          /**&lt; Radio channel that the AP beacon was received on                          */
    cy_wcm_wifi_band_t           band;             /**&lt; Radio band                                                                */
    uint8_t                      ccode[2];         /**&lt; Two letter ISO country code from AP                                       */
    uint8_t                      flags;            /**&lt; flags                                                                     */
    uint8_t                      *ie_ptr;          /**&lt; Pointer to received Beacon/Probe Response IE(Information Element)         */
    uint32_t                     ie_len;           /**&lt; Length of IE(Information Element)                                         */
} cy_wcm_scan_result_t;
</pre>
<p>The other parameter to the callback is the status.  The status will either be CY_WCM_SCAN_COMPLETE or CY_WCM_SCAN_INCOMPLETE.  The first thing that to do is see if this callback is the one that tells me that the scan is complete, if so I just return (and don&#8217;t print anything)</p>
<pre class="start-line:67 EnlighterJSRAW" data-enlighter-language="c"">	if(status == CY_WCM_SCAN_COMPLETE)
		return;</pre>
<p>Then I print out the raw SSID, Signal Strength and Channel.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">	printf("%32s\t%d\t%d\t",result_ptr-&gt;SSID,result_ptr-&gt;signal_strength,result_ptr-&gt;channel);</pre>
<p>Next I figure out what channel we are talking about.  The 4343W is single band 2.4GHZ, however, other Cypress chips have dual band.</p>
<pre class="start-line:68 EnlighterJSRAW" data-enlighter-language="c"">	switch(result_ptr-&gt;band)
	{
		case CY_WCM_WIFI_BAND_ANY:
			printf("ANY");
		break;
		case CY_WCM_WIFI_BAND_5GHZ:
			printf("5.0 GHZ");
		break;
		case CY_WCM_WIFI_BAND_2_4GHZ:
			printf("2.4 GHZ");
		break;
	}</pre>
<p>Then I printout the maximum data rate, which is 0 for all of my test cases.  I have no idea why.</p>
<pre class="start-line:82 EnlighterJSRAW" data-enlighter-language="c"">	printf("%d",(int)result_ptr-&gt;max_data_rate);</pre>
<p>Then I printout what type of AP we are talking about.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">	switch(result_ptr-&gt;bss_type)
	{
		case CY_WCM_BSS_TYPE_INFRASTRUCTURE:
			printf("INFR");
		break; 	
		case CY_WCM_BSS_TYPE_ADHOC: 
			printf("ADHOC");
		break;	
		case CY_WCM__BSS_TYPE_ANY: 	
			printf("ANY");
		break;
		case CY_WCM_BSS_TYPE_MESH:
			printf("MESG");
		break;
		case CY_WCM_BSS_TYPE_UNKNOWN: 
			printf("UNKWN");
		break;
	}</pre>
<p>Then the country code.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">	printf("%c%c",result_ptr-&gt;ccode[0],result_ptr-&gt;ccode[1]);
</pre>
<p>Then the Basic Service Set ID of the AP, which is also known as the MAC address of the AP.</p>
<pre class="start-line:105 EnlighterJSRAW" data-enlighter-language="c"">	printMac(result_ptr-&gt;BSSID);</pre>
<p>Then the security type.</p>
<pre class="start-line:108 EnlighterJSRAW" data-enlighter-language="c"">	switch(result_ptr-&gt;security)
	{
		case CY_WCM_SECURITY_OPEN:
			printf("OPEN");
		break;
    	case CY_WCM_SECURITY_WEP_PSK:
			printf("WEP_PSK");
		break;
		case CY_WCM_SECURITY_WEP_SHARED:
			printf("WEP_SHARED");
		break;
    	case CY_WCM_SECURITY_WPA_TKIP_PSK:
			printf("WPA_TKIP_PSK");
		break;
		case CY_WCM_SECURITY_WPA_AES_PSK:
			printf("WPA_AES_PSK");
		break;
		case CY_WCM_SECURITY_WPA_MIXED_PSK:
			printf("WPA_MIXED_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_AES_PSK:
			printf("WPA2_AES_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_TKIP_PSK:
			printf("WPA2_TKIP_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_MIXED_PSK:
			printf("WPA2_MIXED_PSK");
		break;
		case CY_WCM_SECURITY_WPA2_FBT_PSK:
			printf("WPA2_FBT_PSK");
		break;
		case CY_WCM_SECURITY_WPA3_SAE:
			printf("WPA3_SAE");
		break;
		case CY_WCM_SECURITY_WPA3_WPA2_PSK:
			printf("WPA3_WPA2_PSK");
		break;
		case CY_WCM_SECURITY_IBSS_OPEN:
			printf("IBSS_OPEN");
		break;
		case CY_WCM_SECURITY_WPS_SECURE:
			printf("WPS_SECURE");
		break;
		case CY_WCM_SECURITY_UNKNOWN:
			printf("UNKNOWN");
		break;
		case CY_WCM_SECURITY_FORCE_32_BIT:
			printf("FORCE_32_BIT");
		break;
	}</pre>
<p>With a complete scanCallback function I can now update the networkTask to deal with the queued commands of net_scan type.  This simply either stops or starts the scan based on the message parameter.</p>
<pre class="start-line:212 EnlighterJSRAW" data-enlighter-language="c"">			case net_scan: // 0=stop scan !0=start scan
				if(msg.val0 == 0)
					cy_wcm_stop_scan();
				else
				{
					printf("\n");
					result = cy_wcm_start_scan(scanCallback,0,0);
					if(result != CY_RSLT_SUCCESS)
						printf("Scan error\n");
				}
			break;</pre>
<p>The last things to do is to add the scan command to the usrcmd.c</p>
<pre class="start-line:149 EnlighterJSRAW" data-enlighter-language="c"">static int usrcmd_scan(int argc, char **argv)
{

    static int state=0;

    if(argc==1)
    {
        state = (state ==0)?1:0;
    }
    else if(argc == 2)
    {
        if(strcmp(argv[1],"on") == 0)
        {
            state=1;
        } 
        else if(strcmp(argv[1],"off") == 0)
        {
            state = 0;
        }
        else
        {
            printf("usage: scan [on|off]\n");
            return 0;
        }
        
    }
    else
    {
        printf("usage scan: [on|off]\n");
        return 0;
    }
    
    networkQueueMsg_t msg;
    msg.cmd = net_scan;
    msg.val0 = state;
    xQueueSend(networkQueue,(const void *)&amp;msg,portMAX_DELAY);
    return 0;
}</pre>
<p>OK.  Let it rip.  You should be able to run network scans.  In the next Article I will add a connect and disconnect commands.</p>
<p>You can find all of this example code at https://github.com/iotexpert/wcm_example</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/anycloud-wireless-connection-manager-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mouser Bluetooth Mesh: L1 Developer Resources</title>
		<link>https://iotexpert.com/mouser-bluetooth-mesh-l1-developer-resources/</link>
					<comments>https://iotexpert.com/mouser-bluetooth-mesh-l1-developer-resources/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Wed, 29 May 2019 11:36:47 +0000</pubDate>
				<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[CYW20819]]></category>
		<category><![CDATA[Mouser Bluetooth Mesh]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6951</guid>

					<description><![CDATA[Summary This lesson has a bunch of links to useful documentation about Bluetooth Mesh.  It includes links to all of the Cypress software and application notes.  It also includes links to the Bluetooth Special Interest Group website for the BLE Mesh Specs. Cypress Resources Cypress Bluetooth Mesh Landing Page AN227069 &#8211; Getting Started with Bluetooth [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span><h1>How To Design With Bluetooth Mesh</h1>
<p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >#</th>
<th >Lesson</th>
</tr>
</thead>
<tbody>
<tr><td >0</td>
<td ><a href="https://iotexpert.com/2019/05/25/mouser-bluetooth-mesh-l0-introduction/" target="_blank" rel="noopener">Introduction</a></td>
</tr>

<tr><td >1</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/" target="_blank" rel="noopener">Developer Resources</a></td>
</tr>

<tr><td >2a</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l2a-using-the-cybt-213043-mesh-building-a-mesh-network-using-the-mesh-lighting-app/" target="_blank" rel="noopener">Using the CYBT-213043-MESH &amp; Building a Mesh Network Using the Mesh Lighting App</a></td>
</tr>

<tr><td >2b</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l2b-building-a-mesh-network-using-the-mesh-client/" target="_blank" rel="noopener">Building a Mesh Network Using the Mesh Client</a></td>
</tr>

<tr><td >3</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l3-making-a-light-switch-using-the-example-code/" target="_blank" rel="noopener">Making a Light Switch Using the Example Code</a></td>
</tr>

<tr><td >4</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l4-integrating-the-modus-toolbox-code-examples/" target="_blank" rel="noopener">Integrating the Modus Toolbox Code Examples</a></td>
</tr>

<tr><td >5</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l5-bluetooth-mesh-fundamentals/" target="_blank" rel="noopener">Bluetooth Mesh Fundamentals</a></td>
</tr>

<tr><td >6</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l6-the-dimmable-light-code/" target="_blank" rel="noopener">The Dimmable Light Code</a></td>
</tr>

<tr><td >7</td>
<td ><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l7-modifying-the-dimmable-light-code-to-add-another-light-element/">Modifying the Dimmable Light Code to Add Another Light Element</a></td>
</tr>
</tbody></table></div><br />You can "git" a workspace will all of these files at https://github.com/iotexpert/MouserVTWBluetoothMesh or git@github.com:iotexpert/MouserVTWBluetoothMesh.git</p></span></p>
<h1><span>Summary<br />
</span></h1>
<p>This lesson has a bunch of links to useful documentation about Bluetooth Mesh.  It includes links to all of the Cypress software and application notes.  It also includes links to the Bluetooth Special Interest Group website for the BLE Mesh Specs.</p>
<p><a href="https://www.cypress.com" target="_blank" rel="noopener noreferrer"><span style="text-decoration: underline;">Cypress Resources</span></a></p>
<ol>
<li><a href="https://www.cypress.com/products/ble-mesh" target="_blank" rel="noopener noreferrer">Cypress Bluetooth Mesh Landing Page</a></li>
<li><a href="https://www.cypress.com/file/473921/download" target="_blank" rel="noopener noreferrer">AN227069 &#8211; Getting Started with Bluetooth Mesh</a></li>
<li><a href="https://www.cypress.com/documentation/development-kitsboards/cybt-213043-mesh-ez-bt-module-mesh-evaluation-kit" target="_blank" rel="noopener noreferrer">EZ-BT Mesh Evaluation Kit Landing Page</a></li>
<li><a href="https://www.cypress.com/file/460061/download" target="_blank" rel="noopener noreferrer">EZ-BT Mesh Evaluation Kit QuickStart</a></li>
<li><a href="https://www.cypress.com/products/modustoolbox-software-environment" target="_blank" rel="noopener noreferrer">Modus Toolbox</a></li>
<li><a href="https://community.cypress.com/community/modustoolbox-bt-sdk" target="_blank" rel="noopener noreferrer">Cypress Bluetooth Community</a></li>
<li><a href="https://community.cypress.com/docs/DOC-17416" target="_blank" rel="noopener noreferrer">Bluetooth SDK 1.2</a></li>
<li><a href="https://github.com/cypresssemiconductorco/Code-Examples-BT-SDK-for-ModusToolbox" target="_blank" rel="noopener noreferrer">Modus Toolbox Bluetooth SDK Examples @ github</a></li>
<li><a href="https://github.com/cypresssemiconductorco/CypressAcademy_WBT101_Files" target="_blank" rel="noopener noreferrer">Cypress WICED Bluetooth 101 &#8211; Class</a></li>
<li>Mesh Client</li>
<li><a href="https://www.cypress.com/file/462491/download" target="_blank" rel="noopener noreferrer">Mesh Client Documentation</a></li>
</ol>
<p><a href="https://bluetooth.org" target="_blank" rel="noopener noreferrer"><span style="text-decoration: underline;">Bluetooth Sig Resources</span></a></p>
<ol>
<li><a href="https://www.bluetooth.com/specifications/mesh-specifications/" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Specs</a></li>
<li><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=457092" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Profile Spec</a></li>
<li><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=457091" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Model Spec</a></li>
<li><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=429635" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Device Properties</a></li>
<li><a href="https://www.bluetooth.com/blog/introducing-bluetooth-mesh-networking/" target="_blank" rel="noopener noreferrer">Introducing Bluetooth Mesh Networking</a></li>
<li><a href="https://www.bluetooth.com/blog/an-intro-to-bluetooth-mesh-part1/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Intro Bluetooth Mesh Part 1</a></li>
<li><a href="https://blog.bluetooth.com/an-intro-to-bluetooth-mesh-part2?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Intro Bluetooth Mesh Part 2</a></li>
<li><a href="https://www.bluetooth.com/blog/the-fundamental-concepts-of-bluetooth-mesh-networking-part-1/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Fundamental Concepts of BT Mesh Networking Part1</a></li>
<li><a href="https://www.bluetooth.com/blog/the-fundamental-concepts-of-bluetooth-mesh-networking-part-2/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Fundamental Concepts of BT Mesh Networking Part2</a></li>
<li><a href="https://blog.bluetooth.com/bluetooth-mesh-networking-series-friendship?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Networking: Friendship</a></li>
<li><a href="https://blog.bluetooth.com/management-of-devices-bluetooth-mesh-network?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Management of Devices in a Bluetooth Mesh Network</a></li>
<li><a href="https://blog.bluetooth.com/in-market-bluetooth-low-energy-devices-and-bluetooth-mesh-networking?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">In-Market Bluetooth Low Energy Devices and Bluetooth Mesh Networking</a></li>
<li><a href="https://blog.bluetooth.com/bluetooth-mesh-security-overview?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Security Overview</a></li>
<li><a href="https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-1?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Provisioning a Bluetooth Mesh Network Part 1</a></li>
<li><a href="https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-2?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Provisioning a Bluetooth Mesh Network Part 2</a></li>
</ol>
<p>Other Useful Links</p>
<ol>
<li><a href="https://en.wikipedia.org/wiki/Bluetooth_mesh_networking" target="_blank" rel="noopener noreferrer">Wikipedia Bluetooth Mesh</a></li>
</ol>
<h1><a href="https://www.cypress.com/products/ble-mesh" target="_blank" rel="noopener noreferrer">Cypress Bluetooth Mesh Landing Page</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-21-25-am/" rel="attachment wp-att-7002"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.25-AM-1024x902.png" alt="" width="1024" height="902" class="alignnone size-large wp-image-7002" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.25-AM-1024x902.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.25-AM-600x528.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.25-AM-300x264.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.25-AM-768x676.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.cypress.com/file/473921/download" target="_blank" rel="noopener noreferrer">AN227069 &#8211; Getting Started with Bluetooth Mesh</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-21-55-am/" rel="attachment wp-att-7003"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.55-AM-1024x762.png" alt="" width="1024" height="762" class="alignnone size-large wp-image-7003" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.55-AM-1024x762.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.55-AM-600x447.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.55-AM-300x223.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.21.55-AM-768x572.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.cypress.com/documentation/development-kitsboards/cybt-213043-mesh-ez-bt-module-mesh-evaluation-kit" target="_blank" rel="noopener noreferrer">EZ-BT Mesh Evaluation Kit Landing Page</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-22-47-am/" rel="attachment wp-att-7004"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.22.47-AM-1024x964.png" alt="" width="1024" height="964" class="alignnone size-large wp-image-7004" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.22.47-AM-1024x964.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.22.47-AM-600x565.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.22.47-AM-300x282.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.22.47-AM-768x723.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.cypress.com/file/460061/download" target="_blank" rel="noopener noreferrer">EZ-BT Mesh Evaluation Kit QuickStart</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-24-12-am/" rel="attachment wp-att-7005"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM-1024x899.png" alt="" width="1024" height="899" class="alignnone size-large wp-image-7005" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM-1024x899.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM-600x527.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM-300x264.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM-768x675.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.24.12-AM.png 1628w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.cypress.com/products/modustoolbox-software-environment" target="_blank" rel="noopener noreferrer">Modus Toolbox</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-25-56-am/" rel="attachment wp-att-7007"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM-971x1024.png" alt="" width="971" height="1024" class="alignnone size-large wp-image-7007" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM-971x1024.png 971w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM-600x633.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM-284x300.png 284w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM-768x810.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.25.56-AM.png 1818w" sizes="auto, (max-width: 971px) 100vw, 971px" /></a></p>
<h1><a href="https://community.cypress.com/community/modustoolbox-bt-sdk" target="_blank" rel="noopener noreferrer">Cypress Bluetooth Community</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-26-46-am/" rel="attachment wp-att-7008"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.26.46-AM-1024x967.png" alt="" width="1024" height="967" class="alignnone size-large wp-image-7008" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.26.46-AM-1024x967.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.26.46-AM-600x567.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.26.46-AM-300x283.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.26.46-AM-768x726.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://community.cypress.com/docs/DOC-17416" target="_blank" rel="noopener noreferrer">Bluetooth SDK 1.2</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-27-24-am/" rel="attachment wp-att-7009"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM-1024x859.png" alt="" width="1024" height="859" class="alignnone size-large wp-image-7009" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM-1024x859.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM-600x504.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM-300x252.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM-768x645.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.27.24-AM.png 1916w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://github.com/cypresssemiconductorco/Code-Examples-BT-SDK-for-ModusToolbox" target="_blank" rel="noopener noreferrer">Modus Toolbox Bluetooth SDK Examples @ github</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-28-04-am/" rel="attachment wp-att-7010"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM-819x1024.png" alt="" width="819" height="1024" class="alignnone size-large wp-image-7010" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM-819x1024.png 819w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM-600x750.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM-240x300.png 240w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM-768x960.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.04-AM.png 1812w" sizes="auto, (max-width: 819px) 100vw, 819px" /></a></p>
<h1><a href="https://github.com/cypresssemiconductorco/CypressAcademy_WBT101_Files" target="_blank" rel="noopener noreferrer">Cypress WICED Bluetooth 101 &#8211; Class</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-28-39-am/" rel="attachment wp-att-7011"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM-1024x859.png" alt="" width="1024" height="859" class="alignnone size-large wp-image-7011" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM-1024x859.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM-600x503.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM-300x252.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM-768x644.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.28.39-AM.png 1760w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1>Mesh Client</h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-19-29-am/" rel="attachment wp-att-6999"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM-1024x661.png" alt="" width="1024" height="661" class="alignnone size-large wp-image-6999" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM-1024x661.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM-600x387.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM-300x194.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM-768x496.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.19.29-AM.png 1980w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.cypress.com/file/462491/download" target="_blank" rel="noopener noreferrer">Mesh Client Documentation</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-20-30-am/" rel="attachment wp-att-7001"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM-842x1024.png" alt="" width="842" height="1024" class="alignnone size-large wp-image-7001" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM-842x1024.png 842w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM-600x730.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM-247x300.png 247w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM-768x934.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.20.30-AM.png 1654w" sizes="auto, (max-width: 842px) 100vw, 842px" /></a></p>
<h1><a href="https://www.bluetooth.com/specifications/mesh-specifications/" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Specs</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-31-19-am/" rel="attachment wp-att-7013"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.31.19-AM-1024x677.png" alt="" width="1024" height="677" class="alignnone size-large wp-image-7013" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.31.19-AM-1024x677.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.31.19-AM-600x397.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.31.19-AM-300x198.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.31.19-AM-768x508.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=457092" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Profile Spec</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-32-01-am/" rel="attachment wp-att-7014"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM-1024x626.png" alt="" width="1024" height="626" class="alignnone size-large wp-image-7014" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM-1024x626.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM-600x367.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM-300x184.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM-768x470.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.01-AM.png 1710w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=457091" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Model Spec</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-32-36-am/" rel="attachment wp-att-7015"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM-1024x703.png" alt="" width="1024" height="703" class="alignnone size-large wp-image-7015" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM-1024x703.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM-600x412.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM-300x206.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM-768x527.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.32.36-AM.png 1558w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=429635" target="_blank" rel="noopener noreferrer">Bluetooth SIG Mesh Device Properties</a></h1>
<p><a href="https://iotexpert.com/2019/05/29/mouser-bluetooth-mesh-l1-developer-resources/screen-shot-2019-05-26-at-8-33-07-am/" rel="attachment wp-att-7016"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM-1024x546.png" alt="" width="1024" height="546" class="alignnone size-large wp-image-7016" srcset="https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM-1024x546.png 1024w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM-600x320.png 600w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM-300x160.png 300w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM-768x410.png 768w, https://iotexpert.com/wp-content/uploads/2019/05/Screen-Shot-2019-05-26-at-8.33.07-AM.png 1582w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h1><a href="https://www.bluetooth.com/blog/introducing-bluetooth-mesh-networking/" target="_blank" rel="noopener noreferrer">Introducing Bluetooth Mesh Networking</a></h1>
<h1><a href="https://www.bluetooth.com/blog/an-intro-to-bluetooth-mesh-part1/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Intro Bluetooth Mesh Part 1</a></h1>
<h1><a href="https://blog.bluetooth.com/an-intro-to-bluetooth-mesh-part2?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Intro Bluetooth Mesh Part 2</a></h1>
<h1><a href="https://www.bluetooth.com/blog/the-fundamental-concepts-of-bluetooth-mesh-networking-part-1/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Fundamental Concepts of BT Mesh Networking Part1</a></h1>
<h1><a href="https://www.bluetooth.com/blog/the-fundamental-concepts-of-bluetooth-mesh-networking-part-2/?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Fundamental Concepts of BT Mesh Networking Part2</a></h1>
<h1><a href="https://blog.bluetooth.com/bluetooth-mesh-networking-series-friendship?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Networking: Friendship</a></h1>
<h1><a href="https://blog.bluetooth.com/management-of-devices-bluetooth-mesh-network?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Management of Devices in a Bluetooth Mesh Network</a></h1>
<h1><a href="https://blog.bluetooth.com/in-market-bluetooth-low-energy-devices-and-bluetooth-mesh-networking?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">In-Market Bluetooth Low Energy Devices and Bluetooth Mesh Networking</a></h1>
<h1><a href="https://blog.bluetooth.com/bluetooth-mesh-security-overview?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Bluetooth Mesh Security Overview</a></h1>
<h1><a href="https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-1?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Provisioning a Bluetooth Mesh Network Part 1</a></h1>
<h1><a href="https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-2?utm_campaign=mesh&amp;utm_source=internal&amp;utm_medium=blog&amp;utm_content=introducing-bluetooth-mesh-networking" target="_blank" rel="noopener noreferrer">Provisioning a Bluetooth Mesh Network Part 2</a></h1>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mouser-bluetooth-mesh-l1-developer-resources/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MBEDOS Little File System &#038; CY8CPROTO_62_4343W</title>
		<link>https://iotexpert.com/mbedos-little-file-system-cy8cproto_62_4343w/</link>
					<comments>https://iotexpert.com/mbedos-little-file-system-cy8cproto_62_4343w/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 01 Apr 2019 12:00:30 +0000</pubDate>
				<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[MBED OS]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6636</guid>

					<description><![CDATA[Summary This is the first article in a series that will discuss how to use the MBED OS file systems with Cypress SPI Nor Flash chips and PSoC 6. The Back Story On a bunch of our development kits there is a SPI NOR Flash sitting right next to the PSoC 6.  Which exact SPI [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This is the first article in a series that will discuss how to use the MBED OS file systems with <a href="https://www.cypress.com/products/serial-nor-flash-memory" target="_blank" rel="noopener noreferrer">Cypress SPI Nor Flash</a> chips and PSoC 6.</p>
<p><span><p><div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Title</th>
</tr>
</thead>
<tbody>
<tr><td >The Back Story &amp; Making the <a href="https://os.mbed.com/blog/entry/littlefs-high-integrity-embedded-fs/" target="_blank" rel="noopener noreferrer">LittleFS</a> Work with the CY8CKIT_062_4343W</td>
</tr>

<tr><td >The Architecture of Filesystems in MBEDOS</td>
</tr>

<tr><td >SPI Nor Flash</td>
</tr>

<tr><td >SFDP</td>
</tr>

<tr><td >The MBED OS Quad SPI Driver</td>
</tr>

<tr><td >LittleFS</td>
</tr>

<tr><td >FATFS</td>
</tr>

<tr><td >MBED OS and POSIX Files</td>
</tr>
</tbody></table></div></p>
<p>&nbsp;</p></span></p>
<h1>The Back Story</h1>
<p>On a bunch of our development kits there is a SPI NOR Flash sitting right next to the PSoC 6.  Which exact SPI flash depends on the exact generation of development kit.  I have always wanted to use these chips, but had never had time to sort out how they work.  And quite frankly we never made it very easy to use them because although they were connected, we didn&#8217;t provide much in the way of software support.  However, with the advent of MBED OS at Cypress we were suddenly gifted with two file systems to use, LittleFS and FATFS.</p>
<p>This journey starts with an email note to the Applications manager in India (an awesome woman named Jaya)&#8230; &#8220;Hey, can you get someone to send me an example of the MBED OS flash file system on the CY8CPROTO_062_4343W.&#8221;  A day or so later I got an email with an attached project and a &#8220;memo&#8221; that explained what to do.  This exchange happened right before Embedded World in February and I was really busy.  Finally, a couple of weeks ago I read the email and the instructions which started with &#8220;Break off the NOR Flash wing and solder&#8230;.&#8221;  If you look in the picture below you can see that at the top of the kit there is a breakaway wing (circled in green) that has a SPI Flash chip on it (circled in red).</p>
<p><a href="https://iotexpert.com/?attachment_id=6637" rel="attachment wp-att-6637"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/IMG_0286-e1553952138595-1024x768.jpg" alt="" width="1024" height="768" class="alignnone wp-image-6637 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/03/IMG_0286-e1553952138595-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/03/IMG_0286-e1553952138595-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/03/IMG_0286-e1553952138595-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/03/IMG_0286-e1553952138595-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Honestly, I didn&#8217;t read any further than &#8220;.. break off the wing&#8230;&#8221;.  So, I sent another note &#8230; &#8220;Uh&#8230; how about no.  Why can&#8217;t I use the development kit without soldering?&#8221;&#8230; And these two emails were my first steps down the Embedded FileSystem &amp; NOR Flash Rabbit Hole which is the subject of this series of articles.</p>
<h1>Making the LittleFS Work with the CY8CKIT_062_4343W</h1>
<p>I am going to start by giving you the step by step instructions to make the LittleFS work &#8230; and these instruction will only include a little bit of commentary on how it works.  I will expand on the &#8220;how&#8221; in all of the follow on articles.  To make it work you need to follow these steps:</p>
<ol>
<li>Clone the MBEDOS FileSystem Example</li>
<li>Clone my QSPI driver path</li>
<li>Then patch MBEDOS with the updated QSPI driver.</li>
<li>Test</li>
<li>Examine the Project</li>
</ol>
<p>The first step in the process of running the example is to clone the MBED OS Example Project for Filesystems.  To do this, run &#8220;mbed import mbed-os-example-filesystem&#8221;.  As I noted above, the default MBED does not have the required drivers for the Quad SPI interface.  Fortunately another excellent Applications engineer in India named Vaira built me a QSPI driver in advance of the actual official release from Cypress.  I have put these drivers on the iotexpert github repository and you can get them with a &#8220;git clone git@github.com:iotexpert/MBED_QSPI_PATCHES.git&#8221;.  Once you have them you can apply the patch by</p>
<ol>
<li>cd mbed-os-example-filesystem</li>
<li>../MBED_QSPI_PATCHES/patch-qspi-mbed.sh</li>
</ol>
<p>The shell script is simple program that copies the driver files into the correct locations in your mbed-os directory in your current project.  I will talk in detail about these files in a later article.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#!/bin/sh

cp ../MBED_QSPI_PATCHES/qspi_api.c ../MBED_QSPI_PATCHES/objects.h mbed-os/targets/TARGET_Cypress/TARGET_PSoC6
cp ../MBED_QSPI_PATCHES/targets.json mbed-os/targets
cp ../MBED_QSPI_PATCHES/PinNames.h mbed-os/targets/TARGET_Cypress/TARGET_PSOC6/TARGET_CY8CMOD_062_4343W/TARGET_CY8CPROTO_062_4343W/</pre>
<p>Here is what my terminal looks like after I run the import, clone and apply patches.</p>
<p><a href="https://iotexpert.com/?attachment_id=6640" rel="attachment wp-att-6640"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-10.21.27-AM.png" alt="" width="791" height="564" class="alignnone size-full wp-image-6640" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-10.21.27-AM.png 791w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-10.21.27-AM-600x428.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-10.21.27-AM-300x214.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-10.21.27-AM-768x548.png 768w" sizes="auto, (max-width: 791px) 100vw, 791px" /></a></p>
<p>Next I will build the project &#8220;as-is&#8221; using &#8220;<span>mbed compile -t GCC_ARM -m CY8CPROTO_062_4343W&#8221;</span></p>
<p><a href="https://iotexpert.com/?attachment_id=6642" rel="attachment wp-att-6642"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM-1024x741.png" alt="" width="1024" height="741" class="alignnone size-large wp-image-6642" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM-1024x741.png 1024w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM-600x434.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM-300x217.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM-768x556.png 768w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.05.22-PM.png 1558w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>OK, the project looks like it builds with no problems (other than a very annoying boatload of warnings &#8211; I really wish people weren&#8217;t slobs).  Running the compile also has the nice side effect of setting the default target and toolchain.  You can see this by either looking at the &#8220;.mbed&#8221; file or by running &#8220;mbed config target&#8221; or &#8220;mbed config toolchain&#8221;.  Here is what my terminal window looks like</p>
<p><a href="https://iotexpert.com/?attachment_id=6643" rel="attachment wp-att-6643"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.07.23-PM.png" alt="" width="946" height="258" class="alignnone size-full wp-image-6643" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.07.23-PM.png 946w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.07.23-PM-600x164.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.07.23-PM-300x82.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-30-at-7.07.23-PM-768x209.png 768w" sizes="auto, (max-width: 946px) 100vw, 946px" /></a></p>
<h1>Test</h1>
<p>I generally like to test a project before I start making changes to it.  I already compiled, so now, I program it into the board with either the Cypress Programmer or by running &#8220;mbed compile -f&#8221;.  When you attach a serial program to the development kit you will get something like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6646" rel="attachment wp-att-6646"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.48.22-AM.png" alt="" width="804" height="576" class="alignnone size-full wp-image-6646" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.48.22-AM.png 804w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.48.22-AM-600x430.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.48.22-AM-300x215.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.48.22-AM-768x550.png 768w" sizes="auto, (max-width: 804px) 100vw, 804px" /></a></p>
<p>So, the project seems to work.  When I run the project again (by pressing the reset button on the board), here is what I get:</p>
<p><a href="https://iotexpert.com/?attachment_id=6647" rel="attachment wp-att-6647"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.54.27-AM.png" alt="" width="647" height="456" class="alignnone size-full wp-image-6647" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.54.27-AM.png 647w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.54.27-AM-600x423.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-6.54.27-AM-300x211.png 300w" sizes="auto, (max-width: 647px) 100vw, 647px" /></a></p>
<p>But what is it doing?  First, lets get the code into an editor where we can see what is happening:</p>
<h1>Visual Studio Code</h1>
<p>Recently, I have been using <a href="https://code.visualstudio.com" target="_blank" rel="noopener noreferrer">Visual Studio Code</a> to view and edit my projects.  To make that experience better, it is a good idea to &#8220;export&#8221; the project from the MBED CLI.  This doesn&#8217;t change anything in your project, but it does create the files to make VSCODE work better.  To do this run &#8220;<span>mbed export -i vscode_gcc_arm -m CY8CPROTO_062_4343W &#8211;profile mbed-os/tools/profiles/debug.json&#8221;</span></p>
<p>When you start VSCODE it will look something like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6648" rel="attachment wp-att-6648"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM-1024x759.png" alt="" width="1024" height="759" class="alignnone size-large wp-image-6648" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM-1024x759.png 1024w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM-600x445.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM-300x222.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM-768x569.png 768w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.02.49-AM.png 1279w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When I open the directory with my project with the &#8220;File -&gt; Open &#8230;&#8221; menu</p>
<p><a href="https://iotexpert.com/?attachment_id=6649" rel="attachment wp-att-6649"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.04.47-AM.png" alt="" width="349" height="115" class="alignnone size-full wp-image-6649" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.04.47-AM.png 349w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.04.47-AM-300x99.png 300w" sizes="auto, (max-width: 349px) 100vw, 349px" /></a></p>
<p>It will look like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6650" rel="attachment wp-att-6650"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.05.34-AM.png" alt="" width="462" height="952" class="alignnone size-full wp-image-6650" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.05.34-AM.png 462w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.05.34-AM-146x300.png 146w" sizes="auto, (max-width: 462px) 100vw, 462px" /></a></p>
<h1>Examine the Project</h1>
<p>Now click on main.cpp and your screen should look like this:</p>
<p><a href="https://iotexpert.com/?attachment_id=6652" rel="attachment wp-att-6652"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM-1024x750.png" alt="" width="1024" height="750" class="alignnone size-large wp-image-6652" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM-1024x750.png 1024w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM-600x440.png 600w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM-300x220.png 300w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM-768x563.png 768w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-7.07.41-AM.png 1265w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>To make any of the MBED OS Filesystems work, they need to have a &#8220;BlockDevice&#8221; to read and write the media, meaning the SPI Flash or SD Card or &#8230; The project as it comes from ARM creates the BlockDevice on line 23 where it asks for the &#8220;default_instance&#8221;.  Those configuration files which we patched MBED with earlier sets up the default instance to be the QSPI flash on the development kit (which I will explain in great detail in a later article).</p>
<p>After you have a BlockDevice, the next thing that you need is a FileSystem object.  In this case on line 31-33 you can see that this project uses a LittleFileSystem.  The argument to the LittleFileSystem object creation is the mount point (think Unix &#8220;/fs/&#8221;).  The mount point is used by all of the POSIX APIs (open, close, read etc).  I will talk more about POSIX in later article.</p>
<pre class="start-line:30 lang:c++ decode:true ">// This example uses LittleFileSystem as the default file system
#include "LittleFileSystem.h"
LittleFileSystem fs("fs");</pre>
<p>Near the start of main, the first real thing that happens is that you need to &#8220;mount&#8221; the Filesystem onto the BlockDevice.  This is done on line 80.  The mount will return an non-zero error code if there is nothing on the SPI Flash or the SPI Flash is corrupted.  If the mount fails, the program will try to create a filesystem by calling &#8220;reformat&#8221; on line 87.  If that fails the &#8220;error&#8221; will halt the whole thing and blink the red light on the board.</p>
<pre class="start-line:80 lang:c++ decode:true ">    int err = fs.mount(bd);
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        // Reformat if we can't mount the filesystem
        // this should only happen on the first boot
        printf("No filesystem found, formatting... ");
        fflush(stdout);
        err = fs.reformat(bd);
        printf("%s\n", (err ? "Fail :(" : "OK"));
        if (err) {
            error("error: %s (%d)\n", strerror(-err), err);
        }
    }</pre>
<p>Once we have a Filesystem (object) and it is formatted, the project will try to open the file &#8220;/fs/numbers.txt&#8221; using the POSIX API &#8220;open&#8221; on line 97.  The open specifics that it is to open the file for &#8220;read&#8221; and that it will append the &#8220;+&#8221;.  If that operation fails, it will try to create the file on line 103.</p>
<pre class="start-line:97 EnlighterJSRAW" data-enlighter-language="c" "> FILE *f = fopen("/fs/numbers.txt", "r+");
    printf("%s\n", (!f ? "Fail :(" : "OK"));
    if (!f) {
        // Create the numbers file if it doesn't exist
        printf("No file found, creating a new file... ");
        fflush(stdout);
        f = fopen("/fs/numbers.txt", "w+");
        printf("%s\n", (!f ? "Fail :(" : "OK"));
        if (!f) {
            error("error: %s (%d)\n", strerror(errno), -errno);
        }</pre>
<p>If the file was opened for the first time, it will write the numbers 0-9 into the file using the loop (109) and fprintf (line 112).  The file will have lines with 4 spaces followed by a number then a &#8220;\n&#8221;.  This format was chosen to make the parsing easier later on in the program.</p>
<pre class="start-line:109 EnlighterJSRAW" data-enlighter-language="c"">        for (int i = 0; i &lt; 10; i++) {
            printf("\rWriting numbers (%d/%d)... ", i, 10);
            fflush(stdout);
            err = fprintf(f, "    %d\n", i);
            if (err &lt; 0) {
                printf("Fail :(\n");
                error("error: %s (%d)\n", strerror(errno), -errno);
            }
        }
        printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);</pre>
<p>Once the file is initialized, you want the put the file point back to the start which is done with the &#8220;fseek&#8221; on line 122.</p>
<pre class="start-line:120 EnlighterJSRAW" data-enlighter-language="c"">        printf("Seeking file... ");
        fflush(stdout);
        err = fseek(f, 0, SEEK_SET);
        printf("%s\n", (err &lt; 0 ? "Fail :(" : "OK"));
        if (err &lt; 0) {
            error("error: %s (%d)\n", strerror(errno), -errno);
        }</pre>
<p>The main part of the program will start at the top,  read the numbers and increment them, and write them back into the file.  I am not really in love with this block of code&#8230; but I suppose that it is functional.</p>
<pre class="start-line:129 EnlighterJSRAW" data-enlighter-language="c" ">    // Go through and increment the numbers
    for (int i = 0; i &lt; 10; i++) {
        printf("\rIncrementing numbers (%d/%d)... ", i, 10);
        fflush(stdout);

        // Get current stream position
        long pos = ftell(f);

        // Parse out the number and increment
        int32_t number;
        fscanf(f, "%d", &amp;number);
        number += 1;

        // Seek to beginning of number
        fseek(f, pos, SEEK_SET);
    
        // Store number
        fprintf(f, "    %d\n", number);

        // Flush between write and read on same file
        fflush(f);
    }
    printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);</pre>
<p>Once all of the numbers are incremented and written back into the file, the last step is closing the file on line 156.</p>
<pre class="start-line:153 EnlighterJSRAW" data-enlighter-language="c" ">    // Close the file which also flushes any cached writes
    printf("Closing \"/fs/numbers.txt\"... ");
    fflush(stdout);
    err = fclose(f);
    printf("%s\n", (err &lt; 0 ? "Fail :(" : "OK"));
    if (err &lt; 0) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }</pre>
<p>The next phase of the program is to do a directory listing using the POSIX directory APIs (opendir, readdir,closedir).  This little block of code will print out all of the files in the &#8220;/fs&#8221; directory.</p>
<pre class="start-line:162 EnlighterJSRAW" data-enlighter-language="c"">  // Display the root directory
    printf("Opening the root directory... ");
    fflush(stdout);
    DIR *d = opendir("/fs/");
    printf("%s\n", (!d ? "Fail :(" : "OK"));
    if (!d) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }

    printf("root directory:\n");
    while (true) {
        struct dirent *e = readdir(d);
        if (!e) {
            break;
        }

        printf("    %s\n", e-&gt;d_name);
    }

    printf("Closing the root directory... ");
    fflush(stdout);
    err = closedir(d);
    printf("%s\n", (err &lt; 0 ? "Fail :(" : "OK"));
    if (err &lt; 0) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }
</pre>
<p>Then they demonstrate opening the numbers.txt file and printing out the data.</p>
<pre class="start-line:189 EnlighterJSRAW" data-enlighter-language="c" ">    // Display the numbers file
    printf("Opening \"/fs/numbers.txt\"... ");
    fflush(stdout);
    f = fopen("/fs/numbers.txt", "r");
    printf("%s\n", (!f ? "Fail :(" : "OK"));
    if (!f) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }

    printf("numbers:\n");
    while (!feof(f)) {
        int c = fgetc(f);
        printf("%c", c);
    }

    printf("\rClosing \"/fs/numbers.txt\"... ");
    fflush(stdout);
    err = fclose(f);
    printf("%s\n", (err &lt; 0 ? "Fail :(" : "OK"));
    if (err &lt; 0) {
        error("error: %s (%d)\n", strerror(errno), -errno);
    }</pre>
<p>And finally closing things up by unmounting the filesystem.</p>
<pre class="start-line:212 EnlighterJSRAW" data-enlighter-language="c" ">   // Tidy up
    printf("Unmounting... ");
    fflush(stdout);
    err = fs.unmount();
    printf("%s\n", (err &lt; 0 ? "Fail :(" : "OK"));
    if (err &lt; 0) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
        
    printf("Mbed OS filesystem example done!\n");</pre>
<h1>Super Annoying Hard Code</h1>
<p>All through this example program the number &#8220;10&#8221; is hardcoded.  This is called a MAGIC NUMBER and in this particular case is not at all a good thing.  Moreover, lines of code like this represent absolute insanity.</p>
<pre class="start-line:151 EnlighterJSRAW" data-enlighter-language="c" ">    printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
</pre>
<p>Really&#8230; just don&#8217;t do this.  Friends don&#8217;t let friends use magic numbers.</p>
<h1>Erasing the FileSystem</h1>
<p>Near the top of main you can see that they register an interrupt to create an event when the button on the development kit is pressed.</p>
<pre class="start-line:75 EnlighterJSRAW" data-enlighter-language="c" ">   irq.fall(mbed_event_queue()-&gt;event(erase));</pre>
<p>The erase function simply initializes the block device, calls erase and then de-inits the block device.  This will cause the whole thing to begin anew when the kit is reset.</p>
<pre class="start-line:42 lang:c++ decode:true">void erase() {
    printf("Initializing the block device... ");
    fflush(stdout);
    int err = bd-&gt;init();
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }

    printf("Erasing the block device... ");
    fflush(stdout);
    err = bd-&gt;erase(0, bd-&gt;size());
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }

    printf("Deinitializing the block device... ");
    fflush(stdout);
    err = bd-&gt;deinit();
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
}
</pre>
<p>The first time I ran the erase, I thought that there was something wrong&#8230; and I ended up going through a big debug loop.  The final step in the debug loop was being patient&#8230; which isn&#8217;t really in my wheelhouse.  I added this little block of code which timed the erase operation.</p>
<pre class="start-line:63 EnlighterJSRAW" data-enlighter-language="c" ">    Timer t;
    t.start();
    err = bd-&gt;erase(0,bd-&gt;size());
    t.stop();
    
    printf("%s\n", (err ? "Fail :(" : "OK"));
    if (err) {
        error("error: %s (%d)\n", strerror(-err), err);
    }
    printf("Time in s =%f\n",((double)t.read_ms())/1000.0);</pre>
<p>And it turns out the answer is 115.06 seconds.  I am going to have to figure out why it takes so long.</p>
<p><a href="https://iotexpert.com/?attachment_id=6658" rel="attachment wp-att-6658"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-11.08.52-AM.png" alt="" width="315" height="163" class="alignnone size-full wp-image-6658" srcset="https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-11.08.52-AM.png 315w, https://iotexpert.com/wp-content/uploads/2019/03/Screen-Shot-2019-03-31-at-11.08.52-AM-300x155.png 300w" sizes="auto, (max-width: 315px) 100vw, 315px" /></a></p>
<p>The last thing to notice is that if you press the erase button while it is writing the files, Im pretty sure that something bad happens.</p>
<p>In the next articles I will examine this system in much much more detail.  Again thanks to Jaya and Vaira for their excellent work.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mbedos-little-file-system-cy8cproto_62_4343w/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MBED OS &#038; PSoC 6 &#038; SSD1306</title>
		<link>https://iotexpert.com/mbed-os-psoc-6-ssd1306/</link>
					<comments>https://iotexpert.com/mbed-os-psoc-6-ssd1306/#respond</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Sun, 17 Feb 2019 16:29:44 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[Embedded World 2019]]></category>
		<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6600</guid>

					<description><![CDATA[Summary As I wrote about in the last article I have been working to get ready for Embedded World 2019 in a week and a bit.  For my demo, I will be handing out remote controls that have a 128&#215;64 monochrome OLED display that is driven by an I2C SSD1306.  This whole board is controlled [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>As I wrote about in the <a href="https://iotexpert.com/2019/02/11/mbedos-ble/" target="_blank" rel="noopener">last article</a> I have been working to get ready for Embedded World 2019 in a week and a bit.  For my demo, I will be handing out remote controls that have a 128&#215;64 monochrome OLED display that is driven by an I2C SSD1306.  This whole board is controlled by a PSoC 6 &amp; a 4343W WiFi / Bluetooth Combo.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0227/" rel="attachment wp-att-6602"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-493x1024.jpg" alt="" width="493" height="1024" class="alignnone size-large wp-image-6602" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-493x1024.jpg 493w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-600x1246.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-144x300.jpg 144w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-768x1595.jpg 768w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0227-e1550413744346-scaled.jpg 1233w" sizes="auto, (max-width: 493px) 100vw, 493px" /></a></p>
<p>This morning I started to port the <a href="https://iotexpert.com/?s=u8g2" target="_blank" rel="noopener">U8G2</a> library to MBEDOS&#8230; but ran into some problems, so I i decided to see what ports were already out there.  I immediately found a port of the <a href="https://os.mbed.com/users/nkhorman/code/Adafruit_GFX/" target="_blank" rel="noopener">Adafruit_GFX library</a>.  This article talks about using it on my CY8CPROTO_062_4343W board.  As part of this journey I also wanted to be able to draw the Cypress logo on the screen&#8230; so I had to figure out how to create a logo in a format that could be drawn on the screen.</p>
<p>I will follow these steps:</p>
<ol>
<li>Create a new project &amp; add the Adafruit_GFX_library</li>
<li>Create a main.cpp, configure the library and test</li>
<li>Make a Cypress logo using GIMP</li>
<li>Create a function to draw X11 bitmaps &amp; test</li>
</ol>
<h1>Create a new project &amp; add the Adafruit_GFX_library</h1>
<p>The first step to get everything going by running</p>
<ol>
<li>mbed new .</li>
<li>mbed add http://os.mbed.com/users/nkhorman/code/Adafruit_GFX/</li>
</ol>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-48-am/" rel="attachment wp-att-6603"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM.png" alt="" width="797" height="465" class="alignnone size-full wp-image-6603" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM.png 797w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-600x350.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-300x175.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.48-AM-768x448.png 768w" sizes="auto, (max-width: 797px) 100vw, 797px" /></a></p>
<p>The way to figure out how to add the library is by going to the library webpage on the mbedos website.  Then clicking the arrow on &#8220;Import into Compiler&#8221; where you will see two options, &#8220;Import into Compiler&#8221; and &#8220;Import with mbed CLI&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-03-am/" rel="attachment wp-att-6606"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-1024x278.png" alt="" width="1024" height="278" class="alignnone size-large wp-image-6606" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-1024x278.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-600x163.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-300x81.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM-768x209.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.03-AM.png 1182w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>When you select that option you will get a window that tells you the exact command to run.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-41-15-am/" rel="attachment wp-att-6605"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM.png" alt="" width="402" height="161" class="alignnone size-large wp-image-6605" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM.png 402w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.41.15-AM-300x120.png 300w" sizes="auto, (max-width: 402px) 100vw, 402px" /></a></p>
<p>I have been using <a href="https://atom.io" target="_blank" rel="noopener">Atom</a> as an editor (and sort of IDE).  When you open the lcd-example directory using Atom you will see your project including</p>
<ol>
<li>The mbed-os directory with all of the mbed stuff in it.</li>
<li>The Adafruit_GFX library</li>
</ol>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-9-46-14-am/" rel="attachment wp-att-6609"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM.png" alt="" width="815" height="662" class="alignnone size-full wp-image-6609" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM.png 815w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-600x487.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-300x244.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-9.46.14-AM-768x624.png 768w" sizes="auto, (max-width: 815px) 100vw, 815px" /></a></p>
<h1>Create a main.cpp, configure the library and test</h1>
<p>The next step is to create a main.cpp.</p>
<ol>
<li>Setup the I2C.  In order to use the graphics library you need to setup a communication vehicle.  In my case that is an I2C bus that is connected to P6[0] and P6[1] on my development board.  Lines 6-15 create the communication class of I2CPreInit, configure it to 400kbs and connect the I2C master to P6[0]/P6[1]</li>
<li>Line 16 actually setups up the graphics library and get it going.</li>
<li>The main simply prints out some information about the display on lines 22-23</li>
<li>Line 24 causes the current frame buffer to be displayed (more on this in a second)</li>
<li>The main loop blinks the LED and prints a counter on the top of the screen.</li>
</ol>
<pre class="lang:c++ decode:true">#include "mbed.h"
#include "Adafruit_SSD1306.h"

DigitalOut myled(LED1);

class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(400000);
        start();
    };
};
I2CPreInit gI2C(P6_1,P6_0);
Adafruit_SSD1306_I2c gOled2(gI2C,P0_2,0x78,64,128);

int main()
{   uint16_t x=0;

    printf("Started\n");
    printf("%ux%u OLED Display\r\n", gOled2.width(), gOled2.height());
    printf("Rotation = %u\n",gOled2.getRotation());
    gOled2.display();
    while(1)
    {
        x += 1;
        myled = !myled;
        gOled2.printf("%u\r",x);
        gOled2.display();
        wait(1.0);
    }
}
</pre>
<p>In order to build this thing I run &#8220;mbed compile -t GCC_ARM -m CY8CPROTO_062_4343w&#8221;.  When I run the project it looks like this:</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0228/" rel="attachment wp-att-6612"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-1024x768.jpg" alt="" width="1024" height="768" class="alignnone wp-image-6612 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0228-e1550416310771-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>There are several things to notice about this picture.  First, there is an Adafruit logo on the screen.  Where did this come from?  Simple on line 152 of Adafruit_ssd1306.cpp there is a function called &#8220;splash&#8221; which is called by the constructor.  The spash function just copies a bitmap into the frame buffer of the Adafruit_SSD1306 object.</p>
<pre class="start-line:152 EnlighterJSRAW" data-enlighter-language="c" ">void Adafruit_SSD1306::splash(void)
{
#ifndef NO_SPLASH_ADAFRUIT
	uint8_t adaFruitLogo[64 * 128 / 8] =
	{ 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
</pre>
<p>The constructor is in Adafruit_ssd1306.h on line 152</p>
<pre class="start-line:173 lang:c++ decode:true ">	Adafruit_SSD1306_I2c(I2C &amp;i2c, PinName RST, uint8_t i2cAddress = SSD_I2C_ADDRESS, uint8_t rawHeight = 32, uint8_t rawWidth = 128)
	    : Adafruit_SSD1306(RST, rawHeight, rawWidth)
	    , mi2c(i2c)
	    , mi2cAddress(i2cAddress)
	    {
		    begin();
		    splash();
		    display();
	    };</pre>
<p>And if you don&#8217;t want to have this splash screen you can uncomment the #define NO_SPLASH_ADAFRUIT in the file &#8220;Adafruit_GFC_Config.h&#8221;</p>
<pre class="lang:c++ decode:true ">#ifndef _ADAFRUIT_GFX_CONFIG_H_
#define _ADAFRUIT_GFX_CONFIG_H_

// Uncomment this to turn off the builtin splash
#define NO_SPLASH_ADAFRUIT

// Uncomment this to enable all functionality
//#define GFX_WANT_ABSTRACTS

// Uncomment this to enable only runtime font scaling, without all the rest of the Abstracts
//#define GFX_SIZEABLE_TEXT


#endif</pre>
<p>The next thing to notice in the picture is that I have lead wires attached to the LCD pins&#8230; and those wires are attached to a logic analyzer because I typed the I2C incorrectly and I couldn&#8217;t figure out why they didn&#8217;t talk.  And finally notice my grandfathers magnifying glass which I use every day.</p>
<h1>Make a Cypress logo using GIMP</h1>
<p>For my project I am less interested in displaying Adafruits Logo and more interested in displaying Cypress&#8217;.  To do this I loaded up the Cypress logo in <a href="https://www.gimp.org" target="_blank" rel="noopener">Gimp</a>.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-22-23-am/" rel="attachment wp-att-6614"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-1024x658.png" alt="" width="1024" height="658" class="alignnone size-large wp-image-6614" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-1024x658.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-600x385.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-300x193.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM-768x493.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.22.23-AM.png 1194w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>I then converted it to pure black and white using the &#8220;Image-&gt;Mode-&gt;Indexed&#8230;&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-23-11-am/" rel="attachment wp-att-6616"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM.png" alt="" width="438" height="156" class="alignnone size-large wp-image-6616" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM.png 438w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.11-AM-300x107.png 300w" sizes="auto, (max-width: 438px) 100vw, 438px" /></a></p>
<p>Then selected &#8220;black and white palette&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-23-23-am/" rel="attachment wp-att-6615"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM.png" alt="" width="367" height="395" class="alignnone size-full wp-image-6615" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM.png 367w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.23.23-AM-279x300.png 279w" sizes="auto, (max-width: 367px) 100vw, 367px" /></a></p>
<p>Then I scaled the image to 128&#215;40 using the &#8220;Image-&gt;Scale Image&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-10-am/" rel="attachment wp-att-6619"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.10-AM.png" alt="" width="226" height="194" class="alignnone size-large wp-image-6619" /></a></p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-22-am/" rel="attachment wp-att-6618"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM.png" alt="" width="380" height="385" class="alignnone size-large wp-image-6618" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM.png 380w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM-100x100.png 100w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.22-AM-296x300.png 296w" sizes="auto, (max-width: 380px) 100vw, 380px" /></a></p>
<p>Unfortunately it made a bit of a mess of the logo during the scaling process&#8230; so I put my son to editing it.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-25-52-am/" rel="attachment wp-att-6617"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM.png" alt="" width="654" height="390" class="alignnone size-full wp-image-6617" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM.png 654w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM-600x358.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.25.52-AM-300x179.png 300w" sizes="auto, (max-width: 654px) 100vw, 654px" /></a></p>
<p>Which looks like this after he was done.  Pretty good eh?</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-28-26-am/" rel="attachment wp-att-6620"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM.png" alt="" width="542" height="317" class="alignnone size-full wp-image-6620" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM.png 542w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.28.26-AM-300x175.png 300w" sizes="auto, (max-width: 542px) 100vw, 542px" /></a></p>
<p>In order to use the image you need a &#8220;C program&#8221; version of it.  It turns out that there is a format called &#8220;X11&#8221; or &#8220;xbm&#8221; which is exactly that (a c-file).  You can read about the format on <a href="http://www.fileformat.info/format/xbm/egff.htm" target="_blank" rel="noopener">this website</a>.  To get one of these files, just run &#8220;File-&gt;Export As&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-14-am/" rel="attachment wp-att-6623"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.14-AM.png" alt="" width="204" height="281" class="alignnone size-full wp-image-6623" /></a></p>
<p>Then give it a name with a &#8220;.xbm&#8221; on the end</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-45-am/" rel="attachment wp-att-6622"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM.png" alt="" width="617" height="117" class="alignnone size-large wp-image-6622" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM.png 617w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM-600x114.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.45-AM-300x57.png 300w" sizes="auto, (max-width: 617px) 100vw, 617px" /></a></p>
<p>Make sure and &#8220;de-select the X10 format bitmap&#8221; (and older version of the xbm format)</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/screen-shot-2019-02-17-at-10-29-56-am/" rel="attachment wp-att-6621"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM.png" alt="" width="321" height="351" class="alignnone size-full wp-image-6621" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM.png 321w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-17-at-10.29.56-AM-274x300.png 274w" sizes="auto, (max-width: 321px) 100vw, 321px" /></a></p>
<p>When all that is said and done you will find the xbm file with goodness in it.  Here is the top of it.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c">#define cylogo_width 128
#define cylogo_height 40
static unsigned char cylogo_bits[] = {
   0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x3f,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
</pre>
<p>The format of this file is unsigned 8-bit integers&#8230; each bit represents the bit of one pixel&#8230; in BIG ENDIAN!!!! format.  In other words this table will be 128&#215;40/8 bytes long.</p>
<h1>Create a function to draw X11 bitmaps &amp; test</h1>
<p>But how do we use this format?  Well, write a new function in the Adafruit library to draw X11 bitmaps.</p>
<p>First add the new function name to the class on line 168 of &#8220;Adafruit_GFX.h&#8221;</p>
<pre class="start-line:72 EnlighterJSRAW" data-enlighter-language="c"">    virtual void drawX11BitMap(const uint8_t bitmap[],uint16_t bitMapWidth,uint16_t bitMapSize,uint16_t posX,uint16_t posY);
</pre>
<p>Then add the code.</p>
<pre class="start-line:152 EnlighterJSRAW" data-enlighter-language="c"">// Write an X11 formatted bitmap to the screen at posX, posY
void Adafruit_GFX::drawX11BitMap(const uint8_t bitmap[],uint16_t bitMapWidth,uint16_t bitMapSize,uint16_t posX,uint16_t posY)
{
  int16_t x1 = posX;
  int16_t y1 = posY;

  for(unsigned int i=0;i&lt;bitMapSize;i++)
  {
    uint8_t val = bitmap[i];

    for(int j=0;j&lt;8;j++)
    {
        uint16_t pixColor;
        if(val&gt;&gt;j &amp; 0x01)
          pixColor = 1;
        else
          pixColor = 0;

        drawPixel(x1,y1, pixColor);
        x1 = x1 + 1;
        if(x1 == posX + bitMapWidth)
        {
          x1 = posX;
          y1 = y1 + 1;
        }
    }
  }</pre>
<p>This may not be the most beautiful code in the world&#8230; which I suppose makes it fit right in with some of the other stuff in this driver.  Oh well it works.</p>
<p>Once you have added the function to the library, lets test it to see if it can draw the logo.  First, copy the &#8220;cylogo.xbm&#8221; into the project and call it &#8220;cylogo.h&#8221;.  Then modify the &#8220;main.cpp&#8221; to use it.  Add an include of the &#8220;cylogo.h&#8221;.  Then on line 26, call the function to draw it at 0,(half way down the screen)</p>
<pre class="lang:c++ decode:true ">#include "mbed.h"
#include "Adafruit_SSD1306.h"
#include "cylogo.h"
DigitalOut myled(LED1);

class I2CPreInit : public I2C
{
public:
    I2CPreInit(PinName sda, PinName scl) : I2C(sda, scl)
    {
        frequency(400000);
        start();
    };
};
I2CPreInit gI2C(P6_1,P6_0);
Adafruit_SSD1306_I2c gOled2(gI2C,P0_2,0x78,64,128);

int main()
{   uint16_t x=0;

    printf("Started\n");
    printf("%ux%u OLED Display\r\n", gOled2.width(), gOled2.height());
    printf("Rotation = %u\n",gOled2.getRotation());


    gOled2.drawX11BitMap(cylogo_bits,cylogo_width,sizeof(cylogo_bits),0,(64-cylogo_height)/2);

    gOled2.display();
</pre>
<p>When you program this&#8230; everything seems to be good.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0229/" rel="attachment wp-att-6625"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-6625" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0229-e1550418582969-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>By the way if it isn&#8217;t clear by now, I did a solder in a male header onto the board so that I could attach the I2C wires for the display.</p>
<p><a href="https://iotexpert.com/2019/02/17/mbed-os-psoc-6-ssd1306/img_0230/" rel="attachment wp-att-6626"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-1024x768.jpg" alt="" width="1024" height="768" class="alignnone size-large wp-image-6626" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-1024x768.jpg 1024w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-600x450.jpg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-300x225.jpg 300w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_0230-e1550418732146-768x576.jpg 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mbed-os-psoc-6-ssd1306/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MBEDOS &#038; BLE &#038; PSoC 6 &#038; CYW4343W</title>
		<link>https://iotexpert.com/mbedos-ble/</link>
					<comments>https://iotexpert.com/mbedos-ble/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Mon, 11 Feb 2019 22:04:06 +0000</pubDate>
				<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6585</guid>

					<description><![CDATA[Summary At the Embedded World Show in Germany in a couple of weeks I am going to be showing a crazy demo (more on this later) that uses MBED OS and BLE and WiFi and PSoC 6 and the 4343W.  Given how close things are and how new MBED OS is to me I figure [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>At the Embedded World Show in Germany in a couple of weeks I am going to be showing a crazy demo (more on this later) that uses MBED OS and BLE and WiFi and PSoC 6 and the 4343W.  Given how close things are and how new MBED OS is to me I figure that I had better get going sorting out the BLE interface.   This article and probably the next several are going to show my progress through the learning curve.</p>
<p>It turns out that in MBED OS, instead of using the Cypress BLE Host Stack I will be using the ARM Cordio BLE host stack talking via HCI to the Cypress BLE Controller stack running on the 4343W (a Bluetooth, BLE and WiFi combo chip).  At this point all of my experience with BLE has been with Cypress stacks, either the PSoC 4/6 BLE stack or with the Cypress IoT stacks e.g. the CYW20719.  Lot&#8217;s of new learning.  Add in that all of the code is in C++ and it makes for an adventure.</p>
<p>For this article I will show the steps to get an ARM BLE example going on the CY8CPROTO_062_4343W development kit.  This will involve.</p>
<ol>
<li>Importing the ARM MBEDOS BLE Examples</li>
<li>Modifying them to support the Cypress Targets &amp; Test</li>
<li>Updating an example program in a few places to fix things that I don&#8217;t like.</li>
</ol>
<h1>Import ARM MBED OS BLE Examples</h1>
<p>The first step is to make a clone of the ARM examples by running &#8220;mbed import mbed-os-example-ble&#8221;.  This will load a bunch of different example projects (as libraries)</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM-1024x749.png" alt="" width="1024" height="749" class="alignnone wp-image-6587 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM-1024x749.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM-600x439.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM-300x219.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM-768x562.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.43.25-AM.png 1214w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Then, when you look at what you have after all of that mess, you can see 14 example programs with promising names.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM.png" alt="" width="791" height="241" class="alignnone wp-image-6588 size-full" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM.png 791w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM-600x183.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM-300x91.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-9.51.05-AM-768x234.png 768w" sizes="auto, (max-width: 791px) 100vw, 791px" /></a></p>
<p>When you look in the BLE_LED directory you will find a file &#8220;readme.md&#8221; which is a markdown formatted file.  You can view this file on the GitHub website for this example <a href="https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED" target="_blank" rel="noopener">here</a>.  The top of this one looks promising:</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM.png"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM.png" alt="" width="983" height="305" class="alignnone wp-image-6590 size-full" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM.png 983w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM-600x186.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM-300x93.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-11-at-11.47.24-AM-768x238.png 768w" sizes="auto, (max-width: 983px) 100vw, 983px" /></a></p>
<h1>Modify and Test</h1>
<p>I decide that the example called &#8220;<a href="https://github.com/ARMmbed/mbed-os-example-ble/tree/master/BLE_LED" target="_blank" rel="noopener">BLE_LED</a>&#8221; looks like a good place to start.  This example is a simple peripheral that advertises it name.  When you connect to it there is a Service with UUID &#8220;0xA000&#8221; (unfortunately a 16-bit UUID&#8230; bad demo code) that Service has one characteristic with UUID 0xA001 (another 16-UUID &#8230; that isn&#8217;t nice &#8230; come on people&#8230; haven&#8217;t you read the spec?).  When you write a &#8220;1&#8221; to that characteristic the LED2 is supposed to turn on, and when you write a 0 the LED2 is supposed to turn off.</p>
<p>First, until the Cypress stuff is accepted into the main release, I need to update mbed-os to our targets) with &#8220;cd mbed-os ; mbed update master&#8221;.  To build this project Ill run &#8220;<span>mbed compile -t GCC_ARM -m CY8CPROTO_062_4343W&#8221;.  </span>When I program the the development kit, the LED starts blinking and I am able to see it using the GATT browser <a href="https://itunes.apple.com/us/app/lightblue-explorer/id557428110?mt=8" target="_blank" rel="noopener">LightBlue Explorer</a>.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1.jpeg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1-473x1024.jpeg" alt="" width="473" height="1024" class="alignnone wp-image-6593 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1-473x1024.jpeg 473w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1-600x1299.jpeg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1-139x300.jpeg 139w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1-768x1663.jpeg 768w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_84C430E4C9BF-1.jpeg 1125w" sizes="auto, (max-width: 473px) 100vw, 473px" /></a></p>
<p>But when I try to write a 1 to the 0xA001 characteristic nothing happens.</p>
<p><a href="https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1.jpeg"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1-473x1024.jpeg" alt="" width="473" height="1024" class="alignnone wp-image-6592 size-large" srcset="https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1-473x1024.jpeg 473w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1-600x1299.jpeg 600w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1-139x300.jpeg 139w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1-768x1663.jpeg 768w, https://iotexpert.com/wp-content/uploads/2019/02/IMG_7268944B9471-1.jpeg 1125w" sizes="auto, (max-width: 473px) 100vw, 473px" /></a></p>
<p>So, what gives? The answer is that on line 32 you can see that the authors as assuming that you have two LEDs (my development kit only has one.</p>
<pre class="start-line:32 lang:c++ decode:true ">        _alive_led(LED2, 1),
        _actuated_led(LED1, 0),</pre>
<p>And on line 124 you can see a function that inverts the LED</p>
<pre class="start-line:124 EnlighterJSRAW" data-enlighter-language="c" ">void blink() {
        _alive_led = !_alive_led;
    }
</pre>
<p>which is triggered on line 47 to be called every 500ms</p>
<pre class="start-line:42 lang:c++ decode:true">    void start() {
        _ble.gap().setEventHandler(this);

        _ble.init(this, &amp;LEDDemo::on_init_complete);

        _event_queue.call_every(2000, this, &amp;LEDDemo::blink);

        _event_queue.dispatch_forever();
    }</pre>
<p>OK.  I am not loving this. I think that I should make some updates to this project.</p>
<h1>Update</h1>
<p>There are several things that I don&#8217;t like about this program or need to be fixed.</p>
<ol>
<li>Make the user LED2 be LED1 and fix the fact that it is active low.</li>
<li>Change the UUIDs of the Service and Characteristic to be legal 128-bit UUIDs</li>
<li>Make the stdio print out the status of the connection (instead of the blinking LED1)</li>
<li>Make the baud rate of standard i/o be 115200 instead of 9600</li>
</ol>
<p>First, fix the LED2 to be LED1.  Do this by commenting out all of the _alive_led code and switching the _actuated_led to be LED1.  Also set the state of the LED1 to 1 (meaning off because it is active low)</p>
<pre class="start-line:40 EnlighterJSRAW" data-enlighter-language="c"">        //_alive_led(LED1, 1),
        _actuated_led(LED1, 1),</pre>
<p>The author of the example code has a function called blink which is executed by the event queue every 500ms, comment out that function</p>
<pre class="start-line:131 EnlighterJSRAW" data-enlighter-language="c" ">/*
    void blink() {
        _alive_led = !_alive_led;
    }
*/</pre>
<p>And don&#8217;t inject events into the queue to run the blink function</p>
<pre class="start-line:55 EnlighterJSRAW" data-enlighter-language="c" ">        //_event_queue.call_every(500, this, &amp;LEDDemo::blink);</pre>
<p>The LED on my board is active low&#8230; so instead of writing the value write the opposite of the value.</p>
<pre class="start-line:128 lang:c++ decode:true ">            _actuated_led = !*(params-&gt;data);
</pre>
<p>It is illegal in Bluetooth to use 16-bit UUIDs without first registering them with the Bluetooth SIG and having them be &#8220;Assigned numbers&#8221;.  The author of this example program violated the specification by assigning the LED service UUID of 0xA000 and the LED characteristic UUID of 0xA001.  This is super annoying and I am not willing to be a slob.  To fix this modify ledservice.h to declare the UUIDs as UUID type instead of uint16_ts</p>
<pre class="start-line:22 EnlighterJSRAW" data-enlighter-language="c" ">    //const static uint16_t LED_SERVICE_UUID              = 0xA000;
    //const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;

    const static UUID LED_SERVICE_UUID;
    const static UUID LED_STATE_CHARACTERISTIC_UUID;</pre>
<p>Then initialize them in the main.cpp as 128-bit UUIDs using the const char * initializer.</p>
<pre class="wrap-toggle:false start-line:30 EnlighterJSRAW" data-enlighter-language="c" ">const UUID LEDService::LED_SERVICE_UUID("21c04d09-c884-4af1-96a9-52e4e4ba195b");
const UUID LEDService::LED_STATE_CHARACTERISTIC_UUID("1e500043-6b31-4a3d-b91e-025f92ca9763");</pre>
<p>The original code has a blinking LED.  Which I dont really like.  Typically, I like to blink the LED when the device is advertising, and make it be solid when there is a connection.  However, as I only have one LED on my board, and I have allocated it to be the &#8220;_actuated_led&#8221;, I will use the UART to print out status changes.  To do this, I update the &#8220;onDisconnectionComplete&#8221; and &#8220;onConnectionComplete&#8221; events to print out that fact to stdio.</p>
<pre class="start-line:139 EnlighterJSRAW" data-enlighter-language="c"">    void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&amp;) {
        _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
        printf("DisconnectionCompleteEvent\n");
    }

    void onConnectionComplete	(	const ble::ConnectionCompleteEvent &amp; 	event	)
    {
      printf("onConnectionComplete\n");
    }
</pre>
<p>In order to set the stdio to use 115200 instead of 9600 you can change the default rate of the UART in the mbed_app.json.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">  "CY8CPROTO_062_4343W": {
            "platform.stdio-baud-rate": 115200,
            "platform.default-serial-baud-rate": 115200
        },</pre>
<p>Here is the final version of main.cpp</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include &lt;events/mbed_events.h&gt;
#include &lt;mbed.h&gt;
#include "ble/BLE.h"
#include "LEDService.h"
#include "pretty_printer.h"

const static char DEVICE_NAME[] = "LED";

static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);

//const UUID::LongUUIDBytes_t testbytes = { 0x21, 0xc0, 0x4d, 0x09, 0xc8, 0x84, 0x4a, 0xf1, 0x96, 0xa9, 0x52, 0xe4, 0xe4, 0xba, 0x19, 0x5b } ;
// {0x1e, 0x50, 0x00, 0x43, 0x6b, 0x31, 0x4a, 0x3d, 0xb9, 0x1e, 0x02, 0x5f, 0x92, 0xca, 0x97, 0x63}
//const UUID LEDService::LED_SERVICE_UUID(testbytes,UUID::MSB);
const UUID LEDService::LED_SERVICE_UUID("21c04d09-c884-4af1-96a9-52e4e4ba195b");
const UUID LEDService::LED_STATE_CHARACTERISTIC_UUID("1e500043-6b31-4a3d-b91e-025f92ca9763");

class LEDDemo : ble::Gap::EventHandler {
public:


    LEDDemo(BLE &amp;ble, events::EventQueue &amp;event_queue) :
        _ble(ble),
        _event_queue(event_queue),
        //_alive_led(LED1, 1),
        _actuated_led(LED1, 1),
        _led_uuid(LEDService::LED_SERVICE_UUID),
        _led_service(NULL),
        _adv_data_builder(_adv_buffer) { }

    ~LEDDemo() {
        delete _led_service;
    }

    void start() {
        _ble.gap().setEventHandler(this);

        _ble.init(this, &amp;LEDDemo::on_init_complete);

        //_event_queue.call_every(500, this, &amp;LEDDemo::blink);

        _event_queue.dispatch_forever();
    }

private:
    /** Callback triggered when the ble initialization process has finished */
    void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
        if (params-&gt;error != BLE_ERROR_NONE) {
            printf("Ble initialization failed.");
            return;
        }

        _led_service = new LEDService(_ble, false);

        _ble.gattServer().onDataWritten(this, &amp;LEDDemo::on_data_written);

        print_mac_address();

        start_advertising();
    }

    void start_advertising() {
        /* Create advertising parameters and payload */

        ble::AdvertisingParameters adv_parameters(
            ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
            ble::adv_interval_t(ble::millisecond_t(1000))
        );

        _adv_data_builder.setFlags();
        _adv_data_builder.setLocalServiceList(mbed::make_Span(&amp;_led_uuid, 1));
        _adv_data_builder.setName(DEVICE_NAME);

        /* Setup advertising */

        ble_error_t error = _ble.gap().setAdvertisingParameters(
            ble::LEGACY_ADVERTISING_HANDLE,
            adv_parameters
        );

        if (error) {
            printf("_ble.gap().setAdvertisingParameters() failed\r\n");
            return;
        }

        error = _ble.gap().setAdvertisingPayload(
            ble::LEGACY_ADVERTISING_HANDLE,
            _adv_data_builder.getAdvertisingData()
        );

        if (error) {
            printf("_ble.gap().setAdvertisingPayload() failed\r\n");
            return;
        }

        /* Start advertising */

        error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);

        if (error) {
            printf("_ble.gap().startAdvertising() failed\r\n");
            return;
        }
    }

    /**
     * This callback allows the LEDService to receive updates to the ledState Characteristic.
     *
     * @param[in] params Information about the characterisitc being updated.
     */
    void on_data_written(const GattWriteCallbackParams *params) {
        if ((params-&gt;handle == _led_service-&gt;getValueHandle()) &amp;&amp; (params-&gt;len == 1)) {
            _actuated_led = !*(params-&gt;data);
        }
    }
/*
    void blink() {
        _alive_led = !_alive_led;
    }
*/
private:
    /* Event handler */

    void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&amp;) {
        _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
        printf("DisconnectionCompleteEvent\n");
    }

    void onConnectionComplete	(	const ble::ConnectionCompleteEvent &amp; 	event	)
    {
      printf("onConnectionComplete\n");
    }

private:
    BLE &amp;_ble;
    events::EventQueue &amp;_event_queue;
    //DigitalOut _alive_led;
    DigitalOut _actuated_led;

    UUID _led_uuid;
    LEDService *_led_service;

    uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
    ble::AdvertisingDataBuilder _adv_data_builder;
};

/** Schedule processing of events from the BLE middleware in the event queue. */
void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
    event_queue.call(Callback&lt;void()&gt;(&amp;context-&gt;ble, &amp;BLE::processEvents));
}

int main()
{
    printf("Example Bluetooth\n");
    BLE &amp;ble = BLE::Instance();
    ble.onEventsToProcess(schedule_ble_events);

    LEDDemo demo(ble, event_queue);
    demo.start();

    return 0;
}
</pre>
<p>And LEDService.h</p>
<pre class="EnlighterJSRAW" data-enlighter-language="c" ">/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __BLE_LED_SERVICE_H__
#define __BLE_LED_SERVICE_H__

class LEDService {
public:
    //const static uint16_t LED_SERVICE_UUID              = 0xA000;
    //const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;

    const static UUID LED_SERVICE_UUID;
    const static UUID LED_STATE_CHARACTERISTIC_UUID;

    LEDService(BLEDevice &amp;_ble, bool initialValueForLEDCharacteristic) :
        ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &amp;initialValueForLEDCharacteristic)
    {
        GattCharacteristic *charTable[] = {&amp;ledState};
        GattService         ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));

        ble.gattServer().addService(ledService);
    }

    GattAttribute::Handle_t getValueHandle() const
    {
        return ledState.getValueHandle();
    }

private:
    BLEDevice                         &amp;ble;
    ReadWriteGattCharacteristic&lt;bool&gt; ledState;
};

#endif /* #ifndef __BLE_LED_SERVICE_H__ */
</pre>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/mbedos-ble/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Cypress &#038; MBED OS</title>
		<link>https://iotexpert.com/cypress-mbed-os/</link>
					<comments>https://iotexpert.com/cypress-mbed-os/#comments</comments>
		
		<dc:creator><![CDATA[Alan Hawse]]></dc:creator>
		<pubDate>Sat, 09 Feb 2019 13:00:20 +0000</pubDate>
				<category><![CDATA[4343W]]></category>
		<category><![CDATA[CY8CPROTO-062-4343W]]></category>
		<category><![CDATA[MBED OS]]></category>
		<category><![CDATA[PSoC 6]]></category>
		<guid isPermaLink="false">https://iotexpert.com/?p=6550</guid>

					<description><![CDATA[Summary This morning I saw something exciting.  When I went to the ARM mbed-os GitHub site I saw the latest accepted merge commit was from vmedcy and it says something interesting.  &#8220;Add Cypress PSoC 6 Targets&#8221;.  I cannot even begin to describe how gratifying it is to see this commit. But what does it mean? [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Summary</h1>
<p>This morning I saw something exciting.  When I went to the<a href="https://github.com/ARMmbed/mbed-os" target="_blank" rel="noopener"> ARM mbed-os GitHub</a> site I saw the latest accepted merge commit was from vmedcy and it says something interesting.  &#8220;Add Cypress PSoC 6 Targets&#8221;.  I cannot even begin to describe how gratifying it is to see this commit.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-5-53-34-am/" rel="attachment wp-att-6551"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-1024x338.png" alt="" width="1024" height="338" class="alignnone size-large wp-image-6551" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-1024x338.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-600x198.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-300x99.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM-768x253.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-5.53.34-AM.png 1978w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But what does it mean?  Lets look.  I am using a Mac, so I simply install the MBED-CLI using the instructions found on the <a href="https://os.mbed.com/docs/mbed-os/v5.11/tools/installation-and-setup.html" target="_blank" rel="noopener">MBED CLI webpage</a>.</p>
<p>Like all good embedded people, the first thing to do is make sure that the toolchain and everything else works using a simple blinking LED project.  And, the easiest way to do this is to import the ARM example using: &#8220;<span>mbed import mbed-os-example-blinky&#8221;.</span></p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-6-07-26-am/" rel="attachment wp-att-6552"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-1024x535.png" alt="" width="1024" height="535" class="alignnone size-large wp-image-6552" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-1024x535.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-600x314.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-300x157.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM-768x401.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.07.26-AM.png 1186w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>The current release of mbed-os is 5.11.3 which you can see on the Tags page of the <a href="https://github.com/ARMmbed/mbed-os/tags" target="_blank" rel="noopener">mbed-os</a> GitHub site.  Notice in the screenshot above that the commit number for mbed-os is &#8220;a8d1d2&#8230;&#8221;  which means that by default, when you import a project it gives you the &#8220;latest&#8221; version of mbed-os, which really means the latest official release.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-6-11-14-am/" rel="attachment wp-att-6554"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-1024x919.png" alt="" width="1024" height="919" class="alignnone size-large wp-image-6554" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-1024x919.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-600x539.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-300x269.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM-768x690.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-6.11.14-AM.png 1058w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>But, I want to use the version that was accepted with the new Cypress stuff (which will become part of the official release starting with mbed-os-5.11.4).  I can do this by running &#8220;cd mbed-os&#8221; and &#8220;mbed update master&#8221;.  This will move the git repository to point at the head of the master branch, AKA the latest and greatest.  When I do that I get a version that looks like &#8220;32525&#8230;&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-18-30-am/" rel="attachment wp-att-6556"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM.png" alt="" width="853" height="219" class="alignnone size-full wp-image-6556" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM.png 853w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-600x154.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-300x77.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.18.30-AM-768x197.png 768w" sizes="auto, (max-width: 853px) 100vw, 853px" /></a></p>
<p>And when I look at the commit history in GitHub I can see the interesting commit has the same number.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-19-45-am/" rel="attachment wp-att-6557"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-1024x310.png" alt="" width="1024" height="310" class="alignnone size-large wp-image-6557" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-1024x310.png 1024w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-600x182.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-300x91.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM-768x233.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.19.45-AM.png 1148w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<p>Now to the good stuff.  When I look in the targets directory I see that there is a TARGET_CYPRESS.  Where is see two targets:</p>
<ul>
<li>TARGET_PSOC &#8211; the stuff that Cypress created</li>
<li>TARGET_PSOC6_FUTURE &#8211; a really cool target that Future Electronics created.</li>
</ul>
<p>When when I look in the Cypress directory I see a bunch of my favorite Cypress PSoC 6 and WICED wireless development Kits.</p>
<ul>
<li>TARGET_CY8CKIT_062_BLE</li>
<li>TARGET_CY8CKIT_062_4343W</li>
<li>TARGET_CY8CKIT_062_WIFI_BT</li>
<li>TARGET_CYW943012P6EVB_01</li>
<li>TARGET_CY8CMOD_062_4343W</li>
<li>TARGET_CY8CPROTO_062_4343W</li>
</ul>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-25-52-am/" rel="attachment wp-att-6559"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM.png" alt="" width="851" height="468" class="alignnone size-full wp-image-6559" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM.png 851w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-600x330.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-300x165.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.25.52-AM-768x422.png 768w" sizes="auto, (max-width: 851px) 100vw, 851px" /></a></p>
<p>I happen to have a <a href="https://www.cypress.com/documentation/development-kitsboards/psoc-6-wi-fi-bt-prototyping-kit" target="_blank" rel="noopener">CY8CPROTO_062_4343W</a> on my desk at home.  This kit has a bunch of cool stuff on it, but most importantly it a 4343W WiFi Bluetooth Combo chip and a PSoC 6 together.  Finally, A PSoC 6 2M (which is really called CY8C624ABZI-D44) and a WICED 4343W &#8211; a Dual Band 802.11n and Bluetooth 5.0 Combo.  Here is a picture from the development <a href="https://www.cypress.com/file/457891/download" target="_blank" rel="noopener">kit guide</a>.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-43-09-am/" rel="attachment wp-att-6564"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-967x1024.png" alt="" width="967" height="1024" class="alignnone size-large wp-image-6564" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-967x1024.png 967w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-600x635.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-283x300.png 283w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM-768x813.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.43.09-AM.png 1039w" sizes="auto, (max-width: 967px) 100vw, 967px" /></a></p>
<p>Now we have something to program.  Let&#8217;s look at the blinking LED example program.  It resides in the file &#8220;main.cpp&#8221; which is in the root directory of the &#8220;mbed-os-example-blinky&#8221;</p>
<pre class="lang:c++ decode:true ">/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"
#include "stats_report.h"

DigitalOut led1(LED1);

#define SLEEP_TIME                  500 // (msec)
#define PRINT_AFTER_N_LOOPS         20

// main() runs in its own thread in the OS
int main()
{
    SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */);

    int count = 0;
    while (true) {
        // Blink LED and wait 0.5 seconds
        led1 = !led1;
        wait_ms(SLEEP_TIME);

        if ((0 == count) || (PRINT_AFTER_N_LOOPS == count)) {
            // Following the main thread wait, report on the current system status
            sys_state.report_state();
            count = 0;
        }
        ++count;
    }
}
</pre>
<p>This looks simple enough, but I am never a fan of &#8220;other&#8221; stuff in the blinking LED example.  So Ill trim it down to the most basic.</p>
<pre class="lang:c++ decode:true ">/* mbed Microcontroller Library
 * Copyright (c) 2018 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"

DigitalOut led1(LED1);

#define SLEEP_TIME                  500 // (msec)

// main() runs in its own thread in the OS
int main()
{
    while (true) {
        // Blink LED and wait 0.5 seconds
        led1 = !led1;
        wait_ms(SLEEP_TIME);
    }
}
</pre>
<p>All-right, how do I compile this?  Well, run the mbed command line interface with &#8220;<span>mbed compile -m CY8CPROTO_062_4343W -t GCC_ARM</span>&#8220;&#8230; and after a bit of compiling you should end up with a window like this:</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-8-52-14-am/" rel="attachment wp-att-6565"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM.png" alt="" width="852" height="731" class="alignnone size-full wp-image-6565" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM.png 852w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-600x515.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-300x257.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-8.52.14-AM-768x659.png 768w" sizes="auto, (max-width: 852px) 100vw, 852px" /></a></p>
<p>&nbsp;</p>
<p>Now I have a &#8220;hex file&#8221;.  How do I program it?  There are three ways.</p>
<p>#1 You can add the &#8220;-f&#8221; option to the command line and it will &#8220;flash&#8221; the device after it gets done compiling using PyOCD.  In order to do this your development kit&#8217;s KitProg 3 must be in the DAPLink mode.  To get into this mode hold down the KitProg button for 2 seconds and the LED will turn off. (If the LED turns on that means you put the programmer into CMSIS-DAP mode, so hold down the button for 2 seconds again).  At the time of this writing the -f option doesn&#8217;t work in the released version of mbed-cli,  but that will be fixed shortly with an update to the program debug system in mbed (hopefully by the time you read this)</p>
<p>#2 Copy the hex file from the BUILD directory onto the Mass Storage device called &#8220;DAP Link&#8221; using the finder. (drag and drop).  To use this method your KitProg needs to be in DAPLink mode.  (so follow the steps above)</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-10-00-13-am/" rel="attachment wp-att-6580"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM.png" alt="" width="925" height="482" class="alignnone size-full wp-image-6580" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM.png 925w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-600x313.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-300x156.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-10.00.13-AM-768x400.png 768w" sizes="auto, (max-width: 925px) 100vw, 925px" /></a></p>
<p>#3 Use the &#8220;Cypress Programmer&#8221; to program the flash.  You can download it for Windows, Mac or Linux from this <a href="https://www.cypress.com/products/psoc-programming-solutions" target="_blank" rel="noopener">link</a> on cypress.com  When I run Cypress Programmer it looks like this:</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-06-25-am/" rel="attachment wp-att-6570"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM.png" alt="" width="891" height="549" class="alignnone size-full wp-image-6570" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM.png 891w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-600x370.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-300x185.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.06.25-AM-768x473.png 768w" sizes="auto, (max-width: 891px) 100vw, 891px" /></a></p>
<p>Open the hex file by pressing the &#8220;Open&#8221; button and navigating into the BUILD directory to find the hex file called &#8220;mbed-os-example-blinky.hex&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-08-32-am/" rel="attachment wp-att-6571"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM.png" alt="" width="638" height="499" class="alignnone size-full wp-image-6571" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM.png 638w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM-600x469.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.08.32-AM-300x235.png 300w" sizes="auto, (max-width: 638px) 100vw, 638px" /></a></p>
<p>Then press &#8220;connect&#8221; and &#8220;program&#8221;</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-09-56-am/" rel="attachment wp-att-6572"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-789x1024.png" alt="" width="789" height="1024" class="alignnone size-large wp-image-6572" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-789x1024.png 789w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-600x779.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-231x300.png 231w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM-768x997.png 768w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.09.56-AM.png 889w" sizes="auto, (max-width: 789px) 100vw, 789px" /></a></p>
<p>Nothing happens on my development kit?  So I press the reset button and now I get a blinking LED.  But why do I have to press reset?   Do you see the &#8220;Reset Chip&#8221; checkbox at the top of the &#8220;Program Settings&#8221; window?  That has to be clicked.  Now when you program, the debugger will reset the chip and you will be off to the races.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-12-05-am/" rel="attachment wp-att-6573"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM.png" alt="" width="888" height="165" class="alignnone size-full wp-image-6573" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM.png 888w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-600x111.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-300x56.png 300w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.12.05-AM-768x143.png 768w" sizes="auto, (max-width: 888px) 100vw, 888px" /></a></p>
<p>So, what was going on with the rest of that program that came by default?  If you attach a serial terminal to the devkit you will see that the blinky example program is putting out information about the RTOS.</p>
<p><a href="https://iotexpert.com/2019/02/09/cypress-mbed-os/screen-shot-2019-02-09-at-9-15-40-am/" rel="attachment wp-att-6575"><img loading="lazy" decoding="async" src="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM.png" alt="" width="703" height="525" class="alignnone size-full wp-image-6575" srcset="https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM.png 703w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM-600x448.png 600w, https://iotexpert.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-09-at-9.15.40-AM-300x224.png 300w" sizes="auto, (max-width: 703px) 100vw, 703px" /></a></p>
<p>It turns out the mbed-os is really an os&#8230; an operation system.  Actually it is a real time operating system that traces it genealogy to RTX, a product from the old <a href="https://en.wikipedia.org/wiki/Keil_(company)" target="_blank" rel="noopener">Keil Corporation</a> which was acquired by ARM&#8230;. a lot more on this later.</p>
<p>One final note that may cause confusion (I certainly have been confused).  There are four different modes of KitProg 3 (the programmer that is built into most of the Cypress development kits).</p>
<div class="table-responsive"><table  style="width:95%; "  class="easy-table easy-table-default " border="1">
<thead>
<tr><th >Mode</th>
<th >LED</th>
<th >Change modes</th>
</tr>
</thead>
<tbody>
<tr><td >CMSIS-DAP BULK</td>
<td >Solid LED</td>
<td >Short button press toggles between BULK and HID</td>
</tr>

<tr><td >CMSIS-DAP HID</td>
<td >Breathing LED</td>
<td >Short button press toggles between BULK and HID</td>
</tr>

<tr><td >DAPLink</td>
<td >LED Off</td>
<td >Hold KitProg button for &gt;2 seconds (gets in and out of this mode)</td>
</tr>

<tr><td >B00tloader</td>
<td >Fast blinking LED</td>
<td >hold reset button and plug in kit</td>
</tr>
</tbody></table></div>
<p>In order to program from the command line using &#8220;mbed compile -f&#8221; you need to be in &#8220;DAPLink&#8221; mode.  In order to program with Cypress Programmer you need one of the CMSIS-DAP modes.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://iotexpert.com/cypress-mbed-os/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
