From e0fe43357d1f2f986e7969a3d6efe723e6828fcf Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Sun, 30 Oct 2011 20:19:29 +1300 Subject: [PATCH] usb_f107: Fixed lost 4 bytes on control OUT transaction. --- .../stm32/f1/stm32-h107/usb_simple/usbtest.py | 20 +++++++++++++++ lib/usb/usb_f107.c | 25 +++++++++++++------ 2 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 examples/stm32/f1/stm32-h107/usb_simple/usbtest.py diff --git a/examples/stm32/f1/stm32-h107/usb_simple/usbtest.py b/examples/stm32/f1/stm32-h107/usb_simple/usbtest.py new file mode 100644 index 00000000..85b0ade4 --- /dev/null +++ b/examples/stm32/f1/stm32-h107/usb_simple/usbtest.py @@ -0,0 +1,20 @@ +import usb.core + +if __name__ == "__main__": + dev = usb.core.find(idVendor=0xcafe, idProduct=0xcafe) + if dev is None: + raise ValueError('Device not found') + + dev.set_configuration() + + import gtk + w = gtk.Window() + w.connect("destroy", gtk.main_quit) + toggle = gtk.ToggleButton("Toggle LED") + def toggled(button): + dev.ctrl_transfer(0x40, 0, button.get_active(), 0, 'Hello World!') + toggle.connect("toggled", toggled) + w.add(toggle) + w.show_all() + gtk.main() + diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c index 16630eea..8f03571c 100644 --- a/lib/usb/usb_f107.c +++ b/lib/usb/usb_f107.c @@ -81,7 +81,7 @@ static void stm32f107_usbd_init(void) /* Force peripheral only mode. */ - OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD; + OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD | OTG_FS_GUSBCFG_TRDT_MASK; /* Full speed device */ OTG_FS_DCFG |= OTG_FS_DCFG_DSPD; @@ -265,7 +265,7 @@ static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len) * stm32f107_poll() which reads the packet status push register GRXSTSP * for use in stm32f107_ep_read_packet(). */ -static uint16_t rxbcnt[4]; +static uint16_t rxbcnt; static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) { @@ -273,8 +273,8 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) u32 *buf32 = buf; u32 extra; - len = MIN(len, rxbcnt[addr]); - rxbcnt[addr] = 0; + len = MIN(len, rxbcnt); + rxbcnt -= len; volatile u32 *fifo = OTG_FS_FIFO(addr); for(i = len; i >= 4; i -= 4) { @@ -286,9 +286,6 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len) memcpy(buf32, &extra, i); } - if(len == 8) - extra = *fifo++; - OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr]; OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK); @@ -327,10 +324,22 @@ static void stm32f107_poll(void) type = USB_TRANSACTION_OUT; /* Save packet size for stm32f107_ep_read_packet() */ - rxbcnt[ep] = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; + rxbcnt = (rxstsp & OTG_FS_GRXSTSP_BCNT_MASK) >> 4; + + /* FIXME: Why is a delay needed here? + * This appears to fix a problem where the first 4 bytes + * of the DATA OUT stage of a control transaction are lost. + */ + for(i = 0; i < 1000; i++) asm("nop"); if (_usbd_device.user_callback_ctr[ep][type]) _usbd_device.user_callback_ctr[ep][type] (ep); + + /* Discard unread packet data */ + for(i = 0; i < rxbcnt; i += 4) + (void)*OTG_FS_FIFO(ep); + + rxbcnt = 0; } /* There is no global interrupt flag for transmit complete.