summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhihong Chen <[email protected]>2026-04-13 11:45:03 +0800
committersakumisu <[email protected]>2026-04-13 12:08:13 +0800
commit9938fbf78161bb362866d8e102c33732319071b6 (patch)
tree6c3309dd13e44daafa59d5d7912f40218e2a9819
parent86350946ab047197e46bfcb70f8cefb0417705b8 (diff)
[update] port: hpmicro: dcd: using sutw semaphore by isr handler for setup
Signed-off-by: Zhihong Chen <[email protected]>
-rw-r--r--port/hpmicro/usb_dc_hpm.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/port/hpmicro/usb_dc_hpm.c b/port/hpmicro/usb_dc_hpm.c
index 551e90b8..8ece72a3 100644
--- a/port/hpmicro/usb_dc_hpm.c
+++ b/port/hpmicro/usb_dc_hpm.c
@@ -46,6 +46,7 @@ struct hpm_udc {
static USB_NOCACHE_RAM_SECTION ATTR_ALIGN(USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT)
uint8_t _dcd_data[CONFIG_USBDEV_MAX_BUS][HPM_ALIGN_UP(sizeof(dcd_data_t), USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT)];
static USB_NOCACHE_RAM_SECTION usb_device_handle_t usb_device_handle[CONFIG_USBDEV_MAX_BUS];
+static uint8_t _setup_data[8];
/* Index to bit position in register */
static inline uint8_t ep_idx2bit(uint8_t ep_idx)
@@ -234,12 +235,13 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
usb_device_handle_t *handle = g_hpm_udc[busid].handle;
+ bool ret;
if (!data && data_len) {
- return -1;
+ return -USB_ERR_NOMEM;
}
if (!g_hpm_udc[busid].in_ep[ep_idx].ep_enable) {
- return -2;
+ return -USB_ERR_NOTCONN;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
@@ -251,21 +253,22 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
g_hpm_udc[busid].in_ep[ep_idx].actual_xfer_len = 0;
usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
- usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len);
+ ret = usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len);
- return 0;
+ return ret ? 0 : -USB_ERR_INVAL;
}
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep);
usb_device_handle_t *handle = g_hpm_udc[busid].handle;
+ bool ret;
if (!data && data_len) {
- return -1;
+ return -USB_ERR_NOMEM;
}
if (!g_hpm_udc[busid].out_ep[ep_idx].ep_enable) {
- return -2;
+ return -USB_ERR_NOTCONN;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
@@ -277,9 +280,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
g_hpm_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
usb_dcache_invalidate((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
- usb_device_edpt_xfer(handle, ep, data, data_len);
+ ret = usb_device_edpt_xfer(handle, ep, data, data_len);
- return 0;
+ return ret ? 0 : -USB_ERR_INVAL;
}
void USBD_IRQHandler(uint8_t busid)
@@ -310,6 +313,7 @@ void USBD_IRQHandler(uint8_t busid)
memset(g_hpm_udc[busid].out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS);
usbd_event_reset_handler(busid);
usb_device_bus_reset(handle, g_hpm_udc[busid].in_ep[0].ep_mps);
+ return;
}
if (int_status & intr_suspend) {
@@ -359,6 +363,11 @@ void USBD_IRQHandler(uint8_t busid)
break;
} else {
transfer_len += p_qtd->expected_bytes - p_qtd->total_bytes;
+ if ((ep_idx & 0x01) != 0) {
+ g_hpm_udc[busid].in_ep[ep_idx / 2].actual_xfer_len = transfer_len;
+ } else {
+ g_hpm_udc[busid].out_ep[ep_idx / 2].actual_xfer_len = transfer_len;
+ }
p_qtd->in_use = false;
}
@@ -383,10 +392,17 @@ void USBD_IRQHandler(uint8_t busid)
}
if (edpt_setup_status) {
- /*------------- Set up Received -------------*/
- usb_device_clear_setup_status(handle, edpt_setup_status);
+ /*------------- Setup Received -------------*/
dcd_qhd_t *qhd0 = usb_device_qhd_get(handle, 0);
- usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&qhd0->setup_request);
+
+ usb_device_clear_setup_status(handle, edpt_setup_status);
+ do {
+ usb_dcd_set_sutw(handle->regs, true);
+ memcpy(_setup_data, (uint8_t *)(&qhd0->setup_request), 8);
+ } while (!usb_dcd_get_sutw(handle->regs));
+ usb_dcd_set_sutw(handle->regs, false);
+
+ usbd_event_ep0_setup_complete_handler(busid, _setup_data);
}
}
} \ No newline at end of file