From bf0d1a7b4114ca35a2000bd47d9c6d73c6e92ce2 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Mon, 14 Mar 2011 20:31:32 +1300 Subject: [PATCH] Connectivity line USB driver now enumerating correctly. --- include/libopencm3/stm32/otg_fs.h | 10 ++++++++++ lib/usb/usb_f107.c | 21 ++++++++------------- lib/usb/usb_standard.c | 6 ++++++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h index d39593e2..34a7c852 100644 --- a/include/libopencm3/stm32/otg_fs.h +++ b/include/libopencm3/stm32/otg_fs.h @@ -297,6 +297,16 @@ #define OTG_FS_DIEPINTX_EPDISD (1 << 1) #define OTG_FS_DIEPINTX_XFRC (1 << 0) +/* OTG_FS Device IN Endpoint Interrupt Register (OTG_FS_DOEPINTx) */ +/* Bits 31:7 - Reserved */ +#define OTG_FS_DOEPINTX_B2BSTUP (1 << 6) +/* Bit 5 - Reserved */ +#define OTG_FS_DOEPINTX_OTEPDIS (1 << 4) +#define OTG_FS_DOEPINTX_STUP (1 << 3) +/* Bit 2 - Reserved */ +#define OTG_FS_DOEPINTX_EPDISD (1 << 1) +#define OTG_FS_DOEPINTX_XFRC (1 << 0) + /* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_FS_DOEPTSIZ0) */ /* Bit 31 - Reserved */ #define OTG_FS_DIEPSIZ0_STUPCNT_1 (0x1 << 29) diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index a681b608..63574431 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -58,12 +58,13 @@ static void stm32f107_usbd_init(void) int i; /* TODO: Enable interrupts on Reset, Transfer, Suspend and Resume */ + OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS; + /* WARNING: Undocumented! Select internal PHY */ OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL; /* Enable VBUS sensing in device mode and power down the phy */ OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN; - for(i = 0; i < 800000; i++) __asm__("nop"); /* Wait for AHB idle */ while(!(OTG_FS_GRSTCTL & OTG_FS_GRSTCTL_AHBIDL)); @@ -71,7 +72,6 @@ static void stm32f107_usbd_init(void) OTG_FS_GRSTCTL |= OTG_FS_GRSTCTL_CSRST; while(OTG_FS_GRSTCTL & OTG_FS_GRSTCTL_CSRST); - for(i = 0; i < 800000; i++) __asm__("nop"); /* Force peripheral only mode. */ OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD; @@ -82,6 +82,9 @@ static void stm32f107_usbd_init(void) /* Restart the phy clock */ OTG_FS_PCGCCTL = 0; + OTG_FS_GRXFSIZ = 128; + OTG_FS_GNPTXFSIZ = (128 << 16) | 128; + /* Unmask interrupts for TX and RX */ OTG_FS_GINTMSK &= OTG_FS_GINTMSK_RXFLVLM; @@ -89,15 +92,7 @@ static void stm32f107_usbd_init(void) static void stm32f107_set_address(u8 addr) { - /* There is something badly wrong gere! */ - - /* TODO: Set device address and enable. */ - - /* This I think is correct, but doesn't work at all... */ - //OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4); - - /* This is obviously incorrect, but sometimes works... */ - OTG_FS_DCFG |= addr << 4; + OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4); } static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, @@ -171,9 +166,9 @@ static void stm32f107_ep_stall_set(u8 addr, u8 stall) { if(addr == 0) { if(stall) - OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL; + OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL; else - OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL; + OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL; } if(addr & 0x80) { diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c index 59953875..7bac2160 100644 --- a/lib/usb/usb_standard.c +++ b/lib/usb/usb_standard.c @@ -131,6 +131,12 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf, _usbd_device.current_address = req->wValue; + /* Special workaround for STM32F10[57] that require the address + * to be set here. This is undocumented! + */ + if(_usbd_device.driver == &stm32f107_usb_driver) + _usbd_device.driver->set_address(req->wValue); + return 1; }