diff --git a/arch/arm/src/max326xx/Make.defs b/arch/arm/src/max326xx/Make.defs index 9c9bed602c4..325b192b5da 100644 --- a/arch/arm/src/max326xx/Make.defs +++ b/arch/arm/src/max326xx/Make.defs @@ -40,14 +40,14 @@ HEAD_ASRC = CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S CMN_ASRCS += up_testset.S up_fetchadd.S vfork.S -CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c up_createstack.c -CMN_CSRCS += up_doirq.c up_exit.c up_hardfault.c up_initialize.c -CMN_CSRCS += up_initialstate.c up_interruptcontext.c up_mdelay.c -CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c -CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c -CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c -CMN_CSRCS += up_svcall.c up_trigger_irq.c up_unblocktask.c up_udelay.c -CMN_CSRCS += up_usestack.c up_vfork.c +CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copyfullstate.c +CMN_CSRCS += up_createstack.c up_doirq.c up_exit.c up_hardfault.c +CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c +CMN_CSRCS += up_mdelay.c up_memfault.c up_modifyreg8.c up_modifyreg16.c +CMN_CSRCS += up_modifyreg32.c up_releasepending.c up_releasestack.c +CMN_CSRCS += up_reprioritizertr.c up_schedulesigaction.c up_sigdeliver.c +CMN_CSRCS += up_stackframe.c up_svcall.c up_trigger_irq.c up_unblocktask.c +CMN_CSRCS += up_udelay.c up_usestack.c up_vfork.c ifeq ($(CONFIG_ARMV7M_LAZYFPU),y) CMN_ASRCS += up_lazyexception.S @@ -80,15 +80,14 @@ endif # Common MAX326XX Source Files CHIP_ASRCS = -CHIP_CSRCS = max326_start.c max326_clockconfig.c max326_irq.c max326_clrpend.c -CHIP_CSRCS += max326_allocateheap.c +CHIP_CSRCS = max326_start.c max326_irq.c max326_clrpend.c # Source Files for the MAX32620 and MAX32630 # Source Files for the MAX32660 ifeq ($(CONFIG_ARCH_FAMILY_MAX32660),y) -CHIP_CSRCS += max32660_lowputc.c max32660_gpio.c +CHIP_CSRCS += max32660_clockconfig.c max32660_lowputc.c max32660_gpio.c endif # Configuration-Dependent Source Files diff --git a/arch/arm/src/max326xx/chip/max326_flc.h b/arch/arm/src/max326xx/chip/max326_flc.h index 57b08e627e3..d0253707d3a 100644 --- a/arch/arm/src/max326xx/chip/max326_flc.h +++ b/arch/arm/src/max326xx/chip/max326_flc.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_flc.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_flc.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_gcr.h b/arch/arm/src/max326xx/chip/max326_gcr.h index 97b4e09520e..d14d48ccea8 100644 --- a/arch/arm/src/max326xx/chip/max326_gcr.h +++ b/arch/arm/src/max326xx/chip/max326_gcr.h @@ -126,6 +126,7 @@ #define GCR_CLKCTRL_X32KEN (1 << 17) /* Bit 17: 32.768kHz External Oscillator Enable */ #define GCR_CLKCTRL_HIRCEN (1 << 18) /* Bit 18: High-Frequency Internal Oscillator (HFIO) Enable */ #define GCR_CLKCTRL_X32KRDY (1 << 25) /* Bit 25: 32.768kHz External Oscillator Ready Status */ +#define GCR_CLKCTRL_HIRCRDY (1 << 26) /* Bit 26: High-Frequency Internal Oscillator Ready */ #define GCR_CLKCTRL_LIRC8KRDY (1 << 29) /* Bit 29: 8kHz Internal Oscillator Ready Status */ /* Power Management Register */ @@ -156,6 +157,8 @@ /* Memory Clock Control */ #define GCR_MEMCTRL_FWS_SHIFT (0) /* Bits 0-2: Flash Wait States */ +#define GCR_MEMCTRL_FWS_MASK (7 << GCR_MEMCTRL_FWS_SHIFT) +# define GCR_MEMCTRL_FWS(n) ((uint32_t)(n) << GCR_MEMCTRL_FWS_SHIFT) #define GCR_MEMCTRL_RAM0LS (1 << 8) /* Bit 8: System RAM 0 Light Sleep Enable */ #define GCR_MEMCTRL_RAM1LS (1 << 9) /* Bit 9: System RAM 1 Light Sleep Enable */ #define GCR_MEMCTRL_RAM2LS (1 << 10) /* Bit 10: System RAM 2 Light Sleep Enable */ diff --git a/arch/arm/src/max326xx/chip/max326_gpio.h b/arch/arm/src/max326xx/chip/max326_gpio.h index ee79ca05594..8e095116793 100644 --- a/arch/arm/src/max326xx/chip/max326_gpio.h +++ b/arch/arm/src/max326xx/chip/max326_gpio.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_gpio.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_gpio.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_memorymap.h b/arch/arm/src/max326xx/chip/max326_memorymap.h index 83fd5404c01..7896c7ae2d2 100644 --- a/arch/arm/src/max326xx/chip/max326_memorymap.h +++ b/arch/arm/src/max326xx/chip/max326_memorymap.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_memorymap.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_memorymap.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_pinmux.h b/arch/arm/src/max326xx/chip/max326_pinmux.h index 2cddc503a4b..a851dc5ba6e 100644 --- a/arch/arm/src/max326xx/chip/max326_pinmux.h +++ b/arch/arm/src/max326xx/chip/max326_pinmux.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_pinmux.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_pinmux.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_pwrseq.h b/arch/arm/src/max326xx/chip/max326_pwrseq.h index fd7821097a3..72af1557e68 100644 --- a/arch/arm/src/max326xx/chip/max326_pwrseq.h +++ b/arch/arm/src/max326xx/chip/max326_pwrseq.h @@ -75,6 +75,7 @@ * Enable for BACKUP Mode */ #define PWRSEQ_LPCTRL_OVR_SHIFT (4) /* Output Voltage Range */ #define PWRSEQ_LPCTRL_OVR_MASK (3 << PWRSEQ_LPCTRL_OVR_SHIFT) +# define PWRSEQ_LPCTRL_OVR(n) ((uint32_t)(n) << PWRSEQ_LPCTRL_OVR_SHIFT) # define PWRSEQ_LPCTRL_OVR_1p1V (2 << PWRSEQ_LPCTRL_OVR_SHIFT) /* VCORE=1.1V fINTCLK=96MHz */ # define PWRSEQ_LPCTRL_OVR_1p0V (1 << PWRSEQ_LPCTRL_OVR_SHIFT) /* VCORE=1.0V fINTCLK=48MHz */ # define PWRSEQ_LPCTRL_OVR_0p9V (0 << PWRSEQ_LPCTRL_OVR_SHIFT) /* VCORE=0.9V fINTCLK=24MHz */ diff --git a/arch/arm/src/max326xx/chip/max326_rtc.h b/arch/arm/src/max326xx/chip/max326_rtc.h index cac08c636d0..9ae7a502e5b 100644 --- a/arch/arm/src/max326xx/chip/max326_rtc.h +++ b/arch/arm/src/max326xx/chip/max326_rtc.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_rtc.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_rtc.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_tmr.h b/arch/arm/src/max326xx/chip/max326_tmr.h index 4378f75d3f8..0cb00b96f97 100644 --- a/arch/arm/src/max326xx/chip/max326_tmr.h +++ b/arch/arm/src/max326xx/chip/max326_tmr.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_tmr.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_tmr.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_uart.h b/arch/arm/src/max326xx/chip/max326_uart.h index 172860c0d65..062c525a97f 100644 --- a/arch/arm/src/max326xx/chip/max326_uart.h +++ b/arch/arm/src/max326xx/chip/max326_uart.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_uart.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_uart.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/chip/max326_wdt.h b/arch/arm/src/max326xx/chip/max326_wdt.h index 317848c5c46..5a4b414b5ee 100644 --- a/arch/arm/src/max326xx/chip/max326_wdt.h +++ b/arch/arm/src/max326xx/chip/max326_wdt.h @@ -44,7 +44,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "chip/max32620_30_wdt.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "chip/max32660_wdt.h" #else # error "Unsupported MAX326XX family" diff --git a/arch/arm/src/max326xx/common/max326_clrpend.c b/arch/arm/src/max326xx/common/max326_clrpend.c index ea16145ce1e..97583e9366f 100644 --- a/arch/arm/src/max326xx/common/max326_clrpend.c +++ b/arch/arm/src/max326xx/common/max326_clrpend.c @@ -73,7 +73,7 @@ void max326_clrpend(int irq) { putreg32(1 << (irq - MAX326_IRQ_EXTINT), NVIC_IRQ0_31_CLRPEND); } - else if (irq < MAX326_IRQ_NIRQS) + else if (irq < MAX326_IRQ_NVECTORS) { putreg32(1 << (irq - MAX326_IRQ_EXTINT - 32), NVIC_IRQ32_63_CLRPEND); } diff --git a/arch/arm/src/max326xx/common/max326_start.c b/arch/arm/src/max326xx/common/max326_start.c index ad5e0d436bc..eed79a82f98 100644 --- a/arch/arm/src/max326xx/common/max326_start.c +++ b/arch/arm/src/max326xx/common/max326_start.c @@ -71,17 +71,6 @@ # define showprogress(c) #endif -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/* This describes the initial PLL configuration */ - -static const struct clock_setup_s g_initial_clock_setup = -{ -#warning Missing logic -}; - /**************************************************************************** * Private Functions ****************************************************************************/ diff --git a/arch/arm/src/max326xx/max32660/max32660_clockconfig.c b/arch/arm/src/max326xx/max32660/max32660_clockconfig.c new file mode 100644 index 00000000000..09b23d5a8ae --- /dev/null +++ b/arch/arm/src/max326xx/max32660/max32660_clockconfig.c @@ -0,0 +1,585 @@ +/**************************************************************************** + * arch/arm/src/max32660/max326_clockconfig.c + * + * Copyright (C) 2018 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" + +#include "chip/max326_gcr.h" +#include "chip/max326_pwrseq.h" +#include "chip/max326_flc.h" +#include "max326_clockconfig.h" + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This describes the initial clock configuration. It is needed by + * max326_start.c + */ + +const struct clock_setup_s g_initial_clock_setup = +{ + .ovr = 2, /* Output voltage range for internal regulator */ + .clksrc = CLKSRC_HFIO, /* See enum clock_source_e. Determines Fsysosc */ + .psc = 0 /* System Oscillator Prescaler. Derives Fsysclk */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: max326_sysosc_frequency + * + * Description: + * Return the SYSOSC frequency. This is simply the frequency of the + * selected clock source. + * + ****************************************************************************/ + +static uint32_t max326_sysosc_frequency(void) +{ + uint32_t regval; + + /* The clock source is in the GCR_CLKCTRL:CLKCTRL field */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + switch ((regval & GCR_CLKCTRL_CLKSEL_MASK) >> GCR_CLKCTRL_CLKSEL_SHIFT) + { + default: + DEBUGPANIC(); + case CLKSRC_HFIO: + return max326_hfio_frequency(); + + case CLKSRC_8KHZ: + return 8000000; /* Nominally 8MHz */ + + case CLKSRC_32KHZ: + return 32768; + } +} + +/**************************************************************************** + * Name: max326_sysclk_frequency + * + * Description: + * Return the SYSCLK frequency. The SYSCLOCK is simply divided down from + * the SYSOSC. + * + ****************************************************************************/ + +static uint32_t max326_sysclk_frequency(void) +{ + uint32_t regval; + uint32_t psc; + + /* The divider is in the GCR_CLKCTRL:PSC setting: + * + * Fsysclk = Fsysclk / (2^psc) + */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + psc = (regval & GCR_CLKCTRL_PSC_MASK) >> GCR_CLKCTRL_PSC_SHIFT; + return max326_sysosc_frequency() >> psc; +} + +/**************************************************************************** + * Name: max326_select_hfio + * + * Description: + * Select the High-Frequency Internal Oscillator (HFIO) as the SYSOSC + * clock source. + * + ****************************************************************************/ + +static void max326_select_hfio(void) +{ + uint32_t regval; + + /* Enable the HFIO. */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval |= GCR_CLKCTRL_HIRCEN; + putreg32(regval, MAX326_GCR_CLKCTRL); + + /* Wait for the oscillator to become ready */ + + while ((getreg32(GCR_CLKCTRL_HIRCRDY) & GCR_CLKCTRL_HIRCRDY) == 0) + { + } + + /* Select the HIFO as the SYSOSC clock source. */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval &= ~GCR_CLKCTRL_CLKSEL_MASK; + regval |= GCR_CLKCTRL_CLKSEL_HIRC; + putreg32(regval, MAX326_GCR_CLKCTRL); +} + +/**************************************************************************** + * Name: max326_select_lirc8k + * + * Description: + * Select the 8kHz Internal Ultra-Low Power Nano-Ring Oscillator as the + * SYSOSC clock source. + * + ****************************************************************************/ + +static void max326_select_lirc8k(void) +{ + uint32_t regval; + + /* The 8kHz nano-ring oscillator is "always-on": "This oscillator is + * enabled at device powerup by hardware and cannot be disabled by + * application firmware. + */ + + /* Make sure that the oscillator is ready */ + + while ((getreg32(MAX326_GCR_CLKCTRL) & GCR_CLKCTRL_LIRC8KRDY) == 0) + { + } + + /* Select the 8kHz nano-ring oscillator as the SYSOSC clock source. */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval &= ~GCR_CLKCTRL_CLKSEL_MASK; + regval |= GCR_CLKCTRL_CLKSEL_LIRC8K; + putreg32(regval, MAX326_GCR_CLKCTRL); +} + +/**************************************************************************** + * Name: max326_select_x32k + * + * Description: + * Select the 32.768kHz External Crystal Oscillator as the SYSOSC clock + * source. + * + ****************************************************************************/ + +#ifdef BOARD_HAVE_X32K +static void max326_select_x32k(void) +{ + uint32_t regval; + + /* Enable the 32.768kHz external oscillator. */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval |= GCR_CLKCTRL_X32KEN; + putreg32(regval, MAX326_GCR_CLKCTRL); + + /* Wait for the oscillator to become ready */ + + while ((getreg32(MAX326_GCR_CLKCTRL) & GCR_CLKCTRL_X32KRDY) == 0) + { + } + + /* Select the 32.768kHz external oscillator as the SYSOSC clock + * source. + */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval &= ~GCR_CLKCTRL_CLKSEL_MASK; + regval |= GCR_CLKCTRL_CLKSEL_X32K; + putreg32(regval, MAX326_GCR_CLKCTRL); +} +#endif + +/**************************************************************************** + * Name: max326_set_ovr + * + * Description: + * Set the operating voltage range selection. If the OVR setting is + * different from the previous setting, then upon return, we will be + * running on either the 32.768kHz external oscillator or the 8kHz nano- + * ring oscillator with SYCLK prescaler == 0. + * + ****************************************************************************/ + +static void max326_set_ovr(FAR const struct clock_setup_s *clocksetup) +{ + uint32_t ovr; + uint32_t regval; + +#ifndef BOARD_HAVE_X32K + DEBUGASSERT(clocksetup->ovr != CLKSRC_32KHZ); +#endif + + /* First check of the OVR setting is being changed */ + + regval = getreg32(MAX326_PWRSEQ_LPCTRL); + ovr = (regval & PWRSEQ_LPCTRL_OVR_MASK) >> PWRSEQ_LPCTRL_OVR_SHIFT; + if (ovr != clocksetup->ovr) + { + /* Switch to the internal LDO for VCORE + * + * NOTE: "If using an external supply for VCORE, ensure the external + * supply is set to the same voltage as the current OVR setting. The + * external supply must be equal to or greater than the set OVR + * voltage." + */ + + regval &= ~PWRSEQ_LPCTRL_LDODIS; + putreg32(regval, MAX326_PWRSEQ_LPCTRL); + + /* Disable any SYSCLK divider */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval &= ~GCR_CLKCTRL_PSC_MASK; + putreg32(regval, MAX326_GCR_CLKCTRL); + +#ifdef BOARD_HAVE_X32K + /* Select the 32.768kHz External Crystal Oscillator as the SYSOSC + * clock source. + */ + + max326_select_x32k(); +#else + /* Select the 8kHz Internal Ultra-Low Power Nano-Ring Oscillator as + * the SYSOSC clock source. + */ + + max326_select_lirc8k(); +#endif + + /* Wait for SYSOSC to become ready */ + + while ((getreg32(MAX326_GCR_CLKCTRL) & GCR_CLKCTRL_CLKRDY) == 0) + { + } + + /* Change the OVR setting to the desired range */ + + regval = getreg32(MAX326_PWRSEQ_LPCTRL); + regval &= ~PWRSEQ_LPCTRL_OVR_MASK; + regval |= PWRSEQ_LPCTRL_OVR(clocksetup->ovr); + putreg32(regval, MAX326_PWRSEQ_LPCTRL); + } + + /* Set the Flash Low Voltage Enable according to the OVR setting */ + + regval = getreg32(MAX326_FLC_CTRL); + if (clocksetup->ovr < 2) + { + regval |= FLC_CTRL_LVE; + } + else + { + regval &= ~FLC_CTRL_LVE; + } + + putreg32(regval, MAX326_FLC_CTRL); +} + +/**************************************************************************** + * Name: max326_set_clksrc + * + * Description: + * Select the requested clock source. + * + ****************************************************************************/ + +static void max326_set_clksrc(FAR const struct clock_setup_s *clocksetup) +{ + uint32_t regval; + uint32_t clksrc; + + /* Set the system clock source if it is different from the currently + * selected clock source. + */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + clksrc = (regval & GCR_CLKCTRL_CLKSEL_MASK) >> GCR_CLKCTRL_CLKSEL_SHIFT; + + if (clksrc != clocksetup->clksrc) + { + /* Set the selected clock source */ + + switch (clocksetup->clksrc) + { + case CLKSRC_HFIO: /* High frequency internal oscillator */ + /* Select the High-Frequency Internal Oscillator (HFIO) as the + * SYSOSC clock source. + */ + + max326_select_hfio(); + break; + + case CLKSRC_8KHZ: /* 8kHz Internal Ultra-Low Power Nano-Ring Oscillator */ + /* Select the 8kHz Internal Ultra-Low Power Nano-Ring Oscillator + * as the SYSOSC clock source. + */ + + max326_select_lirc8k(); + break; + + case CLKSRC_32KHZ: /* 32.768kHz External Crystal Oscillator */ +#ifdef BOARD_HAVE_X32K + /* Select the 32.768kHz External Crystal Oscillator as the + * SYSOSC clock source. + */ + + max326_select_x32k(); + break; +#endif + + default: + DEBUGPANIC(); + return; + } + + /* Wait for SYSOSC to become ready */ + + while ((getreg32(MAX326_GCR_CLKCTRL) & GCR_CLKCTRL_CLKRDY) == 0) + { + } + } + + /* Set the SYSCLK prescaler */ + + regval = getreg32(MAX326_GCR_CLKCTRL); + regval &= ~GCR_CLKCTRL_PSC_MASK; + regval |= GCR_CLKCTRL_PSC(clocksetup->psc); + putreg32(regval, MAX326_GCR_CLKCTRL); +} + +/**************************************************************************** + * Name: max326_set_fwsdefault + * + * Description: + * Set the the FLASH wait states to the default value (5) + * + ****************************************************************************/ + +static void max326_set_fwsdefault(void) +{ + uint32_t regval; + + /* Set the number of Flash Wait States to the POR default value of 5. */ + + regval = getreg32(MAX326_GCR_MEMCTRL); + regval &= ~GCR_MEMCTRL_FWS_MASK; + regval |= GCR_MEMCTRL_FWS(5); + putreg32(regval, MAX326_GCR_MEMCTRL); +} + +/**************************************************************************** + * Name: max326_set_fws + * + * Description: + * Set an optimal value for the FLASH wait states. + * + ****************************************************************************/ + +static void max326_set_fws(void) +{ + uint32_t regval; + uint32_t sysclk; + uint32_t fws; + + /* Get the SYSCLK frequency */ + + sysclk = max326_sysclk_frequency(); + + /* Set the FLASH states according to the SYSCLK frequency. + * + * This does not quite match the settings in Table 4.2 of the User Guide. + * that table has 1 or 2 wait states at 24MHz and 2 or 3 wait states at + * 48MH. Perhaps there is more to the wait state calculations than raw + * SYSCLK frequency? + */ + + if (sysclk < 24000000) + { + fws = 1; + } + else if (sysclk < 48000000) + { + fws = 2; + } + else if (sysclk < 72000000) + { + fws = 3; + } + else if (sysclk <= 96000000) + { + fws = 4; + } + else + { + fws = 5; + } + + regval = getreg32(MAX326_GCR_MEMCTRL); + regval &= ~GCR_MEMCTRL_FWS_MASK; + regval |= GCR_MEMCTRL_FWS(fws); + putreg32(regval, MAX326_GCR_MEMCTRL); +} + +/**************************************************************************** + * Name: max326_periph_reset + * + * Description: + * Set an optimal value for the FLASH wait states. + * + ****************************************************************************/ + +static void max326_periph_reset(void) +{ + uint32_t regval; + + /* Initiate the peripheral reset */ + + regval = getreg32(MAX326_GCR_RST0); + regval |= GCR_RST0_PERIPH; + putreg32(regval, MAX326_GCR_RST0); + + /* Wait for the peripheral reset to complete */ + + while ((getreg32(MAX326_GCR_RST0) & GCR_RST0_PERIPH) != 0) + { + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: max326_clockconfig + * + * Description: + * Called to initialize the MAX3266xx. This does whatever setup is needed + * to put the MCU in a usable state. This includes the initialization of + * clocking using the settings in board.h. This function also performs + * other low-level chip as necessary. + * + *****************************************************************************/ + +void max326_clockconfig(FAR const struct clock_setup_s *clocksetup) +{ + /* Set the the FLASH wait states to the default value (5) */ + + max326_set_fwsdefault(); + + /* Set the operating voltage range selection. If the OVR setting is + * different from the previous setting, then upon return, we will be + * running on either the 32.768kHz external oscillator or the 8kHz nano- + * ring oscillator with SYCLK prescaler == 0. + */ + + max326_set_ovr(clocksetup); + + /* Select the requested clock source. */ + + max326_set_clksrc(clocksetup); + + /* Set an optimal value for the FLASH wait states */ + + max326_set_fws(); + + /* Perform a peripheral reset */ + + max326_periph_reset(); +} + +/**************************************************************************** + * Name: max326_hfio_frequency + * + * Description: + * Return the High-Frequency Internal Oscillator (HFIO) frequency. + * + *****************************************************************************/ + +uint32_t max326_hfio_frequency(void) +{ + uint32_t regval; + + /* The HFIO frequency depends of the PWRSEQ_LP_CTRL:OVR setting */ + + regval = getreg32(MAX326_PWRSEQ_LPCTRL); + switch ((regval & PWRSEQ_LPCTRL_OVR_MASK) >> PWRSEQ_LPCTRL_OVR_SHIFT) + { + case 0: + return 24000000; /* Nominally 24MHz */ + + case 1: + return 48000000; /* Nominally 48MHz */ + + default: + DEBUGPANIC(); + case 2: + return 96000000; /* Nominally 96MHz */ + } +} + +/**************************************************************************** + * Name: max326_cpu_frequency + * + * Description: + * Return the current CPU frequency. + * + *****************************************************************************/ + +uint32_t max326_cpu_frequency(void) +{ + return max326_sysclk_frequency(); +} + +/**************************************************************************** + * Name: max326_pclk_frequency + * + * Description: + * Return the current peripheral clock frequency. + * + *****************************************************************************/ + +uint32_t max326_pclk_frequency(void) +{ + /* Fpclk = Fsysclk / 2 */ + + return max326_sysclk_frequency() >> 1; +} diff --git a/arch/arm/src/max326xx/max32660/max32660_clockconfig.h b/arch/arm/src/max326xx/max32660/max32660_clockconfig.h index f482112d21d..587cf5bfa4c 100644 --- a/arch/arm/src/max326xx/max32660/max32660_clockconfig.h +++ b/arch/arm/src/max326xx/max32660/max32660_clockconfig.h @@ -60,7 +60,7 @@ enum clock_source_e /* This structure can be used to define a clock configuration. * * Fhfio Determined by Output Voltage Range. - * Fsysoc Determined by source clock selection. + * Fsysosc Determined by source clock selection. * Fsysclk = Fsysclk / (2^psc) * Fpclk = Fsysclk / 2 */ @@ -90,5 +90,4 @@ extern "C" } #endif -#endif /* __ASSEMBLY__ */ #endif /* __ARCH_ARM_SRC_MAX326XX_MAX_32660_MAX32660_CLOCKCONFIG_H */ diff --git a/arch/arm/src/max326xx/max326_clockconfig.h b/arch/arm/src/max326xx/max326_clockconfig.h index e235c0f92d8..5c760c670d1 100644 --- a/arch/arm/src/max326xx/max326_clockconfig.h +++ b/arch/arm/src/max326xx/max326_clockconfig.h @@ -51,7 +51,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "max32620_30/max32620_30_clockconfig.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "max32660/max32660_clockconfig.h" #else # error "Unsupported MAX326XX family" @@ -76,6 +76,16 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* This describes the initial clock configuration. g_initial_clock_setup + * must be provided by MCU-specific logic. + */ + +EXTERN const struct clock_setup_s g_initial_clock_setup; + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ @@ -89,7 +99,7 @@ extern "C" * clocking using the settings in board.h. This function also performs * other low-level chip as necessary. * - *****************************************************************************/ + ****************************************************************************/ void max326_clockconfig(FAR const struct clock_setup_s *clocksetup); @@ -99,7 +109,7 @@ void max326_clockconfig(FAR const struct clock_setup_s *clocksetup); * Description: * Return the High-Frequency Internal Oscillator (HFIO) frequency. * - *****************************************************************************/ + ****************************************************************************/ uint32_t max326_hfio_frequency(void); @@ -109,10 +119,20 @@ uint32_t max326_hfio_frequency(void); * Description: * Return the current CPU frequency. * - *****************************************************************************/ + ****************************************************************************/ uint32_t max326_cpu_frequency(void); +/**************************************************************************** + * Name: max326_pclk_frequency + * + * Description: + * Return the current peripheral clock frequency. + * + ****************************************************************************/ + +uint32_t max326_pclk_frequency(void); + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/max326xx/max326_gpio.h b/arch/arm/src/max326xx/max326_gpio.h index decaa3df9a6..ca3564861e0 100644 --- a/arch/arm/src/max326xx/max326_gpio.h +++ b/arch/arm/src/max326xx/max326_gpio.h @@ -55,7 +55,7 @@ #if defined(CONFIG_ARCH_FAMILY_MAX32620) || defined(CONFIG_ARCH_FAMILY_MAX32630) # include "max32620_30/max32620_30_gpio.h" -#if defined(CONFIG_ARCH_FAMILY_MAX32660) +#elif defined(CONFIG_ARCH_FAMILY_MAX32660) # include "max32660/max32660_gpio.h" #else # error "Unsupported MAX326XX family" diff --git a/configs/max32660-evsys/include/board.h b/configs/max32660-evsys/include/board.h index 7d96ebd7c28..b53e05d27e0 100644 --- a/configs/max32660-evsys/include/board.h +++ b/configs/max32660-evsys/include/board.h @@ -48,6 +48,8 @@ /* Clocking *****************************************************************/ +#define BOARD_HAVE_X32K 1 /* Have external 32.786KHz crystal oscialltor */ + /* LED definitions **********************************************************/ /* The MAX32660-EVSYS board has a single red LED is connected to GPIO P0.13