usb_f107: Fixed lost 4 bytes on control OUT transaction.

This commit is contained in:
Gareth McMullin 2011-10-30 20:19:29 +13:00 committed by Piotr Esden-Tempski
parent 1fea1df39a
commit e0fe43357d
2 changed files with 37 additions and 8 deletions

View File

@ -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()

View File

@ -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.