PIC32MZ Oscillator
- Summary
- Primary Oscillator (POSC)
- Secondary Oscillator
- System PLL (SPLL)
- System PLL Input Divider
- System PLL Multiplier
- System PLL Output Divider
- System PLL Lock Status
- Peripheral Bus Clocks (PBCLKx)
- Reference Clocks (REFCLK)
- Clock Distribution Table
- Two-Speed Start-up
- Fail-Safe Clock Monitor (FSCM)
- Clock Switching
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 the
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
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 = HS //default = high-speed crystal
External Clock Mode with Output Clock
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 = OFF // clock out disabled
USB Input Clock Requirements
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 UPLLFSEL = FREQ_12MHZ // USB PLL input clock = 12MHz
#pragma config UPLLFSEL = FREQ_24MHZ // USB PLL input clock = 24MHz
Fast RC Oscillator (FRC)
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 percent (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.
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
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.
#pragma config FNOSC = LPRC
...
// System Clock = LPRC (run-time config)
PLIB_OSC_SysClockSelect(OSC_ID_0, OSC_LPRC);
Backup Fast RC Oscillator
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.
Secondary Oscillator
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.
#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:
- Section 6. Oscillators (PIC32MX795F512L)
- Section 42. Oscillators with Enhanced PLL (PIC32MZ2048EFG100)
The device datasheet 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
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.
#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
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.
#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
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.
#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
The System PLL output clock divider has values from 2 to 32. Ensure the output is between 10 and 200 MHz.
#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 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.
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
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 default configuration for SYSCLK is programmable and can also be changed at run-time. See the code examples below.
#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)
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.
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.
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)
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:
- 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.
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.
For more information on the clock sources shown above, check the following:
- Fast RC Oscillator (FRC)
- Low Power RC Oscillator (LPRC)
- Secondary Oscillator (SOSC)
- System Clock (SYSCLK)
- USB Clock (USBCLK)
- Peripheral Bus Clocks (PBCLKx)
- Reference Clock Out (REFCLKOx)
Detailed Overview
For more detail on the Oscillator module for a specific PIC32MZ device, please view the family reference manual chapter:
- "Section 42. Oscillators with Enhanced PLL" (PIC32MZ2048EFG100)
The device datasheet should then be consulted to verify the specific features implemented in that device.
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.
#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
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:
- Section 6. Oscillators (PIC32MX795F512L)
- Section 42. Oscillators with Enhanced PLL (PIC32MZ2048EFG100)
The device datasheet should then be consulted to verify the specific features implemented in that device.
Fail-Safe Clock Monitor (FSCM)
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 executes 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.
#pragma config FCKSM = CSECME
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:
- Section 6. Oscillators (PIC32MX795F512L)
- Section 42. Oscillators with Enhanced PLL (PIC32MZ2048EFG100)
The device datasheet should then be consulted to verify the specific features implemented in that device.
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.
#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:
- Optional…determine the current clock source
- Perform the unlock sequence to allow a write to the Oscillator Configuration register (OSCCON)
- Configure the New Oscillator (NOSC) setting with the clock source you want to switch to
- Initiate the oscillator switch by setting the Oscillator Switch Enable (OSWEN) bit
- Optional…perform the lock sequence to prevent an unintended clock switch
The following example code shows how to perform a clock switch using MPLAB Harmony functions.
// 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));
Detailed Overview
For more detail on the Clock Switching feature, please review the Oscillator family reference manual chapter for that device, for example:
- Section 6. Oscillators (PIC32MX795F512L)
- Section 42. Oscillators with Enhanced PLL (PIC32MZ2048EFG100)
The device datasheet should then be consulted to verify the specific features implemented in that device.