Skip navigation
Home > All Places > ModusToolbox > Blog
1 2 3 Previous Next

ModusToolbox

41 posts

I don’t know about you, but I quickly got bored of always starting the ball in the same place. I’ve added some code to make that position random. The PSoC 6 device has an on-board true random number generator but, I’ll be honest, I’ve not looked up how to use it yet! So I shall use the poor-man’s option – read the noise on a pin with the ADC. Maybe I’ll circle back to this in the future and do it right!

The ADC on the PSoC 6 connects to port 10 and, after a quick scan of the kit silk screen I found that P10.7 has nothing connected to it (other than a solder hole). OK, that’s a lie. It was not quick and I did not find it. It’s been years since I could read a silk screen with my clapped-out old peepers. I had to go find a teenager and bribe him to read it for me. Why am I so honest with you on this blog???

Anyway, this pin will have enough noise to be a good random number seed. Note that I will not use the noise itself as the random number because it does not have a wide range of values. I’d just get a varying number in a small area of the screen. Instead I am going to use a pair of C stdlib run-time library functions. Start by including the header file.

#include <stdlib.h>

Write this simple function to get a random number from the library rand() function and constrain it to a desired range.

uint32_t getRandomInRange( uint32_t lo, uint32_t hi )

{

    uint32_t num = rand();

 

    num %= ( hi - lo );

    num += lo;

 

    return num;

}

Then change the bounce() function to call this function instead of hard-coding the values.

    uint16_t xPos = getRandomInRange( BOX_LEFT + radius, BOX_RIGHT  - radius );

    uint16_t yPos = getRandomInRange( BOX_TOP  + radius, BOX_BOTTOM - radius );

The last job is to get the random number and use it as a seed. I did this in a function with a pin as argument so I could experiment with different pins and verify that P10.7 is a good choice. The function initializes the ADC and selects a channel for the desired pin, then it reads the voltage at the pin and passes that value to srand() as the seed argument. Then it dutifully deinitializes the ADC like a good function should.

void initRandomNumber( cyhal_gpio_t noisy_pin )

{

    cyhal_adc_t adc;

    cyhal_adc_channel_t channel;

    uint16_t seed;

 

    /* Turn on the ADC for the specified pin */

    cyhal_adc_init( &adc, noisy_pin, (cyhal_clock_divider_t*)NULL );

    cyhal_adc_channel_init( &channel, &adc, noisy_pin );

 

    /* Read the noise (random) and use it as the seed */

    seed = cyhal_adc_read_u16( &channel );

    srand( seed );

 

    /* Turn off the ADC */

    cyhal_adc_channel_free( &channel );

    cyhal_adc_free( &adc );

}

Call this function from main(), with the argument “P10_7”, which is defined in the BSP, before you call bounce().

    initRandomNumber( P10_7 );

Program the kit with the new program and you’ll see that it (probably) does not start the ball in the center of the box. Good eh? Try resetting the kit a few times and the start point should change every time.

bounce_random_1.jpg     bounce_random_3.jpg

As before I have attached a copy of the main.c source file for your reference. I think we have had as much fun as you can have with just one ball now. Next time, I am going to add an RTOS to my project and spawn multiple ball-bouncing tasks…

MarkS_11

Fun with the TFT

Posted by MarkS_11 Jan 20, 2020

I have never used the TFT to do anything other than draw some shapes and print text. Of course, that’s not too surprising really... since that’s what they are designed to do! But I am going to make some simple animated applications now and that should force me to dig a little deeper into what the screen can do and how emWin works. Should be fun!

I am going to use the function void GUI_FillCircle(int x0, int y0, int r) to draw a ball and move it around the screen. I’ll be doing this from the TFT_Play project I created last time so I do not need to bother adding the libraries and setting the COMPONENT in the Makefile again. I’ll start by defining the screen dimensions and a box inside that. The idea is that the ball shall bounce around inside the box so the following allows me to define a box of any shape and position.

#define SCREEN_WIDTH    (320)

#define SCREEN_HEIGHT   (240)

 

#define SCREEN_LEFT     (0)

#define SCREEN_RIGHT    (SCREEN_WIDTH-1)

#define SCREEN_TOP      (0)

#define SCREEN_BOTTOM   (SCREEN_HEIGHT-1)

 

/* Define the box in which to bounce */

#define BOX_HMARGIN     (10)

#define BOX_VMARGIN     (10)

#define BOX_LEFT        (SCREEN_LEFT+BOX_HMARGIN)

#define BOX_RIGHT       (SCREEN_RIGHT-BOX_HMARGIN)

#define BOX_TOP         (SCREEN_TOP+BOX_VMARGIN)

#define BOX_BOTTOM      (SCREEN_BOTTOM-BOX_VMARGIN)

The FillCircle function takes a radius as the third argument and so whenever the ball is drawn such that its edge touches a side, we should bounce. Here are some handy functions that figure out if the ball is touching

inline int isBallTouchingLeft(   int x, int radius) { return ( x <= ( BOX_LEFT   + radius ) ); }

inline int isBallTouchingRightint x, int radius) { return ( x >= ( BOX_RIGHT  - radius ) ); }

inline int isBallTouchingTop(    int y, int radius) { return ( y <= ( BOX_TOP    + radius ) ); }

inline int isBallTouchingBottom( int y, int radius) { return ( y >= ( BOX_BOTTOM - radius ) ); }

Next, here is a type for the ball. It may seem unnecessary to create this right now but, in my next blogs, I intend to create multiple balls and bounce them all at the same time.

typedef struct

{

    GUI_COLOR   color;

    uint8_t    radius;

    uint8_t    speed;

    int8_t     xDir;

    int8_t        yDir;

} ball_t;

