#include "ao_usb.h"
#include "ao_product.h"
+#ifndef USE_USB_STDIO
+#define USE_USB_STDIO 1
+#endif
+
+#if USE_USB_STDIO
+#define AO_USB_OUT_SLEEP_ADDR (&ao_stdin_ready)
+#else
+#define AO_USB_OUT_SLEEP_ADDR (&ao_usb_out_avail)
+#endif
+
#define USB_DEBUG 0
#define USB_DEBUG_DATA 0
#define USB_ECHO 0
#define debug_data(format, args...)
#endif
-struct ao_task ao_usb_task;
-
struct ao_usb_setup {
uint8_t dir_type_recip;
uint8_t request;
}
static void
-ao_usb_ep0_in_start(uint8_t max)
+ao_usb_ep0_in_start(uint16_t max)
{
/* Don't send more than asked for */
if (ao_usb_ep0_in_len > max)
/* 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();
}
_rx_dbg1("RX ISR", *ao_usb_epn_out(AO_USB_OUT_EP));
ao_usb_out_avail = 1;
_rx_dbg0("out avail set");
- ao_wakeup(&ao_stdin_ready);
+ ao_wakeup(AO_USB_OUT_SLEEP_ADDR)
_rx_dbg0("stdin awoken");
}
ao_arch_block_interrupts();
while ((c = _ao_usb_pollchar()) == AO_READ_AGAIN)
- ao_sleep(&ao_stdin_ready);
+ ao_sleep(AO_USB_OUT_SLEEP_ADDR);
ao_arch_release_interrupts();
return c;
}
{
ao_arch_block_interrupts();
+#if HAS_USB_PULLUP
+ ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
+#endif
/* Disable interrupts */
lpc_usb.inten = 0;
/* 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) |
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)))
;
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;
for (t = 0; t < 1000; t++)
ao_arch_nop();
+#if HAS_USB_PULLUP
+ ao_gpio_set(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 1);
+#endif
+
ao_usb_set_ep0();
}
void
ao_usb_init(void)
{
+#if HAS_USB_PULLUP
+ ao_enable_output(AO_USB_PULLUP_PORT, AO_USB_PULLUP_PIN, AO_USB_PULLUP, 0);
+#endif
+
ao_usb_enable();
debug ("ao_usb_init\n");
#if USB_DEBUG
ao_cmd_register(&ao_usb_cmds[0]);
#endif
-#if !USB_ECHO
+#if USE_USB_STDIO
ao_add_stdio(_ao_usb_pollchar, ao_usb_putchar, ao_usb_flush);
#endif
}