Skip navigation
Home > All Places > ModusToolbox > Blog

Back in February I committed to write about peripheral setup using the ModusToolbox device configurator tool. I have not done very well! We have had another release since then - ModusToolbox 1.1 - and I have been buried in planning for the 2.0 release and training our internal teams. But that is real work and I've had enough of it. It's time to get back to writing about PSoC and developing cool applications.

But first a word or two about a change in the project structure for PSoC applications between the 1.0 and 1.1 releases. In 1.0 we created five projects for a single application; one each for the CM4 and CM0+ cores, one each for the PDL libraries for each core, and one for the configuration. Early feedback was that this was confusing and difficult to manage and so we re-jigged things in the 1.1 software. We also found that most engineers do not use the CM0+ core in real applications because they prefer the faster (more power efficient) CM4 and the simplicity of single-core development. As a result, by default, we now only create the CM4 project and leave the CM0+ to the experts. That removed two of the required projects, which was a good start. Next, we realized that there is no longer any point having a separate configuration project, so we moved the design.modus file into the CM4 project and put all the generated source into a local folder, instead of a link to another project. The result is a major usability improvement. You get the application project, where you do all the work, and a library project, which you typically never edit - just build once and link. Another benefit of this is that the library project can be linked to any number of a applications. The first application you create in a new workspace will have a library project but, if you then create more applications they default to sharing the original library. I find this really helps me manage projects and I only rarely have to change, or create new, workspaces.

In previous posts I have written about creating applications, starter templates for single-threaded and FreeRTOS applications, and doing some basic things like twiddling LEDs and reacting to button presses. Note that in the post about <here all the generated code goes I wrote about the GeneratedSource folder being in the configuration project. Obviously, if you are using ModusToolbox 1.1 that folder is now in the main application project.

OK, that's enough housekeeping about releases. We've all got v1.1 right! Good, let's modify a start project to set up a peripheral. You all know how to do this by now (check out the links above if you need a reminder) so create a new application using the PioneerKitApp starter template. This template has the buttons and LEDs configured for us so we do not need to repeat all that work.

Open the device configurator (click on "Configure Device" in the Quick Panel or double-click on design.modus) and look for KIT_LED1 in the Pins tab. Click on the Digital Output internal connection and choose the 16-bit TCPWM.

Choosing a PWM to drive the LED

 

 

Now click on the chain button to jump to the TCPWM.

LED driven from PWM 14 in block 1

