PIC32MZ Oscillator

 Summary

The PIC32MZ oscillator is highly configurable. The many different clock options allow you to maximize device performance while controlling power consumption on other parts of the device. The sections below provide code examples to configure this oscillator for your specific needs.

PIC32 Oscillator Configuration Spreadsheet

Download this Microsoft Excel file which simulates the PIC32 oscillator configuration settings. Most configuration options are provided for you. It will also keep you out of trouble by highlighting incompatible configurations. Note the tabs at the bottom of the spreadsheet that select PIC32MX or PIC32MZ configurations.


Primary Oscillator (POSC)

External Clock and Oscillator Modes

posc_1.PNG

The Primary Oscillator (POSC) uses the OSC1 and OSC2 pins. POSC can be configured for an External Clock Input (EC mode) or an External Crystal or Resonator (HS mode).

#pragma config POSCMOD = EC  //default = external clock
#pragma config POSCMOD = HS  //default = high-speed crystal

External Clock Mode with Output Clock

posc_2.PNG

When POSC is in the EC mode, the OSC1 pin is a high-impedance input that can be driven by a CMOS driver.

The EC mode also disables the internal feedback buffer allowing the OSC2/CLKO pin to be used for other functions (general purpose I/O or as a clock out). The output clock provided on the CLKO pin is the peripheral bus clock number 1 (PBCLK1) divided by 2.

#pragma config OSCIOFNC = ON  // clock out enabled
#pragma config OSCIOFNC = OFF // clock out disabled

USB Input Clock Requirements

posc_3.PNG

If using the USB peripheral, POSC must be 12 MHz or 24 MHz. You must also configure the USB PLL for a 12 MHz or 24 MHz input frequency.

#pragma config UPLLEN = ON            // Enable USB PLL
#pragma config UPLLFSEL = FREQ_12MHZ  // USB PLL input clock = 12MHz
#pragma config UPLLFSEL = FREQ_24MHZ  // USB PLL input clock = 24MHz

Fast RC Oscillator (FRC)

Fast RC Oscillator (FRC)

frc.PNG

The FRC oscillator is a fast (8 MHz nominal), user-trimmable, internal RC oscillator. The output can drive the System PLL or be divided using the FRCDIV bits.

The FRCDIV bits configure a selectable output divider that allows the choice of a lower clock frequency from seven different options, plus the direct 8 MHz output. Available lower frequency options range from 4 MHz (divide-by-2) to 31 kHz (divide-by-256).

The FRC Oscillator Tuning (OSCTUN) register allows the user to fine-tune the FRC oscillator over a range of approximately ±12% (typical). Each bit increment or decrement changes the factory calibrated frequency of the FRC oscillator by a fixed amount.

The following MPLAB® Harmony function examples configure the FRC divider and tune values at run-time.

// FRCDIV = FRC/1
PLIB_OSC_FRCDivisorSelect(OSC_ID_0, OSC_FRC_DIV_1);
// Tune = 0 (no deviation from nominal)
PLIB_OSC_FRCTuningSelect(OSC_ID_0, 0);

Low Power Oscillator

lprc.PNG

Low-Power RC (LPRC) Oscillator

The LPRC oscillator is different from the Fast RC oscillator. It oscillates at a nominal frequency of 32.768 kHz. The LPRC oscillator is the clock source for the Power-up Timer (PWRT), Watchdog Timer (WDT), Fail-Safe Clock Monitor (FSCM), and Phase-Locked Loop (PLL) reference circuits. It may also be used to provide a low-frequency clock source option for the device in those applications where power consumption is critical and timing accuracy is not required.

// default System clock = LPRC
#pragma config FNOSC = LPRC
...
// System Clock = LPRC (run-time config)
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_LPRC);

Backup Fast RC Oscillator

bfrc.PNG

Backup Fast RC (BFRC) Oscillator

The PIC32MZ oscillator system includes a Fail-Safe Clock Monitor (FSCM). The FSCM monitors the SYSCLK for continuous operation. If it detects that the SYSCLK has failed, it switches the SYSCLK over to the BFRC oscillator and triggers a Non-Maskable Interrupt (NMI). The BFRC is an untuned 8 MHz oscillator that will drive the SYSCLK during an FSCM event. When code at the NMI vector is executed, the software can attempt to restart the main oscillator or shut down the system.

