Skip to content

microchip-pic-avr-examples/pic32cmjh-basic-spi-mplab-harmony

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Microchip Technologies Inc.

Getting Started with SERCOM (SPI) Communication on PIC32CM M0+ Devices

This example project demonstrates basic SPI communication with the external EEPROM on the Curiosity Nano Explorer Board using the SERCOM peripheral on a PIC32CM JH00 device. The application enables write access, stores a single byte of data into the EEPROM, polls the device until the write completes, and then reads the value back. The result is then transmitted over UART, which is also implemented using a SERCOM peripheral, to a terminal window to provide confirmation of successful write and read operations.

While this project uses a PIC32CM JH00 device, the same initialization and communication principles apply to other PIC32CM M0+ devices that support SERCOM-based SPI and UART.

Hardware Used



Software Used


Opening Projects in Visual Studio Code (VSCode®)

This example project was developed in MPLAB X IDE and can also be opened in VSCode® using the MPLAB Extension Pack. Follow the provided instructions here to import and run the project in VSCode®.

For a step-by-step walkthrough on importing the project, watch the following video: Importing an MPLAB® X Project into Microsoft® VS Code®


Related Documentation

Operation

SPI Communication Concept:

The SPI communication uses a high-speed four-wire bus that connects a host device to one or more clients. The bus consists of an SDO (Serial Data Out) for sending data from the host, an SDI (Serial Data In) for receiving data from the client, an SCK (Serial Clock) to synchronize transfers, and an SS (Serial Select) to enable a specific device on the bus.

Unlike I²C, which uses addresses on a shared two-wire bus, SPI relies on the Serial Select line to determine which device the host is communicating with. Only the device whose Serial Select line is driven low will respond, while all other devices on the bus remain inactive.

This makes SPI a straightforward and fast way to exchange data with external peripherals, such as the EEPROM on the Curiosity Nano Explorer Board, using only these four pins.


SPIDiagram


Application on PIC32CM:

In this example, the concept is applied using SERCOM0 configured for SPI on a PIC32CM JH00 device. The SPI lines: SDO, SDI, SCK, and SS (Serial Select) connect to the 25CSM04 4 Mb SPI Serial EEPROM on the Curiosity Nano Explorer Board. A second SERCOM (e.g., SERCOM1) runs UART to print results to a terminal.

The PIC32CM JH00 acts as the SPI host: it writes a byte to the 25CSM04 at a chosen address, waits for the write to finish, reads the byte back, and reports the value over UART.


Application Sequence / Output Behavior

  1. Initialize: Sets up SPI to talking to the EEPROM and configures UART so the MCU can send messages to a terminal window.
  2. Program & Verify: Enables writes on the EEPROM, stores a byte of data at a chosen address, waits until the device finishes writing, then reads the same address back to confirm the value was saved correctly..
  3. Report: Sends a success message and the value read from the EEPROM to the terminal over UART.

Once programmed, the MCU communicates with the 25CSM04 EEPROM over the SPI bus to carry out the write-and-verify cycle. The terminal output confirms the operation by showing the value 0x52 read back from memory, and the SPI signals can also be observed with a logic analyzer on SDO, SDI, SCK, and SS (Serial Select).


Running the Example project

  1. Connect the Debug USB port of the PIC32CM JH00 Curiosity Nano to a PC using a Micro-USB to USB 2.0 cable.
  2. If not already installed, download and install MPLAB X IDE version 6.25 or newer.
  3. If not already installed, download and install the XC32 C-Compiler version 4.60 or newer.
  4. Clone or download this project from GitHub to the local machine.
  5. If downloaded as a .zip file, extract the files to a location preferably as close as possible to the root directory.
  6. In MPLAB X IDE, go to File → Open Project. Navigate to the extracted location and select the following project file:
    FilePath

  1. Click the Make and Program Device button in the MPLAB X IDE toolbar to program the device. Then, verify that the device is successfully programmed.
    Program
    programcomplete

View the results:

After programming the device, the output can be viewed in the MPLAB Data Visualizer terminal window. The message shown below indicates that the byte 0x52 was written into the EEPROM and then read back correctly. This verifies that the entire write–verify cycle worked as intended using the MCC-generated drivers and helper functions.


ResultsSPI


Project Configuration

This example project is already provided as a preconfigured MPLAB X project. Start by opening the project in MPLAB X IDE. Once the project is loaded, launch the MPLAB® Code Configurator (MCC) in Harmony to review the configuration.

For detailed instructions on how to create and set up a new MPLAB X project and open MCC Harmony, refer to the this Microchip online reference here

When opened in MCC Harmony, the Project Graph provides a visual overview of the project, showing the active components and their interactions.


ProjectGraph


With the Project Graph open, review the configuration step by step. Use the following checklist to confirm each setting before proceeding:

Step 1: Confirm Clock Settings

Open the Clock Configurator from the Plugins section in the Project Graph to verify the system clock is set to 48 MHz.

To check the system clock, go to Project Graph → Plugins → Clock Configurator


ClockConfigPlugins
ClockConfig48

Note: Most Harmony v3 projects default to the 48 MHz internal oscillator.


Step 2: Add and Configure the SPI Peripheral (SERCOM0)

The PIC32CM JH00 Curiosity Nano includes multiple SERCOM peripherals that can be configured for UART, SPI, or I²C communication. For this lab, SERCOM0 is used as SPI interface, since it connects directly to the Explorer Board’s SPI bus and the on board 25CSM04 SPI EEPROM.

This mapping is shown in the PIC32CM JH00 Curiosity Nano Hardware User Guide; similar guides are available for all Curiosity Nano products.
SPI_Mapping


To add and configure SERCOM0:

  1. In Device Resources, expand the SERCOM module and add SERCOM0 to the project.
    SERCOM0DeviceResources

  1. Once added, select SERCOM0 in the Project Graph. In the Configuration Options panel, apply the following settings:

    • Operation Mode: SPI Host. Configures the selected SERCOM instance as SPI controller, which drives the clock and manages communication with the external EEPROM.
    • SPI Data In Pad: PAD[2]. Assigns the input pad used for the SDI (Serial Data In) line so the MCU can receive data from the EEPROM.
    • All other settings can remain default for this project.

      SERCOM0Config

Step 3: Assign SPI Pins (SERCOM0)

After configuring SERCOM0 for SPI, the signal pins (SDO, SDI, SCK, and SS) must be mapped to the correct I/O lines that connect to the Explorer Board’s EEPROM. This ensures the microcontroller can communicate properly with the on board 25CSM04 SPI EEPROM.

According to the Curiosity Nano hardware user guide mentioned previously and Explorer Board documentation:

  • PA04 → SERCOM0 PAD0 MOSI (SDO): Serial Data Out, used by the MCU to send commands and data to the EEPROM.
  • PA05 → SERCOM0 PAD1 SCK: Serial Clock, generated by the MCU to synchronize data transfers.
  • PA06 → SERCOM0 PAD3 MISO (SDI): Serial Data In, used by the MCU to receive data back from the EEPROM.
  • PA07 → SERCOM0 PAD2 CS1 (SS): Lets the MCU choose which SPI device to talk to by pulling its line low.