Note that it is in block 1, which contains 24 16-bit TCPWMs (block 0 are the 32-bit TCPWMs - that's overkill for this application). Click on the checkbox to enable the peripheral and give it a name - "LED1_PWM".

Enable the TCPWM and give it an alias to make C code easier to write

Notice the configuration panel that appeared when you enabled the peripheral. It has set the Period to the maximum value (32768) and the Compare to 50% of that (16384). Those are good starting conditions - the LED will "glow" at 50% of maximum intensity. You can also see that the PWM_n signal is connected to KIT_LED1, which is a useful confirmation.

Configuration panel showing the period and compare values

The last edit is to set up a source clock, which follows a very similar path to what we just did. Click on the Clock Signal, under Inputs, and choose "8 bit Divider 2 clk". In the pull-down you will see all the other clocks that are set up by the template. You could reuse one of those if you wish to share the resources, but this is a simple application that will only use a fraction of available resources so I am keeping things simple. Click on the chain to jump to the clocks tab. Notice that the clock is enabled for you, with a divider of 1, giving a 72MHz frequency for the counter. That's plenty o' Hertz! Save the changes and exit the configurator.

In the GeneratedSource/cycfg_peripherals.h file you will find these new defines that we will use to start the PWM.

#define LED1_PWM_HWTCPWM1

#define LED1_PWM_NUM 14UL

#define LED1_PWM_MASK (1UL << 14)

In cycfg_peripherals.c there is a configuration struct. All those PWM options are really impressive but I am glad I do not have to set them up by hand!

const cy_stc_tcpwm_pwm_config_t LED1_PWM_config =

{

.pwmMode = CY_TCPWM_PWM_MODE_PWM,

.clockPrescaler = CY_TCPWM_PWM_PRESCALER_DIVBY_1,

.pwmAlignment = CY_TCPWM_PWM_LEFT_ALIGN,

.deadTimeClocks = 0,

.runMode = CY_TCPWM_PWM_CONTINUOUS,

.period0 = 32768,

.period1 = 32768,

.enablePeriodSwap = false,

.compare0 = 16384,

.compare1 = 16384,

.enableCompareSwap = false,

.interruptSources = CY_TCPWM_INT_NONE,

.invertPWMOut = CY_TCPWM_PWM_INVERT_DISABLE,

.invertPWMOutN = CY_TCPWM_PWM_INVERT_DISABLE,

.killMode = CY_TCPWM_PWM_STOP_ON_KILL,

.swapInputMode = LED1_PWM_INPUT_DISABLED & 0x3U,

.swapInput = CY_TCPWM_INPUT_0,

.reloadInputMode = LED1_PWM_INPUT_DISABLED & 0x3U,

.reloadInput = CY_TCPWM_INPUT_0,

.startInputMode = LED1_PWM_INPUT_DISABLED & 0x3U,

.startInput = CY_TCPWM_INPUT_0,

.killInputMode = LED1_PWM_INPUT_DISABLED & 0x3U,

.killInput = CY_TCPWM_INPUT_0,

.countInputMode = LED1_PWM_INPUT_DISABLED & 0x3U,

.countInput = CY_TCPWM_INPUT_1,

};

Add these lines to your main() function (in Source/main.c) before the for loop.

    Cy_TCPWM_PWM_Init(     LED1_PWM_HW, LED1_PWM_NUM, &LED1_PWM_config );

    Cy_TCPWM_TriggerStart( LED1_PWM_HW, LED1_PWM_MASK );

    Cy_TCPWM_PWM_Enable(   LED1_PWM_HW, LED1_PWM_NUM );

Notice that the trigger function works on all 24 TCPWMs in the block, and so we pass a MASK argument, not the individual TCPWM number. LED1_PWM_MASK is just a 1 shifted left by LED1_PWM_NUM and so you can see how to control and synchronize the triggering of individual TCPWMs by ORing the masks.

When you build and program the application into your Pioneer kit the LED should glow quite brightly. This is because a 50% duty cycle is almost as bright as 100% to our eyes. Even your young ones! A household mirror reflects about 50% of the light that hits it and your reflection does not appear especially dim! So play with the duty cycle to reduce the brightness. You can do this by editing the compare value in the configurator or by calling the Cy_TCPWM_PWM_SetCompare0() function to change it your C code (use the Compare0 function because the PWM supports two period and compare values, which we will play with next time). If you have never done this before I think you will be surprised at how low the duty cycle has to be in order to really dim the LED.

I wrote about Zerynth just after the Embedded World show, where they gave a great demo of their Python virtual machine running an IoT demonstration on a PSoC Pioneer kit.

Like all good demos it was, in essence, really simple. They dropped a MikroE Weather Click board (with a Bosch BME280 humidity/pressure/temperature sensor) onto the Pioneer kit, read values over I2C into the PSoC application, which published the weather data to the cloud wirelessly whenever the CapSense button was pressed. Simple right? Yeah, of course it is simple - but only because Cypress has invested decades of R&D effort and millions of dollars into making the most robust and best performing CapSense and wireless solutions on the planet! But the demo is simple and the Zerynth stuff is cool.

Better still, late last week they formally announced the availability of the software in their excellent Zerynth Studio product. So go download it now!!!!

PSoC Pioneer kit running the Zerynth Python VM with a MikroE Arduino Uno shield and Weather Click sensor board

I am very excited about this collaboration. The Zerynth folk are really easy to work with and their excitement about the product is infectious. I think it has something to do with being young and Italian, and having perfect hair! When they are not making innovative products I imagine they just scoot around Pisa, on Vespas, calling out "ciao" to all the pretty people. Well, maybe that's just what I would do?

In case you hadn't figured it our yet, I've run out of things to write... I want to go learn Python and try it out on my Pioneer kit... and so should you... so get downloading and join the millennials by coding in Python. It'll make you feel years younger. And your hair will look good too.

JimT_21

Sharing My Eclipse Project

Posted by JimT_21 Apr 4, 2019

When in the course of a developer’s life it becomes necessary to share a project, an Eclipse IDE (and ModusToolbox IDE is no exception) is both helpful and confusing. The use case we’re talking about here is: “I want to pack up my project and send it to someone for them to see, use, or comment on.” A perfect example is when you have a support question and the support engineer asks you to send them the project.

Here’s how.

 

Before we get started....

  • Pro Tip #1: Before archiving, select the projects in the project explorer. Then they are automatically selected for the archive.
  • Pro Tip #2: When you archive a project, do not include the Debug folder. The IDE regenerates this information, you don’t need to include it. You will save many, many megabytes of space excluding the Debug folder.

 

To send someone your project, you create a project archive. Use File > Export and then choose General > Archive file. In the resulting dialog, you’ll see your projects and all their elements. Select the project you want to include. Expand it to see all the “stuff” in the project, and deselect the Debug folder. Browse to where you want it to be, give it a name, and click Finish.

Now, how about the other side of this equation. Someone sent you an archive. How do I get it into the IDE? This is where Eclipse is confusing.

 

To import projects from the file system, use File > Import and then General. See the screenshot below. There are several wizards to choose from, one of which is called Archive File. Hey, I just created an archive file, so that’s what I should import it, right? WRONG! Silly you for being that logical.  

Instead, use Existing Projects into Workspace. Your archive includes an existing project. So you are importing the existing project.

 

For Existing Projects into Workspace, you specify that this is an archive file. Browse to it and click Finish.

 

Finally, as an aside, this and many other Eclipse oddities are discussed in my Eclipse Survival Guide. If you're new to Eclipse, you may want to check it out.  Happy Eclipsing!

Hey ModusToolbox users.  This blog post is a follow-up to the post I recently made showing a WiFi Scanner using the Mbed->ModusToolbox flow. While that was meant as an introduction, this post will actually be a lot shorter. Basically, all I’ll cover here is how to use an example from the Cypress GitHub code example repository instead of Mbed’s.

 

I will be using the PSoC 6 Wi-Fi BT prototyping kit (CY8CPROTO-062-4343W).  But, you can also use the CY8CKIT-062-BLE or the CY8CKIT-062-WiFi-BT. You can use any Cypress kit supported in Mbed that has a CapSense slider on the board.

 

OK, I am going to assume you have already gone through that first blog post and have your ModusToolbox and Mbed environment all set up.  The first thing we need to do is go get the code example.  You can do that in a couple of ways.

 

1. Go directly to the GitHub location for ModusToolbox examples, which is here

     https://github.com/cypresssemiconductorco/Code-Examples-for-ModusToolbox-Software

 

2. From the ModusToolbox IDE Quick Panel, select “Search Online for Code Examples” like this

Either way, you’ll end up at this location.  Focus on the area labeled “Mbed OS Examples”.

I want the Mbed OS and CapSense example so I’ll click on that.  There are actually instructions on running this example right on that GitHub page, but I’ll repeat most of them here so you are not jumping back and forth.

 

3. Open up a Git Bash shell first (you can use a Cygwin terminal or a Windows cmd window, the instructions for setting up your environment will vary slightly).

 

4. Import the code example like this

mbed import https://github.com/cypresssemiconductorco/mbed-os-example-capsense

Depending network traffic, it may take a minute or two to copy the example over (it’s almost a Gb on disk).

 

5. Go to the example folder

cd mbed-os-example-capsense

 

6. Plug in your kit and ensure the kit is in DAPLink mode. See my earlier blog post or the Switch Kit to DAPLink Mode section in chapter 3 of the ModusToolbox IDE User Guide if you need more information on this.  For my kit, I press and hold SW3 for > 2 seconds.

 

7. Compile the example and program the board with the following command

mbed compile --target CY8CPROTO_062_4343W --toolchain GCC_ARM --flash --sterm

For other targets:

mbed compile -m CY8CKIT_062_WIFI_BT -t GCC_ARM -f –sterm

mbed compile -m CY8CKIT_062_BLE -t GCC_ARM -f --sterm

Note: -f is equivalent to –flash, -t is equivalent to --toolchain

 

OK, what is that –sterm option?  In my other examples I have used PuTTY or TeraTerm (you can still use those if you want).

The --sterm option opens a serial terminal set to 9600-8N1 on your the command window after programming completes. Obviously, leave this option out if you wish to connect using another serial terminal application.

 

8. After the kit is programmed and the program starts, you will see this message in your terminal window that looks something like this.

+++++++++++++++++++ Application has started. Touch any CapSense button or slider.

 

9. Touch the buttons and the slider to observe the red LED changing its state and to see the status of the various CapSense sensors printed in the terminal.  The messages in the terminal will look something like this.

10. You can also monitor the CapSense data using the CapSense Tuner application as described on the GitHub site or in this blog post.

 

That’s it for this post. Hit me up in the comments if you have questions.

--Matt

Hello again Embedded Developers,

 

In this blog post I’ll introduce you to using the Mbed flow with ModusToolbox. The example design will scan for WiFi networks in range, print them to a tutorial, then connect to a WiFi network.  This article will cover

 

I. Setting up your environment

a. Install ModusToolbox 1.1

b. Install Cygwin (for Windows)

c. Install SRecord

d. Install/Configure the Mbed Command Line Interface (CLI)

e. Update PyOCD

f. Setup your Windows environment

g. Setup your compiler

 

II. Importing an example WiFi Scanner application from Mbed

 

III. Compiling with the Mbed CLI, targetting a Cypress board

 

IV. Flashing the design using the Mbed CLI or from the ModusToobox IDE

 

V. Importing the design into the ModusToolbox IDE for further editing, programming, and debugging.

 

One key document to have handy is Chapter 3 of the ModusToolbox IDE User Guide (Mbed OS to ModusToolbox Flow)  You can find this document in the installation ($install/docs/mt_ide_user_guide.pdf) or on the website (the 1.1 version is here).  Now is a good time to mention that this example is for ModusToolbox 1.1.

 

I. Environment setup

 

Install ModusToolbox

If you don’t already have ModusToolbox 1.1 installed, install it now.

 

Install Cygwin Make (Windows)

You need Cygwin Make for the Cypress Mbed flow to work properly in a Windows version of Eclipse. Refer to the Cygwin website for instructions to download and install Cygwin. Do not add Cygwin to your Windows PATH system environment variable. Cygwin is only required for Eclipse.

 

Install SRecord

You must install the SRecord utility (https://sourceforge.net/projects/srecord/) which is used by the ModusToolbox IDE build process to produce a combined HEX file for program/debug.

 

Install/Configure the Mbed CLI (you won't be able to do anything past here without completing this step)

Go here and follow the instructions for your platform (I’ll be using Windows for this post)

https://os.mbed.com/docs/mbed-os/v5.11/tools/installation-and-setup.html

If you want to see the including supported boards and code examples, visit the Cypress page on the Mbed website.  It’s here.

https://os.mbed.com/teams/Cypress/

 

If necessary, Update PyOCD

In order for Mbed applications to work with ModusToolbox and Cypress kits, PyOCD 0.16.1 or greater is required.  Run the following from a cmd window.

pyocd --version

Again, the reply should be 0.16.1 or greater.

 

If you don’t have the correct version, run:

pip install -U pyocd

I used 0.18.0 for this blog post.

 

Set up your Windows environment

You need an environment variable called CYSDK that points to the ModusToolbox installation. In my case, I have the following two lines in my  .bash_profile (I’m using a Git Bash shell for this example.

export CYSDK="C:/Users/mdl/ModusToolbox_1.1" (or in a plain Windows cmd window, set CYSDK=C:/Users/mdl/ModusToolbox_1.1)

 

Set up your compiler

While there are many compilers you can use with Mbed (e.g. ARM and IAR), I will just cover the one I am using; the GCC distribution shipped with ModusToolbox.  This is done with an Mbed command.  You must do this with an Mbed command.  It doesn’t look at an environment variables you have set up in Windows.  Here is the command I used.

mbed config -G GCC_ARM_PATH /c/users/mdl/ModusToolbox_1.1/tools/gcc-7.2.1-1.0/bin

You should see a confirmation message that looks similar to

[mbed] C:/users/mdl/ModusToolbox_1.1/tools/gcc-7.2.1-1.0/bin now set as global GCC_ARM_PATH

 

(if you are using a plain Windows cmd window, the mbed config command would be something like

mbed config -G GCC_ARM_PATH C:\users\mdl\ModusToolbox_1.1\tools\gcc-7.2.1-1.0\bin )

 

II. Go get an example from the Mbed repository

1. Create a directory for you example and navigate to it.

2. Get an example using the mbed command “mbed import [example name]”.  Here is the command I ran from the command line

mbed import mbed-os-example-wifi

This many take a bit of time to complete based on net work traffic because there is a lot of stuff in this example.  You can add the “-v” option to the end of the command to get a little more status.

Pro Tip:This is actually a pretty hairy example for your very first Mbed design. You may want to start with the simple Mbed blinking LED example. That command would look like

mbed import mbed-os-example-blinky

 

III. Compile the example

You could wait to do this step after importing into the ModusToolbox IDE, but I like to make sure I have the basic example compiling before importing.

 

1. Change directory to the example you just imported. In my case:

cd mbed-os-example-wifi

2. Explore and review the contents of the directory

Some of the key files are a README file, an mbed-os directory (that is responsible for most of the disk space consumption) and a C++ source file, main.cpp.

3. Compile the design with a Cypress board as the target

The format of the mbed compile command we will use is

mbed compile --target [Cypress Board] --toolchain [TOOLCHAIN]

where TOOLCHAIN = GCC_ARM and Cypress Board = CYW943012P6EVB_01

If you want to see all the compile options, you can type

mbed compile --help

If you want to see table of all available toolchains and targets, type

mbed toolchain --supported

Cypress targets at the time I created this blog post include:

 

CY8CKIT_062_BLE

CY8CKIT_062_WIFI_BT

CY8CKIT_062_4343W

CY8CPROTO_062_4343W

CYW943012P6EVB_01  (the board I am using)

 

4. Configure the example for your specific WiFi network

Now, we will set up the WiFi network we will connect to in this example.  Do this before running a build/compile.  In the project directory, you will see a file named mbed_app.json.  Replace SSID and PASSWORD as shown below with the SSID and password for your network.

 

Leave the quotation marks and backslashes exactly as shown.  Now, the actual compile command for my board will look like this.

mbed compile --target CYW943012P6EVB_01 --toolchain GCC_ARM

If I had a Cypress 062 WiFi-BT board, the command would look like.

mbed compile --target CY8CKIT_062_WIFI_BT--toolchain GCC_ARM

 

If I were using the IAR compiler, I’d replace GCC_ARM with IAR.

One quick note: At the time of this blog post, IAR 8 was not compatible with Mbed OS.

The first time you build this example, it will take a while.  The end of the compile will look something like the following.

DAPLink

Before you can program the board, you must put it in Arm Mbed DAPLink mode. Arm Mbed DAPLink is open-source software project that enables programming and debugging application software running on Arm Cortex CPUs. DAPLink runs on a secondary MCU (often a PSoC 5LP on Cypress boards) that is attached to the SWD or JTAG port of the application MCU.  It enumerates as a USB composite device and creates a bridge between your development computer and the CPU debug access port. More info can be found here.

 

You need to do a one-time load of the DAPLink firmware onto your board. The full instructions for installing DAPLink onto supported Cypress development boards can be found in Chapter 3 of the ModusToolbox IDE User Guide, but I will go ahead and list them for my CYW943012P6EVB board here.

1. Plug a USB cable into your computer.

2. Press and hold SW3 while plugging in the other end of the cable to your board. This puts the kit in firmware bootload mode.  Obviously use the USB port near the PSoC 5LP, not the USB for the device USB.  Just look on the screen printing for a string starting WITH CY8C5868.

3. From a command window, run the command

fw-loader --update-kp3

The fw-loader can be found in the ModusToolbox installation directory under tools/fw-loader-2.1/bin .  I put it in my path, but you can just go over to the directory and run it.

4. After the fw update is complete, you can put your kit into DAPLink mode by pressing and holding SW4 (Custom App) for 2 seconds are so.  You can tell you are successful by running the following in a command window

mbedls

The results of this command will look something like this

If you need to return the standard CMSIS-DAP HID/BULK mode, just press and hold the Custom App switch (SW4) for about 2 seconds again.

 

IV. Program the board

 

There are a couple of ways to program the board.

1. From the Mbed command line, with the --flash option.  Here’s the command for this blog post.

mbed compile --target CYW943012P6EVB_01 --toolchain GCC_ARM --flash

2. From the ModusToolbox IDE, which is a longer discussion. I will talk about this later.

 

About the WiFi Scanner Application

Now, I’ll take some time to talk about the application you have programmed onto the board.  This example

1. brings up the WiFi and underlying network interface

2. scans the available networks, and

3. prints network interface and connection details.

 

Connect to the mbed serial port using a terminal emulation program such as PuTTY (my buddy Keith says that for serial stuff in embedded design, RealTerm is better than PuTTY or TeraTerm).  The mbed serial port should look something like this in the Windows Device Manager.

If you don’t see something like that, it’s possible you are not in DAPLink mode. Windows 7 users may also need to do an additional step (which is described in Chapter 3 of the ModusToolbox IDE User Guide).

I set PuTTY up with a baud rate of 9600, 8 data bits, 1 stop bit, no parity, no flow control.  Once connected with PuTTY, I press the RST switch (SW5) on my board.  The results will look something like the following (note DAWG5 is the SSID in this case).

If you would like to play around with the source a bit (maybe you want to play with the output or take some commands from stdin), just open up the source in main.cpp using the ModusToolbox IDE or your favorite code editor. Also, explore source code in various directories under mbed-os. For this example, you may want to look at the code in mbed-os/features/netsocket/.  For example, the WiFiInterface class is defined in

mbed-os/features/netsocket/WiFiInteface.h

 

V. Importing into the ModusToolbox IDE

At any point after importing the example from Mbed, you can export to a number of different IDEs. For example, to export to an Eclipsed-based IDE, such as the ModusToolbox IDE, run a command of the following format.

1. mbed export --ide [IDE] --target [target]

For this example, use the following command

mbed export --ide eclipse_gcc_arm --target CYW943012P6EVB_01

mbed export --supported  will print a matrix of supported IDEs and targets.

2. Now open the ModusToolbox IDE and use the standard Eclipse Import function (File > Import) to import this Mbed application.  Here again, you may want to refer to Chapter 3 of the ModusToolbox IDE User Guide. After selecting File > Import, expand the C/C++ folder and select the Existing Code as Makefile Project option. Click Next >.

3. Click Browse… and navigate to the directory where you exported the application from Mbed. Ensure the Toolchain for Indexer Settings is set to <none>. Do not change any other settings, including the project name.

4. Click OK then Finish.

When the import finishes, the Mbed OS application will be shown in the Eclipse Project Explorer

 

Define the Workspace PyOCD Path

Your Eclipse IDE (in this example it’s the ModusToolbox IDE) will need to know how to get to PyOCD for programming and debugging.

Open the Window > Preferences dialog, select MCU > Workspace PyOCD Path, and set the following workspace paths (adjust the path to the Scripts directory for your python/pyocd installation):

 

 

Here are the settings for the various platforms.

Windows:

⦁ Workspace PyOCD Path > Executable = pyocd-gdbserver

⦁ Workspace PyOCD Path > Folder = C:\Python27\Scripts

macOS:

⦁ Workspace PyOCD Path > Executable = pyocd-gdbserver

⦁ Workspace PyOCD Path > Folder = /Applications/MBEDCLI.app/Contents/Resources/miniconda/bin

Linux:

⦁ Workspace PyOCD Path > Executable = pyocd-gdbserver

⦁ Workspace PyOCD Path > Folder = ~/.local/bin

 

Create the PATH variable

Right-click on the project and select Properties. Navigate to C/C++ Build > Environment.

 

Click Add to add a new variable with name PATH, leave the value blank, and select "Add to all configurations."

Click OK to close the New Variable dialog. This step is recommended for Windows to clean up any existing value of the system PATH variable in the current project (this ensures that the project configuration is isolated from the host environment).

Then, click Edit to open the dialog again. Remove anything there, and enter the appropriate value:

 

⦁ Windows: C:/cygwin64/bin;${cy_tools_path:gcc-7.2.1}/bin

 

⦁ macOS: ${cy_sdk_install_dir}/tools/gcc-7.2.1-1.0/bin:/usr/bin:/bin:/Applications/MBEDCLI.app/Contents/Resources/miniconda/bin:/Applications/MBEDCLI.app/Contents/Resources/bin:/Applications/MBEDCLI.app/Contents/Resources/git/bin:/usr/local/bin

Also add /usr/local/Cellar/srecord/1.64/bin to /etc/paths

 

⦁ Linux: Check the gcc directory path: /usr/bin:/bin:${cy_sdk_install_dir}/tools/gcc-7.2.1-1.0/bin

 

Note: It is possible to target another toolchain instead of GCC 7.2.1 provided by ModusToolbox. To use the GNU Arm Embedded Toolchain, install the following to the default location:

https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads

Then prepend the following to the Eclipse PATH instead of ${cy_tools_path:gcc-7.2.1}/bin:

<install_dir>/GNU Tools ARM Embedded/7 2018-q2-update/bin

 

Build, Program, and Debug the Application from the ModusToolbox IDE

 

Build

If you haven’t recently built the application, select Project > Build to build the project and generate the combined HEX file for programming. When complete, the Console displays a message similar to the following:

hex file ready to flash: BUILD/mbed-os-example-wifi-combined.hex

 

Program

Open the Run > Run Configurations dialog. Select the “program” configuration for your application under GDB PyOCD Debugging.

On the Main tab, under C/C++ Application, click Browse… to change the specified target from the ELF file to the combined HEX file. Click Apply

 

On the Startup tab, make sure the Load symbols option is using the ELF file. If not, select the [application].elf file.

Click Run (the red text in the console is normal for PyOCD). It will look something like this.

 

After programming, you can reconnect with PuTTY as described earlier.  Press the kit reset button to start the program from the beginning.

 

Debug

Open the Run > Debug Configurations dialog and select the “debug” configuration for your application under GDB PyOCD Debugging. Repeat the same process described earlier for changing the configuration under programming. Click Debug.

The IDE will switch to debugging mode and will halt at the break, ready for debugging.  The screen will look something like this.

Note: While debugging, you may see various errors in your code (main.cpp file), such as “function ‘printf’ could not be resolved.” These are likely not real errors. They are caused by the import of the make file into Eclipse. To turn these errors off, go to Project > Properties > C/C++ > Code Analysis, and disable “Potential Programming Problems” and “Syntax and Semantic Errors.”

That’s it for this example.  There’s a ton of stuff it can do, so play around with it a bit. As an advanced exercise modify it to prompt for an SSID and Password.

One reminder, if you are having trouble with this example, get the mbed-os-example-blinky example working first.  Hit me up in the comments if you have questions.

 

--Matt

 

P.S. I soooo wanted to title this post, A Scanner Darkly MichaelF_56 dared me, but MarkS_11 wouldn't let me (Any Philip K. Dick / Rickard Linklater fans out there?)

Objective:

This blog post discusses implementation of BLE Proximity Profile in  CYW20819 using the device configurator tool in ModusToolBox IDE.

Requirment:

Tool: ModusToolBox 1.1 or above, Serial Terminal (Example: TeraTerm, CoolTerm)

Programming Language: C

Associated Parts: CYW20819

Related Hardware: CYW920819EVB-02 Board (2 boards required)

Proximity Profile:

The purpose of proximity profile is to keep an eye on the BLE Connection link between two devices and trigger an alert when the link is weakened as path loss increases. This profile supports two roles:

  1. Proximity Server (Reporter)
  2. Proximity Client (Monitor)

The proximity profile must include the Link Loss Service. It may optionally include Tx Power Service and Immediate alert service also. Link Loss Service:  The GATT DB of the link loss service has the “Alert Level” characteristic which may be written by the proximity client. This indicates the level of alert to be triggered in the server when the disconnection happens.Tx power Service:  The proximity client may anytime know the Transmitter Power level of the server. This is enabled by reading the Tx Power level characteristic included in the Tx power service.Immediate Alert Service:  The proximity monitor may keep calculating the path loss as follows:

Path Loss = Tx Power Level – RSSI

If the path loss exceeds a certain threshold, the monitor may write the Alert Level characteristic of the IAS, thereby prompting the user to perform appropriate action to avoid disconnection.

Block Diagram:


Using the Device Configurator to generate Proximity Server project:

We can use the Device Configurator Tool in ModusToolBox IDE to generate the GATT DB and an outline code for the firmware. For more details on using the Device Configurator, refer to the Bluetooth Designer Guide in WICED Studio SDK. The GATT DB of the Proximity Server has 3 different services. It is easy to generate the GATT DB and a skeleton code using the Bluetooth Device Configurator Tool.

  1. In the ModusToolBox IDE, go to project folder -> design.modus-> Device Configurator.
  2. Select ‘Bluetooth’ and Click on ‘Launch Bluetooth Configurator’.

      

       3. Using the “Add Service” Option, different services are selected.

        

       4. Add the characteristics as shown above and save the configuration to obtain the skeleton project. The files will be


Firmware: This example contains two projects – The proximity server and the proximity client. Proximity Server:  A skeleton code of the proximity server can be generated using the above steps. Certain key features need to be added to the skeleton code to make the server project complete. According to the specification, a proximity reporter has to advertise with the UUID of Link Loss Service. So, the advertisement data should be modified as follows

 

:/* Set Advertisement Data */

void proximityserver_set_advertisement_data( void )

{    wiced_bt_ble_advert_elem_t adv_elem[3] = { 0 };

    uint8_t adv_flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;

    uint8_t num_elem = 0;
    /* Advertisement Element for Flags */

adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_FLAG;

adv_elem[num_elem].len = sizeof(uint8_t);

adv_elem[num_elem].p_data = &adv_flag;

num_elem++;


adv_elem[num_elem].advert_type  = BTM_BLE_ADVERT_TYPE_16SRV_COMPLETE;

adv_elem[num_elem].len = sizeof(lls_uuid);

adv_elem[num_elem].p_data       = ( uint8_t* )lls_uuid;

   num_elem++;


    /* Advertisement Element for Name */

adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_NAME_COMPLETE;

adv_elem[num_elem].len = strlen((const char*)BT_LOCAL_NAME);

adv_elem[num_elem].p_data = BT_LOCAL_NAME;

num_elem++;


    /* Set Raw Advertisement Data */

wiced_bt_ble_set_raw_advertisement_data(num_elem, adv_elem);

}


Where lls_uuid is declared and initialized as:

/* Link Loss service UUID  */

const uint8_t lls_uuid[2] = {(uint8_t)UUID_SERVICE_LINK_LOSS & 0xFF, (uint8_t)(UUID_SERVICE_LINK_LOSS >> 8)  };


The proximity server receives Link Loss and IAS Alerts in the form of writes. The IAS Alert is triggered instantaneously whereas the link loss alert happens when there is a disconnection. The Alerts are indicated by the LEDs. Proximity Client:  This is a central / client device that performs read / write operations with the GATT DB of the server. The central starts scanning for peripherals that advertise with a Link Loss Service UUID, upon a GPIO button press and initiates the connection. Then it begins to discover all the three services of the proximity profile in the server, one by one and saves the handles of the attributes. Following this, the TX power characteristic of the server is read. Now the client periodically calculates the RSSI every 100 mS and thus the average path loss. If the path loss reaches beyond certain thresholds, the client writes to the Immediate alert characteristics of the server, resulting in an immediate trigger. The thresholds are as follows: MILD ALERT: Path loss above 90 dB HIGH ALERT: Path loss above 100 dBThe Link loss alert can be written to the server by pressing the GPIO Interrupts on the client Eval Board. Every time the GPIO is pressed, a different LL alert value is written to the server.


Programming and Testing:

  1. Install the ModusToolBox 1.1 (or above) in your PC. Plug in two CYW920819EVB-02 Boards and let the drivers bind to the devices. Make sure the jumpers are in place. For more details, please refer Getting Started with CYW20819.
  2. Refer this Knowledge Base Article for importing a new ModustoolBox Project.
  3. Open two windows of Serial Terminal (Example: Teraterm or Coolterm), and bind each of those windows to the PUART COM Ports of each devices. Each device has two COM Ports with consecutive numbers. The COM Port with the bigger number corresponds to the PUART that displays Debug Messages. The one with the smaller number corresponds to the HCI UART. The BaudRate is set to 115200 in the firmware. Make sure the BaudRate in serial terminals is also set to 115200.
  4. Select the proximity_server project you created, and click on ‘Build and Program’ as shown in below figure. You can see the Secure_hub program being built and downloaded into one of the boards. (For more details or troubleshooting, please refer the Getting Started with CYW20819)

       

       

  1. Similarly program the ProximityClient program to the device.
  2. The ProximityServer device will start to advertise. In the ProximityClient device, press the BTN (D2) button for more than 5 seconds for the scan to start. Once the ProximityClient finds the ProximityServer device advertising, it will automatically initiate connection and pairing process.
  3. The client performs discovery in the server and saves the attribute handles of the Link loss alert, immediate alert and transmit power characteristics. The initial Tx power is also read from the server.
  4. Click the BTN (D2) button to write LL Alert value to the server. Every time the button is pressed, a different value of alert level (among the 3: NO_ALERT, MILD_ALERT, HIGH_ALERT) is written to the server. When a link loss happens, the server will be triggered based on the alert level that was written, as indicated by the LED 2.
  5. The client will also keep calculating the Path loss and writes immediate alerts to the server if the path loss value exceeds a certain threshold. Such alerts immediately trigger the server, as indicated by the LED 1.


Path Loss Vs Distance:

 

For a Tx Power of 4 dBm in CYW20819, the path loss Vs Distance values are observed as below in an office environment

 

 

  

Related Documents:

The below table lists all relevant application notes, code examples, knowledge base articles, device datasheets, and Component / user module datasheets.

 

Document

Title

Comment

002-25684

AN225684 - Getting Started with CYW20819

The Getting Started Guide can be downloaded from here.

002-26340

CYW920819EVB-02 Evaluation Kit User Guide

This Evaluation Kit User Guide can be downloaded from here.

Objective:

This example demonstrates the implementation of different security levels of pairing and the data transfer in a multi-connection environment.

 

Overview:

This project instantiates a data hub that plays the roles of GAP Central, GAP Peripheral, GATT Client and GATT Server at the same time, and that is able to pair with up to 3 slaves at different security levels. In addition, the device will also be able to pair with a Master, to which it can send the data collected from the slaves or distribute the data from the master to the slaves.


Requirements:

Tool: ModusToolBox IDE 1.1 and above, Any BLE Central (Example: CySmart Mobile Application), Serial Terminal (Example: TeraTerm, CoolTerm)

Programming Language: C

Associated Parts: CYW20819

Related Hardware: CYW920819EVB-02 Board (2 to 4 required)

 

Block Diagram:

                                                  Figure 1: Block Diagram

 

          

As shown in the above block diagram, the Secure Hub can connect with up to 3 slave devices (programmed with hello_sensor project). It in turn serves as a slave for a master device. All the CYW20819 devices will be able to communicate with the PC via PUART interfaces that appear as serial terminal COM Ports in the PC.

 

Firmware Flow of secure_hub Device:

 

                                                                              Figure 2: Firmware Flow

                

 

 

  • application_start is the program entry point. Here the peripheral UART is set for displaying Debug Messages. The BT Stack and the corresponding management callback are started using the wiced_bt_stack_init () API.
  • db_management_cback()  function in secure_hub.c handles the events generated for the BLE Stack. The BTM_ENABLED_EVT indicates that the Bluetooth stack is ready. Upon the reception of this event, we start the Non-Connectable High Duty Cycle advertisement. The Timer and GPIO Interrupts are registered. The Timer and GPIO Button Press Interrupt callbacks increment the suffix in the Device Name by 1 and then continues the advertisement with the incremented name.
  • In the secure_hub and the hello_sensor projects, the user needs to enter the desired security level and IO Capabilities via console. The console accepts inputs via PUART. The 4 security levels supported in this project are
  1. Just Works
  2. MITM
  3. LE Secure Connection
  4. LE Secure Connection with MITM
  • The hello_sensor project starts advertising, once these details are entered. A Scan is initiated via GPIO Interrupt button press on the secure_hub device. The UUID of the service available in the hello_sensor node is verified in the callback, after which the connection is initiated by the secure_hub.
  • Once a connection is established with the slave, the secure_hub performs a GATT Discovery of the slave using the custom UUIDs of hello_service. The discovery happens in 3 stages:

                 (i)Service

                (ii) Characteristic

                (iii) Descriptor

 

GATT DB:

The GATT DB of the hello_sensor device contains the hello service. The hello_service contains two characteristics (Refer hello_sensor/gatt_db.c and hello_sensor/gatt_db.h files)

  • HANDLE_HSENS_SERVICE_CHAR_NOTIFY:This characteristic has the properties of Notification and Indication. The Bytes to be notified    / indicated are typed in the serial terminal of the hello_sensor device and are transmitted as Notification or Indication to the secure_hub.
  • HANDLE_HSENS_SERVICE_CHAR_BLINK:This characteristic has the properties of Read and Write. The secure nature of the application is demonstrated using this characteristic. In the gatt_db.c file of the hello_sensor, it can be noticed that the permissions of this characteristic include these bitmasks: LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE. This means that this characteristic can be written only when the link has been paired with MITM (Man in the middle protection).  Security Levels (either BTM_LE_AUTH_REQ_MITM or BTM_LE_AUTH_REQ_SC_MITM. The user has to manually take care of this in the application level. When other security levels are used, a write to this characteristic will result in an “Insufficient Authentication” error. Once this characteristic is successfully written by a one byte value, the Red LED on the board blinks as many times as the written value. By the end of the discovery, the secure_hub device stores the Attribute handles of the HANDLE_HSENS_SERVICE_CHAR_BLINK characteristic and the CCCD (Client Characteristic Configuration Descriptor) of the HANDLE_HSENS_SERVICE_CHAR_NOTIFY characteristic. With the attribute handles, the secure_hub device can write to these characteristics descriptors. The CCCD Handle is required, so that the notifications / indications can be enabled / disabled on the hello_sensor slaves. The handles are stored in a global structure g_secure_hub.
  • The GATT DB of the secure_hub device correspondingly has two characteristics HANDLE_SECURE_HUB_SERVICE_CHAR_NOTIFY and HANDLE_SECURE_HUB_SERVICE_CHAR_LED_WRITE. The former is used to transmit the Notifications / Indications received from the hello_sensor devices to the master (if present any). Such notifications are appended along with the Connection ID of the slave, so that the master can identify the slave that has sent the notification. The latter is used to receive writes from the master, which is in-turn written to the HANDLE_HSENS_SERVICE_CHAR_BLINK characteristic on the hello_sensor slaves.
  • At any instant, a new slave may be connected to the secure_hub or a old one may detach itself by pressing the SW1 button the board. A maximum of 3 hello_sensor slaves can be connected to the secure_hub device at a time, in addition to a master. The secure_hub keeps advertising, until a master has connected to it. It will again start advertising when the master has disconnected from it.

 

Programming and Testing:

  • Install the ModusToolBox 1.1 (or above) in your PC. Plug in two CYW920819EVB-02 Boards and let the drivers bind to the devices. Make sure the jumpers are in place. For more details, please refer Getting Started with CYW20819.
  • Refer this Knowledge Base Article   for importing a new ModustoolBox Project.
  • Open two windows of Serial Terminal (Example: Teraterm Coolterm), and bind each of those windows to the PUART COM Ports of each devices. Each device has two COM Ports with consecutive numbers. The COM Port with the bigger number corresponds to the PUART that displays Debug Messages. The one with the smaller number corresponds to the HCI UART. The BaudRate is set to 115200 in the firmware. Make sure the BaudRate in serial terminals is also set to 115200.
  • Select the secure_hub project you created, and click on ‘Build and Program’ as shown in below figure. You can see the Secure_hub program being built and downloaded into one of the boards. (For more details or troubleshooting, please refer the Getting Started with CYW20819)

 

      

  • Similarly program the hello_sensor firmware to another device.
  • In the Teraterm, the debug logs can be seen asking to select the security level among these 4 – No Security, MITM (Man in the middle), LE Secure Connection, LE Secure Connection with MITM. Select the appropriate security level on either device, by entering the corresponding number. Following this, for the security levels that involve MITM, you will have to select the IO Capabilities. The user has to select the MITM.

 

           

          

  • The hello_sensor device will start to advertise. In the secure_hub device, press the SW3 button for more than 5 seconds for the scan to start. Once the secure_hub finds the hello_sensor device advertising, it will automatically initiate connection and pairing process. In case of the security levels with MITM, passkey entry might be required, where the user has to enter the passkey displayed by one device as input to another device.
  • The secure_hub device keeps advertising and it can be connected to another central (any BLE App on Smart Phone, say CySmart.)
  • Once the pairing is complete, the secure_hub automatically enables notifications on the hello_sensor device. The user will be able to send notifications by directly typing on the terminal of the hello_sensor byte by byte. The secure_hub displays the notifications received from the hello_sensor and in turn sends them to the Central if present, and if notifications / indications have been enabled by the Central.
  • At any time, another hello_sensor device can be connected the secure_hub by following steps 7,8,9 while preserving the existing connection. A maximum of 3 hello_sensor devices can be connected to the secure hub.
  • The Central can send write requests to the secure_hub which in turn performs write requests to the slave hello_sensor devices connected to it.

Note: When the secure_hub tries to write to a slave with which it has paired with security levels without MITM, it will receive “Insufficient Authentication Error”. Also, when the master tries to write to the secure_hub, when no slaves are connected to the secure_hub, it will result in an “insufficient authorization” error.

 

Related Documents:

Table -1 lists all relevant application notes, code examples, knowledge base articles, device datasheets, and Component / user module datasheets.

 

Table 1: Related Documents

 

Document

Title

Comment

002-25684

AN225684 - Getting Started with CYW20819

This Getting Started Guide can be downloaded from here.

002-26340

CYW920819EVB-02 Evaluation Kit User Guide

This Evaluation Kit User Guide can be downloaded from here.

Hello Embedded Developers,

 

This is a follow-on to my blog post on using ModusToolbox from the Windows command line. In this example, I add configurators to the mix. In this post I will

  1. Adjust my pinout with the ModusToolbox Device Configurator, launched from the command line
  2. Observe CapSense signals with the CapSense Tuner (launched from the Device Configurator or from the command line).

I’ll also going to show the how to set a make variable on the command line and get help with the various make variables and targets Cypress provides in ModusToolbox.

 

Remember to have your environment set up similar to what is described in the previous blog post. This means:

  • We need GNU make, such as might be found in Cygwin and
  • An environment variable called CYSDK that points to the ModusToolbox installation. In my case have the following two lines in my Cygwin .bash_profile.

    

     CYSDK=C:/Users/mdl/ModusToolbox_1.1

     export CYSDK

 

I have also set up my path to make it easier to launch the tools I am interested in running.  Here are the lines I have in my .bash_profile.

...

# I want to run several ModusToolbox tools from the command line

# The following is how I manage that. You don’t have to use this variable

MTB_TOOLS=/cygdrive/c/Users/mdl/ModusToolbox_1.1/tools

 

# Add the ModusToolbox Device Configurator (allows me to do things like change the pinout)

PATH=$MTB_TOOLS/device-configurator-1.1:$PATH

# CapSense Configurator and CapSense Tuner

PATH=$MTB_TOOLS/capsense-configurator-1.1:$PATH

...

 

Again, start with an example template

In my case, I’m going to start with CapSenseSlider, which is found here $INSTALL\libraries\psoc6sw-1.1\examples\CapSenseSlider

  1. Copy that whole directory over into a clean workspace, for example, C:\Users\<User>\Desktop\CapSense.
  2. Open a Cygwin terminal and go to that directory.
  3. Once you are in that project directory, go to the Source subdirectory and open (or just view) main.c.  Instructions for this example are shown in the comments at the top of the file.  For this walk through, I am using a CY8CPROTO-062-4343W kit.  So, from the instructions I can already see I’ll need to change the pins as the pin assignments for this example are, by default, set up for the CY8CKIT-062-BLE kit or the CY8CKIT-062-WIFI-BT Kit.

 

Here is an excerpt from main.c of the CapSenseSlider example template.

 

...

* Migration to CY8CPROTO-062-4343W kit (ModusToolbox IDE):

*   1. Create this project targeting the CY8CPROTO-062-4343W kit.

*   2. Open design.modus file and replicate P0[3] configuration on P13[7]. Give

*      this pin the alias "LED_RED". Disable P0[3].

*   3. Build and Program

*

* Migration to CY8CPROTO-062-4343W kit (command line make):

*   1. Launch the Device Configurator tool from

*      ModusToolbox_x.x\tools\device-configurator-x.x\

...

 

Set up the pin that drives the LED

 

4. Go up one level in the hierarchy from main.c and from the Cygwin command line type

 

device-configurator design.modus

 

You should see a window similar to the following

 

 

5. Click on the Pins tab to modify the assignments.  According to the instructions in main.c, we will need to replicate all the settings from P0[3] (Pin 3 on Port 0) to P13[7] and disable P0[3]. P13[7] corresponds to LED4 on the board I am using.  Here is a screen shot showing LED4, near the center of the CY8CPROTO-062-4343W board (see red rectangle).

 

 

6. Here is what the settings for P13[7] look like after the edit.

 

Note the alias, LED_RED. That is important. That is how we will be referencing that signal in our code.  If you like, search for the string LED_RED in main.c.  You will see code such as

 

Cy_GPIO_Write(LED_RED_PORT, LED_RED_PIN, redLedState);

 

Cy_GPIO_Write is the API Cypress has provide to write a value to a GPIO.

 

7. Save your new pin configuration (File->Save)

8. Fortunately, pin assignments for the CapSense buttons and slider segments don’t need to be changed since they are the same across several Cypress boards (e.g. CY8CPROTO-062-4343W, CY8CKIT-062-BLE, and CY8CKIT-062-WIFI-BT).

9. I’ll show you how to launch the CapSense Tuner later in this post, but first let’s just see if we can make LED4 turn on and off with the button, BTN0. Make sure you are in the project directory (that is, the one with the design.modus file).

10. Since we’ve modified pin assignments, let’s be safe do a make clean from the command line.

11. Plug in your board to a USB port on your computer using a USB cable. Make sure you that on the board you plug into the USB port that is the Program/Debug USB port on the top-left (when the board is oriented so the CapSense slider is on the bottom). The other USB port is for the PSoC 6’s USB.

 

Build your application and program the board

 

12. Now type make DEVICE=CY8C624ABZI-D44 program

 

Specifying the Make variable DEVICE=CY8C624ABZI-D44 overrides the default targeted device and targets instead the particular PSoC 6 on the board I am using. The make target named program will launch the appropriate tools to download the program from you computer to the board (flash the part).

 

Recall from the previous blog post that the first build of a given project will be substantially longer than future builds.

 

If you want to know more about the make variables available with ModusToolbox, refer to the document Running ModusToolbox from the Command Line. You can also just type make help in a ModusToolbox project directory to get a plethora of information (see the following screen shot for a partial list)

 

 

13. After a successful build, you should be able to repeatedly touch BTN0 on the board to toggle LED4.  You may need to press SW1 (RESET) first.

 

Observe what’s happening with the CapSense sensors using the CapSense Tuner

 

We can watch what happens when each of the sensors are pressed in the CapSenseTuner, which can be launched from the command line in two ways. The first method is to launch it from the Device Configurator. The second is to launch the CapSense Tuner directly from the command line. I'll show both ways.

 

First from the ModusToolbox Device Configurator.

  1. Launch the Device Configurator, as described earlier in this post, that is device-configurator design.modus
  2. Switch to the Peripherals tab
  3. Expand the System group if it’s not already expanded.  You will see that CapSense is enabled (see check mark).  Your window will look something like this

4. Select the CapSense row

5. Launch the CapSense Tuner from the right side under External Tools (see the following screen shot)

 

6. Once the CapSense Tuner window opens

    • Select Communication->Connect KitProg3 UART-[some string]->I2C
    • Select the Widget View if not already selected
    • Select everything in the Widget Explorer
    • Connect (click the round, green button, press F4, or select Connect from the Communication menu)
    • Start (click the triangle pointing to the right, press F5, or select Start from the Communication menu)

     If you forget those last two steps (Connect and Start), the output will be quite boring.

7. Now, touch BTN0 on the board and observe that Button0 in the middle window of the appliation will turn blue. Also notice the blue graph bar in the Touch Signal Graph Window on the right side of the application. It will look something like following screen shot.

 

 

You can also launch the CapSense Tuner directly from the command line (Instead of launching from the ModusToolbox Device Configurator),

That’s done as follows:

 

  1. From the command line, type capsense-tuner
  2. Choose File->Open from the tool menu
  3. Navigate to [Project Directory]/GeneratedSource folder and select cycfg_capsense.h

 

Remember that I have the CapSense tuner set up in my path via my .bash_profile.  You can also launch it directly from $Install\tools\capsense-configurator-1.1 (depending on your version of ModusToolbox, you may need to replace 1.1 with the proper substring).

 

Now, run your finger across the CapSense slider and watch the results in the CapSense Tuner Application (make sure all the sensors are selected on the left). Again, don't forget to connect and start in the CapSense Tuner application. The application will show something like this

 

That it for this post.  You can follow similar steps for other ModusToolbox configurators. In future posts, we’ll show other things, such as the Mbed command line flow.  Let us know in the comments if there is something specific you would like to see.

 

--Matt

Hello Embedded Developers,

 

In this post, I’ll run through a quick example of using ModusToolbox from the Windows command line.  First, let me point you to a couple of reference documents.

  1. Running ModusToolbox from the Command Line – This is shipped with ModusToolbox in the $Install/docs folder and can be found on cypress.com as well (just follow the link).  You will want to refer to this document for additional information, especially if you want to run under Linux or MacOS instead of Windows.  There is also documentation of several make variables available with ModusToolbox.
  2. Cypress Programmer 2.1 OpenOCD CLI User Guide – This is also shipped with ModusToolbox but is located in the $Install/tools/openocd-2.1/docs directory (it’s also on cypress.com). Specifically, you may want to review the Usage Examples chapter.   The path name may vary slightly base on which version of ModusToolbox you have installed.

 

One clarification before I get started: I am not going to cover running configurators or the Mbed command line flow in this post. We will do that separately.

 

OK, first let’s get our Windows environment setup

 

1. We need GNU make.  For Windows, Cypress recommends using a standard make distribution, such as found in Cygwin (uname -r returns “2.11.1(0.329/5/3)” for me).  I use Cygwin64 Terminal to do all my Windows command line stuff.

 

2.  ModusToolbox looks for an environment variable called CYSDK that points to the ModusToolbox installation. I have the following two lines in my Cygwin .bash_profile

 

CYSDK=C:/Users/mdl/ModusToolbox_1.1

export CYSDK

 

Now, let’s build an application

I’ll start with the simple Blinky Application found in $INSTALL\libraries\psoc6sw-1.1\examples\Blinky (see screenshot that follows).

 

  1. Copy that whole directory over into a clean workspace.  Let’s say the new location is C:\Users\<User>\Desktop\BlinkyLED. You can run right from the install location, but I prefer to leave that alone.
  2. Open a Cygwin terminal and go to that directory.
  3. Once I am in the directory, I just type make. The output will look something like this.

 

Be aware that the first build will take a lot longer than subsequent builds for this same project as the shared library, PSoC6_PDL.a, gets compiled the first time.

 

Note: Now is a good time to point out one of my favorite ModusToolbox make variables, DEBUG.  If I experience weird or unexpected behavior, make DEBUG=true is my best friend (observe that DEBUG in all caps and true is all lowercase).

 

4. After a successful build, you’ll see a directory named “build” has been created.  If you’re curious, take a look at the contents of that directory. For example, an ELF file has been created in build/PSoC6_cm4_dual/Debug/mainapp

The file [project name]_mainapp_final.elf in that directory is what we will use to program our device.

5. Optionally edit main.c in the Source directory. For example, I might want to change the blink rate of the LED.  If you edit this file, you obviously need to go up one level in the hierarchy and type make again.

6. As discussed in the Running ModusToolbox from the Command Line document, we have built several handy make targets into ModusToolbox. Let’s use one now!

  1. Plug in your target board (I’m using a CY8CKIT-062-BLE for this example)
  2. type make program (this will program your board with the elf file you just created).

 

Successful programming will end with output that look something like the following.

 

That’s it. You are ready to try some examples on your own.

 

For reference, here is a portion of my .bash_profile. A few notes about it:

  • My user name for this example is “mdl”
  • My ModusToolbox is installed in C:\Users\mdl\ModusToolbox_1.1
  • It’s easy to get tripped up setting CYSDK if you are not careful.  Pay close attention to this.

 

####### excerpt from the .bash_profile file for my Cygwin terminal

 

# Set up environment variable used by ModusToolbox tools

export CYSDK=C:/Users/mdl/ModusToolbox_1.1

 

# I want to run several ModusToolbox tools from the command line

# The following is how I manage that. You don’t have to use this variable

MTB_TOOLS=/cygdrive/c/Users/mdl/ModusToolbox_1.1/tools

 

# Add the ModusToolbox Device Configurator

PATH=$MTB_TOOLS/device-configurator-1.1:$PATH

 

# To Add CapSense Configurator, uncomment the next line

#PATH=$MTB_TOOLS/capsense-configurator-1.1:$PATH

 

# To Add the Bluetooth Configurator, uncomment the next line

#PATH=$MTB_TOOLS/bt-configurator-1.1:$PATH

 

# To Add USB Configurator, uncomment the next line

#PATH=$MTB_TOOLS/usbdev-configurator-1.1:$PATH

 

# You can add similar lines for QSPI, SmartIO, etc.

 

# Add the FW Loader utility (used for various things such as updating kits to Kitprog3)

PATH=$MTB_TOOLS/fw-loader-2.1/bin:$PATH

 

####### End excerpt from the .bash_profile

 

In future posts, we’ll show things like running the configurators from the command line and using the Mbed flow.  Let me know in the comments if there is something specific you would like to see.

 

--Matt

Our friends over at Percepio just won a Best in Show award at Embedded World in Germany. Device Firmware Monitor (DFM) was the winner in the Development Tools category.

Percepio Device Firmware Monitor, the new cloud service for software quality assurance in IoT product organizations, has been awarded Best in Show at Embedded World 2019, in the Development Tools category.DFM is an exciting new cloud service for IoT firmware developers, providing awareness of firmware issues in deployed devices and speeding up resolution. DFM notifies firmware developers within seconds after an error has been detected and provides diagnostic information about the issue via the cloud, including a software trace that visualizes what was going on in the firmware when the error occurred. This makes it far easier to understand the problem, find a solution, and quickly dispatch an over-the-air (OTA) update to correct the problem. DFM integrates Percepio's leading analysis tool Tracealyzer, with AWS IoT connectivity.Percepio Best in Show Diploma

 

Most embedded software is shipped with defects remaining in the code. On average, 5 percent of all bugs introduced during development elude verification efforts and make their way to customers. The IoT trend brings OTA updates as a potential remedy, but developers can't fix bugs they are not aware of. Automatic feedback is needed. Percepio DFM is a ground-breaking new approach, providing awareness and diagnostics that allow IoT developers to leverage the full potential of OTA updates to continuously improve their firmware and customer experience.

Congratulations to Johan, Mike and the rest of the Percepio team! We think DFM is an exciting new product and, pretty soon, we hope to test it out with PSoC 6 and our connectivity devices.

On Windows 10, mbed build times are greatly affected by Windows Defender scan. To speed up the builds, follow the steps below. The steps basically add process and folder exclusions to Windows Defender.

 

  • Open Windows PowerShell:
    • Click Start
    • Type in PowerShell
    • Right Click Windows PowerShell in the search results and then click Run as Administrator
    • Run the following commands depending upon the toolchain that you are using

 

Add-MpPreference -ExclusionPath "C:\mbed-cli\" <-- replace with your mbed cli folder path

Add-MpPreference -ExclusionPath "D:\mbed\" <--  replace with your mbed working folder path

 

Add-MpPreference -ExclusionProcess "cmd.exe"

Add-MpPreference -ExclusionProcess "make.exe"

Add-MpPreference -ExclusionProcess "python.exe”

Add-MpPreference -ExclusionProcess "cc1.exe”

Add-MpPreference -ExclusionProcess "cc1plus.exe”

Add-MpPreference -ExclusionProcess "mbed.exe”

Add-MpPreference -ExclusionProcess "sh.exe”

Add-MpPreference -ExclusionProcess "as.exe”

 

Using GCC ARM ToolChain

 

Add-MpPreference -ExclusionPath "C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin\" <-- change this to your GCC installation path

 

Add-MpPreference -ExclusionProcess "arm-none-eabi-gcc.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-cpp.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-g++.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-objcopy.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-as.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-ar.exe"

 

Using GCC ARM ToolChain Provided with ModusToolbox

 

Add-MpPreference -ExclusionPath "C:\Users\snvn\ModusToolbox_1.1\tools\gcc-7.2.1-1.0\bin\" <-- change this to your ModusToolbox installation path

 

Add-MpPreference -ExclusionProcess "ModusToolbox.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-gcc.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-cpp.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-g++.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-objcopy.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-as.exe"

Add-MpPreference -ExclusionProcess "arm-none-eabi-ar.exe"

 

Using IAR ToolChain

 

Add-MpPreference -ExclusionPath "C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.8\arm" <-- change this to your IAR installation path

 

Add-MpPreference -ExclusionProcess "iccarm.exe”

Add-MpPreference -ExclusionProcess "iasmarm.exe”

Add-MpPreference -ExclusionProcess "ilinkarm.exe”

 

Using ARMCC ToolChain

 

Add-MpPreference -ExclusionPath "C:\Keil_v5\ARM" <-- change this to your ARMCC installation path

 

Add-MpPreference -ExclusionProcess "armar.exe”

Add-MpPreference -ExclusionProcess "armasm.exe”

Add-MpPreference -ExclusionProcess "armcc.exe”

Add-MpPreference -ExclusionProcess "armlink.exe”

 

  • By default, mbed cli uses parallel builds, that’s why you will notice that a simple mbed compile command spawns a lot of processes. That feature is not enabled by default in ModusToolbox 1.1 for mbed imports. Please follow the page below to enable it for each project. Set it to an optimal number as suggested by the IDE.

How do I enable parallel builds within Eclipse?

 

  • Further, Eclipse/ModusToolbox 1.1, by default, tries to refresh the workspace and index the files as the build progresses. This will slow down your machine. Follow the page below to stop that from happening:

Eclipse stop background refresh

 

  • If your mbed working folder is inside your corporate OneDrive sync folder, pause the OneDrive sync. The sync process hogs CPU and will slow down the build time further

 

  • Build speed could be further increased by using a pre-built static library of the mbed-os. Thanks to my colleague K Aadhi Vairava Sundaram for this tip.
    • Import required example:
    • Git clone mbed-os separately
      • use mbed import <commit code> from above
      • change directory to mbed-os
      • Run mbed compile -m <your compile target> -t <your toolchain> --library
    • copy generated library to example folder
      • copy BUILD/libraries/mbed-os/*  ../mbed-os-example-blinky/mbed-os
    • Build example
      • mbed compile --toolchain <your toolchain> --target <your compile target>

 

Note that although mbed-os library can be built for multiple targets and multiple toolchains, only one library at time can be copied to example folder.

Last time I blogged (is that really a word? what a strange world this is) I wrote about the ModusToolbox device configurator. We set up a pair of pins, one called "LED" and the other "SW" (because, it turns out that I am too lazy to write "Switch" or "Button"). Anyway, I mentioned that the configurator generates the setup code for the pins and that I would explain how that works. So here goes...

At the top of main() there is a function call to "init_cycfg_all()" and that's where the pins get initialized. That function lives in a file called cycfg.c which you can find in the GeneratedSource folder.

You can see here that this folder is actually a link (see the tiny arrow on the folder icon) to the configuration project. That project is the one that contains the design.modus file, which contains all the selections and information from the configurators, and the source files generated when I saved my configuration.

Also in this folder are the configuration files for connectivity, which means the signals that are connected inside the PSoC, platform, which is the power, debug and clock setup code, and pins, which we are most interested in.

 

First, here is the meat of cycfg.c, showing the init_cycfg_all() function.

 

#include "cycfg.h"

void init_cycfg_all()
{
    init_cycfg_pins();
    init_cycfg_platform();
    init_cycfg_connectivity();
}

 

I am sure you'll be flabbergasted to learn that init_cycfg_pins() is in cycfg_pins.c - this is pretty simple stuff (by design - so you can dig in and really understand what the tools are doing for you). What does that function look like? Well, this...

 

void init_cycfg_pins(void)
{
    Cy_GPIO_Pin_Init(SW_PORT, SW_PIN, &SW_config);
    Cy_GPIO_Pin_Init(LED_PORT, LED_PIN, &LED_config);
    Cy_GPIO_Pin_Init(SWO_PORT, SWO_PIN, &SWO_config);
    Cy_GPIO_Pin_Init(SWDIO_PORT, SWDIO_PIN, &SWDIO_config);
    Cy_GPIO_Pin_Init(SWCLK_PORT, SWCLK_PIN, &SWCLK_config);
}

 

The pins are set up with a call to a PDL function that accepts the port address, pin number within the port, and a pointer to a configuration struct. There are five calls - one for LED, one for SW, and three for debugging - SWCLK, SWDIO, and SWO. It's all simple enough, but where do those arguments come from? The ports and pins are defines and they come from cycfg_pins.h. Here is a snippet for SW, the input pin.

 

#define SW_PORT GPIO_PRT0
#define SW_PIN 4U
#define SW_NUM 4U
#define SW_DRIVEMODE CY_GPIO_DM_PULLUP
#define SW_INIT_DRIVESTATE 1
#ifndef ioss_0_port_0_pin_4_HSIOM
#define ioss_0_port_0_pin_4_HSIOM HSIOM_SEL_GPIO
#endif
#define SW_HSIOM ioss_0_port_0_pin_4_HSIOM
#define SW_IRQ ioss_interrupts_gpio_0_IRQn

 

 

I'll go through all of those defines in order. SW_PORT is the crucial macro, it maps to a pointer to the port 0 hardware:

#define GPIO_PRT0                               ((GPIO_PRT_Type*) &GPIO->PRT[0])

I am glad that's generated for me!

Next there is SW_PIN, the pin number. SW_NUM is always the same as the PIN macro - the "NUM" style is used for lots of peripherals (which I'll show you next time) and so we generate two macros, in case you are lazy like me and always want to use one style. it's your choice.

After that we have the drive mode - PULLUP creates an active low button. DRIVESTATE is the initial pin value (so pin reads get the right result before the button is pressed). Then there are some definitions of internal connections, which are unused for software-driven GPIOs. Lastly, there is the IRQ definition, which is useful when you trigger interrupts from the pin and REALLY useful when you trigger interrupts on multiple pins in the same port (another subject for another day).

All that explains where the first two arguments come from. The last one is a C variable and it is back in the cycfg_pins.c file. Here is the configuration struct for SW.

 

const cy_stc_gpio_pin_config_t SW_config =
{
    .outVal = 1,
    .driveMode = CY_GPIO_DM_PULLUP,
    .hsiom = SW_HSIOM,
    .intEdge = CY_GPIO_INTR_DISABLE,
    .intMask = 0UL,
    .vtrip = CY_GPIO_VTRIP_CMOS,
    .slewRate = CY_GPIO_SLEW_FAST,
    .driveSel = CY_GPIO_DRIVE_FULL,
    .vregEn = 0UL,
    .ibufMode = 0UL,
    .vtripSel = 0UL,
    .vrefSel = 0UL,
    .vohSel = 0UL,
};

 

I will not bore you explaining all of that but a few things are intreesting. Firstly, the struct is const. That means it is stored in flash and not copied into RAM on startup. This saves memory but, if you want to change the struct at run-time, you can turn off the const from the device configurator, by un-checking "Store Config in Flash". Note that this option saves RAM, but not flash, because the INITDATA always has to be kept in non-volatile memory.

 

 

Back in the C code you can see that the pin initialization, like the PULLUP and interrupt settings, is all contained in the struct. The end result of all this code is that device initialization is an automated function with PSoC in ModusToolbox but, if you need to over-ride these choices for any reason, it is really easy to make a copy of the generated code, edit it and simply call your new function and not the generated one!

Next time, I'll take you a little deeper into the configurators and set up some more interesting peripherals, and then, if all goes well, I'll introduce you to the wonders of the CapSense configurator and its pal, the CapSense tuner!

I promised to tell you about the FreeRTOS templates and, now is the time, so, here we go... In the last post I used the PioneerKitApp template. This time I'll try PioneerKitAppFreeRTOS. It's a bit of a mouthful.

PioneerKitAppFreeRTOS starter template

When the project is created it looks identical to last week's project except this one includes the FreeRTOS code and has an example FreeRTOSConfig.h in your source folder.

ModusToolbox application with Amazon FreeRTOS middleware

You will see that the code in main.c is quite different from the other template. First of all, in main(), it creates a task and starts the FreeRTOS scheduler.

    BaseType_t retval;      retval = xTaskCreate( blinky, BLINKY_NAME, BLINKY_STACK_SIZE, NULL, BLINKY_PRIORITY, NULL );     if( pdPASS == retval )     {         vTaskStartScheduler();     }

 

Notice how the code checks the return code from the create call because that is the easiest way to avoid out of memory start-up problems in the OS. I had no problems because I configured ooooooodles of RAM for my tasks, and I only have one! The task itself is implemented in a function called blinky() and has the following parameters.

/* Defines for a simple task */ #define BLINKY_NAME         ("Blinky") #define BLINKY_STACK_SIZE   (1024) #define BLINKY_PRIORITY     (5) #define BLINKY_DELAY_TICKS  (500)

 

The two NULL arguments are unused options you can use when creating tasks - the first is a pointer to to an argument that gets passed into blinky() and the second is a pointer for the OS to return the created task's ID. I'll go into more detail on that later.

And here is the blinky() code. It's very complex (not) - toggle the pin and wait for a while!

void blinky( void * arg ) { (void)arg; for(;;) { /* Toggle the user LED periodically */ Cy_GPIO_Inv( KIT_LED1_PORT, KIT_LED1_PIN ); vTaskDelay( BLINKY_DELAY_TICKS ); } }

 

You can build and program the application to verify the OS running - the orange LED blinks at 1Hz (BLINKY_DELAY_TICKS is 500, and each tick is 1ms, so the LED is off for 500ms and on for 500ms). Let's extend that a little by blinking another LED. First, let's make a copy of blinky() and change the LED and frequency.

void blinky2( void * arg ) { (void)arg; for(;;) { /* Toggle the user LED periodically */ Cy_GPIO_Inv( KIT_LED2_PORT, KIT_LED2_PIN ); vTaskDelay( BLINKY_DELAY_TICKS / 3 ); } } 

 

Then create the new task with a new name.

#define BLINKY2_NAME        ("Blinky2")  retval = xTaskCreate( blinky, BLINKY_NAME, BLINKY_STACK_SIZE, NULL, BLINKY_PRIORITY, NULL ); if( pdPASS == retval ) retval = xTaskCreate( blinky2, BLINKY2_NAME, BLINKY_STACK_SIZE, NULL, BLINKY_PRIORITY, NULL );

 

When I program the application the red LED blinks three times faster than the orange one.

I do not know about you but that copied code in blinky() and blinky2() drives me a bit nutty. Its the same code! I want to reuse it - for all the LEDs. The functions only differ in the pin they toggle and the time they go to sleep. Let's use that argument pointer I talked about above. First I create a struct to contain the arguments and five variables for each of the LEDs on the kit (red, orange, and the RGB).

struct led_t { GPIO_PRT_Type* port; unsigned int   pin; int            rate; };  const struct led_t LED1 = { KIT_LED1_PORT,  KIT_LED1_PIN,  300 }; const struct led_t LED2 = { KIT_LED2_PORT,  KIT_LED2_PIN,  600 }; const struct led_t LEDR = { KIT_RGB_R_PORT, KIT_RGB_R_PIN, 100 }; const struct led_t LEDG = { KIT_RGB_G_PORT, KIT_RGB_G_PIN, 150 }; const struct led_t LEDB = { KIT_RGB_B_PORT, KIT_RGB_B_PIN, 750 };

 

Then create more tasks and give each call the argument pointer.

    retval = xTaskCreate( blinky, "LED 1", BLINKY_STACK_SIZE, (void *)&LED1, BLINKY_PRIORITY, NULL ); if( pdPASS == retval ) retval = xTaskCreate( blinky, "LED 2", BLINKY_STACK_SIZE, (void *)&LED2, BLINKY_PRIORITY, NULL ); if( pdPASS == retval ) retval = xTaskCreate( blinky, "LED R", BLINKY_STACK_SIZE, (void *)&LEDR, BLINKY_PRIORITY, NULL ); if( pdPASS == retval ) retval = xTaskCreate( blinky, "LED G", BLINKY_STACK_SIZE, (void *)&LEDG, BLINKY_PRIORITY, NULL ); if( pdPASS == retval ) retval = xTaskCreate( blinky, "LED B", BLINKY_STACK_SIZE, (void *)&LEDB, BLINKY_PRIORITY, NULL );

 

Lastly, I deleted blinky2() and modified blinky() to use the argument.

void blinky( void * arg ) { struct led_t *led = (struct led_t *)arg; for(;;) { /* Toggle the user LED periodically */ Cy_GPIO_Inv( led->port, led->pin ); vTaskDelay( led->rate ); } }

 

Now, when I program the kit, it twinkles like the lights in my Christmas tree (that I already miss terribly) and I did not have to write 5 almost-identical tasks to make it work. I attached the source code to this article for you, in case you want to play with the LEDs (note: I had to change the file extension to "txt" because, apparently, "c" files are dangerous!!!).

The point of all this is not really to create a Christmas tree replacement. Hopefully it's obvious that the template is a really nice way to get started on a multi-tasking application because it configures all the basic peripherals on the board, sets up the OS, and gives you a stub task (blinky) that you can modify and copy to make your own tasks (that do a little more than blink LEDs). Happy tasking!

I have recently shown you two of the most helpful starter templates in ModusToolbox - PioneerKitApp and PioneerKitAppFreeRTOS. Just as an FYI, if you have the PSoC 6 prototyping kit instead, there are equivalent templates for that kit called ProtoKitApp and ProtoKitAppFreeRTOS. All of these templates set up some kit basics for you so that you can jump straight into writing your application code. Essential peripherals like clocks, debugging, LED and button pins, CapSense, plus the I2C and UART bridge peripherals are all pre-configured in the design.modus file. If you do not like our configuration, you are very welcome to launch the configurators and modify the setup the way you need it. How should you go about that?

Well, the short answer is to just double-click on the design.modus file and have a good time! But, since I am feeling a little more helpful that that today, a walk-through of how to set up peripherals from scratch might be good. I'll start with a new project and will use (yet) another project template - EmptyPSoC6App. This template sets up the barest of bare minima - just the clocks and debug.

In the EmptyPSoC6App_config project, find and double-click on design-modus to open the device configurator. There are five panels in the GUI - Peripherals, Pins, Platform, Peripheral Clocks, and DMA. Switch to the Platform tab and you will see the very minimal setup from the template.

 

MTconfigs1.png

In the Resource panel (left) you will see Debug, Power and System Clocks. If you just select each of them in turn you will see, in the Parameters panel (right), that SWD and SWO are enabled for debugging, the power supply is set to 3.3V, and the PLL is configured to generate a frequency of 144MHz. For your early projects there is probably no reason to change any of these values so I'll move on to configuring an LED and button.

 

Switch over to the Pins tab and open the tree display to see the pins in Port 13. Click on the checkbox next to pin 7 to start setting up the pin. Conveniently, this pin is attached to an LED on both of our Pioneer kits and prototyping kit so this should work on whatever board you have. Start by giving the pin a name (or alias if you want to be fancy) - I am using "LED". Then set the Drive Mode of the pin to "Strong Drive. Iinput buffer off" using the drop-down menu in the parameters panel.

 

MTconfigs2.png

 

Next repeat that basic sequence for Port 0. Pin 5 is connected to a push button (again, thanks to my pal Ronak who designs all these boards, it is the same pin on all kits) with I am calling "SW". To configure the input choose "Resistive Pull-Up. Input buffer on" drive mode so that my active-low button reads 1 when up and 0 when pressed. Save the edits and switch back to the IDE.

MTconfigs3.png

In the EmptyPSoC6App_mainapp project, open the Source folder and double-click on main.c to open it in the editor and write the following code in the infinite loop.

 

state = Cy_GPIO_Read( SW_PORT, SW_PIN );

Cy_GPIO_Write( LED_PORT, LED_PIN, state );

 

That is all we need to prove that our configuration works. In the IDE Quick Panel click on "EmptyPSoC6App Program (KitProg3)" and, if you did everything right, it will build the application and program the kit. When you press and hold the button, the LED will turn on...

 

So, there are the basics for device configuration with ModusToolbox. Next time I'll show you the firmware that makes all this work and get a little more fancy with some PWM tricks and fun with the serial communication blocks.

I previously wrote about using the New Application wizard in ModusToolbox and showed you the BlinkyLED project. Now I want to show you another template that I believe will be more useful to you in the long run. It is called PioneerKitApp and it supports both the PSoC 6 Pioneer kits - CY8CKIT-062-BLE and CY8CKIT-062-WIFI-BT. When you highlight the template in the wizard it tells you the following about the project.

 

Basic peripheral configuration for the PSoC 6 Pioneer kits (CY8CKIT-062-*). Debug is enabled and platform clocks are set for high performance (144MHz CLK_FAST for CM4 core and 72MHz CLK_SLOW for CM0+) but with a peripheral-friendly CLK_PERI frequency (72MHz). In addition the user LEDs and switch, KitProg3 UART and I2C bridges, and CapSense buttons and slider are  configured.

ModusToolbox templates

My job involves creating a lot of projects and almost every one of them blinks an LED or prints a message to the UART at some point. Depending upon how well my day is going the message might be "PSoC Rocks!" or, if things aren't going so well, something a little less repeatable! But I digress, the point is that I get really fed up of configuring pins and UARTs every day.  So I created a template and my boss told I should share it with you.

 

When you create the application ModusToolbox opens up the file setup_readme.txt automatically. This file describes all the settings I made in the configurator tools... clocks, pins, UART, I2C and CapSense. This means I can start programming without even opening the configurators. For example, here is a program to print a message and toggle an LED. I wrote this code immediately after creating the application without worrying about configuring peripherals, adding middleware (to support printf), picking libraries, choosing part numbers, setting include paths, or any of that nonsense.

 

#include "cy_device_headers.h"

#include "cycfg.h"

#include "cycfg_capsense.h"

#include "stdio.h"

 

int main(void)

{

    int count = 0;

    cy_stc_scb_uart_context_t uart_context;

    init_cycfg_all();

    __enable_irq();

 

    Cy_SCB_UART_Init( KIT_UART_HW, &KIT_UART_config, &uart_context );

    Cy_SCB_UART_Enable( KIT_UART_HW );

 

    for(;;)

    {

        Cy_GPIO_Inv( KIT_LED1_PORT, KIT_LED1_PIN );

        printf( "Message #%d\r\n", ++count );

        Cy_SysLib_Delay( 500 );

    }

}

 

Let's dig in a little. First of all, notice that I am using printf(), which is defined in the usual C stdio.h header file. This is supported by the retarget_io middleware package that adds three files to the application - retarget_io.c, stdio_user.c and stdio_user.h - which you can see highlighted in the project here.

ModusToolbox printf

The "user" files are placed into the Source folder because they are intended to be user-modifiable. In the template I already did that to choose the serial block for the KitProg3 serial-USB bridge (so I can see the output in a PC terminal emulator like teraterm). Here are the settings I made in stdio_user.h.

 

#include "cycfg.h"

/* Must remain uncommented to use this utility */

#define IO_STDOUT_ENABLE

#define IO_STDIN_ENABLE

#define IO_STDOUT_UART      KIT_UART_HW

#define IO_STDIN_UART       KIT_UART_HW

 

Where did that KIT_UART_HW macro come from? Or the KIT_LED_PORT macro for that matter? Well, they got set up in the device configurator. Here is a screenshot of the device configurator, where I have called the serial communication block #3 "KIT_UART" and given it the personality UART_v1.0 (I could have used I2C or SPI instead).

ModusToolbox templates and printf middleware

The configurator generates the KIT_UART_HW macro and the KIT_UART_config variable automatically, so writing the code is easy and fast. I did a similar thing for the LEDs, giving the orange LED the alias "KIT_LED1" so that the tool generates the PORT and PIN macros for me.

ModusToolbox configuration

Next time, I'll show you a variation of this template that sets up FreeRTOS for you so you can get multi-tasking in no time at all.