You cannot choose to use the BFRC for SYSCLK. Only the hardware will use this when FSCM detects a problem.

Secondary Oscillator

sosc.PNG

Secondary Oscillator (SOSC)

The Secondary Oscillator (SOSC) is designed specifically for low-power operation with an external 32 to 100 KHz crystal. The oscillator is connected to the SOSCO and SOSCI device pins and serves as a secondary crystal clock source for low-power operation. It can also drive Timer1 and/or the Real-Time Clock and Calendar (RTCC) module for Real-Time Clock (RTC) applications.

The following code sample demonstrates how to (a) enable the secondary oscillator for a specific device using configuration bit settings, and (b) how to perform simple run-time modification using the MPLAB® Harmony PLIB APIs

// Enable Secondary oscillator by default
#pragma config FSOSCEN = ON
// default System clock = Secondary oscillator
#pragma config FNOSC = SOSC

// Run-time configuration using Harmony functions shown below

// System Clock = SOSC (run-time config)
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_SECONDARY);
// Enable Secondary oscillator
PLIB_OSC_SecondaryEnable(OSC_ID_0);
// Disable Secondary oscillator
PLIB_OSC_SecondaryDisable(OSC_ID_0);

Detailed Overview

For more detail on the Secondary Oscillator module for a specific PIC32 device, please view the Oscillator family reference manual chapter for that device, for example:

The device data sheet should then be consulted to verify the specific features implemented in that device.

System PLL (SPLL)

The System Phase-Locked Loop (PLL) has a user-selectable input divider, multiplier, and output divider to provide a wide range of output frequencies. The oscillator circuit will consume more current when the PLL is enabled.

System PLL Input Selection

spll_input.PNG

The System PLL can use the Fast RC (FRC) or Primary Oscillators (POSC) as the input.

The default input can be configured at program time and MPLAB® Harmony functions can be used to configure it at run-time.

// Default input is Fast RC Oscillator
#pragma config FPLLICLK = PLL_FRC
// Default input is Primary Oscillator
#pragma config FPLLICLK = PLL_POSC
//Run-time configuration using Harmony functions shown below
...
// PLL input = FRC
PLIB_OSC_SysPLLInputClockSourceSet(OSC_ID_0, OSC_SYSPLL_IN_CLK_SOURCE_FRC);
// PLL input = POSC
PLIB_OSC_SysPLLInputClockSourceSet(OSC_ID_0, OSC_SYSPLL_IN_CLK_SOURCE_PRIMARY);

System PLL Input Divider

spll_input_div.PNG

System PLL Input divider values include all integers from 1 to 8.

The input divider must be chosen such that the resulting frequency applied to the PLL multiplier is in the range that is specified by the FPLLRNG bits in the Device Configuration (DEVCFG2) register. The FPLLRNG bits can be set to one of the following ranges:

  • 34-64 MHz
  • 21-42 MHz
  • 13-26 MHz
  • 8-16 MHz
  • 5-10 MHz
  • Bypass (input frequency = output)

The default values are programmable and can be changed at run-time.

// default PLL input divider = 1
#pragma config FPLLIDIV = DIV_1
// default PLL input divider = 8 (max)
#pragma config FPLLIDIV = DIV_8
// default multiplier input freq
#pragma config FPLLRNG = 5-10 MHz
...
// PLL input divider = 1
PLIB_OSC_SysPLLInputDivisorSet(OSC_ID_0, OSC_SYSPLL_IN_DIV_1);
// PLL input divider = 8
PLIB_OSC_SysPLLInputDivisorSet(OSC_ID_0, OSC_SYSPLL_IN_DIV_8);

System PLL Multiplier

spll_mult.PNG

The multiplier values can be any integer from 1 to 128 and the output of the multiplier must be between 350 and 700 MHz. The PLL multiplier must be configured for the specific input frequency as specified by the FPLLRNG bits.

