more refactor double buffered rp2040

This commit is contained in:
hathach 2021-06-11 18:14:11 +07:00
parent 1d48320d8a
commit 93cb2ff4cf
1 changed files with 86 additions and 93 deletions

View File

@ -111,76 +111,69 @@ void _hw_endpoint_buffer_control_update32(struct hw_endpoint *ep, uint32_t and_m
*ep->buffer_control = value; *ep->buffer_control = value;
} }
//static void prepare_ep_buf(struct hw_endpoint *ep, uint8_t buf_id) static uint32_t compute_ep_buf(struct hw_endpoint *ep, uint8_t buf_id)
//{
// uint16_t buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize);
//
//
//}
// Prepare buffer control register value
void _hw_endpoint_start_next_buffer(struct hw_endpoint *ep)
{ {
uint32_t ep_ctrl = *ep->endpoint_control; uint16_t const buflen = tu_min16(ep->remaining_len, ep->wMaxPacketSize);
uint32_t buf_ctrl; ep->remaining_len -= buflen;
// Buffer 0 uint32_t buf_ctrl = buflen | USB_BUF_CTRL_AVAIL;
ep->transfer_size = tu_min16(ep->remaining_len, ep->wMaxPacketSize);
ep->remaining_len -= ep->transfer_size;
buf_ctrl = ep->transfer_size | USB_BUF_CTRL_AVAIL;
if ( !ep->rx )
{
// Copy data from user buffer to hw buffer
memcpy(ep->hw_data_buf, ep->user_buf, ep->transfer_size);
ep->user_buf += ep->transfer_size;
// Mark as full
buf_ctrl |= USB_BUF_CTRL_FULL;
}
// PID // PID
buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID; buf_ctrl |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
ep->next_pid ^= 1u; ep->next_pid ^= 1u;
// Buffer 1
ep->buf_1_len = tu_min16(ep->remaining_len, ep->wMaxPacketSize);
ep->remaining_len -= ep->buf_1_len;
if (ep->buf_1_len)
{
buf_ctrl |= (ep->buf_1_len | USB_BUF_CTRL_AVAIL) << 16;
buf_ctrl |= (ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID) << 16;
ep->next_pid ^= 1u;
if ( !ep->rx ) if ( !ep->rx )
{ {
// Copy data from user buffer to hw buffer // Copy data from user buffer to hw buffer
memcpy(ep->hw_data_buf+64, ep->user_buf, ep->buf_1_len); memcpy(ep->hw_data_buf, ep->user_buf, buflen);
ep->user_buf += ep->buf_1_len; ep->user_buf += buflen;
}
// Set endpoint control double buffered bit if needed // Mark as full
ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER; buf_ctrl |= USB_BUF_CTRL_FULL;
ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER;
}else
{
ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
} }
*ep->endpoint_control = ep_ctrl;
#if TUSB_OPT_HOST_ENABLED #if TUSB_OPT_HOST_ENABLED
// Is this the last buffer? Only really matters for host mode. Will trigger // Is this the last buffer? Only really matters for host mode. Will trigger
// the trans complete irq but also stop it polling. We only really care about // the trans complete irq but also stop it polling. We only really care about
// trans complete for setup packets being sent // trans complete for setup packets being sent
if (ep->remaining_len == 0) if (ep->remaining_len == 0)
{ {
buf_ctrl |= USB_BUF_CTRL_LAST << (ep->buf_1_len ? 16 : 0); buf_ctrl |= USB_BUF_CTRL_LAST;
} }
#endif #endif
if (buf_id) buf_ctrl = buf_ctrl << 16;
return buf_ctrl;
}
// Prepare buffer control register value
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 = compute_ep_buf(ep, 0);
if(ep->remaining_len)
{
// Use buffer 1 (double buffered) if there is still data
// TODO: Isochronous for buffer1 bit-field is different than CBI (control bulk, interrupt)
buf_ctrl |= compute_ep_buf(ep, 1);
// Set endpoint control double buffered bit if needed
ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER;
ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER;
}else
{
// Single buffered since 1 is enough
ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
}
*ep->endpoint_control = ep_ctrl;
print_bufctrl32(buf_ctrl); print_bufctrl32(buf_ctrl);
// Finally, write to buffer_control which will trigger the transfer // Finally, write to buffer_control which will trigger the transfer