From 3c855e75d1c2af46ce80de21594535fc6f43f645 Mon Sep 17 00:00:00 2001 From: Sebastian Holzapfel Date: Sun, 11 Feb 2018 09:30:10 +1100 Subject: [PATCH] efm32hg: cmu: add updated cmu implementation based on efm32lg --- include/libopencm3/efm32/cmu.h | 2 + include/libopencm3/efm32/hg/cmu.h | 674 ++++++++++++++++++++++++++++++ lib/efm32/hg/Makefile | 2 +- lib/efm32/hg/cmu.c | 290 +++++++++++++ 4 files changed, 967 insertions(+), 1 deletion(-) create mode 100644 include/libopencm3/efm32/hg/cmu.h create mode 100644 lib/efm32/hg/cmu.c diff --git a/include/libopencm3/efm32/cmu.h b/include/libopencm3/efm32/cmu.h index d89e28c6..e6f7a348 100644 --- a/include/libopencm3/efm32/cmu.h +++ b/include/libopencm3/efm32/cmu.h @@ -19,6 +19,8 @@ #if defined(EFM32LG) # include +#elif defined(EFM32HG) +# include #else # error "efm32 family not defined." #endif diff --git a/include/libopencm3/efm32/hg/cmu.h b/include/libopencm3/efm32/hg/cmu.h new file mode 100644 index 00000000..d93a2733 --- /dev/null +++ b/include/libopencm3/efm32/hg/cmu.h @@ -0,0 +1,674 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * Copyright (C) 2018 Seb Holzapfel + * + * 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 . + */ + +#ifndef LIBOPENCM3_EFM32_CMU_H +#define LIBOPENCM3_EFM32_CMU_H + +#include +#include + +#define CMU_CTRL MMIO32(CMU_BASE + 0x000) +#define CMU_HFCORECLKDIV MMIO32(CMU_BASE + 0x004) +#define CMU_HFPERCLKDIV MMIO32(CMU_BASE + 0x008) +#define CMU_HFRCOCTRL MMIO32(CMU_BASE + 0x00C) +#define CMU_LFRCOCTRL MMIO32(CMU_BASE + 0x010) +#define CMU_AUXHFRCOCTR MMIO32(CMU_BASE + 0x014) +#define CMU_CALCTRL MMIO32(CMU_BASE + 0x018) +#define CMU_CALCNT MMIO32(CMU_BASE + 0x01C) +#define CMU_OSCENCMD MMIO32(CMU_BASE + 0x020) +#define CMU_CMD MMIO32(CMU_BASE + 0x024) +#define CMU_LFCLKSEL MMIO32(CMU_BASE + 0x028) +#define CMU_STATUS MMIO32(CMU_BASE + 0x02C) +#define CMU_IF MMIO32(CMU_BASE + 0x030) +#define CMU_IFS MMIO32(CMU_BASE + 0x034) +#define CMU_IFC MMIO32(CMU_BASE + 0x038) +#define CMU_IEN MMIO32(CMU_BASE + 0x03C) +#define CMU_HFCORECLKEN0 MMIO32(CMU_BASE + 0x040) +#define CMU_HFPERCLKEN0 MMIO32(CMU_BASE + 0x044) +#define CMU_SYNCBUSY MMIO32(CMU_BASE + 0x050) +#define CMU_FREEZE MMIO32(CMU_BASE + 0x054) +#define CMU_LFACLKEN0 MMIO32(CMU_BASE + 0x058) +#define CMU_LFBCLKEN0 MMIO32(CMU_BASE + 0x060) +#define CMU_LFCCLKEN0 MMIO32(CMU_BASE + 0x064) +#define CMU_LFAPRESC0 MMIO32(CMU_BASE + 0x068) +#define CMU_LFBPRESC0 MMIO32(CMU_BASE + 0x070) +#define CMU_PCNTCTRL MMIO32(CMU_BASE + 0x078) +#define CMU_ROUTE MMIO32(CMU_BASE + 0x080) +#define CMU_LOCK MMIO32(CMU_BASE + 0x084) +#define CMU_USBCRCTRL MMIO32(CMU_BASE + 0x0D0) +#define CMU_USHFRCOCTRL MMIO32(CMU_BASE + 0x0D4) +#define CMU_USHFRCOTUNE MMIO32(CMU_BASE + 0x0D8) +#define CMU_USHFRCOCONF MMIO32(CMU_BASE + 0x0DC) + +/* CMU_CTRL */ +#define CMU_CTRL_CLKOUTSEL1_SHIFT (23) +#define CMU_CTRL_CLKOUTSEL1_MASK (0x7 << CMU_CTRL_CLKOUTSEL1_SHIFT) +#define CMU_CTRL_CLKOUTSEL1(v) \ + (((v) << CMU_CTRL_CLKOUTSEL1_SHIFT) & CMU_CTRL_CLKOUTSEL1_MASK) +#define CMU_CTRL_CLKOUTSEL1_LFRCO CMU_CTRL_CLKOUTSEL1(0) +#define CMU_CTRL_CLKOUTSEL1_LFXO CMU_CTRL_CLKOUTSEL1(1) +#define CMU_CTRL_CLKOUTSEL1_HFCLK CMU_CTRL_CLKOUTSEL1(2) +#define CMU_CTRL_CLKOUTSEL1_LFXOQ CMU_CTRL_CLKOUTSEL1(3) +#define CMU_CTRL_CLKOUTSEL1_HFXOQ CMU_CTRL_CLKOUTSEL1(4) +#define CMU_CTRL_CLKOUTSEL1_LFRCOQ CMU_CTRL_CLKOUTSEL1(5) +#define CMU_CTRL_CLKOUTSEL1_HFRCOQ CMU_CTRL_CLKOUTSEL1(6) +#define CMU_CTRL_CLKOUTSEL1_AUXHFRCOQ CMU_CTRL_CLKOUTSEL1(7) +#define CMU_CTRL_CLKOUTSEL1_USHFRCO CMU_CTRL_CLKOUTSEL1(8) + +#define CMU_CTRL_CLKOUTSEL0_SHIFT (20) +#define CMU_CTRL_CLKOUTSEL0_MASK (0x7 << CMU_CTRL_CLKOUTSEL0_SHIFT) +#define CMU_CTRL_CLKOUTSEL0(v) \ + (((v) << CMU_CTRL_CLKOUTSEL0_SHIFT) & CMU_CTRL_CLKOUTSEL0_MASK) +#define CMU_CTRL_CLKOUTSEL0_HFRCO CMU_CTRL_CLKOUTSEL0(0) +#define CMU_CTRL_CLKOUTSEL0_HFXO CMU_CTRL_CLKOUTSEL0(1) +#define CMU_CTRL_CLKOUTSEL0_HFCLK2 CMU_CTRL_CLKOUTSEL0(2) +#define CMU_CTRL_CLKOUTSEL0_HFCLK4 CMU_CTRL_CLKOUTSEL0(3) +#define CMU_CTRL_CLKOUTSEL0_HFCLK8 CMU_CTRL_CLKOUTSEL0(4) +#define CMU_CTRL_CLKOUTSEL0_HFCLK16 CMU_CTRL_CLKOUTSEL0(5) +#define CMU_CTRL_CLKOUTSEL0_ULFRCO CMU_CTRL_CLKOUTSEL0(6) +#define CMU_CTRL_CLKOUTSEL0_AUXHFRCO CMU_CTRL_CLKOUTSEL0(7) + +#define CMU_CTRL_LFXOTIMEOUT_SHIFT (18) +#define CMU_CTRL_LFXOTIMEOUT_MASK (0x3 << CMU_CTRL_LFXOTIMEOUT_SHIFT) +#define CMU_CTRL_LFXOTIMEOUT(v) \ + (((v) << CMU_CTRL_LFXOTIMEOUT_SHIFT) & CMU_CTRL_LFXOTIMEOUT_MASK) +#define CMU_CTRL_LFXOTIMEOUT_8CYCLES CMU_CTRL_LFXOTIMEOUT(0) +#define CMU_CTRL_LFXOTIMEOUT_1KCYCLES CMU_CTRL_LFXOTIMEOUT(1) +#define CMU_CTRL_LFXOTIMEOUT_16KCYCLES CMU_CTRL_LFXOTIMEOUT(2) +#define CMU_CTRL_LFXOTIMEOUT_32KCYCLES CMU_CTRL_LFXOTIMEOUT(3) + +#define CMU_CTRL_LFXOBUFCUR (1 << 17) + +#define CMU_CTRL_HFCLKDIV_SHIFT (14) +#define CMU_CTRL_HFCLKDIV_MASK (0x7 << CMU_CTRL_HFCLKDIV_SHIFT) +#define CMU_CTRL_HFCLKDIV(v) \ + (((v) << CMU_CTRL_HFCLKDIV_SHIFT) & CMU_CTRL_HFCLKDIV_MASK) +#define CMU_CTRL_HFCLKDIV_NODIV CMU_CTRL_HFCLKDIV(0) +#define CMU_CTRL_HFCLKDIV_DIV2 CMU_CTRL_HFCLKDIV(1) +#define CMU_CTRL_HFCLKDIV_DIV3 CMU_CTRL_HFCLKDIV(2) +#define CMU_CTRL_HFCLKDIV_DIV4 CMU_CTRL_HFCLKDIV(3) +#define CMU_CTRL_HFCLKDIV_DIV5 CMU_CTRL_HFCLKDIV(4) +#define CMU_CTRL_HFCLKDIV_DIV6 CMU_CTRL_HFCLKDIV(5) +#define CMU_CTRL_HFCLKDIV_DIV7 CMU_CTRL_HFCLKDIV(6) +#define CMU_CTRL_HFCLKDIV_DIV8 CMU_CTRL_HFCLKDIV(7) + +#define CMU_CTRL_LFXOBOOST (1 << 13) + +#define CMU_CTRL_LFXOMODE_SHIFT (11) +#define CMU_CTRL_LFXOMODE_MASK (0x3 << CMU_CTRL_LFXOMODE_SHIFT) +#define CMU_CTRL_LFXOMODE(v) \ + (((v) << CMU_CTRL_LFXOMODE_SHIFT) & CMU_CTRL_LFXOMODE_MASK) +#define CMU_CTRL_LFXOMODE_XTAL CMU_CTRL_LFXOMODE(0) +#define CMU_CTRL_LFXOMODE_BUFEXTCLK CMU_CTRL_LFXOMODE(1) +#define CMU_CTRL_LFXOMODE_DIGEXTCLK CMU_CTRL_LFXOMODE(2) + +#define CMU_CTRL_HFXOTIMEOUT_SHIFT (9) +#define CMU_CTRL_HFXOTIMEOUT_MASK (0x3 << CMU_CTRL_HFXOTIMEOUT_SHIFT) +#define CMU_CTRL_HFXOTIMEOUT(v) \ + (((v) << CMU_CTRL_HFXOTIMEOUT_SHIFT) & CMU_CTRL_HFXOTIMEOUT_MASK) +#define CMU_CTRL_HFXOTIMEOUT_8CYCLES CMU_CTRL_HFXOTIMEOUT(0) +#define CMU_CTRL_HFXOTIMEOUT_256CYCLES CMU_CTRL_HFXOTIMEOUT(1) +#define CMU_CTRL_HFXOTIMEOUT_1KCYCLES CMU_CTRL_HFXOTIMEOUT(2) +#define CMU_CTRL_HFXOTIMEOUT_16KCYCLES CMU_CTRL_HFXOTIMEOUT(3) + +#define CMU_CTRL_HFXOGLITCHDETEN (1 << 7) +#define CMU_CTRL_HFXOBUFCUR_MASK (0x3 << 5) + +#define CMU_CTRL_HFXOBOOST_SHIFT (2) +#define CMU_CTRL_HFXOBOOST_MASK (0x3 << CMU_CTRL_HFXOBOOST_SHIFT) +#define CMU_CTRL_HFXOBOOST(v) \ + (((v) << CMU_CTRL_HFXOBOOST_SHIFT) & CMU_CTRL_HFXOBOOST_MASK) +#define CMU_CTRL_HFXOBOOST_50PCENT CMU_CTRL_HFXOBOOST(0) +#define CMU_CTRL_HFXOBOOST_70PCENT CMU_CTRL_HFXOBOOST(1) +#define CMU_CTRL_HFXOBOOST_80PCENT CMU_CTRL_HFXOBOOST(2) +#define CMU_CTRL_HFXOBOOST_100PCENT CMU_CTRL_HFXOBOOST(3) + +#define CMU_CTRL_HFXOMODE_SHIFT (0) +#define CMU_CTRL_HFXOMODE_MASK (0x3 << CMU_CTRL_HFXOMODE_SHIFT) +#define CMU_CTRL_HFXOMODE(v) \ + (((v) << CMU_CTRL_HFXOMODE_SHIFT) & CMU_CTRL_HFXOMODE_MASK) +#define CMU_CTRL_HFXOMODE_XTAL CMU_CTRL_HFXOMODE(0) +#define CMU_CTRL_HFXOMODE_BUFEXTCLK CMU_CTRL_HFXOMODE(1) +#define CMU_CTRL_HFXOMODE_DIGEXTCLK CMU_CTRL_HFXOMODE(2) + +/* CMU_HFCORECLKDIV */ +#define CMU_HFCORECLKDIV_HFCORECLKLEDIV (1 << 8) + +#define CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT (0) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_MASK \ + (0xF << CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT) +#define CMU_HFCORECLKDIV_HFCORECLKDIV(v) \ + (((v) << CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT) & \ + CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK \ + CMU_HFCORECLKDIV_HFCORECLKDIV(0) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(1) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(2) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(3) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(4) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(5) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(6) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(7) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(8) +#define CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 \ + CMU_HFCORECLKDIV_HFCORECLKDIV(9) + +#define CMU_HFCORECLKDIV_HFCORECLKDIV_NODIV \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV2 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK2 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV4 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK4 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV8 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK8 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV16 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK16 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV32 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK32 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV64 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK64 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV128 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK128 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV256 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK256 +#define CMU_HFCORECLKDIV_HFCORECLKDIV_DIV512 \ + CMU_HFCORECLKDIV_HFCORECLKDIV_HFCLK512 + +/* CMU_HFPERCLKDIV */ +#define CMU_HFPERCLKDIV_HFPERCLKEN (1 << 8) + +#define CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT (0) +#define CMU_HFPERCLKDIV_HFPERCLKDIV_MASK \ + (0xF << CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT) +#define CMU_HFPERCLKDIV_HFPERCLKDIV(v) \ + (((v) << CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT) & \ + CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK CMU_HFPERCLKDIV_HFPERCLKDIV(0) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK2 CMU_HFPERCLKDIV_HFPERCLKDIV(1) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK4 CMU_HFPERCLKDIV_HFPERCLKDIV(2) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK8 CMU_HFPERCLKDIV_HFPERCLKDIV(3) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK16 CMU_HFPERCLKDIV_HFPERCLKDIV(4) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK32 CMU_HFPERCLKDIV_HFPERCLKDIV(5) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK64 CMU_HFPERCLKDIV_HFPERCLKDIV(6) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK128 CMU_HFPERCLKDIV_HFPERCLKDIV(7) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK256 CMU_HFPERCLKDIV_HFPERCLKDIV(8) +#define CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK512 CMU_HFPERCLKDIV_HFPERCLKDIV(9) + +/* CMU_HFPERCLKDIV_HFPERCLKHFCLK_HFCLK* to CMU_HFPERCLKDIV_HFPERCLKHFCLK_DIV* */ +#define CMU_HFPERCLKDIV_HFPERCLKDIV_NODIV \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV2 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK2 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV4 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK4 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV8 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK8 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV16 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK16 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV32 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK32 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV64 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK64 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV128 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK128 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV256 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK256 +#define CMU_HFPERCLKDIV_HFPERCLKDIV_DIV512 \ + CMU_HFPERCLKDIV_HFPERCLKDIV_HFCLK512 + +/* CMU_HFRCOCTRL */ +#define CMU_HFRCOCTRL_SUDELAY_SHIFT (12) +#define CMU_HFRCOCTRL_SUDELAY_MASK (0x1F << CMU_HFRCOCTRL_SUDELAY_SHIFT) +#define CMU_HFRCOCTRL_SUDELAY(v) \ + ((((v) << CMU_HFRCOCTRL_SUDELAY_SHIFT) & CMU_HFRCOCTRL_SUDELAY_MASK)) + +#define CMU_HFRCOCTRL_BAND_SHIFT (8) +#define CMU_HFRCOCTRL_BAND_MASK (0x7 << CMU_HFRCOCTRL_BAND_SHIFT) +#define CMU_HFRCOCTRL_BAND(v) \ + (((v) << CMU_HFRCOCTRL_BAND_SHIFT) & CMU_HFRCOCTRL_BAND_MASK) +#define CMU_HFRCOCTRL_BAND_1MHZ CMU_HFRCOCTRL_BAND(0) +#define CMU_HFRCOCTRL_BAND_7MHZ CMU_HFRCOCTRL_BAND(1) +#define CMU_HFRCOCTRL_BAND_11MHZ CMU_HFRCOCTRL_BAND(2) +#define CMU_HFRCOCTRL_BAND_14MHZ CMU_HFRCOCTRL_BAND(3) +#define CMU_HFRCOCTRL_BAND_21MHZ CMU_HFRCOCTRL_BAND(4) + +#define CMU_HFRCOCTRL_TUNING_SHIFT (0) +#define CMU_HFRCOCTRL_TUNING_MASK (0xFF << CMU_HFRCOCTRL_TUNING_SHIFT) +#define CMU_HFRCOCTRL_TUNING(v) \ + (((v) << CMU_HFRCOCTRL_TUNING_SHIFT) & CMU_HFRCOCTRL_TUNING_MASK) + +/* CMU_LFRCOCTRL */ +#define CMU_LFRCOCTRL_TUNING_SHIFT (0) +#define CMU_LFRCOCTRL_TUNING_MASK (0xFF << CMU_LFRCOCTRL_TUNING_SHIFT) +#define CMU_LFRCOCTRL_TUNING(v) \ + (((v) << CMU_LFRCOCTRL_TUNING_SHIFT) & CMU_LFRCOCTRL_TUNING_MASK) + +/* CMU_AUXHFRCOCTRL */ +#define CMU_AUXHFRCOCTRL_BAND_SHIFT (8) +#define CMU_AUXHFRCOCTRL_BAND_MASK (0x7 << CMU_AUXHFRCOCTRL_BAND_SHIFT) +#define CMU_AUXHFRCOCTRL_BAND(v) \ + (((v) << CMU_AUXHFRCOCTRL_BAND_SHIFT) & CMU_AUXHFRCOCTRL_BAND_MASK) +#define CMU_AUXHFRCOCTRL_BAND_1MHZ CMU_AUXHFRCOCTRL_BAND(0) +#define CMU_AUXHFRCOCTRL_BAND_7MHZ CMU_AUXHFRCOCTRL_BAND(1) +#define CMU_AUXHFRCOCTRL_BAND_11MHZ CMU_AUXHFRCOCTRL_BAND(2) +#define CMU_AUXHFRCOCTRL_BAND_14MHZ CMU_AUXHFRCOCTRL_BAND(3) +#define CMU_AUXHFRCOCTRL_BAND_28MHZ CMU_AUXHFRCOCTRL_BAND(4) +#define CMU_AUXHFRCOCTRL_BAND_21MHZ CMU_AUXHFRCOCTRL_BAND(5) + +#define CMU_AUXHFRCOCTRL_TUNING_SHIFT (0) +#define CMU_AUXHFRCOCTRL_TUNING_MASK (0xFF << CMU_AUXHFRCOCTRL_TUNING_SHIFT) +#define CMU_AUXHFRCOCTRL_TUNING(v) \ + (((v) << CMU_AUXHFRCOCTRL_TUNING_SHIFT) & CMU_AUXHFRCOCTRL_TUNING_MASK) + +/* CMU_CALCTRL */ +#define CMU_CALCTRL_CONT (1 << 6) + +#define CMU_CALCTRL_DOWNSEL_SHIFT (3) +#define CMU_CALCTRL_DOWNSEL_MASK (0x7 << CMU_CALCTRL_DOWNSEL_SHIFT) +#define CMU_CALCTRL_DOWNSEL(v) \ + (((v) << CMU_CALCTRL_DOWNSEL_SHIFT) & CMU_CALCTRL_DOWNSEL_MASK) +#define CMU_CALCTRL_DOWNSEL_HFCLK CMU_CALCTRL_DOWNSEL(0) +#define CMU_CALCTRL_DOWNSEL_HFXO CMU_CALCTRL_DOWNSEL(1) +#define CMU_CALCTRL_DOWNSEL_LFXO CMU_CALCTRL_DOWNSEL(2) +#define CMU_CALCTRL_DOWNSEL_HFRCO CMU_CALCTRL_DOWNSEL(3) +#define CMU_CALCTRL_DOWNSEL_LFRCO CMU_CALCTRL_DOWNSEL(4) +#define CMU_CALCTRL_DOWNSEL_AUXHFRCO CMU_CALCTRL_DOWNSEL(5) +#define CMU_CALCTRL_DOWNSEL_USHFRCO CMU_CALCTRL_DOWNSEL(6) + +#define CMU_CALCTRL_UPSEL_SHIFT (3) +#define CMU_CALCTRL_UPSEL_MASK (0x7 << CMU_CALCTRL_UPSEL_SHIFT) +#define CMU_CALCTRL_UPSEL(v) \ + (((v) << CMU_CALCTRL_UPSEL_SHIFT) & CMU_CALCTRL_UPSEL_MASK) +#define CMU_CALCTRL_UPSEL_HFXO CMU_CALCTRL_UPSEL(0) +#define CMU_CALCTRL_UPSEL_LFXO CMU_CALCTRL_UPSEL(1) +#define CMU_CALCTRL_UPSEL_HFRCO CMU_CALCTRL_UPSEL(2) +#define CMU_CALCTRL_UPSEL_LFRCO CMU_CALCTRL_UPSEL(3) +#define CMU_CALCTRL_UPSEL_AUXHFRCO CMU_CALCTRL_UPSEL(4) +#define CMU_CALCTRL_UPSEL_USHFRCO CMU_CALCTRL_UPSEL(5) + +/* CMU_CALCNT */ +#define CMU_CALCNT_CALCNT_SHIFT (0) +#define CMU_CALCNT_CALCNT_MASK (0xFFFFF << CMU_CALCNT_CALCNT_SHIFT) +#define CMU_CALCNT_CALCNT(v) \ + (((v) << CMU_CALCNT_CALCNT_SHIFT) & CMU_CALCNT_CALCNT_MASK) + +/* CMU_OSCENCMD */ +/* Bits 31:12 - Reserved */ +#define CMU_OSCENCMD_USHFRCODIS (1 << 11) +#define CMU_OSCENCMD_USHFRCOEN (1 << 10) +#define CMU_OSCENCMD_LFXODIS (1 << 9) +#define CMU_OSCENCMD_LFXOEN (1 << 8) +#define CMU_OSCENCMD_LFRCODIS (1 << 7) +#define CMU_OSCENCMD_LFRCOEN (1 << 6) +#define CMU_OSCENCMD_AUXHFRCODIS (1 << 5) +#define CMU_OSCENCMD_AUXHFRCOEN (1 << 4) +#define CMU_OSCENCMD_HFXODIS (1 << 3) +#define CMU_OSCENCMD_HFXOEN (1 << 2) +#define CMU_OSCENCMD_HFRCODIS (1 << 1) +#define CMU_OSCENCMD_HFRCOEN (1 << 0) + +/* CMU_CMD */ +#define CMU_CMD_USBCCLKSEL_SHIFT (5) +#define CMU_CMD_USBCCLKSEL_MASK (0x5 << CMU_CMD_USBCCLKSEL_SHIFT) +#define CMU_CMD_USBCCLKSEL(v) \ + (((v) << CMU_CMD_USBCCLKSEL_SHIFT) & CMU_CMD_USBCCLKSEL_MASK) +#define CMU_CMD_USBCCLKSEL_LFXO CMU_CMD_USBCCLKSEL(2) +#define CMU_CMD_USBCCLKSEL_LFRCO CMU_CMD_USBCCLKSEL(3) +#define CMU_CMD_USBCCLKSEL_USHFRCO CMU_CMD_USBCCLKSEL(4) + +#define CMU_CMD_CALSTOP (1 << 4) +#define CMU_CMD_CALSTART (1 << 3) + +#define CMU_CMD_HFCLKSEL_SHIFT (0) +#define CMU_CMD_HFCLKSEL_MASK (0x7 << CMU_CMD_HFCLKSEL_SHIFT) +#define CMU_CMD_HFCLKSEL(v) \ + (((v) << CMU_CMD_HFCLKSEL_SHIFT) & CMU_CMD_HFCLKSEL_MASK) +#define CMU_CMD_HFCLKSEL_HFRCO CMU_CMD_HFCLKSEL(1) +#define CMU_CMD_HFCLKSEL_HFXO CMU_CMD_HFCLKSEL(2) +#define CMU_CMD_HFCLKSEL_LFRCO CMU_CMD_HFCLKSEL(3) +#define CMU_CMD_HFCLKSEL_LFXO CMU_CMD_HFCLKSEL(4) + +/* CMU_LFCLKSEL */ +/* Bits 31:21 - Reserved */ +#define CMU_LFCLKSEL_LFBE (1 << 20) +/* Bits 19:17 - Reserved */ +#define CMU_LFCLKSEL_LFAE (1 << 16) +/* Bits 15:6 - Reserved */ + +#define CMU_LFCLKSEL_LFC_SHIFT (4) +#define CMU_LFCLKSEL_LFC_MASK (0x3 << CMU_LFCLKSEL_LFC_SHIFT) +#define CMU_LFCLKSEL_LFC(v) \ + (((v) << CMU_LFCLKSEL_LFC_SHIFT) & CMU_LFCLKSEL_LFC_MASK) +#define CMU_LFCLKSEL_LFC_DISABLED CMU_LFCLKSEL_LFC(0) +#define CMU_LFCLKSEL_LFC_LFRCO CMU_LFCLKSEL_LFC(1) +#define CMU_LFCLKSEL_LFC_LFXO CMU_LFCLKSEL_LFC(2) + +#define CMU_LFCLKSEL_LFB_SHIFT (2) +#define CMU_LFCLKSEL_LFB_MASK (0x3 << CMU_LFCLKSEL_LFB_SHIFT) +#define CMU_LFCLKSEL_LFB(v) \ + (((v) << CMU_LFCLKSEL_LFB_SHIFT) & CMU_LFCLKSEL_LFB_MASK) + +#define CMU_LFCLKSEL_LFA_SHIFT (0) +#define CMU_LFCLKSEL_LFA_MASK (0x3 << CMU_LFCLKSEL_LFA_SHIFT) +#define CMU_LFCLKSEL_LFA(v) \ + (((v) << CMU_LFCLKSEL_LFA_SHIFT) & CMU_LFCLKSEL_LFA_MASK) + +/* CMU_STATUS */ +/* Bits 31:27 - Reserved */ +#define CMU_STATUS_USHFRCODIV2SEL (1 << 26) +/* Bits 25:24 - Reserved */ +#define CMU_STATUS_USHFRCOSUSPEND (1 << 23) +#define CMU_STATUS_USHFRCORDY (1 << 22) +#define CMU_STATUS_USHFRCOENS (1 << 21) +#define CMU_STATUS_USBCHFCLKSYNC (1 << 20) +/* Bit 19 - Reserved */ +#define CMU_STATUS_USBCUSHFRCOSEL (1 << 18) +#define CMU_STATUS_USBCLFRCOSEL (1 << 17) +#define CMU_STATUS_USBCLFXOSEL (1 << 16) +/* Bit 15 - Reserved */ +#define CMU_STATUS_CALBSY (1 << 14) +#define CMU_STATUS_LFXOSEL (1 << 13) +#define CMU_STATUS_LFRCOSEL (1 << 12) +#define CMU_STATUS_HFXOSEL (1 << 11) +#define CMU_STATUS_HFRCOSEL (1 << 10) +#define CMU_STATUS_LFXORDY (1 << 9) +#define CMU_STATUS_LFXOENS (1 << 8) +#define CMU_STATUS_LFRCORDY (1 << 7) +#define CMU_STATUS_LFRCOENS (1 << 6) +#define CMU_STATUS_AUXHFRCORDY (1 << 5) +#define CMU_STATUS_AUXHFRCOENS (1 << 4) +#define CMU_STATUS_HFXORDY (1 << 3) +#define CMU_STATUS_HFXOENS (1 << 2) +#define CMU_STATUS_HFRCORDY (1 << 1) +#define CMU_STATUS_HFRCOENS (1 << 0) + +/* CMU_IF */ +/* Bits 31:10 - Reserved */ +#define CMU_IF_USBCHFOSCSEL (1 << 9) +#define CMU_IF_USHFRCORDY (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_IF_CALOF (1 << 6) +#define CMU_IF_CALRDY (1 << 5) +#define CMU_IF_AUXHFRCORDY (1 << 4) +#define CMU_IF_LFXORDY (1 << 3) +#define CMU_IF_LFRCORDY (1 << 2) +#define CMU_IF_HFXORDY (1 << 1) +#define CMU_IF_HFRCORDY (1 << 0) + +/* CMU_IFS */ +/* Bits 31:10 - Reserved */ +#define CMU_IFS_USBCHFOSCSEL (1 << 9) +#define CMU_IFS_USHFRCORDY (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_IFS_CALOF (1 << 6) +#define CMU_IFS_CALRDY (1 << 5) +#define CMU_IFS_AUXHFRCORDY (1 << 4) +#define CMU_IFS_LFXORDY (1 << 3) +#define CMU_IFS_LFRCORDY (1 << 2) +#define CMU_IFS_HFXORDY (1 << 1) +#define CMU_IFS_HFRCORDY (1 << 0) + +/* CMU_IFC */ +/* Bits 31:10 - Reserved */ +#define CMU_IFC_USBCHFOSCSEL (1 << 9) +#define CMU_IFC_USHFRCORDY (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_IFC_CALOF (1 << 6) +#define CMU_IFC_CALRDY (1 << 5) +#define CMU_IFC_AUXHFRCORDY (1 << 4) +#define CMU_IFC_LFXORDY (1 << 3) +#define CMU_IFC_LFRCORDY (1 << 2) +#define CMU_IFC_HFXORDY (1 << 1) +#define CMU_IFC_HFRCORDY (1 << 0) + +/* CMU_IEN */ +/* Bits 31:10 - Reserved */ +#define CMU_IEN_USBCHFOSCSEL (1 << 9) +#define CMU_IEN_USHFRCORDY (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_IEN_CALOF (1 << 6) +#define CMU_IEN_CALRDY (1 << 5) +#define CMU_IEN_AUXHFRCORDY (1 << 4) +#define CMU_IEN_LFXORDY (1 << 3) +#define CMU_IEN_LFRCORDY (1 << 2) +#define CMU_IEN_HFXORDY (1 << 1) +#define CMU_IEN_HFRCORDY (1 << 0) + +/* CMU_HFCORECLKEN0 */ +/* Bits 31:5 - Reserved */ +#define CMU_HFCORECLKEN0_USB (1 << 4) +#define CMU_HFCORECLKEN0_USBC (1 << 3) +#define CMU_HFCORECLKEN0_LE (1 << 2) +#define CMU_HFCORECLKEN0_DMA (1 << 1) +#define CMU_HFCORECLKEN0_AES (1 << 0) + +/* CMU_HFPERCLKEN0 */ +/* Bits 31:12 - Reserved */ +#define CMU_HFPERCLKEN0_I2C0 (1 << 11) +#define CMU_HFPERCLKEN0_ADC0 (1 << 10) +#define CMU_HFPERCLKEN0_VCMP (1 << 9) +#define CMU_HFPERCLKEN0_GPIO (1 << 8) +#define CMU_HFPERCLKEN0_IDAC0 (1 << 7) +#define CMU_HFPERCLKEN0_PRS (1 << 6) +#define CMU_HFPERCLKEN0_ACMP0 (1 << 5) +#define CMU_HFPERCLKEN0_USART1 (1 << 4) +#define CMU_HFPERCLKEN0_USART0 (1 << 3) +#define CMU_HFPERCLKEN0_TIMER2 (1 << 2) +#define CMU_HFPERCLKEN0_TIMER1 (1 << 1) +#define CMU_HFPERCLKEN0_TIMER0 (1 << 0) + +/* CMU_SYNCBUSY */ +/* Bits 31:9 - Reserved */ +#define CMU_SYNCBUSY_LFCCLKEN0 (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_SYNCBUSY_LFBPRESC0 (1 << 6) +/* Bit 5 - Reserved */ +#define CMU_SYNCBUSY_LFBCLKEN0 (1 << 4) +/* Bit 3 - Reserved */ +#define CMU_SYNCBUSY_LFAPRESC0 (1 << 2) +/* Bit 1 - Reserved */ +#define CMU_SYNCBUSY_LFACLKEN0 (1 << 0) + +/* CMU_FREEZE */ +#define CMU_FREEZE_REGFREEZE (1 << 0) + +/* CMU_LFACLKEN0 */ +#define CMU_LFACLKEN0_RTC (1 << 0) + +/* CMU_LFBCLKEN0 */ +#define CMU_LFBCLKEN0_LEUART0 (1 << 0) + +/* CMU_LFCCLKEN0 */ +#define CMU_LFCCLKEN0_USBLE (1 << 0) + +/* CMU_LFAPRESC0 */ +#define CMU_LFAPRESC0_RTC_SHIFT (0) +#define CMU_LFAPRESC0_RTC_MASK (0xF << CMU_LFAPRESC0_RTC_SHIFT) +#define CMU_LFAPRESC0_RTC(v) \ + (((v) << CMU_LFAPRESC0_RTC_SHIFT) & CMU_LFAPRESC0_RTC_MASK) +#define CMU_LFAPRESC0_RTC_DIV1 CMU_LFAPRESC0_RTC(0) +#define CMU_LFAPRESC0_RTC_DIV2 CMU_LFAPRESC0_RTC(1) +#define CMU_LFAPRESC0_RTC_DIV4 CMU_LFAPRESC0_RTC(2) +#define CMU_LFAPRESC0_RTC_DIV8 CMU_LFAPRESC0_RTC(3) +#define CMU_LFAPRESC0_RTC_DIV16 CMU_LFAPRESC0_RTC(4) +#define CMU_LFAPRESC0_RTC_DIV32 CMU_LFAPRESC0_RTC(5) +#define CMU_LFAPRESC0_RTC_DIV64 CMU_LFAPRESC0_RTC(6) +#define CMU_LFAPRESC0_RTC_DIV128 CMU_LFAPRESC0_RTC(7) +#define CMU_LFAPRESC0_RTC_DIV256 CMU_LFAPRESC0_RTC(8) +#define CMU_LFAPRESC0_RTC_DIV512 CMU_LFAPRESC0_RTC(9) +#define CMU_LFAPRESC0_RTC_DIV1024 CMU_LFAPRESC0_RTC(10) +#define CMU_LFAPRESC0_RTC_DIV2048 CMU_LFAPRESC0_RTC(11) +#define CMU_LFAPRESC0_RTC_DIV4096 CMU_LFAPRESC0_RTC(12) +#define CMU_LFAPRESC0_RTC_DIV8192 CMU_LFAPRESC0_RTC(13) +#define CMU_LFAPRESC0_RTC_DIV16384 CMU_LFAPRESC0_RTC(14) +#define CMU_LFAPRESC0_RTC_DIV32768 CMU_LFAPRESC0_RTC(15) +#define CMU_LFAPRESC0_RTC_NODIV CMU_LFAPRESC0_RTC_DIV1 + +/* CMU_LFBPRESC0 */ +#define CMU_LFBPRESC0_LEUART0_SHIFT (0) +#define CMU_LFBPRESC0_LEUART0_MASK (0x3 << CMU_LFBPRESC0_LEUART0_SHIFT) +#define CMU_LFBPRESC0_LEUART0(v) \ + (((v) << CMU_LFBPRESC0_LEUART0_SHIFT) & CMU_LFBPRESC0_LEUART0_MASK) +#define CMU_LFBPRESC0_LEUART0_DIV1 CMU_LFBPRESC0_LEUART0(0) +#define CMU_LFBPRESC0_LEUART0_DIV2 CMU_LFBPRESC0_LEUART0(1) +#define CMU_LFBPRESC0_LEUART0_DIV4 CMU_LFBPRESC0_LEUART0(2) +#define CMU_LFBPRESC0_LEUART0_DIV8 CMU_LFBPRESC0_LEUART0(3) +#define CMU_LFBPRESC0_LEUART0_NODIV CMU_LFBPRESC0_LEUART0_DIV1 + +/* CMU_PCNTCTRL */ +#define CMU_PCNTCTRL_PCNT0CLKSEL (1 << 1) +#define CMU_PCNTCTRL_PCNT0CLKEN (1 << 0) + +/* CMU_ROUTE */ +#define CMU_ROUTE_LOCATION_SHIFT (2) +#define CMU_ROUTE_LOCATION_MASK (0x7 << CMU_ROUTE_LOCATION_SHIFT) +#define CMU_ROUTE_LOCATION_LOCx(i) \ + (((i) << CMU_ROUTE_LOCATION_SHIFT) & CMU_ROUTE_LOCATION_MASK) +#define CMU_ROUTE_LOCATION_LOC0 CMU_ROUTE_LOCATION_LOCx(0) +#define CMU_ROUTE_LOCATION_LOC1 CMU_ROUTE_LOCATION_LOCx(1) +#define CMU_ROUTE_LOCATION_LOC2 CMU_ROUTE_LOCATION_LOCx(2) +#define CMU_ROUTE_LOCATION_LOC3 CMU_ROUTE_LOCATION_LOCx(3) + +#define CMU_ROUTE_CLKOUT1PEN (1 << 1) +#define CMU_ROUTE_CLKOUT0PEN (1 << 0) + +/* CMU_LOCK */ +#define CMU_LOCK_LOCKKEY_SHIFT (0) +#define CMU_LOCK_LOCKKEY_MASK (0xFFFF << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_UNLOCKED (0x0000 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_LOCKED (0x0001 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_LOCK (0x0000 << CMU_LOCK_LOCKKEY_SHIFT) +#define CMU_LOCK_LOCKKEY_UNLOCK (0x580E << CMU_LOCK_LOCKKEY_SHIFT) + +/* CMU_USBCRCTRL */ +#define CMU_USBCRCTRL_LSMODE (1 << 1) +#define CMU_USBCRCTRL_EN (1 << 0) + +/* CMU_USHFRCOCTRL */ +/* Bits 31:20 - Reserved */ +#define CMU_USHFRCOCTRL_TIMEOUT_MASK (0xff << 12) +/* Bits 11:10 - Reserved */ +#define CMU_USHFRCOCTRL_SUSPEND (1 << 9) +#define CMU_USHFRCOCTRL_DITHEN (1 << 8) +/* Bit 7 - Reserved */ +#define CMU_USHFRCOCTRL_TUNING_MASK (0x7f << 0) + +/* CMU_USHFRCOTUNE */ +/* Bits 31:6 - Reserved */ +#define CMU_USHFRCOTUNE_FINETUNING_MASK (0x3f << 0) + +/* CMU_USHFRCOCONF */ +/* Bits 31:5 - Reserved */ +#define CMU_USHFRCOTUNE_USHFRCODIV2DIS (1 << 4) +/* Bit 3 - Reserved */ +#define CMU_USHFRCOCONF_BAND_MASK (0x7 << 0) +#define CMU_USHFRCOCONF_BAND_48MHZ (0x1 << 0) +#define CMU_USHFRCOCONF_BAND_24MHZ (0x3 << 0) + +#define _REG_BIT(base, bit) (((base) << 5) + (bit)) + +enum cmu_periph_clken { + /* CMU_PCNTCTRL */ + CMU_PCNT0 = _REG_BIT(0x078, 1), + + /* CMU_LFCCLKEN0 */ + CMU_USBLE = _REG_BIT(0x064, 0), + + /* CMU_LFBCLKEN0 */ + CMU_LEUART0 = _REG_BIT(0x060, 0), + + /* CMU_LFACLKEN0 */ + CMU_RTC = _REG_BIT(0x058, 0), + + /* CMU_HFPERCLKEN0 */ + CMU_I2C0 = _REG_BIT(0x044, 11), + CMU_ADC0 = _REG_BIT(0x044, 10), + CMU_VCMP = _REG_BIT(0x044, 9), + CMU_GPIO = _REG_BIT(0x044, 8), + CMU_IDAC0 = _REG_BIT(0x044, 7), + CMU_PRS = _REG_BIT(0x044, 6), + CMU_ACMP0 = _REG_BIT(0x044, 5), + CMU_USART1 = _REG_BIT(0x044, 4), + CMU_USART0 = _REG_BIT(0x044, 3), + CMU_TIMER2 = _REG_BIT(0x044, 2), + CMU_TIMER1 = _REG_BIT(0x044, 1), + CMU_TIMER0 = _REG_BIT(0x044, 0), + + /* CMU_HFCORECLKEN0 */ + CMU_USB = _REG_BIT(0x040, 4), + CMU_USBC = _REG_BIT(0x040, 3), + CMU_LE = _REG_BIT(0x040, 2), + CMU_DMA = _REG_BIT(0x040, 1) +}; + +enum cmu_osc { + HFRCO, /**< Internal, 1 - 28Mhz */ + LFRCO, /**< Internal, 32.768kHz */ + HFXO, /**< External, 4-48Mhz */ + LFXO, /**< External, 32.768kHz */ + AUXHFRCO, /**< Internal, 1-28Mhz */ + USHFRCO, /**< Internal, 48MHz */ +}; + +/* --- Function prototypes ------------------------------------------------- */ + +BEGIN_DECLS + +void cmu_enable_lock(void); +void cmu_disable_lock(void); +bool cmu_get_lock_flag(void); + +void cmu_periph_clock_enable(enum cmu_periph_clken periph); +void cmu_periph_clock_disable(enum cmu_periph_clken periph); + +/* TODO: CMU_CTRL, CMU_HFCORECLKDIV, CMU_HFPERCLKDIV, CMU_HFRCOCTRL, + * CMU_LFRCOCTRL, CMU_AUXHFRCOCTRL, CMU_CALCTRL, CMU_CALCNT */ + +void cmu_osc_on(enum cmu_osc osc); +void cmu_osc_off(enum cmu_osc osc); + +/* TODO: CMU_CMD, CMU_LFCLKSEL */ + +/* TODO: portions of CMU_STATUS */ +bool cmu_osc_ready_flag(enum cmu_osc osc); +void cmu_wait_for_osc_ready(enum cmu_osc osc); +void cmu_set_hfclk_source(enum cmu_osc osc); +enum cmu_osc cmu_get_hfclk_source(void); + +void cmu_set_usbclk_source(enum cmu_osc osc); +void cmu_wait_for_usbclk_selected(enum cmu_osc osc); + +/* TODO: CMU_IF, CMU_IFS, CMU_IFC, CMU_IEN */ + +/* TODO: CMU_SYNCBUSY, CMU_FREEZE, CMU_LFACLKEN0 */ + +/* TODO: CMU_LFAPRESC0, CMU_LFBPRESC0, CMU_PCNTCTRL, CMU_LCDCTRL, CMU_ROUTE */ + +END_DECLS + +#endif diff --git a/lib/efm32/hg/Makefile b/lib/efm32/hg/Makefile index 979ce439..634895e1 100644 --- a/lib/efm32/hg/Makefile +++ b/lib/efm32/hg/Makefile @@ -40,7 +40,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS) ARFLAGS = rcs -OBJS = gpio_common_hglg.o timer_common_hglg.o +OBJS = cmu.o gpio_common_hglg.o timer_common_hglg.o VPATH += ../../usb:../:../../cm3:../common diff --git a/lib/efm32/hg/cmu.c b/lib/efm32/hg/cmu.c new file mode 100644 index 00000000..db28680d --- /dev/null +++ b/lib/efm32/hg/cmu.c @@ -0,0 +1,290 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2015 Kuldeep Singh Dhaka + * Copyright (C) 2018 Seb Holzapfel + * + * 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 + +/** + * Enable CMU registers lock. + */ +void cmu_enable_lock(void) +{ + CMU_LOCK = CMU_LOCK_LOCKKEY_LOCK; +} + +/** + * Disable CMU registers lock + */ +void cmu_disable_lock(void) +{ + CMU_LOCK = CMU_LOCK_LOCKKEY_UNLOCK; +} + +/** + * Get CMU register lock flag + * @retval true if flag is set + * @retval false if flag is not set + */ +bool cmu_get_lock_flag(void) +{ + return (CMU_LOCK & CMU_LOCK_LOCKKEY_MASK) == CMU_LOCK_LOCKKEY_LOCKED; +} + +#define _CMU_REG(i) MMIO32(CMU_BASE + ((i) >> 5)) +#define _CMU_BIT(i) (1 << ((i) & 0x1f)) + +/** + * @brief Enable Peripheral Clock in running mode. + * + * Enable the clock on particular peripheral. + * + * @param[in] periph enum cmu_periph_clken Peripheral Name + * + * For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for + * example) + */ + +void cmu_periph_clock_enable(enum cmu_periph_clken clken) +{ + _CMU_REG(clken) |= _CMU_BIT(clken); +} + +/** + * @brief Disable Peripheral Clock in running mode. + * Disable the clock on particular peripheral. + * + * @param[in] periph enum cmu_periph_clken Peripheral Name + * + * For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for + * example) + */ + +void cmu_periph_clock_disable(enum cmu_periph_clken clken) +{ + _CMU_REG(clken) &= ~_CMU_BIT(clken); +} + +/** + * Turn on Oscillator + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_osc_on(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_HFRCOEN; + break; + case LFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN; + break; + case USHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_USHFRCOEN; + break; + case HFXO: + CMU_OSCENCMD = CMU_OSCENCMD_HFXOEN; + break; + case LFXO: + CMU_OSCENCMD = CMU_OSCENCMD_LFXOEN; + break; + case AUXHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN; + break; + } +} + +/** + * Turn off Oscillator + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_osc_off(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS; + break; + case LFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_LFRCODIS; + break; + case USHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_USHFRCODIS; + break; + case HFXO: + CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS; + break; + case LFXO: + CMU_OSCENCMD = CMU_OSCENCMD_LFXODIS; + break; + case AUXHFRCO: + CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCODIS; + break; + } +} + +/** + * Get Oscillator read flag + * @param[in] osc enum cmu_osc Oscillator name + * @retval true if flag is set + * @retval false if flag is not set + */ +bool cmu_osc_ready_flag(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + return (CMU_STATUS & CMU_STATUS_HFRCORDY) != 0; + break; + case LFRCO: + return (CMU_STATUS & CMU_STATUS_LFRCORDY) != 0; + break; + case USHFRCO: + return (CMU_STATUS & CMU_STATUS_USHFRCORDY) != 0; + break; + case HFXO: + return (CMU_STATUS & CMU_STATUS_HFXORDY) != 0; + break; + case LFXO: + return (CMU_STATUS & CMU_STATUS_LFXORDY) != 0; + break; + case AUXHFRCO: + return (CMU_STATUS & CMU_STATUS_AUXHFRCORDY) != 0; + break; + } + + return false; +} + +/** + * Wait while oscillator is not ready + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_wait_for_osc_ready(enum cmu_osc osc) +{ + switch (osc) { + case HFRCO: + while ((CMU_STATUS & CMU_STATUS_HFRCORDY) == 0); + break; + case LFRCO: + while ((CMU_STATUS & CMU_STATUS_LFRCORDY) == 0); + break; + case USHFRCO: + while ((CMU_STATUS & CMU_STATUS_USHFRCORDY) == 0); + break; + case HFXO: + while ((CMU_STATUS & CMU_STATUS_HFXORDY) == 0); + break; + case LFXO: + while ((CMU_STATUS & CMU_STATUS_LFXORDY) == 0); + break; + case AUXHFRCO: + while ((CMU_STATUS & CMU_STATUS_AUXHFRCORDY) == 0); + break; + } +} + +/** + * Set HFCLK clock source + * @param[in] osc enum cmu_osc Oscillator name + * @note calling cmu_set_hfclk_source() do not set source immediately, use + * @a cmu_get_hfclk_source() to verify that the source has been set. + * @see cmu_get_hfclk_source() + */ +void cmu_set_hfclk_source(enum cmu_osc osc) +{ + switch (osc) { + case HFXO: + CMU_CMD = CMU_CMD_HFCLKSEL_HFXO; + break; + case HFRCO: + CMU_CMD = CMU_CMD_HFCLKSEL_HFRCO; + break; + case LFXO: + CMU_CMD = CMU_CMD_HFCLKSEL_LFXO; + break; + case LFRCO: + CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO; + break; + default: + /* not applicable */ + return; + } +} + +/** + * Get HFCLK clock source + * @retval enum cmu_osc Oscillator name + */ +enum cmu_osc cmu_get_hfclk_source(void) +{ + uint32_t status = CMU_STATUS; + if (status & CMU_STATUS_LFXOSEL) { + return LFXO; + } else if (status & CMU_STATUS_LFRCOSEL) { + return LFRCO; + } else if (status & CMU_STATUS_HFXOSEL) { + return HFXO; + } else if (status & CMU_STATUS_HFRCOSEL) { + return HFRCO; + } + + /* never reached */ + return (enum cmu_osc) -1; +} + +/** + * Set USBCLK clock source + * @retval enum cmu_osc Oscillator name + */ +void cmu_set_usbclk_source(enum cmu_osc osc) +{ + switch (osc) { + case LFXO: + CMU_CMD = CMU_CMD_USBCCLKSEL_LFXO; + break; + case LFRCO: + CMU_CMD = CMU_CMD_USBCCLKSEL_LFRCO; + break; + case USHFRCO: + CMU_CMD = CMU_CMD_USBCCLKSEL_USHFRCO; + break; + default: + /* not applicable */ + return; + } +} + +/** + * Wait while USBCLK is not selected + * @param[in] osc enum cmu_osc Oscillator name + */ +void cmu_wait_for_usbclk_selected(enum cmu_osc osc) +{ + switch (osc) { + case LFXO: + while ((CMU_STATUS & CMU_STATUS_USBCLFXOSEL) == 0); + break; + case LFRCO: + while ((CMU_STATUS & CMU_STATUS_USBCLFRCOSEL) == 0); + break; + case USHFRCO: + while ((CMU_STATUS & CMU_STATUS_USBCUSHFRCOSEL) == 0); + break; + default: + /* not applicable */ + return; + } +}