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 "stm32f1xx.h"
00023 #include "DAP_config.h"
00024 #include "gpio.h"
00025 #include "daplink.h"
00026 #include "util.h"
00027 
00028 static TIM_HandleTypeDef timer;
00029 
00030 static void busy_wait(uint32_t cycles)
00031 {
00032     volatile uint32_t i;
00033     i = cycles;
00034 
00035     while (i > 0) {
00036         i--;
00037     }
00038 }
00039 
00040 static uint32_t tim1_clk_div(uint32_t apb2clkdiv)
00041 {
00042     switch (apb2clkdiv) {
00043         case RCC_CFGR_PPRE2_DIV2:
00044             return 1;
00045         case RCC_CFGR_PPRE2_DIV4:
00046             return 2;
00047         case RCC_CFGR_PPRE2_DIV8:
00048             return 4;
00049         default: // RCC_CFGR_PPRE2_DIV1
00050             return 1;
00051     }
00052 }
00053 
00054 static void output_clock_enable(void)
00055 {
00056     HAL_StatusTypeDef ret;
00057     RCC_ClkInitTypeDef clk_init;
00058     TIM_OC_InitTypeDef pwm_config;
00059     uint32_t unused;
00060     uint32_t period;
00061     uint32_t source_clock;
00062 
00063     HAL_RCC_GetClockConfig(&clk_init, &unused);
00064 
00065     /* Compute the period value to have TIMx counter clock equal to 8000000 Hz */
00066     source_clock = SystemCoreClock / tim1_clk_div(clk_init.APB2CLKDivider);
00067     period = (uint32_t)(source_clock / 8000000) - 1;
00068 
00069     /* Set TIMx instance */
00070     timer.Instance = TIM1;
00071 
00072     timer.Init.Period            = period;
00073     timer.Init.Prescaler         = 0;
00074     timer.Init.ClockDivision     = 0;
00075     timer.Init.CounterMode       = TIM_COUNTERMODE_UP;
00076     timer.Init.RepetitionCounter = 0;//period / 2;
00077 
00078     __HAL_RCC_TIM1_CLK_ENABLE();
00079 
00080     ret = HAL_TIM_PWM_DeInit(&timer);
00081     if (ret != HAL_OK) {
00082         util_assert(0);
00083         return;
00084     }
00085 
00086     ret = HAL_TIM_PWM_Init(&timer);
00087     if (ret != HAL_OK) {
00088         util_assert(0);
00089         return;
00090     }
00091 
00092     pwm_config.OCMode = TIM_OCMODE_PWM2;
00093     pwm_config.Pulse = 0; // TODO - make sure this isn't used
00094     pwm_config.OCPolarity = TIM_OCPOLARITY_HIGH;
00095     pwm_config.OCNPolarity = TIM_OCPOLARITY_HIGH;
00096     pwm_config.OCFastMode = TIM_OCFAST_DISABLE;
00097     pwm_config.OCIdleState = TIM_OCIDLESTATE_RESET;
00098     pwm_config.OCNIdleState = TIM_OCIDLESTATE_RESET;
00099     ret = HAL_TIM_PWM_ConfigChannel(&timer, &pwm_config, TIM_CHANNEL_1);
00100     if (ret != HAL_OK) {
00101         util_assert(0);
00102         return;
00103     }
00104 
00105     __HAL_TIM_SET_COMPARE(&timer, TIM_CHANNEL_1, period / 2);
00106     ret = HAL_TIM_PWM_Start(&timer, TIM_CHANNEL_1);
00107     if (ret != HAL_OK) {
00108         util_assert(0);
00109         return;
00110     }
00111 
00112     return;
00113 }
00114 
00115 void gpio_init(void)
00116 {
00117     GPIO_InitTypeDef GPIO_InitStructure;
00118     // enable clock to ports
00119     __HAL_RCC_GPIOA_CLK_ENABLE();
00120     __HAL_RCC_GPIOB_CLK_ENABLE();
00121     __HAL_RCC_GPIOC_CLK_ENABLE();
00122     __HAL_RCC_GPIOD_CLK_ENABLE();
00123     // Enable USB connect pin
00124     __HAL_RCC_AFIO_CLK_ENABLE();
00125     // Disable JTAG to free pins for other uses
00126     // Note - SWD is still enabled
00127     __HAL_AFIO_REMAP_SWJ_NOJTAG();
00128 
00129     USB_CONNECT_PORT_ENABLE();
00130     USB_CONNECT_OFF();
00131     GPIO_InitStructure.Pin = USB_CONNECT_PIN;
00132     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00133     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00134     HAL_GPIO_Init(USB_CONNECT_PORT, &GPIO_InitStructure);
00135     // configure LEDs
00136     HAL_GPIO_WritePin(RUNNING_LED_PORT, RUNNING_LED_PIN, GPIO_PIN_SET);
00137     GPIO_InitStructure.Pin = RUNNING_LED_PIN;
00138     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00139     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00140     HAL_GPIO_Init(RUNNING_LED_PORT, &GPIO_InitStructure);
00141 
00142     HAL_GPIO_WritePin(CONNECTED_LED_PORT, CONNECTED_LED_PIN, GPIO_PIN_SET);
00143     GPIO_InitStructure.Pin = CONNECTED_LED_PIN;
00144     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00145     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00146     HAL_GPIO_Init(CONNECTED_LED_PORT, &GPIO_InitStructure);
00147 
00148     HAL_GPIO_WritePin(PIN_CDC_LED_PORT, PIN_CDC_LED, GPIO_PIN_SET);
00149     GPIO_InitStructure.Pin = PIN_CDC_LED;
00150     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00151     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00152     HAL_GPIO_Init(PIN_CDC_LED_PORT, &GPIO_InitStructure);
00153 
00154     HAL_GPIO_WritePin(PIN_MSC_LED_PORT, PIN_MSC_LED, GPIO_PIN_SET);
00155     GPIO_InitStructure.Pin = PIN_MSC_LED;
00156     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00157     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00158     HAL_GPIO_Init(PIN_MSC_LED_PORT, &GPIO_InitStructure);
00159 
00160     // reset button configured as gpio open drain output with a pullup
00161     HAL_GPIO_WritePin(nRESET_PIN_PORT, nRESET_PIN, GPIO_PIN_SET);
00162     GPIO_InitStructure.Pin = nRESET_PIN;
00163     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
00164     GPIO_InitStructure.Pull = GPIO_PULLUP;
00165     HAL_GPIO_Init(nRESET_PIN_PORT, &GPIO_InitStructure);
00166 
00167     // Turn on power to the board. When the target is unpowered
00168     // it holds the reset line low.
00169     HAL_GPIO_WritePin(POWER_EN_PIN_PORT, POWER_EN_PIN, GPIO_PIN_RESET);
00170     GPIO_InitStructure.Pin = POWER_EN_PIN;
00171     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00172     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
00173     HAL_GPIO_Init(POWER_EN_PIN_PORT, &GPIO_InitStructure);
00174 
00175     // Setup the 8MHz MCO
00176     GPIO_InitStructure.Pin = GPIO_PIN_8;
00177     GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
00178     GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
00179     HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
00180     output_clock_enable();
00181 
00182     // Let the voltage rails stabilize.  This is especailly important
00183     // during software resets, since the target's 3.3v rail can take
00184     // 20-50ms to drain.  During this time the target could be driving
00185     // the reset pin low, causing the bootloader to think the reset
00186     // button is pressed.
00187     // Note: With optimization set to -O2 the value 1000000 delays for ~85ms
00188     busy_wait(1000000);
00189 }
00190 
00191 void gpio_set_hid_led(gpio_led_state_t state)
00192 {
00193     // LED is active low
00194     HAL_GPIO_WritePin(PIN_HID_LED_PORT, PIN_HID_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
00195 }
00196 
00197 void gpio_set_cdc_led(gpio_led_state_t state)
00198 {
00199     // LED is active low
00200     HAL_GPIO_WritePin(PIN_CDC_LED_PORT, PIN_CDC_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
00201 }
00202 
00203 void gpio_set_msc_led(gpio_led_state_t state)
00204 {
00205     // LED is active low
00206     HAL_GPIO_WritePin(PIN_MSC_LED_PORT, PIN_MSC_LED, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
00207 }
00208 
00209 uint8_t gpio_get_reset_btn_no_fwrd(void)
00210 {
00211     return (nRESET_PIN_PORT->IDR & nRESET_PIN) ? 0 : 1;
00212 }
00213 
00214 uint8_t gpio_get_reset_btn_fwrd(void)
00215 {
00216     return 0;
00217 }
00218 
00219 
00220 uint8_t GPIOGetButtonState(void)
00221 {
00222     return 0;
00223 }
00224 
00225 void target_forward_reset(bool assert_reset)
00226 {
00227     // Do nothing - reset is forwarded in gpio_get_sw_reset
00228 }
00229 
00230 void gpio_set_board_power(bool powerEnabled)
00231 {
00232 }