From 1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Nov 2014 10:14:39 +0000 Subject: fish --- libopencm3/lib/sam/common/pmc.c | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 libopencm3/lib/sam/common/pmc.c (limited to 'libopencm3/lib/sam/common/pmc.c') diff --git a/libopencm3/lib/sam/common/pmc.c b/libopencm3/lib/sam/common/pmc.c new file mode 100644 index 0000000..b4e0d7f --- /dev/null +++ b/libopencm3/lib/sam/common/pmc.c @@ -0,0 +1,97 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include + +/** Default peripheral clock frequency after reset. */ +uint32_t pmc_mck_frequency = 4000000; + +void pmc_xtal_enable(bool en, uint8_t startup_time) +{ + if (en) { + CKGR_MOR = (CKGR_MOR & ~CKGR_MOR_MOSCXTST_MASK) | + CKGR_MOR_KEY | CKGR_MOR_MOSCXTEN | + (startup_time << 8); + while (!(PMC_SR & PMC_SR_MOSCXTS)); + } else { + CKGR_MOR = CKGR_MOR_KEY | (CKGR_MOR & ~CKGR_MOR_MOSCXTEN); + } +} + +void pmc_plla_config(uint8_t mul, uint8_t div) +{ + CKGR_PLLAR = CKGR_PLLAR_ONE | ((mul - 1) << 16) | + CKGR_PLLAR_PLLACOUNT_MASK | div; + while (!(PMC_SR & PMC_SR_LOCKA)); +} + +void pmc_peripheral_clock_enable(uint8_t pid) +{ + if (pid < 32) { + PMC_PCER0 = 1 << pid; + } else { + PMC_PCER1 = 1 << (pid & 31); + } +} + +void pmc_peripheral_clock_disable(uint8_t pid) +{ + if (pid < 32) { + PMC_PCDR0 = 1 << pid; + } else { + PMC_PCDR1 = 1 << (pid & 31); + } +} + +void pmc_mck_set_source(enum mck_src src) +{ + PMC_MCKR = (PMC_MCKR & ~PMC_MCKR_CSS_MASK) | src; + while (!(PMC_SR & PMC_SR_MCKRDY)); +} + +void pmc_clock_setup_in_xtal_12mhz_out_84mhz(void) +{ + eefc_set_latency(4); + + /* 12MHz external xtal, maximum possible startup time */ + pmc_xtal_enable(true, 0xff); + /* Select as main oscillator */ + CKGR_MOR |= CKGR_MOR_KEY | CKGR_MOR_MOSCSEL; + /* Multiply by 7 for 84MHz */ + pmc_plla_config(7, 1); + pmc_mck_set_source(MCK_SRC_PLLA); + + pmc_mck_frequency = 84000000; +} + +void pmc_clock_setup_in_rc_4mhz_out_84mhz(void) +{ + eefc_set_latency(4); + + /* Select as main oscillator */ + CKGR_MOR = CKGR_MOR_KEY | + (CKGR_MOR & ~(CKGR_MOR_MOSCSEL | CKGR_MOR_MOSCRCF_MASK)); + /* Multiply by 21 for 84MHz */ + pmc_plla_config(21, 1); + pmc_mck_set_source(MCK_SRC_PLLA); + + pmc_mck_frequency = 84000000; +} + -- cgit v1.2.3