// default PLL multiply = 1
#pragma config FPLLMULT = MUL_1
// default PLL multiply = 128
#pragma config FPLLMULT = MUL_128
...
// run-time config sets PLL multiplier to 128 (max)
PLIB_OSC_SysPLLMultiplierSelect(OSC_ID_0, 128);

System PLL Output Divider

spll_output_div.PNG

The System PLL output clock divider has values from 2 to 32. Ensure the output is between 10 and 200 MHz.

// default PLL output divider = 2
#pragma config FPLLODIV = DIV_2
// default PLL output divider = 32
#pragma config FPLLODIV = DIV_32
...
// set PLL output divider to 2
PLIB_OSC_SysPLLOutputDivisorSet(OSC_ID_0, OSC_SYSPLL_OUT_DIV_2);

System PLL Lock Status

The System PLL requires some time to achieve lock when a clock source is first applied. The SLOCK status bit can be checked to determine if enough time has passed to ensure a stable PLL output.

When the clock input to the PLL is changed, the hardware automatically clears this bit. After the PLL start-up timer has expired, the bit is automatically set. Please refer to the specific device datasheet for PLL lock time ("TLOCK" = 100 us max).

The PLL lock status bit will be set upon the expiration of the timer even if the PLL has not achieved a lock. If the PLL does not stabilize during start-up, SLOCK may not reflect the status of the PLL lock. Similarly, it does not detect when the PLL loses lock during normal operation.

The following MPLAB® Harmony function returns the state of the PLL lock status. You are responsible for checking this status anytime you change the input to the System PLL.

// variable to hold the status of PLL lock
bool clockPLL_st;
// function returns value of PLL lock status
clockPLL_st = PLIB_OSC_PLLClockIsLocked(OSC_ID_0);

System Clock (SYSCLK)

System Clock (SYSCLK) Generation

sysclk.PNG

The System Clock provides the time base for the peripheral clocks, DMA, interrupts, and Flash. SYSCLK is determined from one of the input clocks: SPLL, POSC, FRCDIV, LPRC, BFRC, and SOSC.

The PIC32MX uses SYSCLK to drive the core. This is NOT true for the PIC32MZ. The PIC32MZ core clock is provided by Peripheral Bus Clock #7 (PBCLK7).

You cannot choose to use the BFRC for SYSCLK. Only the hardware will use this when the Fail-Safe Clock Monitor (FSCM) detects a problem.

The default configuration for SYSCLK is programmable and can also be changed at run-time. See the code examples below.

// default system clock = FRCDIV
#pragma config FNOSC = FRCDIV
// default system clock = SPLL
#pragma config FNOSC = SPLL
...    
// run-time config SYSCLK = FRCDIV
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_FRC_BY_FRCDIV);
// run-time config SYSCLK = POSC with SPLL
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_PRIMARY_WITH_PLL);

Peripheral Bus Clocks (PBCLKx)

Peripheral Bus Clocks (PBCLKx)

pbclk.PNG

PIC32MZ devices include more than one peripheral clock, allowing peripherals to run at different bus speeds, depending on the application. All peripheral clocks (except PBCLK1) also have individual enable/disable control.

Each peripheral clock is derived from the System Clock (SYSCLK) divided by the specific peripheral clock divisor setting (one to 128). The maximum clock rate for most peripheral clocks is 100 MHz. The one exception to this is PBCLK7 which is 200 MHz (drives the core).

The peripheral bus frequency can be changed on the fly by writing a new value to the divisor bits. These bits are protected from accidental writes with an unlock sequence. A state machine ensures a stable transition from one clock frequency to another.

PBCLK1 ÷ 2 can also be driven out the CLKO pin.

The following MPLAB® Harmony code provides several examples for controlling the peripheral clocks. These functions will perform all unlocking and locking and state machine control for you.

// PBCLK1=SYSCLK/2
PLIB_OSC_PBClockDivisorSet(OSC_ID_0, OSC_PERIPHERAL_BUS_1, 2);
// enable PBCLK1
PLIB_OSC_PBOutputClockEnable(OSC_ID_0, OSC_PERIPHERAL_BUS_1);
// disable PBCLK8
PLIB_OSC_PBOutputClockDisable(OSC_ID_0, OSC_PERIPHERAL_BUS_8);

Reference Clocks (REFCLK)

