5.1 Creating a Bootloader Client for PIC® Devices

This section demonstrates how to configure a bootloader for 8-bit PIC devices using UART, SPI, or I2C for communication.

Note: When adding a bootloader to an existing application, make sure to select a device that has sufficient memory to hold both the bootloader and the application.

Description: This section details a basic bootloader use case on the PIC18F57Q43 microcontroller, which applies to many variants of the PIC18F family and can also be extrapolated to other 8-bit PIC MCUs. This example uses the PIC18F57Q43 Curiosity Nano board for demonstration. Refer to the board schematics for configuration information.

  1. Create a new MPLAB X IDE project.

    Figure 5-1. New Project
    Note: If “Simulator” is the only option displayed in the Tools combo box while selecting the device, then the target board is not plugged into the computer or it is not communicating with MPLAB X IDE properly.
  2. MCC opens up automatically when a new project is created. If not, click the MCC button in the menu bar to start the MPLAB Code Configurator.

    Figure 5-2. Open MCC
  3. Click Next on MCC Melody in the MCC Content Type Wizard window.

    Figure 5-3. Select MCC Melody
  4. Click Finish in the Content Download Required window and wait for all the required content to be downloaded.

    Figure 5-4. Content Download
  5. Open the MCC Content Manager from the Device Resources tab and make sure the latest version of 8-Bit MDFU Client is selected under Libraries>Bootloader.
    Figure 5-5. MCC Content Manager
  6. Add the 8-Bit MDFU Client library into the Project Resources tab from Device Resources. In previous versions of MCC, a user needed to manually attach all peripheral drivers required by their library, using the Device Resources tab. The new MCC Melody allows users to select the required library from the Device Resources, and Melody can bring in all the dependencies.

    Figure 5-6. Device Resources
  7. Confirm that the 8-Bit MDFU Client library has been included into the Builder window. The Builder UI reflects all the required peripheral driver dependencies such as the Non-Volatile Memory (NVM) and Timer Delay modules and links them to the 8-Bit MDFU Client library.

    Figure 5-7. 8-Bit MDFU Client
  8. One of the modules that cannot be configured automatically is the communication peripheral. All of the communication protocols that are supported by the 8-Bit MDFU Client are shown below. Navigate to the section for the communication peripheral that you would like to use:

    1. UART
    2. SPI
    3. I2C

    UART:

    For UART communication, this example will configure the UART peripheral to route data through the CDC ports of the on-board debugger. This is the simplest UART configuration that we can create using the Curiosity Nano platform.

    Select UART from the Communication Protocol drop-down list in the 8-Bit MDFU Client Easy View tab.

    Figure 5-8. UART Communication Protocol

    For the bootloader to communicate with the host application (PyMDFU) over UART, a driver instance needs to be configured to exchange data through the serial ports on the target device. To understand which communication ports are required to be opened for the device in use, check the schematics and look for the Serial or CDC Ports definition for the Curiosity Nano board, as shown in the image below. Using this definition, the MCU is communicating through the RF0 pin for transmitting data serially and the RF1 pin for receiving data serially.

    Figure 5-9. Serial/CDC Port

    A communication driver version that communicates through the RF0 and RF1 pins is needed. For the PIC18F57Q43 Curiosity Nano, attach the UART1 driver since that is the UART driver that can communicate through those pins. Select UART1 from the “UART PLIB Selector” in the SERCOM(None) tab. The UART1 PLIB settings will open up.

    Figure 5-10. UART PLIB Selector
    Figure 5-11. UART1 Settings
    Note: Some devices will automatically select the required UART pins. Open the Pin Grid View tab to make sure the pins are configured correctly.

    SPI:

    For SPI communication, this example will utilize the MCP2210 Breakout Module to send SPI signals through a USB port. This breakout module is one of the ways we can allow PyMDFU to send SPI signals through a USB port.

    Select SPI from the Communication Protocol drop-down list in the 8-Bit MDFU Client Easy View tab.

    Figure 5-12. SPI Communication Protocol

    Select an instance of the SPI driver from the SPI Client PLIB Selector drop-down list. For example, SPI1 and the driver settings will open up.

    Figure 5-13. SPI Client PLIB Selector
    Figure 5-14. SERCOM Settings

    Make sure the correct SDI (MOSI), SDO (MISO), SS and SCK pins are selected and rename the SS pin to CHIP_SELECT.

    Figure 5-15. SPI Settings

    I2C:

    For I2C communication, this example will utilize a USB-I2C bridge, like the MCP2221A or an Aardvark Total Phase I2C/SPI Host to send I2C signals through a USB port. This method allows PyMDFU to send I2C signals through a USB port.

    Select I2C from the Communication Protocol drop-down list in the 8-Bit MDFU Client Easy View tab.

    Figure 5-16. I2C Communication Protocol

    Select an instance of the I2C driver from the I2C Client PLIB Selector drop-down list. For example, I2C1 and the driver settings will open up. Set the Client Address and Client Mask appropriately.

    Note: If the device only has one I2C module, then the PLIB will be added automatically.
    Figure 5-17. SERCOM Settings

    Make sure the correct SCL, and SDA pins.

    Important: It is strongly suggested to use interrupts for I2C communication. Follow the steps provided in the Supporting Interrupts for PIC® Devices section to finish setting up interrupts in the ecosystem.
    Figure 5-18. I2C Settings
  9. In the System/Clock Control module, configure the oscillator and clock divider. In general, a faster clock is better for more reliable communication. For this PIC18F57Q43 example, 64 MHz internal oscillator is selected and the Clock Divider set to 1.
    Figure 5-19. Clock Control Settings
  10. In the System/Configuration Bits module, set the External Oscillator Selection to “Oscillator not enabled”.
    Tip: Matching the clock settings and oscillator configuration bits settings in the bootloader client and the end application can help to create similar behavior when testing the application alone and when ran through a bootloader.
    Figure 5-20. Configuration Bits Settings
    Attention: This example does not utilize the code protection features of the device hardware. Follow the information presented in the device data sheet to understand how to configure your bootloader to use the code protection features of the hardware, if that is desired.
  11. There are several advantages to configuring I/O pins in a bootloader, but the most important one is the ability to receive an operating state back from the MCU based on an LED status. In this bootloader module, the LED will be illuminated when in a Boot state, and it will turn off when the application state takes control of the MCU. This helps to track the program flow during the development process and helps to identify the Active state of the device.

    Another helpful feature we can configure using the I/O pins is a hardware entry mechanism. In many development scenarios, users will want to be able to switch from the running application back to the Boot mode in order to load a new application. Providing a push button that can give a signal to the MCU that a bootload is being requested by the user is a very helpful feature for testing the ecosystem. In this bootloader module, the Entry pin can force entry into the Boot mode when an expected voltage level is observed on the pin at the time of a device reset.

    Configure the bootloader module to utilize both of the I/O options. Click the switches on the Easy View to activate the I/O Pins features.

    Figure 5-21. I/O Pins

    Check the schematics to configure the I/O pins for using the LED and switch on the board. Find the I/O interface declaration, which is similar to the image below. For the PIC18F57Q43, make sure the RF3 port is connected to control the LED and RB4 is connected to control the switch.

    Figure 5-22. On-Board Peripherals

    Go back to MPLAB X IDE and navigate to the Pin Grid View tab in the bottom center of the screen. Then select the RF3 and RB4 pins for BOOT INDICATE and BOOT ENTRY in the grid, respectively. Open the Project Resources> System>Pins to view the specific GPIO pin settings.

    Note: The output pin is assumed to start in an Off state and the starting voltage level of the pin must be configured to follow the required activation level of the pin. For example, most Curiosity Nano devices have an Active-Low setting for the LED pins. Since in this scenario the LED pin will read a low voltage when enabled, it will start in the Off state, meaning the voltage will start high and the bootloader will set that pin low once it starts running.
    Note: The input pin must be configured to use a Pull-up if the pin is Active-Low to help stabilize the signal during a power cycle or other reset.
    Figure 5-23.  Pin Grid View
  12. Device ID is automatically populated for the device used in the current project.
    Figure 5-24. Device Information
  13. Before generating the initial code, address the warnings in the Notifications [MCC] tab. For example, NVM options must be enabled.

    Figure 5-25.  Notification [MCC] Tab

    For example, enable Generate Device ID APIs for the NVM driver. Addressing the notification will either turn it into a hint or remove it from the list.

    Figure 5-26. Clear NVM Notification
  14. For the notification “Application Start Address cannot be set to 0x0”, set the memory offset/Application start address to the program memory size. The actual value of the application start address can be calculated after compiling the project for the first time.

    Note: Initially, set the Application Start Address to the last Flash address. This value will be scaled to the correct address after compilation.
    Figure 5-27. Application Start Address
  15. For this example, the verification scheme is set to Checksum.
    Figure 5-28. Verification Scheme
  16. Now, with the basic configurations complete, click the Generate button in the Project Resources tab to generate the project code.

    Figure 5-29. Generate Project Code
  17. The bl_example.c file provides routines for running a basic bootloader update process. The main.c file will be automatically updated to call the BL_ExampleInitialize() and BL_Example(). If not, open the main.c file, and add the code shown below.
    Figure 5-30. Bootloader Update Process Call
  18. Click the “Clean and Build” icon drop-down option and select Clean and Build Main Project to compile the bootloader code.

    Figure 5-31. Clean and Build Main Project
  19. The compilation log can be used to determine the compilation size of the program. The Program Space shows how large the bootloader code compiles to. The Application Start Address can be set accordingly. The address that you choose must not span across a page boundary.
    Tip: Running applications in Debug mode requires more space than a normal production build. If you want to be able to run the bootloader in Debug mode, you will need to save some extra space in the bootloader partition for the debug data.
    Figure 5-32.  Program Memory Consumption
    Note: For PIC16 device, these address values are the word addresses.
    Figure 5-33. Updated Application Start Address
  20. Before generating the code again and programming the device, the linker settings from the 8-Bit MDFU Client Easy View must be copied into their respective boxes. Right click the project in the Projects tab and open the project properties. Go to XC8 Global Option>XC8 Linker>Memory Model>ROM ranges and paste the copied value.
    Figure 5-34. 8-Bit MDFU Client - ROM Range
    Figure 5-35. Compiler - Linker Settings
  21. Click the Generate button in the Project Resources tab to generate the updated project code and compile the project again with the updated Application Start Address.
    Figure 5-36. Compile Project
  22. To prepare the chip to bootload, click the Make and Program Device button. After this programming process ends, the LED on the PIC18F57Q43 Curiosity Nano board will remain ON.

    Figure 5-37. Make and Program Device Main Project
Figure 5-38. Bootloader is running and waiting for communication
Note: The below example is from a UART hardware setup.