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

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

Revision:
0:01f31e923fe2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/daplink/interface/main.c	Tue Apr 07 12:55:42 2020 +0200
@@ -0,0 +1,475 @@
+/**
+ * @file    main.c
+ * @brief   Entry point for interface program logic
+ *
+ * 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 <string.h>
+#include <stdio.h>
+
+#include "cmsis_os2.h"
+#include "rl_usb.h"
+#include "main.h"
+#include "gpio.h"
+#include "uart.h"
+#include "tasks.h"
+#include "swd_host.h"
+#include "info.h"
+#include "settings.h"
+#include "daplink.h"
+#include "util.h"
+#include "DAP.h"
+#include "bootloader.h"
+#include "cortex_m.h"
+#include "sdk.h"
+#include "target_family.h"
+#include "target_board.h"
+
+#ifdef DRAG_N_DROP_SUPPORT
+#include "vfs_manager.h"
+#include "flash_intf.h"
+#include "flash_manager.h"
+#endif
+
+// Event flags for main task
+// Timers events
+#define FLAGS_MAIN_90MS         (1 << 0)
+#define FLAGS_MAIN_30MS         (1 << 1)
+// Reset events
+#define FLAGS_MAIN_RESET        (1 << 2)
+// Other Events
+#define FLAGS_MAIN_POWERDOWN    (1 << 4)
+#define FLAGS_MAIN_DISABLEDEBUG (1 << 5)
+#define FLAGS_MAIN_PROC_USB     (1 << 9)
+// Used by cdc when an event occurs
+#define FLAGS_MAIN_CDC_EVENT    (1 << 11)
+// Used by msd when flashing a new binary
+#define FLAGS_LED_BLINK_30MS    (1 << 6)
+
+// Timing constants (in 90mS ticks)
+// USB busy time (~3 sec)
+#define USB_BUSY_TIME           (33)
+// Delay before a USB device connect may occur (~1 sec)
+#define USB_CONNECT_DELAY       (11)
+// Timeout for USB being configured (~2 sec)
+#define USB_CONFIGURE_TIMEOUT   (22)
+// Delay before target may be taken out of reset or reprogrammed after startup
+#define STARTUP_DELAY           (1)
+
+// Decrement to zero
+#define DECZERO(x)              (x ? --x : 0)
+
+//default hid led settings
+#ifndef HID_LED_DEF
+#define HID_LED_DEF GPIO_LED_OFF
+#endif
+
+//default cdc led settings
+#ifndef CDC_LED_DEF
+#define CDC_LED_DEF GPIO_LED_OFF
+#endif
+
+//default msc led settings
+#ifndef MSC_LED_DEF
+#define MSC_LED_DEF GPIO_LED_OFF
+#endif
+
+// Reference to our main task
+osThreadId_t main_task_id;
+
+// USB busy LED state; when TRUE the LED will flash once using 30mS clock tick
+static uint8_t hid_led_usb_activity = 0;
+static uint8_t cdc_led_usb_activity = 0;
+static uint8_t msc_led_usb_activity = 0;
+static main_led_state_t hid_led_state = MAIN_LED_FLASH;
+static main_led_state_t cdc_led_state = MAIN_LED_FLASH;
+static main_led_state_t msc_led_state = MAIN_LED_FLASH;
+
+// Global state of usb
+main_usb_connect_t usb_state;
+static bool usb_test_mode = false;
+
+// 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);
+    }
+}
+
+// Functions called from other tasks to trigger events in the main task
+// parameter should be reset type??
+void main_reset_target(uint8_t send_unique_id)
+{
+    osThreadFlagsSet(main_task_id, FLAGS_MAIN_RESET);
+    return;
+}
+
+// Flash HID LED using 30mS tick
+void main_blink_hid_led(main_led_state_t state)
+{
+    hid_led_usb_activity = 1;
+    hid_led_state = state;
+    return;
+}
+
+// Flash CDC LED using 30mS tick
+void main_blink_cdc_led(main_led_state_t state)
+{
+    cdc_led_usb_activity = 1;
+    cdc_led_state = state;
+    return;
+}
+
+// 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;
+}
+
+// Power down the interface
+void main_powerdown_event(void)
+{
+    osThreadFlagsSet(main_task_id, FLAGS_MAIN_POWERDOWN);
+    return;
+}
+
+// Disable debug on target
+void main_disable_debug_event(void)
+{
+    osThreadFlagsSet(main_task_id, FLAGS_MAIN_DISABLEDEBUG);
+    return;
+}
+
+// Start CDC processing
+void main_cdc_send_event(void)
+{
+    osThreadFlagsSet(main_task_id, FLAGS_MAIN_CDC_EVENT);
+    return;
+}
+
+void main_usb_set_test_mode(bool enabled)
+{
+    usb_test_mode = enabled;
+}
+
+void USBD_SignalHandler()
+{
+    osThreadFlagsSet(main_task_id, FLAGS_MAIN_PROC_USB);
+}
+
+extern void cdc_process_event(void);
+
+void main_task(void * arg)
+{
+    // State processing
+    uint16_t flags = 0;
+    // LED
+    gpio_led_state_t hid_led_value = HID_LED_DEF;
+    gpio_led_state_t cdc_led_value = CDC_LED_DEF;
+    gpio_led_state_t msc_led_value = MSC_LED_DEF;
+    // USB
+    uint32_t usb_state_count = USB_BUSY_TIME;
+    uint32_t usb_no_config_count = USB_CONFIGURE_TIMEOUT;
+    // button state
+    uint8_t reset_pressed = 0;
+#ifdef PBON_BUTTON
+    uint8_t power_on = 1;
+#endif
+
+    // Initialize settings - required for asserts to work
+    config_init();
+    // Update bootloader if it is out of date
+    bootloader_check_and_update();
+    // Get a reference to this task
+    main_task_id = osThreadGetId();
+    // leds
+    gpio_init();
+    // Turn to LED default settings
+    gpio_set_hid_led(hid_led_value);
+    gpio_set_cdc_led(cdc_led_value);
+    gpio_set_msc_led(msc_led_value);
+    // Initialize the DAP
+    DAP_Setup();
+
+    // make sure we have a valid board info structure.
+    util_assert(g_board_info.info_version == kBoardInfoVersion);
+
+    // do some init with the target before USB and files are configured
+    if (g_board_info.prerun_board_config) {
+        g_board_info.prerun_board_config();
+    }
+
+    //initialize the family
+    init_family();
+
+    if (g_target_family && g_target_family->prerun_target_config) {
+        g_target_family->prerun_target_config();
+    }
+
+    //setup some flags
+    if (g_board_info.flags & kEnableUnderResetConnect) {
+        swd_set_reset_connect(CONNECT_UNDER_RESET);
+    }
+    if (g_board_info.flags & kEnablePageErase) {
+#ifdef DRAG_N_DROP_SUPPORT
+        flash_manager_set_page_erase(true);
+#endif
+    }
+
+    // Update versions and IDs
+    info_init();
+    // USB
+    usbd_init();
+#ifdef DRAG_N_DROP_SUPPORT
+    vfs_mngr_fs_enable((config_ram_get_disable_msd()==0));
+#endif
+    usbd_connect(0);
+    usb_state = 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) {
+        flags = osThreadFlagsWait(FLAGS_MAIN_RESET             // Put target in reset state
+                       | FLAGS_MAIN_90MS            // 90mS tick
+                       | FLAGS_MAIN_30MS            // 30mS tick
+                       | FLAGS_MAIN_POWERDOWN       // Power down interface
+                       | FLAGS_MAIN_DISABLEDEBUG    // Disable target debug
+                       | FLAGS_MAIN_PROC_USB        // process usb events
+                       | FLAGS_MAIN_CDC_EVENT       // cdc event
+                       , osFlagsWaitAny
+                       , osWaitForever);
+
+        if (flags & FLAGS_MAIN_PROC_USB) {
+            if (usb_test_mode) {
+                // When in USB test mode Insert a delay to
+                // simulate worst-case behavior.
+                osDelay(1);
+            }
+            USBD_Handler();
+        }
+
+        if (flags & FLAGS_MAIN_RESET) {
+            target_set_state(RESET_RUN);
+        }
+
+        if (flags & FLAGS_MAIN_POWERDOWN) {
+            // Disable debug
+            target_set_state(NO_DEBUG);
+            // Disable board power before USB is disconnected.
+            gpio_set_board_power(false);
+            // Disconnect USB
+            usbd_connect(0);
+            // Turn off LED
+            gpio_set_hid_led(GPIO_LED_OFF);
+            gpio_set_cdc_led(GPIO_LED_OFF);
+            gpio_set_msc_led(GPIO_LED_OFF);
+
+            // TODO: put the interface chip in sleep mode
+            while (1);
+        }
+
+        if (flags & FLAGS_MAIN_DISABLEDEBUG) {
+            // Disable debug
+            target_set_state(NO_DEBUG);
+        }
+
+        if (flags & FLAGS_MAIN_CDC_EVENT) {
+            cdc_process_event();
+        }
+
+        if (flags & FLAGS_MAIN_90MS) {
+            // Update USB busy status
+#ifdef DRAG_N_DROP_SUPPORT
+            vfs_mngr_periodic(90); // FLAGS_MAIN_90MS
+#endif
+            // Update USB connect status
+            switch (usb_state) {
+                case USB_DISCONNECTING:
+                    usb_state = USB_DISCONNECTED;
+                    // Disable board power before USB is disconnected.
+                    gpio_set_board_power(false);
+                    usbd_connect(0);
+                    break;
+
+                case USB_CONNECTING:
+                    // Wait before connecting
+                    if (DECZERO(usb_state_count) == 0) {
+                        usbd_connect(1);
+                        usb_state = USB_CHECK_CONNECTED;
+                        // Reset connect timeout
+                        usb_no_config_count = USB_CONFIGURE_TIMEOUT;
+                    }
+
+                    break;
+
+                case USB_CHECK_CONNECTED:
+                    if (usbd_configured()) {
+                        // Let the HIC enable power to the target now that high power has been negotiated.
+                        gpio_set_board_power(true);
+
+                        usb_state = USB_CONNECTED;
+                    }
+                    else if (DECZERO(usb_no_config_count) == 0) {
+                        // USB configuration timed out, which most likely indicates that the HIC is
+                        // powered by a USB wall wart or similar power source. Go ahead and enable
+                        // board power.
+                        gpio_set_board_power(true);
+                    }
+
+                    break;
+
+                case USB_CONNECTED:
+                case USB_DISCONNECTED:
+                default:
+                    break;
+            }
+        }
+
+        // 30mS tick used for flashing LED when USB is busy
+        if (flags & FLAGS_MAIN_30MS) {
+
+            // handle reset button without eventing
+            if (!reset_pressed && gpio_get_reset_btn_fwrd()) {
+#ifdef DRAG_N_DROP_SUPPORT
+               if (!flash_intf_target->flash_busy()) //added checking if flashing on target is in progress
+#endif
+                {
+                    // Reset button pressed
+                    target_set_state(RESET_HOLD);
+                    reset_pressed = 1;
+                }
+            } else if (reset_pressed && !gpio_get_reset_btn_fwrd()) {
+                // Reset button released
+                target_set_state(RESET_RUN);
+                reset_pressed = 0;
+            }
+
+#ifdef PBON_BUTTON
+            // handle PBON pressed
+            if(gpio_get_pbon_btn())
+            {
+                if(power_on)
+                {
+                    // Loop till PBON is pressed
+                    while (gpio_get_pbon_btn()) {;}
+                    // Power button released when target was running
+                    target_set_state(SHUTDOWN);
+                    power_on = 0;
+                }
+                else
+                {
+                    // Loop till PBON is pressed
+                    while (gpio_get_pbon_btn()) {;}
+                    // Power button released when target was already powered off
+                    target_set_state(POWER_ON);
+                    power_on = 1;
+                }
+            }
+#endif
+
+            // DAP LED
+            if (hid_led_usb_activity) {
+
+                if ((hid_led_state == MAIN_LED_FLASH) || (hid_led_state == MAIN_LED_FLASH_PERMANENT)) {
+                    // Toggle LED value
+                    hid_led_value = GPIO_LED_ON == hid_led_value ? GPIO_LED_OFF : GPIO_LED_ON;
+
+                    // If in flash mode stop after one cycle
+                    if ((HID_LED_DEF == hid_led_value) && (MAIN_LED_FLASH == hid_led_state)) {
+                        hid_led_usb_activity = 0;
+                        hid_led_state = MAIN_LED_DEF;
+                    }
+                } else {
+                    //LED next state is MAIN_LED_DEF
+                    hid_led_value = HID_LED_DEF;
+                    hid_led_usb_activity = 0;
+                }
+
+                // Update hardware
+                gpio_set_hid_led(hid_led_value);
+            }
+
+            // MSD LED
+            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
+                    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);
+            }
+
+            // CDC LED
+            if (cdc_led_usb_activity) {
+
+                if ((cdc_led_state == MAIN_LED_FLASH) || (cdc_led_state == MAIN_LED_FLASH_PERMANENT)){
+                    // Toggle LED value
+                    cdc_led_value = GPIO_LED_ON == cdc_led_value ? GPIO_LED_OFF : GPIO_LED_ON;
+
+                    // If in flash mode stop after one cycle
+                    if ((CDC_LED_DEF == cdc_led_value) && (MAIN_LED_FLASH == cdc_led_state)) {
+                        cdc_led_usb_activity = 0;
+                        cdc_led_state = MAIN_LED_DEF;
+                    }
+                }else{
+                    //LED next state is MAIN_LED_DEF
+                    cdc_led_value = CDC_LED_DEF;
+                    cdc_led_usb_activity = 0;
+                }
+
+                // Update hardware
+                gpio_set_cdc_led(cdc_led_value);
+            }
+        }
+    }
+}
+
+int main(void)
+{
+    // Explicitly set the vector table since the bootloader might not set
+    // it to what we expect.
+#if DAPLINK_ROM_BL_SIZE > 0
+    SCB->VTOR = SCB_VTOR_TBLOFF_Msk & DAPLINK_ROM_IF_START;
+#endif
+    // initialize vendor sdk
+    sdk_init();
+
+    osKernelInitialize();                 // Initialize CMSIS-RTOS
+    osThreadNew(main_task, NULL, NULL);    // Create application main thread
+    osKernelStart();                      // Start thread execution
+    for (;;) {}
+}