The color and radius should be pretty self-explanatory. The speed is going to control the time between moves and has a range between 0 and 50 (#define MAX_SPEED (50)). A speed of 0 is the slowest (boring) and a speed of 50 hurtles around the screen with wild abandon! The direction arguments indicate the number of pixels to move every time, which provides a lot of freedom to alter the angle of travel. Note that they are signed quantities so you can start the ball in either a left/right or north/south.

The meat of the program is going to be in the void bounce( ball_t* ball ) function, below. It takes a pointer to the ball as an argument. Again, this is a little overkill for a single ball, but it will be really useful in my next few blogs. It is good form to make local copies of the ball_t values because it is pointing to memory outside of the function. Making copies of the values helps avoid very bad results if you make the mistake of passing a pointer to local (non-static) data. You will see a little later that I explicitly define the ball in static memory but constrain its scope to the main() function. I could have just created a global but then I would be tempted to access it directly inside bounce(), which is lazy and would have to be re-written in my next blog anyway.

Once the color, speed, size and direction are set, the forever loop draws the ball (in red), delays a while based on the speed, then clears the ball (in black), changes the position, and repeats.  You can also see how those helper functions, above, are used to make the ball actually bounce of the edges.

void bounce( ball_t* ball )

{

    /* Set up local variables to control the ball */

    GUI_COLOR color = ball->color;

    uint32_t speed = ( MAX_SPEED < ball->speed ) ? 0 : MAX_SPEED - ball->speed;

    uint8_t radius = ball->radius;

 

    /* Extract the up/down and left/right increments */

    int8_t xDir = ball->xDir;

    int8_t yDir = ball->yDir;

 

    /* Start the ball at a fixed position */

    uint16_t xPos = BOX_LEFT + ( ( BOX_RIGHT - BOX_LEFT ) / 2 );

    uint16_t yPos = BOX_TOP + ( ( BOX_BOTTOM - BOX_TOP ) / 2 );

 

    /* Draw - wait - clear - move */

    for(;;)

        {

        /* Draw the ball */

        GUI_SetColor( color );

        GUI_FillCircle( xPos, yPos, radius );

 

        /* Moderate the speed of the ball */

        Cy_SysLib_Delay( speed );

 

        /* Clear the previously drawn ball */

        GUI_SetColor( GUI_BLACK );

        GUI_FillCircle( xPos, yPos, radius );

 

        /* If the ball touches an edge, change direction */

        if( isBallTouchingLeft( xPos, radius ) || isBallTouchingRight( xPos, radius ) )

            { xDir = -xDir; }

        if( isBallTouchingTop( yPos, radius ) || isBallTouchingBottom( yPos, radius ) )

            { yDir = -yDir; }

 

        /* Move the ball in both axes */

        xPos += xDir;

        yPos += yDir;

    }

}

All that is needed now is to show you the code in main() that sets everything up. I created a small, speedy red ball (in permanent memory) that moves one pixel left-right and 3 pixels up-down on every cycle, then I turned on the display with a gray background, and finally called my bounce() function (which never returns).

    static ball_t b1 = { GUI_RED, 3, 45, +1 /*RIGHT*/, -3 /*UP*/ };

 

    GUI_Init();

    GUI_SetBkColor( GUI_GRAY );

    GUI_Clear();

 

    bounce( &b1 );

I’ve attached a completed main.c file to this blog so, if you run into problems following my ramblings, you have a good reference. Try out a few different values in the ball_t struct and you’ll find out that making them too big and too fast creates display problems because you start pushing the limits of the OLED update rate. Or maybe it is my eyes???

Here is a picture of the screen after a few seconds. Notice how the background is gray and the ball is leaving a black trail behind it. I did that because I like the way it looks but you should be able to turn the effect off if you do not like it. Try out the program with a few different box sizes too – and let me know if you find a bug!!!

 

bounce1.jpg

MarkS_11

Adding TFT to my project

Posted by MarkS_11 Jan 13, 2020

Last time out I showed you how to create a new application in ModusToolbox IDE 2.0 Today, I am going to add TFT support and draw a few things on the screen. Before I launch into that, I think I should explain how eclipse presents your project, because it is a little different to what you've seen on the command-line. Here is the Project Explorer view.

project-explorer.png

Binaries is a virtual folder, not a real one on disk. It appears once you have successfully built the application and, in our case, just shows you the elf file(s) that have been built.

 

Archives is another virtual folder and it shows all the binary libraries in the project. If you look in there you will see the CapSense archives (.a and .ar files) for both hard and soft floating point on the three supported compilers (GNU, Arm and IAR).

 

Includes lists the include paths. Note that, because we are using a Make-based flow, PSoC applications only need the paths to the compiler run-time libraries in here, not all the ModusToolbox headers.

 

build is a real folder where all the generated object files are saved, in sub-folders for the kit and compiler configuration (e.g. CY8CKIT-062-WIFI-BT/Debug).

 

images comes from the starter example project (empty app) and it contains the pictures and diagrams that are displayed in the README.md file.

libs is the folder you've seen before, where the ModusToolbox Library Manager saves lib files and sources.

Hopefully you are now a little more comfortable with Eclipse so let's add that TFT code. Open the Library Manager from the Tools section of the Quick Panel or by right-clicking on the project name in the Project Explorer and opening the ModusToolbox menu. Switch to the Libraries tab and select two libraries.

  • PSoC 6 Middleware / emwin
  • Board Utils / CY8CKIT-028-TFT

The first library is the emWin library from Segger. It's a really easy-to-use and popular graphics package for embedded devices like PSoC. The second is the Cypress shield support package, which enables emWin to run on the PSoC and interface to the shield pins. The library name comes from the separately-purchasable TFT shield, which is included in the 062-WIFI-BT kit.

lib-mgr.png

Apply the changes in the manager and wait until you get the "Successfully updated the project" message. Back in the IDE, you will see the new files in the libs folder.
The emWin software is designed to run in various configurations, as follows.

  • EMWIN_NOSNTS - No multitasking and no touch support
  • EMWIN_NOSTS - No multitasking support, touch support
  • EMWIN_OSNTS - Multitasking support, no touch support
  • EMWIN_OSTS - Multitasking and touch support

We are going to start with the simplest (for us) method, which is to run with no RTOS and no touch screen. Open the Makefile and change line 69 to this.

 

COMPONENTS=EMWIN_NOSNTS

 

This will cause the build system to include the right support files for running with no RTOS and to leave out the touch support (the screen does not support it). Finally, it is time to write a little code... three whole lines of it. Include the header file for emWin.

 

#include "GUI.h"

 

Then add these two lines in main(), before the infinite loop.

 

GUI_Init();

GUI_DispString( "Hello!" );

 

Press the TFT_Play Program (KitProg3) to build download the program. The string should appear in the top left corner of the screen. That's how easy it is to write to the TFT!

So, now you have a start point for creating cool programs with the TFT. Try moving the text to another location on screen (hint: GUI_DispStringAt) and changing the fore- and background colors. Next time I shall start drawing more stuff and show you how to use the screen with an RTOS. For some light bed-time reading I have attached the Segger emWin documentation to this post. Well worth a look.

MarkS_11

ModusToolbox IDE 2.0

Posted by MarkS_11 Jan 11, 2020

In most of my previous blogs I have written about working on the command line and using the project-creator and library-manager utilities. Now I am going to introduce you to the IDE and start a sequence of articles to show off the TFT display integration.

ModusToolbox IDE is just Eclipse with a Cypress twist to make a few things easier to do. There is nothing fancy going on, just a new perspective called ModusToolbox. If you are an Eclipse master and do not like our idea if what's easy, just switch to the regular C/C++ perspective and you'll be grand.
The ModusToolbox perspective is actually intended to save you the chore of repeatedly switching between C/C++ and Debug. It merges the editing views, like Project Explorer, Outline, and Console, with the Breakpoints, Registers, Variables (and so on) debugging views into a single screen. We think it's nifty. We have also grouped some of the most common actions into a super-handy-dandy "Quick Panel" that gives you one-click access to project creation, library management, building, cleaning, configuring, programming, debugging, cooking, bathing, exercising, and calling your mom on the weekend.
In this picture you can see these options for a TFT project that I am about to walk you through.

quick-panel.png

New Application launches the same GUI that I wrote about in My Second ModusToolbox 2.0 Project. I strongly recommend using this button (or "File->New->ModusToolbox IDE Application" if you're a menu-centric guy) to create projects because this GUI ensures that your files, settings, paths, and launch configurations are all set up correctly. Again, if you know Eclipse and Make inside out (and backwards and ideally sideways) then you could just create an Eclipse C/C++ project and set all that up manually. You could also build a microwave out of chewing gum and after shave but I do not recommend that either.

 

 

 

Search Online for Code Examples just points your browser to our GitHub examples page.

 

 

 

Build and Clean, youll be shocked to learn, build and clean the project by running Make with the appropriate options.

 

 

 

Launches are shortcuts to pre-built launch configurations that program and/or Debug the kit with the application. Configurations exist for Segger J-Link the Cypress KitProg3 (which also supports MiniProg4) hardware.

 

 

 

Tools is a collection of ModusToolbox utilities like the configurators, CapSense tuner, firmware updater (updates KitProg3) and so on. I'll write about those in some detail in future blogs.

 

 

 

Documentation gather together some device and kit information along with links to the documentation for all the libraries included in your project.


OK, that's the Quick Panel. Like it? Good. Let's go make something. I want to show off the TFT display integration that my friends Misha and Oleksandr wrote. So I will use the CY8CKIT-062-WIFI-BT kit that includes a plug-in shield with a 2.4" TFT screen.
Press the New Application button in the Quick Panel and choose the kit.

new-project.png

Choose the "Empty PSoC6 App" template and give your project a name (I chose "TFT_Play").

starter.png

When you complete the wizard it pulls in all the firmware you need from GitHub and updates the libraries to make sure you are ready to go. The Quick Panel should look like the image above.

Press Build TFT_Play Application to verify that the project will compile and give you HEX and ELF files in the build/CY8CKIT-062-WIFI-BT/Debug folder. If the Console view contains this text then, be happy!

  Total Internal Flash (Available)       1048576   
  Total Internal Flash (Utilized)          21000   

  Total Internal SRAM (Available)      292864    
  Total Internal SRAM (Utilized)         279920  

09:44:19 Build Finished. 0 errors, 0 warnings. (took 59s.752ms)

Plug your kit into a USB port and press TFT_Play Program (KitProg3) to download the program. If your Console view contains this text then, be more happy!

** Program operation completed successfully **
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
Info : SWD DPIDR 0x6ba02477
Info : psoc6.cpu.cm0: external reset detected
Info : psoc6.cpu.cm4: external reset detected
shutdown command invoked

The program does not actually do anything yet. But press the TFT_Play Debug (KitProg3) button to start the debugger. You should be able to step through the BSP setup code. The debugger starts and runs the code up to the start of the main() function. Use the F5 (Step Into) and F6 (Step Over) buttons to get a feel for the debugger. Here is a picture of the debugger buttons providing, in order:

debug-buttons150.png
Resume                  Execute code
Suspend                 Pause code execution
Terminate               Close the debugger
Disconnect             (Not enabled by KitProg3)
Step Into                Step into a function call
Step Over              Step over a function call (stay in the calling function)
Step Return           Execute up one level of the stack
Drop to Frame       (Not enabled)
Use Step Filters     (Not enabled)
Restart                   Start the program from the beginning

So now you know how to create a new application inside the IDE. It is remarkably like the command-line and project-creator tools methods isn't it? That's because we're creating a framework that lets you choose the way you work, what IDE you like, what debugger you use, what editor, and so on. Tomorrow I'll write a little bit more about the project and show you how easy it is to get started with the TFT.

I am excited to announce the release of our Wi-Fi Host Driver (WHD), along with TCP/IP and TLS libraries in the PSoC 6 SDK. It's a first step toward the creation of a flexible, cloud-agnostic wireless development flow within ModusToolbox. We'll be adding plenty of new features and protocols to round out the offering over the next few releases.

 

WHD is already well-proven in the Arm Mbed and Amazon FreeRTOS ecosystems, enabling high-performance Wi-Fi support for the Cypress CYW43012 and CYW4343W devices. We have combined WHD with the popular and trusted lwIP networking stack and the industry-standard Mbed TLS implementation to create a robust and secure solution that is remarkably easy to use.

To add Wi-Fi to your project, simply add the required libraries; WHD, lwIP, wifi-mw-core and mbedTLS (optional) using the ModusToolbox Library Manager (which I have discussed in several previous posts - most notably Extending and Re-Targeting My Second ModusToolbox Project and Managing GitHub Libraries).

 

Adding the Wi-Fi Host driver, lwIP TCP/IP stack, Mbed TLS and Wi-Fi middleware core libraries to a ModusToolbox project.

 

Supporting the new libraries are some informative starter projects that you can use to evaluate and learn, then launch your next wireless product. The examples all start with the string "Connectivity" so they are easy to find in the Project Creator and they show you how to make secure (using Mbed TLS)_and non-secure client-server applications.

 

Choosing a Connectivity starter application in the ModusToolbox Project Creator

 

I am confident that you'll be able to jump start your next wireless application with these new libraries because they leverage all the ModusToolbox features I have been writing about recently. This makes it easy to quickly pull everything you need into your project, and nothing that you do not. I know I am really excited to try them out - so look out for some new blogs with some tips, tricks and fun examples.

 

Availability Notice: For about 24 hours after making this post the new examples and libraries were not accessible within ModusToolbox IDE. The New Application wizard was unable to create a Wi-Fi application. This problem is now resolved and application development is fully enabled within the IDE.

MarkS_11

Managing GitHub Libraries

Posted by MarkS_11 Dec 29, 2019

In my last blog, Using the retarget-io library to enable printf(), I assuaged some of my guilt over not bothering to explain where the pin and baud rate defines come from in Extending and Re-Targeting My Second ModusToolbox Project. Now it is time to explain the library shenanigans! Actually, there are precisely zero shenanigans involved... it is all clean and above board... but I just wanted to say "shenanigans". I think it is out of my system now.

When you add a library from the command line using git clone, as I have been doing in my last few blogs, then you get all the firmware and a .git folder, where all the GitHub information is maintained. If you are good at using git (I am not!!!) then this is all you need to be able to update the firmware to new releases and all that good stuff. If you are not a git maven (like me) or are a bit lazy (a lot like me) then Library Manager can really help you out.

When you add a library using the manager then it creates a cunning extra file with the extension .lib. This lib file records where the library came from and its version. It contains just a single line, like this example for retarget-io:

 

https://github.com/cypresssemiconductorco/retarget-io/#latest-v1.X

 

Simple huh? There really is no shenanigans here - just the GitHub address and the version (after the #).

When you run the Library Manager it reads this file to figure out what libraries are included in the project and marks them with a checkbox. In this image the manager is showing that the retarget-io library is included. Also, if you click in the Version column you will see all the available versions. If you select a different version and press Apply the manager will replace the firmware for you.

The "Latest_v1.X" version is special. It means that the manager will update to the newest available v1 implementation. If we release a new version, the manager (or "make getlibs") will update your project without any extra effort on your part. Good eh? Of course, when you are deep into a project you will probably want to lock down the version. It's easy, just use the pull-down to choose a specific version, like "1.0.0 release" in our example, and press Apply. That will get the right software and only update it if you go back and request it explicitly.

This is probably my last blog of 2019. I hope you found some of this year's content helpful! I'll be back in January with some more descriptions of cool ModusToolbox features and examples of how to leverage them to make fabulous applications. And maybe some more shenanigans!

Last week I slid in a call to cy_retarget_io_init() in my application without explaining it. I felt a bit naughty about that and so promised to explain it to you. Here goes!

The Cypress retarget-io library implements low-level character I/O functions expected by the Arm and GNU C compilers. These functions are called from the printf() and scanf() functions that come from the STDIO C-language run-time library. The actual names of the functions depend on the compiler you are using, but the library is written so that the right implementations are enabled for you automatically. Here is some code to remind you how it works (this code works on all supported compilers).

Start by adding these two header files to tell the compiler about the low-level functions and printf(), respectively.

#include "cy_retarget_io.h"

#include <stdio.h>

In the main() function you need to just initialize the UART, check it worked correctly, and start printing with wild abandon.

    result = cy_retarget_io_init( CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE );

    CY_ASSERT( result == CY_RSLT_SUCCESS );

    printf( "Program started...\r\n" );

Note that the CY_ASSERT() call just halts the application if the expression equates to false, which is probably a little simplistic in a real application but makes the point here. About the only reasons why this call would fail, though, are that you have a) passed in a pin that is not accessible from any of the PSoC SCB blocks, or b) requested a baud rate that cannot be achieved, or c) have already initialized the UART.

So, this is all fine and dandy but the arguments to cy_retarget_io_init() need a little explanation. The function just sets up the UART for the pins defined by the first two arguments - CYBSP_DEBUG_UART_TX and CYBSP_DEBUG_UART_RX. The prefix to those macros is a hint as to where they are defined - the BSP. Take a look in your project folder and jump down into the libs folder - this is where the Library Manager saves the content you select. There are folders with the prefix "TARGET", which are the kit BSPs. Looking in TARGET_CY8CKIT-062-WIFI-BT you will see a useful little file called cybsp_types.h. Here's a snippet from that file.

/** Pin: UART RX */

#define CYBSP_DEBUG_UART_RX         (P5_0)

/** Pin: UART TX */

#define CYBSP_DEBUG_UART_TX         (P5_1)

The author of the BSP has helpfully defined the pins that connect to the KitProg device. This means that, regardless of the kit you have, those macros will help you set up I/O across the KitProg bridge (to your computer). When you call cy_retarget_io_init() with those macros as the first two arguments, the library code figures out which SCB they are connected to and initializes it as a UART. If you wish to redirect the I/O then just change the arguments of the desired pins, such as P6_0 and P6_1.

The other argument in our function call is CY_RETARGET_IO_BAUDRATE, which is obviously the baud rate, but where is it defined. This is not a BSP macro. Rather, it is a retarget-io library define which helps all Cypress examples run UARTs at the same speed. Look in libs/retarget-io and you will see cy_retarget_io.h, the file that we included at the top of this blog. The following define is easy to find in that file.

/** UART baud rate */

#define CY_RETARGET_IO_BAUDRATE         (115200)

As you can see, if you want to run your UART at a different speed, just use a different number, such as 9600, like this:

    cy_retarget_io_init( P6_1, P6_0, 9600 );

Hopefully this explains what is going on with the library and explains how to make simple changes in your code to modify the printf() speed and hardware. I feel better for honoring my commitment from last week... next time I shall explain how the Library Manager works its magic!

 

In My Second ModusToolbox 2.0 Project I wrote about the project-creator tool and built a TCPWMSquareWave project for the CY8CKIT-062-WIFI-BT kit. Today I am going to add a library to the project and enable printf() through a device UART. Wooooooo! First, let's take a look at the libraries we already have (which came in with the code example project that I cloned last week).

lib-mgr-1.png

There are two TARGET_* folders, which are the kit BSPs. Then there are things like capsense and psoc6pdl. Each folder contains a library and we are going to add a new one. I do this by starting the library-manager from my shell.

 

yfs@YFS-T550 ~/TCPWMSquareWave

$ ~/ModusToolbox/tools_2.0/library-manager/library-manager.exe &

[1] 2258

yfs@YFS-T550 ~/TCPWMSquareWave

 

After a short while the tool pops up and shows the BSPs that you can use. It also lists more that you can add, if you like.

lib-mgr-2.png

Switching to the "Libraries" tab I can see the ones that are already on disk. Check the "retarget-io" box and press "Apply" to add that library.

lib-mgr-3.png

A quick look at the folders shows that the manager has added the new folder and a .lib file (more on that next time).

lib-mgr-4.png

Now that we have added the library, let's write a bit of code to try it out. Start by adding these two include files. These bring in the function definitions for the retarget-io library and also the C run-time printf() function, which is pretty much the raison d'etre of this blog.

 

#include "cy_retarget_io.h"

#include <stdio.h>

 

Note that I am using the angley bracketty thingies around stdio.h, also known as the less than and greater than signs, and probably a more mature and professional name as well. That is just because I am grabbing the header from a system rather than user path. It turns out that you can just use the regular quotes in ModusToolbox projects if you want but, if you set up your compiler paths using -J instead of -I, then angley thingies it must be!

Now we need to tell printf() where to print. Here is the code to do that - put it in main() somewhere after the call to cybsp_init() and before the PWM code. The cy_retarget_io_init() function sets up the UART that gets used when printf() has formatted the string and is sending out the characters via __write(), which is in libs/retarget-io/cy_retarget_io.c. Note that __write() is the function used by the GNU compiler printf() implementation. If you build with the Arm Compiler then the library automatically sets up fputc() instead - so you can change compilers and continue to print without torture!

 

    result = cy_retarget_io_init( CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE );

    CY_ASSERT( result == CY_RSLT_SUCCESS );

    printf( "TCPWM Square Wave started...\r\n" );

 

To check this works just run "make program" and connect up a terminal emulator.

lib-mgr-5.png

Woo hoo! Looks like I got it right. Now I am going to make another change with the library manager - switching to a new target board. I have touched on this before but switching hardware is really easy in ModusToolbox. The only essential change is to edit the "TARGET" rule in the Makefile. That works for command line builds but, as we saw in the comments for Re-Targeting My ModusToolbox 2.0 project, it does not regenerate the launch configurations for the IDE. So, to avoid confusion it is probably best to use the library-manager. There is a handy drop-down menu for that and so I have made it a habit to use that to change the BSP. Just choose the board, as shown here, then press "Apply" to safely switch the default BSP for your project.

lib-mgr-6.png

As before, all I need to do now is "make program" (and remember to connect the new board to my laptop!). It works like a charm!

Now I have to admit that I kinda glossed over two things today. Firstly, I talked about the libraries but did not explain how the manager knows where to get them and how to update them, so I'll fix that soon. I also told you about the cy_retarget_io_init() function and completely glossed over where the arguments come from! I do not like the idea of you guys blindly copying the code and not understanding it fully - that makes me feel itchy - so I'll explain that too. Honest. I promise... next time!

With any luck, my last two blogs - My First ModusToolbox Project and Re-Targeting My ModusToolbox 2.0 Project - gave you some insight into the anatomy of ModusToolbox projects. The most important learning from them was not really to get used to the git clone and make commands, rather to understand where the files in a project come from and how to manage them. That said, I have to admit, it's a lot to keep in your brain. Let's face it, we've all got more important things to dedicate memory cells to!

Let's look at some easier methods of creating projects. In your ~/ModusToolbox/tools_2.0/project-creator folder there are two executables which automate the process for you.

 

project-creator-cli.exe

As you might have guessed, this is the command-line tool. I am going to pretend to be a real engineer for a moment and advise you to start by running the command with the "--help" option to get started. Obviously, being lazy and obstinate, I did not do this, but it would have saved me some time so I'll ask you practice what I preach, not what I do! It will tell you about the --board-id, --app-id and --user-app-name options, which I'll use in a moment. But there is also the fiendishly clever --list-apps option which tells you all the GitHub-hosted projects that are compatible with a kit. Here are the options for the WIFI-BT kit.

 

$ ~/ModusToolbox/tools_2.0/project-creator/project-creator-cli.exe --list-apps CY8CKIT-062-WIFI-BT

Getting manifest...

super-manifest: https://github.com/cypresssemiconductorco/mtb-super-manifest/raw/v2.X/mtb-super-manifest.xml

Successfully acquired BSP/Application information from remote server.

List of template applications supported by the board "CY8CKIT-062-WIFI-BT":

mtb-example-psoc6-capsense-buttons-slider

mtb-example-psoc6-capsense-buttons-slider-freertos

mtb-example-psoc6-crypto-aes

mtb-example-psoc6-crypto-sha

mtb-example-psoc6-crypto-trng

mtb-example-psoc6-empty-app

mtb-example-psoc6-emulated-eeprom

mtb-example-psoc6-emwin-eink

mtb-example-psoc6-emwin-oled

mtb-example-psoc6-fault-handling

mtb-example-psoc6-gpio-interrupt

mtb-example-psoc6-hello-world

mtb-example-psoc6-i2c-master

mtb-example-psoc6-i2c-master-ezi2c-slave

mtb-example-psoc6-i2c-slave-callback

mtb-example-psoc6-i2s

mtb-example-psoc6-mcwdt

mtb-example-psoc6-pdm-pcm

mtb-example-psoc6-pdm-to-i2s

mtb-example-psoc6-qspi-readwrite

mtb-example-psoc6-qspi-readwrite-sfdp

mtb-example-psoc6-rtc-basics

mtb-example-psoc6-smartio-ramping-led

mtb-example-psoc6-spi-master

mtb-example-psoc6-spi-master-dma

mtb-example-psoc6-switching-power-modes

mtb-example-psoc6-tcpwm-square-wave

mtb-example-psoc6-uart-transmit-receive

mtb-example-psoc6-uart-transmit-receive-dma

mtb-example-psoc6-usb-hid

mtb-example-psoc6-wdt

 

Nice! This is a convenient way to see the examples without trawling around https://github.com/cypresssemiconductorco. I am going to try the tcpwm-square-wave example. I shall call my project "square-wave" and put it into the folder called "square" using those options we saw in the help output. Here goes...

 

$ ~/ModusToolbox/tools_2.0/project-creator/project-creator-cli.exe --board-id CY8CKIT-062-WIFI-BT --app-id mtb-example-psoc6-tcpwm-square-wave --user-app-name square_wave

Getting manifest...

super-manifest: https://github.com/cypresssemiconductorco/mtb-super-manifest/raw/v2.X/mtb-super-manifest.xml

Successfully acquired BSP/Application information from remote server.

 

 

==============================================================================

= Cloning 'mtb-example-psoc6-tcpwm-square-wave' =

==============================================================================

Cloning https://github.com/cypresssemiconductorco/mtb-example-psoc6-tcpwm-square-wave into C:/Users/yfs directory...

Cloning into 'square_wave'...

remote: Enumerating objects: 13, done.

remote: Counting objects: 100% (13/13), done.

remote: Compressing objects: 100% (10/10), done.

remote: Total 13 (delta 0), reused 10 (delta 0), pack-reused 0

Unpacking objects: 100% (13/13), done.

 

 

Cheking out latest-v1.X...

Note: checking out 'latest-v1.X'.

 

 

You are in 'detached HEAD' state. You can look around, make experimental

changes and commit them, and you can discard any commits you make in this

state without impacting any branches by performing another checkout.

 

 

If you want to create a new branch to retain commits you create, you may

do so (now or later) by using -b with the checkout command again. Example:

 

 

  git checkout -b <new-branch-name>

 

 

HEAD is now at 17f92ae Upload mtb-example-psoc6-tcpwm-square-wave 1.0.0.55

 

 

==============================================================================

= Creating 'TARGET_CY8CKIT-062-WIFI-BT.lib' file(s) =

==============================================================================

 

 

==============================================================================

= Updating Makefile for 'square_wave' =

==============================================================================

Tools Directory: C:/Users/yfs/ModusToolbox/tools_2.0

 

 

Initializing import: mtb-example-psoc6-tcpwm-square-wave

 

 

==============================================================================

= Importing libraries =

==============================================================================

Git is git version 2.17.0, found at /usr/bin/git

 

 

Searching application directories...

Application directories search complete.

 

 

Searching libs directory...

Found 2 file(s)

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W.lib

Libraries were processed. Re-evaluating libs directory...

Found 14 file(s)

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/capsense.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/core-lib.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6cm0p.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6hal.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6make.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6pdl.lib

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/capsense.lib

        Library "capsense.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/capsense.lib.

        Skipping current reference...

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/core-lib.lib

        Library "core-lib.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/core-lib.lib.

        Skipping current reference...

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6cm0p.lib

        Library "psoc6cm0p.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6cm0p.lib.

        Skipping current reference...

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6hal.lib

        Library "psoc6hal.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6hal.lib.

        Skipping current reference...

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6make.lib

        Library "psoc6make.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6make.lib.

        Skipping current reference...

    Processing file C:/Users/yfs/square_wave/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6pdl.lib

        Library "psoc6pdl.lib" was already processed at C:/Users/yfs/square_wave/libs/TARGET_CY8CKIT-062-WIFI-BT/libs/psoc6pdl.lib.

        Skipping current reference...

Libraries were processed. Re-evaluating libs directory...

Found 14 file(s)

libs directory search complete.

 

 

==============================================================================

= Import complete =

==============================================================================

 

 

Successfully created "square_wave" application.

 

In one command I have created a new project, added a BSP, set it as the default for build and program, and pulled in all firmware libraries needed to build the application. Just plugging in the kit and running "make program" is all it takes to build and program the board.

 

project-creator.exe

 

If the above is still too much typing then run the non-CLI executable - ~/ModusToolbox/tools_2.0/project-creator/project-creator.exe. You can start it from Windows Explorer or launch from the command line with "~/ModusToolbox/tools_2.0/project-creator/project-creator.exe &". Note that I do it in the background with the ampersand at the end of the line, so I can still use the shell.

 