To assign the pins:

  1. In the Project Graph, open Plugins → Pin Configuration.

    SERCOMConfig

  1. In the Pin Settings tab, locate PA04 (Pin #13), PA05 (Pin #14), PA06 (Pin #15), and PA07 (Pin #16) in the Pin table.
    • Set the following:
      • PA04 → SERCOM0_PAD0 (SDO) – Serial Data Out from the MCU to the EEPROM
      • PA05 → SERCOM0_PAD1 (SCK) – Serial Clock generated by the MCU
      • PA06 → SERCOM0_PAD2 (SDI) – Serial Data In from the EEPROM to the MCU
      • PA07 → GPIO (rename to EEPROM_CS, set as Output) – Serial Select line controlled by the MCU.
      • Renaming makes the signal easier to identify in code. Configuring it as an output lets the MCU actively drive the line low to enable the EEPROM during communication, and high to deselect it when Idle.

        SERCOMConfig

Step 4: Add and Configure the UART Peripheral (SERCOM1)

The PIC32CM JH00 Curiosity Nano includes multiple SERCOM peripherals. For this lab, SERCOM1 is used as a UART interface to print EEPROM results to a terminal.

This mapping is shown in the PIC32CM JH00 Curiosity Nano Hardware User Guide; similar guides are available for all Curiosity Nano products.
SERCOMPinOut


To add and configure SERCOM1:

  1. In Device Resources, expand the SERCOM module and add SERCOM1 to the project.
    SERCOM1DeviceResources

  1. Once added, select SERCOM1 in the Project Graph. In the Configuration Options panel, apply the following settings:

    • Operation Mode: USART with internal Clock. Enables UART mode for the selected SERCOM instance using the internal clock.
    • Transmit/Receive Enable: Enable both. Transmit is required to send data to the terminal; receive is optional but recommended for flexibility.
    • Baud Rate: Set to match your terminal (e.g., 9600 or 115200).
    • All other settings can remain default.
      SERCOMConfig

Step 5: Assign UART Pins (SERCOM1)

After configuring SERCOM1, the TX (transmit) and RX (receive) pins must be assigned to the correct I/O lines connected to the debugger’s CDC interface. This allows UART messages to be sent and received through the Curiosity Nano’s USB connection.

According to the Curiosity Nano user guide, PA17 is used for RX and PA16 is used for TX.


SERCOMPinOut


To assign the pins:

  1. In the Project Graph, open Plugins → Pin Configuration.

    PinConfigPlugins

  1. In the Pin Settings tab. Locate PA16 (Pin #35) and PA17 (Pin #36) in the Pin table.
    • Set the following:
      • PA16 → SERCOM1_PAD0 (RX)
      • PA17 → SERCOM1_PAD1 (TX)
        PinConfig

Step 6: Generate the MCC Code

With SPI, UART, and pin mappings configured, the final step is to generate code. MCC creates the initialization files, peripheral drivers, and APIs, preparing the project for EEPROM communication and UART output.
Generate


Application Source Code

This project combines MCC-generated functions with custom helpers to manage the 25CSM04 SPI EEPROM on the Curiosity Nano Explorer Board.

  • MCC provides: SYS_Initialize, SERCOM0_SPI_Write, SERCOM0_SPI_Read, SERCOM0_SPI_IsBusy, SERCOM1_USART_Write, and SERCOM1_USART_WriteIsBusy.
  • Custom code manages the EEPROM chip select (GPIO) and wraps the SPI operations into clear functions like write-enable, write, poll, and read.

Constants and Opcodes

#define success_msg "EEPROM Write and Read Complete\r\n"

uint8_t Write_EN  = 0x06; // Write Enable
uint8_t Write_DIS = 0x04; // Write Disable (not used here)
uint8_t READ_OP   = 0x03; // Read
uint8_t WRITE_OP  = 0x02; // Write
uint8_t WRBP_OP   = 0x08; // Status opcode for polling
uint8_t DATA_R    = 0x00; // Holds received status/data

These opcodes come directly from the EEPROM data sheet and tell the device which action to perform.

Helper Functions

  • UART_SendString: Prints a string to the terminal using SERCOM1. It waits with SERCOM1_USART_WriteIsBusy before sending each byte with SERCOM1_USART_Write. This ensures messages appear clean without being cut off.

  • EEPROM_Write_Enable: Toggles chip select and sends the Write Enable opcode (0x06). This is mandatory before any write; without it, the EEPROM ignores program commands.

  • EEPROM_WRITE: Wraps a complete program sequence: chip select low → WRITE_OP (0x02) → three address bytes → the data byte → chip select high. This stores one byte into the EEPROM memory.

  • EEPROM_CHECK_STATUS: Sends a status command (WRBP_OP) and reads one byte into DATA_R. Returns True only when the device signals it has finished writing. This polling prevents moving ahead before the data is actually stored.

  • EEPROM_READ: Sends a read command (READ_OP) plus the target address, then captures one byte into DATA_R. This retrieves the value just written so it can be verified.

Each helper makes use of MCC SPI generated functions (SERCOM0_SPI_Write, SERCOM0_SPI_Read, SERCOM0_SPI_IsBusy) while keeping chip select control explicit.


Main Function

The main() routine ties everything together: it writes a known byte to EEPROM, waits for the device to complete the operation, reads it back, and prints the result over UART.

int main(void) {
    SYS_Initialize(NULL);                  // initialize clocks, pins, SERCOM0 (SPI), SERCOM1 (UART)

    EEPROM_Write_Enable();                 // allow EEPROM programming
    EEPROM_WRITE(0xAAAAAA, 0x52);          // write 0x52 to address 0x00AAAAAA
    while (!EEPROM_CHECK_STATUS());        // block until write is finished
    EEPROM_READ(0xAAAAAA);                 // DATA_R now contains the stored byte

    SERCOM1_USART_Write(success_msg, sizeof(success_msg));   // confirmation message

    char msg[64];
    snprintf(msg, sizeof(msg), "EEPROM Data: 0x%02X\r\n", DATA_R);
    UART_SendString(msg);                  // e.g., "EEPROM Data: 0x52"

    while (true) { }                       // idle loop
    return (EXIT_FAILURE);
}

Summary

  • SPI (SERCOM0) issues the low-level commands that control the 25CSM04 EEPROM.
  • Custom helpers simplify these commands into readable operations like “enable write,” “write byte,” “check status,” and “read byte.”
  • UART (SERCOM1) reports the result to the terminal, proving that the EEPROM write and read sequence worked.

By combining MCC-generated drivers with focused custom functions, the application demonstrates the complete write–verify–report cycle on the Explorer Board EEPROM.


Conclusion

This demo highlights how SPI communication enables reliable interaction with an external EEPROM. By using MCC-generated drivers and helper functions, it demonstrates a complete write–verify cycle over SPI, confirming proper data storage and retrieval.

Related Projects

About

Demonstrates basic SPI communication on PIC32CM JH devices using MPLAB X and Harmony v3

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages