Module rp2040_hal::clocks[][src]

Expand description

Clocks (CLOCKS)

Usage simple

use rp2040_hal::{clocks::init_clocks_and_plls, watchdog::Watchdog, pac};

let mut peripherals = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(peripherals.WATCHDOG);
const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // Typically found in BSP crates
let mut clocks = init_clocks_and_plls(XOSC_CRYSTAL_FREQ, peripherals.XOSC, peripherals.CLOCKS, peripherals.PLL_SYS, peripherals.PLL_USB, &mut peripherals.RESETS, &mut watchdog).ok().unwrap();

Usage extended

use embedded_time::rate::*;
use rp2040_hal::{clocks::{Clock, ClocksManager, ClockSource, InitError}, gpio::Pins, pac, pll::{common_configs::{PLL_SYS_125MHZ, PLL_USB_48MHZ}, setup_pll_blocking}, Sio, watchdog::Watchdog, xosc::setup_xosc_blocking};

let mut peripherals = pac::Peripherals::take().unwrap();
let mut watchdog = Watchdog::new(peripherals.WATCHDOG);
const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // Typically found in BSP crates

// Start tick in watchdog
watchdog.enable_tick_generation(XOSC_CRYSTAL_FREQ as u8);

let mut clocks = ClocksManager::new(peripherals.CLOCKS);
// Enable the xosc
let xosc = setup_xosc_blocking(peripherals.XOSC, XOSC_CRYSTAL_FREQ.Hz()).map_err(InitError::XoscErr)?;

// Configure PLLs
//                   REF     FBDIV VCO            POSTDIV
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
// PLL USB: 12 / 1 = 12MHz * 40  = 480 MHz / 5 / 2 =  48MHz
let pll_sys = setup_pll_blocking(peripherals.PLL_SYS, xosc.operating_frequency().into(), PLL_SYS_125MHZ, &mut clocks, &mut peripherals.RESETS).map_err(InitError::PllError)?;
let pll_usb = setup_pll_blocking(peripherals.PLL_USB, xosc.operating_frequency().into(), PLL_USB_48MHZ, &mut clocks, &mut peripherals.RESETS).map_err(InitError::PllError)?;

// Configure clocks
// CLK_REF = XOSC (12MHz) / 1 = 12MHz
clocks.reference_clock.configure_clock(&xosc, xosc.get_freq()).map_err(InitError::ClockError)?;

// CLK SYS = PLL SYS (125MHz) / 1 = 125MHz
clocks.system_clock.configure_clock(&pll_sys, pll_sys.get_freq()).map_err(InitError::ClockError)?;

// CLK USB = PLL USB (48MHz) / 1 = 48MHz
clocks.usb_clock.configure_clock(&pll_usb, pll_usb.get_freq()).map_err(InitError::ClockError)?;

// CLK ADC = PLL USB (48MHZ) / 1 = 48MHz
clocks.adc_clock.configure_clock(&pll_usb, pll_usb.get_freq()).map_err(InitError::ClockError)?;

// CLK RTC = PLL USB (48MHz) / 1024 = 46875Hz
clocks.rtc_clock.configure_clock(&pll_usb, 46875u32.Hz()).map_err(InitError::ClockError)?;

// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
// Normally choose clk_sys or clk_usb
clocks.peripheral_clock.configure_clock(&clocks.system_clock, clocks.system_clock.freq()).map_err(InitError::ClockError)?;

See Chapter 2 Section 15 for more details

Structs

Adc Clock

Token which can be used to await the glitchless switch

Abstraction layer providing Clock Management.

GPIO Output 0 Clock

GPIO Output 1 Clock

GPIO Output 2 Clock

GPIO Output 3 Clock

Peripheral Clock

Reference Clock

RTC Clock

System Clock

USB Clock

Enums

Holds register value for ClockSource for AdcClock

Holds register value for ClockSource for GpioOutput0Clock

Holds register value for ClockSource for GpioOutput1Clock

Holds register value for ClockSource for GpioOutput2Clock

Holds register value for ClockSource for GpioOutput3Clock

Holds register value for ClockSource for PeripheralClock

Holds register value for ClockSource for ReferenceClock

Holds register value for ClockSource for RtcClock

Holds register value for ClockSource for SystemClock

Holds register value for ClockSource for UsbClock

Something when wrong setting up the clock

Possible init errors

Traits

For clocks

Trait for things that can be used as clock source

For clocks that can be disabled

Trait to contrain which ClockSource is valid for which Clock

Functions

Initialize the clocks and plls according to the reference implementation