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.
This commit is contained in:
Gregory Nutt 2019-08-17 14:36:40 -06:00
parent e7a3231d7a
commit be55a6542f
10 changed files with 982 additions and 241 deletions

View File

@ -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

View File

@ -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 */

View File

@ -0,0 +1,127 @@
/********************************************************************************************************************************************
* arch/arm/src/s32k1xx/s32k11x/s32k11x_periphfeatures.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#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 */
};

View File

@ -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 */
};

View File

@ -0,0 +1,149 @@
/********************************************************************************************************************************************
* arch/arm/src/s32k1xx/s32k14x/s32k14x_periphfeatures.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <nuttx/config.h>
#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 */
};

View File

@ -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;
}

View File

@ -64,6 +64,12 @@
#include <stdint.h>
#include <stdbool.h>
#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)
}

View File

@ -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
@ -242,9 +197,7 @@ void s32k1xx_lowsetup(void)
int s32k1xx_lpuart_configure(uint32_t base,
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,29 +207,47 @@ 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;
clkname = LPUART2_CLK;
}
else
#endif
#ifdef CONFIG_S32K1XX_LPUART2
if (base == S32K1XX_LPUART2_BASE)
{
pll3_div = 20;
clkname = LPUART2_CLK;
}
else
#endif
{
DEBUGPANIC();
return -EINVAL;
}
src_freq = (BOARD_XTAL_FREQUENCY * pll3_div) / 6;
ret = s32k1xx_get_pclkfreq(clkname, &lpuart_freq);
DEBUGASSERT(ret >= 0);
if (ret < 0)
{
return ret;
}
uart_div = (getreg32(S32K1XX_CCM_CSCDR1) & CCM_CSCDR1_UART_CLK_PODF_MASK) + 1;
lpuart_freq = src_freq / uart_div;
/* This LPUART instantiation uses a slightly different baud rate
* calculation. The idea is to use the best OSR (over-sampling rate)
* possible.
@ -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);

View File

@ -63,19 +63,13 @@
#include <debug.h>
#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;
}

View File

@ -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 <nuttx/config.h>
@ -78,9 +78,9 @@
# 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.
@ -151,9 +151,21 @@
#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)