From be55a6542f8b335f07ad06a7fdee0ff6831cae35 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 17 Aug 2019 14:36:40 -0600 Subject: [PATCH] Squashed commit of the following: arch/arm/src/s32k1xx/: Add logic to look up the peripheral clock frequency. Fix baud calcuation logic in s32k1xx_lowputc.c: In no longer tries to enable clocking. That must be done with board logic. Now gets the peripheral functional clock frequency to determine the baud rate. arch/arm/src/s32k1xx: Add peripheral feature arrays. --- arch/arm/src/s32k1xx/s32k11x/Make.defs | 2 +- .../s32k1xx/s32k11x/s32k11x_clockmapping.c | 24 +- .../s32k1xx/s32k11x/s32k11x_periphfeatures.c | 127 +++++++++++ .../s32k1xx/s32k14x/s32k14x_clockmapping.c | 126 ++++++----- .../s32k1xx/s32k14x/s32k14x_periphfeatures.c | 149 +++++++++++++ arch/arm/src/s32k1xx/s32k1xx_clockconfig.c | 206 +++++++++++++++++- arch/arm/src/s32k1xx/s32k1xx_clockconfig.h | 64 +++++- arch/arm/src/s32k1xx/s32k1xx_lowputc.c | 139 +++++------- arch/arm/src/s32k1xx/s32k1xx_periphclocks.c | 198 ++++++++++++++++- arch/arm/src/s32k1xx/s32k1xx_periphclocks.h | 188 +++++++++------- 10 files changed, 982 insertions(+), 241 deletions(-) create mode 100644 arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c create mode 100644 arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c diff --git a/arch/arm/src/s32k1xx/s32k11x/Make.defs b/arch/arm/src/s32k1xx/s32k11x/Make.defs index fe7fedd740..82b79dff7e 100644 --- a/arch/arm/src/s32k1xx/s32k11x/Make.defs +++ b/arch/arm/src/s32k1xx/s32k11x/Make.defs @@ -55,7 +55,7 @@ endif # Source file specific to the S32k11x family -CHIP_CSRCS += s32k11x_irq.c s32k11x_clockmapping.c +CHIP_CSRCS += s32k11x_irq.c s32k11x_clockmapping.c s32k11x_periphfeatures.c # Configuration-dependent S32k11x files diff --git a/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c b/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c index e2651dbf2c..b028c65aeb 100644 --- a/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c +++ b/arch/arm/src/s32k1xx/s32k11x/s32k11x_clockmapping.c @@ -62,7 +62,7 @@ const uint16_t g_clkname_mapping[] = PCC_INVALID_INDEX, /* SIRC clock 4 */ PCC_INVALID_INDEX, /* FIRC clock 5 */ PCC_INVALID_INDEX, /* SOSC clock 6 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 7 */ + PCC_INVALID_INDEX, /* No clock entry 7 */ PCC_INVALID_INDEX, /* RTC_CLKIN clock 8 */ PCC_INVALID_INDEX, /* SCG CLK_OUT clock 9 */ PCC_INVALID_INDEX, /* SIRCDIV1 functional clock 10 */ @@ -71,11 +71,11 @@ const uint16_t g_clkname_mapping[] = PCC_INVALID_INDEX, /* FIRCDIV2 functional clock 13 */ PCC_INVALID_INDEX, /* SOSCDIV1 functional clock 14 */ PCC_INVALID_INDEX, /* SOSCDIV2 functional clock 15 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 16 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 17 */ + PCC_INVALID_INDEX, /* No clock entry 16 */ + PCC_INVALID_INDEX, /* No clock entry 17 */ PCC_INVALID_INDEX, /* End of SCG clocks 18 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 19 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 20 */ + PCC_INVALID_INDEX, /* No clock entry 19 */ + PCC_INVALID_INDEX, /* No clock entry 20 */ PCC_INVALID_INDEX, /* FTM0 External Clock Pin Select 21 */ PCC_INVALID_INDEX, /* FTM1 External Clock Pin Select 22 */ PCC_INVALID_INDEX, /* CLKOUT Select 23 */ @@ -89,13 +89,13 @@ const uint16_t g_clkname_mapping[] = PCC_INVALID_INDEX, /* DMA clock source 31 */ PCC_INVALID_INDEX, /* MPU clock source 32 */ PCC_INVALID_INDEX, /* MSCM clock source 33 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 34 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 35 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 36 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 37 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 38 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 39 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 40 */ + PCC_INVALID_INDEX, /* No clock entry 34 */ + PCC_INVALID_INDEX, /* No clock entry 35 */ + PCC_INVALID_INDEX, /* No clock entry 36 */ + PCC_INVALID_INDEX, /* No clock entry 37 */ + PCC_INVALID_INDEX, /* No clock entry 38 */ + PCC_INVALID_INDEX, /* No clock entry 39 */ + PCC_INVALID_INDEX, /* No clock entry 40 */ PCC_CMP0_INDEX, /* CMP0 clock source 41 */ PCC_CRC_INDEX, /* CRC clock source 42 */ PCC_DMAMUX_INDEX, /* DMAMUX clock source 43 */ diff --git a/arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c b/arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c new file mode 100644 index 0000000000..08c2b35a8e --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c @@ -0,0 +1,127 @@ +/******************************************************************************************************************************************** + * arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c + * + * 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. + * + ********************************************************************************************************************************************/ + +/******************************************************************************************************************************************** + * Included Files + ********************************************************************************************************************************************/ + +#include + +#include "s32k1xx_periphclocks.h" + +/**************************************************************************** + * Public Data + ********************************************************************************************************************************************/ + +/* Peripheral Features. + * + * Each S32K1xx architecture must provide this array. This is an array of + * bit-encoded peripheral clocking features. See the peripheral instance + * feature definitions above + */ + +const uint8_t g_periph_features[] = +{ + (NO_PERIPHERAL_FEATURE), /* Core clock 0 */ + (NO_PERIPHERAL_FEATURE), /* Bus clock 1 */ + (NO_PERIPHERAL_FEATURE), /* Slow clock 2 */ + (NO_PERIPHERAL_FEATURE), /* CLKOUT clock 3 */ + (NO_PERIPHERAL_FEATURE), /* SIRC clock 4 */ + (NO_PERIPHERAL_FEATURE), /* FIRC clock 5 */ + (NO_PERIPHERAL_FEATURE), /* SOSC clock 6 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 7 */ + (NO_PERIPHERAL_FEATURE), /* RTC_CLKIN clock 8 */ + (NO_PERIPHERAL_FEATURE), /* SCG CLK_OUT clock 9 */ + (NO_PERIPHERAL_FEATURE), /* End of SCG clocks 10 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 11 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 12 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 13 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 14 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 15 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 16 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 17 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 18 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 19 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 20 */ + (NO_PERIPHERAL_FEATURE), /* FTM0 External Clock Pin Select 21 */ + (NO_PERIPHERAL_FEATURE), /* FTM1 External Clock Pin Select 22 */ + (NO_PERIPHERAL_FEATURE), /* CLKOUT Select 23 */ + (NO_PERIPHERAL_FEATURE), /* CLK32K clock 24 */ + (NO_PERIPHERAL_FEATURE), /* LPO clock 25 */ + (NO_PERIPHERAL_FEATURE), /* LPO 1KHz clock 26 */ + (NO_PERIPHERAL_FEATURE), /* LPO 32KHz clock 27 */ + (NO_PERIPHERAL_FEATURE), /* LPO 128KHz clock 28 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* EIM clock source 29 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* ERM clock source 30 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* DMA clock source 31 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* MPU clock source 32 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* MSCM clock source 33 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 34 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 35 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 36 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 37 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 38 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 39 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 40 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* CMP0 clock source 41 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* CRC clock source 42 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* DMAMUX clock source 43 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTA clock source 44 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTB clock source 45 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTC clock source 46 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTD clock source 47 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTE clock source 48 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* RTC clock source 49 */ + (NO_PERIPHERAL_FEATURE), /* End of BUS clocks 50 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FlexCAN0 clock source 51 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* PDB0 clock source 52 */ + (NO_PERIPHERAL_FEATURE), /* End of SYS clocks 53 */ + (HAS_INT_CLOCK_FROM_SLOW_CLOCK), /* FTFC clock source 54 */ + (NO_PERIPHERAL_FEATURE), /* End of SLOW clocks 55 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM0 clock source 56 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM1 clock source 57 */ + (NO_PERIPHERAL_FEATURE), /* End of ASYNCH DIV1 clocks 58 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* ADC0 clock source 59 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* FLEXIO clock source 60 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPI2C0 clock source 61 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPIT clock source 62 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPSPI0 clock source 63 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPSPI1 clock source 64 */ + (HAS_MULTIPLIER | HAS_DIVIDER | HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPTMR0 clock source 65 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPUART0 clock source 66 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPUART1 clock source 67 */ + (NO_PERIPHERAL_FEATURE), /* End of ASYNCH DIV2 clocks 68 */ + (NO_PERIPHERAL_FEATURE) /* End of PCC clocks 69 */ +}; diff --git a/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c index 30bc49aafe..3d1a24102e 100644 --- a/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c +++ b/arch/arm/src/s32k1xx/s32k14x/s32k14x_clockmapping.c @@ -62,7 +62,7 @@ const uint16_t g_clkname_mapping[] = PCC_INVALID_INDEX, /* SIRC clock 4 */ PCC_INVALID_INDEX, /* FIRC clock 5 */ PCC_INVALID_INDEX, /* SOSC clock 6 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 7 */ + PCC_INVALID_INDEX, /* SPLL clock 7 */ PCC_INVALID_INDEX, /* RTC_CLKIN clock 8 */ PCC_INVALID_INDEX, /* SCG CLK_OUT clock 9 */ PCC_INVALID_INDEX, /* SIRCDIV1 functional clock 10 */ @@ -71,58 +71,80 @@ const uint16_t g_clkname_mapping[] = PCC_INVALID_INDEX, /* FIRCDIV2 functional clock 13 */ PCC_INVALID_INDEX, /* SOSCDIV1 functional clock 14 */ PCC_INVALID_INDEX, /* SOSCDIV2 functional clock 15 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 16 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 17 */ + PCC_INVALID_INDEX, /* SPLLDIV1 functional clock 16 */ + PCC_INVALID_INDEX, /* SPLLDIV2 functional clock 17 */ PCC_INVALID_INDEX, /* End of SCG clocks 18 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 19 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 20 */ + PCC_INVALID_INDEX, /* No clock entry 19 */ + PCC_INVALID_INDEX, /* No clock entry 20 */ PCC_INVALID_INDEX, /* FTM0 External Clock Pin Select 21 */ PCC_INVALID_INDEX, /* FTM1 External Clock Pin Select 22 */ - PCC_INVALID_INDEX, /* CLKOUT Select 23 */ - PCC_INVALID_INDEX, /* CLK32K clock 24 */ - PCC_INVALID_INDEX, /* LPO clock 25 */ - PCC_INVALID_INDEX, /* LPO 1KHz clock 26 */ - PCC_INVALID_INDEX, /* LPO 32KHz clock 27 */ - PCC_INVALID_INDEX, /* LPO 128KHz clock 28 */ - PCC_INVALID_INDEX, /* EIM clock source 29 */ - PCC_INVALID_INDEX, /* ERM clock source 30 */ - PCC_INVALID_INDEX, /* DMA clock source 31 */ - PCC_INVALID_INDEX, /* MPU clock source 32 */ - PCC_INVALID_INDEX, /* MSCM clock source 33 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 34 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 35 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 36 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 37 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 38 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 39 */ - PCC_INVALID_INDEX, /* No clock entry in clock_names_t 40 */ - PCC_CMP0_INDEX, /* CMP0 clock source 41 */ - PCC_CRC_INDEX, /* CRC clock source 42 */ - PCC_DMAMUX_INDEX, /* DMAMUX clock source 43 */ - PCC_PORTA_INDEX, /* PORTA clock source 44 */ - PCC_PORTB_INDEX, /* PORTB clock source 45 */ - PCC_PORTC_INDEX, /* PORTC clock source 46 */ - PCC_PORTD_INDEX, /* PORTD clock source 47 */ - PCC_PORTE_INDEX, /* PORTE clock source 48 */ - PCC_RTC_INDEX, /* RTC clock source 49 */ - PCC_INVALID_INDEX, /* End of BUS clocks 50 */ - PCC_FLEXCAN0_INDEX, /* FlexCAN0 clock source 51 */ - PCC_PDB0_INDEX, /* PDB0 clock source 52 */ - PCC_INVALID_INDEX, /* End of SYS clocks 53 */ - PCC_FTFC_INDEX, /* FTFC clock source 54 */ - PCC_INVALID_INDEX, /* End of SLOW clocks 55 */ - PCC_FTM0_INDEX, /* FTM0 clock source 56 */ - PCC_FTM1_INDEX, /* FTM1 clock source 57 */ - PCC_INVALID_INDEX, /* End of ASYNCH DIV1 clocks 58 */ - PCC_ADC0_INDEX, /* ADC0 clock source 59 */ - PCC_FLEXIO_INDEX, /* FlexIO clock source 60 */ - PCC_LPI2C0_INDEX, /* LPI2C0 clock source 61 */ - PCC_LPIT_INDEX, /* LPIT clock source 62 */ - PCC_LPSPI0_INDEX, /* LPSPI0 clock source 63 */ - PCC_LPSPI1_INDEX, /* LPSPI1 clock source 64 */ - PCC_LPTMR0_INDEX, /* LPTMR0 clock source 65 */ - PCC_LPUART0_INDEX, /* LPUART0 clock source 66 */ - PCC_LPUART1_INDEX, /* LPUART1 clock source 67 */ - PCC_INVALID_INDEX, /* End of ASYNCH DIV2 clocks 68 */ - PCC_INVALID_INDEX, /* End of PCC clocks 69 */ + PCC_INVALID_INDEX, /* FTM2 External Clock Pin Select 23 */ + PCC_INVALID_INDEX, /* FTM3 External Clock Pin Select 24 */ + PCC_INVALID_INDEX, /* FTM4 External Clock Pin Select 25 */ + PCC_INVALID_INDEX, /* FTM5 External Clock Pin Select 26 */ + PCC_INVALID_INDEX, /* FTM6 External Clock Pin Select 27 */ + PCC_INVALID_INDEX, /* FTM7 External Clock Pin Select 28 */ + PCC_INVALID_INDEX, /* CLKOUT Select 29 */ + PCC_INVALID_INDEX, /* CLK32K clock 30 */ + PCC_INVALID_INDEX, /* LPO clock 31 */ + PCC_INVALID_INDEX, /* LPO 1KHz clock 32 */ + PCC_INVALID_INDEX, /* LPO 32KHz clock 33 */ + PCC_INVALID_INDEX, /* LPO 128KHz clock 34 */ + PCC_INVALID_INDEX, /* EIM clock source 35 */ + PCC_INVALID_INDEX, /* ERM clock source 36 */ + PCC_INVALID_INDEX, /* DMA clock source 37 */ + PCC_INVALID_INDEX, /* MPU clock source 38 */ + PCC_INVALID_INDEX, /* MSCM clock source 39 */ + PCC_INVALID_INDEX, /* QSPI module SFIF clock source 40 */ + PCC_INVALID_INDEX, /* QSPI module clock source 41 */ + PCC_INVALID_INDEX, /* QSPI module clock source SFIF 42 */ + PCC_INVALID_INDEX, /* QSPI module clock source 2XSFIF 43 */ + PCC_INVALID_INDEX, /* No clock entry 44 */ + PCC_CMP0_INDEX, /* CMP0 clock source 45 */ + PCC_CRC_INDEX, /* CRC clock source 46 */ + PCC_DMAMUX_INDEX, /* DMAMUX clock source 47 */ + PCC_EWM_INDEX, /* EWM clock source 48 */ + PCC_PORTA_INDEX, /* PORTA clock source 49 */ + PCC_PORTB_INDEX, /* PORTB clock source 50 */ + PCC_PORTC_INDEX, /* PORTC clock source 51 */ + PCC_PORTD_INDEX, /* PORTD clock source 52 */ + PCC_PORTE_INDEX, /* PORTE clock source 53 */ + PCC_RTC_INDEX, /* RTC clock source 54 */ + PCC_SAI0_INDEX, /* SAI0 clock source 55 */ + PCC_SAI1_INDEX, /* SAI1 clock source 56 */ + PCC_INVALID_INDEX, /* End of BUS clocks 57 */ + PCC_FLEXCAN0_INDEX, /* FlexCAN0 clock source 58 */ + PCC_FLEXCAN1_INDEX, /* FlexCAN1 clock source 59 */ + PCC_FLEXCAN2_INDEX, /* FlexCAN2 clock source 60 */ + PCC_PDB0_INDEX, /* PDB0 clock source 61 */ + PCC_PDB1_INDEX, /* PDB1 clock source 62 */ + PCC_INVALID_INDEX, /* End of SYS clocks 63 */ + PCC_FTFC_INDEX, /* FTFC clock source 64 */ + PCC_INVALID_INDEX, /* End of SLOW clocks 65 */ + PCC_ENET_INDEX, /* ENET clock source 66 */ + PCC_FTM0_INDEX, /* FTM0 clock source 67 */ + PCC_FTM1_INDEX, /* FTM1 clock source 68 */ + PCC_FTM2_INDEX, /* FTM2 clock source 69 */ + PCC_FTM3_INDEX, /* FTM3 clock source 70 */ + PCC_FTM4_INDEX, /* FTM4 clock source 71 */ + PCC_FTM5_INDEX, /* FTM5 clock source 72 */ + PCC_FTM6_INDEX, /* FTM6 clock source 73 */ + PCC_FTM7_INDEX, /* FTM7 clock source 74 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV1 clocks 75 */ + PCC_ADC0_INDEX, /* ADC0 clock source 76 */ + PCC_ADC1_INDEX, /* ADC1 clock source 77 */ + PCC_FLEXIO_INDEX, /* FLEXIO clock source 78 */ + PCC_LPI2C0_INDEX, /* LPI2C0 clock source 79 */ + PCC_LPI2C1_INDEX, /* LPI2C1 clock source 80 */ + PCC_LPIT_INDEX, /* LPIT clock source 81 */ + PCC_LPSPI0_INDEX, /* LPSPI0 clock source 82 */ + PCC_LPSPI1_INDEX, /* LPSPI1 clock source 83 */ + PCC_LPSPI2_INDEX, /* LPSPI2 clock source 84 */ + PCC_LPTMR0_INDEX, /* LPTMR0 clock source 85 */ + PCC_LPUART0_INDEX, /* LPUART0 clock source 86 */ + PCC_LPUART1_INDEX, /* LPUART1 clock source 87 */ + PCC_LPUART2_INDEX, /* LPUART2 clock source 88 */ + PCC_QSPI_INDEX, /* QSPI clock source 89 */ + PCC_INVALID_INDEX, /* End of ASYNCH DIV2 clocks 90 */ + PCC_INVALID_INDEX /* End of PCC clocks 91 */ }; diff --git a/arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c b/arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c new file mode 100644 index 0000000000..0380b04dea --- /dev/null +++ b/arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c @@ -0,0 +1,149 @@ +/******************************************************************************************************************************************** + * arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c + * + * 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. + * + ********************************************************************************************************************************************/ + +/******************************************************************************************************************************************** + * Included Files + ********************************************************************************************************************************************/ + +#include + +#include "s32k1xx_periphclocks.h" + +/**************************************************************************** + * Public Data + ********************************************************************************************************************************************/ + +/* Peripheral Features. + * + * Each S32K1xx architecture must provide this array. This is an array of + * bit-encoded peripheral clocking features. See the peripheral instance + * feature definitions above + */ + +const uint8_t g_periph_features[] = +{ + (NO_PERIPHERAL_FEATURE), /* Core clock 0 */ + (NO_PERIPHERAL_FEATURE), /* Bus clock 1 */ + (NO_PERIPHERAL_FEATURE), /* Slow clock 2 */ + (NO_PERIPHERAL_FEATURE), /* CLKOUT clock 3 */ + (NO_PERIPHERAL_FEATURE), /* SIRC clock 4 */ + (NO_PERIPHERAL_FEATURE), /* FIRC clock 5 */ + (NO_PERIPHERAL_FEATURE), /* SOSC clock 6 */ + (NO_PERIPHERAL_FEATURE), /* SPLL clock 7 */ + (NO_PERIPHERAL_FEATURE), /* RTC_CLKIN clock 8 */ + (NO_PERIPHERAL_FEATURE), /* SCG CLK_OUT clock 9 */ + (NO_PERIPHERAL_FEATURE), /* End of SCG clocks 10 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 11 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 12 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 13 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 14 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 15 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 16 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 17 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 18 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 19 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 20 */ + (NO_PERIPHERAL_FEATURE), /* FTM0 External Clock Pin Select 21 */ + (NO_PERIPHERAL_FEATURE), /* FTM1 External Clock Pin Select 22 */ + (NO_PERIPHERAL_FEATURE), /* FTM2 External Clock Pin Select 23 */ + (NO_PERIPHERAL_FEATURE), /* FTM3 External Clock Pin Select 24 */ + (NO_PERIPHERAL_FEATURE), /* FTM4 External Clock Pin Select 25 */ + (NO_PERIPHERAL_FEATURE), /* FTM5 External Clock Pin Select 26 */ + (NO_PERIPHERAL_FEATURE), /* FTM6 External Clock Pin Select 27 */ + (NO_PERIPHERAL_FEATURE), /* FTM7 External Clock Pin Select 28 */ + (NO_PERIPHERAL_FEATURE), /* CLKOUT Select 29 */ + (NO_PERIPHERAL_FEATURE), /* CLK32K clock 30 */ + (NO_PERIPHERAL_FEATURE), /* LPO clock 31 */ + (NO_PERIPHERAL_FEATURE), /* LPO 1KHz clock 32 */ + (NO_PERIPHERAL_FEATURE), /* LPO 32KHz clock 33 */ + (NO_PERIPHERAL_FEATURE), /* LPO 128KHz clock 34 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* EIM clock source 35 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* ERM clock source 36 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* DMA clock source 37 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* MPU clock source 38 */ + (HAS_CLOCK_GATING_IN_SIM | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* MSCM clock source 39 */ + (NO_PERIPHERAL_FEATURE), /* QSPI module SFIF clock source 40 */ + (NO_PERIPHERAL_FEATURE), /* QSPI module clock source 41 */ + (NO_PERIPHERAL_FEATURE), /* QSPI module clock source SFIF 42 */ + (NO_PERIPHERAL_FEATURE), /* QSPI module clock source 2XSFIF 43 */ + (NO_PERIPHERAL_FEATURE), /* No clock entry in clock_names_t 44 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* CMP0 clock source 45 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* CRC clock source 46 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* DMAMUX clock source 47 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* EWM clock source 48 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTA clock source 49 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTB clock source 50 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTC clock source 51 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTD clock source 52 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* PORTE clock source 53 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* RTC clock source 54 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* SAI0 clock source 55 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* SAI1 clock source 56 */ + (NO_PERIPHERAL_FEATURE), /* End of BUS clocks 57 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FlexCAN0 clock source 58 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FlexCAN1 clock source 59 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FlexCAN2 clock source 60 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* PDB0 clock source 61 */ + (HAS_INT_CLOCK_FROM_SYS_CLOCK), /* PDB1 clock source 62 */ + (NO_PERIPHERAL_FEATURE), /* End of SYS clocks 63 */ + (HAS_INT_CLOCK_FROM_SLOW_CLOCK), /* FTFC clock source 64 */ + (NO_PERIPHERAL_FEATURE), /* End of SLOW clocks 65 */ + (HAS_MULTIPLIER | HAS_DIVIDER | HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* ENET clock source 66 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM0 clock source 67 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM1 clock source 68 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM2 clock source 69 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM3 clock source 70 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM4 clock source 71 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM5 clock source 72 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM6 clock source 73 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | HAS_INT_CLOCK_FROM_SYS_CLOCK), /* FTM7 clock source 74 */ + (NO_PERIPHERAL_FEATURE), /* End of ASYNCH DIV1 clocks 75 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* ADC0 clock source 76 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* ADC1 clock source 77 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* FLEXIO clock source 78 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPI2C0 clock source 79 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPI2C1 clock source 80 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPIT clock source 81 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPSPI0 clock source 82 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPSPI1 clock source 83 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPSPI2 clock source 84 */ + (HAS_MULTIPLIER | HAS_DIVIDER | HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPTMR0 clock source 85 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPUART0 clock source 86 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPUART1 clock source 87 */ + (HAS_PROTOCOL_CLOCK_FROM_ASYNC2 | HAS_INT_CLOCK_FROM_BUS_CLOCK), /* LPUART2 clock source 88 */ + (HAS_INT_CLOCK_FROM_BUS_CLOCK), /* QSPI clock source 89 */ + (NO_PERIPHERAL_FEATURE), /* End of ASYNCH DIV2 clocks 90 */ + (NO_PERIPHERAL_FEATURE), /* End of PCC clocks 91 */ + }; diff --git a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c index 3aeabd7f8f..bae5f81b83 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c +++ b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.c @@ -463,6 +463,7 @@ static uint32_t s32k1xx_get_srcfreq(enum scg_system_clock_src_e src) return srcfreq; } + /**************************************************************************** * Name: s32k1xx_set_sysclk_configuration * @@ -632,7 +633,7 @@ s32k1xx_transition_systemclock(const struct scg_system_clock_config_s *cfg) { timeout--; } - while ((s32k1xx_get_scgclk_source() != ((uint32_t)cfg->src)) && (timeout > 0U)); + while (s32k1xx_get_scgclk_source() != cfg->src && timeout > 0); if (timeout == 0) { @@ -755,7 +756,7 @@ static int s32k11_firc_clocksource(void) * 2. Switch to FIRC. */ - if (s32k1xx_get_scgclk_source() != ((uint32_t)SCG_SYSTEM_CLOCK_SRC_FIRC)) + if (s32k1xx_get_scgclk_source() != SCG_SYSTEM_CLOCK_SRC_FIRC) { /* If FIRC is not on, then FIRC is configured with the default * configuration @@ -1697,3 +1698,204 @@ uint32_t s32k1xx_get_coreclk(void) return coreclk / divider; } + +/**************************************************************************** + * Name: s32k1xx_get_sysclk + * + * Description: + * Return the current value of an SCG system clock frequency, these clocks + * are used for core, platform, external and bus clock domains.. + * + * Input Parameters: + * type - Identifies the system clock of interest + * + * Returned Values: + * The current value of the system clock frequency. Zero is returned on any + * failure. + * + *****************************************************************************/ + +uint32_t s32k1xx_get_sysclk(enum scg_system_clock_type_e type) +{ + enum scg_system_clock_src_e clksrc; + uint32_t regval; + uint32_t divider; + uint32_t freq; + + /* Get the SCG current system clock source */ + + clksrc = (enum scg_system_clock_src_e)s32k1xx_get_scgclk_source(); + freq = s32k1xx_get_srcfreq(clksrc); + + /* Adjust to count for the code divider */ + + regval = getreg32(S32K1XX_SCG_CSR); + divider = ((regval & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT) + 1; + freq /= divider; + + /* Handle additional dividers for the clock type */ + + switch (type) + { + case SCG_SYSTEM_CLOCK_CORE: + break; + + case SCG_SYSTEM_CLOCK_BUS: + divider = ((regval & SCG_CSR_DIVBUS_MASK) >> SCG_CSR_DIVBUS_SHIFT) + 1; + freq /= divider; + break; + + case SCG_SYSTEM_CLOCK_SLOW: + divider = ((regval & SCG_CSR_DIVSLOW_MASK) >> SCG_CSR_DIVSLOW_SHIFT) + 1; + freq /= divider; + break; + + default: + freq = 0; + break; + } + + return freq; +} + +/**************************************************************************** + * Name: s32k1xx_get_asnchfreq + * + * Description: + * Gets SCG asynchronous clock frequency from a clock source. + * + * Input Parameters: + * clksrc - The requested clock source. + * type - The requested clock type. + * + * Returned Value: + * The frequency of the requested asynchronous clock source. + * + ****************************************************************************/ + +uint32_t s32k1xx_get_asnchfreq(enum clock_names_e clksrc, + enum scg_async_clock_type_e type) +{ + uint32_t regval; + uint32_t freq = 0; + uint32_t div = 0; + + switch (type) + { + case SCG_ASYNC_CLOCK_DIV1: + { + switch (clksrc) + { + case FIRC_CLK: + { + freq = s32k1xx_get_fircfreq(); + regval = getreg32(S32K1XX_SCG_FIRCDIV); + div = (regval & SCG_FIRCDIV_FIRCDIV1_MASK) >> SCG_FIRCDIV_FIRCDIV1_SHIFT; + } + break; + + case SIRC_CLK: + { + freq = s32k1xx_get_sircfreq(); + regval = getreg32(S32K1XX_SCG_SIRCDIV); + div = (regval & SCG_SIRCDIV_SIRCDIV1_MASK) >> SCG_SIRCDIV_SIRCDIV1_SHIFT; + } + break; + + case SOSC_CLK: + { + freq = s32k1xx_get_soscfreq(); + regval = getreg32(S32K1XX_SCG_SOSCDIV); + div = (regval & SCG_SOSCDIV_SOSCDIV1_MASK) >> SCG_SOSCDIV_SOSCDIV1_SHIFT; + } + break; + +#ifdef CONFIG_S32K1XX_HAVE_SPLL + case SPLL_CLK: + { + freq = s32k1xx_get_spllfreq(); + regval = getreg32(S32K1XX_SCG_SPLLDIV); + div = (regval & SCG_SPLLDIV_SPLLDIV1_MASK) >> SCG_SPLLDIV_SPLLDIV1_SHIFT; + } + break; +#endif + + default: + { + /* Invalid clock source type */ + + freq = 0; + DEBUGPANIC(); + } + break; + } + } + break; + + case SCG_ASYNC_CLOCK_DIV2: + { + switch (clksrc) + { + case FIRC_CLK: + { + freq = s32k1xx_get_fircfreq(); + regval = getreg32(S32K1XX_SCG_FIRCDIV); + div = (regval & SCG_FIRCDIV_FIRCDIV2_MASK) >> SCG_FIRCDIV_FIRCDIV2_SHIFT; + } + break; + + case SIRC_CLK: + { + freq = s32k1xx_get_sircfreq(); + regval = getreg32(S32K1XX_SCG_SIRCDIV); + div = (regval & SCG_SIRCDIV_SIRCDIV2_MASK) >> SCG_SIRCDIV_SIRCDIV2_SHIFT; + } + break; + case SOSC_CLK: + { + freq = s32k1xx_get_soscfreq(); + regval = getreg32(S32K1XX_SCG_SOSCDIV); + div = (regval & SCG_SOSCDIV_SOSCDIV2_MASK) >> SCG_SOSCDIV_SOSCDIV2_SHIFT; + } + break; +#ifdef CONFIG_S32K1XX_HAVE_SPLL + case SPLL_CLK: + { + freq = s32k1xx_get_spllfreq(); + regval = getreg32(S32K1XX_SCG_SPLLDIV); + div = (regval & SCG_SPLLDIV_SPLLDIV2_MASK) >> SCG_SPLLDIV_SPLLDIV2_SHIFT; + } + break; +#endif + default: + { + /* Invalid clock source type */ + + freq = 0; + DEBUGPANIC(); + } + break; + } + } + break; + + default: + /* Invalid async clock source */ + + freq = 0; + DEBUGPANIC(); + break; + } + + if (div != 0) + { + freq = (freq >> (div - 1)); + } + else /* Output disabled. */ + { + freq = 0; + } + + return freq; +} + diff --git a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h index 0a93761bf4..ab686da11d 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h +++ b/arch/arm/src/s32k1xx/s32k1xx_clockconfig.h @@ -64,6 +64,12 @@ #include #include +#if defined(CONFIG_ARCH_CHIP_S32K11X) +# include "s32k14x/s32k14x_clocknames.h" +#elif defined(CONFIG_ARCH_CHIP_S32K14X) +# include "s32k14x/s32k14x_clocknames.h" +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -80,10 +86,24 @@ * Public Types ****************************************************************************/ -/* Clock Configuration - * - * These structure are used to define the clock configuration. - */ +/* Clock Configuration ******************************************************/ + +enum scg_system_clock_type_e +{ + SCG_SYSTEM_CLOCK_CORE, /* Core clock */ + SCG_SYSTEM_CLOCK_BUS, /* BUS clock */ + SCG_SYSTEM_CLOCK_SLOW, /* System slow clock */ + SCG_SYSTEM_CLOCK_MAX /* Max value */ +}; + +enum scg_async_clock_type_e +{ + SCG_ASYNC_CLOCK_DIV1 = 0, /* Clock divider 1 */ + SCG_ASYNC_CLOCK_DIV2 = 1, /* Clock divider 2 */ + SCG_ASYNC_CLOCK_MAX = 2, /* Max value */ +}; + +/* These structure are used to define the clock configuration. */ /* SCG SIRC clock configuration */ @@ -513,6 +533,42 @@ int s32k1xx_clockconfig(FAR const struct clock_configuration_s *clkcfg); uint32_t s32k1xx_get_coreclk(void); +/**************************************************************************** + * Name: s32k1xx_get_sysclk + * + * Description: + * Return the current value of an SCG system clock frequency, these clocks + * are used for core, platform, external and bus clock domains.. + * + * Input Parameters: + * type - Identifies the system clock of interest + * + * Returned Values: + * The current value of the system clock frequency. Zero is returned on any + * failure. + * + *****************************************************************************/ + +uint32_t s32k1xx_get_sysclk(enum scg_system_clock_type_e type); + +/**************************************************************************** + * Name: s32k1xx_get_asnchfreq + * + * Description: + * Gets SCG asynchronous clock frequency from a clock source. + * + * Input Parameters: + * clksrc - The requested clock source. + * type - The requested clock type. + * + * Returned Value: + * The frequency of the requested asynchronous clock source. + * + ****************************************************************************/ + +uint32_t s32k1xx_get_asnchfreq(enum clock_names_e clksrc, + enum scg_async_clock_type_e type); + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/s32k1xx/s32k1xx_lowputc.c b/arch/arm/src/s32k1xx/s32k1xx_lowputc.c index af6d837c7d..41c6cd7f5a 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_lowputc.c +++ b/arch/arm/src/s32k1xx/s32k1xx_lowputc.c @@ -47,10 +47,11 @@ #include "hardware/s32k1xx_pinmux.h" #include "hardware/s32k1xx_lpuart.h" + #include "s32k1xx_config.h" -#include "s32k1xx_periphclks.h" -#include "s32k1xx_gpio.h" +#include "s32k1xx_pin.h" #include "s32k1xx_lowputc.h" +#include "s32k1xx_periphclocks.h" #include "up_internal.h" @@ -81,39 +82,13 @@ # define S32K1XX_CONSOLE_BITS CONFIG_LPUART2_BITS # define S32K1XX_CONSOLE_PARITY CONFIG_LPUART2_PARITY # define S32K1XX_CONSOLE_2STOP CONFIG_LPUART2_2STOP +# endif #endif /* Clocking *****************************************************************/ -/* The UART module receives two clocks, a peripheral_clock (ipg_clk) and the - * module_clock (ipg_perclk). The peripheral_clock is used as write clock - * of the TxFIFO, read clock of the RxFIFO and synchronization of the modem - * control input pins. It must always be running when UART is enabled. - * - * The default lpuart0 ipg_clk is 66MHz (max 66.5MHz). ipg_clk is shared - * among many modules and should not be controlled by the UART logic. - * - * The module_clock is for all the state machines, writing RxFIFO, reading - * TxFIFO, etc. It must always be running when UART is sending or receiving - * characters. This clock is used in order to allow frequency scaling on - * peripheral_clock without changing configuration of baud rate. - * - * The default ipg_perclk is 80MHz (max 80MHz). ipg_perclk is gated by - * CCGR5[CG12], lpuart0_clk_enable. The clock generation sequence is: - * - * pll3_sw_clk (480M) -> CCGR5[CG12] -> 3 bit divider cg podf=6 -> - * PLL3_80M (80Mhz) -> CDCDR1: lpuart0_clk_podf -> - * 6 bit divider default=1 -> LPUART0_CLK_ROOT - * - * REVISIT: This logic assumes that all dividers are at the default value - * and that the value of the ipg_perclk is 80MHz. - */ - -#define IPG_PERCLK_FREQUENCY 80000000 - -/* The BRM sub-block receives ref_clk (module_clock clock after divider). - * From this clock, and with integer and non-integer division, BRM generates - * a 16x baud rate clock. +/* Functional clocking is provided via the PCC. The PCC clocking must + * be configured by board-specific logic prior to using the LPUART. */ /**************************************************************************** @@ -130,26 +105,6 @@ static const struct uart_config_s g_console_config = }; #endif -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -void s32k1xx_lpuart_clock_enable (uint32_t base) -{ - if (base == S32K1XX_LPUART0_BASE) - { - s32k1xx_clockall_lpuart0(); - } - else if (base == S32K1XX_LPUART1_BASE) - { - s32k1xx_clockall_lpuart1(); - } - else if (base == S32K1XX_LPUART2_BASE) - { - s32k1xx_clockall_lpuart2(); - } -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -176,14 +131,14 @@ void s32k1xx_lowsetup(void) * control is enabled. */ - (void)s32k1xx_config_gpio(GPIO_LPUART0_RX); - (void)s32k1xx_config_gpio(GPIO_LPUART0_TX); + (void)s32k1xx_pinconfig(GPIO_LPUART0_RX); + (void)s32k1xx_pinconfig(GPIO_LPUART0_TX); #ifdef CONFIG_LPUART0_OFLOWCONTROL - (void)s32k1xx_config_gpio(GPIO_LPUART0_CTS); + (void)s32k1xx_pinconfig(GPIO_LPUART0_CTS); #endif #if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART0_RS485RTSCONTROL)) || \ (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART0_IFLOWCONTROL))) - (void)s32k1xx_config_gpio(GPIO_LPUART0_RTS); + (void)s32k1xx_pinconfig(GPIO_LPUART0_RTS); #endif #endif @@ -193,14 +148,14 @@ void s32k1xx_lowsetup(void) * control is enabled. */ - (void)s32k1xx_config_gpio(GPIO_LPUART1_RX); - (void)s32k1xx_config_gpio(GPIO_LPUART1_TX); + (void)s32k1xx_pinconfig(GPIO_LPUART1_RX); + (void)s32k1xx_pinconfig(GPIO_LPUART1_TX); #ifdef CONFIG_LPUART1_OFLOWCONTROL - (void)s32k1xx_config_gpio(GPIO_LPUART1_CTS); + (void)s32k1xx_pinconfig(GPIO_LPUART1_CTS); #endif #if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART1_RS485RTSCONTROL)) || \ (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL))) - (void)s32k1xx_config_gpio(GPIO_LPUART1_RTS); + (void)s32k1xx_pinconfig(GPIO_LPUART1_RTS); #endif #endif @@ -210,14 +165,14 @@ void s32k1xx_lowsetup(void) * control is enabled. */ - (void)s32k1xx_config_gpio(GPIO_LPUART2_RX); - (void)s32k1xx_config_gpio(GPIO_LPUART2_TX); + (void)s32k1xx_pinconfig(GPIO_LPUART2_RX); + (void)s32k1xx_pinconfig(GPIO_LPUART2_TX); #ifdef CONFIG_LPUART2_OFLOWCONTROL - (void)s32k1xx_config_gpio(GPIO_LPUART2_CTS); + (void)s32k1xx_pinconfig(GPIO_LPUART2_CTS); #endif #if ((defined(CONFIG_SERIAL_RS485CONTROL) && defined(CONFIG_LPUART2_RS485RTSCONTROL)) || \ (defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART2_IFLOWCONTROL))) - (void)s32k1xx_config_gpio(GPIO_LPUART2_RTS); + (void)s32k1xx_pinconfig(GPIO_LPUART2_RTS); #endif #endif @@ -240,11 +195,9 @@ void s32k1xx_lowsetup(void) #ifdef HAVE_LPUART_DEVICE int s32k1xx_lpuart_configure(uint32_t base, - FAR const struct uart_config_s *config) + FAR const struct uart_config_s *config) { - uint32_t src_freq = 0; - uint32_t pll3_div = 0; - uint32_t uart_div = 0; + enum clock_names_e clkname; uint32_t lpuart_freq = 0; uint16_t sbr; uint16_t temp_sbr; @@ -254,28 +207,46 @@ int s32k1xx_lpuart_configure(uint32_t base, uint32_t calculated_baud; uint32_t baud_diff; uint32_t regval; + int ret; - if ((getreg32(S32K1XX_CCM_CSCDR1) & CCM_CSCDR1_UART_CLK_SEL) != 0) + /* Functional clocking is provided via the PCC. The PCC clocking must + * be configured by board-specific logic prior to using the LPUART. + */ + + /* Get the PCC source clock */ + +#ifdef CONFIG_S32K1XX_LPUART0 + if (base == S32K1XX_LPUART0_BASE) { - src_freq = BOARD_XTAL_FREQUENCY; + clkname = LPUART0_CLK; } else +#endif +#ifdef CONFIG_S32K1XX_LPUART1 + if (base == S32K1XX_LPUART1_BASE) { - if ((getreg32(S32K1XX_CCM_ANALOG_PLL_USB1) & - CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0) - { - pll3_div = 22; - } - else - { - pll3_div = 20; - } - - src_freq = (BOARD_XTAL_FREQUENCY * pll3_div) / 6; + clkname = LPUART2_CLK; + } + else +#endif +#ifdef CONFIG_S32K1XX_LPUART2 + if (base == S32K1XX_LPUART2_BASE) + { + clkname = LPUART2_CLK; + } + else +#endif + { + DEBUGPANIC(); + return -EINVAL; } - uart_div = (getreg32(S32K1XX_CCM_CSCDR1) & CCM_CSCDR1_UART_CLK_PODF_MASK) + 1; - lpuart_freq = src_freq / uart_div; + ret = s32k1xx_get_pclkfreq(clkname, &lpuart_freq); + DEBUGASSERT(ret >= 0); + if (ret < 0) + { + return ret; + } /* This LPUART instantiation uses a slightly different baud rate * calculation. The idea is to use the best OSR (over-sampling rate) @@ -333,10 +304,6 @@ int s32k1xx_lpuart_configure(uint32_t base, return ERROR; } - /* Enable lpuart clock */ - - s32k1xx_lpuart_clock_enable(base); - /* Reset all internal logic and registers, except the Global Register */ regval = getreg32(base + S32K1XX_LPUART_GLOBAL_OFFSET); diff --git a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c index 08a275901d..9170fb9ef5 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c +++ b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.c @@ -63,19 +63,13 @@ #include #include "up_arch.h" +#include "hardware/s32k1xx_scg.h" #include "hardware/s32k1xx_pcc.h" +#include "s32k1xx_clockconfig.h" #include "s32k1xx_periphclocks.h" /**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Functions + * Private Functions ****************************************************************************/ /**************************************************************************** @@ -147,7 +141,8 @@ static void s32k1xx_pclk_disable(enum clock_names_e clkname) * ****************************************************************************/ -static inline void s32k1xx_set_pclkctrl(struct peripheral_clock_config_s *pclk) +static inline void +s32k1xx_set_pclkctrl(const struct peripheral_clock_config_s *pclk) { uint32_t *ctrlp = s32k1xx_get_pclkctrl(pclk->clkname); uint32_t regval; @@ -173,6 +168,80 @@ static inline void s32k1xx_set_pclkctrl(struct peripheral_clock_config_s *pclk) *ctrlp = regval; } +/**************************************************************************** + * Name: s32k1xx_get_pclkfreq_divided + * + * Description: + * This is part of the implementation of s32k1xx_get_pclkfreq. + * + * Input Parameters: + * clkname - Identifies the clock. + * divider - Identifies the divider to use. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static uint32_t s32k1xx_get_pclkfreq_divided(enum clock_names_e clkname, + enum scg_async_clock_type_e divider) +{ + uint32_t *ctrlp; + uint32_t frequency = 0; + uint32_t frac; + uint32_t div; + + ctrlp = s32k1xx_get_pclkctrl(clkname); + frac = ((*ctrlp & PCC_FRAC) == 0) ? 0 : 1; + div = (*ctrlp & PCC_PCD_MASK) >> PCC_PCD_SHIFT; + + /* Check division factor */ + + if (frac <= div) + { + /* Check clock gate */ + + if ((*ctrlp & PCC_CGC) != 0) + { + uint32_t clksrc; + + /* Check clock source */ + + clksrc = (*ctrlp & PCC_PCS_MASK) >> PCC_PCS_SHIFT; + switch (clksrc) + { + case CLK_SRC_SOSC: + frequency = s32k1xx_get_asnchfreq(SOSC_CLK, divider); + break; + + case CLK_SRC_SIRC: + frequency = s32k1xx_get_asnchfreq(SIRC_CLK, divider); + break; + + case CLK_SRC_FIRC: + frequency = s32k1xx_get_asnchfreq(FIRC_CLK, divider); + break; + +#ifdef CONFIG_S32K1XX_HAVE_SPLL + case CLK_SRC_SPLL: + frequency = s32k1xx_get_asnchfreq(SPLL_CLK, divider); + break; +#endif + + default: + frequency = 0; + break; + } + + frequency = frequency / (div + 1); + frequency = frequency * (frac + 1); + } + } + + return frequency; +} + + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -193,7 +262,7 @@ static inline void s32k1xx_set_pclkctrl(struct peripheral_clock_config_s *pclk) ****************************************************************************/ void s32k1xx_periphclocks(unsigned int count, - struct peripheral_clock_config_s *pclks) + const struct peripheral_clock_config_s *pclks) { unsigned int i; @@ -210,3 +279,110 @@ void s32k1xx_periphclocks(unsigned int count, s32k1xx_set_pclkctrl(pclks); } } + +/**************************************************************************** + * Name: s32k1xx_get_pclkfreq + * + * Description: + * This function returns the clock frequency of the specified peripheral + * functional clock. + * + * Input Parameters: + * clkname - Identifies the peripheral clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int s32k1xx_get_pclkfreq(enum clock_names_e clkname, uint32_t *frequency) +{ + uint32_t *ctrlp; + uint32_t freq = 0; + int ret = -ENODEV; + + /* Check if the clock is enabled */ + + ctrlp = s32k1xx_get_pclkctrl(clkname); + if ((*ctrlp & PCC_CGC) != 0) + { + if ((g_periph_features[clkname] & HAS_INT_CLOCK_FROM_BUS_CLOCK) != 0) + { + uint32_t busclk; + + /* Check whether BUS CLOCK is clocked. */ + + busclk = s32k1xx_get_sysclk(SCG_SYSTEM_CLOCK_BUS); + ret = (busclk == 0) ? -ENODEV : OK; + } + else if ((g_periph_features[clkname] & HAS_INT_CLOCK_FROM_SYS_CLOCK) != 0) + { + uint32_t sysclk; + + /* Check whether SYS CLOCK is clocked. */ + + sysclk = s32k1xx_get_sysclk(SCG_SYSTEM_CLOCK_CORE); + ret = (sysclk == 0) ? -ENODEV : OK; + } + else if ((g_periph_features[clkname] & HAS_INT_CLOCK_FROM_SLOW_CLOCK) != 0) + { + uint32_t slowclk; + + /* Check whether SLOW CLOCK is clocked. */ + + slowclk = s32k1xx_get_sysclk(SCG_SYSTEM_CLOCK_SLOW); + ret = (slowclk == 0) ? -ENODEV : OK; + } + else + { + /* It's an issue in peripheral features list, each peripheral must + * have one interface clock. + */ + + DEBUGPANIC(); + } + + if (ret == OK) + { + /* Check whether peripheral has protocol clock (functional clock) */ + + if ((g_periph_features[clkname] & (HAS_PROTOCOL_CLOCK_FROM_ASYNC1 | + HAS_PROTOCOL_CLOCK_FROM_ASYNC2)) != 0) + { + if ((g_periph_features[clkname] & HAS_PROTOCOL_CLOCK_FROM_ASYNC1) != 0) + { + /* Check whether the functional clock is clocked */ + + freq = s32k1xx_get_pclkfreq_divided(clkname, SCG_ASYNC_CLOCK_DIV1); + } + + if ((g_periph_features[clkname] & HAS_PROTOCOL_CLOCK_FROM_ASYNC2) != 0U) + { + /* Check whether the functional clock is clocked */ + + freq = s32k1xx_get_pclkfreq_divided(clkname, SCG_ASYNC_CLOCK_DIV2); + } + + if (freq == 0) + { + ret = -ENODEV; + } + } + } + } + + /* If frequency reference is provided, write this value */ + + if (frequency != NULL) + { + *frequency = freq; + } + + return ret; +} + + diff --git a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h index 989d55d533..642281592a 100644 --- a/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h +++ b/arch/arm/src/s32k1xx/s32k1xx_periphclocks.h @@ -1,4 +1,4 @@ -/**************************************************************************** +/************************************************************************************ * arch/arm/src/s32k1xx/s32k1xx_preriphclocks.h * * Copyright (C) 2019 Gregory Nutt. All rights reserved. @@ -50,14 +50,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - ****************************************************************************/ + ************************************************************************************/ #ifndef __ARCH_ARM_SRC_S32K1XX_S32K1XX_PERIPHCLOCKS_H #define __ARCH_ARM_SRC_S32K1XX_S32K1XX_PERIPHCLOCKS_H -/**************************************************************************** +/************************************************************************************ * Included Files - ****************************************************************************/ + ************************************************************************************/ #include @@ -78,82 +78,94 @@ # include "s32k14x/s32k14x_clocknames.h" #endif -/**************************************************************************** +/************************************************************************************ * Pre-processor Definitions - ****************************************************************************/ + ************************************************************************************/ /* Values for peripheral_clock_source_t. An enumeration is not appropriate * because some of the values are duplicates. */ -#define CLK_SRC_OFF 0 /* Clock is off */ -#define CLK_SRC_SOSC 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL 6 /* SCGPCLK System PLL clock */ -#define CLK_SRC_SOSC_DIV1 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC_DIV1 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC_DIV1 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL_DIV1 6 /* SCGPCLK System PLL clock */ -#define CLK_SRC_SOSC_DIV2 1 /* OSCCLK - System Oscillator Bus Clock */ -#define CLK_SRC_SIRC_DIV2 2 /* SCGIRCLK - Slow IRC Clock */ -#define CLK_SRC_FIRC_DIV2 3 /* SCGFIRCLK - Fast IRC Clock */ -#define CLK_SRC_SPLL_DIV2 6 /* SCGPCLK System PLL clock */ +#define CLK_SRC_OFF 0 /* Clock is off */ +#define CLK_SRC_SOSC 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL 6 /* SCGPCLK System PLL clock */ +#define CLK_SRC_SOSC_DIV1 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC_DIV1 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC_DIV1 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL_DIV1 6 /* SCGPCLK System PLL clock */ +#define CLK_SRC_SOSC_DIV2 1 /* OSCCLK - System Oscillator Bus Clock */ +#define CLK_SRC_SIRC_DIV2 2 /* SCGIRCLK - Slow IRC Clock */ +#define CLK_SRC_FIRC_DIV2 3 /* SCGFIRCLK - Fast IRC Clock */ +#define CLK_SRC_SPLL_DIV2 6 /* SCGPCLK System PLL clock */ /* PCC index offsets (all S32K1xx families). These are used in in the * family-specific mapping table g_clkname_mapping[] that is used to map a * clock name to a PCC control register index. */ -#define PCC_INVALID_INDEX 0 +#define PCC_INVALID_INDEX 0 -#define PCC_FTFC_INDEX 32 -#define PCC_DMAMUX_INDEX 33 -#define PCC_FLEXCAN0_INDEX 36 -#define PCC_FLEXCAN1_INDEX 37 -#define PCC_FTM3_INDEX 38 -#define PCC_ADC1_INDEX 39 -#define PCC_FLEXCAN2_INDEX 43 -#define PCC_LPSPI0_INDEX 44 -#define PCC_LPSPI1_INDEX 45 -#define PCC_LPSPI2_INDEX 46 -#define PCC_PDB1_INDEX 49 -#define PCC_CRC_INDEX 50 -#define PCC_PDB0_INDEX 54 -#define PCC_LPIT_INDEX 55 -#define PCC_FTM0_INDEX 56 -#define PCC_FTM1_INDEX 57 -#define PCC_FTM2_INDEX 58 -#define PCC_ADC0_INDEX 59 -#define PCC_RTC_INDEX 61 -#define PCC_CMU0_INDEX 62 -#define PCC_CMU1_INDEX 63 -#define PCC_LPTMR0_INDEX 64 -#define PCC_PORTA_INDEX 73 -#define PCC_PORTB_INDEX 74 -#define PCC_PORTC_INDEX 75 -#define PCC_PORTD_INDEX 76 -#define PCC_PORTE_INDEX 77 -#define PCC_SAI0_INDEX 84 -#define PCC_SAI1_INDEX 85 -#define PCC_FLEXIO_INDEX 90 -#define PCC_EWM_INDEX 97 -#define PCC_LPI2C0_INDEX 102 -#define PCC_LPI2C1_INDEX 103 -#define PCC_LPUART0_INDEX 106 -#define PCC_LPUART1_INDEX 107 -#define PCC_LPUART2_INDEX 108 -#define PCC_FTM4_INDEX 110 -#define PCC_FTM5_INDEX 111 -#define PCC_FTM6_INDEX 112 -#define PCC_FTM7_INDEX 113 -#define PCC_CMP0_INDEX 115 -#define PCC_QSPI_INDEX 118 -#define PCC_ENET_INDEX 121 +#define PCC_FTFC_INDEX 32 +#define PCC_DMAMUX_INDEX 33 +#define PCC_FLEXCAN0_INDEX 36 +#define PCC_FLEXCAN1_INDEX 37 +#define PCC_FTM3_INDEX 38 +#define PCC_ADC1_INDEX 39 +#define PCC_FLEXCAN2_INDEX 43 +#define PCC_LPSPI0_INDEX 44 +#define PCC_LPSPI1_INDEX 45 +#define PCC_LPSPI2_INDEX 46 +#define PCC_PDB1_INDEX 49 +#define PCC_CRC_INDEX 50 +#define PCC_PDB0_INDEX 54 +#define PCC_LPIT_INDEX 55 +#define PCC_FTM0_INDEX 56 +#define PCC_FTM1_INDEX 57 +#define PCC_FTM2_INDEX 58 +#define PCC_ADC0_INDEX 59 +#define PCC_RTC_INDEX 61 +#define PCC_CMU0_INDEX 62 +#define PCC_CMU1_INDEX 63 +#define PCC_LPTMR0_INDEX 64 +#define PCC_PORTA_INDEX 73 +#define PCC_PORTB_INDEX 74 +#define PCC_PORTC_INDEX 75 +#define PCC_PORTD_INDEX 76 +#define PCC_PORTE_INDEX 77 +#define PCC_SAI0_INDEX 84 +#define PCC_SAI1_INDEX 85 +#define PCC_FLEXIO_INDEX 90 +#define PCC_EWM_INDEX 97 +#define PCC_LPI2C0_INDEX 102 +#define PCC_LPI2C1_INDEX 103 +#define PCC_LPUART0_INDEX 106 +#define PCC_LPUART1_INDEX 107 +#define PCC_LPUART2_INDEX 108 +#define PCC_FTM4_INDEX 110 +#define PCC_FTM5_INDEX 111 +#define PCC_FTM6_INDEX 112 +#define PCC_FTM7_INDEX 113 +#define PCC_CMP0_INDEX 115 +#define PCC_QSPI_INDEX 118 +#define PCC_ENET_INDEX 121 -/**************************************************************************** +/* Peripheral instance features. */ + +#define NO_PERIPHERAL_FEATURE (0) /* No peripheral feature */ +#define HAS_CLOCK_GATING_IN_SIM (1 << 0) /* Clock gating implemented in SIM */ +#define HAS_MULTIPLIER (1 << 1) /* Multiplier implemented in PCC */ +#define HAS_DIVIDER (1 << 2) /* Divider implemented in PCC */ +#define HAS_PROTOCOL_CLOCK_FROM_ASYNC1 (1 << 3) /* Clock source provided by first asynch clock */ +#define HAS_PROTOCOL_CLOCK_FROM_ASYNC2 (1 << 4) /* Clock source iprovided by second asynch clock */ +#define HAS_INT_CLOCK_FROM_BUS_CLOCK (1 << 5) /* Clock is provided by the bus clock */ +#define HAS_INT_CLOCK_FROM_SYS_CLOCK (1 << 6) /* Clock is provided by the sys clock */ +#define HAS_INT_CLOCK_FROM_SLOW_CLOCK (1 << 7) /* Clock is provided by the slow clock */ + +/************************************************************************************ * Public Types - ****************************************************************************/ + ************************************************************************************/ typedef uint8_t peripheral_clock_source_t; /* See CLK_SRC_* definitions */ @@ -190,9 +202,9 @@ struct peripheral_clock_config_s #ifndef __ASSEMBLY__ -/**************************************************************************** +/************************************************************************************ * Public Data - ****************************************************************************/ + ************************************************************************************/ #undef EXTERN #if defined(__cplusplus) @@ -213,11 +225,20 @@ extern "C" EXTERN const uint16_t g_clkname_mapping[]; -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ +/* Peripheral Features. + * + * Each S32K1xx architecture must provide this array. This is an array of + * bit-encoded peripheral clocking features. See the peripheral instance + * feature definitions above + */ -/**************************************************************************** +EXTERN const uint8_t g_periph_features[]; + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ * Name: s32k1xx_periphclocks * * Description: @@ -230,10 +251,31 @@ EXTERN const uint16_t g_clkname_mapping[]; * Returned Value: * None * - ****************************************************************************/ + ************************************************************************************/ void s32k1xx_periphclocks(unsigned int count, - struct peripheral_clock_config_s *pclks); + const struct peripheral_clock_config_s *pclks); + +/**************************************************************************** + * Name: s32k1xx_get_pclkfreq + * + * Description: + * This function returns the clock frequency of the specified peripheral + * functional clock. + * + * Input Parameters: + * clkname - Identifies the peripheral clock of interest + * frequency - The location where the peripheral clock frequency will be + * returned + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. -ENODEV is returned if the clock is not enabled or is not + * being clocked. + * + ****************************************************************************/ + +int s32k1xx_get_pclkfreq(enum clock_names_e clkname, uint32_t *frequency); #undef EXTERN #if defined(__cplusplus)