|  | 
|  | 1 | +/* | 
|  | 2 | + * | 
|  | 3 | + * Copyright (c) 2022, Andrey Kunitsyn | 
|  | 4 | + * Copyright (c) 2022, Nikolay Semenov | 
|  | 5 | + * | 
|  | 6 | + * This file is part of the modm project. | 
|  | 7 | + * | 
|  | 8 | + * This Source Code Form is subject to the terms of the Mozilla Public | 
|  | 9 | + * License, v. 2.0. If a copy of the MPL was not distributed with this | 
|  | 10 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|  | 11 | + */ | 
|  | 12 | +// ---------------------------------------------------------------------------- | 
|  | 13 | + | 
|  | 14 | +#pragma once | 
|  | 15 | + | 
|  | 16 | +#include <modm/architecture/interface/clock.hpp> | 
|  | 17 | +#include <modm/platform.hpp> | 
|  | 18 | + | 
|  | 19 | +using namespace modm::platform; | 
|  | 20 | + | 
|  | 21 | +namespace Board | 
|  | 22 | +{ | 
|  | 23 | +using namespace modm::literals; | 
|  | 24 | + | 
|  | 25 | +/// RP2040 running at 125MHz generated from the external 12MHz crystal | 
|  | 26 | +/// @ingroup modm_board_feather_rp2040 | 
|  | 27 | +struct SystemClock | 
|  | 28 | +{ | 
|  | 29 | +	static constexpr uint32_t Frequency = 125_MHz; | 
|  | 30 | +	static constexpr uint32_t XOSCFrequency = 12_MHz; | 
|  | 31 | +	// https://github.com/raspberrypi/pico-sdk/pull/457 | 
|  | 32 | +	static constexpr uint16_t XOSCDelayMultiplier = 64; | 
|  | 33 | +	static constexpr uint32_t PllSysFrequency = Frequency; | 
|  | 34 | +	static constexpr uint32_t PllUsbFrequency = 48_MHz; | 
|  | 35 | +	static constexpr uint32_t SysPLLMul = 125; | 
|  | 36 | +	static constexpr uint32_t UsbPLLMul = 40; | 
|  | 37 | +	static constexpr uint32_t RefFrequency = XOSCFrequency; | 
|  | 38 | +	static constexpr uint32_t UsbFrequency = PllUsbFrequency; | 
|  | 39 | +	static constexpr uint32_t SysFrequency = Frequency; | 
|  | 40 | +	static constexpr uint32_t PeriFrequency = SysFrequency; | 
|  | 41 | + | 
|  | 42 | +	static bool inline enable() | 
|  | 43 | +	{ | 
|  | 44 | +		ClockControl::disableResus(); | 
|  | 45 | +		ClockControl::enableExternalCrystal(XOSCFrequency, XOSCDelayMultiplier); | 
|  | 46 | +		ClockControl::disableAux<ClockControl::Clock::Sys>(); | 
|  | 47 | +		ClockControl::disableAux<ClockControl::Clock::Ref>(); | 
|  | 48 | +		// PLL SYS: 12MHz / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz | 
|  | 49 | +		ClockControl::initPll<ClockControl::Pll::Sys, 1, SysPLLMul, 6, 2>(); | 
|  | 50 | +		// PLL USB: 12MHz / 1 = 12MHz * 40  = 480 MHz / 5 / 2 =  48MHz | 
|  | 51 | +		ClockControl::initPll<ClockControl::Pll::Usb, 1, UsbPLLMul, 5, 2>(); | 
|  | 52 | + | 
|  | 53 | +		// CLK_REF = XOSC (12MHz) / 1 = 12MHz | 
|  | 54 | +		ClockControl::configureClock<ClockControl::Clock::Ref, ClockControl::ClockSrc::Xosc, | 
|  | 55 | +									 XOSCFrequency, RefFrequency>(); | 
|  | 56 | +		// CLK SYS = PLL SYS (125MHz) / 1 = 125MHz | 
|  | 57 | +		ClockControl::configureClock<ClockControl::Clock::Sys, ClockControl::ClockSrc::PllSys, | 
|  | 58 | +									 PllSysFrequency, SysFrequency>(); | 
|  | 59 | +		// CLK USB = PLL USB (48MHz) / 1 = 48MHz | 
|  | 60 | +		ClockControl::configureClock<ClockControl::Clock::Usb, ClockControl::ClockSrc::PllUsb, | 
|  | 61 | +									 PllUsbFrequency, UsbFrequency>(); | 
|  | 62 | +		// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select | 
|  | 63 | +		// and enable Normally choose clk_sys or clk_usb | 
|  | 64 | +		ClockControl::configureClock<ClockControl::Clock::Peri, ClockControl::ClockSrc::Sys, | 
|  | 65 | +									 SysFrequency, PeriFrequency>(); | 
|  | 66 | + | 
|  | 67 | +		ClockControl::updateCoreFrequency<Frequency>(); | 
|  | 68 | +		return true; | 
|  | 69 | +	} | 
|  | 70 | +}; | 
|  | 71 | + | 
|  | 72 | +namespace usb | 
|  | 73 | +{ | 
|  | 74 | +/// @ingroup modm_board_feather_rp2040 | 
|  | 75 | +using Device = Usb; | 
|  | 76 | +} | 
|  | 77 | + | 
|  | 78 | +/// @ingroup modm_board_feather_rp2040 | 
|  | 79 | +/// @{ | 
|  | 80 | +// User LED | 
|  | 81 | +using LedRed = GpioOutput13; | 
|  | 82 | +using Led = LedRed; | 
|  | 83 | +using Leds = SoftwareGpioPort<Led>; | 
|  | 84 | + | 
|  | 85 | +using Button = GpioUnused; | 
|  | 86 | + | 
|  | 87 | +inline void | 
|  | 88 | +initialize() | 
|  | 89 | +{ | 
|  | 90 | +	SystemClock::enable(); | 
|  | 91 | +	SysTickTimer::initialize<SystemClock>(); | 
|  | 92 | + | 
|  | 93 | +	Led::setOutput(); | 
|  | 94 | +} | 
|  | 95 | + | 
|  | 96 | +inline void | 
|  | 97 | +initializeUsbFs(uint8_t priority=3) | 
|  | 98 | +{ | 
|  | 99 | +	usb::Device::initialize<SystemClock>(priority); | 
|  | 100 | +	usb::Device::connect<>(); | 
|  | 101 | +} | 
|  | 102 | +/// @} | 
|  | 103 | + | 
|  | 104 | +}  // namespace Board | 
0 commit comments