Exemple #1
0
void target_forward_reset(bool assert_reset)
{
    if (assert_reset) {
        target_set_state(RESET_HOLD);
    } else {
        target_set_state(RESET_RUN);
    }
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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;
}
Exemple #7
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;
}
Exemple #8
0
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);
}
Exemple #9
0
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);
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
__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);
            }

        }
    }
}
Exemple #17
0
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;
}
Exemple #18
0
__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);
            }

        }
    }
}
Exemple #19
0
__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);
            }

        }
    }
}