diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_pmc.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_pmc.h new file mode 100644 index 00000000000..fdf656f0721 --- /dev/null +++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_pmc.h @@ -0,0 +1,93 @@ +/********************************************************************************************* + * arch/arm/src/s32k1xx/chip/s32k1xx_pmc.h + * + * Copyright (C) 2019 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. + * + *********************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_PMC_H +#define __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_PMC_H + +/********************************************************************************************* + * Included Files + *********************************************************************************************/ + +#include +#include + +/********************************************************************************************* + * Pre-processor Definitions + *********************************************************************************************/ + +/* PMC Register Offsets **********************************************************************/ + +#define S32K1XX_PMC_LVDSC1_OFFSET 0x0000 /* Low Voltage Detect Status and Control 1 Register */ +#define S32K1XX_PMC_LVDSC2_OFFSET 0x0001 /* Low Voltage Detect Status and Control 2 Register */ +#define S32K1XX_PMC_REGSC_OFFSET 0x0002 /* Regulator Status and Control Register */ +#define S32K1XX_PMC_LPOTRIM_OFFSET 0x0004 /* Low Power Oscillator Trim Register */ + +/* PMC Register Addresses ********************************************************************/ + +#define S32K1XX_PMC_LVDSC1 (S32K1XX_PMC_BASE + S32K1XX_PMC_LVDSC1_OFFSET) +#define S32K1XX_PMC_LVDSC2 (S32K1XX_PMC_BASE + S32K1XX_PMC_LVDSC2_OFFSET) +#define S32K1XX_PMC_REGSC (S32K1XX_PMC_BASE + S32K1XX_PMC_REGSC_OFFSET) +#define S32K1XX_PMC_LPOTRIM (S32K1XX_PMC_BASE + S32K1XX_PMC_LPOTRIM_OFFSET) + +/* PMC Register Bitfield Definitions *********************************************************/ + +/* Low Voltage Detect Status and Control 1 Register */ + +#define PMC_LVDSC1_LVDRE (1 << 4) /* Bit 4: Low Voltage Detect Reset Enable */ +#define PMC_LVDSC1_LVDIE (1 << 5) /* Bit 5: Low Voltage Detect Interrupt Enable */ +#define PMC_LVDSC1_LVDACK (1 << 6) /* Bit 6: Low Voltage Detect Acknowledge */ +#define PMC_LVDSC1_LVDF (1 << 7) /* Bit 7: Low Voltage Detect Flag */ + +/* Low Voltage Detect Status and Control 2 Register */ + +#define PMC_LVDSC2_LVWIE (1 << 5) /* Bit 5: Low-Voltage Warning Interrupt Enable */ +#define PMC_LVDSC2_LVWACK (1 << 6) /* Bit 6: Low-Voltage Warning Acknowledge */ +#define PMC_LVDSC2_LVWF (1 << 7) /* Bit 7: Low-Voltage Warning Flag */ + +/* Regulator Status and Control Register */ + +#define PMC_REGSC_CLKBIASDIS (1 << 1) /* Bit 1: Clock Bias Disable Bit */ +#define PMC_REGSC_REGFPM (1 << 2) /* Bit 2: Regulator in Full Performance Mode Status Bit */ +#define PMC_REGSC_LPOSTAT (1 << 6) /* Bit 6: LPO Status Bit */ +#define PMC_REGSC_LPODIS (1 << 7) /* Bit 7: LPO Disable Bit */ + +/* Low Power Oscillator Trim Register */ + +#define PMC_LPOTRIM_MASK 0x0f /* Bits 0-3: LPOCLK trim value */ +# define PMC_LPOTRIM_LOWEST 0x80 /* Lowest value -16 */ +# define PMC_LPOTRIM_TYPICAL 0x00 /* Typical 0 (128 kHz) */ +# define PMC_LPOTRIM_HIGEST 0x7f /* Highest value 15 */ + +#endif /* __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_PMC_H */ diff --git a/arch/arm/src/s32k1xx/s32k14x/s32k14x_clrpend.c b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clrpend.c index a4cc44e4477..b8ba7cf5eb2 100644 --- a/arch/arm/src/s32k1xx/s32k14x/s32k14x_clrpend.c +++ b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clrpend.c @@ -70,13 +70,26 @@ void s32k14x_clrpend(int irq) if (irq >= S32K1XX_IRQ_EXTINT) { - if (irq < (S32K1XX_IRQ_EXTINT + 32)) + irq -= S32K1XX_IRQ_EXTINT; + if (irq < 32) { - putreg32(1 << (irq - S32K1XX_IRQ_EXTINT), NVIC_IRQ0_31_CLRPEND); + putreg32(1 << irq , NVIC_IRQ0_31_CLRPEND); + } + else if (irq < 64) + { + putreg32(1 << (irq - 32), NVIC_IRQ32_63_CLRPEND); + } + else if (irq < 96) + { + putreg32(1 << (irq - 64), NVIC_IRQ64_95_CLRPEND); + } + else if (irq < 128) + { + putreg32(1 << (irq - 96), NVIC_IRQ96_127_CLRPEND); } else if (irq < S32K1XX_IRQ_NIRQS) { - putreg32(1 << (irq - S32K1XX_IRQ_EXTINT - 32), NVIC_IRQ32_63_CLRPEND); + putreg32(1 << (irq - 128), NVIC_IRQ128_159_CLRPEND); } } } diff --git a/arch/arm/src/s32k1xx/s32k14x/s32k14x_irq.c b/arch/arm/src/s32k1xx/s32k14x/s32k14x_irq.c index 462d9df74ee..b3ecd5c6584 100644 --- a/arch/arm/src/s32k1xx/s32k14x/s32k14x_irq.c +++ b/arch/arm/src/s32k1xx/s32k14x/s32k14x_irq.c @@ -118,8 +118,11 @@ static void s32k14x_dumpnvic(const char *msg, int irq) getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); #endif - irqinfo(" IRQ ENABLE: %08x %08x\n", - getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE)); + irqinfo(" IRQ ENABLE: %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ0_31_ENABLE), getreg32(NVIC_IRQ32_63_ENABLE), + getreg32(NVIC_IRQ64_95_ENABLE), getreg32(NVIC_IRQ96_127_ENABLE)); + irqinfo(" %08x\n", + getreg32(NVIC_IRQ128_159_ENABLE)); irqinfo(" SYSH_PRIO: %08x %08x %08x\n", getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), getreg32(NVIC_SYSH12_15_PRIORITY)); @@ -132,9 +135,27 @@ static void s32k14x_dumpnvic(const char *msg, int irq) irqinfo(" %08x %08x %08x %08x\n", getreg32(NVIC_IRQ32_35_PRIORITY), getreg32(NVIC_IRQ36_39_PRIORITY), getreg32(NVIC_IRQ40_43_PRIORITY), getreg32(NVIC_IRQ44_47_PRIORITY)); - irqinfo(" %08x %08x %08x\n", + irqinfo(" %08x %08x %08x %08x\n", getreg32(NVIC_IRQ48_51_PRIORITY), getreg32(NVIC_IRQ52_55_PRIORITY), - getreg32(NVIC_IRQ56_59_PRIORITY)); + getreg32(NVIC_IRQ56_59_PRIORITY), getreg32(NVIC_IRQ60_63_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ64_67_PRIORITY), getreg32(NVIC_IRQ68_71_PRIORITY), + getreg32(NVIC_IRQ72_75_PRIORITY), getreg32(NVIC_IRQ76_79_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ80_83_PRIORITY), getreg32(NVIC_IRQ84_87_PRIORITY), + getreg32(NVIC_IRQ88_91_PRIORITY), getreg32(NVIC_IRQ92_95_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ96_99_PRIORITY), getreg32(NVIC_IRQ100_103_PRIORITY), + getreg32(NVIC_IRQ104_107_PRIORITY), getreg32(NVIC_IRQ108_111_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ112_115_PRIORITY), getreg32(NVIC_IRQ116_119_PRIORITY), + getreg32(NVIC_IRQ120_123_PRIORITY), getreg32(NVIC_IRQ124_127_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ128_131_PRIORITY), getreg32(NVIC_IRQ132_135_PRIORITY), + getreg32(NVIC_IRQ136_139_PRIORITY), getreg32(NVIC_IRQ140_143_PRIORITY)); + irqinfo(" %08x %08x %08x %08x\n", + getreg32(NVIC_IRQ144_147_PRIORITY), getreg32(NVIC_IRQ148_151_PRIORITY), + getreg32(NVIC_IRQ152_155_PRIORITY), getreg32(NVIC_IRQ156_159_PRIORITY)); leave_critical_section(flags); } diff --git a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c index 0d6f61fdadc..b835bd18261 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c +++ b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c @@ -69,6 +69,7 @@ #include "hardware/s32k1xx_scg.h" #include "hardware/s32k1xx_smc.h" +#include "hardware/s32k1xx_pmc.h" #include "s32k1xx_clockconfig.h" #include /* Include last. May have dependencies */ @@ -1269,7 +1270,7 @@ static int s32k1xx_configure_scgmodules(const struct scg_config_s *scgcfg) } /**************************************************************************** - * Name: s32k1xx_scgconfig + * Name: s32k1xx_scg_config * * Description: * Configure SCG clocking. @@ -1283,7 +1284,7 @@ static int s32k1xx_configure_scgmodules(const struct scg_config_s *scgcfg) * *****************************************************************************/ -static int s32k1xx_scgconfig(const struct scg_config_s *scgcfg) +static int s32k1xx_scg_config(const struct scg_config_s *scgcfg) { uint32_t regval; int ret = OK; @@ -1353,7 +1354,7 @@ static int s32k1xx_scgconfig(const struct scg_config_s *scgcfg) } /**************************************************************************** - * Name: s32k1xx_pccconfig + * Name: s32k1xx_pcc_config * * Description: * Configure PCC clocking. @@ -1366,13 +1367,13 @@ static int s32k1xx_scgconfig(const struct scg_config_s *scgcfg) * *****************************************************************************/ -static void s32k1xx_pccconfig(const struct pcc_config_s *pcccfg) +static void s32k1xx_pcc_config(const struct pcc_config_s *pcccfg) { #warning Missing logic } /**************************************************************************** - * Name: s32k1xx_simconfig + * Name: s32k1xx_sim_config * * Description: * Configure PCC clocking. @@ -1385,13 +1386,13 @@ static void s32k1xx_pccconfig(const struct pcc_config_s *pcccfg) * *****************************************************************************/ -static void s32k1xx_simconfig(const struct sim_clock_config_s *simcfg) +static void s32k1xx_sim_config(const struct sim_clock_config_s *simcfg) { #warning Missing logic } /**************************************************************************** - * Name: s32k1xx_pmcconfig + * Name: s32k1xx_pmc_config * * Description: * Configure PMC clocking. @@ -1404,9 +1405,35 @@ static void s32k1xx_simconfig(const struct sim_clock_config_s *simcfg) * *****************************************************************************/ -static void s32k1xx_pmcconfig(const struct pmc_config_s *pmccfg) +static void s32k1xx_pmc_config(const struct pmc_config_s *pmccfg) { -#warning Missing logic + uint8_t regval; + + DEBUGASSERT(pmccfg != NULL); + + /* Low Power Clock settings from PMC. */ + + if (pmccfg->lpoclk.initialize) + { + /* Enable/disable the low power oscillator. */ + + regval = getreg8(S32K1XX_PMC_REGSC); + + if (pmccfg->lpoclk.enable) + { + regval &= ~PMC_REGSC_LPODIS; + } + else + { + regval |= PMC_REGSC_LPODIS; + } + + putreg8(regval, S32K1XX_PMC_REGSC); + + /* Write trimming value. */ + + putreg8(pmccfg->lpoclk.trim & PMC_LPOTRIM_MASK, S32K1XX_PMC_LPOTRIM); + } } /**************************************************************************** @@ -1439,20 +1466,20 @@ int s32k1xx_clockconfig(const struct clock_configuration_s *clkcfg) /* Set SCG configuration */ - ret = s32k1xx_scgconfig(&clkcfg->scg); + ret = s32k1xx_scg_config(&clkcfg->scg); if (ret >= 0) { /* Set PCC configuration */ - s32k1xx_pccconfig(&clkcfg->pcc); + s32k1xx_pcc_config(&clkcfg->pcc); /* Set SIM configuration */ - s32k1xx_simconfig(&clkcfg->sim); + s32k1xx_sim_config(&clkcfg->sim); /* Set PMC configuration */ - s32k1xx_pmcconfig(&clkcfg->pmc); + s32k1xx_pmc_config(&clkcfg->pmc); } return ret;