Reference Clock

refclk.PNG

There are four reference clocks in the PIC32MZ devices. They can be used to drive peripherals or an output Reference Clock (REFCLKOx) pin.

The reference clock can be derived from any of the following clock sources: System Phased-Lock Loop, Primary Oscillator, Fast RC Oscillator, Low-Power RC Oscillator, Backup Fast RC Oscillator, Secondary Oscillator, System Clock, Peripheral Bus Clock, and Reference Clock input.

Each reference clock has a high-precision divider based on this formula:

refclk_formula.PNG
  • refOscDiv can be any integer from 1 to 32768,
    • when refOscDiv = 0, the output clock = the input clock.
  • trimValue can be any integer from 1 to 512.
// ref clock #1 base = FRC
PLIB_OSC_ReferenceOscBaseClockSelect (OSC_ID_0, OSC_REFERENCE_1, OSC_REF_BASECLOCK_FRC);
// disable ref clock #2
PLIB_OSC_ReferenceOscDisable(OSC_ID_0, OSC_REFERENCE_2);
// enable ref clock #3
PLIB_OSC_ReferenceOscEnable(OSC_ID_0, OSC_REFERENCE_3);
// refOscDiv #4 = 32768
PLIB_OSC_ReferenceOscDivisorValueSet (OSC_ID_0, OSC_REFERENCE_4, 32768);
// trimValue #1 = 256
PLIB_OSC_ReferenceOscTrimSet(OSC_ID_0, OSC_REFERENCE_1, 256);
// ref clock #3 is driven out REFCLKO3 pin
PLIB_OSC_ReferenceOutputEnable(OSC_ID_0, OSC_REFERENCE_3);

Clock Distribution Table

PIC32MZ Clock Distribution Table

Table 8.1 from the PIC32MZ2048EFG100 datasheet is reproduced here and shows the clock sources associated with each of the peripherals.

table8-1.png

For more information on the clock sources shown above, check the following:

Detailed Overview

For more detail on the Oscillator module for a specific PIC32MZ device, please view the family reference manual chapter:

The device datasheet should then be consulted to verify the specific features implemented in that device.

Two-Speed Start-up

Two-Speed Start-up

If an external crystal (Primary Oscillator) is providing a clock source for your device, you will need to wait for the oscillator and PLL to stabilize before executing any code after a Power-on Reset (POR) or exit from sleep (see Oscillator Start-up Timer and System PLL Lock Status for more information). If you want to start executing code before the oscillator has stabilized, you can use the "Two-Speed Start-up" option.

Two-Speed Start-up uses the internal Fast RC Oscillator (FRC) as the system clock source until the Primary Oscillator (POSC) has stabilized. This allows the CPU to begin running code while the oscillator is stabilizing. After it has stabilized, the clock source will automatically be switched to use the Primary Oscillator (POSC).

If you want to determine the clock source currently in use, the MPLAB® Harmony function shown in the example below can be used. It will return the current oscillator (COSC) setting found in the OSCCON register.

// Enable Two-Speed Start-up (Internal/External switch over)
#pragma config IESO = ON
...
// variable to hold the state of the current clock source
OSC_SYS_TYPE oscCurrent;
// assign the current clock source to oscCurrent
oscCurrent = PLIB_OSC_CurrentSysClockGet(OSC_ID_0);
                                              // 0 = FRC
                                              // 2 = POSC
                                              // 3 = POSC with PLL

The Watchdog Timer (WDT), if enabled, will continue to count at the same rate regardless of the SYSCLK frequency. Care must be taken to service the WDT during Two-Speed Start-up, taking into account the change in SYSCLK.

Detailed Overview

For more detail on the Two-Speed Start-up feature, please view the Oscillator family reference manual chapter for that device, for example:

The device data sheet should then be consulted to verify the specific features implemented in that device.

Fail-Safe Clock Monitor (FSCM)

Fail-Safe Clock Monitor

The Fail-Safe Clock Monitor (FSCM) monitors the Primary Oscillator (POSC) to ensure it is functional. If the POSC stops working, it will automatically switch the clock source to the internal Fast RC Oscillator (FRC) (or Backup FRC (BFRC) if available). The switch to the FRC or BFRC allows continued device operation.

