void target_forward_reset(bool assert_reset) { if (assert_reset) { target_set_state(RESET_HOLD); } else { target_set_state(RESET_RUN); } }
static error_t target_flash_uninit(void) { if (config_get_auto_rst()) { // Resume the target if configured to do so target_set_state(RESET_RUN); } else { // Leave the target halted until a reset occurs target_set_state(RESET_PROGRAM); } swd_off(); return ERROR_SUCCESS; }
static int target_stop(Unit *u) { Target *t = TARGET(u); assert(t); assert(t->state == TARGET_ACTIVE); target_set_state(t, TARGET_DEAD); return 0; }
uint8_t target_unlock_sequence(void) { uint32_t val; if (!swd_read_ap(MDM_IDR, &val)) { return 0; } // Read-only identification register that always reads as 0x001C_0000 if (val != 0x001c0000) { return 0; } if (!swd_read_ap(MDM_CTRL, &val)) { return 0; } if (!swd_read_ap(MDM_STATUS, &val)) { return 0; } // flash in secured mode if (val & (1 << 2)) { target_set_state(RESET_HOLD); while (1) { if (!swd_write_ap(MDM_CTRL, 1)) { return 0; } if (!swd_read_ap(MDM_STATUS, &val)) { return 0; } if (val & 1) { break; } } while (1) { if (!swd_write_ap(MDM_CTRL, 0)) { return 0; } if (!swd_read_ap(MDM_STATUS, &val)) { return 0; } if (!swd_read_ap(MDM_CTRL, &val)) { return 0; } if (val == 0) { break; } } } return 1; }
static error_t target_flash_uninit(void) { // Resume the target if configured to do so if (config_get_auto_rst()) { target_set_state(RESET_RUN); } swd_off(); return ERROR_SUCCESS; }
static int target_coldplug(Unit *u) { Target *t = TARGET(u); assert(t); assert(t->state == TARGET_DEAD); if (t->deserialized_state != t->state) target_set_state(t, t->deserialized_state); return 0; }
target_flash_status_t target_flash_erase_chip(void) { // // 1 == O.K. // 0 == Error // if (!swd_flash_syscall_exec(&flash.sys_call_param, flash.erase_chip, 0, 0, 0, 0)) { // 1 == O.K., 0 == Error return TARGET_FAIL_ERASE_ALL; } target_set_state(RESET_PROGRAM); //target_flash_init(); return TARGET_OK; }
static void target_before_init_debug(void) { // This is for the hardware conflict (the EVK are not consider >2 debugger connection // situation) with another external debugger(such as JLINK). Before drag&pull, to force // RESET pin to high state ensure a successfully access. If external debugger not // connected. It's not necessary for doing that. swd_set_target_reset(0); // In some case the CPU will enter "cannot debug" state (low power, SWD pin mux changed, etc.). // Doing a hardware reset will clear those states (probably, depends on app). Also, if the // external flash's data is not a valid bootable image, DAPLink cannot attached to target. A // hardware reset will increase the chance to connect in this situation. target_set_state(RESET_RUN); }
uint8_t gpio_get_sw_reset(void) { static uint8_t last_reset_forward_pressed = 0; uint8_t reset_forward_pressed; uint8_t reset_pressed; reset_forward_pressed = LPC_GPIO->PIN[PIN_RESET_IN_FWRD_PORT] & PIN_RESET_IN_FWRD ? 0 : 1; // Forward reset if the state of the button has changed // This must be done on button changes so it does not interfere // with other reset sources such as programming or CDC Break if (last_reset_forward_pressed != reset_forward_pressed) { if (reset_forward_pressed) { target_set_state(RESET_HOLD); } else { target_set_state(RESET_RUN); } last_reset_forward_pressed = reset_forward_pressed; } reset_pressed = reset_forward_pressed || (LPC_GPIO->PIN[PIN_RESET_IN_PORT] & PIN_RESET_IN ? 0 : 1); return !reset_pressed; }
uint8_t target_unlock_sequence(void) { uint32_t val; // read the device ID if (!swd_read_ap(MDM_IDR, &val)) { return 0; } // verify the result if (val != MCU_ID) { return 0; } if (!swd_read_ap(MDM_STATUS, &val)) { return 0; } // flash in secured mode if (val & (1 << 2)) { // hold the device in reset target_set_state(RESET_HOLD); // write the mass-erase enable bit if (!swd_write_ap(MDM_CTRL, 1)) { return 0; } while (1) { // wait until mass erase is started if (!swd_read_ap(MDM_STATUS, &val)) { return 0; } if (val & 1) { break; } } // mass erase in progress while (1) { // keep reading until procedure is complete if (!swd_read_ap(MDM_CTRL, &val)) { return 0; } if (val == 0) { break; } } } return 1; }
void prerun_target_config(void) { // SIM peripheral 0x40047000 // address offset 0x 1054 uint32_t UUID_LOC = 0x40048054; uint32_t uuid[4] = {0}; // get a hold of the target target_set_state(RESET_PROGRAM); // do mass-erase if necessary target_unlock_sequence(); // get target UUID swd_read_memory(UUID_LOC, (uint8_t *)&uuid, 16); // stringify and store the MAC generated from a UUID build_mac_string(uuid); }
void semihost_enable(void) { // Called from: // - main task when the interface firmware starts // - cmsis-dap when a debugger closes the swd port // - drag n drop when a binary has been flashed if (semihostEnabled) return; if (semihostTask==0) return; // enable debug target_set_state(DEBUG); os_evt_set(FLAGS_SH_START, semihostTask); semihostEnabled = 1; return; }
target_flash_status_t target_flash_init(extension_t ext) { return TARGET_FAIL_RESET; PORT_SWD_SETUP(); if (!target_set_state(RESET_PROGRAM)) { return TARGET_FAIL_RESET; } // Download flash programming algorithm to target and initialise. if (!swd_write_memory(flash.algo_start, (uint8_t *)flash.image, flash.algo_size)) { return TARGET_FAIL_ALGO_DL; } if (!swd_flash_syscall_exec(&flash.sys_call_param, flash.init, 0, 0 /* clk value is not used */, 0, 0)) { return TARGET_FAIL_INIT; } return TARGET_OK; }
static error_t target_flash_init() { const program_target_t *const flash = target_device.flash_algo; if (0 == target_set_state(RESET_PROGRAM)) { return ERROR_RESET; } // Download flash programming algorithm to target and initialise. if (0 == swd_write_memory(flash->algo_start, (uint8_t *)flash->algo_blob, flash->algo_size)) { return ERROR_ALGO_DL; } if (0 == swd_flash_syscall_exec(&flash->sys_call_s, flash->init, target_device.flash_start, 0, 0, 0)) { return ERROR_INIT; } return ERROR_SUCCESS; }
int32_t USBD_CDC_ACM_SendBreak(uint16_t dur) { uint32_t end_break_time; #ifdef DRAG_N_DROP_SUPPORT if (!flash_intf_target->flash_busy()) #endif { //added checking if flashing on target is in progress // reset and send the unique id over CDC if (dur != 0) { start_break_time = osKernelGetSysTimerCount(); target_set_state(RESET_HOLD); } else { end_break_time = osKernelGetSysTimerCount(); // long reset -> send uID over serial (300 -> break > 3s) if ((end_break_time - start_break_time) >= (300)) { main_reset_target(1); } else { main_reset_target(0); } } } return (1); }
__task void main_task(void) { // State processing uint16_t flags = 0; // LED gpio_led_state_t hid_led_value = GPIO_LED_ON; gpio_led_state_t cdc_led_value = GPIO_LED_ON; gpio_led_state_t msc_led_value = GPIO_LED_ON; // USB uint32_t usb_state_count = USB_BUSY_TIME; // thread running after usb connected started uint8_t thread_started = 0; // button state main_reset_state_t main_reset_button_state = MAIN_RESET_RELEASED; // Initialize settings config_init(); // Initialize our serial mailbox os_mbx_init(&serial_mailbox, sizeof(serial_mailbox)); // Get a reference to this task main_task_id = os_tsk_self(); // leds gpio_init(); // Turn off LED gpio_set_hid_led(GPIO_LED_ON); gpio_set_cdc_led(GPIO_LED_ON); gpio_set_msc_led(GPIO_LED_ON); // do some init with the target before USB and files are configured prerun_target_config(); // Update versions and IDs info_init(); // USB usbd_init(); vfs_user_enable(true); usbd_connect(0); usb_state = USB_CONNECTING; usb_state_count = USB_CONNECT_DELAY; // Start timer tasks os_tsk_create_user(timer_task_30mS, TIMER_TASK_30_PRIORITY, (void *)stk_timer_30_task, TIMER_TASK_30_STACK); // Target running target_set_state(RESET_RUN); while(1) { os_evt_wait_or( 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 ,NO_TIMEOUT); // Find out what event happened flags = os_evt_get(); if (flags & FLAGS_MAIN_PROC_USB) { USBD_Handler(); } if (flags & FLAGS_MAIN_RESET) { target_set_state(RESET_RUN); } if (flags & FLAGS_MAIN_POWERDOWN) { // Disable debug target_set_state(NO_DEBUG); // 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_90MS) { // Update USB busy status vfs_user_periodic(90); // FLAGS_MAIN_90MS // Update USB connect status switch (usb_state) { case USB_DISCONNECTING: usb_state = USB_DISCONNECTED; usbd_connect(0); break; case USB_CONNECTING: // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; } break; case USB_CHECK_CONNECTED: if(usbd_configured()) { if (!thread_started) { os_tsk_create_user(hid_process, DAP_TASK_PRIORITY, (void *)stk_dap_task, DAP_TASK_STACK); serial_task_id = os_tsk_create_user(serial_process, SERIAL_TASK_PRIORITY, (void *)stk_serial_task, SERIAL_TASK_STACK); thread_started = 1; } usb_state = USB_CONNECTED; } 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 switch (main_reset_button_state) { default: case MAIN_RESET_RELEASED: if (0 == gpio_get_sw_reset()) { main_reset_button_state = MAIN_RESET_PRESSED; target_forward_reset(true); } break; case MAIN_RESET_PRESSED: // ToDo: add a counter to do a mass erase or target recovery after xxx seconds of being held if (1 == gpio_get_sw_reset()) { main_reset_button_state = MAIN_RESET_TARGET; } break; case MAIN_RESET_TARGET: target_forward_reset(false); main_reset_button_state = MAIN_RESET_RELEASED; break; } if (hid_led_usb_activity && ((hid_led_state == MAIN_LED_FLASH) || (hid_led_state == MAIN_LED_FLASH_PERMANENT))) { // Flash DAP LED ONCE if (hid_led_value) { hid_led_value = GPIO_LED_OFF; } else { hid_led_value = GPIO_LED_ON; // Turn on if (hid_led_state == MAIN_LED_FLASH) { hid_led_usb_activity = 0; } } // Update hardware gpio_set_hid_led(hid_led_value); } if (msc_led_usb_activity && ((msc_led_state == MAIN_LED_FLASH) || (msc_led_state == MAIN_LED_FLASH_PERMANENT))) { // Flash MSD LED ONCE if (msc_led_value) { msc_led_value = GPIO_LED_OFF; } else { msc_led_value = GPIO_LED_ON; // Turn on if (msc_led_state == MAIN_LED_FLASH) { msc_led_usb_activity = 0; } } // Update hardware gpio_set_msc_led(msc_led_value); } if (cdc_led_usb_activity && ((cdc_led_state == MAIN_LED_FLASH) || (cdc_led_state == MAIN_LED_FLASH_PERMANENT))) { // Flash CDC LED ONCE if (cdc_led_value) { cdc_led_value = GPIO_LED_OFF; } else { cdc_led_value = GPIO_LED_ON; // Turn on if (cdc_led_state == MAIN_LED_FLASH) { cdc_led_usb_activity = 0; } } // Update hardware gpio_set_cdc_led(cdc_led_value); } } } }
void vfs_user_periodic(uint32_t elapsed_ms) { vfs_user_state_t vfs_state_local; vfs_user_state_t vfs_state_local_prev; sync_assert_usb_thread(); sync_lock(); // Return immediately if the desired state has been reached if (!changing_state()) { sync_unlock(); return; } // Wait until the required amount of time has passed // before changing state if (vfs_state_remaining_ms > 0) { vfs_state_remaining_ms -= MIN(elapsed_ms, vfs_state_remaining_ms); sync_unlock(); return; } vfs_user_printf("vfs_user_periodic()\r\n"); // Transistion to new state vfs_state_local_prev = vfs_state; vfs_state = vfs_state_next; switch (vfs_state) { case VFS_USER_STATE_RECONNECTING: // Transition back to the connected state vfs_state_next = VFS_USER_STATE_CONNECTED; vfs_state_remaining_ms = reconnect_delay_ms; break; default: // No state change logic required in other states break; } vfs_state_local = vfs_state; sync_unlock(); // Processing when leaving a state vfs_user_printf(" state %i->%i\r\n", vfs_state_local_prev, vfs_state_local); switch (vfs_state_local_prev) { case VFS_USER_STATE_DISCONNECTED: // No action needed break; case VFS_USER_STATE_RECONNECTING: // No action needed break; case VFS_USER_STATE_CONNECTED: if (file_transfer_state.stream_open) { error_t status; file_transfer_state.stream_open = false; status = stream_close(); if (ERROR_SUCCESS == fail_reason) { fail_reason = status; } vfs_user_printf(" stream_close ret %i\r\n", status); } // Reset if programming was successful //TODO - move to flash layer if (daplink_is_bootloader() && (ERROR_SUCCESS == fail_reason)) { NVIC_SystemReset(); } // If hold in bootloader has been set then reset after usb is disconnected if (daplink_is_interface() && config_ram_get_hold_in_bl()) { NVIC_SystemReset(); } // Resume the target if configured to do so //TODO - move to flash layer if (config_get_auto_rst()) { target_set_state(RESET_RUN); } break; } // Processing when entering a state switch (vfs_state_local) { case VFS_USER_STATE_DISCONNECTED: USBD_MSC_MediaReady = 0; break; case VFS_USER_STATE_RECONNECTING: USBD_MSC_MediaReady = 0; break; case VFS_USER_STATE_CONNECTED: build_filesystem(); USBD_MSC_MediaReady = 1; break; } return; }
__task void main_task(void) { // State processing uint16_t flags; // LED uint8_t dap_led_value = 1; uint8_t cdc_led_value = 1; uint8_t msd_led_value = 1; // USB uint32_t usb_state_count; // thread running after usb connected started uint8_t thread_started = 0; // button state char button_activated; // string containing unique ID uint8_t * id_str; // Get a reference to this task main_task_id = os_tsk_self(); // leds gpio_init(); usbd_init(); swd_init(); // Turn on LED gpio_set_dap_led(1); gpio_set_cdc_led(1); gpio_set_msd_led(1); // Setup reset button gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; // USB usbd_connect(0); usb_busy = USB_IDLE; usb_busy_count = 0; usb_state = USB_CONNECTING; usb_state_count = USB_CONNECT_DELAY; // Update HTML version information file update_html_file(); // Start timer tasks os_tsk_create_user(timer_task_30mS, TIMER_TASK_30_PRIORITY, (void *)stk_timer_30_task, TIMER_TASK_30_STACK); // Target running target_set_state(RESET_RUN_WITH_DEBUG); // start semihost task semihost_init(); semihost_enable(); while(1) { os_evt_wait_or( 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 // Power down interface | FLAGS_MAIN_USB_DISCONNECT, // Disable target debug NO_TIMEOUT); // Find out what event happened flags = os_evt_get(); if (flags & FLAGS_MAIN_USB_DISCONNECT) { usb_busy = USB_IDLE; // USB not busy usb_state_count = 4; usb_state = USB_DISCONNECT_CONNECT; // disconnect the usb } if (flags & FLAGS_MAIN_RESET) { cdc_led_state = LED_OFF; gpio_set_cdc_led(0); //usbd_cdc_ser_flush(); if (send_uID) { // set the target in reset to not receive char on the serial port target_set_state(RESET_HOLD); // send uid id_str = get_uid_string(); USBD_CDC_ACM_DataSend(id_str, strlen((const char *)id_str)); send_uID = 0; } // Reset target target_set_state(RESET_RUN); cdc_led_state = LED_FLASH; gpio_set_cdc_led(1); button_activated = 0; } if (flags & FLAGS_MAIN_POWERDOWN) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); // Disconnect USB usbd_connect(0); // Turn off LED gpio_set_dap_led(0); gpio_set_cdc_led(0); gpio_set_msd_led(0); // TODO: put the interface chip in sleep mode while (1) { } } if (flags & FLAGS_MAIN_DISABLEDEBUG) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); } if (flags & FLAGS_MAIN_90MS) { if (!button_activated) { gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; } // Update USB busy status switch (usb_busy) { case USB_ACTIVE: if (DECZERO(usb_busy_count) == 0) { usb_busy=USB_IDLE; } break; case USB_IDLE: default: break; } // Update USB connect status switch (usb_state) { case USB_DISCONNECTING: // Wait until USB is idle before disconnecting if (usb_busy == USB_IDLE) { usbd_connect(0); usb_state = USB_DISCONNECTED; } break; case USB_DISCONNECT_CONNECT: // Wait until USB is idle before disconnecting if ((usb_busy == USB_IDLE) && (DECZERO(usb_state_count) == 0)) { usbd_connect(0); usb_state = USB_CONNECTING; // Update HTML file update_html_file(); } break; case USB_CONNECTING: // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; } break; case USB_CHECK_CONNECTED: if(usbd_configured()) { if (!thread_started) { os_tsk_create_user(hid_process, DAP_TASK_PRIORITY, (void *)stk_dap_task, DAP_TASK_STACK); serial_task_id = os_tsk_create_user(serial_process, SERIAL_TASK_PRIORITY, (void *)stk_serial_task, SERIAL_TASK_STACK); thread_started = 1; } usb_state = USB_CONNECTED; } break; case USB_CONNECTED: case USB_DISCONNECTED: default: break; } } // 30mS tick used for flashing LED when USB is busy if (flags & FLAGS_MAIN_30MS) { if (dap_led_usb_activity && ((dap_led_state == LED_FLASH) || (dap_led_state == LED_FLASH_PERMANENT))) { // Flash DAP LED ONCE if (dap_led_value) { dap_led_value = 0; } else { dap_led_value = 1; // Turn on if (dap_led_state == LED_FLASH) { dap_led_usb_activity = 0; } } // Update hardware gpio_set_dap_led(dap_led_value); } if (msd_led_usb_activity && ((msd_led_state == LED_FLASH) || (msd_led_state == LED_FLASH_PERMANENT))) { // Flash MSD LED ONCE if (msd_led_value) { msd_led_value = 0; } else { msd_led_value = 1; // Turn on if (msd_led_state == LED_FLASH) { msd_led_usb_activity = 0; } } // Update hardware gpio_set_msd_led(msd_led_value); } if (cdc_led_usb_activity && ((cdc_led_state == LED_FLASH) || (cdc_led_state == LED_FLASH_PERMANENT))) { // Flash CDC LED ONCE if (cdc_led_value) { cdc_led_value = 0; } else { cdc_led_value = 1; // Turn on if (cdc_led_state == LED_FLASH) { cdc_led_usb_activity = 0; } } // Update hardware gpio_set_cdc_led(cdc_led_value); } } } }
__task void main_task(void) { // State processing uint16_t flags; // LED uint8_t dap_led_value = 1; uint8_t cdc_led_value = 1; uint8_t msd_led_value = 1; // USB uint32_t usb_state_count; // thread running after usb connected started uint8_t thread_started = 0; // button state char button_activated; // string containing unique ID uint8_t * id_str; // Initialize our serial mailbox os_mbx_init(&serial_mailbox, sizeof(serial_mailbox)); // Get a reference to this task main_task_id = os_tsk_self(); // leds gpio_init(); // Turn off LED gpio_set_dap_led(1); gpio_set_cdc_led(1); gpio_set_msd_led(1); #ifdef BOARD_UBLOX_C027 PORT_SWD_SETUP(); // wait until reset output to the target is pulled high while (!PIN_nRESET_IN()) { /* wait doing nothing */ } os_dly_wait(4); // if the reset input from button is low then enter isp programming mode if (!(LPC_GPIO->B[19/*RESET_PIN*/ + (1/*RESET_PORT*/ << 5)] & 1)) { enter_isp(); } #endif usbd_init(); swd_init(); // Setup reset button gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; // USB usbd_connect(0); usb_busy = USB_IDLE; usb_busy_count = 0; usb_state = USB_CONNECTING; usb_state_count = USB_CONNECT_DELAY; // Update HTML version information file update_html_file(); // Start timer tasks os_tsk_create_user(timer_task_30mS, TIMER_TASK_30_PRIORITY, (void *)stk_timer_30_task, TIMER_TASK_30_STACK); #ifndef BOARD_UBLOX_C027 // Target running //target_set_state(RESET_RUN_WITH_DEBUG); #endif #ifdef BOARD_NRF51822AA // Target running target_set_state(RESET_RUN); #endif // start semihost task semihost_init(); semihost_enable(); while(1) { os_evt_wait_or( 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 // Power down interface #ifdef USE_USB_EJECT_INSERT | FLAGS_MAIN_USB_DISCONNECT // Disable target debug | FLAGS_MAIN_USB_MEDIA_EJECT, // Eject file system #else | FLAGS_MAIN_USB_DISCONNECT, // Disable target debug #endif NO_TIMEOUT); // Find out what event happened flags = os_evt_get(); if (flags & FLAGS_MAIN_USB_DISCONNECT) { usb_busy = USB_IDLE; // USB not busy usb_state_count = 4; usb_state = USB_DISCONNECT_CONNECT; // disconnect the usb } #ifdef USE_USB_EJECT_INSERT if (flags & FLAGS_MAIN_USB_MEDIA_EJECT) { EjectInsertMediaMode = EJECT_INSERT_WAIT_TO_EJECT; EjectInsertMediaCounter = EJECT_INSERT_DELAY_500MS; } #endif if (flags & FLAGS_MAIN_RESET) { cdc_led_state = LED_OFF; gpio_set_cdc_led(0); //usbd_cdc_ser_flush(); if (send_uID) { // set the target in reset to not receive char on the serial port target_set_state(RESET_HOLD); // send uid id_str = get_uid_string(); USBD_CDC_ACM_DataSend(id_str, strlen((const char *)id_str)); send_uID = 0; } // Reset target target_set_state(RESET_RUN); cdc_led_state = LED_FLASH; gpio_set_cdc_led(1); button_activated = 0; } if (flags & FLAGS_MAIN_POWERDOWN) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); // Disconnect USB usbd_connect(0); // Turn off LED gpio_set_dap_led(0); gpio_set_cdc_led(0); gpio_set_msd_led(0); // TODO: put the interface chip in sleep mode while (1) { } } if (flags & FLAGS_MAIN_DISABLEDEBUG) { // Stop semihost task semihost_disable(); // Disable debug target_set_state(NO_DEBUG); } if (flags & FLAGS_MAIN_90MS) { if (!button_activated) { gpio_enable_button_flag(main_task_id, FLAGS_MAIN_RESET); button_activated = 1; } #ifdef USE_USB_EJECT_INSERT if (EjectInsertMediaMode == EJECT_INSERT_WAIT_TO_EJECT) { if (--EjectInsertMediaCounter == 0) { // Have waited ~0.5 second, time to eject media EjectInsertMediaMode = EJECT_INSERT_WAIT_TO_INSERT; EjectInsertMediaCounter = EJECT_INSERT_DELAY_500MS; USBD_MSC_MediaReady = __FALSE; } } if ((EjectInsertMediaMode == EJECT_INSERT_WAIT_TO_INSERT) && !USBD_MSC_MediaReadyEx) { // The host computer have questioned the state and received // the message that the media has been removed if (--EjectInsertMediaCounter == 0) { // Have waited ~0.5 seconds after ejecting, time to insert media EjectInsertMediaMode = EJECT_INSERT_INACTIVE; USBD_MSC_MediaReady = __TRUE; } } #endif // Update USB busy status switch (usb_busy) { case USB_ACTIVE: if (DECZERO(usb_busy_count) == 0) { usb_busy=USB_IDLE; } break; case USB_IDLE: default: break; } // Update USB connect status switch (usb_state) { case USB_DISCONNECTING: // Wait until USB is idle before disconnecting if (usb_busy == USB_IDLE) { usbd_connect(0); usb_state = USB_DISCONNECTED; } break; case USB_DISCONNECT_CONNECT: // Wait until USB is idle before disconnecting if ((usb_busy == USB_IDLE) && (DECZERO(usb_state_count) == 0)) { usbd_connect(0); usb_state = USB_CONNECTING; // Update HTML file update_html_file(); // Delay the connecting state before reconnecting to the host - improved usage with VMs usb_state_count = 10; //(90ms * 10 = 900ms) } break; case USB_CONNECTING: // Wait before connecting if (DECZERO(usb_state_count) == 0) { usbd_connect(1); usb_state = USB_CHECK_CONNECTED; } break; case USB_CHECK_CONNECTED: if(usbd_configured()) { if (!thread_started) { os_tsk_create_user(hid_process, DAP_TASK_PRIORITY, (void *)stk_dap_task, DAP_TASK_STACK); serial_task_id = os_tsk_create_user(serial_process, SERIAL_TASK_PRIORITY, (void *)stk_serial_task, SERIAL_TASK_STACK); thread_started = 1; } usb_state = USB_CONNECTED; } break; case USB_CONNECTED: case USB_DISCONNECTED: default: break; } } // 30mS tick used for flashing LED when USB is busy if (flags & FLAGS_MAIN_30MS) { if (dap_led_usb_activity && ((dap_led_state == LED_FLASH) || (dap_led_state == LED_FLASH_PERMANENT))) { // Flash DAP LED ONCE if (dap_led_value) { dap_led_value = 0; } else { dap_led_value = 1; // Turn on if (dap_led_state == LED_FLASH) { dap_led_usb_activity = 0; } } // Update hardware gpio_set_dap_led(dap_led_value); } if (msd_led_usb_activity && ((msd_led_state == LED_FLASH) || (msd_led_state == LED_FLASH_PERMANENT))) { // Flash MSD LED ONCE if (msd_led_value) { msd_led_value = 0; } else { msd_led_value = 1; // Turn on if (msd_led_state == LED_FLASH) { msd_led_usb_activity = 0; } } // Update hardware gpio_set_msd_led(msd_led_value); } if (cdc_led_usb_activity && ((cdc_led_state == LED_FLASH) || (cdc_led_state == LED_FLASH_PERMANENT))) { // Flash CDC LED ONCE if (cdc_led_value) { cdc_led_value = 0; } else { cdc_led_value = 1; // Turn on if (cdc_led_state == LED_FLASH) { cdc_led_usb_activity = 0; } } // Update hardware gpio_set_cdc_led(cdc_led_value); } } } }