MPLAB Harmony

Creating a custom board support package (BSP) for Harmony 2.04

This week, I wanted to dive into something a bit technical since it is consuming a good deal of my time and I figure it might help save some of you a few headaches.  I’m developing a new embedded project using a 32bit Microchip MCU (PIC32MZ1024EF) and I’ve committed to building the entire thing using Harmony.  Specifically, the new version of Harmony (2.04 at the time of this writing.)  So far, it’s actually been quite pleasant and has saved a TON of development time.  In exchange, there is a bit of a learning curve and a few bugs / documentation issues to contend with.

One of them involves building Board Support Packages, or BSP’s.  Your typical development board from Microchip comes with a bunch of examples that can be built using Harmony by simply selecting the correct BSP.  I decided that it would be very helpful if I could create my own BSP for a custom board.  The thinking was, I could then create a bunch of projects to test individual parts of that board.  For example, let’s say I just wanted to build an isolated project (think ‘unit test’ here) that only exercised the UART and SPI Flash.  Ideally, I could just choose my BSP and enable those features.  I wouldn’t have to think about pin assignments, oscillator settings, UART settings, etc.

Unfortunately, the documentation for this process seems to have slipped through the cracks and doesn’t reflect the methodology currently used in Harmony.

The document “help_harmony_vol_III.pdf” provides some clues on page 78 “Adding new BSP’s”… but the process they suggest does not seem to mirror the process used for the Microchip BSP’s.  So I dug into it a bit and here are the basic steps:

Add your board to the hconfig file corresponding to your processor

I’m using a PIC32MZ EF, which corresponds to the Microchip datasheet designator DS60001320.

Navigate to your Harmony installation, and then look in /bsp/config and you’ll find a file called DS60001320.hconfig.  This contains board support options specific to the PIC32MZ.

In here, you can add the Harmony option for your custom BSP by creating an addition config block with the choice block.  (Analogous to a case statement inside a switch in C).

config BSP_AWESOME_BOARD
	depends on USE_BSP
	select BSP_TRIGGER
	bool "My Awesome Board"

Now, when you’re in Harmony and you click “Use BSP” , your custom BSP will show up in the menu.  Easy!

Create the file structure for your BSP

Next, we need to create our actual support package with all the info specific to our board.  The easiest way is to just copy an existing one and modify.  I chose to copy /bsp/pic32mz_ef_sk and rename it to my custom name, my_awesome_board.

Inside of the DS60001320.hconfig file, you’ll find a bunch of “SOURCE” commands.  Each of these includes the files for a specific BSP.  Add your newly created BSP to that list by adding your own SOURCE line, like this:

source "$HARMONY_VERSION_PATH/bsp/my_awesome_board/config/bsp.hconfig"

Start customizing your BSP

Inside of your custom bsp.hconfig file, you can setup some of the basic options like USB->UART, switches, LED’s, etc. that are typically found on dev boards.  It is important to note that the XML files that used to be used for setting up pins are no longer functional in Harmony 2.0 or later.  At least, when I make them, nothing happens.  Seems like this functionality was abandoned since it gets specified in the bsp.hconfig anyway.

For example:

ifblock BSP_AWESOME_BOARD
	menu "Select BSP Features"
	depends on USE_BSP
	depends on BSP_AWESOME_BOARD
	config BSP_USART_BRIDGE_AWESOME_BOARD
		bool "Use USART to USB Bridge"
		depends on USE_BSP
		depends on BSP_AWESOME_BOARD
		default y if BSP_USART_BRIDGE_NEEDED
		default n
		set BSP_PIN_67_FUNCTION_TYPE to "U2TX" if BSP_USART_BRIDGE_AWESOME_BOARD
		set BSP_PIN_67_FUNCTION_NAME to "USART to USB Bridge (BSP)" if BSP_USART_BRIDGE_AWESOME_BOARD		
		set BSP_PIN_66_FUNCTION_TYPE to "U2RX" if BSP_USART_BRIDGE_AWESOME_BOARD
		set BSP_PIN_66_FUNCTION_NAME to "USART to USB Bridge (BSP)" if BSP_USART_BRIDGE_AWESOME_BOARD

	config BSP_USART_ID_AWESOME_BOARD
		int "USART Driver Instance Index"
		depends on USE_BSP
		depends on BSP_AWESOME_BOARD
		depends on BSP_USART_BRIDGE_AWESOME_BOARD
		range 0 0 if DRV_USART_INSTANCES_NUMBER = 1
		range 0 1 if DRV_USART_INSTANCES_NUMBER = 2
		range 0 2 if DRV_USART_INSTANCES_NUMBER = 3
		range 0 3 if DRV_USART_INSTANCES_NUMBER = 4
		range 0 4 if DRV_USART_INSTANCES_NUMBER = 5
		range 0 5 if DRV_USART_INSTANCES_NUMBER = 6
		range 0 6 if DRV_USART_INSTANCES_NUMBER = 7
		range 0 7 if DRV_USART_INSTANCES_NUMBER = 8
		range 0 8 if DRV_USART_INSTANCES_NUMBER = 9
		default 0

	set DRV_USART_PERIPHERAL_ID_IDX0 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 0 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX1 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 1 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX2 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 2 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX3 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 3 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX4 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 4 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX5 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 5 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX6 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 6 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX7 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 7 & BSP_USART_BRIDGE_AWESOME_BOARD)
	set DRV_USART_PERIPHERAL_ID_IDX8 optionally to "USART_ID_2" if (BSP_USART_ID_AWESOME_BOARD = 8 & BSP_USART_BRIDGE_AWESOME_BOARD)
	endmenu

endif

Finally, at the end of your custom bsp.hconfig, you’ll want to include anything specific to your board like header files, macros, compiler directives, etc.

file BSP_AWESOME_BOARD_H "$HARMONY_VERSION_PATH/bsp/my_awesome_board/bsp_config.h" to "$PROJECT_HEADER_FILES/bsp/my_awesome_board/bsp_config.h"
file BSP_AWESOME_BOARD_C "$HARMONY_VERSION_PATH/bsp/my_awesome_board/bsp_sys_init.c" to "$PROJECT_SOURCE_FILES/bsp/my_awesome_board/bsp_sys_init.c"
compiler BSP_COMPILER_INCLUDE_BSP_AWESOME_BOARD includepath "$HARMONY_VERSION_PATH/bsp/my_awesome_board"

In the next post, we’ll talk more about customizing pins and adding menu options for different functions!