I recently got volunteered to take some internal engineers through the process of creating a Bluetooth LE peripheral using ModusToolbox. I figured I should share the learning with you because it's been a while since I wrote about making PSoC do interesting things. Who knows, maybe I'll make another robot dog one day? Preferably one that does not run away or spin around like it's got rabies, and that I can control without getting off the couch. Priorities...

The goal was to empower our engineers to be able to make their own BLE designs and I hope it can do the same for you. Each step adds a little more understanding; from advertising and making connections, to sending alert messages from the phone, to receiving battery notifications from the device, and setting up rudimentary security (so engineers can't misbehave in class!!!). This is a hands-on, get up-and-running quick exercise, folks, and it's going to be up to you to take the next steps once I have covered the basics!

I decided to use a CY8CPROTO-063-PROTO kit because it is small and inexpensive, but any kit with a PSoC 63 MCU device would work without much modification (just use different pins). For example, there is the CY8CKIT-062-BLE, which is an Arduino form-factor alternative to the prototyping kit. Note, however, that the other "062" kits, such as CY8CKIT-062-WiFi-BT, use a PSoC 62 MCU, which does not have BLE on-chip. Those kits couple the PSoC MCU to a 43xxx connectivity device, which is supported by a different API.

On my kit, I used the two LEDs, the user button, and a UART to write across the KitProg3 bridge to my PC terminal emulator (TeraTerm or PuTTY). Knowing that I would create many projects during the development of this material I wanted to build a template so I would not have to keep re-creating the same setup. To do that I began with the "EmptyPSoC6App" project template, targeting the CY8CPROTO kit.

Repeating the configuration steps from previous blogs (Starter Templates for ModusToolbox and Customizing your PSoC configuration (buttons and LEDs)) I opened the Device Configurator and made the following edits.

  1. Enabled pin P6[3] with the alias "KIT_LED1" and drive mode "Strong Drive, Input buffer off".
  2. Repeated that task for P7[1] and called it "KIT_LED2".
  3. Enabled pin P0[4] to support the user button, calling it "KIT_BTN1", set to "Resistive Pull-Up, Input buffer on", and with an interrupt triggered of a "Falling Edge".
  4. Finally, I enabled SCB[5] to use the UART-1.0 personality, called it "KIT_UART", with a baud rate of 115200.

For the UART connections I chose "8-bit divider 0" and let the tool figure out the divider value to get the baud rate right (handy!). Lastly I chose P5[0] and P5[1] for the RX and TX pins.

Configuring the PSoC UART for 115200 baud, with P5[0] and P5[1] as RX and TX

The tool gave me a couple of "fix-it tickets" at this step - asking me to set the drive modes for those pins. Another handy feature of the Configurator is that it will make those changes for you by clicking on the wrench (aka "spanner") icons in the Notice List.

Fix-it tickets for the UART configuration - just click on the wrench to set up the drive modes for the UART pins

Once I had everything set up I saved it, switched back to the IDE, and wrote a little code to test things out. In main() I turned on the UART, installed the button ISR, and set one LED on and the other off.

int main(void)
  /* Set up the device based on configurator selections */

  /* Turn on the UART */
  Cy_SCB_UART_Init( KIT_UART_HW, &KIT_UART_config, &KIT_UART_context );
  Cy_SCB_UART_Enable( KIT_UART_HW );
  Cy_SCB_UART_PutString( KIT_UART_HW, "\r\n\n*** Application Started ***\r\n" );

  /* Turn on the button interrupt */
  const cy_stc_sysint_t button_intr_config = { KIT_BTN1_IRQ, ISR_PRIORITY_LOW };
  Cy_SysInt_Init( &button_intr_config, button_isr );
  NVIC_EnableIRQ(  button_intr_config.intrSrc );

  /* Turn one LED on and one off */




Then I added an ISR to do some fairly simple stuff when I press the button.

void button_isr( void )
  /* Clear the interrupt */
  Cy_GPIO_ClearInterrupt( KIT_BTN1_PORT, KIT_BTN1_PIN );
  NVIC_ClearPendingIRQ( KIT_BTN1_IRQ );

  /* Toggle both the LEDs */

  /* Print a friendly message */
  Cy_SCB_UART_PutString( KIT_UART_HW, "Button pressed\r\n" );

When I programmed the kit it behaved perfectly (after 15 bone-headed iterations that I'll not discuss!) - pressing the button swaps the LEDs and prints the nice message. I have a good start point for adding BLE!

Now I want to turn this project into a template. I created a new folder and copied across three files - design.modus, modus.mk, and main.c (in the Source folder). I edited modus.mk to make it more friendly as a template with these settings:


CY_EXAMPLE_DESCRIPTION = Useful start point for BLE designs on the CY8CPROTO-063-BLE kit.



Finally, I trimmed back the main.c file to remove some of the test code from above. I did not want to have to delete it every time! Specifically, I removed the LED toggling and UART printing code from the ISR as well as the LED set/clr calls in main().

With this template, that I have attached to this blog (remember that you need to log in to get it), I am ready to dive into BLE development. Before then, here are instructions on creating projects with the template.

Unpack the attached files into your workspace folder (or anywhere convenient).

1. Click on New Application from the Quick Panel

Creating a new project in ModusToolbox IDE

2. Select CY8CPROTO-063-BLE as the target kit and press Next.

Selecting the target kit in ModusToolbox IDE

3. Click on Import.. then navigate to the template folder and choose modus.mk.

4. Check that the dialog updates with the template information and press Next.

Selecting a custom project template in ModusToolbox

5. Verify the selections in the final view and press Finish to create the project.

In my next blog I'll start our BLE adventure by launching the stack and advertising to my phone!