3 Getting Started PIC32CM MCU With VS Code and MCC

The following software and hardware tools are used for this demonstration:

  • VS Code
  • VS Code Plugins:
    1. MPLAB
    2. Toolchain Support for MPLAB
    3. Code Configurator (MCC) for Microchip devices
  • MPLAB Harmony v3 repository: csp v3.25 or newer
  • PIC32CM Curiosity Nano Evaluation Kit
Note: The latest versions of these tools can also be used to develop the application.

Creating the First Application on the PIC32CM MCU

For new projects, it is recommended to use the MPLAB Tools for VS Code. If not already installed, VS Code can be downloaded from the official Visual Studio Code website and installed following the standard setup procedure. Once installed, the MPLAB Tools for VS Code can be downloaded from the official MPLAB Tools website or directly from the VS Code Marketplace. Both resources offer a complete list of MPLAB extensions, which can be installed individually or collectively as part of the MPLAB Extensions Pack. Installation is performed through the VS Code Extensions interface. Additionally, tutorials are available on the official website, including links to the Extensions Developer Help and the MPLAB Tools for VS Code video playlist. Refer to the Tools and Software section for instructions on installing the basic VS Code setup.

To create a VS Code-based project, follow these steps:

  1. On the Start menu, launch VS Code.
  2. On the left navigation bar, click the MPLAB plugin.
    Figure 3-1. MPLAB Plugin Selection
  3. Under the Project tab window, click the New Project option to create a new MPLAB project.
    Figure 3-2. New Project Window
  4. Enter the project title in the search window and press Enter.
    Figure 3-3. Creating New Project
  5. Select the location where the new project will be created. Here, the default location is selected. Press Enter to proceed.
    Figure 3-4. Selection of New Project Location
  6. Select the PIC32CM6408PL10048 device and press Enter.
    Figure 3-5. Device Selection
  7. Select the latest compiler version (XC32 (5.00)) and press Enter.
    Figure 3-6. Compiler Selection
  8. Type >MPLAB MCC: Launch in the search window.
    Figure 3-7. Launch MCC
  9. Select the Create New MCC Config option.
    Figure 3-8. Select New MCC Config
  10. Link the MPLAB project created with MCC.
    Figure 3-9. Associate MCC Config to MPLAB Project
  11. Configure the MCC configuration and select the Proceed With Default Values option.
    Figure 3-10. Configure MCC Config
  12. Before launching MCC, the Configuration Database Setup window will be displayed, where the Device Family Pack (DFP) and Common Microcontroller Software Interface Standard (CMSIS) path can be changed if required. For this demonstration, the default settings are used.
  13. The MCC plugin will open in a new window as shown in the following figure.
    Figure 3-11. MPLAB Code Configurator Window

Adding and Configuring the MPLAB Harmony Component

To add and configure MPLAB Harmony components using MCC, follow these steps:

  1. In the MCC window, click Project Graph.
    Figure 3-12. MPLAB Code Configurator
  2. In the Plugins drop-down list, select Clock Configuration. The Clock Easy View window will be displayed, verify that the Main Clock is set to 24 MHz.
    Note: Ensure that the following modification is made for GCLK Generator 0.
    Figure 3-13. MPLAB Code Configurator - GCLK Generator 0
  3. Under Device Resources, expand the list of options: Harmony>Peripherals>SERCOM.
  4. Click SERCOM and observe that the SERCOM1 Peripheral Library block is added to the Project Graph window.
    Figure 3-14. MPLAB Code Configurator - Selection of Peripheral
    Note: Users can also select other peripherals under Device Resources: Harmony>Peripherals.
  5. In the Project Graph window, on the left navigation bar, select the SERCOM1 Peripheral Library. In the Configuration Options property page on the right, configure it as follows to print the data on the Serial Console at a baud rate of 115,200.
    Figure 3-15. MPLAB Code Configurator – SERCOM1 Configuration
  6. Under Device Resources, expand the list of options: Harmony>Peripherals>EIC. Click EIC and observe that the EIC Peripheral Library block is added in the Project Graph window.
  7. In the Project Graph window, on the left navigation bar, select the EIC Peripheral Library. In the Configuration Options property page on the right, select the Enable Interrupt checkbox and the Enable EIC Channel3 checkbox for the switch press event.
    Figure 3-16. MPLAB Code Configurator – EIC Configuration
  8. Under Device Resources, expand the list of options: Harmony>Peripherals>RTC. Click RTC and observe that the RTC Peripheral Library block is added to the Project Graph window to generate a compare interrupt every 500 ms. Select the Clear on compare Match checkbox.
    Note: The compare value is set as 0x200. This value generates an RTC compare interrupt every 500 ms.

    RTC Clock = 1024 Hz

    RTC Prescaler = 1

    Required Interrupt rate = 500 ms

    Therefore, the compare value = (500/1000) x 1024 = 512 (i.e., 0x200).

    Figure 3-17. MPLAB Code Configurator – RTC Configuration
  9. From the Plugins drop-down list, select Add Channel and then select DMA Configuration. Configure DMA Channel 0 to transmit the application buffer to the USART TX register. The DMA transfers one byte from the user buffer to the USART transmit buffer on each trigger.
    Figure 3-18. MPLAB Code Configurator – DMA Configuration
  10. From the Plugins drop-down list, select Pin Configuration and then click Pin Settings.
  11. In the Order box, type or select Ports. Build configurations according to the application as indicated below. Change the Custom Name of the pin IDs PB02 and PB03, as shown in the following figure.
    Figure 3-19. MPLAB Code Configurator – Pin Configuration

