AnyCloud Bluetooth Advertising Scanner (Part 2)

Summary

The second article in a series discussing the creation of a PSoC 6 + CYW43xxx Advertising Scanner using the AnyCloud SDK.  This article will use the learning from Part 1 to create a template project that starts the BLE stack.

Story

In the previous article I discussed the structure of the Cypress/Infineon Bluetooth Stack and its integration into AnyCloud.  A bunch of “theory”, well I say BS to that.  Let’s build something.

For this series of articles I will:

  1. Discuss an overview of Bluetooth Application Architecture (Part 1)
  2. Explain how to Start the AnyCloud Bluetooth Stack (Part 1) 
    1. Discuss the configuration structure: bt_platform_cfg_setting (Part 1)
    2. Discuss the configuration structure: wiced_bt_cfg_settings (Part 1)
    3. Discuss the Tasks created by the Bluetooth Stack (Part 1)
    4. Build the Basic Project (Part 2)
    5. Discuss BLE Advertising - Scanner/Observer (Part 3)
    6. Discuss BLE Advertising - Advertiser (Part 3)
    7. Add BLE Scanning Code to the project (Part 3)

    Recall from Part 1 that you need three things to startup the Bluetooth Stack

    • The Hardware Configuration Structure that matches : cybt_platform_config_t
    • The Bluetooth Stack Configuration Structure that matches : wiced_bt_cfg_settings_t
    • The Bluetooth Management Callback that matches : typedef wiced_result_t (wiced_bt_management_cback_t) (wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data);

    Then you need to call

    • The hardware initialization function : cybt_platform_config_init
    • The stack initialization function : wiced_bt_stack_init

    Ok let’s do this!

    Basic Project

    You can do all of these steps from the Eclipse IDE for ModusToolbox.  Or you can do it from the individual programs and the command line.  I like Visual Studio code, so this article will be done completely from the command line and individual configurators.

    Run the new project creator from the start menu.  Start by creating a project for the development kit that you have, in my case the one currently plugged into my computer is the CY8CKIT-062S2-43012, so that is what I pick.  But, this project will work with any of the WiFI/BT combo chips attached to PSoC 6.

    In previous articles I discussed the template that I use to get things going with FreeRTOS.  I won’t discuss that here, but I want FreeRTOS and the NTShell, so pick the IoT Expert FreeRTOS NTShell Template.

    After about a minute you should have a project.  I always like to build the project to make sure that everything is working before I get too far down the road of modifying anything.  Run “make -j build”

    Then to be sure it is working, program the development kit.

    When that is done, open up a terminal window and you should have a functioning base project.  Notice that I ran “help” and “tasks” from the command shell.

    Now that we have a basic project working, add the Bluetooth libraries.  Run the library manager by typing “make modlibs”.  Then select “bluetooth-freertos” and the library manager will automatically select the other libraries you need.  Press Update then Close.

    Next, run the bluetooth configurator by running “make config_bt”  This tool will help you make the bluetooth stack configuration structure.  When the configurator starts, press “New”

    Then select our device (the PSoC 6 and the Combo chip)

    Click on the “GAP Settings”.  Then press the Plus and add “Observer configuration”

    Then setup the scan settings (more detail on these numbers in the next article)

    • Low duty scan window (ms) = 60
    • Low duty scan interval (ms) = 60
    • Low duty scan timeout = deselected (meaning no timeout)

    Then save your configuration file.  Notice that I called it “btconfig”

    When you are done you will have a directory called “GeneratedSource” inside of your project with the needed files.

    The next step is to fix up the Makefile.  I like changing the name of the “App”.

    Then you need the “FREERTOS WICED_BLE” components.

    If you run make vscode it will update the workspace with all of the stuff needed for Visual Studio Code to be able to find all of the files.

    Inside of Visual Studio Code, create a new file called “bt_platform_cfg_settings.h” and add:

    Inside of Visual Studio Code, create a new file called “bt_platform_cfg_settings.c” and add:

    Inside of Visual Studio Code, create bluetoothManager.h.  Remember this is the Bluetooth Stack Management Callback

    Inside of Visual Studio code, create bluetoothManager.c.  This function does a whole lotta nothin… except saying that things got started.

    Next, update main.c with the required includes.

    Then update main.c to start the stack

    Now build and program it, remember “make -j build” and “make program”.  Look, we have a functioning stack with the two bluetooth thread running.

    In the next article Ill finally get around to building the Bluetooth Scanner.

    AnyCloud Bluetooth Advertising Scanner (Part 1)

    Summary

    The first of several articles discussing the use of the AnyCloud BLE Stack to build advertising scanner/observers.

    Story

    A few summers ago while I was writing the WICED Bluetooth Academy book, I created a WICED based BLE advertising scanner.  Actually, I created a framework for the scanner and the remarkable summer intern I had finished the work.  That project has been sitting in the source code repository for the Bluetooth class, mostly only shown to face-to-face students.  This scanner is built using some of the original code combined with the new AnyCloud Bluetooth SDK.  It will act sort-of-like LightBlue or one of the other Bluetooth advertising scanners you might run on your phone, but with a serial console.

    Sometime in the last few months we released the Bluetooth SDK for AnyCloud (things have been crazy and I have lost track of time)  This SDK has all of the stuff needed to add Bluetooth to your AnyCloud project using one of the Cypress Bluetooth/WiFi combo chips.  I had not had a chance to try it out, so I decided to build a Bluetooth project and then port the scanning code.

    For this series of articles I will:

    1. Discuss an overview of Bluetooth Application Architecture (Part 1)
    2. Explain how to Start the AnyCloud Bluetooth Stack (Part 1) 
      1. Discuss the configuration structure: bt_platform_cfg_setting (Part 1)
      2. Discuss the configuration structure: wiced_bt_cfg_settings (Part 1)
      3. Discuss the Tasks created by the Bluetooth Stack (Part 1)
      4. Build the Basic Project (Part 2)
      5. Discuss BLE Advertising - Scanner/Observer (Part 3)
      6. Discuss BLE Advertising - Advertiser (Part 3)
      7. Add BLE Scanning Code to the project (Part 3)

      Bluetooth Application Architecture

      Bluetooth applications are divided into these four pieces

      1. You user application which responds to events and sends messages from/to the Bluetooth host stack
      2. A Bluetooth Host Stack
      3. A Bluetooth Controller Stack
      4. The Bluetooth Radio

      These four pieces can be divided into multiple chips, as few as one or as many as four.  However, for this article, the project will be built to run on a PSoC 6 + CYW43012 WiFi/Bluetooth Combo chip.  Specifically:

      1. My scanner application running on the PSoC 6
      2. The Bluetooth Host Stack running on the PSoC 6
      3. The BlueTooth Controller Firmware running on the CYW43012
      4. A Bluetooth Radio on the CYW43012

      But how do they talk?  Simple, there is:

      1. A UART Host Controller Interface (HCI) between the two chips
      2. A GPIO to serve as a deep sleep wakeup from the 43012 –> PSoC 6
      3. A GPIO to serve as the bluetooth controller wakeup from the PSoC 6 –> 43012
      4. A GPIO to turn on the Bluetooth regulator from the PSoC 6 –> 43012

      Here is the block diagram from the CY8CKIT-062S2-43012 Kit Guide.  Notice that signals labeled UART and Control going between the PSoC 6 and the CYW43012.

      And when you read more deeply into the schematic you can see the signals labeled

      • BT_UART_TXD/RXD/CTS/RTS
      • BT_HOST_WAKE
      • BT_DEV_WAKE
      • BT_REG_ON

      How to Start the AnyCloud Bluetooth Stack

      To actually start the AnyCloud Bluetooth stack you will call two functions

      1. cybt_platform_config_init – that will setup the hardware interface to the CYW43012
      2. wiced_bt_stack_init that will:
        1. Start a task to manage the Host Controller Interface
        2. Download the controller firmware to the CYW43012
        3. Start a task to manage the host stack
        4. Initialize both the host and the controller
        5. Call you back when that is all done

      Here is an example from main.

      When you look at these two function calls, you will find that you need to provide three things:

      1. A platform hardware configuration structure called bt_platform_cfg_settings
      2. The Bluetooth stack configuration settings structure called wiced_bt_cfg_settings
      3. A management callback called app_bt_management_callback

      bt_platform_cfg_settings

      The purpose of the hardware configuration structure is to define the UART + parameters and the wakeup GPIOs.  Specifically, the hardware configuration structure defines the configuration of the host controller interface (hci)

      1. The HCI transport scheme (in this case UART)
      2. The pins of the UART
      3. Baud Rate
      4. Data Bits
      5. Stop Bits
      6. Parity
      7. Flow Control

      And the controller low power behavior (in the .controller_config member)

      This is a fairly standard configuration and I think that we should help you by providing this structure somewhere in the BSP.  But for now, you need to provide it (in an upcoming article I’ll update the IoT Expert Bluetooth Library to provide it).  Here is the specific structure that I will be using.

      wiced_bt_cfg_settings

      The Cypress WICED Bluetooth Stack has a boatload of configuration settings.  When you call the stack start function you need to provide all of those settings in a structure of type “wiced_bt_cfg_settings_t” which is actually a structure of structures.  There are several basic ways to set these settings

      • Start from scratch and build you own settings
      • Copy from an example project
      • Use the Bluetooth Configurator to generate the structure

      For the purposes of THIS project I started by copying the structure from on of the example projects and then modifying the three numbers that were relevant to me.  Specifically

      • max_simultanous_link – which I changed to 0 because this is simply a Bluetooth Observer
      • low_duty_scan_interval – how long in the window to listen for advertising packets
      • low_duty_scan_window – how wide the window of listening should be

      app_bt_management_callback

      The last thing that you need to provide is a management callback.  This function is called by the Bluetooth Stack when a “management event” occurs.  There is a big-long-list of enumerated events of type wiced_bt_management_event_t.  The events include things like the the stack started “BTM_ENABLED_EVENT”.  Each event may have data associated with the event which is passed to you in a pointer to wiced_bt_management_event_data_t.

      You typically deal with these events with a giant switch statement like this:

      Tasks

      The Bluetooth stack on the PSoC6 is operated with two tasks.  Specifically, when you call the wiced_bt_stack_init it will startup:

      1. CYBT_HCI_Task – a task that sends and receives HCI packets going to the Radio chip
      2. CY_BT_Task – a task that manages the Bluetooth Host Stack

      Here is print of the task list from my project:

       

      Now with the background in place, in the next article I will discuss Bluetooth advertising and how to build the observer project.

      Update Project to ModusToolbox 2.2

      Summary

      This article walks you through the steps that I took to convert a ModusToolbox 2.1 project using the “dot lib” flow into a Modus Toolbox 2.2 project using the “mtb” flow.

      Story

      I have been working on way way to many different things and not finishing nearly enough things.  Oh well.  One of the projects that I have been working on is an implementation of a Bluetooth Observer to process iBeacon packets from a Tilt Hydrometer (more on that in a future article).  This project was started in Modus Toolbox 2.1.  It will continue to work perfectly in ModusToolbox 2.2 as it is 100% backwards compatible, but, I want to use some of the new features of 2.2.

      As I discussed in a previous article, there are now two library systems in Modus Toolbox.

      • The “mtb” flow – which allows for “shared libraries”
      • The “dot lib” flow – which has all libraries embedded into the project.

      If you want to convert your Modus Toolbox 2.1 project Modus Toolbox 2.2 you can follow a process like this:

      1. Backup the project into Git
      2. Create a template Modus Toolbox 2.2 project (so I have a “clean” copy of the Makefile and “mtb” files)
      3. Fix the Makefile
      4. Examine and Update the library dependencies
      5. Test

      Backup Everything

      Before you torch your perfectly good project you should back it up.  I typically use Git.  Actually I always use Git.  As I wrote this article I realized that I should have tagged the version before I started the updates.  To figure out which commit that was I ran a “git log” and then I scrolled through my new commits until I found the last one before the conversion to 2.2.  Which requires me to admit that when I left the project a couple of weeks ago there were two files which I hadn’t checked.  So I blindly checked them in and then told the truth in my comment.

      Now that I have the right commit, I tagged with with a “mtb 2.1” tag.

      Now I can go back to my 2.1 project by running “git checkout mtb2.1”

      Create a Template Project

      In order to use the new flow you need to do two things.

      1. Fix the Makefile
      2. Change the “dot lib” files to “mtb” files

      I never can remember the secret incantation to put in either place.  So, I create a blank project called “Simple22” to allow me to steal the bits that I want.

      Makefile

      In Modus Toolbox 2.2 we added two new variables to the Makefile which allow you to specify the location of the shared library.  First, here is the relevant section of the original 2.1 Makefile

      And the new 2.2 Makefile where you can see the two new variables

      • CY_GETLIBS_SHARED_PATH=../
      • CY_GETLIBS_SHARED_NAME=mtb_shared

      Dependencies & Libraries

      The next thing to do is look at what libraries are in my original project.  To do this run the Library manager via “make modlibs”

      All of these libraries are added to the project by creating “dot Libs” in the “deps” directory.  Specifically as I worked on the original project I added the libraries using the library manager, which created a dot lib for each library.  Here is a look at the original “deps” directory.

      When I did an “update” in Modus Toolbox 2.1 it ran “make depend” which brought in the libraries specified by the the “dot libs” into the “libs” directory.  Here it is a listing of the lib directory.

      Now take the dramatic step of:

      • rm deps/*
      • rm -rf libs

      I decided that the easiest thing to do to create the “mtb” files was to run the library manager.  But, with nothing in the deps directory, the library manager doesn’t know what to do.

      So, I copy the target file from the Simple22 project.

      I was sure that I would be able to run the library manager now.  But it gave me the bird.  At least it gave me the hint of running “make getlibs” first.  Which I do:

      Now when I run “make modlibs” I can click on all of the libraries that I used in my project.

      Once I click go.  It brings in all of the needed libraries.  Look at the “deps” directory now.  We are rocking.

      And when I look in the shared library directory which is “../mtb_shared” you can see all of the source files.

      Build and Test

      All the libraries are now fixed.  So run a “make -j build” and see what we have.

      A functioning project.  Sweet!

      Kentucky Inspired Me … Thanks Erich

      I follow Erich’s blog.  In the last few years he has been posting pictures taken near his home in Switzerland.  Remarkable.

      In the last few days Kentucky has inspired to take some fall pictures.  I will not pretend they are great works of photography.  But I think that they are pretty.

      How are they IoT?  They aren’t.

      ModusToolbox 2.2 Template Project – FreeRTOS + NTShell

      Summary

      This article discusses the new library structure that was released with ModusToolbox 2.2.  I explain it by showing the creation of a template project that use FreeRTOS and NT Shell.

      Story

      I have often started projects from the IoT Expert FreeRTOS template project.   I realized the other day that almost always the first thing I do after creating the project is add the NT Shell library.  My friend Hassane has a personal mantra that if he is going to do the same job more than once he will always automate it.  I should have listened to him on this one because I have done it a bunch of times.

      In Modus Toolbox 2.2 we have created a new library scheme which allows sharing of libraries between projects.  So this will also be a good example of how that works.

      This will also give you another example of adding template projects to your own manifest.

      Here is what I am going to do:

      1. Create a project from the IoT Expert FreeRTOS Template
      2. Add the NTShell Library & Examine New Library Structure
      3. Update the Project and Program
      4. Add the Task List functionality (a nice feature of FreeRTOS)
      5. Put the new template on GitHub
      6. Update the IoT Expert App Manifest
      7. Test the new Template

      Create & Test a project from the IoT Expert FreeRTOS Template

      I will start the whole process by creating  new project using my existing base template.  The kit that I happen to have on my desk right now is the CY8CKIT-062S2-43012.

      Select the IoT Expert FreeRTOS Template and give it a name.  Notice that I add “NTShell” to the name (because that is what Im gonna add)

      When you click create, Modus will do its magic and build you a complete project.

      Today Im going to edit using Visual Studio Code.  Actually almost always I edit using Visual Studio Code.  You can do all of these tasks using Eclipse as well.  To turn my created project into a VSCODE project run “make vscode”

      Before getting to far down the road I like to run a build to make sure everything is OK.  So “make -j build”

      Then program it, just to make sure.  “make program”

      Add the NTShell Library & Examine New Library Structure

      Everything is working and my basic project has FreeRTOS and a blinking LED.  Now let’s add the NT Shell Library.  To do this run the library manager by running “make modlibs” (or click on the button in Eclipse).  Select Libraries –> IoT Expert –> ntshell

      When you press update, the library manager will do its thing again.

      When I look in the “deps” directory, I see some new file types called “.mtb”.  These files tell your project where to find each of the libraries.  Notice that the middleware-ntshell.mtb points to “$$ASSET_REPO$$”.  Where is that?

      If you have a aook at the Makefile it tell you that it is “../” and “mtb_shared”.

      To start editing I will run Visual Studio Code by typing “code .”.  The first thing that happens is that it notices that this is a workspace instead of just a directory.

      And when you look at the workspace you can see that it knows about both the example project as well as “mtb_shared”.  That is sweet.

      Update the Project and Program

      Now follow the instructions from the middlware-ntshell readme by copying “usrcmd.*” into my project.

      Then I edit main.c to

      1. #include “usrcmd.h” on line 8
      2. Start the shell task which is called “usrcmd_task” on line 39

      Now buid/project by running “make -j program”

      Now I have a functional shell.  Here is the serial console.

      Add the Task List functionality

      In the main.c above I started up the usrcmd_task with a stack size of config_MINIMAL_STACK_SIZE * 4.  Where did I get that?  Well the first couple of times I did this it crashed by running out of stack so I tried bigger and bigger numbers until it stopped crashing.  This is a kind of a pain in the ass.   If you know FreeRTOS there is a function called “vTaskList” which will give you stats about the tasks.

      In order to use that function you need to turn it on.  Notice that I #ifdef and #if to see if it is turned on inside of usrcmd.c

      So let’s turn it on by editing “FreeRTOSConfig.h” and enabling the two required defines.

      Now build/program.

      When I run help you can see I have a new command called “tasks” which lists all of the tasks and their stack high water marks.

      Put the Template on GitHub

      I am happy with my new template.  So, I go to GitHub and create a new repository.

      Then on my current project:

      1. I blow away the git history (didnt really have to do that).
      2. Create a new git repo “git init .”
      3. Add a pointer to GitHub “git remote add….”
      4. Add all of the files “git add *”
      5. Add the .gitignore “git add .gitignore”
      6. Commit the changes “git commit…”
      7. Push it to GitHub “git push …”

      Update the Manifests

      To get access to the new template I need to add it to the IoT Expert App Manifest.  I edit the xml file to have the new app

      Now I need to git add, git commit and git push it to GitHub.

      Test the new Template

      Everything should be working so make a new project.

      Cool.  There is the new template.

      When I program it… everything is cool.