Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers hic_init.c Source File

hic_init.c

Go to the documentation of this file.
00001 /**
00002  * @file    hic_init.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * Copyright (c) 2016-2017 NXP
00008  * SPDX-License-Identifier: Apache-2.0
00009  *
00010  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00011  * not use this file except in compliance with the License.
00012  * You may obtain a copy of the License at
00013  *
00014  * http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing, software
00017  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00018  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019  * See the License for the specific language governing permissions and
00020  * limitations under the License.
00021  */
00022 
00023 #include "hic_init.h"
00024 #include "gpio.h"
00025 #include "fsl_clock.h "
00026 #include "usb_phy.h"
00027 #include "util.h"
00028 
00029 static void busy_wait(uint32_t cycles)
00030 {
00031     volatile uint32_t i;
00032     i = cycles;
00033 
00034     while (i > 0) {
00035         i--;
00036     }
00037 }
00038 
00039 static void fll_delay(void)
00040 {
00041     // ~2.5ms at 16MHz core clock
00042     busy_wait(10000);
00043 }
00044 
00045 // This IRQ handler will be invoked if VDD falls below the trip point.
00046 void LVD_LVW_IRQHandler(void)
00047 {
00048     if (PMC->LVDSC1 & PMC_LVDSC1_LVDF_MASK)
00049     {
00050         util_assert(false && "low voltage detect tripped");
00051         PMC->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK;
00052     }
00053     if (PMC->LVDSC2 & PMC_LVDSC2_LVWF_MASK)
00054     {
00055         util_assert(false && "low voltage warning tripped");
00056         PMC->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK;
00057     }
00058 }
00059 
00060 //! - MPU is disabled and gated.
00061 //! - 8kB cache is enabled. SRAM is not cached, so no flushing is required for normal operation.
00062 //! - Enable low voltage warning interrupt.
00063 //! - Disable USB current limiter so the voltage doesn't drop as we enable high speed clocks.
00064 void sdk_init(void)
00065 {
00066     CLOCK_SetXtal0Freq(16000000U); // 16 MHz crystal
00067     CLOCK_SetXtal32Freq(0);
00068 
00069     // Disable the MPU if it's enabled.
00070     if (SIM->SCGC7 & SIM_SCGC7_MPU_MASK)
00071     {
00072         SYSMPU->CESR = 0;
00073         SIM->SCGC7 &= ~SIM_SCGC7_MPU_MASK;
00074     }
00075 
00076     // Invalidate and enable code cache.
00077     LMEM->PCCCR = LMEM_PCCCR_GO_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_ENCACHE_MASK;
00078 
00079     // Enable LVD/LVW IRQ.
00080     PMC->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK;
00081     PMC->LVDSC1 = PMC_LVDSC1_LVDIE_MASK | PMC_LVDSC1_LVDV(0); // low trip point
00082     PMC->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK;
00083     PMC->LVDSC2 = PMC_LVDSC2_LVWIE_MASK | PMC_LVDSC2_LVWV(0); // low trip point
00084 //     NVIC_EnableIRQ(LVD_LVW_IRQn);
00085 
00086     // Disable USB inrush current limiter.
00087     SIM->USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM_MASK;
00088 }
00089 
00090 //! - Turn on 16MHz crystal oscillator.
00091 //! - Turn on 32kHz IRC.
00092 //! - Switch core clock to System PLL at 120 MHz, bus clock at 60 MHz, flash clock at 24 MHz.
00093 //! - Enable the 480MHz USB PHY PLL.
00094 //! - Ungate USBPHY and USBHS.
00095 //! - Configure the USB PHY.
00096 void hic_enable_usb_clocks(void)
00097 {
00098     // Enable external oscillator and 32kHz IRC.
00099     MCG->C1 |= MCG_C1_IRCLKEN_MASK; // Select 32k IR.
00100     // Delay at least 100µs for 32kHz IRQ to stabilize.
00101     fll_delay();
00102     // Configure OSC for very high freq, low power mode.
00103     MCG->C2 = (MCG->C2 & ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK)) | MCG_C2_RANGE(2);
00104     OSC0->CR |= OSC_CR_ERCLKEN_MASK; // Enable OSC.
00105     MCG->C2 |= MCG_C2_EREFS_MASK; // Select OSC as ext ref.
00106 
00107     // Wait for the oscillator to stabilize.
00108     while (!(MCG->S & MCG_S_OSCINIT0_MASK))
00109     {
00110     }
00111 
00112     // Divide 16MHz xtal by 512 = 31.25kHz
00113     CLOCK_SetFbeMode(4, kMCG_Dmx32Default , kMCG_DrsMid , fll_delay);
00114 
00115     // Set dividers before switching to SYSPLL.
00116     SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0)       // System/core  /1 = 120MHz
00117                     | SIM_CLKDIV1_OUTDIV2(1)    // Bus          /2 = 60Mhz
00118                     | SIM_CLKDIV1_OUTDIV3(4)    // FlexBus      /5 = 24Mhz
00119                     | SIM_CLKDIV1_OUTDIV4(4);   // Flash        /5 = 24MHz
00120 
00121     // 120MHz SYSPLL
00122     mcg_pll_config_t pllConfig;
00123     pllConfig.enableMode  = 0;
00124     pllConfig.prdiv  = 2 - 1;
00125     pllConfig.vdiv  = 30 - 16;
00126     CLOCK_SetPbeMode(kMCG_PllClkSelPll0 , &pllConfig);
00127     CLOCK_SetPeeMode();
00128 
00129     // Enable USB clock source and init phy. This turns on the 480MHz PLL.
00130     CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0 , CLOCK_GetFreq(kCLOCK_PllFllSelClk ));
00131     USB_EhciPhyInit(0, CPU_XTAL_CLK_HZ);
00132 
00133     SystemCoreClockUpdate();
00134 }
00135 
00136 void hic_power_target(void)
00137 {
00138     // Keep powered off in bootloader mode
00139     // to prevent the target from effecting the state
00140     // of the reset line / reset button
00141     if (!daplink_is_bootloader()) {
00142         // configure pin as GPIO
00143         PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1);
00144         // force always on logic 1
00145         PIN_POWER_EN_GPIO->PSOR = 1UL << PIN_POWER_EN_BIT;
00146         PIN_POWER_EN_GPIO->PDDR |= 1UL << PIN_POWER_EN_BIT;
00147 
00148         // Let the voltage rails stabilize.  This is especailly important
00149         // during software resets, since the target's 3.3v rail can take
00150         // 20-50ms to drain.  During this time the target could be driving
00151         // the reset pin low, causing the bootloader to think the reset
00152         // button is pressed.
00153         // Note: With optimization set to -O2 the value 5115 delays for ~1ms @ 20.9Mhz core
00154         busy_wait(5115 * 50);
00155     }
00156 }