summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2022-04-01 16:01:24 +0700
committerhathach <[email protected]>2022-04-01 16:01:24 +0700
commit75bca96bc630b98723c9f4bbb4958dac22ac594d (patch)
tree912526cde9affbd675f449ccbd9fa85eecf4275e
parente94d11a5b39cae08f39722eaa5f6ac4d527a329b (diff)
pio usb control work well including stall response
-rw-r--r--src/host/hcd.h4
-rw-r--r--src/host/usbh.c16
-rw-r--r--src/portable/raspberrypi/pio/hcd_pio.c116
3 files changed, 77 insertions, 59 deletions
diff --git a/src/host/hcd.h b/src/host/hcd.h
index 0e18351fc..9b41f2447 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -153,10 +153,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
-// Optional: some controllers are capable of carry out the whole Control Transfer (setup, data, status)
-// without help of USBH.
-bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data) TU_ATTR_WEAK;
-
// clear stall, data toggle is also reset to DATA0
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
diff --git a/src/host/usbh.c b/src/host/usbh.c
index b388a4c08..520ef4c7d 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -543,19 +543,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
const uint8_t rhport = usbh_get_rhport(daddr);
TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request");
- TU_LOG2_VAR(&xfer->setup);
+ TU_LOG2_VAR(xfer->setup);
TU_LOG2("\r\n");
if (xfer->complete_cb)
{
- if ( hcd_edpt_control_xfer )
- {
- _ctrl_xfer.stage = CONTROL_STAGE_ACK;
- TU_ASSERT( hcd_edpt_control_xfer(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request, _ctrl_xfer.buffer) );
- }else
- {
- TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) );
- }
+ TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) );
}else
{
// blocking if complete callback is not provided
@@ -643,7 +636,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
{
// DATA stage: initial data toggle is always 1
_set_control_xfer_stage(CONTROL_STAGE_DATA);
- return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength);
+ TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) );
+ return true;
}
__attribute__((fallthrough));
@@ -658,7 +652,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
// ACK stage: toggle is always 1
_set_control_xfer_stage(CONTROL_STAGE_ACK);
- hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
+ TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) );
break;
case CONTROL_STAGE_ACK:
diff --git a/src/portable/raspberrypi/pio/hcd_pio.c b/src/portable/raspberrypi/pio/hcd_pio.c
index 254acf1d2..4eff490c8 100644
--- a/src/portable/raspberrypi/pio/hcd_pio.c
+++ b/src/portable/raspberrypi/pio/hcd_pio.c
@@ -53,15 +53,6 @@ extern pio_port_t pio_port[1];
extern root_port_t root_port[PIO_USB_ROOT_PORT_CNT];
extern endpoint_t ep_pool[PIO_USB_EP_POOL_CNT];
-extern void configure_fullspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port);
-extern void configure_lowspeed_host( pio_port_t *pp, const pio_usb_configuration_t *c, root_port_t *port);
-
-extern void control_setup_transfer( const pio_port_t *pp, uint8_t device_address, uint8_t *tx_data_address, uint8_t tx_data_len);
-extern int control_in_protocol( usb_device_t *device, uint8_t *tx_data, uint16_t tx_length, uint8_t *rx_buffer, uint16_t request_length);
-extern int control_out_protocol( usb_device_t *device, uint8_t *setup_data, uint16_t setup_length, uint8_t *out_data, uint16_t out_length);
-
-extern void update_packet_crc16(usb_setup_packet_t * packet);
-
//--------------------------------------------------------------------+
// HCD API
//--------------------------------------------------------------------+
@@ -157,12 +148,15 @@ void hcd_int_disable(uint8_t rhport)
// Endpoint API
//--------------------------------------------------------------------+
-bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
{
rhport = RHPORT_PIO(rhport);
usb_device_t *device = &usb_device[0];
+ return pio_usb_endpoint_open(rhport, dev_addr, (uint8_t const*) desc_ep);
+
+#if 0
static uint8_t ep_id_idx; // TODO remove later
if (ep_desc->bEndpointAddress == 0)
@@ -202,45 +196,19 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
}
return true;
+#endif
}
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
{
- (void) rhport;
-
- return true;
+ rhport = RHPORT_PIO(rhport);
+ return pio_usb_endpoint_transfer(rhport, dev_addr, ep_addr, buffer, buflen);
}
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
{
- (void) rhport;
- return false;
-}
-
-
-bool hcd_edpt_control_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8], uint8_t* data)
-{
- int ret;
rhport = RHPORT_PIO(rhport);
-
- uint16_t const len = ((tusb_control_request_t const*) setup_packet)->wLength;
-
- usb_setup_packet_t pio_setup = { USB_SYNC, USB_PID_DATA0 };
- memcpy(&pio_setup.request_type, setup_packet, 8);
- update_packet_crc16(&pio_setup);
-
- if (setup_packet[0] & TUSB_DIR_IN_MASK)
- {
- ret = control_in_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len);
- }else
- {
- ret = control_out_protocol(&usb_device[0], (uint8_t*) &pio_setup, sizeof(pio_setup), data, len);
- }
-
- // TODO current pio is blocking
- hcd_event_xfer_complete(dev_addr, 0, 0, ret ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS, false);
-
- return ret == 0;
+ return pio_usb_endpoint_send_setup(rhport, dev_addr, setup_packet);
}
//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
@@ -265,23 +233,83 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
return true;
}
+void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* port, uint32_t flag)
+{
+ volatile uint32_t* ep_reg;
+ xfer_result_t result;
+
+ if ( flag == PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+ {
+ ep_reg = &port->ep_complete;
+ result = XFER_RESULT_SUCCESS;
+ }
+ else if ( flag == PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+ {
+ ep_reg = &port->ep_error;
+ result = XFER_RESULT_FAILED;
+ }
+ else if ( flag == PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+ {
+ ep_reg = &port->ep_stalled;
+ result = XFER_RESULT_STALLED;
+ }
+ else
+ {
+ // something wrong
+ return;
+ }
+
+ const uint32_t ep_all = *ep_reg;
+
+ for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
+ {
+ uint32_t const mask = (1u << ep_idx);
+
+ if (ep_all & mask)
+ {
+ endpoint_t* ep = PIO_USB_EP(ep_idx);
+ hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true);
+ }
+ }
+
+ // clear all
+ (*ep_reg) &= ~ep_all;
+}
+
// IRQ Handler
-void pio_usb_irq_handler(uint8_t root_id)
+void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id)
{
root_port_t* port = PIO_USB(root_id);
if ( port->ints & PIO_USB_INTS_CONNECT_BITS )
{
- hcd_event_device_attach(root_id+1, true);
-
port->ints &= ~PIO_USB_INTS_CONNECT_BITS;
+
+ hcd_event_device_attach(root_id+1, true);
}
if ( port->ints & PIO_USB_INTS_DISCONNECT_BITS )
{
+ port->ints &= ~PIO_USB_INTS_DISCONNECT_BITS;
hcd_event_device_remove(root_id+1, true);
+ }
- port->ints &= ~PIO_USB_INTS_DISCONNECT_BITS;
+ if ( port->ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+ {
+ port->ints &= ~PIO_USB_INTS_ENDPOINT_COMPLETE_BITS;
+ handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_COMPLETE_BITS);
+ }
+
+ if ( port->ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+ {
+ port->ints &= ~PIO_USB_INTS_ENDPOINT_ERROR_BITS;
+ handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_ERROR_BITS);
+ }
+
+ if ( port->ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+ {
+ port->ints &= ~PIO_USB_INTS_ENDPOINT_STALLED_BITS;
+ handle_endpoint_irq(port, PIO_USB_INTS_ENDPOINT_STALLED_BITS);
}
}