Connectivity line USB driver now enumerating correctly.

This commit is contained in:
Gareth McMullin 2011-03-14 20:31:32 +13:00
parent 7faea389e8
commit bf0d1a7b41
3 changed files with 24 additions and 13 deletions

View File

@ -297,6 +297,16 @@
#define OTG_FS_DIEPINTX_EPDISD (1 << 1) #define OTG_FS_DIEPINTX_EPDISD (1 << 1)
#define OTG_FS_DIEPINTX_XFRC (1 << 0) #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) */ /* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_FS_DOEPTSIZ0) */
/* Bit 31 - Reserved */ /* Bit 31 - Reserved */
#define OTG_FS_DIEPSIZ0_STUPCNT_1 (0x1 << 29) #define OTG_FS_DIEPSIZ0_STUPCNT_1 (0x1 << 29)

View File

@ -58,12 +58,13 @@ static void stm32f107_usbd_init(void)
int i; int i;
/* TODO: Enable interrupts on Reset, Transfer, Suspend and Resume */ /* TODO: Enable interrupts on Reset, Transfer, Suspend and Resume */
OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
/* WARNING: Undocumented! Select internal PHY */ /* WARNING: Undocumented! Select internal PHY */
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL; OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL;
/* Enable VBUS sensing in device mode and power down the phy */ /* Enable VBUS sensing in device mode and power down the phy */
OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN; OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN;
for(i = 0; i < 800000; i++) __asm__("nop");
/* Wait for AHB idle */ /* Wait for AHB idle */
while(!(OTG_FS_GRSTCTL & OTG_FS_GRSTCTL_AHBIDL)); 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; OTG_FS_GRSTCTL |= OTG_FS_GRSTCTL_CSRST;
while(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. */ /* Force peripheral only mode. */
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD; OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD;
@ -82,6 +82,9 @@ static void stm32f107_usbd_init(void)
/* Restart the phy clock */ /* Restart the phy clock */
OTG_FS_PCGCCTL = 0; OTG_FS_PCGCCTL = 0;
OTG_FS_GRXFSIZ = 128;
OTG_FS_GNPTXFSIZ = (128 << 16) | 128;
/* Unmask interrupts for TX and RX */ /* Unmask interrupts for TX and RX */
OTG_FS_GINTMSK &= OTG_FS_GINTMSK_RXFLVLM; OTG_FS_GINTMSK &= OTG_FS_GINTMSK_RXFLVLM;
@ -89,15 +92,7 @@ static void stm32f107_usbd_init(void)
static void stm32f107_set_address(u8 addr) static void stm32f107_set_address(u8 addr)
{ {
/* There is something badly wrong gere! */ OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4);
/* 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;
} }
static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size, 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(addr == 0) {
if(stall) if(stall)
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL; OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL;
else else
OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL; OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL;
} }
if(addr & 0x80) { if(addr & 0x80) {

View File

@ -131,6 +131,12 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
_usbd_device.current_address = req->wValue; _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; return 1;
} }