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

« Back to documentation index

Show/hide line numbers main.c Source File

main.c

00001 /**
00002  * @file    main.c
00003  * @brief   Entry point for interface program logic
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2019, 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 <string.h>
00023 #include <stdio.h>
00024 
00025 #include "cmsis_os2.h"
00026 #include "rl_usb.h"
00027 #include "main.h"
00028 #include "gpio.h"
00029 #include "uart.h"
00030 #include "tasks.h"
00031 #include "swd_host.h"
00032 #include "info.h"
00033 #include "settings.h"
00034 #include "daplink.h"
00035 #include "util.h"
00036 #include "DAP.h"
00037 #include "bootloader.h"
00038 #include "cortex_m.h"
00039 #include "sdk.h"
00040 #include "target_family.h"
00041 #include "target_board.h"
00042 
00043 #ifdef DRAG_N_DROP_SUPPORT
00044 #include "vfs_manager.h"
00045 #include "flash_intf.h"
00046 #include "flash_manager.h"
00047 #endif
00048 
00049 // Event flags for main task
00050 // Timers events
00051 #define FLAGS_MAIN_90MS         (1 << 0)
00052 #define FLAGS_MAIN_30MS         (1 << 1)
00053 // Reset events
00054 #define FLAGS_MAIN_RESET        (1 << 2)
00055 // Other Events
00056 #define FLAGS_MAIN_POWERDOWN    (1 << 4)
00057 #define FLAGS_MAIN_DISABLEDEBUG (1 << 5)
00058 #define FLAGS_MAIN_PROC_USB     (1 << 9)
00059 // Used by cdc when an event occurs
00060 #define FLAGS_MAIN_CDC_EVENT    (1 << 11)
00061 // Used by msd when flashing a new binary
00062 #define FLAGS_LED_BLINK_30MS    (1 << 6)
00063 
00064 // Timing constants (in 90mS ticks)
00065 // USB busy time (~3 sec)
00066 #define USB_BUSY_TIME           (33)
00067 // Delay before a USB device connect may occur (~1 sec)
00068 #define USB_CONNECT_DELAY       (11)
00069 // Timeout for USB being configured (~2 sec)
00070 #define USB_CONFIGURE_TIMEOUT   (22)
00071 // Delay before target may be taken out of reset or reprogrammed after startup
00072 #define STARTUP_DELAY           (1)
00073 
00074 // Decrement to zero
00075 #define DECZERO(x)              (x ? --x : 0)
00076 
00077 //default hid led settings
00078 #ifndef HID_LED_DEF
00079 #define HID_LED_DEF GPIO_LED_OFF
00080 #endif
00081 
00082 //default cdc led settings
00083 #ifndef CDC_LED_DEF
00084 #define CDC_LED_DEF GPIO_LED_OFF
00085 #endif
00086 
00087 //default msc led settings
00088 #ifndef MSC_LED_DEF
00089 #define MSC_LED_DEF GPIO_LED_OFF
00090 #endif
00091 
00092 // Reference to our main task
00093 osThreadId_t main_task_id;
00094 
00095 // USB busy LED state; when TRUE the LED will flash once using 30mS clock tick
00096 static uint8_t hid_led_usb_activity = 0;
00097 static uint8_t cdc_led_usb_activity = 0;
00098 static uint8_t msc_led_usb_activity = 0;
00099 static main_led_state_t hid_led_state = MAIN_LED_FLASH;
00100 static main_led_state_t cdc_led_state = MAIN_LED_FLASH;
00101 static main_led_state_t msc_led_state = MAIN_LED_FLASH;
00102 
00103 // Global state of usb
00104 main_usb_connect_t usb_state;
00105 static bool usb_test_mode = false;
00106 
00107 // Timer task, set flags every 30mS and 90mS
00108 void timer_task_30mS(void * arg)
00109 {
00110     static uint32_t i = 0;
00111     osThreadFlagsSet(main_task_id, FLAGS_MAIN_30MS);
00112     if (!(i++ % 3)) {
00113         osThreadFlagsSet(main_task_id, FLAGS_MAIN_90MS);
00114     }
00115 }
00116 
00117 // Functions called from other tasks to trigger events in the main task
00118 // parameter should be reset type??
00119 void main_reset_target(uint8_t send_unique_id)
00120 {
00121     osThreadFlagsSet(main_task_id, FLAGS_MAIN_RESET);
00122     return;
00123 }
00124 
00125 // Flash HID LED using 30mS tick
00126 void main_blink_hid_led(main_led_state_t state)
00127 {
00128     hid_led_usb_activity = 1;
00129     hid_led_state = state;
00130     return;
00131 }
00132 
00133 // Flash CDC LED using 30mS tick
00134 void main_blink_cdc_led(main_led_state_t state)
00135 {
00136     cdc_led_usb_activity = 1;
00137     cdc_led_state = state;
00138     return;
00139 }
00140 
00141 // Flash MSC LED using 30mS tick
00142 void main_blink_msc_led(main_led_state_t state)
00143 {
00144     msc_led_usb_activity = 1;
00145     msc_led_state = state;
00146     return;
00147 }
00148 
00149 // Power down the interface
00150 void main_powerdown_event(void)
00151 {
00152     osThreadFlagsSet(main_task_id, FLAGS_MAIN_POWERDOWN);
00153     return;
00154 }
00155 
00156 // Disable debug on target
00157 void main_disable_debug_event(void)
00158 {
00159     osThreadFlagsSet(main_task_id, FLAGS_MAIN_DISABLEDEBUG);
00160     return;
00161 }
00162 
00163 // Start CDC processing
00164 void main_cdc_send_event(void)
00165 {
00166     osThreadFlagsSet(main_task_id, FLAGS_MAIN_CDC_EVENT);
00167     return;
00168 }
00169 
00170 void main_usb_set_test_mode(bool enabled)
00171 {
00172     usb_test_mode = enabled;
00173 }
00174 
00175 void USBD_SignalHandler()
00176 {
00177     osThreadFlagsSet(main_task_id, FLAGS_MAIN_PROC_USB);
00178 }
00179 
00180 extern void cdc_process_event(void);
00181 
00182 void main_task(void * arg)
00183 {
00184     // State processing
00185     uint16_t flags = 0;
00186     // LED
00187     gpio_led_state_t hid_led_value = HID_LED_DEF;
00188     gpio_led_state_t cdc_led_value = CDC_LED_DEF;
00189     gpio_led_state_t msc_led_value = MSC_LED_DEF;
00190     // USB
00191     uint32_t usb_state_count = USB_BUSY_TIME;
00192     uint32_t usb_no_config_count = USB_CONFIGURE_TIMEOUT;
00193     // button state
00194     uint8_t reset_pressed = 0;
00195 #ifdef PBON_BUTTON
00196     uint8_t power_on = 1;
00197 #endif
00198 
00199     // Initialize settings - required for asserts to work
00200     config_init();
00201     // Update bootloader if it is out of date
00202     bootloader_check_and_update();
00203     // Get a reference to this task
00204     main_task_id = osThreadGetId();
00205     // leds
00206     gpio_init();
00207     // Turn to LED default settings
00208     gpio_set_hid_led(hid_led_value);
00209     gpio_set_cdc_led(cdc_led_value);
00210     gpio_set_msc_led(msc_led_value);
00211     // Initialize the DAP
00212     DAP_Setup();
00213 
00214     // make sure we have a valid board info structure.
00215     util_assert(g_board_info.info_version == kBoardInfoVersion);
00216 
00217     // do some init with the target before USB and files are configured
00218     if (g_board_info.prerun_board_config) {
00219         g_board_info.prerun_board_config();
00220     }
00221 
00222     //initialize the family
00223     init_family();
00224 
00225     if (g_target_family && g_target_family->prerun_target_config ) {
00226         g_target_family->prerun_target_config ();
00227     }
00228 
00229     //setup some flags
00230     if (g_board_info.flags & kEnableUnderResetConnect ) {
00231         swd_set_reset_connect(CONNECT_UNDER_RESET);
00232     }
00233     if (g_board_info.flags & kEnablePageErase ) {
00234 #ifdef DRAG_N_DROP_SUPPORT
00235         flash_manager_set_page_erase(true);
00236 #endif
00237     }
00238 
00239     // Update versions and IDs
00240     info_init();
00241     // USB
00242     usbd_init();
00243 #ifdef DRAG_N_DROP_SUPPORT
00244     vfs_mngr_fs_enable((config_ram_get_disable_msd()==0));
00245 #endif
00246     usbd_connect(0);
00247     usb_state = USB_CONNECTING;
00248     usb_state_count = USB_CONNECT_DELAY;
00249 
00250     // Start timer tasks
00251     osTimerId_t tmr_id = osTimerNew(timer_task_30mS, osTimerPeriodic, NULL, NULL);
00252     osTimerStart(tmr_id, 3);
00253     while (1) {
00254         flags = osThreadFlagsWait(FLAGS_MAIN_RESET             // Put target in reset state
00255                        | FLAGS_MAIN_90MS            // 90mS tick
00256                        | FLAGS_MAIN_30MS            // 30mS tick
00257                        | FLAGS_MAIN_POWERDOWN       // Power down interface
00258                        | FLAGS_MAIN_DISABLEDEBUG    // Disable target debug
00259                        | FLAGS_MAIN_PROC_USB        // process usb events
00260                        | FLAGS_MAIN_CDC_EVENT       // cdc event
00261                        , osFlagsWaitAny
00262                        , osWaitForever);
00263 
00264         if (flags & FLAGS_MAIN_PROC_USB) {
00265             if (usb_test_mode) {
00266                 // When in USB test mode Insert a delay to
00267                 // simulate worst-case behavior.
00268                 osDelay(1);
00269             }
00270             USBD_Handler();
00271         }
00272 
00273         if (flags & FLAGS_MAIN_RESET) {
00274             target_set_state(RESET_RUN);
00275         }
00276 
00277         if (flags & FLAGS_MAIN_POWERDOWN) {
00278             // Disable debug
00279             target_set_state(NO_DEBUG);
00280             // Disable board power before USB is disconnected.
00281             gpio_set_board_power(false);
00282             // Disconnect USB
00283             usbd_connect(0);
00284             // Turn off LED
00285             gpio_set_hid_led(GPIO_LED_OFF);
00286             gpio_set_cdc_led(GPIO_LED_OFF);
00287             gpio_set_msc_led(GPIO_LED_OFF);
00288 
00289             // TODO: put the interface chip in sleep mode
00290             while (1);
00291         }
00292 
00293         if (flags & FLAGS_MAIN_DISABLEDEBUG) {
00294             // Disable debug
00295             target_set_state(NO_DEBUG);
00296         }
00297 
00298         if (flags & FLAGS_MAIN_CDC_EVENT) {
00299             cdc_process_event();
00300         }
00301 
00302         if (flags & FLAGS_MAIN_90MS) {
00303             // Update USB busy status
00304 #ifdef DRAG_N_DROP_SUPPORT
00305             vfs_mngr_periodic(90); // FLAGS_MAIN_90MS
00306 #endif
00307             // Update USB connect status
00308             switch (usb_state) {
00309                 case USB_DISCONNECTING:
00310                     usb_state = USB_DISCONNECTED;
00311                     // Disable board power before USB is disconnected.
00312                     gpio_set_board_power(false);
00313                     usbd_connect(0);
00314                     break;
00315 
00316                 case USB_CONNECTING:
00317                     // Wait before connecting
00318                     if (DECZERO(usb_state_count) == 0) {
00319                         usbd_connect(1);
00320                         usb_state = USB_CHECK_CONNECTED;
00321                         // Reset connect timeout
00322                         usb_no_config_count = USB_CONFIGURE_TIMEOUT;
00323                     }
00324 
00325                     break;
00326 
00327                 case USB_CHECK_CONNECTED:
00328                     if (usbd_configured()) {
00329                         // Let the HIC enable power to the target now that high power has been negotiated.
00330                         gpio_set_board_power(true);
00331 
00332                         usb_state = USB_CONNECTED;
00333                     }
00334                     else if (DECZERO(usb_no_config_count) == 0) {
00335                         // USB configuration timed out, which most likely indicates that the HIC is
00336                         // powered by a USB wall wart or similar power source. Go ahead and enable
00337                         // board power.
00338                         gpio_set_board_power(true);
00339                     }
00340 
00341                     break;
00342 
00343                 case USB_CONNECTED:
00344                 case USB_DISCONNECTED:
00345                 default:
00346                     break;
00347             }
00348         }
00349 
00350         // 30mS tick used for flashing LED when USB is busy
00351         if (flags & FLAGS_MAIN_30MS) {
00352 
00353             // handle reset button without eventing
00354             if (!reset_pressed && gpio_get_reset_btn_fwrd()) {
00355 #ifdef DRAG_N_DROP_SUPPORT
00356                if (!flash_intf_target->flash_busy()) //added checking if flashing on target is in progress
00357 #endif
00358                 {
00359                     // Reset button pressed
00360                     target_set_state(RESET_HOLD);
00361                     reset_pressed = 1;
00362                 }
00363             } else if (reset_pressed && !gpio_get_reset_btn_fwrd()) {
00364                 // Reset button released
00365                 target_set_state(RESET_RUN);
00366                 reset_pressed = 0;
00367             }
00368 
00369 #ifdef PBON_BUTTON
00370             // handle PBON pressed
00371             if(gpio_get_pbon_btn())
00372             {
00373                 if(power_on)
00374                 {
00375                     // Loop till PBON is pressed
00376                     while (gpio_get_pbon_btn()) {;}
00377                     // Power button released when target was running
00378                     target_set_state(SHUTDOWN);
00379                     power_on = 0;
00380                 }
00381                 else
00382                 {
00383                     // Loop till PBON is pressed
00384                     while (gpio_get_pbon_btn()) {;}
00385                     // Power button released when target was already powered off
00386                     target_set_state(POWER_ON);
00387                     power_on = 1;
00388                 }
00389             }
00390 #endif
00391 
00392             // DAP LED
00393             if (hid_led_usb_activity) {
00394 
00395                 if ((hid_led_state == MAIN_LED_FLASH) || (hid_led_state == MAIN_LED_FLASH_PERMANENT)) {
00396                     // Toggle LED value
00397                     hid_led_value = GPIO_LED_ON == hid_led_value ? GPIO_LED_OFF : GPIO_LED_ON;
00398 
00399                     // If in flash mode stop after one cycle
00400                     if ((HID_LED_DEF == hid_led_value) && (MAIN_LED_FLASH == hid_led_state)) {
00401                         hid_led_usb_activity = 0;
00402                         hid_led_state = MAIN_LED_DEF;
00403                     }
00404                 } else {
00405                     //LED next state is MAIN_LED_DEF
00406                     hid_led_value = HID_LED_DEF;
00407                     hid_led_usb_activity = 0;
00408                 }
00409 
00410                 // Update hardware
00411                 gpio_set_hid_led(hid_led_value);
00412             }
00413 
00414             // MSD LED
00415             if (msc_led_usb_activity) {
00416 
00417                 if ((msc_led_state == MAIN_LED_FLASH) || (msc_led_state == MAIN_LED_FLASH_PERMANENT)) {
00418                     // Toggle LED value
00419                     msc_led_value = GPIO_LED_ON == msc_led_value ? GPIO_LED_OFF : GPIO_LED_ON;
00420 
00421                     // If in flash mode stop after one cycle
00422                     if ((MSC_LED_DEF == msc_led_value) && (MAIN_LED_FLASH == msc_led_state)) {
00423                         msc_led_usb_activity = 0;
00424                         msc_led_state = MAIN_LED_DEF;
00425                     }
00426                 } else {
00427                     //LED next state is MAIN_LED_DEF
00428                     msc_led_value = MSC_LED_DEF;
00429                     msc_led_usb_activity = 0;
00430                 }
00431 
00432                 // Update hardware
00433                 gpio_set_msc_led(msc_led_value);
00434             }
00435 
00436             // CDC LED
00437             if (cdc_led_usb_activity) {
00438 
00439                 if ((cdc_led_state == MAIN_LED_FLASH) || (cdc_led_state == MAIN_LED_FLASH_PERMANENT)){
00440                     // Toggle LED value
00441                     cdc_led_value = GPIO_LED_ON == cdc_led_value ? GPIO_LED_OFF : GPIO_LED_ON;
00442 
00443                     // If in flash mode stop after one cycle
00444                     if ((CDC_LED_DEF == cdc_led_value) && (MAIN_LED_FLASH == cdc_led_state)) {
00445                         cdc_led_usb_activity = 0;
00446                         cdc_led_state = MAIN_LED_DEF;
00447                     }
00448                 }else{
00449                     //LED next state is MAIN_LED_DEF
00450                     cdc_led_value = CDC_LED_DEF;
00451                     cdc_led_usb_activity = 0;
00452                 }
00453 
00454                 // Update hardware
00455                 gpio_set_cdc_led(cdc_led_value);
00456             }
00457         }
00458     }
00459 }
00460 
00461 int main(void)
00462 {
00463     // Explicitly set the vector table since the bootloader might not set
00464     // it to what we expect.
00465 #if DAPLINK_ROM_BL_SIZE > 0
00466     SCB->VTOR = SCB_VTOR_TBLOFF_Msk & DAPLINK_ROM_IF_START;
00467 #endif
00468     // initialize vendor sdk
00469     sdk_init();
00470 
00471     osKernelInitialize();                 // Initialize CMSIS-RTOS
00472     osThreadNew(main_task, NULL, NULL);    // Create application main thread
00473     osKernelStart();                      // Start thread execution
00474     for (;;) {}
00475 }