void gpio_init(void) { SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK; // configure pin as GPIO PIN_HID_LED_PORT->PCR[PIN_HID_LED_BIT] = PORT_PCR_MUX(1); PIN_MSC_LED_PORT->PCR[PIN_MSC_LED_BIT] = PORT_PCR_MUX(1); PIN_CDC_LED_PORT->PCR[PIN_CDC_LED_BIT] = PORT_PCR_MUX(1); PIN_SW_RESET_PORT->PCR[PIN_SW_RESET_BIT] = PORT_PCR_MUX(1); PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1); // led off gpio_set_hid_led(GPIO_LED_OFF); gpio_set_cdc_led(GPIO_LED_OFF); gpio_set_msc_led(GPIO_LED_OFF); // power regulator on PIN_POWER_EN_GPIO->PDOR |= PIN_POWER_EN; // set as output PIN_HID_LED_GPIO->PDDR |= PIN_HID_LED; PIN_MSC_LED_GPIO->PDDR |= PIN_MSC_LED; PIN_CDC_LED_GPIO->PDDR |= PIN_CDC_LED; PIN_POWER_EN_GPIO->PDDR |= PIN_POWER_EN; // set as input PIN_SW_RESET_GPIO->PDDR &= ~PIN_SW_RESET; }
void gpio_init(void) { SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK; // configure pin as GPIO PIN_HID_LED_PORT->PCR[PIN_HID_LED_BIT] = PORT_PCR_MUX(1); PIN_MSC_LED_PORT->PCR[PIN_MSC_LED_BIT] = PORT_PCR_MUX(1); PIN_CDC_LED_PORT->PCR[PIN_CDC_LED_BIT] = PORT_PCR_MUX(1); PIN_SW_RESET_PORT->PCR[PIN_SW_RESET_BIT] = PORT_PCR_MUX(1); PIN_POWER_EN_PORT->PCR[PIN_POWER_EN_BIT] = PORT_PCR_MUX(1); // led off gpio_set_hid_led(GPIO_LED_OFF); gpio_set_cdc_led(GPIO_LED_OFF); gpio_set_msc_led(GPIO_LED_OFF); // power regulator on PIN_POWER_EN_GPIO->PDOR |= PIN_POWER_EN; // set as output PIN_HID_LED_GPIO->PDDR |= PIN_HID_LED; PIN_MSC_LED_GPIO->PDDR |= PIN_MSC_LED; PIN_CDC_LED_GPIO->PDDR |= PIN_CDC_LED; PIN_POWER_EN_GPIO->PDDR |= PIN_POWER_EN; // set as input PIN_SW_RESET_GPIO->PDDR &= ~PIN_SW_RESET; // Let the voltage rails stabilize. This is especailly important // during software resets, since the target's 3.3v rail can take // 20-50ms to drain. During this time the target could be driving // the reset pin low, causing the bootloader to think the reset // button is pressed. // Note: With optimization set to -O2 the value 1000000 delays for ~85ms busy_wait(1000000); }
__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); } } } }