The FSCM will generate an interrupt (optional on some devices) and you determine what code runs in that interrupt. You can retry the POSC to see if it recovers, or execute code appropriate for a clock failure.

The following code example shows how to enable the FSCM. It controls the clock switching and monitor (FCKSM) setting in one of the device configuration registers.

 // clock switching enabled and clock monitor enabled
#pragma config FCKSM = CSECME

All devices have at least one internal FRC oscillator. If your device also has a Backup FRC (BFRC) it will be used as the clock source instead. The BFRC is dedicated to the FSCM and can not be used for anything else.

Detailed Overview

For more detail on the Fail-Safe Clock Monitor feature, please review the Oscillator family reference manual chapter for that device, for example:

The device data sheet should then be consulted to verify the specific features implemented in that device.

Clock Switching

Clock Switching

With few limitations, applications are free to switch between any of the following clock sources at run-time:

  • Primary Oscillator (POSC)
  • Secondary Oscillator (SOSC)
  • Fast RC Oscillator (FRC)
  • Low Power RC Oscillator (LPRC)

To limit the possible side effects that could result from this flexibility, PIC32 devices have a safeguard lock built into the switch process.

Clock switching is disabled by default. You can enable it with the clock switching and monitor (FCKSM) setting. See the example code below.

// clock switching enabled and clock monitor enabled
#pragma config FCKSM = CSECME
// clock switching enabled and clock monitor disabled
#pragma config FCKSM = CSECMD
// clock switching disabled and clock monitor disabled (default)
#pragma config FCKSM = CSDCMD

The oscillator switching sequence is as follows:

  1. optional…determine the current clock source
  2. perform the unlock sequence to allow a write to the Oscillator Configuration register (OSCCON)
  3. configure the New Oscillator (NOSC) setting with the clock source you want to switch to
  4. initiate the oscillator switch by setting the Oscillator Switch Enable (OSWEN) bit
  5. optional…perform the lock sequence to prevent an unintended clock switch

The device will not permit direct switching between PLL clock sources and you should not change the PLL multiplier values or postscaler values when running from the PLL source. To perform either of these clock switching functions, follow these steps:

  1. Switch to a non-PLL source, such as FRC
  2. Modify the multiplier and postscaler values
  3. Switch to the desired PLL source

The following example code shows how to perform a clock switch using MPLAB® Harmony functions.

// Assume the current oscillator is the Primary Oscillator with the PLL and we want to
// change the PLL settings.  We will need to switch to another non-PLL clock source
// (FRC in this case) to perform this switch.

// variable to hold the state of the current clock source
OSC_SYS_TYPE currOsc;
// assign FRC as the oscillator we want to switch to
OSC_SYS_TYPE newOsc=OSC_FRC;

// assign the current clock source to currOsc
currOsc = PLIB_OSC_CurrentSysClockGet(OSC_ID_0);

// if the current osc and new osc are different, perform the switch
if(currOsc != newOsc)
{
    // unlocks the Oscillator Control register,
    // configures the new oscillator setting to Primary Oscillator
    // and initiates the oscillator switch
    PLIB_OSC_SysClockSelect ( OSC_ID_0, newOsc );

    // returns true when switch is complete
    while (!PLIB_OSC_ClockSwitchingIsComplete(OSC_ID_0));
}

// change the PLL multiplier to 24
PLIB_OSC_SysPLLMultiplierSelect(OSC_ID_0, 24);
// change output divide to 256
PLIB_OSC_SysPLLOutputDivisorSet(OSC_ID_0, OSC_SYSPLL_OUT_DIV_256);

// Switch clock source back to the 
// primary osc now using new PLL values
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_PRIMARY_WITH_PLL);
// returns true when switch is complete
while (!PLIB_OSC_ClockSwitchingIsComplete(OSC_ID_0));

The Primary Oscillator mode has two or three different sub-modes (XT, HS, and EC). These sub-modes are determined at program time and can not be changed at run time.

Detailed Overview

For more detail on the Clock Switching feature, please review the Oscillator family reference manual chapter for that device, for example:

The device data sheet should then be consulted to verify the specific features implemented in that device.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.