diff --git a/arch/arm/src/imxrt/chip/imxrt_ccm.h b/arch/arm/src/imxrt/chip/imxrt_ccm.h index c7f56800706..55d9e1c6f01 100644 --- a/arch/arm/src/imxrt/chip/imxrt_ccm.h +++ b/arch/arm/src/imxrt/chip/imxrt_ccm.h @@ -2,7 +2,8 @@ * arch/arm/src/imxrt/imxrt_ccm.h * * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Author: Janne Rosberg + * Authors: Janne Rosberg + * David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -159,6 +160,10 @@ #define IMXRT_CCM_ANALOG_MISC1 (IMXRT_ANATOP_BASE + IMXRT_CCM_ANALOG_MISC1_OFFSET) #define IMXRT_CCM_ANALOG_MISC2 (IMXRT_ANATOP_BASE + IMXRT_CCM_ANALOG_MISC2_OFFSET) +/* Helper Macros *********************************************************************************/ + +#define CCM_PODF_FROM_DIVISOR(n) ((n)-1) /* PODF Values are divisor-1 */ + /* Register bit definitions *********************************************************************************/ /* Control Register */ @@ -210,7 +215,12 @@ #define CCM_CBCDR_SEMC_PODF_MASK (0x3 << CCM_CBCDR_SEMC_PODF_SHIFT) # define CCM_CBCDR_SEMC_PODF(n) ((uint32_t)(n) << CCM_CBCDR_SEMC_PODF_SHIFT) /* Bits 19-24: Reserved */ -#define CCM_CBCDR_SEMC_PERIPH_CLK_SEL (1 << 25) /* Bit 25: Selector for peripheral main clock */ +#define CCM_CBCDR_PERIPH_CLK_SEL_SHIFT (25) /* Bit 25: Selector for peripheral main clock */ +#define CCM_CBCDR_PERIPH_CLK_SEL_MASK (1 << CCM_CBCDR_PERIPH_CLK_SEL_SHIFT) +# define CCM_CBCDR_PERIPH_CLK_SEL(n) ((uint32_t)(n) << CCM_CBCDR_PERIPH_CLK_SEL_SHIFT) +# define CCM_CBCDR_PERIPH_CLK_SEL_PRE_PERIPH (0) +# define CCM_CBCDR_PERIPH_CLK_SEL_PERIPH_CLK2 (1) + /* Bit 26: Reserved */ #define CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT (27) /* Bits 27-29: Divider for periph_clk2_podf */ #define CCM_CBCDR_PERIPH_CLK2_PODF_MASK (0x7 << CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) @@ -228,7 +238,7 @@ # define CCM_CBCMR_LPSPI_CLK_SEL_PLL2 ((uint32_t)(2) << CCM_CBCMR_LPSPI_CLK_SEL_SHIFT) # define CCM_CBCMR_LPSPI_CLK_SEL_PLL2_PFD2 ((uint32_t)(3) << CCM_CBCMR_LPSPI_CLK_SEL_SHIFT) /* Bits 6-11: Reserved */ -#define CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT (12) /* Bits 13-13: Selector for peripheral clk2 clock multiplexer */ +#define CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT (12) /* Bits 12-13: Selector for peripheral clk2 clock multiplexer */ #define CCM_CBCMR_PERIPH_CLK2_SEL_MASK (0x3 << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) # define CCM_CBCMR_PERIPH_CLK2_SEL(n) ((uint32_t)(n) << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) # define CCM_CBCMR_PERIPH_CLK2_SEL_PLL3_SW ((uint32_t)(0) << CCM_CBCMR_PERIPH_CLK2_SEL_SHIFT) @@ -245,10 +255,10 @@ #define CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT (18) /* Bits 18-19: Selector for pre_periph clock multiplexer */ #define CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK (0x3 << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) # define CCM_CBCMR_PRE_PERIPH_CLK_SEL(n) ((uint32_t)(n) << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) -# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2 ((uint32_t)(0) << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) -# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD2 ((uint32_t)(1) << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) -# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD0 ((uint32_t)(2) << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) -# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL1 ((uint32_t)(3) << CCM_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT) +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2 (0) +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD2 (1) +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL2_PFD0 (2) +# define CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL1 (3) /* Bits 20-22: Reserved */ #define CCM_CBCMR_LCDIF_PODF_SHIFT (23) /* Bits 23-25: Post-divider for LCDIF clock */ #define CCM_CBCMR_LCDIF_PODF_MASK (0x7 << CCM_CBCMR_LCDIF_PODF_SHIFT) @@ -262,7 +272,11 @@ #define CCM_CSCMR1_PERCLK_PODF_SHIFT (0) /* Bits 0-5: Divider for perclk podf */ #define CCM_CSCMR1_PERCLK_PODF_MASK (0x3f << CCM_CSCMR1_PERCLK_PODF_SHIFT) # define CCM_CSCMR1_PERCLK_PODF(n) ((uint32_t)(n) << CCM_CSCMR1_PERCLK_PODF_SHIFT) -#define CCM_CSCMR1_PERCLK_CLK_SEL (1 << 6) /* Bit 6: Selector for the perclk clock multiplexer */ +#define CCM_CSCMR1_PERCLK_CLK_SEL_SHIFT (6) /* Bit 6: Selector for the perclk clock multiplexer */ +#define CCM_CSCMR1_PERCLK_CLK_SEL_MASK (1 << CCM_CSCMR1_PERCLK_CLK_SEL_SHIFT) +# define CCM_CSCMR1_PERCLK_CLK_SEL(n) ((uint32_t)(n) << CCM_CSCMR1_PERCLK_CLK_SEL_SHIFT) +# define CCM_CSCMR1_PERCLK_CLK_SEL_IPG_CLK_ROOT (0) +# define CCM_CSCMR1_PERCLK_CLK_SEL_OSC_CLK (1) /* Bits 7-9: Reserved */ #define CCM_CSCMR1_SAI1_CLK_SEL_SHIFT (10) /* Bits 10-11: Selector for sai1 clock multiplexer */ #define CCM_CSCMR1_SAI1_CLK_SEL_MASK (0x3 << CCM_CSCMR1_SAI1_CLK_SEL_SHIFT) @@ -821,8 +835,8 @@ #define CCM_ANALOG_PLL_SYS_DIV_SELECT_SHIFT (0) /* Bits 0-1: This field controls the PLL loop divider 20 or 22 */ #define CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK (0x3 << CCM_ANALOG_PLL_SYS_DIV_SELECT_SHIFT) # define CCM_ANALOG_PLL_SYS_DIV_SELECT(n) ((uint32_t)(n) << CCM_ANALOG_PLL_SYS_DIV_SELECT_SHIFT) -# define CCM_ANALOG_PLL_SYS_DIV_SELECT_20 ((uint32_t)(0) << CCM_ANALOG_PLL_SYS_DIV_SELECT_SHIFT) -# define CCM_ANALOG_PLL_SYS_DIV_SELECT_22 ((uint32_t)(1) << CCM_ANALOG_PLL_SYS_DIV_SELECT_SHIFT) +# define CCM_ANALOG_PLL_SYS_DIV_SELECT_20 (0) +# define CCM_ANALOG_PLL_SYS_DIV_SELECT_22 (1) #define CCM_ANALOG_PLL_SYS_POWERDOWN (1 << 12) /* Bit 12: Powers down the PLL */ #define CCM_ANALOG_PLL_SYS_ENABLE (1 << 13) /* Bit 13: Enable the PLL clock output */ #define CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_SHIFT (14) /* Bits 14-15: Determines the bypass source */ diff --git a/arch/arm/src/imxrt/imxrt_clockconfig.c b/arch/arm/src/imxrt/imxrt_clockconfig.c index 8d8c6eacc55..3ce3f438b0d 100644 --- a/arch/arm/src/imxrt/imxrt_clockconfig.c +++ b/arch/arm/src/imxrt/imxrt_clockconfig.c @@ -2,8 +2,9 @@ * arch/arm/src/imxrt/imxrt_clockconfig.c * * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Author: Janne Rosberg - * Modified: Ivan Ucherdzhiev + * Authors: Janne Rosberg + * Ivan Ucherdzhiev + * David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -84,7 +85,8 @@ void imxrt_clockconfig(void) /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ reg = getreg32(IMXRT_CCM_CBCDR); - reg |= CCM_CBCDR_SEMC_PERIPH_CLK_SEL; + reg &= ~CCM_CBCDR_PERIPH_CLK_SEL_MASK; + reg |= CCM_CBCDR_PERIPH_CLK_SEL(CCM_CBCDR_PERIPH_CLK_SEL_PERIPH_CLK2); putreg32(reg, IMXRT_CCM_CBCDR); /* Wait handshake */ @@ -102,7 +104,7 @@ void imxrt_clockconfig(void) /* Init Arm PLL1 */ - reg = CCM_ANALOG_PLL_ARM_DIV_SELECT(IMXRT_ARM_PLL_SELECT) | CCM_ANALOG_PLL_ARM_ENABLE; + reg = CCM_ANALOG_PLL_ARM_DIV_SELECT(IMXRT_ARM_PLL_DIV_SELECT) | CCM_ANALOG_PLL_ARM_ENABLE; putreg32(reg, IMXRT_CCM_ANALOG_PLL_ARM); while ((getreg32(IMXRT_CCM_ANALOG_PLL_ARM) & CCM_ANALOG_PLL_ARM_LOCK) == 0) { @@ -122,35 +124,41 @@ void imxrt_clockconfig(void) reg = getreg32(IMXRT_CCM_CACRR); reg &= ~CCM_CACRR_ARM_PODF_MASK; - reg |= CCM_CACRR_ARM_PODF(IMXRT_ARM_CLOCK_DIVIDER); + reg |= CCM_CACRR_ARM_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_ARM_PODF_DIVIDER)); putreg32(reg, IMXRT_CCM_CACRR); reg = getreg32(IMXRT_CCM_CBCDR); reg &= ~CCM_CBCDR_AHB_PODF_MASK; - reg |= CCM_CBCDR_AHB_PODF(IMXRT_AHB_CLOCK_DIVIDER); + reg |= CCM_CBCDR_AHB_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_AHB_PODF_DIVIDER)); putreg32(reg, IMXRT_CCM_CBCDR); reg = getreg32(IMXRT_CCM_CBCDR); reg &= ~CCM_CBCDR_IPG_PODF_MASK; - reg |= CCM_CBCDR_IPG_PODF(IMXRT_IPG_CLOCK_DIVIDER); + reg |= CCM_CBCDR_IPG_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_IPG_PODF_DIVIDER)); putreg32(reg, IMXRT_CCM_CBCDR); + reg = getreg32(IMXRT_CCM_CSCMR1); + reg &= ~CCM_CSCMR1_PERCLK_PODF_MASK; + reg |= CCM_CSCMR1_PERCLK_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_PERCLK_PODF_DIVIDER)); + putreg32(reg, IMXRT_CCM_CSCMR1); + reg = getreg32(IMXRT_CCM_CBCDR); reg &= ~CCM_CBCDR_SEMC_PODF_MASK; - reg |= CCM_CBCDR_SEMC_PODF(IMXRT_SEMC_CLOCK_DIVIDER); + reg |= CCM_CBCDR_SEMC_PODF(CCM_PODF_FROM_DIVISOR(IMXRT_SEMC_PODF_DIVIDER)); putreg32(reg, IMXRT_CCM_CBCDR); - /* Set PRE_PERIPH_CLK to PLL1 */ + /* Set PRE_PERIPH_CLK to Board Selection */ reg = getreg32(IMXRT_CCM_CBCMR); reg &= ~CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK; - reg |= CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL1; + reg |= CCM_CBCMR_PRE_PERIPH_CLK_SEL(IMXRT_PRE_PERIPH_CLK_SEL); putreg32(reg, IMXRT_CCM_CBCMR); - /* Set PERIPH_CLK MUX to PRE_PERIPH_CLK2 */ + /* Set PERIPH_CLK MUX to Board Selection */ reg = getreg32(IMXRT_CCM_CBCDR); - reg &= ~CCM_CBCDR_SEMC_PERIPH_CLK_SEL; + reg &= ~CCM_CBCDR_PERIPH_CLK_SEL_MASK; + reg |= CCM_CBCDR_PERIPH_CLK_SEL(IMXRT_PERIPH_CLK_SEL); putreg32(reg, IMXRT_CCM_CBCDR); /* Wait handshake */ @@ -159,6 +167,13 @@ void imxrt_clockconfig(void) { } + /* Set PERCLK_CLK_SEL to Board Selection */ + + reg = getreg32(IMXRT_CCM_CSCMR1); + reg &= ~CCM_CSCMR1_PERCLK_CLK_SEL_MASK; + reg |= CCM_CSCMR1_PERCLK_CLK_SEL(IMXRT_PERCLK_CLK_SEL); + putreg32(reg, IMXRT_CCM_CSCMR1); + /* Set UART source to PLL3 80M */ reg = getreg32(IMXRT_CCM_CSCDR1); @@ -174,7 +189,7 @@ void imxrt_clockconfig(void) putreg32(reg, IMXRT_CCM_CSCDR1); #ifdef CONFIG_IMXRT_LPI2C - /* Set UART source to PLL3 80M */ + /* Set LPI2C source to PLL3 60M */ reg = getreg32(IMXRT_CCM_CSCDR2); reg &= CCM_CSCDR2_LPI2C_CLK_SEL; @@ -185,7 +200,7 @@ void imxrt_clockconfig(void) { } - /* Set LPI2C divider to 5 */ + /* Set LPI2C divider to 5 for 12 Mhz */ reg = getreg32(IMXRT_CCM_CSCDR2); reg &= CCM_CSCDR2_LPI2C_CLK_PODF_MASK; diff --git a/arch/arm/src/imxrt/imxrt_lpi2c.c b/arch/arm/src/imxrt/imxrt_lpi2c.c index ebf6bbf4b38..7d7a6db8eaf 100644 --- a/arch/arm/src/imxrt/imxrt_lpi2c.c +++ b/arch/arm/src/imxrt/imxrt_lpi2c.c @@ -1211,7 +1211,7 @@ static int imxrt_lpi2c_isr_process(struct imxrt_lpi2c_priv_s *priv) /* Continue with either sending or reading data */ - /* Check if there is more butes to send */ + /* Check if there is more bytes to send */ if (((priv->flags & I2C_M_READ) == 0) && (status & LPI2C_MSR_TDF) != 0) { @@ -1239,8 +1239,8 @@ static int imxrt_lpi2c_isr_process(struct imxrt_lpi2c_priv_s *priv) { imxrt_lpi2c_traceevent(priv, I2CEVENT_RCVBYTE, priv->dcnt); - /* No interrupts or contex switches should occur in the following - * seuence. Otherwise, additional bytes may be sent by the device. + /* No interrupts or context switches should occur in the following + * sequence. Otherwise, additional bytes may be sent by the device. */ #ifdef CONFIG_I2C_POLLED diff --git a/arch/arm/src/imxrt/imxrt_wdog.c b/arch/arm/src/imxrt/imxrt_wdog.c index 22ef611ff22..8f9f2410ed1 100644 --- a/arch/arm/src/imxrt/imxrt_wdog.c +++ b/arch/arm/src/imxrt/imxrt_wdog.c @@ -73,23 +73,26 @@ void imxrt_wdog_disable_all(void) { uint32_t reg; + irqstate_t flags; - reg = getreg32(IMXRT_WDOG1_WCR); + reg = getreg16(IMXRT_WDOG1_WCR); if (reg & WDOG_WCR_WDE) { reg &= ~WDOG_WCR_WDE; - putreg32(reg, IMXRT_WDOG1_WCR); + putreg16(reg, IMXRT_WDOG1_WCR); } - reg = getreg32(IMXRT_WDOG2_WCR); + reg = getreg16(IMXRT_WDOG2_WCR); if (reg & WDOG_WCR_WDE) { reg &= ~WDOG_WCR_WDE; - putreg32(reg, IMXRT_WDOG2_WCR); + putreg16(reg, IMXRT_WDOG2_WCR); } + flags = enter_critical_section(); putreg32(RTWDOG_UPDATE_KEY, IMXRT_RTWDOG_CNT); putreg32(0xFFFF, IMXRT_RTWDOG_TOVAL); modifyreg32(IMXRT_RTWDOG_CS, RTWDOG_CS_EN, RTWDOG_CS_UPDATE); + leave_critical_section(flags); } diff --git a/configs/imxrt1050-evk/include/board.h b/configs/imxrt1050-evk/include/board.h index 490bc8b9469..369d73cfac0 100644 --- a/configs/imxrt1050-evk/include/board.h +++ b/configs/imxrt1050-evk/include/board.h @@ -2,7 +2,8 @@ * configs/imxrt1050/include/board.h * * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Authors: Gregory Nutt + * David Sidrane * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -48,31 +49,59 @@ /* Clocking *************************************************************************/ -/* Set VDD_SOC to 1.5V */ +/* Set VDD_SOC to 1.25V */ #define IMXRT_VDD_SOC (0x12) -/* Set Arm PLL (PLL1) to 1200Mhz = (24Mhz * 100) / 2 - * Set Sys PLL (PLL2) to 528Mhz = 1 - * (0 = 20 * 24Mhz = 480Mhz - * 1 = 22 * 24Mhz = 528Mhz) +/* Set Arm PLL (PLL1) to fOut = (24Mhz * ARM_PLL_DIV_SELECT/2) / ARM_PODF_DIVISOR + * 600Mhz = (24Mhz * ARM_PLL_DIV_SELECT/2) / ARM_PODF_DIVISOR + * ARM_PLL_DIV_SELECT = 100 + * ARM_PODF_DIVISOR = 2 + * 600Mhz = (24Mhz * 100/2) / 2 * - * Arm clock divider = 2 -> Arm Clock = 600Mhz - * AHB clock divider = 1 - * IPG clock divider = 4 + * AHB_CLOCK_ROOT = PLL1fOut / IMXRT_AHB_PODF_DIVIDER + * 1Hz to 600 Mhz = 600Mhz / IMXRT_ARM_CLOCK_DIVIDER + * IMXRT_ARM_CLOCK_DIVIDER = 1 + * 600Mhz = 600Mhz / 1 + * + * PRE_PERIPH_CLK_SEL = PRE_PERIPH_CLK_SEL_PLL1 + * PERIPH_CLK_SEL = 1 (0 select PERIPH_CLK2_PODF, 1 select PRE_PERIPH_CLK_SEL_PLL1) + * PERIPH_CLK = 600Mhz + * + * IPG_CLOCK_ROOT = AHB_CLOCK_ROOT / IMXRT_IPG_PODF_DIVIDER + * IMXRT_IPG_PODF_DIVIDER = 4 + * 150Mhz = 600Mhz / 4 + * + * PRECLK_CLOCK_ROOT = IPG_CLOCK_ROOT / IMXRT_PERCLK_PODF_DIVIDER + * IMXRT_PERCLK_PODF_DIVIDER = 1 + * 150Mhz = 150Mhz / 1 + * + * SEMC_CLK_ROOT = 600Mhz / IMXRT_SEMC_PODF_DIVIDER (labeled AIX_PODF in 18.2) + * IMXRT_SEMC_PODF_DIVIDER = 8 + * 75Mhz = 600Mhz / 8 + * + * Set Sys PLL (PLL2) to fOut = (24Mhz * (20+(2*(DIV_SELECT))) + * 528Mhz = (24Mhz * (20+(2*(1))) + * + * Set USB1 PLL (PLL3) to fOut = (24Mhz * 20) + * 480Mhz = (24Mhz * 20) */ -#define BOARD_XTAL_FREQUENCY 24000000 +#define BOARD_XTAL_FREQUENCY 24000000 +#define IMXRT_PRE_PERIPH_CLK_SEL CCM_CBCMR_PRE_PERIPH_CLK_SEL_PLL1 +#define IMXRT_PERIPH_CLK_SEL CCM_CBCDR_PERIPH_CLK_SEL_PRE_PERIPH +#define IMXRT_ARM_PLL_DIV_SELECT 100 +#define IMXRT_ARM_PODF_DIVIDER 2 +#define IMXRT_AHB_PODF_DIVIDER 1 +#define IMXRT_IPG_PODF_DIVIDER 4 +#define IMXRT_PERCLK_CLK_SEL CCM_CSCMR1_PERCLK_CLK_SEL_IPG_CLK_ROOT +#define IMXRT_PERCLK_PODF_DIVIDER 9 +#define IMXRT_SEMC_PODF_DIVIDER 8 -#define IMXRT_ARM_PLL_SELECT (100) -#define IMXRT_SYS_PLL_SELECT (1) -#define IMXRT_ARM_CLOCK_DIVIDER (1) -#define IMXRT_AHB_CLOCK_DIVIDER (0) -#define IMXRT_IPG_CLOCK_DIVIDER (3) -#define IMXRT_SEMC_CLOCK_DIVIDER (7) +#define IMXRT_SYS_PLL_SELECT CCM_ANALOG_PLL_SYS_DIV_SELECT_22 #define BOARD_CPU_FREQUENCY \ - (BOARD_XTAL_FREQUENCY * IMXRT_ARM_PLL_SELECT) / (IMXRT_ARM_CLOCK_DIVIDER + 1) + (BOARD_XTAL_FREQUENCY * (IMXRT_ARM_PLL_DIV_SELECT / 2)) / IMXRT_ARM_PODF_DIVIDER /* LED definitions ******************************************************************/ /* There are four LED status indicators located on the EVK Board. The functions of