Exemple #1
0
void bootloader_main() {
	SystemInit();
	spiflash_reinit();
	CGU_Init();

	hw_digital_output(LED1);
	hw_digital_output(LED2);
	hw_digital_output(CC3K_CONN_LED);
	hw_digital_output(CC3K_ERR_LED);
	hw_digital_write(CC3K_CONN_LED, 0);
	hw_digital_write(CC3K_ERR_LED, 0);

	init_systick();

	__enable_irq();

	usb_init();
	usb_set_speed(USB_SPEED_FULL);
	usb_attach();

	while(!exit_and_jump) {
		led_task();
		__WFI(); /* conserve power */
	}

	delay_ms(25);

	usb_detach();

	delay_ms(100);

	if (dfu_target == TARGET_RAM) {
		jump_to_flash(DFU_DEST_BASE, 0);
	}
}
Exemple #2
0
static void usb_hub_attach(USBPort *port1, USBDevice *dev)
{
    USBHubState *s = port1->opaque;
    USBHubPort *port = &s->ports[port1->index];

    if (dev) {
        if (port->port.dev)
            usb_attach(port1, NULL);

        port->wPortStatus |= PORT_STAT_CONNECTION;
        port->wPortChange |= PORT_STAT_C_CONNECTION;
        if (dev->speed == USB_SPEED_LOW)
            port->wPortStatus |= PORT_STAT_LOW_SPEED;
        else
            port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
        port->port.dev = dev;
        /* send the attach message */
        usb_send_msg(dev, USB_MSG_ATTACH);
    } else {
        dev = port->port.dev;
        if (dev) {
            port->wPortStatus &= ~PORT_STAT_CONNECTION;
            port->wPortChange |= PORT_STAT_C_CONNECTION;
            if (port->wPortStatus & PORT_STAT_ENABLE) {
                port->wPortStatus &= ~PORT_STAT_ENABLE;
                port->wPortChange |= PORT_STAT_C_ENABLE;
            }
            /* send the detach message */
            usb_send_msg(dev, USB_MSG_DETACH);
            port->port.dev = NULL;
        }
    }
}
Exemple #3
0
// see usb_hw_layer.h for documentation
void usb_task(void) 
{
   if (usb_attached()) 
   {
      if (UCON_USBEN==0) 
      {
         usb_attach();
      }
   }
   else 
   {
      if (UCON_USBEN==1)  
      {
         usb_detach();
      }
   }

   if ((usb_state == USB_STATE_ATTACHED)&&(!UCON_SE0)) 
   {
      UIR=0;
      UIE=0;
      //enable_interrupts(INT_USB);
      //enable_interrupts(GLOBAL);
      UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  //enable IDLE and RESET USB ISR
      usb_state=USB_STATE_POWERED;
   }
}
Exemple #4
0
void usb_port_reset(USBPort *port)
{
    USBDevice *dev = port->dev;

    assert(dev != NULL);
    usb_detach(port);
    usb_attach(port);
    usb_device_reset(dev);
}
Exemple #5
0
void usb_reset(USBPort *port)
{
    USBDevice *dev = port->dev;

    assert(dev != NULL);
    usb_detach(port);
    usb_attach(port);
    usb_send_msg(dev, USB_MSG_RESET);
}
Exemple #6
0
/* Attach or detach a device on a root hub port.  */
static void ohci_attach(USBPort *port1, USBDevice *dev)
{
    OHCIState *s = port1->opaque;
    OHCIPort *port = &s->rhport[port1->index];
    uint32_t old_state = port->ctrl;

    if (dev) {
        if (port->port.dev) {
            usb_attach(port1, NULL);
        }
        /* set connect status */
        port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC;

        /* update speed */
        if (dev->speed == USB_SPEED_LOW)
            port->ctrl |= OHCI_PORT_LSDA;
        else
            port->ctrl &= ~OHCI_PORT_LSDA;
        port->port.dev = dev;

        /* notify of remote-wakeup */
        if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND)
            ohci_set_interrupt(s, OHCI_INTR_RD);

        /* send the attach message */
        usb_send_msg(dev, USB_MSG_ATTACH);
        dprintf("usb-ohci: Attached port %d\n", port1->index);
    } else {
        /* set connect status */
        if (port->ctrl & OHCI_PORT_CCS) {
            port->ctrl &= ~OHCI_PORT_CCS;
            port->ctrl |= OHCI_PORT_CSC;
        }
        /* disable port */
        if (port->ctrl & OHCI_PORT_PES) {
            port->ctrl &= ~OHCI_PORT_PES;
            port->ctrl |= OHCI_PORT_PESC;
        }
        dev = port->port.dev;
        if (dev) {
            /* send the detach message */
            usb_send_msg(dev, USB_MSG_DETACH);
        }
        port->port.dev = NULL;
        dprintf("usb-ohci: Detached port %d\n", port1->index);
    }

    if (old_state != port->ctrl)
        ohci_set_interrupt(s, OHCI_INTR_RHSC);
}
/* Reset the controller */
static void ohci_reset(void *opaque)
{
    OHCIState *ohci = opaque;
    OHCIPort *port;
    int i;

    ohci_bus_stop(ohci);
    ohci->ctl = 0;
    ohci->old_ctl = 0;
    ohci->status = 0;
    ohci->intr_status = 0;
    ohci->intr = OHCI_INTR_MIE;

    ohci->hcca = 0;
    ohci->ctrl_head = ohci->ctrl_cur = 0;
    ohci->bulk_head = ohci->bulk_cur = 0;
    ohci->per_cur = 0;
    ohci->done = 0;
    ohci->done_count = 7;

    /* FSMPS is marked TBD in OCHI 1.0, what gives ffs?
     * I took the value linux sets ...
     */
    ohci->fsmps = 0x2778;
    ohci->fi = 0x2edf;
    ohci->fit = 0;
    ohci->frt = 0;
    ohci->frame_number = 0;
    ohci->pstart = 0;
    ohci->lst = OHCI_LS_THRESH;

    ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports;
    ohci->rhdesc_b = 0x0; /* Impl. specific */
    ohci->rhstatus = 0;

    for (i = 0; i < ohci->num_ports; i++)
      {
        port = &ohci->rhport[i];
        port->ctrl = 0;
        if (port->port.dev) {
            usb_attach(&port->port, port->port.dev);
        }
      }
    if (ohci->async_td) {
        usb_cancel_packet(&ohci->usb_packet);
        ohci->async_td = 0;
    }
    DPRINTF("usb-ohci: Reset %s\n", ohci->name);
}
Exemple #8
0
void usb_attach(USBPort *port, USBDevice *dev)
{
    if (dev != NULL) {
        /* attach */
        if (port->dev) {
            usb_attach(port, NULL);
        }
        dev->port = port;
        port->dev = dev;
        port->ops->attach(port);
        usb_send_msg(dev, USB_MSG_ATTACH);
    } else {
        /* detach */
        dev = port->dev;
        assert(dev);
        port->ops->detach(port);
        usb_send_msg(dev, USB_MSG_DETACH);
        dev->port = NULL;
        port->dev = NULL;
    }
}
Exemple #9
0
// see usb_hw_layer.h for documentation
void usb_task(void) 
{
  #if defined(USB_ISR_POLLING)
   if (interrupt_active(INT_USB))
   {
      usb_isr();
   }
  #endif

   if (usb_attached()) 
   {
      if (UCON_USBEN==0) 
      {
         debug_usb(debug_putc, "\r\n\nUSB TASK: ATTACH");
         usb_attach();
      }
   }
   else 
   {
      if (UCON_USBEN==1)  
      {
         debug_usb(debug_putc, "\r\n\nUSB TASK: DE-ATTACH");
         usb_detach();
      }
   }

   if ((usb_state == USB_STATE_ATTACHED)&&(!UCON_SE0)) 
   {
      UIR=0;
      UIE=0;
     #if !defined(USB_ISR_POLLING)
      enable_interrupts(INT_USB);
      enable_interrupts(GLOBAL);
     #endif
      UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  //enable IDLE and RESET USB ISR
      usb_state=USB_STATE_POWERED;
      debug_usb(debug_putc, "\r\n\nUSB TASK: POWERED");
   }
}
Exemple #10
0
/* inline since branch is chosen at compile time */
static inline void usb_slave_mode(bool on)
{
#ifdef USE_ROCKBOX_USB
    int rc;

    if (on)
    {
        trigger_cpu_boost();
#ifdef HAVE_PRIORITY_SCHEDULING
        thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
#endif
        usb_attach();
    }
    else /* usb_state == USB_INSERTED (only!) */
    {
#ifndef USB_DETECT_BY_DRV
        usb_enable(false);
#endif
#ifdef HAVE_PRIORITY_SCHEDULING
        thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
#endif
        /* Entered exclusive mode */
        rc = disk_mount_all();
        if (rc <= 0) /* no partition */
            panicf("mount: %d",rc);

        cancel_cpu_boost();
    }
#else /* !USE_ROCKBOX_USB */
    if (on)
    {
        /* until we have native mass-storage mode, we want to reboot on
           usb host connect */
        try_reboot();
    }
#endif /* USE_ROCKBOX_USB */
}
// ****************************************************************************
void HAL_hardware_init_final(void)
{
    usb_init();
    usb_attach();
}
Exemple #12
0
static void usb_thread(void)
{
    int num_acks_to_expect = 0;
    struct queue_event ev;

    while(1)
    {
        queue_wait(&usb_queue, &ev);
        switch(ev.id)
        {
#ifdef USB_DRIVER_CLOSE
            case USB_QUIT:
                return;
#endif
#ifdef HAVE_USBSTACK
            case USB_TRANSFER_COMPLETION:
                usb_core_handle_transfer_completion(
                    (struct usb_transfer_completion_event_data*)ev.data);
                break;
#endif
#ifdef USB_DETECT_BY_DRV
            /* In this case, these events the handle cable insertion USB
             * driver determines INSERTED/EXTRACTED state. */
            case USB_POWERED:
                /* Set the state to USB_POWERED for now and enable the driver
                 * to detect a bus reset only. If a bus reset is detected,
                 * USB_INSERTED will be received. */
                usb_state = USB_POWERED;
                usb_enable(true);
                break;

            case USB_UNPOWERED:
                usb_enable(false);
                /* This part shouldn't be obligatory for anything that can
                 * reliably detect removal of the data lines. USB_EXTRACTED
                 * could be posted on that event while bus power remains
                 * available. */
                queue_post(&usb_queue, USB_EXTRACTED, 0);
                break;
#endif /* USB_DETECT_BY_DRV */
            case USB_INSERTED:
#ifdef HAVE_LCD_BITMAP
                if(do_screendump_instead_of_usb)
                {
                    usb_state = USB_SCREENDUMP;
                    screen_dump();
#ifdef HAVE_REMOTE_LCD
                    remote_screen_dump();
#endif
                    break;
                }
#endif
#ifdef HAVE_USB_POWER
                if(usb_power_button())
                {
                    /* Only charging is desired */
                    usb_state = USB_POWERED;
#ifdef HAVE_USBSTACK
#ifdef USB_ENABLE_STORAGE
                    usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
#endif

#ifdef USB_ENABLE_HID
#ifdef USB_ENABLE_CHARGING_ONLY
                    usb_core_enable_driver(USB_DRIVER_HID, false);
#else
                    usb_core_enable_driver(USB_DRIVER_HID, true);
#endif /* USB_ENABLE_CHARGING_ONLY */
#endif /* USB_ENABLE_HID */

#ifdef USB_ENABLE_CHARGING_ONLY
                    usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
#endif
                    usb_attach();
#endif
                    break;
                }
#endif /* HAVE_USB_POWER */
#ifdef HAVE_USBSTACK
#ifdef HAVE_USB_POWER
                /* Set the state to USB_POWERED for now. If permission to connect
                 * by threads and storage is granted it will be changed to
                 * USB_CONNECTED. */
                usb_state = USB_POWERED;
#endif
#ifdef USB_ENABLE_STORAGE
                usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true);
#endif
#ifdef USB_ENABLE_HID
                usb_core_enable_driver(USB_DRIVER_HID, usb_hid);
#endif
#ifdef USB_ENABLE_CHARGING_ONLY
                usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false);
#endif

                /* Check any drivers enabled at this point for exclusive storage
                 * access requirements. */
                exclusive_storage_access = usb_core_any_exclusive_storage();

                if(!exclusive_storage_access)
                {
                    usb_attach();
                    break;
                }
#endif /* HAVE_USBSTACK */
                /* Tell all threads that they have to back off the storage.
                   We subtract one for our own thread. */
                num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
                DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
                       num_acks_to_expect);
                break;

            case SYS_USB_CONNECTED_ACK:
                if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
                {
                    DEBUGF("All threads have acknowledged the connect.\n");
                    usb_slave_mode(true);
                    usb_state = USB_INSERTED;
                }
                else
                {
                    DEBUGF("usb: got ack, %d to go...\n",
                           num_acks_to_expect);
                }
                break;

            case USB_EXTRACTED:
#ifdef HAVE_LCD_BITMAP
                if(usb_state == USB_SCREENDUMP)
                {
                    usb_state = USB_EXTRACTED;
                    break; /* Connected for screendump only */
                }
#endif
#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
#ifdef HAVE_USB_POWER
                if(usb_state == USB_POWERED)
                {
                    usb_state = USB_EXTRACTED;
                    break;
                }
#endif
#endif /* HAVE_USBSTACK */
                if(usb_state == USB_INSERTED)
                {
                    /* Only disable the USB mode if we really have enabled it
                       some threads might not have acknowledged the
                       insertion */
                    usb_slave_mode(false);
                }

                usb_state = USB_EXTRACTED;
#ifdef HAVE_USBSTACK
                if(!exclusive_storage_access)
                {
#ifndef USB_DETECT_BY_DRV /* Disabled handling USB_UNPOWERED */
                    usb_enable(false);
#endif
                    break;
                }

#endif /* HAVE_USBSTACK */
                num_acks_to_expect = usb_release_exclusive_storage();

                break;

            case SYS_USB_DISCONNECTED_ACK:
                if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
                {
                    DEBUGF("All threads have acknowledged. "
                           "We're in business.\n");
                }
                else
                {
                    DEBUGF("usb: got ack, %d to go...\n",
                           num_acks_to_expect);
                }
                break;

