Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
Diff: source/daplink/bootloader/main.c
- Revision:
- 0:01f31e923fe2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/daplink/bootloader/main.c Tue Apr 07 12:55:42 2020 +0200 @@ -0,0 +1,253 @@ +/** + * @file main.c + * @brief DAPLink Bootloader application entry point + * + * DAPLink Interface Firmware + * Copyright (c) 2009-2019, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "main.h" +#include "gpio.h" +#include "validation.h" +#include "vfs_manager.h" +#include "cmsis_os2.h" +#include "rl_usb.h" +#include "settings.h" +#include "info.h" +#include "target_config.h" +#include "util.h" +#include "cortex_m.h" +#include "sdk.h" +#include "target_board.h" + +//default msc led settings +#ifndef MSC_LED_DEF +#define MSC_LED_DEF GPIO_LED_ON +#endif + +__asm void modify_stack_pointer_and_start_app(uint32_t r0_sp, uint32_t r1_pc) +{ + MOV SP, R0 + BX R1 +} + +// Event flags for main task +// Timers events +#define FLAGS_MAIN_90MS (1 << 0) +#define FLAGS_MAIN_30MS (1 << 1) +// USB Events +#define FLAGS_MAIN_PROC_USB (1 << 9) +// Used by msc when flashing a new binary +#define FLAGS_LED_BLINK_30MS (1 << 6) + +// Timing constants (in 90mS ticks) +// USB busy time +#define USB_BUSY_TIME (33) +// Delay before a USB device connect may occur +#define USB_CONNECT_DELAY (11) +// Decrement to zero +#define DECZERO(x) (x ? --x : 0) +#define NO_TIMEOUT (0xffff) + +// Global state of usb used in +main_usb_connect_t usb_state; + +// Reference to our main task +osThreadId_t main_task_id; + +static uint8_t msc_led_usb_activity = 0; +static main_led_state_t msc_led_state = MAIN_LED_FLASH; + +static main_usb_busy_t usb_busy; +static uint32_t usb_busy_count; + +// Timer task, set flags every 30mS and 90mS +void timer_task_30mS(void * arg) +{ + static uint32_t i = 0; + osThreadFlagsSet(main_task_id, FLAGS_MAIN_30MS); + if (!(i++ % 3)) { + osThreadFlagsSet(main_task_id, FLAGS_MAIN_90MS); + } +} + +// Flash MSC LED using 30mS tick +void main_blink_msc_led(main_led_state_t state) +{ + msc_led_usb_activity = 1; + msc_led_state = state; + return; +} + +void USBD_SignalHandler() +{ + osThreadFlagsSet(main_task_id, FLAGS_MAIN_PROC_USB); +} + +void main_task(void * arg) +{ + // State processing + uint16_t flags; + // LED + gpio_led_state_t msc_led_value = MSC_LED_DEF; + // USB + uint32_t usb_state_count; + + if (config_ram_get_initial_hold_in_bl()) { + // Delay for 1 second for VMs + osDelay(100); + } + + // Get a reference to this task + main_task_id = osThreadGetId(); + // Set LED defaults + gpio_set_hid_led(GPIO_LED_OFF); + gpio_set_cdc_led(GPIO_LED_OFF); + gpio_set_msc_led(msc_led_value); + // Update version information file + info_init(); + // USB + usbd_init(); + vfs_mngr_init(true); + usbd_connect(0); + usb_busy = MAIN_USB_IDLE; + usb_busy_count = 0; + usb_state = MAIN_USB_CONNECTING; + usb_state_count = USB_CONNECT_DELAY; + // Start timer tasks + osTimerId_t tmr_id = osTimerNew(timer_task_30mS, osTimerPeriodic, NULL, NULL); + osTimerStart(tmr_id, 3); + + while (1) { + // need to create a new event for programming failure + flags = osThreadFlagsWait(FLAGS_MAIN_90MS // 90mS tick + | FLAGS_MAIN_30MS // 30mS tick + | FLAGS_MAIN_PROC_USB // process usb events + , osFlagsWaitAny, + osWaitForever); + + if (flags & FLAGS_MAIN_PROC_USB) { + USBD_Handler(); + } + + if (flags & FLAGS_MAIN_90MS) { + vfs_mngr_periodic(90); // FLAGS_MAIN_90MS + + // Update USB busy status + switch (usb_busy) { + case MAIN_USB_ACTIVE: + if (DECZERO(usb_busy_count) == 0) { + usb_busy = MAIN_USB_IDLE; + } + + break; + + case MAIN_USB_IDLE: + default: + break; + } + + // Update USB connect status + switch (usb_state) { + case MAIN_USB_DISCONNECTING: + + // Wait until USB is idle before disconnecting + if (usb_busy == MAIN_USB_IDLE && (DECZERO(usb_state_count) == 0)) { + usbd_connect(0); + usb_state = MAIN_USB_DISCONNECTED; + } + + break; + + case MAIN_USB_CONNECTING: + + // Wait before connecting + if (DECZERO(usb_state_count) == 0) { + usbd_connect(1); + usb_state = MAIN_USB_CHECK_CONNECTED; + } + + break; + + case MAIN_USB_CHECK_CONNECTED: + if (usbd_configured()) { + usb_state = MAIN_USB_CONNECTED; + } + + break; + + case MAIN_USB_DISCONNECTED: + SystemReset(); + break; + + case MAIN_USB_CONNECTED: + default: + break; + } + } + + // 30mS tick used for flashing LED when USB is busy + if (flags & FLAGS_MAIN_30MS) { + if (msc_led_usb_activity) { + + if ((msc_led_state == MAIN_LED_FLASH) || (msc_led_state == MAIN_LED_FLASH_PERMANENT)) { + // Toggle LED value + msc_led_value = (GPIO_LED_ON == msc_led_value) ? GPIO_LED_OFF : GPIO_LED_ON; + // If in flash mode stop after one cycle but in bootloader LED stays on + if ((MSC_LED_DEF == msc_led_value) && (MAIN_LED_FLASH == msc_led_state)) { + msc_led_usb_activity = 0; + msc_led_state = MAIN_LED_DEF; + } + + }else{ + //LED next state is MAIN_LED_DEF + msc_led_value = MSC_LED_DEF; + msc_led_usb_activity = 0; + } + + // Update hardware + gpio_set_msc_led(msc_led_value); + } + } + } +} + +int main(void) +{ + // initialize vendor sdk + sdk_init(); + // init leds and button + gpio_init(); + // init settings + config_init(); + + // check for invalid app image or rst button press. Should be checksum or CRC but NVIC validation is better than nothing. + // If the interface has set the hold in bootloader setting don't jump to app + 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()) { + // change to the new vector table + SCB->VTOR = g_board_info.target_cfg->flash_regions[0].start; //bootloaders should only have one flash region for interface + // modify stack pointer and start app + 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))); + } + + // config the usb interface descriptor and web auth token before USB connects + //unique_string_auth_config(); + // either the rst pin was pressed or we have an empty app region + osKernelInitialize(); // Initialize CMSIS-RTOS + osThreadNew(main_task, NULL, NULL); // Create application main thread + osKernelStart(); // Start thread execution + for (;;) {} +}