altos/lpc: Get the IRC turned off after boot time
[fw/altos] / src / lpc / ao_usb_lpc.c
index cd8967249643c365312985816a37a4429dfd681d..e574f1e23f6eb3b6d80afc5b05cca9fe9a6888b2 100644 (file)
@@ -81,8 +81,7 @@ static uint8_t        ao_usb_tx_count;
 static uint8_t ao_usb_rx_buffer[AO_USB_OUT_SIZE];
 static uint8_t ao_usb_rx_count, ao_usb_rx_pos;
 
-__attribute__((section(".usb")))
-static struct lpc_usb_endpoint lpc_usb_endpoint __attribute((aligned(256)));
+extern struct lpc_usb_endpoint lpc_usb_endpoint;
 
 /* Marks when we don't need to send an IN packet.
  * This happens only when the last IN packet is not full,
@@ -606,8 +605,14 @@ ao_usb_ep0_handle(uint8_t receive)
                /* Wait until the IN packet is received from addr 0
                 * before assigning our local address
                 */
-               if (ao_usb_address_pending)
+               if (ao_usb_address_pending) {
+#if HAS_FLIGHT
+                       /* Go to idle mode if USB is connected
+                        */
+                       ao_flight_force_idle = 1;
+#endif
                        ao_usb_set_address(ao_usb_address);
+               }
                if (ao_usb_ep0_state == AO_USB_EP0_DATA_IN)
                        ao_usb_ep0_flush();
        }
@@ -829,8 +834,9 @@ ao_usb_disable(void)
        /* Turn off USB clock */
        lpc_scb.usbclkdiv = 0;
 
-       /* Disable USB PHY */
-       lpc_scb.pdruncfg |= (1 << LPC_SCB_PDRUNCFG_USBPAD_PD);
+       /* Disable USB PHY and PLL */
+       lpc_scb.pdruncfg |= ((1 << LPC_SCB_PDRUNCFG_USBPAD_PD) |
+                            (1 << LPC_SCB_PDRUNCFG_USBPLL_PD));
 
        /* Disable USB registers and RAM */
        lpc_scb.sysahbclkctrl &= ~((1 << LPC_SCB_SYSAHBCLKCTRL_USB) |
@@ -872,7 +878,6 @@ ao_usb_enable(void)
        lpc_scb.pdruncfg &= ~(1 << LPC_SCB_PDRUNCFG_USBPLL_PD);
 
        lpc_scb.usbpllclksel = (LPC_SCB_SYSPLLCLKSEL_SEL_SYSOSC << LPC_SCB_SYSPLLCLKSEL_SEL);
-       lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
        lpc_scb.usbpllclkuen = (0 << LPC_SCB_USBPLLCLKUEN_ENA);
        lpc_scb.usbpllclkuen = (1 << LPC_SCB_USBPLLCLKUEN_ENA);
        while (!(lpc_scb.usbpllclkuen & (1 << LPC_SCB_USBPLLCLKUEN_ENA)))
@@ -882,6 +887,10 @@ ao_usb_enable(void)
                ;
 
        lpc_scb.usbclksel = 0;
+       lpc_scb.usbclkuen = (0 << LPC_SCB_USBCLKUEN_ENA);
+       lpc_scb.usbclkuen = (1 << LPC_SCB_USBCLKUEN_ENA);
+       while (!(lpc_scb.usbclkuen & (1 << LPC_SCB_USBCLKUEN_ENA)))
+               ;
 
        /* Turn on USB clock, use 48MHz clock unchanged */
        lpc_scb.usbclkdiv = 1;