mirror of
https://github.com/hathach/tinyusb.git
synced 2025-02-19 15:40:41 +00:00
force single buffered for device mode, out endpoint
This commit is contained in:
parent
5c567129ea
commit
832d22d7ad
@ -1254,14 +1254,13 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
|||||||
|
|
||||||
if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) )
|
if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) )
|
||||||
{
|
{
|
||||||
TU_LOG2("OK\r\n");
|
|
||||||
return true;
|
return true;
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
// DCD error, mark endpoint as ready to allow next transfer
|
// DCD error, mark endpoint as ready to allow next transfer
|
||||||
_usbd_dev.ep_status[epnum][dir].busy = false;
|
_usbd_dev.ep_status[epnum][dir].busy = false;
|
||||||
_usbd_dev.ep_status[epnum][dir].claimed = 0;
|
_usbd_dev.ep_status[epnum][dir].claimed = 0;
|
||||||
TU_LOG2("failed\r\n");
|
TU_LOG2("FAILED\r\n");
|
||||||
TU_BREAKPOINT();
|
TU_BREAKPOINT();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,7 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t ep_addr, uint16_t
|
|||||||
|
|
||||||
// Now if it hasn't already been done
|
// Now if it hasn't already been done
|
||||||
//alloc a buffer and fill in endpoint control register
|
//alloc a buffer and fill in endpoint control register
|
||||||
|
// TODO device may change configuration (dynamic), should clear and reallocate
|
||||||
if(!(ep->configured))
|
if(!(ep->configured))
|
||||||
{
|
{
|
||||||
_hw_endpoint_alloc(ep);
|
_hw_endpoint_alloc(ep);
|
||||||
@ -194,9 +195,6 @@ static void hw_handle_buff_status(void)
|
|||||||
{
|
{
|
||||||
if (remaining_buffers & bit)
|
if (remaining_buffers & bit)
|
||||||
{
|
{
|
||||||
uint __unused which = (usb_hw->buf_cpu_should_handle & bit) ? 1 : 0;
|
|
||||||
// Should be single buffered
|
|
||||||
assert(which == 0);
|
|
||||||
// clear this in advance
|
// clear this in advance
|
||||||
usb_hw_clear->buf_status = bit;
|
usb_hw_clear->buf_status = bit;
|
||||||
// IN transfer for even i, OUT transfer for odd i
|
// IN transfer for even i, OUT transfer for odd i
|
||||||
@ -463,7 +461,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * re
|
|||||||
|
|
||||||
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||||
{
|
{
|
||||||
pico_info("dcd_edpt_open %d %02x\n", rhport, desc_edpt->bEndpointAddress);
|
pico_info("dcd_edpt_open %02x\n", desc_edpt->bEndpointAddress);
|
||||||
assert(rhport == 0);
|
assert(rhport == 0);
|
||||||
hw_endpoint_init(desc_edpt->bEndpointAddress, desc_edpt->wMaxPacketSize.size, desc_edpt->bmAttributes.xfer);
|
hw_endpoint_init(desc_edpt->bEndpointAddress, desc_edpt->wMaxPacketSize.size, desc_edpt->bmAttributes.xfer);
|
||||||
return true;
|
return true;
|
||||||
@ -478,14 +476,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
|
|||||||
|
|
||||||
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
pico_trace("dcd_edpt_stall %d %02x\n", rhport, ep_addr);
|
pico_trace("dcd_edpt_stall %02x\n", ep_addr);
|
||||||
assert(rhport == 0);
|
assert(rhport == 0);
|
||||||
hw_endpoint_stall(ep_addr);
|
hw_endpoint_stall(ep_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
pico_trace("dcd_edpt_clear_stall %d %02x\n", rhport, ep_addr);
|
pico_trace("dcd_edpt_clear_stall %02x\n", ep_addr);
|
||||||
assert(rhport == 0);
|
assert(rhport == 0);
|
||||||
hw_endpoint_clear_stall(ep_addr);
|
hw_endpoint_clear_stall(ep_addr);
|
||||||
}
|
}
|
||||||
@ -493,8 +491,11 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
|
|||||||
|
|
||||||
void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
|
(void) rhport;
|
||||||
|
(void) ep_addr;
|
||||||
|
|
||||||
// usbd.c says: In progress transfers on this EP may be delivered after this call
|
// usbd.c says: In progress transfers on this EP may be delivered after this call
|
||||||
pico_trace("dcd_edpt_close %d %02x\n", rhport, ep_addr);
|
pico_trace("dcd_edpt_close %02x\n", ep_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dcd_int_handler(uint8_t rhport)
|
void dcd_int_handler(uint8_t rhport)
|
||||||
|
@ -148,10 +148,15 @@ static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
|
|||||||
{
|
{
|
||||||
uint32_t ep_ctrl = *ep->endpoint_control;
|
uint32_t ep_ctrl = *ep->endpoint_control;
|
||||||
|
|
||||||
// always compute buffer 0
|
// always compute and start with buffer 0
|
||||||
uint32_t buf_ctrl = prepare_ep_buffer(ep, 0);
|
uint32_t buf_ctrl = prepare_ep_buffer(ep, 0) | USB_BUF_CTRL_SEL;
|
||||||
|
|
||||||
if(ep->remaining_len)
|
// For now: skip double buffered for Device mode, OUT endpoint since
|
||||||
|
// host could send < 64 bytes and cause short packet on buffer0
|
||||||
|
// NOTE this could happen to Host mode IN endpoint
|
||||||
|
bool const force_single = !(usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && !tu_edpt_dir(ep->ep_addr);
|
||||||
|
|
||||||
|
if(ep->remaining_len && !force_single)
|
||||||
{
|
{
|
||||||
// Use buffer 1 (double buffered) if there is still data
|
// Use buffer 1 (double buffered) if there is still data
|
||||||
// TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt)
|
// TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt)
|
||||||
@ -181,8 +186,7 @@ static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
|
|||||||
void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len)
|
void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t total_len)
|
||||||
{
|
{
|
||||||
_hw_endpoint_lock_update(ep, 1);
|
_hw_endpoint_lock_update(ep, 1);
|
||||||
pico_trace("Start transfer of total len %d on ep %d %s\n", total_len, tu_edpt_number(ep->ep_addr),
|
|
||||||
ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
|
|
||||||
if ( ep->active )
|
if ( ep->active )
|
||||||
{
|
{
|
||||||
// TODO: Is this acceptable for interrupt packets?
|
// TODO: Is this acceptable for interrupt packets?
|
||||||
@ -251,10 +255,42 @@ static void _hw_endpoint_xfer_sync (struct hw_endpoint *ep)
|
|||||||
// always sync buffer 0
|
// always sync buffer 0
|
||||||
uint16_t buf0_bytes = sync_ep_buffer(ep, 0);
|
uint16_t buf0_bytes = sync_ep_buffer(ep, 0);
|
||||||
|
|
||||||
// sync buffer 1 if double buffered and buffer 0 is not short packet
|
// sync buffer 1 if double buffered
|
||||||
if ( ((*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS) && (buf0_bytes == ep->wMaxPacketSize) )
|
if ( (*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS )
|
||||||
{
|
{
|
||||||
sync_ep_buffer(ep, 1);
|
if (buf0_bytes == ep->wMaxPacketSize)
|
||||||
|
{
|
||||||
|
// sync buffer 1 if not short packet
|
||||||
|
sync_ep_buffer(ep, 1);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// short packet on buffer 0
|
||||||
|
// TODO couldn't figure out how to handle this case which happen with net_lwip_webserver example
|
||||||
|
// At this time (currently trigger per 2 buffer), the buffer1 is probably filled with data from
|
||||||
|
// the next transfer (not current one). For now we disable double buffered for device OUT
|
||||||
|
// NOTE this could happen to Host IN
|
||||||
|
#if 0
|
||||||
|
uint8_t const ep_num = tu_edpt_number(ep->ep_addr);
|
||||||
|
uint8_t const dir = (uint8_t) tu_edpt_dir(ep->ep_addr);
|
||||||
|
uint8_t const ep_id = 2*ep_num + (dir ? 0 : 1);
|
||||||
|
|
||||||
|
// abort queued transfer on buffer 1
|
||||||
|
usb_hw->abort |= TU_BIT(ep_id);
|
||||||
|
|
||||||
|
while ( !(usb_hw->abort_done & TU_BIT(ep_id)) ) {}
|
||||||
|
|
||||||
|
uint32_t ep_ctrl = *ep->endpoint_control;
|
||||||
|
ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
|
||||||
|
ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
|
||||||
|
|
||||||
|
_hw_endpoint_buffer_control_set_value32(ep, 0);
|
||||||
|
|
||||||
|
usb_hw->abort &= ~TU_BIT(ep_id);
|
||||||
|
|
||||||
|
TU_LOG(3, "----SHORT PACKET buffer0 on EP %02X:\r\n", ep->ep_addr);
|
||||||
|
print_bufctrl32(buf_ctrl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ static inline void print_bufctrl16(uint32_t u16)
|
|||||||
.u16 = u16
|
.u16 = u16
|
||||||
};
|
};
|
||||||
|
|
||||||
TU_LOG(3, "len = %u, available = %u, stall = %u, reset = %u, toggle = %u, last = %u, full = %u\r\n",
|
TU_LOG(3, "len = %u, available = %u, full = %u, last = %u, stall = %u, reset = %u, toggle = %u\r\n",
|
||||||
bufctrl.xfer_len, bufctrl.available, bufctrl.stall, bufctrl.reset_bufsel, bufctrl.data_toggle, bufctrl.last_buf, bufctrl.full);
|
bufctrl.xfer_len, bufctrl.available, bufctrl.full, bufctrl.last_buf, bufctrl.stall, bufctrl.reset_bufsel, bufctrl.data_toggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void print_bufctrl32(uint32_t u32)
|
static inline void print_bufctrl32(uint32_t u32)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user