The GUI tool (why is it not spelled "gooey"?) starts by grabbing a bunch of information from the mtb-super-manifest.xml file on GitHub (I'll write more about this file, and creating your own manifests, in a future blog).

project-creator-1.png

Just press "Next>" to get to the good stuff.

project-creator-2.png

Now pick your kit.

project-creator-3.png

Choose the application and give it a name and a sensible location.

project-creator-4.png

You then get a summary of what you ordered. Press "Create" and let the tool assemble all the parts. You'll recognize all the GitHub and make output in the dialog. Once it is all done you just "make program" in the shell to get the application onto the kit (you may want to edit main.c to change the value of PWM_FREQUENCY to make sure your new program is actually running rather than the old one!).

 

Next time, I shall show you how to add BSPs and firmware libraries to a project using another helpful tool, the library-manager.

Last time out we got hello world running on the PROTO-062-4343W kit. That was a lot of fun for me… because I have that kit! Actually, I have about 20 of them because they arrived too late for the training event last week. But most of you don’t have 20 kits so, today, I am going to show you how to re-target an application to another kit.

 

All ModusToolbox applications have a BSP. It is the thing that defines the PSoC device, the memory layout, the connection to the Wi-Fi device over SDIO, the CapSense buttons and sliders, the I2C and UART peripherals, and the mechanical buttons and LEDs. We give these things standard names, like CYBSP_USER_LED, so that applications using those names can run on just about any kit even if the physical pins connected to the LED are different. So, to re-target our application we only have to do two things; add a new BSP to the project and tell the build tools to use it instead of the original BSP. Some examples actually include more than one BSP, for convenience, so you can often skip the first step!

 

I’ve been writing about CY8CPROTO-063-BLE kit recently (github.com/cypresssemiconductorco/TARGET_CY8CPROTO-063-BLE) so let’s switch our program to that one. You can read about the BSP on the GitHub site or you can just get on with it and download the thing (as you can tell, I’m a type-first, read-later guy). Just jump into the libs folder and clone the BSP.

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ cd libs

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world/libs

$ git clone https://github.com/cypresssemiconductorco/TARGET_CY8CPROTO-063-BLE

Cloning into 'TARGET_CY8CPROTO-063-BLE'...

remote: Enumerating objects: 156, done.

remote: Counting objects: 100% (156/156), done.

remote: Compressing objects: 100% (106/106), done.

Receiving objectsremote: Total 156 (delta 43), reused 153 (delta 43), pack-reused 0:   % (85/

Receiving objects: 100% (156/156), 391.77 KiB | 1.42 MiB/s, done.

Resolving deltas: 100% (43/43), done.

Checking out files: 100% (135/135), done.

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world/libs

$ ls -la

total 34

drwxr-xr-x 1 yfs 1049089  0 Nov 4 09:24 .

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:24 ..

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:12 capsense

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:12 core-lib

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:12 psoc6cm0p

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:13 psoc6hal

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:13 psoc6make

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:14 psoc6pdl

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:12 retarget-io

-rw-r--r-- 1 yfs 1049089 67 Nov  1 15:40 retarget-io.lib

drwxr-xr-x 1 yfs 1049089  0 Nov 1 16:12 TARGET_CY8CPROTO-062-4343W

-rw-r--r-- 1 yfs 1049089 82 Nov  1 15:40 TARGET_CY8CPROTO-062-4343W.lib

drwxr-xr-x 1 yfs 1049089  0 Nov 4 09:24 TARGET_CY8CPROTO-063-BLE

 

As you can see, you have added a new TARGET folder. Great, now let’s build for it. I can almost feel you gearing up for a stream of edit-this and move-that with a little bit of delete-the-other and a frustrating time. Not exactly, just add the name of the target to the build command.

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world/libs

$ cd ..

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ make build TARGET=CY8CPROTO-063-BLE

Tools Directory: C:/Users/yfs/ModusToolbox/tools_2.0

 

Initializing build: mtb-example-psoc6-hello-world Debug CY8CPROTO-063-BLE GCC_ARM

    Stale device files detected. Running device configurator to regenerate files...

 

Auto-discovery in progress...

-> Found 158 .c file(s)

-> Found 36 .S file(s)

-> Found 18 .s file(s)

-> Found 0 .cpp file(s)

-> Found 0 .o file(s)

-> Found 4 .a file(s)

-> Found 377 .h file(s)

-> Found 0 .hpp file(s)

-> Found 0 resource file(s)

Applying filters...

Auto-discovery complete

 

==============================================================================

= Building application =

==============================================================================

Building 142 file(s)

    Compiling app file startup_psoc6_01_cm4.S

    Compiling app file cy_syslib_gcc.S

    Compiling app file cycfg.c

    Compiling app file cycfg_clocks.c

    Compiling app file cycfg_peripherals.c

    Compiling app file cycfg_pins.c

    Compiling app file cycfg_routing.c

    Compiling app file cycfg_system.c

    Compiling app file cybsp.c

    Compiling app file system_psoc6_cm4.c

    Compiling app file cy_capsense_centroid.c

    Compiling app file cy_capsense_control.c

    Compiling app file cy_capsense_csd.c

    Compiling app file cy_capsense_csx.c

    Compiling app file cy_capsense_filter.c

    Compiling app file cy_capsense_processing.c

    Compiling app file cy_capsense_sensing.c

    Compiling app file cy_capsense_structure.c

    Compiling app file cy_capsense_tuner.c

    Compiling app file psoc6_01_cm0p_sleep.c

    Compiling app file psoc6_02_cm0p_sleep.c

    Compiling app file psoc6_03_cm0p_sleep.c

    Compiling app file cyhal_adc.c

    Compiling app file cyhal_analog_common.c

    Compiling app file cyhal_crc.c

    Compiling app file cyhal_crypto_common.c

    Compiling app file cyhal_dac.c

    Compiling app file cyhal_flash.c

    Compiling app file cyhal_gpio.c

    Compiling app file cyhal_hwmgr.c

    Compiling app file cyhal_i2c.c

    Compiling app file cyhal_interconnect.c

    Compiling app file cyhal_lptimer.c

    Compiling app file cyhal_not_implemented.c

    Compiling app file cyhal_pwm.c

    Compiling app file cyhal_qspi.c

    Compiling app file cyhal_rtc.c

    Compiling app file cyhal_scb_common.c

    Compiling app file cyhal_sdhc.c

    Compiling app file cyhal_spi.c

    Compiling app file cyhal_system.c

    Compiling app file cyhal_tcpwm_common.c

    Compiling app file cyhal_timer.c

    Compiling app file cyhal_trng.c

    Compiling app file cyhal_uart.c

    Compiling app file cyhal_udb_sdio.c

    Compiling app file cyhal_usb_dev.c

    Compiling app file cyhal_utils.c

    Compiling app file cyhal_wdt.c

    Compiling app file cyhal_psoc6_01_104_m_csp_ble.c

    Compiling app file cyhal_psoc6_01_104_m_csp_ble_usb.c

    Compiling app file cyhal_psoc6_01_116_bga_ble.c

    Compiling app file cyhal_psoc6_01_116_bga_usb.c

    Compiling app file cyhal_psoc6_01_124_bga.c

    Compiling app file cyhal_psoc6_01_124_bga_sip.c

    Compiling app file cyhal_psoc6_01_43_smt.c

    Compiling app file cyhal_psoc6_01_68_qfn_ble.c

    Compiling app file cyhal_psoc6_01_80_wlcsp.c

    Compiling app file cyhal_psoc6_02_100_wlcsp.c

    Compiling app file cyhal_psoc6_02_124_bga.c

    Compiling app file cyhal_psoc6_02_128_tqfp.c

    Compiling app file cyhal_psoc6_02_68_qfn.c

    Compiling app file cyhal_psoc6_03_100_tqfp.c

    Compiling app file cyhal_psoc6_03_49_wlcsp.c

    Compiling app file cyhal_psoc6_03_68_qfn.c

    Compiling app file cy_ble_clk.c

    Compiling app file cy_canfd.c

    Compiling app file cy_crypto.c

    Compiling app file cy_crypto_core_aes_v1.c

    Compiling app file cy_crypto_core_aes_v2.c

    Compiling app file cy_crypto_core_cmac_v1.c

    Compiling app file cy_crypto_core_cmac_v2.c

    Compiling app file cy_crypto_core_crc_v1.c

    Compiling app file cy_crypto_core_crc_v2.c

    Compiling app file cy_crypto_core_des_v1.c

    Compiling app file cy_crypto_core_des_v2.c

    Compiling app file cy_crypto_core_ecc_domain_params.c

    Compiling app file cy_crypto_core_ecc_ecdsa.c

    Compiling app file cy_crypto_core_ecc_key_gen.c

    Compiling app file cy_crypto_core_ecc_nist_p.c

    Compiling app file cy_crypto_core_hmac_v1.c

    Compiling app file cy_crypto_core_hmac_v2.c

    Compiling app file cy_crypto_core_hw.c

    Compiling app file cy_crypto_core_hw_v1.c

    Compiling app file cy_crypto_core_mem_v1.c

    Compiling app file cy_crypto_core_mem_v2.c

    Compiling app file cy_crypto_core_prng_v1.c

    Compiling app file cy_crypto_core_prng_v2.c

    Compiling app file cy_crypto_core_rsa.c

    Compiling app file cy_crypto_core_sha_v1.c

    Compiling app file cy_crypto_core_sha_v2.c

    Compiling app file cy_crypto_core_trng_v1.c

    Compiling app file cy_crypto_core_trng_v2.c

    Compiling app file cy_crypto_core_vu.c

    Compiling app file cy_crypto_server.c

    Compiling app file cy_csd.c

    Compiling app file cy_ctb.c

    Compiling app file cy_ctdac.c

    Compiling app file cy_device.c

    Compiling app file cy_dma.c

    Compiling app file cy_dmac.c

    Compiling app file cy_efuse.c

    Compiling app file cy_flash.c

    Compiling app file cy_gpio.c

    Compiling app file cy_i2s.c

    Compiling app file cy_ipc_drv.c

    Compiling app file cy_ipc_pipe.c

    Compiling app file cy_ipc_sema.c

    Compiling app file cy_lpcomp.c

    Compiling app file cy_lvd.c

    Compiling app file cy_mcwdt.c

    Compiling app file cy_pdm_pcm.c

    Compiling app file cy_profile.c

    Compiling app file cy_prot.c

    Compiling app file cy_rtc.c

    Compiling app file cy_sar.c

    Compiling app file cy_scb_common.c

    Compiling app file cy_scb_ezi2c.c

    Compiling app file cy_scb_i2c.c

    Compiling app file cy_scb_spi.c

    Compiling app file cy_scb_uart.c

    Compiling app file cy_sd_host.c

    Compiling app file cy_seglcd.c

    Compiling app file cy_smartio.c

    Compiling app file cy_smif.c

    Compiling app file cy_smif_memslot.c

    Compiling app file cy_sysanalog.c

    Compiling app file cy_sysclk.c

    Compiling app file cy_sysint.c

    Compiling app file cy_syslib.c

    Compiling app file cy_syspm.c

    Compiling app file cy_systick.c

    Compiling app file cy_tcpwm_counter.c

    Compiling app file cy_tcpwm_pwm.c

    Compiling app file cy_tcpwm_quaddec.c

    Compiling app file cy_trigmux.c

    Compiling app file cy_usbfs_dev_drv.c

    Compiling app file cy_usbfs_dev_drv_io.c

    Compiling app file cy_usbfs_dev_drv_io_dma.c

    Compiling app file cy_wdt.c

    Compiling app file cy_retarget_io.c

    Compiling app file main.c

    Linking output file mtb-example-psoc6-hello-world.elf

==============================================================================

= Build complete =

==============================================================================

 

Calculating memory consumption: CYBLE-416045-02 GCC_ARM -Og

 

   --------------------------------------------------

  | Section Name         |  Address |  Size     |

--------------------------------------------------

  | .cy_m0p_image        |  0x10000000 |  5328     |

  | .text                |  0x10002000 |  36180    |

  | .ARM.exidx           |  0x1000ad54 |  8        |

  | .copy.table          |  0x1000ad5c |  24       |

  | .zero.table          |  0x1000ad74 |  8        |

  | .data                |  0x0800228c |  1892     |

  | .cy_sharedmem        |  0x080029f0 |  12       |

  | .noinit              |  0x08002a00 |  148      |

  | .bss                 |  0x08002a94 |  976      |

  | .heap                |  0x08002e68 |  276888   |

--------------------------------------------------

 

  Total Internal Flash (Available) 1048576

  Total Internal Flash (Utilized)           46324

 

  Total Internal SRAM (Available) 292864

  Total Internal SRAM (Utilized) 279916

 

Now you can just run ”make qprogram” and hello world will run just the same way as it did on the original kit. That was cool, let’s do it again!

 

When you type as haphazardly as I do, that extra text at the end of the command is just asking for a typo. So I need a more permanent solution. It’s easy to do… just open the Makefile in a text editor, look for the line “TARGET=CY8CPROTO-062-4343W” and change the name of the board to CY8CPROTO-063-BLE, like this.

 

################################################################################

# Basic Configuration

################################################################################

 

# Target board/hardware

# TARGET=CY8CPROTO-062-4343W

TARGET=CY8CPROTO-063-BLE

 

Now you can build and program your kit in one step with the almost-impossible-to-mistype command “make program”. You’ll never guess how to go back to the other kit!

OK, that’s enough typing for me. Next time I’ll show off the new GUI tools we have created to automate all this make shenanigans.

Well, I did not get a visit from any of the VPs I was being rude about yesterday, so I can start showing you some of the ways to do cool projects with ModusToolbox. I usually dive straight into the IDE for things like this but I have lots of options with ModusToolbox so I will start with a simple command-line example instead. This will demonstrate the four fundamental steps involved in making a program.

  1. Clone a starter project from GitHub
  2. Pull down all the required libraries - startup code, board support, CapSense and so on
  3. Build
  4. Program

If you have installed ModusToolbox 2.0 already, then you can follow all these steps (only step 4 requires a kit). If you have not installed ModusToolbox… what the heck are you waiting for???

ModusToolbox includes a convenient "modus-shell", which is just a cygwin DLL with the path set up for the make and compiler executables. I start that by running cygwin.bat from the ModusToolbox\tools_2.0\modus-shell folder. That launches the shell in your home directory.

Clone a Project

All the ModusToolbox firmware is distributed as libraries in the cypresssemiconductorco repo on GitHub (yes, there are three consecutive 's' in there!). To get started you just have to clone an example from that site. As is traditional, I picked "hello world", and it takes just a few seconds to download.

yfs@YFS-T550 ~

$ mkdir MyFirstProject

 

yfs@YFS-T550 ~

$ cd MyFirstProject

 

yfs@YFS-T550 ~/MyFirstProject

$ git clone https://github.com/cypresssemiconductorco/mtb-example-psoc6-hello-world

Cloning into 'mtb-example-psoc6-hello-world'...

remote: Enumerating objects: 15, done.

remote: Counting objects: 100% (15/15), done.

remote: Compressing objects: 100% (13/13), done.

remote: Total 15 (delta 0), reused 12 (delta 0), pack-reused 0

Unpacking objects: 100% (15/15), done.

 

yfs@YFS-T550 ~/MyFirstProject

$ cd mtb-example-psoc6-hello-world

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ ls -la

total 64

drwxr-xr-x 1 yfs 1049089     0 Nov 1 15:40 .

drwxr-xr-x 1 yfs 1049089     0 Nov 1 15:40 ..

drwxr-xr-x 1 yfs 1049089     0 Nov 1 15:40 .git

drwxr-xr-x 1 yfs 1049089     0 Nov 1 15:40 images

drwxr-xr-x 1 yfs 1049089     0 Nov 1 15:40 libs

-rw-r--r-- 1 yfs 1049089 12443 Nov  1 15:40 LICENSE

-rw-r--r-- 1 yfs 1049089 10161 Nov  1 15:40 main.c

-rw-r--r-- 1 yfs 1049089  5207 Nov 1 15:40 Makefile

-rw-r--r-- 1 yfs 1049089 17480 Nov  1 15:40 README.md

 

What do you get? Well, there’s main.c and a Makefile, which is pretty much the whole application for “hello world”! Then there is README.md, which is a markdown file that tells you all about the application. You can read that file as plain text or open it in a markdown viewer. When you do that the document is nicely formatted and includes the pictures in the “images” folder. Then is also a LICENSE file, of course, and a “.git” folder, which contains all the clever stuff to support updating and pushing and pulling and cloning and tickling and tweaking and, oh you know, all that git stuff.

Pull in Libraries

The most interesting folder, though, is “libs”. Take a peak in there and you’ll see two files with the extension “.lib” (in this example). These files contain a hash of the GitHub repos and branch for all the extra firmware needed by the application. We use a make rule “getlibs” to pull in those libraries.

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ ls -la libs

total 6

drwxr-xr-x 1 yfs 1049089 0 Nov  1 15:40 .

drwxr-xr-x 1 yfs 1049089 0 Nov  1 15:40 ..

-rw-r--r-- 1 yfs 1049089 67 Nov 1 15:40 retarget-io.lib

-rw-r--r-- 1 yfs 1049089 82 Nov 1 15:40 TARGET_CY8CPROTO-062-4343W.lib

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ make getlibs

Tools Directory: C:/Users/yfs/ModusToolbox/tools_2.0

 

Initializing import: mtb-example-psoc6-hello-world

 

==============================================================================

= Importing libraries =

==============================================================================

Git is git version 2.17.0, found at /usr/bin/git

 

Searching application directories...

Application directories search complete.

 

Searching libs directory...

Found 2 file(s)

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/retarget-io.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W.lib

Libraries were processed. Re-evaluating libs directory...

Found 8 file(s)

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/capsense.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/core-lib.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6cm0p.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6hal.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6make.lib

    Processing file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/libs/TARGET_CY8CPROTO-062-4343W/libs/psoc6pdl.lib

Libraries were processed. Re-evaluating libs directory...

Found 8 file(s)

libs directory search complete.

 

==============================================================================

= Import complete =

==============================================================================

 

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ ls -la libs

total 46

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:13 .

drwxr-xr-x 1 yfs 1049089 0 Nov  1 15:40 ..

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:12 capsense

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:12 core-lib

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:12 psoc6cm0p

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:13 psoc6hal

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:13 psoc6make

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:14 psoc6pdl

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:12 retarget-io

-rw-r--r-- 1 yfs 1049089 67 Nov 1 15:40 retarget-io.lib

drwxr-xr-x 1 yfs 1049089 0 Nov  1 16:12 TARGET_CY8CPROTO-062-4343W

-rw-r--r-- 1 yfs 1049089 82 Nov 1 15:40 TARGET_CY8CPROTO-062-4343W.lib

 

When you look at the libs folder now you have all the Board and Chip support firmware in TARGET_CY8CPROTO-062-4343W and the retarget-io library to enable STDIO output to printf(). Note that the TARGET library, which is known as the BSP, automatically pulls in other libraries that it depends up; core-lib, psoc6hal, psoc6pdl and so on.

Build

So now we have used make to complete the application. The cool part is that we can also use make to update the library versions, or add more, or remove one that you no longer want. The next step is to see if it works… it’s really complicated. Not really, just type “make build”.

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ make build

Tools Directory: C:/Users/yfs/ModusToolbox/tools_2.0

 

Initializing build: mtb-example-psoc6-hello-world Debug CY8CPROTO-062-4343W GCC_ARM

 

Auto-discovery in progress...

-> Found 150 .c file(s)

-> Found 34 .S file(s)

-> Found 16 .s file(s)

-> Found 0 .cpp file(s)

-> Found 0 .o file(s)

-> Found 4 .a file(s)

-> Found 367 .h file(s)

-> Found 0 .hpp file(s)

-> Found 0 resource file(s)

Applying filters...

Auto-discovery complete

 

==============================================================================

= Building application =

==============================================================================

Building 144 file(s)

    Compiling app file startup_psoc6_02_cm4.S

    Compiling app file cy_syslib_gcc.S

    Compiling app file cycfg.c

    Compiling app file cycfg_capsense.c

    Compiling app file cycfg_clocks.c

    Compiling app file cycfg_peripherals.c

    Compiling app file cycfg_pins.c

    Compiling app file cycfg_qspi_memslot.c

    Compiling app file cycfg_routing.c

    Compiling app file cycfg_system.c

    Compiling app file cybsp.c

    Compiling app file system_psoc6_cm4.c

    Compiling app file cy_capsense_centroid.c

    Compiling app file cy_capsense_control.c

    Compiling app file cy_capsense_csd.c

    Compiling app file cy_capsense_csx.c

    Compiling app file cy_capsense_filter.c

    Compiling app file cy_capsense_processing.c

    Compiling app file cy_capsense_sensing.c

    Compiling app file cy_capsense_structure.c

    Compiling app file cy_capsense_tuner.c

    Compiling app file psoc6_01_cm0p_sleep.c

    Compiling app file psoc6_02_cm0p_sleep.c

    Compiling app file psoc6_03_cm0p_sleep.c

    Compiling app file cyhal_adc.c

    Compiling app file cyhal_analog_common.c

    Compiling app file cyhal_crc.c

    Compiling app file cyhal_crypto_common.c

    Compiling app file cyhal_dac.c

    Compiling app file cyhal_flash.c

    Compiling app file cyhal_gpio.c

    Compiling app file cyhal_hwmgr.c

    Compiling app file cyhal_i2c.c

    Compiling app file cyhal_interconnect.c

    Compiling app file cyhal_lptimer.c

    Compiling app file cyhal_not_implemented.c

    Compiling app file cyhal_pwm.c

    Compiling app file cyhal_qspi.c

    Compiling app file cyhal_rtc.c

    Compiling app file cyhal_scb_common.c

    Compiling app file cyhal_sdhc.c

    Compiling app file cyhal_spi.c

    Compiling app file cyhal_system.c

    Compiling app file cyhal_tcpwm_common.c

    Compiling app file cyhal_timer.c

    Compiling app file cyhal_trng.c

    Compiling app file cyhal_uart.c

    Compiling app file cyhal_udb_sdio.c

    Compiling app file cyhal_usb_dev.c

    Compiling app file cyhal_utils.c

    Compiling app file cyhal_wdt.c

    Compiling app file cyhal_psoc6_01_104_m_csp_ble.c

    Compiling app file cyhal_psoc6_01_104_m_csp_ble_usb.c

    Compiling app file cyhal_psoc6_01_116_bga_ble.c

    Compiling app file cyhal_psoc6_01_116_bga_usb.c

    Compiling app file cyhal_psoc6_01_124_bga.c

    Compiling app file cyhal_psoc6_01_124_bga_sip.c

    Compiling app file cyhal_psoc6_01_43_smt.c

    Compiling app file cyhal_psoc6_01_68_qfn_ble.c

    Compiling app file cyhal_psoc6_01_80_wlcsp.c

    Compiling app file cyhal_psoc6_02_100_wlcsp.c

    Compiling app file cyhal_psoc6_02_124_bga.c

    Compiling app file cyhal_psoc6_02_128_tqfp.c

    Compiling app file cyhal_psoc6_02_68_qfn.c

    Compiling app file cyhal_psoc6_03_100_tqfp.c

    Compiling app file cyhal_psoc6_03_49_wlcsp.c

    Compiling app file cyhal_psoc6_03_68_qfn.c

    Compiling app file cy_ble_clk.c

    Compiling app file cy_canfd.c

    Compiling app file cy_crypto.c

    Compiling app file cy_crypto_core_aes_v1.c

    Compiling app file cy_crypto_core_aes_v2.c

    Compiling app file cy_crypto_core_cmac_v1.c

    Compiling app file cy_crypto_core_cmac_v2.c

    Compiling app file cy_crypto_core_crc_v1.c

    Compiling app file cy_crypto_core_crc_v2.c

    Compiling app file cy_crypto_core_des_v1.c

    Compiling app file cy_crypto_core_des_v2.c

    Compiling app file cy_crypto_core_ecc_domain_params.c

    Compiling app file cy_crypto_core_ecc_ecdsa.c

    Compiling app file cy_crypto_core_ecc_key_gen.c

    Compiling app file cy_crypto_core_ecc_nist_p.c

    Compiling app file cy_crypto_core_hmac_v1.c

    Compiling app file cy_crypto_core_hmac_v2.c

    Compiling app file cy_crypto_core_hw.c

    Compiling app file cy_crypto_core_hw_v1.c

    Compiling app file cy_crypto_core_mem_v1.c

    Compiling app file cy_crypto_core_mem_v2.c

    Compiling app file cy_crypto_core_prng_v1.c

    Compiling app file cy_crypto_core_prng_v2.c

    Compiling app file cy_crypto_core_rsa.c

    Compiling app file cy_crypto_core_sha_v1.c

    Compiling app file cy_crypto_core_sha_v2.c

    Compiling app file cy_crypto_core_trng_v1.c

    Compiling app file cy_crypto_core_trng_v2.c

    Compiling app file cy_crypto_core_vu.c

    Compiling app file cy_crypto_server.c

    Compiling app file cy_csd.c

    Compiling app file cy_ctb.c

    Compiling app file cy_ctdac.c

    Compiling app file cy_device.c

    Compiling app file cy_dma.c

    Compiling app file cy_dmac.c

    Compiling app file cy_efuse.c

    Compiling app file cy_flash.c

    Compiling app file cy_gpio.c

    Compiling app file cy_i2s.c

    Compiling app file cy_ipc_drv.c

    Compiling app file cy_ipc_pipe.c

    Compiling app file cy_ipc_sema.c

    Compiling app file cy_lpcomp.c

    Compiling app file cy_lvd.c

    Compiling app file cy_mcwdt.c

    Compiling app file cy_pdm_pcm.c

    Compiling app file cy_profile.c

    Compiling app file cy_prot.c

    Compiling app file cy_rtc.c

    Compiling app file cy_sar.c

    Compiling app file cy_scb_common.c

    Compiling app file cy_scb_ezi2c.c

    Compiling app file cy_scb_i2c.c

    Compiling app file cy_scb_spi.c

    Compiling app file cy_scb_uart.c

    Compiling app file cy_sd_host.c

    Compiling app file cy_seglcd.c

    Compiling app file cy_smartio.c

    Compiling app file cy_smif.c

    Compiling app file cy_smif_memslot.c

    Compiling app file cy_sysanalog.c

    Compiling app file cy_sysclk.c

    Compiling app file cy_sysint.c

    Compiling app file cy_syslib.c

    Compiling app file cy_syspm.c

    Compiling app file cy_systick.c

    Compiling app file cy_tcpwm_counter.c

    Compiling app file cy_tcpwm_pwm.c

    Compiling app file cy_tcpwm_quaddec.c

    Compiling app file cy_trigmux.c

    Compiling app file cy_usbfs_dev_drv.c

    Compiling app file cy_usbfs_dev_drv_io.c

    Compiling app file cy_usbfs_dev_drv_io_dma.c

    Compiling app file cy_wdt.c

    Compiling app file cy_retarget_io.c

    Compiling app file main.c

    Linking output file mtb-example-psoc6-hello-world.elf

==============================================================================

= Build complete =

==============================================================================

 

Calculating memory consumption: CY8C624ABZI-D44 GCC_ARM -Og

 

--------------------------------------------------

  | Section Name         |  Address |  Size     |

--------------------------------------------------

  | .cy_m0p_image        |  0x10000000 |  5068     |

  | .text                |  0x10002000 |  37276    |

  | .ARM.exidx           |  0x1000b19c |  8        |

  | .copy.table          |  0x1000b1a4 |  24       |

  | .zero.table          |  0x1000b1bc |  8        |

  | .data                |  0x080022e0 |  1888     |

  | .cy_sharedmem        | 0x08002a40   |  8 |

  | .noinit              |  0x08002a48 |  148      |

  | .bss                 |  0x08002adc |  996      |

  | .heap                |  0x08002ec0 |  1030464  |

--------------------------------------------------

 

  Total Internal Flash (Available) 2097152

  Total Internal Flash (Utilized)           47412

 

  Total Internal SRAM (Available) 1046528

  Total Internal SRAM (Utilized) 1033504

 

Program

The last step is obviously to program the kit. Plug a CY8CPROTO-062-4343W kit into the USB port and give your computer a few moments to install the drivers for it. Then open a serial terminal like PuTTY or TeraTerm and set them up for the “KitProg3 USB-UART COMxx” port in the Windows Device Manager. The baud rate is 115200.

If you do not have that kit… don’t worry, next time I’ll show you how easy it is to switch applications onto different kits.

To program the kit just type “make program”. This will check that the build is up to date (and build again if necessary) and then download the program using the CMSIS-DAP protocol to the board. If you are super impatient, like me, then you can use “make qprogram” instead and that is quicker (hence the ‘q’) because it skips the build check.

yfs@YFS-T550 ~/MyFirstProject/mtb-example-psoc6-hello-world

$ make program

Tools Directory: C:/Users/yfs/ModusToolbox/tools_2.0

 

Initializing build: mtb-example-psoc6-hello-world Debug CY8CPROTO-062-4343W GCC_ARM

 

Auto-discovery in progress...

-> Found 150 .c file(s)

-> Found 34 .S file(s)

-> Found 16 .s file(s)

-> Found 0 .cpp file(s)

-> Found 0 .o file(s)

-> Found 4 .a file(s)

-> Found 367 .h file(s)

-> Found 0 .hpp file(s)

-> Found 0 resource file(s)

Applying filters...

Auto-discovery complete

 

==============================================================================

= Building application =

==============================================================================

Building 144 file(s)

==============================================================================

= Build complete =

==============================================================================

 

Calculating memory consumption: CY8C624ABZI-D44 GCC_ARM -Og

 

--------------------------------------------------

  | Section Name         |  Address |  Size     |

   --------------------------------------------------

  | .cy_m0p_image        |  0x10000000 |  5068     |

  | .text                |  0x10002000 |  37276    |

  | .ARM.exidx           |  0x1000b19c |  8        |

  | .copy.table          |  0x1000b1a4 |  24       |

  | .zero.table          |  0x1000b1bc |  8        |

  | .data                |  0x080022e0 |  1888     |

  | .cy_sharedmem        |  0x08002a40 |  8        |

  | .noinit              |  0x08002a48 |  148      |

  | .bss                 |  0x08002adc |  996      |

  | .heap                |  0x08002ec0 |  1030464  |

--------------------------------------------------

 

  Total Internal Flash (Available) 2097152

  Total Internal Flash (Utilized)           47412

 

  Total Internal SRAM (Available) 1046528

  Total Internal SRAM (Utilized) 1033504

 

Programming target device...

Open On-Chip Debugger 0.10.0+dev-2.2.0.249 (2019-09-10-10:57)

Licensed under GNU GPL v2

For bug reports, read

http://openocd.org/doc/doxygen/bugs.html

adapter speed: 1500 kHz

adapter speed: 1000 kHz

** Auto-acquire enabled, use "set ENABLE_ACQUIRE 0" to disable

cortex_m reset_config sysresetreq

cortex_m reset_config vectreset

Info : Using CMSIS loader 'CY8C6xxA_SMIF' for bank 'psoc6_smif0_cm0' (footprint 6105 bytes)

Warn : SFlash programming allowed for regions: USER, TOC, KEY

Info : CMSIS-DAP: SWD  Supported

Info : CMSIS-DAP: FW Version = 2.0.0

Info : CMSIS-DAP: Interface Initialised (SWD)

Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1

Info : CMSIS-DAP: Interface ready

Info : VTarget = 3.332 V

Info : kitprog3: acquiring PSoC device...

Info : clock speed 1000 kHz

Info : SWD DPIDR 0x6ba02477

Info : psoc6.cpu.cm0: hardware has 4 breakpoints, 2 watchpoints

Info : psoc6.cpu.cm0: external reset detected

***************************************

** Silicon: 0xE402, Family: 0x102, Rev.: 0x11 (A0)

** Detected Device: CY8C624ABZI-S2D44A0

** Detected Main Flash size, kb: 2048

** Flash Boot version 3.1.0.45

** Chip Protection: NORMAL

***************************************

Info : psoc6.cpu.cm4: hardware has 6 breakpoints, 4 watchpoints

Info : psoc6.cpu.cm4: external reset detected

Info : Listening on port 3333 for gdb connections

Info : Listening on port 3334 for gdb connections

Warn : Only resetting the Cortex-M core, use a reset-init event handler to reset any peripherals or configure hardware srst support.

Info : kitprog3: acquiring PSoC device...

target halted due to debug-request, current mode: Thread

xPSR: 0x41000000 pc: 0x00000190 msp: 0x080ff800

** Device acquired successfully

** psoc6.cpu.cm4: Ran after reset and before halt...

target halted due to debug-request, current mode: Thread

xPSR: 0x01000000 pc: 0x0000012a msp: 0x080ff800

** Programming Started **

auto erase enabled

Info : Flash write discontinued at 0x100013cc, next section at 0x10002000

Info : Padding image section 0 at 0x100013cc with 52 bytes (bank write end alignment)

[100%] [################################] [ Erasing     ]

[100%] [################################] [ Programming ]

Info : Padding image section 1 at 0x1000b92c with 212 bytes (bank write end alignment)

[100%] [################################] [ Erasing     ]

[100%] [################################] [ Programming ]

wrote 44544 bytes from file C:/Users/yfs/MyFirstProject/mtb-example-psoc6-hello-world/build/CY8CPROTO-062-4343W/Debug/mtb-example-psoc6-hello-world.hex in 5.370537s (8.100 KiB/s)

** Programming Finished **

** Verify Started **

verified 44280 bytes in 0.267027s (161.939 KiB/s)

** Verified OK **

** Resetting Target **

Warn : Only resetting the Cortex-M core, use a reset-init event handler to reset any peripherals or configure hardware srst support.

shutdown command invoked

 

You should see the red LED blinking at about 1Hz. That’s just way too slow for me and it drives me nuts - I always open main.c in an editor and speed that up! In the terminal emulator you should see this. You can turn the LED blinking on and off by pressing the Enter key.

My First ModusToolbox 2_0 Design PuTTY.png

 

Congratulations! If you followed along then you just created, built, and programmed your first ModusToolbox application.

Oh my stars, it has been a week since we released ModusToolbox 2.0! I thought I'd be getting some down time after the release but, as usual, things did not really go that way. Instead of taking a break we decided to give all the San Jose vice presidents a crash course in all things ModusToolbox. This was a group of sales guys, marketeers, and business unit managers, with not a single engineer among them... what could possibly go wrong?

Alan Hawse (who else!) was hosting the day but he missed his plane from Kentucky. We had no course materials. The kits we wanted to use for lab sessions arrived two days late. And, worst of all, we found that all VPs share one common skill - the ability to mess up software installations. It was a hectic day but, by the end of it all, these guys...

ModusToolbox training SJ.jpeg

... got our motley collection of non-programmers writing programs using every customer development flow that we could think of...

  • Mbed CLI
  • Mbed Online Compiler
  • Mbed Studio
  • ModusToolbox IDE
  • Visual Studio Code
  • And from the command-line

And we were not just building blinky. When you get a group of VPs at your mercy... it would be wrong not to torture them with a little C and C++ programming ("I wrote Pascal in college and waaa waaa waaa"). So we had them writing to TFT displays, connecting to Wi-Fi networks, polling NTP servers, and pulling all that together to create a PSoC-based alarm clock. In one day.

I think this is a testament to the design goal of ModusToolbox. We wanted to create a set of tools and libraries that are so flexible and interchangeable that we can support bare metal or RTOS-based applications; running in our own ecosystems or partner platforms like Mbed and Amazon FreeRTOS; using our IDE, a partner IDE, or no IDE at all; and building with the compiler of your choice. I think we crushed that objective, so 'Chapeau' to all the 226 engineers that have worked on the project!

Another good thing to come from that crazy day was that I now have a good set of starter projects and use cases that I can blog about and get everyone excited and up to speed with the new tools. Watch this space...

 

 

 

 

 

 

 

 

 

 

 

Over the weekend we released a major upgrade to ModusToolbox. The 2.0 software improves the development experience for PSoC 6 and Bluetooth SoC applications as well as being available in the Mbed OS and Amazon FreeRTOS ecosystems.

 

A big addition to all flows is the Cypress HAL (Hardware Abstraction Layer), which is a device-agnostic driver API. It simplifies the code you write for simple peripheral operation and, best of all, allows us to build middleware libraries that can be used in any flow you choose... from deeply embedded industrial control all the way across to wireless IoT applications. With a standardized HAL, all Cypress middleware - the good stuff like CapSense, MagSense and Bluetooth - will work the same way, and just as reliably, on all of our devices and in all your ecosystems. Our middleware roadmap for 2020 is really exciting!

 

ModusToolbox 2.0 also completes our commitment to distributing firmware through the web. ALL firmware libraries, including examples, are hosted on github so we can push out updates as soon as they are ready. It also means you can have a good old-fashioned rummage around the source code without downloading gigabytes of development tools.

 

Oh yeah! That reminds me... our firmware is now completely IDE-agnostic so you can use whatever tools you like. We obsessively test our firmware on the Arm, IAR and GNU compiler tool chains and our build recipes require no proprietary format conversion or mysterious merge utilities.

 

Interested? Of course you are! Now get over here and do some downloading.

Here's another interesting post from Matt Mielke, over at Digi-Key. It's actually two posts and, together, they describe how to set up the PSoC 6 PDM-PCM converter in the ModusToolbox Device Configurator.

The first article takes you through the PDM-PCM configuration process. I like how it breaks everything down into logical steps. It's well worth a read. Go on! Off you go. I'll still be here when you get back.

Oh, you're back already. I thought it was particularly interesting how Matt identifies, and provides a workaround, for an error in the Device Configurator. The PDM-PCM conversion requires a fast, accurate clock source and that comes from the PSoC External Crystal Oscillator (ECO). In ModusToolbox 1.1 the ECO frequency range is erroneously limited to between 4MHz and 33MHz. The error check exists to prevent users from inadvertently trying to generate frequencies that the ECO block cannot handle. Unfortunately, we got the upper limit wrong - it is too conservative. Matt's workaround is great but I wanted to let everyone know that we have already fixed the problem in our upcoming 2.0 release, which sets the upper limit at 35MHz.

Here is a pic of the configurator tool from the 1.1 release, showing the erroneous error check. You won't get that problem in our 2.0 software. Happy sampling!

Setting the ECO input frequency in ModusToolbox Device Configurator

It is time to take the final step in our week-long BLE adverture. Hopefully you have a working peripheral already. You should be able to send messages from your phone and have it send messages to you. OK, it's just a find me application and battery monitor right now, but those two things tell you a lot of what you need to know to make bigger, more interesting peripherals. Our last task is to make sure your device only talks to the right people. That process is called pairing and we shall control that with a passkey.

We shall start this job in familiar territory - the BLE Configurator. Switch the view to the GAP Settings and look at "Security configuration 0". Note that more complex peripherals can implement multiple configurations but we are only making one.

Change the Security level to "Authenticated pairing with encryption". The authentication means that the pairing requires a passkey. The IO Capability should be "Display" which means the peripheral has a way for presenting a passkey to the user. In our case that is the terminal and we will write a little code to print the key. Some peripherals do not have a display and so the authentication process has to done differently - for example, the passkey can be sent to, and displayed on, the phone instead and the a simple button can be used to accept the number on the peripheral. The last edit is for Binding, which should be set to "No Bond". In real-world applications you alnmost always bond, to the point that pairing and bonding are often considered to be synonyms. Strictly, bonding is just the storage of pairing information in non-volatile memory which enables bonded phones and devices to automatically recognize each other and connect without a passkey. We are not going to bond because it's a lot easy to learn about piring without the need to force your phone and peripheral to forget each other all the time. Let's get good at pairing first!

Setting up security in the ModusToolbox BLE Configurator

Saving the configurator edits, we need to add four events to our stack_handler() function.

  • CY_BLE_EVT_GAP_AUTH_REQ occurs when the phone asks to initiate pairing. The peripheral responds by sending back the authentication method(s) that it can support (in our case this means "display").
  • CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST means the central wants the peripheral to display the passkey. The phone asks the user to enter the value (6-digit code with leading zeros).
  • CY_BLE_EVT_GAP_AUTH_COMPLETE means that the phone has sent the user's passkey and it matched the displayed value.
  • CY_BLE_EVT_GAP_AUTH_FAILED means the value entered was wrong, or the user waited too long, or some other reason for not allowing pairing.

Here is the code to handle those events. Just add it into the switch statement in stack_handler().

/* Include stdio.h at the top of main.c */

#include "stdio.h"

...

char passkey_str[50]; /* Put the string declaration at the top of stack_handler() */

...

case CY_BLE_EVT_GAP_AUTH_REQ:
    Cy_SCB_UART_PutString( KIT_UART_HW, "Authenticating\r\n" );
    /* Send the authentication settings set by the BLE Configurator - GAP Settings */
    Cy_BLE_GAPP_AuthReqReply( &cy_ble_config.authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX] );
break;

case CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
    sprintf( passkey_str, "Passkey requested\tKey = %06ld\r\n", ( (cy_stc_ble_gap_auth_pk_info_t*)eventParam )->passkey );
    Cy_SCB_UART_PutString( KIT_UART_HW, passkey_str );
break;

case CY_BLE_EVT_GAP_AUTH_COMPLETE:
    Cy_SCB_UART_PutString( KIT_UART_HW, "Authentication complete\r\n" );
break;

case CY_BLE_EVT_GAP_AUTH_FAILED:
    Cy_SCB_UART_PutString( KIT_UART_HW, "Authentication fail\r\n" );
break;

As you can see, there is not a lot to it. The stack does the hard part of communicating with the phone and deciding whether to pair. The call to Cy_BLE_GAPP_AuthReqReply() takes an argument that is in the generated code from the BLE Configurator. The variable cy_ble_config is a big struct containing all the user selections from that tool. The authInfo member contains the information we just provided in an array of one element (CY_BLE_SECURITY_CONFIGURATION_0_INDEX is the only element in that array because we only have one configuration). So, sending that information up to the phone is all that is required to tell it to pop up a passkey request dialog.

CySmart prompting for a passkey

Of course, we have to print the passkey to give the user a chance to guess right! That happens in the CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST event. The stack generates a random number and passes it into the event handler in the eventParam argument.

When you build and program the application, you should connect to it as normal. When you try to open the Battery service the CySmart app should automatically pop up the passkey request, as above. Note that the Android version of the app does this as soon as you connect but the iPhone version waits for you to do something that requires the peripheral to respond. On the iPhone, then, you can send an Immediate Alert before pairing and, while the phone says it was sent (it was) the peripheral ignores the message (and the LED does not light). Everything is working correctly in both cases, because you need to have completed pairing before either service will be honored by the peripheral.

Here is the terminal output for a session where I got the password wrong. There is no code to enable a re-try so you need to disconnect and reconnect on order to try again. When I got it right I could send and receive messages with the usual wild abandon! When you play with this, remember to include any leading zeros when entering the passkey - you must enter all 6 digits.

PSoC BLE Peripheral output

So that's the full set of BLE exercises. I hope you followed along and had some fun with it. We have a large array of examples of how to take this further and I have attached a template for you to recreate exactly what I have done here. To use the template download and unzip it, then open the New Application dialog, select the prototyping kit, then use the "Import..." button to open the modus.mk file in the BLE_proj folder.

Happy Blootoothing!!!