Code Generation

After configuring the peripherals as shown in the following figure, click Generate under Resource Management [MCC].

Figure 3-20. Code Generation
Note:
  1. The generated code will add files and folders to the 32-bit MCC Harmony project. In the generated code, notice the Peripheral Library files generated for the Real-Time Clock (RTC), External Interrupt Controller (EIC), PORT peripherals, SERCOM1 (as Universal Synchronous Asynchronous Receiver Transmitter (USART)), and the Direct Memory Access (DMA) peripherals. MCC also generates the main.c file.
  2. MCC provides an option to change the generated file name. By default, the file name main.c is used if a name is not assigned.

Adding Application Logic

To develop and run the application, follow these steps:

  1. Open the main.c file of the project and add the following application code.
    Figure 3-21. Logic for Register Callback Event Handlers
  2. Implement the registered callback event handlers for the peripherals by adding the following code before the main() function.
    static void SW_userHandler(uintptr_t context)
    {
        changeTempSamplingRate = true;
    }
    static void rtcEventHandler (RTC_TIMER32_INT_MASK intCause, uintptr_t context)
    {
        if (intCause & RTC_MODE0_INTENSET_CMP0_Msk)
        {
            isRTCExpired = true;
        }
    }
    static void uartDmaChannelHandler_Tx(DMAC_TRANSFER_EVENT event, uintptr_t contextHandle)
    {
        if (event == DMAC_TRANSFER_EVENT_COMPLETE)
        {
            isUARTTxComplete = true;
        }
    }
    
  3. According to the status of the isRTCExpired and isUARTTxComplete flags (these flags are handled by the rtcEventHandler and uartDmaChannelHandler_Tx event handlers when the RTC timer expires and when UART completes the data transfer), LED0 is toggled at a default rate of 500 ms. To change the toggling rate, if the user presses the SW switch, the toggling rate changes to 1s, 2s, and 4s and then returns to 500 ms with subsequent switch press events. The SW_userHandler is responsible for changing the toggling rate when the user presses the SW switch on the board.

    Inside the while loop, delete SYS_Tasks() and add the following code to toggle the LED at the default rate of 500 ms.

    if ((isRTCExpired == true) && (true == isUARTTxComplete))
            {
                isRTCExpired = false;
                isUARTTxComplete = false;
                LED_Toggle();
                sprintf((char*)(uartTxBuffer), "Toggling LED at %s rate 
                \r\n",&timeouts[(uint8_t)tempSampleRate][0]);
                DMAC_ChannelTransfer(DMAC_CHANNEL_0, uartTxBuffer,(const void *)&
                (SERCOM1_REGS->USART.SERCOM_DATA),strlen((const char*)uartTxBuffer));
            }
    
  4. Add the following code immediately after the code above to change the toggling rate when a switch press event occurs.
    if(changeTempSamplingRate == true)
            {
                changeTempSamplingRate = false;
                if(tempSampleRate == TEMP_SAMPLING_RATE_500MS)
                {
                    tempSampleRate = TEMP_SAMPLING_RATE_1S;
                    RTC_Timer32CompareSet(PERIOD_1S);
                }
                else if(tempSampleRate == TEMP_SAMPLING_RATE_1S)
                {
                    tempSampleRate = TEMP_SAMPLING_RATE_2S;
                    RTC_Timer32CompareSet(PERIOD_2S);
                }
                else if(tempSampleRate == TEMP_SAMPLING_RATE_2S)
                {
                    tempSampleRate = TEMP_SAMPLING_RATE_4S;
                    RTC_Timer32CompareSet(PERIOD_4S);
                }
                else if(tempSampleRate == TEMP_SAMPLING_RATE_4S)
                {
                    tempSampleRate = TEMP_SAMPLING_RATE_500MS;
                    RTC_Timer32CompareSet(PERIOD_500MS);
                }
                else
                {
                ;
                }
                RTC_Timer32CounterSet(0);
                sprintf((char*)uartLocalTxBuffer, "LED Toggling rate is changed to %s\r\n", 
                &timeouts[(uint8_t)tempSampleRate][0]);
                DMAC_ChannelTransfer(DMAC_CHANNEL_0, uartLocalTxBuffer, (const void *)&
                (SERCOM1_REGS->USART.SERCOM_DATA), strlen((const char*)uartLocalTxBuffer));
            }
    
  5. Add the following code to include the necessary header files and define the macros for different RTC compare values.
    #include <stddef.h>                     // Defines NULL
    #include <stdbool.h>                    // Defines true
    #include <stdlib.h>                     // Defines EXIT_FAILURE
    #include "definitions.h"                // SYS function prototypes
    #include <string.h>
    #include <stdio.h>
    

    This code declares the various flags whose status is monitored and changed by the event handlers in the application. It also includes declarations and definitions of arrays used to print the LED toggling rate on the console.

    static void SW_userHandler(uintptr_t context);
    static void rtcEventHandler (RTC_TIMER32_INT_MASK intCause, uintptr_t context);
    static void uartDmaChannelHandler_Tx(DMAC_TRANSFER_EVENT event, uintptr_t contextHandle);
    
    /* Timer Counter Time period match values for input clock of 4096 Hz */
    #define PERIOD_500MS        (512)
    #define PERIOD_1S           (1024)
    #define PERIOD_2S           (2048)
    #define PERIOD_4S           (4096)
    
    #define TX_BUFFER_SIZE      (100)
    
    static volatile bool isRTCExpired = false;
    static volatile bool changeTempSamplingRate = false;
    static volatile bool isUARTTxComplete = true;
    static volatile bool isUARTRxComplete = false;
    
    static uint8_t uartTxBuffer[TX_BUFFER_SIZE] = {0};
    

Building and Programming Application

To build and program the application, follow these steps:

  1. The PIC32CM Curiosity Nano evaluation kit supports debugging using a debugger. Connect the USB Type-C cable to the PIC32CM Curiosity Nano evaluation kit to power and debug the PIC32CM PL10 Curiosity Nano board.
  2. Ensure that the compiler optimization is set to the default value (i.e., 1). To check this, select the Fileset option under the Project tab. Then select the C compiler option and verify the optimization level.
    Figure 3-22. Project Properties
    Figure 3-23. Hardware Setup
  3. Set pic32cm6408pl10-project as the main project, and in Project Properties, select the latest compiler version (v5.00). Clean and build the project by clicking the highlighted icon.
    Figure 3-24. Build Main Project
  4. Program the application by clicking the highlighted icon.
    Figure 3-25. Program the Application

Observing the Output on the Board and Serial Terminal

To observe the output on the board and serial terminal, follow these steps:

  1. Open any terminal window (TeraTerm in this case).
  2. Select the required serial port and then click OK.
    Figure 3-26. Selection of Serial COM Port
  3. In the TeraTerm serial port setup and connection dialog box, type or select 115200 as the baud rate in the Speed box.
    Figure 3-27. Setting the Baud Rate
  4. An LED on the PIC32CM Curiosity Nano evaluation kit toggles on a timeout basis, with a default periodicity of 500 ms.
  5. The LED toggling rate is displayed on the serial terminal.
  6. Press the SW switch on the PIC32CM Curiosity Nano evaluation kit to change the default timeout periodicity to 1s.
  7. Each subsequent press of the SW switch on the PIC32CM Curiosity Nano evaluation kit changes the periodicity of the timeout periodicity to 2s, 4s, 500 ms, and back to 1s in a cyclic order.
    Figure 3-28. Output Window

As the LED toggling rate displayed on the serial terminal changes with each subsequent switch press, observe the same change in the toggling rate of LED0 on the evaluation kit.