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