mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08: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) )
|
||||
{
|
||||
TU_LOG2("OK\r\n");
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
// DCD error, mark endpoint as ready to allow next transfer
|
||||
_usbd_dev.ep_status[epnum][dir].busy = false;
|
||||
_usbd_dev.ep_status[epnum][dir].claimed = 0;
|
||||
TU_LOG2("failed\r\n");
|
||||
TU_LOG2("FAILED\r\n");
|
||||
TU_BREAKPOINT();
|
||||
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
|
||||
//alloc a buffer and fill in endpoint control register
|
||||
// TODO device may change configuration (dynamic), should clear and reallocate
|
||||
if(!(ep->configured))
|
||||
{
|
||||
_hw_endpoint_alloc(ep);
|
||||
@ -194,9 +195,6 @@ static void hw_handle_buff_status(void)
|
||||
{
|
||||
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
|
||||
usb_hw_clear->buf_status = bit;
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
hw_endpoint_init(desc_edpt->bEndpointAddress, desc_edpt->wMaxPacketSize.size, desc_edpt->bmAttributes.xfer);
|
||||
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)
|
||||
{
|
||||
pico_trace("dcd_edpt_stall %d %02x\n", rhport, ep_addr);
|
||||
pico_trace("dcd_edpt_stall %02x\n", ep_addr);
|
||||
assert(rhport == 0);
|
||||
hw_endpoint_stall(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);
|
||||
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) rhport;
|
||||
(void) ep_addr;
|
||||
|
||||
// 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)
|
||||
|
@ -148,10 +148,15 @@ static void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
|
||||
{
|
||||
uint32_t ep_ctrl = *ep->endpoint_control;
|
||||
|
||||
// always compute buffer 0
|
||||
uint32_t buf_ctrl = prepare_ep_buffer(ep, 0);
|
||||
// always compute and start with buffer 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
|
||||
// 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)
|
||||
{
|
||||
_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 )
|
||||
{
|
||||
// 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
|
||||
uint16_t buf0_bytes = sync_ep_buffer(ep, 0);
|
||||
|
||||
// sync buffer 1 if double buffered and buffer 0 is not short packet
|
||||
if ( ((*ep->endpoint_control) & EP_CTRL_DOUBLE_BUFFERED_BITS) && (buf0_bytes == ep->wMaxPacketSize) )
|
||||
// sync buffer 1 if double buffered
|
||||
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
|
||||
};
|
||||
|
||||
TU_LOG(3, "len = %u, available = %u, stall = %u, reset = %u, toggle = %u, last = %u, full = %u\r\n",
|
||||
bufctrl.xfer_len, bufctrl.available, bufctrl.stall, bufctrl.reset_bufsel, bufctrl.data_toggle, bufctrl.last_buf, bufctrl.full);
|
||||
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.full, bufctrl.last_buf, bufctrl.stall, bufctrl.reset_bufsel, bufctrl.data_toggle);
|
||||
}
|
||||
|
||||
static inline void print_bufctrl32(uint32_t u32)
|
||||
|
Loading…
x
Reference in New Issue
Block a user