usb_f107: Fixed lost 4 bytes on control OUT transaction.
This commit is contained in:
parent
1fea1df39a
commit
e0fe43357d
20
examples/stm32/f1/stm32-h107/usb_simple/usbtest.py
Normal file
20
examples/stm32/f1/stm32-h107/usb_simple/usbtest.py
Normal 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()
|
||||||
|
|
@ -81,7 +81,7 @@ static void stm32f107_usbd_init(void)
|
|||||||
|
|
||||||
|
|
||||||
/* Force peripheral only mode. */
|
/* 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 */
|
/* Full speed device */
|
||||||
OTG_FS_DCFG |= OTG_FS_DCFG_DSPD;
|
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
|
* stm32f107_poll() which reads the packet status push register GRXSTSP
|
||||||
* for use in stm32f107_ep_read_packet().
|
* 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)
|
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 *buf32 = buf;
|
||||||
u32 extra;
|
u32 extra;
|
||||||
|
|
||||||
len = MIN(len, rxbcnt[addr]);
|
len = MIN(len, rxbcnt);
|
||||||
rxbcnt[addr] = 0;
|
rxbcnt -= len;
|
||||||
|
|
||||||
volatile u32 *fifo = OTG_FS_FIFO(addr);
|
volatile u32 *fifo = OTG_FS_FIFO(addr);
|
||||||
for(i = len; i >= 4; i -= 4) {
|
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);
|
memcpy(buf32, &extra, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len == 8)
|
|
||||||
extra = *fifo++;
|
|
||||||
|
|
||||||
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
|
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
|
||||||
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
|
||||||
(force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
|
(force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
|
||||||
@ -327,10 +324,22 @@ static void stm32f107_poll(void)
|
|||||||
type = USB_TRANSACTION_OUT;
|
type = USB_TRANSACTION_OUT;
|
||||||
|
|
||||||
/* Save packet size for stm32f107_ep_read_packet() */
|
/* 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])
|
if (_usbd_device.user_callback_ctr[ep][type])
|
||||||
_usbd_device.user_callback_ctr[ep][type] (ep);
|
_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.
|
/* There is no global interrupt flag for transmit complete.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user