#ifdef HAVE_HOTSWAP
            case SYS_HOTSWAP_INSERTED:
            case SYS_HOTSWAP_EXTRACTED:
#ifdef HAVE_USBSTACK
                usb_core_hotswap_event(1,ev.id == SYS_HOTSWAP_INSERTED);
#else  /* !HAVE_USBSTACK */
                if(usb_state == USB_INSERTED)
                {
#if (CONFIG_STORAGE & STORAGE_MMC)
                    usb_enable(false);
                    usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */
#endif /* STORAGE_MMC */
                }
#endif /* HAVE_USBSTACK */
                break;

#if (CONFIG_STORAGE & STORAGE_MMC)
            case USB_REENABLE:
                if(usb_state == USB_INSERTED)
                    usb_enable(true);  /* reenable only if still inserted */
                break;
#endif /* STORAGE_MMC */
#endif /* HAVE_HOTSWAP */

#ifdef USB_FIREWIRE_HANDLING
            case USB_REQUEST_REBOOT:
#ifdef HAVE_USB_POWER
                if (usb_reboot_button())
#endif
                    try_reboot();
                break;
#endif /* USB_FIREWIRE_HANDLING */

#if defined(HAVE_USB_CHARGING_ENABLE) && defined(HAVE_USBSTACK)
            case USB_CHARGER_UPDATE:
                usb_charging_maxcurrent_change(usb_charging_maxcurrent());
                break;
