Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file hic_init.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * Copyright (c) 2016-2017 NXP
Pawel Zarembski 0:01f31e923fe2 8 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 9 *
Pawel Zarembski 0:01f31e923fe2 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 11 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 12 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 13 *
Pawel Zarembski 0:01f31e923fe2 14 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 15 *
Pawel Zarembski 0:01f31e923fe2 16 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 19 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 20 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 21 */
Pawel Zarembski 0:01f31e923fe2 22
Pawel Zarembski 0:01f31e923fe2 23 #include "hic_init.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "gpio.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "fsl_clock.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "usb_phy.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 28
Pawel Zarembski 0:01f31e923fe2 29 static void busy_wait(uint32_t cycles)
Pawel Zarembski 0:01f31e923fe2 30 {
Pawel Zarembski 0:01f31e923fe2 31 volatile uint32_t i;
Pawel Zarembski 0:01f31e923fe2 32 i = cycles;
Pawel Zarembski 0:01f31e923fe2 33
Pawel Zarembski 0:01f31e923fe2 34 while (i > 0) {
Pawel Zarembski 0:01f31e923fe2 35 i--;
Pawel Zarembski 0:01f31e923fe2 36 }
Pawel Zarembski 0:01f31e923fe2 37 }
Pawel Zarembski 0:01f31e923fe2 38
Pawel Zarembski 0:01f31e923fe2 39 static void fll_delay(void)
Pawel Zarembski 0:01f31e923fe2 40 {
Pawel Zarembski 0:01f31e923fe2 41 // ~2.5ms at 16MHz core clock
Pawel Zarembski 0:01f31e923fe2 42 busy_wait(10000);
Pawel Zarembski 0:01f31e923fe2 43 }
Pawel Zarembski 0:01f31e923fe2 44
Pawel Zarembski 0:01f31e923fe2 45 // This IRQ handler will be invoked if VDD falls below the trip point.
Pawel Zarembski 0:01f31e923fe2 46 void LVD_LVW_IRQHandler(void)
Pawel Zarembski 0:01f31e923fe2 47 {
Pawel Zarembski 0:01f31e923fe2 48 if (PMC->LVDSC1 & PMC_LVDSC1_LVDF_MASK)
Pawel Zarembski 0:01f31e923fe2 49 {
Pawel Zarembski 0:01f31e923fe2 50 util_assert(false && "low voltage detect tripped");
Pawel Zarembski 0:01f31e923fe2 51 PMC->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK;
Pawel Zarembski 0:01f31e923fe2 52 }
Pawel Zarembski 0:01f31e923fe2 53 if (PMC->LVDSC2 & PMC_LVDSC2_LVWF_MASK)
Pawel Zarembski 0:01f31e923fe2 54 {
Pawel Zarembski 0:01f31e923fe2 55 util_assert(false && "low voltage warning tripped");
Pawel Zarembski 0:01f31e923fe2 56 PMC->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK;
Pawel Zarembski 0:01f31e923fe2 57 }
Pawel Zarembski 0:01f31e923fe2 58 }
Pawel Zarembski 0:01f31e923fe2 59
Pawel Zarembski 0:01f31e923fe2 60 //! - MPU is disabled and gated.
Pawel Zarembski 0:01f31e923fe2 61 //! - 8kB cache is enabled. SRAM is not cached, so no flushing is required for normal operation.
Pawel Zarembski 0:01f31e923fe2 62 //! - Enable low voltage warning interrupt.
Pawel Zarembski 0:01f31e923fe2 63 //! - Disable USB current limiter so the voltage doesn't drop as we enable high speed clocks.
Pawel Zarembski 0:01f31e923fe2 64 void sdk_init(void)
Pawel Zarembski 0:01f31e923fe2 65 {
Pawel Zarembski 0:01f31e923fe2 66 CLOCK_SetXtal0Freq(16000000U); // 16 MHz crystal
Pawel Zarembski 0:01f31e923fe2 67 CLOCK_SetXtal32Freq(0);
Pawel Zarembski 0:01f31e923fe2 68
Pawel Zarembski 0:01f31e923fe2 69 // Disable the MPU if it's enabled.
Pawel Zarembski 0:01f31e923fe2 70 if (SIM->SCGC7 & SIM_SCGC7_MPU_MASK)
Pawel Zarembski 0:01f31e923fe2 71 {
Pawel Zarembski 0:01f31e923fe2 72 SYSMPU->CESR = 0;
Pawel Zarembski 0:01f31e923fe2 73 SIM->SCGC7 &= ~SIM_SCGC7_MPU_MASK;
Pawel Zarembski 0:01f31e923fe2 74 }
Pawel Zarembski 0:01f31e923fe2 75
Pawel Zarembski 0:01f31e923fe2 76 // Invalidate and enable code cache.
Pawel Zarembski 0:01f31e923fe2 77 LMEM->PCCCR = LMEM_PCCCR_GO_MASK | LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_ENCACHE_MASK;
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 // Enable LVD/LVW IRQ.
Pawel Zarembski 0:01f31e923fe2 80 PMC->LVDSC1 |= PMC_LVDSC1_LVDACK_MASK;
Pawel Zarembski 0:01f31e923fe2 81 PMC->LVDSC1 = PMC_LVDSC1_LVDIE_MASK | PMC_LVDSC1_LVDV(0); // low trip point
Pawel Zarembski 0:01f31e923fe2 82 PMC->LVDSC2 |= PMC_LVDSC2_LVWACK_MASK;
Pawel Zarembski 0:01f31e923fe2 83 PMC->LVDSC2 = PMC_LVDSC2_LVWIE_MASK | PMC_LVDSC2_LVWV(0); // low trip point
Pawel Zarembski 0:01f31e923fe2 84 // NVIC_EnableIRQ(LVD_LVW_IRQn);
Pawel Zarembski 0:01f31e923fe2 85
Pawel Zarembski 0:01f31e923fe2 86 // Disable USB inrush current limiter.
Pawel Zarembski 0:01f31e923fe2 87 SIM->USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM_MASK;
Pawel Zarembski 0:01f31e923fe2 88 }
Pawel Zarembski 0:01f31e923fe2 89
Pawel Zarembski 0:01f31e923fe2 90 //! - Turn on 16MHz crystal oscillator.
Pawel Zarembski 0:01f31e923fe2 91 //! - Turn on 32kHz IRC.
Pawel Zarembski 0:01f31e923fe2 92 //! - Switch core clock to System PLL at 120 MHz, bus clock at 60 MHz, flash clock at 24 MHz.
Pawel Zarembski 0:01f31e923fe2 93 //! - Enable the 480MHz USB PHY PLL.
Pawel Zarembski 0:01f31e923fe2 94 //! - Ungate USBPHY and USBHS.
Pawel Zarembski 0:01f31e923fe2 95 //! - Configure the USB PHY.
Pawel Zarembski 0:01f31e923fe2 96 void hic_enable_usb_clocks(void)
Pawel Zarembski 0:01f31e923fe2 97 {
Pawel Zarembski 0:01f31e923fe2 98 // Enable external oscillator and 32kHz IRC.
Pawel Zarembski 0:01f31e923fe2 99 MCG->C1 |= MCG_C1_IRCLKEN_MASK; // Select 32k IR.
Pawel Zarembski 0:01f31e923fe2 100 // Delay at least 100µs for 32kHz IRQ to stabilize.
Pawel Zarembski 0:01f31e923fe2 101 fll_delay();
Pawel Zarembski 0:01f31e923fe2 102 // Configure OSC for very high freq, low power mode.
Pawel Zarembski 0:01f31e923fe2 103 MCG->C2 = (MCG->C2 & ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK)) | MCG_C2_RANGE(2);
Pawel Zarembski 0:01f31e923fe2 104 OSC0->CR |= OSC_CR_ERCLKEN_MASK; // Enable OSC.
Pawel Zarembski 0:01f31e923fe2 105 MCG->C2 |= MCG_C2_EREFS_MASK; // Select OSC as ext ref.
Pawel Zarembski 0:01f31e923fe2 106
Pawel Zarembski 0:01f31e923fe2 107 // Wait for the oscillator to stabilize.
Pawel Zarembski 0:01f31e923fe2 108 while (!(MCG->S & MCG_S_OSCINIT0_MASK))
Pawel Zarembski 0:01f31e923fe2 109 {
Pawel Zarembski 0:01f31e923fe2 110 }
Pawel Zarembski 0:01f31e923fe2 111
Pawel Zarembski 0:01f31e923fe2 112 // Divide 16MHz xtal by 512 = 31.25kHz
Pawel Zarembski 0:01f31e923fe2 113 CLOCK_SetFbeMode(4, kMCG_Dmx32Default, kMCG_DrsMid, fll_delay);
Pawel Zarembski 0:01f31e923fe2 114
Pawel Zarembski 0:01f31e923fe2 115 // Set dividers before switching to SYSPLL.
Pawel Zarembski 0:01f31e923fe2 116 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) // System/core /1 = 120MHz
Pawel Zarembski 0:01f31e923fe2 117 | SIM_CLKDIV1_OUTDIV2(1) // Bus /2 = 60Mhz
Pawel Zarembski 0:01f31e923fe2 118 | SIM_CLKDIV1_OUTDIV3(4) // FlexBus /5 = 24Mhz
Pawel Zarembski 0:01f31e923fe2 119 | SIM_CLKDIV1_OUTDIV4(4); // Flash /5 = 24MHz
Pawel Zarembski 0:01f31e923fe2 120
Pawel Zarembski 0:01f31e923fe2 121 // 120MHz SYSPLL
Pawel Zarembski 0:01f31e923fe2 122 mcg_pll_config_t pllConfig;
Pawel Zarembski 0:01f31e923fe2 123 pllConfig.enableMode = 0;
Pawel Zarembski 0:01f31e923fe2 124 pllConfig.prdiv = 2 - 1;
Pawel Zarembski 0:01f31e923fe2 125 pllConfig.vdiv = 30 - 16;
Pawel Zarembski 0:01f31e923fe2 126 CLOCK_SetPbeMode(kMCG_PllClkSelPll0, &pllConfig);
Pawel Zarembski 0:01f31e923fe2 127 CLOCK_SetPeeMode();
Pawel Zarembski 0:01f31e923fe2 128
Pawel Zarembski 0:01f31e923fe2 129 // Enable USB clock source and init phy. This turns on the 480MHz PLL.
Pawel Zarembski 0:01f31e923fe2 130 CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
Pawel Zarembski 0:01f31e923fe2 131 USB_EhciPhyInit(0, CPU_XTAL_CLK_HZ);
Pawel Zarembski 0:01f31e923fe2 132
Pawel Zarembski 0:01f31e923fe2 133 SystemCoreClockUpdate();
Pawel Zarembski 0:01f31e923fe2 134 }
Pawel Zarembski 0:01f31e923fe2 135
Pawel Zarembski 0:01f31e923fe2 136 void hic_power_target(void)
Pawel Zarembski 0:01f31e923fe2 137 {
Pawel Zarembski 0:01f31e923fe2 138 // Keep powered off in bootloader mode
Pawel Zarembski 0:01f31e923fe2 139 // to prevent the target from effecting the state
Pawel Zarembski 0:01f31e923fe2 140 // of the reset line / reset button
Pawel Zarembski 0:01f31e923fe2 141 if (!daplink_is_bootloader()) {
Pawel Zarembski 0:01f31e923fe2 142 // configure pin as GPIO
Pawel Zarembski 0:01f31e923fe2 143 PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1);
Pawel Zarembski 0:01f31e923fe2 144 // force always on logic 1
Pawel Zarembski 0:01f31e923fe2 145 PIN_POWER_EN_GPIO->PSOR = 1UL << PIN_POWER_EN_BIT;
Pawel Zarembski 0:01f31e923fe2 146 PIN_POWER_EN_GPIO->PDDR |= 1UL << PIN_POWER_EN_BIT;
Pawel Zarembski 0:01f31e923fe2 147
Pawel Zarembski 0:01f31e923fe2 148 // Let the voltage rails stabilize. This is especailly important
Pawel Zarembski 0:01f31e923fe2 149 // during software resets, since the target's 3.3v rail can take
Pawel Zarembski 0:01f31e923fe2 150 // 20-50ms to drain. During this time the target could be driving
Pawel Zarembski 0:01f31e923fe2 151 // the reset pin low, causing the bootloader to think the reset
Pawel Zarembski 0:01f31e923fe2 152 // button is pressed.
Pawel Zarembski 0:01f31e923fe2 153 // Note: With optimization set to -O2 the value 5115 delays for ~1ms @ 20.9Mhz core
Pawel Zarembski 0:01f31e923fe2 154 busy_wait(5115 * 50);
Pawel Zarembski 0:01f31e923fe2 155 }
Pawel Zarembski 0:01f31e923fe2 156 }