Module rp2040_hal::clocks

source ·
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 fugit::RateExtU32;
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

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

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

let mut clocks = ClocksManager::new(peripherals.CLOCKS);

// 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