#endif
        }
    }
}
Exemple #13
0
int main(void) {
    if (PM->RCAUSE.reg & (PM_RCAUSE_POR | PM_RCAUSE_BOD12 | PM_RCAUSE_BOD33)) {
        // On powerup, force a clean reset of the MT7620
        pin_low(PIN_SOC_RST);
        pin_out(PIN_SOC_RST);

        // turn off 3.3V to SoC
        pin_low(PIN_SOC_PWR);
        pin_out(PIN_SOC_PWR);

        // pull 1.8V low
        pin_low(PIN_18_V);
        pin_out(PIN_18_V);

        clock_init_crystal(GCLK_SYSTEM, GCLK_32K);
        timer_clock_enable(TC_BOOT);

        // hold everything low
        boot_delay_ms(50); // power off for 50ms

        pin_high(PIN_SOC_PWR);

        boot_delay_ms(2); // 2ms until 1.8 rail comes on

        pin_high(PIN_18_V);

        boot_delay_ms(50); // 50ms before soc rst comes on
    } else {
        clock_init_crystal(GCLK_SYSTEM, GCLK_32K);
    }

    pin_mux(PIN_USB_DM);
    pin_mux(PIN_USB_DP);
    usb_init();
    usb_attach();
    NVIC_SetPriority(USB_IRQn, 0xff);

    pin_high(PIN_LED);
    pin_out(PIN_LED);

    pin_in(PIN_SOC_RST);

    pin_high(PIN_SOC_PWR);
    pin_out(PIN_SOC_PWR);

    pin_low(PORT_A.power);
    pin_out(PORT_A.power);

    pin_low(PORT_B.power);
    pin_out(PORT_B.power);

    pin_pull_up(PIN_BRIDGE_CS);
    pin_pull_up(PIN_FLASH_CS);

    pin_pull_up(PIN_SERIAL_TX);
    pin_pull_up(PIN_SERIAL_RX);

    dma_init();
    NVIC_EnableIRQ(DMAC_IRQn);
    NVIC_SetPriority(DMAC_IRQn, 0xff);

    eic_init();
    NVIC_EnableIRQ(EIC_IRQn);
    NVIC_SetPriority(EIC_IRQn, 0xff);

    evsys_init();
    NVIC_EnableIRQ(EVSYS_IRQn);
    NVIC_SetPriority(EVSYS_IRQn, 0);

    adc_init(GCLK_SYSTEM, ADC_REFCTRL_REFSEL_INTVCC1);
    dac_init(GCLK_32K);

    bridge_init();

    port_init(&port_a, 1, &PORT_A, GCLK_PORT_A,
        TCC_PORT_A, DMA_PORT_A_TX, DMA_PORT_A_RX);
    port_init(&port_b, 2, &PORT_B, GCLK_PORT_B,
        TCC_PORT_B, DMA_PORT_B_TX, DMA_PORT_B_RX);

    __enable_irq();
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
    
    init_systick();

    while (1) { __WFI(); }
}