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 main.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief DAPLink Bootloader application entry point
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include "main.h"
Pawel Zarembski 0:01f31e923fe2 23 #include "gpio.h"
Pawel Zarembski 0:01f31e923fe2 24 #include "validation.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "vfs_manager.h"
Pawel Zarembski 0:01f31e923fe2 26 #include "cmsis_os2.h"
Pawel Zarembski 0:01f31e923fe2 27 #include "rl_usb.h"
Pawel Zarembski 0:01f31e923fe2 28 #include "settings.h"
Pawel Zarembski 0:01f31e923fe2 29 #include "info.h"
Pawel Zarembski 0:01f31e923fe2 30 #include "target_config.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 32 #include "cortex_m.h"
Pawel Zarembski 0:01f31e923fe2 33 #include "sdk.h"
Pawel Zarembski 0:01f31e923fe2 34 #include "target_board.h"
Pawel Zarembski 0:01f31e923fe2 35
Pawel Zarembski 0:01f31e923fe2 36 //default msc led settings
Pawel Zarembski 0:01f31e923fe2 37 #ifndef MSC_LED_DEF
Pawel Zarembski 0:01f31e923fe2 38 #define MSC_LED_DEF GPIO_LED_ON
Pawel Zarembski 0:01f31e923fe2 39 #endif
Pawel Zarembski 0:01f31e923fe2 40
Pawel Zarembski 0:01f31e923fe2 41 __asm void modify_stack_pointer_and_start_app(uint32_t r0_sp, uint32_t r1_pc)
Pawel Zarembski 0:01f31e923fe2 42 {
Pawel Zarembski 0:01f31e923fe2 43 MOV SP, R0
Pawel Zarembski 0:01f31e923fe2 44 BX R1
Pawel Zarembski 0:01f31e923fe2 45 }
Pawel Zarembski 0:01f31e923fe2 46
Pawel Zarembski 0:01f31e923fe2 47 // Event flags for main task
Pawel Zarembski 0:01f31e923fe2 48 // Timers events
Pawel Zarembski 0:01f31e923fe2 49 #define FLAGS_MAIN_90MS (1 << 0)
Pawel Zarembski 0:01f31e923fe2 50 #define FLAGS_MAIN_30MS (1 << 1)
Pawel Zarembski 0:01f31e923fe2 51 // USB Events
Pawel Zarembski 0:01f31e923fe2 52 #define FLAGS_MAIN_PROC_USB (1 << 9)
Pawel Zarembski 0:01f31e923fe2 53 // Used by msc when flashing a new binary
Pawel Zarembski 0:01f31e923fe2 54 #define FLAGS_LED_BLINK_30MS (1 << 6)
Pawel Zarembski 0:01f31e923fe2 55
Pawel Zarembski 0:01f31e923fe2 56 // Timing constants (in 90mS ticks)
Pawel Zarembski 0:01f31e923fe2 57 // USB busy time
Pawel Zarembski 0:01f31e923fe2 58 #define USB_BUSY_TIME (33)
Pawel Zarembski 0:01f31e923fe2 59 // Delay before a USB device connect may occur
Pawel Zarembski 0:01f31e923fe2 60 #define USB_CONNECT_DELAY (11)
Pawel Zarembski 0:01f31e923fe2 61 // Decrement to zero
Pawel Zarembski 0:01f31e923fe2 62 #define DECZERO(x) (x ? --x : 0)
Pawel Zarembski 0:01f31e923fe2 63 #define NO_TIMEOUT (0xffff)
Pawel Zarembski 0:01f31e923fe2 64
Pawel Zarembski 0:01f31e923fe2 65 // Global state of usb used in
Pawel Zarembski 0:01f31e923fe2 66 main_usb_connect_t usb_state;
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 // Reference to our main task
Pawel Zarembski 0:01f31e923fe2 69 osThreadId_t main_task_id;
Pawel Zarembski 0:01f31e923fe2 70
Pawel Zarembski 0:01f31e923fe2 71 static uint8_t msc_led_usb_activity = 0;
Pawel Zarembski 0:01f31e923fe2 72 static main_led_state_t msc_led_state = MAIN_LED_FLASH;
Pawel Zarembski 0:01f31e923fe2 73
Pawel Zarembski 0:01f31e923fe2 74 static main_usb_busy_t usb_busy;
Pawel Zarembski 0:01f31e923fe2 75 static uint32_t usb_busy_count;
Pawel Zarembski 0:01f31e923fe2 76
Pawel Zarembski 0:01f31e923fe2 77 // Timer task, set flags every 30mS and 90mS
Pawel Zarembski 0:01f31e923fe2 78 void timer_task_30mS(void * arg)
Pawel Zarembski 0:01f31e923fe2 79 {
Pawel Zarembski 0:01f31e923fe2 80 static uint32_t i = 0;
Pawel Zarembski 0:01f31e923fe2 81 osThreadFlagsSet(main_task_id, FLAGS_MAIN_30MS);
Pawel Zarembski 0:01f31e923fe2 82 if (!(i++ % 3)) {
Pawel Zarembski 0:01f31e923fe2 83 osThreadFlagsSet(main_task_id, FLAGS_MAIN_90MS);
Pawel Zarembski 0:01f31e923fe2 84 }
Pawel Zarembski 0:01f31e923fe2 85 }
Pawel Zarembski 0:01f31e923fe2 86
Pawel Zarembski 0:01f31e923fe2 87 // Flash MSC LED using 30mS tick
Pawel Zarembski 0:01f31e923fe2 88 void main_blink_msc_led(main_led_state_t state)
Pawel Zarembski 0:01f31e923fe2 89 {
Pawel Zarembski 0:01f31e923fe2 90 msc_led_usb_activity = 1;
Pawel Zarembski 0:01f31e923fe2 91 msc_led_state = state;
Pawel Zarembski 0:01f31e923fe2 92 return;
Pawel Zarembski 0:01f31e923fe2 93 }
Pawel Zarembski 0:01f31e923fe2 94
Pawel Zarembski 0:01f31e923fe2 95 void USBD_SignalHandler()
Pawel Zarembski 0:01f31e923fe2 96 {
Pawel Zarembski 0:01f31e923fe2 97 osThreadFlagsSet(main_task_id, FLAGS_MAIN_PROC_USB);
Pawel Zarembski 0:01f31e923fe2 98 }
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 void main_task(void * arg)
Pawel Zarembski 0:01f31e923fe2 101 {
Pawel Zarembski 0:01f31e923fe2 102 // State processing
Pawel Zarembski 0:01f31e923fe2 103 uint16_t flags;
Pawel Zarembski 0:01f31e923fe2 104 // LED
Pawel Zarembski 0:01f31e923fe2 105 gpio_led_state_t msc_led_value = MSC_LED_DEF;
Pawel Zarembski 0:01f31e923fe2 106 // USB
Pawel Zarembski 0:01f31e923fe2 107 uint32_t usb_state_count;
Pawel Zarembski 0:01f31e923fe2 108
Pawel Zarembski 0:01f31e923fe2 109 if (config_ram_get_initial_hold_in_bl()) {
Pawel Zarembski 0:01f31e923fe2 110 // Delay for 1 second for VMs
Pawel Zarembski 0:01f31e923fe2 111 osDelay(100);
Pawel Zarembski 0:01f31e923fe2 112 }
Pawel Zarembski 0:01f31e923fe2 113
Pawel Zarembski 0:01f31e923fe2 114 // Get a reference to this task
Pawel Zarembski 0:01f31e923fe2 115 main_task_id = osThreadGetId();
Pawel Zarembski 0:01f31e923fe2 116 // Set LED defaults
Pawel Zarembski 0:01f31e923fe2 117 gpio_set_hid_led(GPIO_LED_OFF);
Pawel Zarembski 0:01f31e923fe2 118 gpio_set_cdc_led(GPIO_LED_OFF);
Pawel Zarembski 0:01f31e923fe2 119 gpio_set_msc_led(msc_led_value);
Pawel Zarembski 0:01f31e923fe2 120 // Update version information file
Pawel Zarembski 0:01f31e923fe2 121 info_init();
Pawel Zarembski 0:01f31e923fe2 122 // USB
Pawel Zarembski 0:01f31e923fe2 123 usbd_init();
Pawel Zarembski 0:01f31e923fe2 124 vfs_mngr_init(true);
Pawel Zarembski 0:01f31e923fe2 125 usbd_connect(0);
Pawel Zarembski 0:01f31e923fe2 126 usb_busy = MAIN_USB_IDLE;
Pawel Zarembski 0:01f31e923fe2 127 usb_busy_count = 0;
Pawel Zarembski 0:01f31e923fe2 128 usb_state = MAIN_USB_CONNECTING;
Pawel Zarembski 0:01f31e923fe2 129 usb_state_count = USB_CONNECT_DELAY;
Pawel Zarembski 0:01f31e923fe2 130 // Start timer tasks
Pawel Zarembski 0:01f31e923fe2 131 osTimerId_t tmr_id = osTimerNew(timer_task_30mS, osTimerPeriodic, NULL, NULL);
Pawel Zarembski 0:01f31e923fe2 132 osTimerStart(tmr_id, 3);
Pawel Zarembski 0:01f31e923fe2 133
Pawel Zarembski 0:01f31e923fe2 134 while (1) {
Pawel Zarembski 0:01f31e923fe2 135 // need to create a new event for programming failure
Pawel Zarembski 0:01f31e923fe2 136 flags = osThreadFlagsWait(FLAGS_MAIN_90MS // 90mS tick
Pawel Zarembski 0:01f31e923fe2 137 | FLAGS_MAIN_30MS // 30mS tick
Pawel Zarembski 0:01f31e923fe2 138 | FLAGS_MAIN_PROC_USB // process usb events
Pawel Zarembski 0:01f31e923fe2 139 , osFlagsWaitAny,
Pawel Zarembski 0:01f31e923fe2 140 osWaitForever);
Pawel Zarembski 0:01f31e923fe2 141
Pawel Zarembski 0:01f31e923fe2 142 if (flags & FLAGS_MAIN_PROC_USB) {
Pawel Zarembski 0:01f31e923fe2 143 USBD_Handler();
Pawel Zarembski 0:01f31e923fe2 144 }
Pawel Zarembski 0:01f31e923fe2 145
Pawel Zarembski 0:01f31e923fe2 146 if (flags & FLAGS_MAIN_90MS) {
Pawel Zarembski 0:01f31e923fe2 147 vfs_mngr_periodic(90); // FLAGS_MAIN_90MS
Pawel Zarembski 0:01f31e923fe2 148
Pawel Zarembski 0:01f31e923fe2 149 // Update USB busy status
Pawel Zarembski 0:01f31e923fe2 150 switch (usb_busy) {
Pawel Zarembski 0:01f31e923fe2 151 case MAIN_USB_ACTIVE:
Pawel Zarembski 0:01f31e923fe2 152 if (DECZERO(usb_busy_count) == 0) {
Pawel Zarembski 0:01f31e923fe2 153 usb_busy = MAIN_USB_IDLE;
Pawel Zarembski 0:01f31e923fe2 154 }
Pawel Zarembski 0:01f31e923fe2 155
Pawel Zarembski 0:01f31e923fe2 156 break;
Pawel Zarembski 0:01f31e923fe2 157
Pawel Zarembski 0:01f31e923fe2 158 case MAIN_USB_IDLE:
Pawel Zarembski 0:01f31e923fe2 159 default:
Pawel Zarembski 0:01f31e923fe2 160 break;
Pawel Zarembski 0:01f31e923fe2 161 }
Pawel Zarembski 0:01f31e923fe2 162
Pawel Zarembski 0:01f31e923fe2 163 // Update USB connect status
Pawel Zarembski 0:01f31e923fe2 164 switch (usb_state) {
Pawel Zarembski 0:01f31e923fe2 165 case MAIN_USB_DISCONNECTING:
Pawel Zarembski 0:01f31e923fe2 166
Pawel Zarembski 0:01f31e923fe2 167 // Wait until USB is idle before disconnecting
Pawel Zarembski 0:01f31e923fe2 168 if (usb_busy == MAIN_USB_IDLE && (DECZERO(usb_state_count) == 0)) {
Pawel Zarembski 0:01f31e923fe2 169 usbd_connect(0);
Pawel Zarembski 0:01f31e923fe2 170 usb_state = MAIN_USB_DISCONNECTED;
Pawel Zarembski 0:01f31e923fe2 171 }
Pawel Zarembski 0:01f31e923fe2 172
Pawel Zarembski 0:01f31e923fe2 173 break;
Pawel Zarembski 0:01f31e923fe2 174
Pawel Zarembski 0:01f31e923fe2 175 case MAIN_USB_CONNECTING:
Pawel Zarembski 0:01f31e923fe2 176
Pawel Zarembski 0:01f31e923fe2 177 // Wait before connecting
Pawel Zarembski 0:01f31e923fe2 178 if (DECZERO(usb_state_count) == 0) {
Pawel Zarembski 0:01f31e923fe2 179 usbd_connect(1);
Pawel Zarembski 0:01f31e923fe2 180 usb_state = MAIN_USB_CHECK_CONNECTED;
Pawel Zarembski 0:01f31e923fe2 181 }
Pawel Zarembski 0:01f31e923fe2 182
Pawel Zarembski 0:01f31e923fe2 183 break;
Pawel Zarembski 0:01f31e923fe2 184
Pawel Zarembski 0:01f31e923fe2 185 case MAIN_USB_CHECK_CONNECTED:
Pawel Zarembski 0:01f31e923fe2 186 if (usbd_configured()) {
Pawel Zarembski 0:01f31e923fe2 187 usb_state = MAIN_USB_CONNECTED;
Pawel Zarembski 0:01f31e923fe2 188 }
Pawel Zarembski 0:01f31e923fe2 189
Pawel Zarembski 0:01f31e923fe2 190 break;
Pawel Zarembski 0:01f31e923fe2 191
Pawel Zarembski 0:01f31e923fe2 192 case MAIN_USB_DISCONNECTED:
Pawel Zarembski 0:01f31e923fe2 193 SystemReset();
Pawel Zarembski 0:01f31e923fe2 194 break;
Pawel Zarembski 0:01f31e923fe2 195
Pawel Zarembski 0:01f31e923fe2 196 case MAIN_USB_CONNECTED:
Pawel Zarembski 0:01f31e923fe2 197 default:
Pawel Zarembski 0:01f31e923fe2 198 break;
Pawel Zarembski 0:01f31e923fe2 199 }
Pawel Zarembski 0:01f31e923fe2 200 }
Pawel Zarembski 0:01f31e923fe2 201
Pawel Zarembski 0:01f31e923fe2 202 // 30mS tick used for flashing LED when USB is busy
Pawel Zarembski 0:01f31e923fe2 203 if (flags & FLAGS_MAIN_30MS) {
Pawel Zarembski 0:01f31e923fe2 204 if (msc_led_usb_activity) {
Pawel Zarembski 0:01f31e923fe2 205
Pawel Zarembski 0:01f31e923fe2 206 if ((msc_led_state == MAIN_LED_FLASH) || (msc_led_state == MAIN_LED_FLASH_PERMANENT)) {
Pawel Zarembski 0:01f31e923fe2 207 // Toggle LED value
Pawel Zarembski 0:01f31e923fe2 208 msc_led_value = (GPIO_LED_ON == msc_led_value) ? GPIO_LED_OFF : GPIO_LED_ON;
Pawel Zarembski 0:01f31e923fe2 209 // If in flash mode stop after one cycle but in bootloader LED stays on
Pawel Zarembski 0:01f31e923fe2 210 if ((MSC_LED_DEF == msc_led_value) && (MAIN_LED_FLASH == msc_led_state)) {
Pawel Zarembski 0:01f31e923fe2 211 msc_led_usb_activity = 0;
Pawel Zarembski 0:01f31e923fe2 212 msc_led_state = MAIN_LED_DEF;
Pawel Zarembski 0:01f31e923fe2 213 }
Pawel Zarembski 0:01f31e923fe2 214
Pawel Zarembski 0:01f31e923fe2 215 }else{
Pawel Zarembski 0:01f31e923fe2 216 //LED next state is MAIN_LED_DEF
Pawel Zarembski 0:01f31e923fe2 217 msc_led_value = MSC_LED_DEF;
Pawel Zarembski 0:01f31e923fe2 218 msc_led_usb_activity = 0;
Pawel Zarembski 0:01f31e923fe2 219 }
Pawel Zarembski 0:01f31e923fe2 220
Pawel Zarembski 0:01f31e923fe2 221 // Update hardware
Pawel Zarembski 0:01f31e923fe2 222 gpio_set_msc_led(msc_led_value);
Pawel Zarembski 0:01f31e923fe2 223 }
Pawel Zarembski 0:01f31e923fe2 224 }
Pawel Zarembski 0:01f31e923fe2 225 }
Pawel Zarembski 0:01f31e923fe2 226 }
Pawel Zarembski 0:01f31e923fe2 227
Pawel Zarembski 0:01f31e923fe2 228 int main(void)
Pawel Zarembski 0:01f31e923fe2 229 {
Pawel Zarembski 0:01f31e923fe2 230 // initialize vendor sdk
Pawel Zarembski 0:01f31e923fe2 231 sdk_init();
Pawel Zarembski 0:01f31e923fe2 232 // init leds and button
Pawel Zarembski 0:01f31e923fe2 233 gpio_init();
Pawel Zarembski 0:01f31e923fe2 234 // init settings
Pawel Zarembski 0:01f31e923fe2 235 config_init();
Pawel Zarembski 0:01f31e923fe2 236
Pawel Zarembski 0:01f31e923fe2 237 // check for invalid app image or rst button press. Should be checksum or CRC but NVIC validation is better than nothing.
Pawel Zarembski 0:01f31e923fe2 238 // If the interface has set the hold in bootloader setting don't jump to app
Pawel Zarembski 0:01f31e923fe2 239 if (!gpio_get_reset_btn() && g_board_info.target_cfg && validate_bin_nvic((uint8_t *)g_board_info.target_cfg->flash_regions[0].start) && !config_ram_get_initial_hold_in_bl()) {
Pawel Zarembski 0:01f31e923fe2 240 // change to the new vector table
Pawel Zarembski 0:01f31e923fe2 241 SCB->VTOR = g_board_info.target_cfg->flash_regions[0].start; //bootloaders should only have one flash region for interface
Pawel Zarembski 0:01f31e923fe2 242 // modify stack pointer and start app
Pawel Zarembski 0:01f31e923fe2 243 modify_stack_pointer_and_start_app((*(uint32_t *)(g_board_info.target_cfg->flash_regions[0].start)), (*(uint32_t *)(g_board_info.target_cfg->flash_regions[0].start + 4)));
Pawel Zarembski 0:01f31e923fe2 244 }
Pawel Zarembski 0:01f31e923fe2 245
Pawel Zarembski 0:01f31e923fe2 246 // config the usb interface descriptor and web auth token before USB connects
Pawel Zarembski 0:01f31e923fe2 247 //unique_string_auth_config();
Pawel Zarembski 0:01f31e923fe2 248 // either the rst pin was pressed or we have an empty app region
Pawel Zarembski 0:01f31e923fe2 249 osKernelInitialize(); // Initialize CMSIS-RTOS
Pawel Zarembski 0:01f31e923fe2 250 osThreadNew(main_task, NULL, NULL); // Create application main thread
Pawel Zarembski 0:01f31e923fe2 251 osKernelStart(); // Start thread execution
Pawel Zarembski 0:01f31e923fe2 252 for (;;) {}
Pawel Zarembski 0:01f31e923fe2 253 }