コード例 #1
0
ファイル: main.c プロジェクト: c1728p9/DAPLink_old
__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);
            }

        }
    }
}
コード例 #2
0
ファイル: gpio.c プロジェクト: redbear/DAPLink
void gpio_init(void)
{
    // enable clock for GPIO port 0
    LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6);
#if defined(TARGET_POWER_HOLD)
    // Target PowerHOLD port
    PIN_PWH_IOCON = PIN_PWH_IOCON_INIT;
    LPC_GPIO->CLR[PIN_PWH_PORT] = PIN_PWH;
    LPC_GPIO->DIR[PIN_PWH_PORT] |= PIN_PWH;
#endif
    // configure GPIO-LED as output
#if defined(CONTROLLED_POWER_LED)
    // Power led (red)
    PIN_POW_LED_IOCON = PIN_POW_LED_IOCON_INIT;
    LPC_GPIO->CLR[PIN_POW_LED_PORT] = PIN_POW_LED;
    LPC_GPIO->DIR[PIN_POW_LED_PORT] |= PIN_POW_LED;
#endif
    // DAP led (green)
    PIN_DAP_LED_IOCON = PIN_DAP_LED_IOCON_INIT;
    LPC_GPIO->SET[PIN_DAP_LED_PORT] = PIN_DAP_LED;
    LPC_GPIO->DIR[PIN_DAP_LED_PORT] |= PIN_DAP_LED;
    // MSD led (red)
    PIN_MSD_LED_IOCON = PIN_MSD_LED_IOCON_INIT;
    LPC_GPIO->SET[PIN_MSD_LED_PORT] = PIN_MSD_LED;
    LPC_GPIO->DIR[PIN_MSD_LED_PORT] |= PIN_MSD_LED;
    // Serial LED (blue)
    PIN_CDC_LED_IOCON = PIN_CDC_LED_IOCON_INIT;
    LPC_GPIO->SET[PIN_CDC_LED_PORT] = PIN_CDC_LED;
    LPC_GPIO->DIR[PIN_CDC_LED_PORT] |= PIN_CDC_LED;
    // configure Button(s) as input
    PIN_RESET_IN_IOCON = PIN_RESET_IN_IOCON_INIT;
    LPC_GPIO->DIR[PIN_RESET_IN_PORT] &= ~PIN_RESET_IN;
    PIN_RESET_IN_FWRD_IOCON = PIN_RESET_IN_FWRD_IOCON_INIT;
    LPC_GPIO->DIR[PIN_RESET_IN_FWRD_PORT] &= ~PIN_RESET_IN_FWRD;
#if !defined(PIN_nRESET_FET_DRIVE)
    // open drain logic for reset button
    PIN_nRESET_IOCON = PIN_nRESET_IOCON_INIT;
    LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
    LPC_GPIO->DIR[PIN_nRESET_PORT] &= ~PIN_nRESET;
#else
    // FET drive logic for reset button
    PIN_nRESET_IOCON = PIN_nRESET_IOCON_INIT;
    LPC_GPIO->CLR[PIN_nRESET_PORT] = PIN_nRESET;
    LPC_GPIO->DIR[PIN_nRESET_PORT] |= PIN_nRESET;
#endif
    /* Enable AHB clock to the FlexInt, GroupedInt domain. */
    LPC_SYSCON->SYSAHBCLKCTRL |= ((1 << 19) | (1 << 23) | (1 << 24));
    // Give the cap on the reset button time to charge
    busy_wait(10000);

    if ((gpio_get_sw_reset() == 0) || config_ram_get_initial_hold_in_bl()) {
        IRQn_Type irq;
        // Disable SYSTICK timer and interrupt before calling into ISP
        SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);

        // Disable all nvic interrupts
        for (irq = (IRQn_Type)0; irq < (IRQn_Type)32; irq++) {
            NVIC_DisableIRQ(irq);
            NVIC_ClearPendingIRQ(irq);
        }

        // If switching to "bootloader" mode then setup the watchdog
        // so it will exit CRP mode after ~30 seconds
        if (config_ram_get_initial_hold_in_bl()) {
            LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 15); // Enable watchdog module
            LPC_SYSCON->PDRUNCFG &= ~(1 << 6);      // Enable watchdog clock (WDOSC)
            LPC_SYSCON->WDTOSCCTRL = (0xF << 5);    // Set max frequency - 2.3MHz
            LPC_WWDT->CLKSEL = (1 << 0);            // Select watchdog clock
            LPC_WWDT->TC = 0x00FFFFFF;              // Set time to reset to ~29s
            LPC_WWDT->MOD = (1 << 0) | (1 << 1);    // Enable watchdog and set reset
            LPC_WWDT->FEED = 0xAA;                  // Enable watchdog
            LPC_WWDT->FEED = 0x55;
        }

        ReinvokeISP();
    }
}