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

« Back to documentation index

Show/hide line numbers gpio.c Source File

gpio.c

00001 /**
00002  * @file    gpio.c
00003  * @brief
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #include "LPC11Uxx.h"
00023 #include "gpio.h"
00024 #include "compiler.h"
00025 #include "IO_Config.h"
00026 #include "settings.h"
00027 #include "iap.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 void gpio_init(void)
00040 {
00041     // enable clock for GPIO port 0
00042     LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6);
00043 #if defined(TARGET_POWER_HOLD)
00044     // Target PowerHOLD port
00045     PIN_PWH_IOCON = PIN_PWH_IOCON_INIT;
00046     LPC_GPIO->CLR[PIN_PWH_PORT] = PIN_PWH;
00047     LPC_GPIO->DIR[PIN_PWH_PORT] |= PIN_PWH;
00048 #endif
00049     // configure GPIO-LED as output
00050 #if defined(CONTROLLED_POWER_LED)
00051     // Power led (red)
00052     PIN_POW_LED_IOCON = PIN_POW_LED_IOCON_INIT;
00053     LPC_GPIO->CLR[PIN_POW_LED_PORT] = PIN_POW_LED;
00054     LPC_GPIO->DIR[PIN_POW_LED_PORT] |= PIN_POW_LED;
00055 #endif
00056     // DAP led (green)
00057     PIN_DAP_LED_IOCON = PIN_DAP_LED_IOCON_INIT;
00058     LPC_GPIO->SET[PIN_DAP_LED_PORT] = PIN_DAP_LED;
00059     LPC_GPIO->DIR[PIN_DAP_LED_PORT] |= PIN_DAP_LED;
00060     // MSD led (red)
00061     PIN_MSD_LED_IOCON = PIN_MSD_LED_IOCON_INIT;
00062     LPC_GPIO->SET[PIN_MSD_LED_PORT] = PIN_MSD_LED;
00063     LPC_GPIO->DIR[PIN_MSD_LED_PORT] |= PIN_MSD_LED;
00064     // Serial LED (blue)
00065     PIN_CDC_LED_IOCON = PIN_CDC_LED_IOCON_INIT;
00066     LPC_GPIO->SET[PIN_CDC_LED_PORT] = PIN_CDC_LED;
00067     LPC_GPIO->DIR[PIN_CDC_LED_PORT] |= PIN_CDC_LED;
00068     // configure Button(s) as input
00069     PIN_RESET_IN_IOCON = PIN_RESET_IN_IOCON_INIT;
00070     LPC_GPIO->DIR[PIN_RESET_IN_PORT] &= ~PIN_RESET_IN;
00071     PIN_RESET_IN_FWRD_IOCON = PIN_RESET_IN_FWRD_IOCON_INIT;
00072     LPC_GPIO->DIR[PIN_RESET_IN_FWRD_PORT] &= ~PIN_RESET_IN_FWRD;
00073 #if !defined(PIN_nRESET_FET_DRIVE)
00074     // open drain logic for reset button
00075     PIN_nRESET_IOCON = PIN_nRESET_IOCON_INIT;
00076     LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
00077     LPC_GPIO->DIR[PIN_nRESET_PORT] &= ~PIN_nRESET;
00078 #else
00079     // FET drive logic for reset button
00080     PIN_nRESET_IOCON = PIN_nRESET_IOCON_INIT;
00081     LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
00082     LPC_GPIO->DIR[PIN_nRESET_PORT] |= PIN_nRESET;
00083 #endif
00084     /* Enable AHB clock to the FlexInt, GroupedInt domain. */
00085     LPC_SYSCON->SYSAHBCLKCTRL |= ((1 << 19) | (1 << 23) | (1 << 24));
00086     // Give the cap on the reset button time to charge
00087     busy_wait(10000);
00088 
00089     if (gpio_get_reset_btn() || config_ram_get_initial_hold_in_bl()) {
00090         IRQn_Type irq;
00091         // Disable SYSTICK timer and interrupt before calling into ISP
00092         SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
00093 
00094         // Disable all nvic interrupts
00095         for (irq = (IRQn_Type)0; irq < (IRQn_Type )32; irq++) {
00096             NVIC_DisableIRQ(irq);
00097             NVIC_ClearPendingIRQ(irq);
00098         }
00099 
00100         // If switching to "bootloader" mode then setup the watchdog
00101         // so it will exit CRP mode after ~30 seconds
00102         if (config_ram_get_initial_hold_in_bl()) {
00103             LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 15); // Enable watchdog module
00104             LPC_SYSCON->PDRUNCFG &= ~(1 << 6);      // Enable watchdog clock (WDOSC)
00105             LPC_SYSCON->WDTOSCCTRL = (0xF << 5);    // Set max frequency - 2.3MHz
00106             LPC_WWDT->CLKSEL = (1 << 0);            // Select watchdog clock
00107             LPC_WWDT->TC = 0x00FFFFFF;              // Set time to reset to ~29s
00108             LPC_WWDT->MOD = (1 << 0) | (1 << 1);    // Enable watchdog and set reset
00109             LPC_WWDT->FEED = 0xAA;                  // Enable watchdog
00110             LPC_WWDT->FEED = 0x55;
00111         }
00112 
00113         iap_reinvoke();
00114     }
00115 }
00116 
00117 void gpio_set_hid_led(gpio_led_state_t state)
00118 {
00119     if (state) {
00120         LPC_GPIO->CLR[PIN_DAP_LED_PORT] = PIN_DAP_LED;
00121     } else {
00122         LPC_GPIO->SET[PIN_DAP_LED_PORT] = PIN_DAP_LED;
00123     }
00124 }
00125 
00126 void gpio_set_cdc_led(gpio_led_state_t state)
00127 {
00128     if (state) {
00129         LPC_GPIO->CLR[PIN_CDC_LED_PORT] = PIN_CDC_LED;
00130     } else {
00131         LPC_GPIO->SET[PIN_CDC_LED_PORT] = PIN_CDC_LED;
00132     }
00133 }
00134 
00135 void gpio_set_msc_led(gpio_led_state_t state)
00136 {
00137     if (state) {
00138         LPC_GPIO->CLR[PIN_MSD_LED_PORT] = PIN_MSD_LED;
00139     } else {
00140         LPC_GPIO->SET[PIN_MSD_LED_PORT] = PIN_MSD_LED;
00141     }
00142 }
00143 
00144 uint8_t gpio_get_reset_btn_no_fwrd()
00145 {
00146     return LPC_GPIO->PIN[PIN_RESET_IN_PORT] & PIN_RESET_IN ? 0 : 1;
00147 }
00148 
00149 uint8_t gpio_get_reset_btn_fwrd()
00150 {
00151     return LPC_GPIO->PIN[PIN_RESET_IN_FWRD_PORT] & PIN_RESET_IN_FWRD ? 0 : 1;
00152 }
00153 
00154 void gpio_set_board_power(bool powerEnabled)
00155 {
00156 }