summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWini-Buh <[email protected]>2021-06-11 22:36:17 +0200
committerWini-Buh <[email protected]>2021-06-11 22:36:17 +0200
commit60d8ecbfe617b0f398f90c3fede9a9488f4da407 (patch)
tree30484f43a2e94b8bd6ce6301377a32036950f625
parent1c23462b43f47685cf0051568f4bfea5de37d563 (diff)
parentb34724215bea28ef93fd80ed9c2e4ddc87874093 (diff)
clean up
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md5
-rw-r--r--.gitmodules3
-rw-r--r--examples/make.mk2
m---------hw/mcu/mindmotion/mm32sdk0
-rw-r--r--src/class/cdc/cdc_host.c12
-rw-r--r--src/class/hid/hid.h79
-rw-r--r--src/class/hid/hid_device.c2
-rw-r--r--src/class/hid/hid_device.h12
-rw-r--r--src/class/hid/hid_host.c4
-rw-r--r--src/class/msc/msc_host.c4
-rw-r--r--src/common/tusb_common.h2
-rw-r--r--src/device/dcd.h12
-rw-r--r--src/device/usbd.c4
-rw-r--r--src/device/usbd_pvt.h2
-rw-r--r--src/host/hcd.h3
-rw-r--r--src/host/hub.c1
-rw-r--r--src/host/usbh.c53
-rw-r--r--src/host/usbh.h50
-rw-r--r--src/host/usbh_classdriver.h83
-rw-r--r--src/host/usbh_hcd.h6
-rw-r--r--src/portable/ehci/ehci.c12
-rw-r--r--src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c471
-rw-r--r--src/portable/ohci/ohci.c12
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c32
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.c11
-rw-r--r--src/tusb_option.h3
26 files changed, 722 insertions, 158 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 00d16bc2b..3beef45d0 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -9,7 +9,7 @@ assignees: ''
**Set Up**
-- **PC OS** e.g Ubuntu 20.04 / Windows 10/ macOS 10.15
+- **PC OS** e.g Ubuntu 20.04 / Windows 10 / macOS 10.15
- **Board** e.g Feather nRF52840 Express (if custom specify your MCUs)
- **TinyUSB version** relase version or git hash (preferrably running with master for lastest code)
- **Firmware** e.g examples/device/cdc_msc
@@ -31,6 +31,5 @@ If applicable, add screenshots, bus capture to help explain your problem.
**Log**
-If applicable, provide the stack's log (uart/rtt/swo) where the issue occurred, best with comments to explain the actual events. If the log is too long, attach it as txt file instead.
-
+If applicable, provide the stack's log (uart/rtt/swo) where the issue occurred as attached txt file, best with comments to explain the actual events.
Note: To enable logging, add `LOG=2` to to the make command if building with stock examples or set `CFG_TUSB_DEBUG=2` in your tusb_config.h. More information can be found at [example's readme](/docs/getting_started.md)
diff --git a/.gitmodules b/.gitmodules
index 79ef8e0ad..c0e6f8f91 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -121,3 +121,6 @@
[submodule "hw/mcu/nxp/nxp_sdk"]
path = hw/mcu/nxp/nxp_sdk
url = https://github.com/hathach/nxp_sdk.git
+[submodule "hw/mcu/mindmotion/mm32sdk"]
+ path = hw/mcu/mindmotion/mm32sdk
+ url = https://github.com/zhangslice/mm32sdk.git
diff --git a/examples/make.mk b/examples/make.mk
index df8bfd617..9daf60e35 100644
--- a/examples/make.mk
+++ b/examples/make.mk
@@ -5,7 +5,7 @@
# Build directory
BUILD := _build/$(BOARD)
-PROJECT := $(BOARD)-$(notdir $(CURDIR))
+PROJECT := $(notdir $(CURDIR))
BIN := $(TOP)/_bin/$(BOARD)/$(notdir $(CURDIR))
# Handy check parameter function
diff --git a/hw/mcu/mindmotion/mm32sdk b/hw/mcu/mindmotion/mm32sdk
new file mode 160000
+Subproject b6b99de3ab26218784ec158488bdd91377288f9
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index facf86d56..33f1a8ad3 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -29,6 +29,8 @@
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC)
#include "host/usbh.h"
+#include "host/usbh_classdriver.h"
+
#include "cdc_host.h"
//--------------------------------------------------------------------+
@@ -71,13 +73,13 @@ bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid)
switch (pipeid)
{
case CDC_PIPE_NOTIFICATION:
- return hcd_edpt_busy(dev_addr, p_cdc->ep_notif );
+ return usbh_edpt_busy(dev_addr, p_cdc->ep_notif );
case CDC_PIPE_DATA_IN:
- return hcd_edpt_busy(dev_addr, p_cdc->ep_in );
+ return usbh_edpt_busy(dev_addr, p_cdc->ep_in );
case CDC_PIPE_DATA_OUT:
- return hcd_edpt_busy(dev_addr, p_cdc->ep_out );
+ return usbh_edpt_busy(dev_addr, p_cdc->ep_out );
default:
return false;
@@ -101,7 +103,7 @@ bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool i
TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA);
uint8_t const ep_out = cdch_data[dev_addr-1].ep_out;
- if ( hcd_edpt_busy(dev_addr, ep_out) ) return false;
+ if ( usbh_edpt_busy(dev_addr, ep_out) ) return false;
return usbh_edpt_xfer(dev_addr, ep_out, (void *) p_data, length);
}
@@ -113,7 +115,7 @@ bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is
TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA);
uint8_t const ep_in = cdch_data[dev_addr-1].ep_in;
- if ( hcd_edpt_busy(dev_addr, ep_in) ) return false;
+ if ( usbh_edpt_busy(dev_addr, ep_in) ) return false;
return usbh_edpt_xfer(dev_addr, ep_in, p_buffer, length);
}
diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h
index 5cc9233b5..ec14c9c7c 100644
--- a/src/class/hid/hid.h
+++ b/src/class/hid/hid.h
@@ -201,30 +201,73 @@ typedef struct TU_ATTR_PACKED
int8_t rx; ///< Delta Rx movement of analog left trigger
int8_t ry; ///< Delta Ry movement of analog right trigger
uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat
- uint16_t buttons; ///< Buttons mask for currently pressed buttons
+ uint32_t buttons; ///< Buttons mask for currently pressed buttons
}hid_gamepad_report_t;
-/// Standard Gamepad Buttons Bitmap (from Linux input event codes)
+/// Standard Gamepad Buttons Bitmap
typedef enum
{
- GAMEPAD_BUTTON_A = TU_BIT(0), ///< A/South button
- GAMEPAD_BUTTON_B = TU_BIT(1), ///< B/East button
- GAMEPAD_BUTTON_C = TU_BIT(2), ///< C button
- GAMEPAD_BUTTON_X = TU_BIT(3), ///< X/North button
- GAMEPAD_BUTTON_Y = TU_BIT(4), ///< Y/West button
- GAMEPAD_BUTTON_Z = TU_BIT(5), ///< Z button
- GAMEPAD_BUTTON_TL = TU_BIT(6), ///< L1 button
- GAMEPAD_BUTTON_TR = TU_BIT(7), ///< R1 button
- GAMEPAD_BUTTON_TL2 = TU_BIT(8), ///< L2 button
- GAMEPAD_BUTTON_TR2 = TU_BIT(9), ///< R2 button
- GAMEPAD_BUTTON_SELECT = TU_BIT(10), ///< Select button
- GAMEPAD_BUTTON_START = TU_BIT(11), ///< Start button
- GAMEPAD_BUTTON_MODE = TU_BIT(12), ///< Mode button
- GAMEPAD_BUTTON_THUMBL = TU_BIT(13), ///< L3 button
- GAMEPAD_BUTTON_THUMBR = TU_BIT(14), ///< R3 button
-//GAMEPAD_BUTTON_ = TU_BIT(15), ///< Undefined button
+ GAMEPAD_BUTTON_0 = TU_BIT(0),
+ GAMEPAD_BUTTON_1 = TU_BIT(1),
+ GAMEPAD_BUTTON_2 = TU_BIT(2),
+ GAMEPAD_BUTTON_3 = TU_BIT(3),
+ GAMEPAD_BUTTON_4 = TU_BIT(4),
+ GAMEPAD_BUTTON_5 = TU_BIT(5),
+ GAMEPAD_BUTTON_6 = TU_BIT(6),
+ GAMEPAD_BUTTON_7 = TU_BIT(7),
+ GAMEPAD_BUTTON_8 = TU_BIT(8),
+ GAMEPAD_BUTTON_9 = TU_BIT(9),
+ GAMEPAD_BUTTON_10 = TU_BIT(10),
+ GAMEPAD_BUTTON_11 = TU_BIT(11),
+ GAMEPAD_BUTTON_12 = TU_BIT(12),
+ GAMEPAD_BUTTON_13 = TU_BIT(13),
+ GAMEPAD_BUTTON_14 = TU_BIT(14),
+ GAMEPAD_BUTTON_15 = TU_BIT(15),
+ GAMEPAD_BUTTON_16 = TU_BIT(16),
+ GAMEPAD_BUTTON_17 = TU_BIT(17),
+ GAMEPAD_BUTTON_18 = TU_BIT(18),
+ GAMEPAD_BUTTON_19 = TU_BIT(19),
+ GAMEPAD_BUTTON_20 = TU_BIT(20),
+ GAMEPAD_BUTTON_21 = TU_BIT(21),
+ GAMEPAD_BUTTON_22 = TU_BIT(22),
+ GAMEPAD_BUTTON_23 = TU_BIT(23),
+ GAMEPAD_BUTTON_24 = TU_BIT(24),
+ GAMEPAD_BUTTON_25 = TU_BIT(25),
+ GAMEPAD_BUTTON_26 = TU_BIT(26),
+ GAMEPAD_BUTTON_27 = TU_BIT(27),
+ GAMEPAD_BUTTON_28 = TU_BIT(28),
+ GAMEPAD_BUTTON_29 = TU_BIT(29),
+ GAMEPAD_BUTTON_30 = TU_BIT(30),
+ GAMEPAD_BUTTON_31 = TU_BIT(31),
}hid_gamepad_button_bm_t;
+/// Standard Gamepad Buttons Naming from Linux input event codes
+/// https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
+#define GAMEPAD_BUTTON_A GAMEPAD_BUTTON_0
+#define GAMEPAD_BUTTON_SOUTH GAMEPAD_BUTTON_0
+
+#define GAMEPAD_BUTTON_B GAMEPAD_BUTTON_1
+#define GAMEPAD_BUTTON_EAST GAMEPAD_BUTTON_1
+
+#define GAMEPAD_BUTTON_C GAMEPAD_BUTTON_2
+
+#define GAMEPAD_BUTTON_X GAMEPAD_BUTTON_3
+#define GAMEPAD_BUTTON_NORTH GAMEPAD_BUTTON_3
+
+#define GAMEPAD_BUTTON_Y GAMEPAD_BUTTON_4
+#define GAMEPAD_BUTTON_WEST GAMEPAD_BUTTON_4
+
+#define GAMEPAD_BUTTON_Z GAMEPAD_BUTTON_5
+#define GAMEPAD_BUTTON_TL GAMEPAD_BUTTON_6
+#define GAMEPAD_BUTTON_TR GAMEPAD_BUTTON_7
+#define GAMEPAD_BUTTON_TL2 GAMEPAD_BUTTON_8
+#define GAMEPAD_BUTTON_TR2 GAMEPAD_BUTTON_9
+#define GAMEPAD_BUTTON_SELECT GAMEPAD_BUTTON_10
+#define GAMEPAD_BUTTON_START GAMEPAD_BUTTON_11
+#define GAMEPAD_BUTTON_MODE GAMEPAD_BUTTON_12
+#define GAMEPAD_BUTTON_THUMBL GAMEPAD_BUTTON_13
+#define GAMEPAD_BUTTON_THUMBR GAMEPAD_BUTTON_14
+
/// Standard Gamepad HAT/DPAD Buttons (from Linux input event codes)
typedef enum
{
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c
index 151a36225..e44f282c4 100644
--- a/src/class/hid/hid_device.c
+++ b/src/class/hid/hid_device.c
@@ -149,7 +149,7 @@ bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id,
}
bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
- int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint16_t buttons)
+ int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons)
{
hid_gamepad_report_t report =
{
diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h
index beb755888..e2c950dd1 100644
--- a/src/class/hid/hid_device.h
+++ b/src/class/hid/hid_device.h
@@ -72,9 +72,9 @@ bool tud_hid_n_keyboard_report(uint8_t instance, uint8_t report_id, uint8_t modi
// use template layout report as defined by hid_mouse_report_t
bool tud_hid_n_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
-// Gamepad: convenient helper to send mouse report if application
+// Gamepad: convenient helper to send gamepad report if application
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
-bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint16_t buttons);
+bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
//--------------------------------------------------------------------+
// Application API (Single Port)
@@ -85,7 +85,7 @@ static inline uint8_t tud_hid_get_protocol(void);
static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
-static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint16_t buttons);
+static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
//--------------------------------------------------------------------+
// Callbacks (Weak is optional)
@@ -152,7 +152,7 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8
return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal);
}
-static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint16_t buttons)
+static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons)
{
return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons);
}
@@ -344,10 +344,10 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
/* 16 bit Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
HID_USAGE_MIN ( 1 ) ,\
- HID_USAGE_MAX ( 16 ) ,\
+ HID_USAGE_MAX ( 32 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 1 ) ,\
- HID_REPORT_COUNT ( 16 ) ,\
+ HID_REPORT_COUNT ( 32 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
HID_COLLECTION_END \
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index 83f3f3039..cde5e23a5 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -29,6 +29,8 @@
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HID)
#include "host/usbh.h"
+#include "host/usbh_classdriver.h"
+
#include "hid_host.h"
//--------------------------------------------------------------------+
@@ -199,7 +201,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u
// TU_VERIFY(tuh_n_hid_n_mounted(dev_addr, instance));
//
// hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
-// return !hcd_edpt_busy(dev_addr, hid_itf->ep_in);
+// return !usbh_edpt_busy(dev_addr, hid_itf->ep_in);
//}
//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len);
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index 205f0fd2d..7f98ef9b1 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -29,6 +29,8 @@
#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC
#include "host/usbh.h"
+#include "host/usbh_classdriver.h"
+
#include "msc_host.h"
//--------------------------------------------------------------------+
@@ -109,7 +111,7 @@ bool tuh_msc_mounted(uint8_t dev_addr)
bool tuh_msc_ready(uint8_t dev_addr)
{
msch_interface_t* p_msc = get_itf(dev_addr);
- return p_msc->mounted && !hcd_edpt_busy(dev_addr, p_msc->ep_in);
+ return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in);
}
//--------------------------------------------------------------------+
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index 3350ed86c..889ad7b25 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -51,7 +51,7 @@
#define U32_TO_U8S_BE(u32) TU_U32_BYTE3(u32), TU_U32_BYTE2(u32), TU_U32_BYTE1(u32), TU_U32_BYTE0(u32)
#define U32_TO_U8S_LE(u32) TU_U32_BYTE0(u32), TU_U32_BYTE1(u32), TU_U32_BYTE2(u32), TU_U32_BYTE3(u32)
-#define TU_BIT(n) (1U << (n))
+#define TU_BIT(n) (1UL << (n))
//--------------------------------------------------------------------+
// Includes
diff --git a/src/device/dcd.h b/src/device/dcd.h
index 25cfafc4b..63e97df96 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -121,20 +121,20 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
// May help DCD to prepare for next control transfer, this API is optional.
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
+// Configure endpoint's registers according to descriptor
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep);
+
// Close an endpoint.
// Since it is weak, caller must TU_ASSERT this function's existence before calling it.
void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
+// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
+bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+
// Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack
// This API is optional, may be useful for register-based for transferring data.
bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK;
-// Configure endpoint's registers according to descriptor
-bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
-
-// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
-bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
-
// Stall endpoint
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 49c9279bf..cedca540e 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -1254,8 +1254,8 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
- // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return
- // and usbd task can preempt and clear the busy
+ // Set busy first since the actual transfer can be complete before dcd_edpt_xfer()
+ // could return and USBD task can preempt and clear the busy
_usbd_dev.ep_status[epnum][dir].busy = true;
if ( dcd_edpt_xfer(rhport, ep_addr, buffer, total_bytes) )
diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h
index bb2267d40..6a4b30956 100644
--- a/src/device/usbd_pvt.h
+++ b/src/device/usbd_pvt.h
@@ -34,7 +34,7 @@
#endif
//--------------------------------------------------------------------+
-// Class Drivers
+// Class Driver API
//--------------------------------------------------------------------+
typedef struct
diff --git a/src/host/hcd.h b/src/host/hcd.h
index 46209dc45..7a9aadc73 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -137,9 +137,6 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
-
-bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr);
-bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr);
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
//--------------------------------------------------------------------+
diff --git a/src/host/hub.c b/src/host/hub.c
index f921027c7..b2761184d 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -29,6 +29,7 @@
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB)
#include "usbh.h"
+#include "usbh_classdriver.h"
#include "hub.h"
//--------------------------------------------------------------------+
diff --git a/src/host/usbh.c b/src/host/usbh.c
index ca0653409..59246a663 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -24,7 +24,7 @@
* This file is part of the TinyUSB stack.
*/
-#include "common/tusb_common.h"
+#include "tusb_option.h"
#if TUSB_OPT_HOST_ENABLED
@@ -32,10 +32,9 @@
#define CFG_TUH_TASK_QUEUE_SZ 16
#endif
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
#include "tusb.h"
+#include "host/usbh.h"
+#include "host/usbh_classdriver.h"
#include "hub.h"
#include "usbh_hcd.h"
@@ -315,8 +314,11 @@ uint8_t* usbh_get_enum_buf(void)
return _usbh_ctrl_buf;
}
-//------------- Endpoint API -------------//
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+// TODO has some duplication code with device, refactor later
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
{
uint8_t const epnum = tu_edpt_number(ep_addr);
@@ -344,6 +346,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
return ret;
}
+// TODO has some duplication code with device, refactor later
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
{
uint8_t const epnum = tu_edpt_number(ep_addr);
@@ -369,11 +372,36 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
return ret;
}
+// TODO has some duplication code with device, refactor later
bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
usbh_device_t* dev = &_usbh_devices[dev_addr];
- TU_LOG2(" Queue EP %02X with %u bytes ... OK\r\n", ep_addr, total_bytes);
- return hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes);
+
+ TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes);
+
+ // Attempt to transfer on a busy endpoint, sound like an race condition !
+ TU_ASSERT(dev->ep_status[epnum][dir].busy == 0);
+
+ // Set busy first since the actual transfer can be complete before hcd_edpt_xfer()
+ // could return and USBH task can preempt and clear the busy
+ dev->ep_status[epnum][dir].busy = true;
+
+ if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) )
+ {
+ TU_LOG2("OK\r\n");
+ return true;
+ }else
+ {
+ // HCD error, mark endpoint as ready to allow next transfer
+ dev->ep_status[epnum][dir].busy = false;
+ dev->ep_status[epnum][dir].claimed = 0;
+ TU_LOG2("failed\r\n");
+ TU_BREAKPOINT();
+ return false;
+ }
}
bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size)
@@ -420,6 +448,17 @@ bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
return ret;
}
+bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
+{
+ uint8_t const epnum = tu_edpt_number(ep_addr);
+ uint8_t const dir = tu_edpt_dir(ep_addr);
+
+ usbh_device_t* dev = &_usbh_devices[dev_addr];
+
+ return dev->ep_status[epnum][dir].busy;
+}
+
+
//--------------------------------------------------------------------+
// HCD Event Handler
//--------------------------------------------------------------------+
diff --git a/src/host/usbh.h b/src/host/usbh.h
index a9790b484..4de6e7ba6 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -24,9 +24,6 @@
* This file is part of the TinyUSB stack.
*/
-/** \ingroup group_usbh USB Host Core (USBH)
- * @{ */
-
#ifndef _TUSB_USBH_H_
#define _TUSB_USBH_H_
@@ -40,27 +37,6 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-typedef enum tusb_interface_status_{
- TUSB_INTERFACE_STATUS_READY = 0,
- TUSB_INTERFACE_STATUS_BUSY,
- TUSB_INTERFACE_STATUS_COMPLETE,
- TUSB_INTERFACE_STATUS_ERROR,
- TUSB_INTERFACE_STATUS_INVALID_PARA
-} tusb_interface_status_t;
-
-typedef struct {
- #if CFG_TUSB_DEBUG >= 2
- char const* name;
- #endif
-
- uint8_t class_code;
-
- void (* const init )(void);
- bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t* outlen);
- bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num);
- bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
- void (* const close )(uint8_t dev_addr);
-} usbh_class_driver_t;
typedef bool (*tuh_control_complete_cb_t)(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result);
@@ -101,34 +77,14 @@ bool tuh_control_xfer (uint8_t dev_addr, tusb_control_request_t const* request,
//--------------------------------------------------------------------+
//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device);
-/** Callback invoked when device is mounted (configured) */
+// Invoked when device is mounted (configured)
TU_ATTR_WEAK void tuh_mount_cb (uint8_t dev_addr);
-/** Callback invoked when device is unmounted (bus reset/unplugged) */
+/// Invoked when device is unmounted (bus reset/unplugged)
TU_ATTR_WEAK void tuh_umount_cb(uint8_t dev_addr);
-//--------------------------------------------------------------------+
-// CLASS-USBH & INTERNAL API
-// TODO move to usbh_pvt.h
-//--------------------------------------------------------------------+
-
-bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
-bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
-
-// Claim an endpoint before submitting a transfer.
-// If caller does not make any transfer, it must release endpoint for others.
-bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr);
-
-void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num);
-
-uint8_t usbh_get_rhport(uint8_t dev_addr);
-
-uint8_t* usbh_get_enum_buf(void);
-
#ifdef __cplusplus
}
#endif
-#endif /* _TUSB_USBH_H_ */
-
-/** @} */
+#endif
diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h
new file mode 100644
index 000000000..07480fe8e
--- /dev/null
+++ b/src/host/usbh_classdriver.h
@@ -0,0 +1,83 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef _TUSB_USBH_CLASSDRIVER_H_
+#define _TUSB_USBH_CLASSDRIVER_H_
+
+#include "osal/osal.h"
+#include "common/tusb_fifo.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Class Driver API
+//--------------------------------------------------------------------+
+
+typedef struct {
+ #if CFG_TUSB_DEBUG >= 2
+ char const* name;
+ #endif
+
+ uint8_t class_code;
+
+ void (* const init )(void);
+ bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t* outlen);
+ bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num);
+ bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+ void (* const close )(uint8_t dev_addr);
+} usbh_class_driver_t;
+
+// Call by class driver to tell USBH that it has complete the enumeration
+void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num);
+
+uint8_t usbh_get_rhport(uint8_t dev_addr);
+
+uint8_t* usbh_get_enum_buf(void);
+
+//--------------------------------------------------------------------+
+// USBH Endpoint API
+//--------------------------------------------------------------------+
+
+// Open an endpoint
+bool usbh_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep);
+
+// Submit a usb transfer
+bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
+
+// Claim an endpoint before submitting a transfer.
+// If caller does not make any transfer, it must release endpoint for others.
+bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr);
+
+// Check if endpoint transferring is complete
+bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
diff --git a/src/host/usbh_hcd.h b/src/host/usbh_hcd.h
index abc7fd250..b3856d6b7 100644
--- a/src/host/usbh_hcd.h
+++ b/src/host/usbh_hcd.h
@@ -97,12 +97,6 @@ typedef struct {
extern usbh_device_t _usbh_devices[CFG_TUSB_HOST_DEVICE_MAX+1]; // including zero-address
-//--------------------------------------------------------------------+
-// callback from HCD ISR
-//--------------------------------------------------------------------+
-
-
-
#ifdef __cplusplus
}
#endif
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index bcba360bb..48788ba06 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -440,18 +440,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
-{
- ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr);
- return !p_qhd->qtd_overlay.halted && (p_qhd->p_qtd_list_head != NULL);
-}
-
-bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr)
-{
- ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr);
- return p_qhd->qtd_overlay.halted && !qhd_has_xact_error(p_qhd);
-}
-
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
{
ehci_qhd_t *p_qhd = qhd_get_from_addr(dev_addr, ep_addr);
diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
new file mode 100644
index 000000000..59a40dc68
--- /dev/null
+++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
@@ -0,0 +1,471 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 SE TEAM
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MM32F327X )
+
+#include "reg_usb_otg_fs.h"
+#include "mm32_device.h"
+#include "hal_conf.h"
+#include "device/dcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+enum {
+ TOK_PID_OUT = 0x1u,
+ TOK_PID_IN = 0x9u,
+ TOK_PID_SETUP = 0xDu,
+};
+
+typedef struct TU_ATTR_PACKED
+{
+ union {
+ uint32_t head;
+ struct {
+ union {
+ struct {
+ uint16_t : 2;
+ uint16_t tok_pid : 4;
+ uint16_t data : 1;
+ uint16_t own : 1;
+ uint16_t : 8;
+ };
+ struct {
+ uint16_t : 2;
+ uint16_t bdt_stall: 1;
+ uint16_t dts : 1;
+ uint16_t ninc : 1;
+ uint16_t keep : 1;
+ uint16_t : 10;
+ };
+ };
+ uint16_t bc : 10;
+ uint16_t : 6;
+ };
+ };
+ uint8_t *addr;
+}buffer_descriptor_t;
+
+TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" );
+
+typedef struct TU_ATTR_PACKED
+{
+ union {
+ uint32_t state;
+ struct {
+ uint32_t max_packet_size :11;
+ uint32_t : 5;
+ uint32_t odd : 1;
+ uint32_t :15;
+ };
+ };
+ uint16_t length;
+ uint16_t remaining;
+}endpoint_state_t;
+
+TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" );
+
+typedef struct
+{
+ union {
+ /* [#EP][OUT,IN][EVEN,ODD] */
+ buffer_descriptor_t bdt[16][2][2];
+ uint16_t bda[512];
+ };
+ TU_ATTR_ALIGNED(4) union {
+ endpoint_state_t endpoint[16][2];
+ endpoint_state_t endpoint_unified[16 * 2];
+ };
+ uint8_t setup_packet[8];
+ uint8_t addr;
+}dcd_data_t;
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+// BDT(Buffer Descriptor Table) must be 256-byte aligned
+CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+
+TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
+
+static void prepare_next_setup_packet(uint8_t rhport)
+{
+ const unsigned out_odd = _dcd.endpoint[0][0].odd;
+ const unsigned in_odd = _dcd.endpoint[0][1].odd;
+ if (_dcd.bdt[0][0][out_odd].own) {
+ TU_LOG1("DCD fail to prepare the next SETUP %d %d\r\n", out_odd, in_odd);
+ return;
+ }
+ _dcd.bdt[0][0][out_odd].data = 0;
+ _dcd.bdt[0][0][out_odd ^ 1].data = 1;
+ _dcd.bdt[0][1][in_odd].data = 1;
+ _dcd.bdt[0][1][in_odd ^ 1].data = 0;
+ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
+ _dcd.setup_packet, sizeof(_dcd.setup_packet));
+}
+
+static void process_stall(uint8_t rhport)
+{
+ if (USB_OTG_FS->EP_CTL[0] & USB_ENDPT_EPSTALL_MASK) {
+ /* clear stall condition of the control pipe */
+ prepare_next_setup_packet(rhport);
+ USB_OTG_FS->EP_CTL[0] &= ~USB_ENDPT_EPSTALL_MASK;
+ }
+}
+
+static void process_tokdne(uint8_t rhport)
+{
+ const unsigned s = USB_OTG_FS->STAT;
+ USB_OTG_FS->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */
+ buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s];
+ endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3];
+ unsigned odd = (s & USB_STAT_ODD_MASK) ? 1 : 0;
+
+ /* fetch pid before discarded by the next steps */
+ const unsigned pid = bd->tok_pid;
+ /* reset values for a next transfer */
+ bd->bdt_stall = 0;
+ bd->dts = 1;
+ bd->ninc = 0;
+ bd->keep = 0;
+ /* update the odd variable to prepare for the next transfer */
+ ep->odd = odd ^ 1;
+ if (pid == TOK_PID_SETUP) {
+ dcd_event_setup_received(rhport, bd->addr, true);
+ USB_OTG_FS->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+ return;
+ }
+ if (s >> 4) {
+ TU_LOG1("TKDNE %x\r\n", s);
+ }
+
+ const unsigned bc = bd->bc;
+ const unsigned remaining = ep->remaining - bc;
+ if (remaining && bc == ep->max_packet_size) {
+ /* continue the transferring consecutive data */
+ ep->remaining = remaining;
+ const int next_remaining = remaining - ep->max_packet_size;
+ if (next_remaining > 0) {
+ /* prepare to the after next transfer */
+ bd->addr += ep->max_packet_size * 2;
+ bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining;
+ __DSB();
+ bd->own = 1; /* the own bit must set after addr */
+ }
+ return;
+ }
+ const unsigned length = ep->length;
+ dcd_event_xfer_complete(rhport,
+ ((s & USB_STAT_TX_MASK) << 4) | (s >> USB_STAT_ENDP_SHIFT),
+ length - remaining, XFER_RESULT_SUCCESS, true);
+ if (0 == (s & USB_STAT_ENDP_MASK) && 0 == length) {
+ /* After completion a ZLP of control transfer,
+ * it prepares for the next steup transfer. */
+ if (_dcd.addr) {
+ /* When the transfer was the SetAddress,
+ * the device address should be updated here. */
+ USB_OTG_FS->ADDR = _dcd.addr;
+ _dcd.addr = 0;
+ }
+ prepare_next_setup_packet(rhport);
+ }
+}
+
+static void process_bus_reset(uint8_t rhport)
+{
+ USB_OTG_FS->CTL |= USB_CTL_ODDRST_MASK;
+ USB_OTG_FS->ADDR = 0;
+ USB_OTG_FS->INT_ENB = (USB_OTG_FS->INT_ENB & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK;
+
+ USB_OTG_FS->EP_CTL[0] = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
+ for (unsigned i = 1; i < 16; ++i) {
+ USB_OTG_FS->EP_CTL[i] = 0;
+ }
+ buffer_descriptor_t *bd = _dcd.bdt[0][0];
+ for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) {
+ bd->head = 0;
+ }
+ const endpoint_state_t ep0 = {
+ .max_packet_size = CFG_TUD_ENDPOINT0_SIZE,
+ .odd = 0,
+ .length = 0,
+ .remaining = 0,
+ };
+ _dcd.endpoint[0][0] = ep0;
+ _dcd.endpoint[0][1] = ep0;
+ tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0]));
+ _dcd.addr = 0;
+ prepare_next_setup_packet(rhport);
+ USB_OTG_FS->CTL &= ~USB_CTL_ODDRST_MASK;
+ dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
+}
+
+static void process_bus_inactive(uint8_t rhport)
+{
+ (void) rhport;
+ const unsigned inten = USB_OTG_FS->INT_ENB;
+ USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK;
+ dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
+}
+
+static void process_bus_active(uint8_t rhport)
+{
+ (void) rhport;
+ const unsigned inten = USB_OTG_FS->INT_ENB;
+ USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK;
+ dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
+}
+
+/*------------------------------------------------------------------*/
+/* Device API
+ *------------------------------------------------------------------*/
+void dcd_init(uint8_t rhport)
+{
+ (void) rhport;
+
+ tu_memclr(&_dcd, sizeof(_dcd));
+ USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8);
+ USB_OTG_FS->BDT_PAGE_02 = (uint8_t)((uintptr_t)_dcd.bdt >> 16);
+ USB_OTG_FS->BDT_PAGE_03 = (uint8_t)((uintptr_t)_dcd.bdt >> 24);
+
+ dcd_connect(rhport);
+ NVIC_ClearPendingIRQ(USB_FS_IRQn);
+}
+#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
+void dcd_int_enable(uint8_t rhport)
+{
+ uint8_t irqNumber;
+ irqNumber = USB_FS_IRQn;
+ (void) rhport;
+ USB_OTG_FS->INT_ENB = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK |
+ USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK;
+ NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY);
+ NVIC_EnableIRQ(USB_FS_IRQn);
+}
+
+void dcd_int_disable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_DisableIRQ(USB_FS_IRQn);
+ USB_OTG_FS->INT_ENB = 0;
+}
+
+void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
+{
+ (void) rhport;
+ _dcd.addr = dev_addr & 0x7F;
+ /* Response with status first before changing device address */
+ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
+}
+extern u32 SystemCoreClock ;
+void dcd_remote_wakeup(uint8_t rhport)
+{
+ (void) rhport;
+ unsigned cnt = SystemCoreClock / 100;
+ USB_OTG_FS->CTL |= USB_CTL_RESUME_MASK;
+ while (cnt--) __NOP();
+ USB_OTG_FS->CTL &= ~USB_CTL_RESUME_MASK;
+}
+
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ USB_OTG_FS->CTL |= USB_CTL_USBENSOFEN_MASK;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ USB_OTG_FS->CTL = 0;
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
+{
+ (void) rhport;
+
+ const unsigned ep_addr = ep_desc->bEndpointAddress;
+ const unsigned epn = ep_addr & 0xFu;
+ const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ const unsigned xfer = ep_desc->bmAttributes.xfer;
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ const unsigned odd = ep->odd;
+ buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0];
+
+ /* No support for control transfer */
+ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL));
+
+ ep->max_packet_size = ep_desc->wMaxPacketSize.size;
+ unsigned val = USB_ENDPT_EPCTLDIS_MASK;
+ val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0;
+ val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
+ USB_OTG_FS->EP_CTL[epn] |= val;
+
+ if (xfer != TUSB_XFER_ISOCHRONOUS) {
+ bd[odd].dts = 1;
+ bd[odd].data = 0;
+ bd[odd ^ 1].dts = 1;
+ bd[odd ^ 1].data = 1;
+ }
+
+ return true;
+}
+
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+
+ const unsigned epn = ep_addr & 0xFu;
+ const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0];
+ const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
+ USB_OTG_FS->EP_CTL[epn] &= ~msk;
+ ep->max_packet_size = 0;
+ ep->length = 0;
+ ep->remaining = 0;
+ bd->head = 0;
+}
+
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
+{
+ (void) rhport;
+ NVIC_DisableIRQ(USB_FS_IRQn);
+ const unsigned epn = ep_addr & 0xFu;
+ const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
+
+ if (bd->own) {
+ TU_LOG1("DCD XFER fail %x %d %lx %lx\r\n", ep_addr, total_bytes, ep->state, bd->head);
+ return false; /* The last transfer has not completed */
+ }
+ ep->length = total_bytes;
+ ep->remaining = total_bytes;
+
+ const unsigned mps = ep->max_packet_size;
+ if (total_bytes > mps) {
+ buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1;
+ /* When total_bytes is greater than the max packet size,
+ * it prepares to the next transfer to avoid NAK in advance. */
+ next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps;
+ next->addr = buffer + mps;
+ next->own = 1;
+ }
+ bd->bc = total_bytes >= mps ? mps: total_bytes;
+ bd->addr = buffer;
+ __DSB();
+ bd->own = 1; /* the own bit must set after addr */
+ NVIC_EnableIRQ(USB_FS_IRQn);
+ return true;
+}
+
+void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+ const unsigned epn = ep_addr & 0xFu;
+ if (0 == epn) {
+ USB_OTG_FS->EP_CTL[epn] |= USB_ENDPT_EPSTALL_MASK;
+ } else {
+ const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
+ bd[0].bdt_stall = 1;
+ bd[1].bdt_stall = 1;
+ }
+}
+
+void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+ const unsigned epn = ep_addr & 0xFu;
+ const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
+ const unsigned odd = _dcd.endpoint[epn][dir].odd;
+ buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
+
+ bd[odd ^ 1].own = 0;
+ bd[odd ^ 1].data = 1;
+ bd[odd ^ 1].bdt_stall = 0;
+ bd[odd].own = 0;
+ bd[odd].data = 0;
+ bd[odd].bdt_stall = 0;
+}
+
+//--------------------------------------------------------------------+
+// ISR
+//--------------------------------------------------------------------+
+void dcd_int_handler(uint8_t rhport)
+{
+ (void) rhport;
+
+ uint32_t is = USB_OTG_FS->INT_STAT;
+ uint32_t msk = USB_OTG_FS->INT_ENB;
+ USB_OTG_FS->INT_STAT = is & ~msk;
+ is &= msk;
+ if (is & USB_ISTAT_ERROR_MASK) {
+ /* TODO: */
+ uint32_t es = USB_OTG_FS->ERR_STAT;
+ USB_OTG_FS->ERR_STAT = es;
+ USB_OTG_FS->INT_STAT = is; /* discard any pending events */
+ return;
+ }
+
+ if (is & USB_ISTAT_USBRST_MASK) {
+ USB_OTG_FS->INT_STAT = is; /* discard any pending events */
+ process_bus_reset(rhport);
+ return;
+ }
+ if (is & USB_ISTAT_SLEEP_MASK) {
+ USB_OTG_FS->INT_STAT = USB_ISTAT_SLEEP_MASK;
+ process_bus_inactive(rhport);
+ return;
+ }
+ if (is & USB_ISTAT_RESUME_MASK) {
+ USB_OTG_FS->INT_STAT = USB_ISTAT_RESUME_MASK;
+ process_bus_active(rhport);
+ return;
+ }
+ if (is & USB_ISTAT_SOFTOK_MASK) {
+ USB_OTG_FS->INT_STAT = USB_ISTAT_SOFTOK_MASK;
+ dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
+ return;
+ }
+ if (is & USB_ISTAT_STALL_MASK) {
+ USB_OTG_FS->INT_STAT = USB_ISTAT_STALL_MASK;
+ process_stall(rhport);
+ return;
+ }
+ if (is & USB_ISTAT_TOKDNE_MASK) {
+ process_tokdne(rhport);
+ return;
+ }
+}
+
+#endif
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index dbd2cc793..73489c764 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -489,18 +489,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
return true;
}
-bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
-{
- ohci_ed_t const * const p_ed = ed_from_addr(dev_addr, ep_addr);
- return tu_align16(p_ed->td_head.address) != tu_align16(p_ed->td_tail);
-}
-
-bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr)
-{
- ohci_ed_t const * const p_ed = ed_from_addr(dev_addr, ep_addr);
- return p_ed->td_head.halted && p_ed->is_stalled;
-}
-
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
{
ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr);
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 3c62b5732..b575c6afc 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -515,25 +515,19 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
return true;
}
-bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
-{
- // EPX is shared, so multiple device addresses and endpoint addresses share that
- // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
- // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
- // on that device
- pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
- struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
- assert(ep);
- bool busy = ep->active;
- pico_trace("busy == %d\n", busy);
- return busy;
-}
-
-bool hcd_edpt_stalled(uint8_t dev_addr, uint8_t ep_addr)
-{
- panic("hcd_pipe_stalled");
- return false;
-}
+//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
+//{
+// // EPX is shared, so multiple device addresses and endpoint addresses share that
+// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
+// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
+// // on that device
+// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
+// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
+// assert(ep);
+// bool busy = ep->active;
+// pico_trace("busy == %d\n", busy);
+// return busy;
+//}
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
{
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c
index a0263612f..31381e6c2 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.c
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c
@@ -205,10 +205,7 @@ void _hw_endpoint_xfer_sync(struct hw_endpoint *ep)
// Update hw endpoint struct with info from hardware
// after a buff status interrupt
- // Get the buffer state and amount of bytes we have
- // transferred
uint32_t buf_ctrl = _hw_endpoint_buffer_control_get_value32(ep);
- uint16_t transferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK;
#if TUSB_OPT_HOST_ENABLED
// RP2040-E4
@@ -227,6 +224,9 @@ void _hw_endpoint_xfer_sync(struct hw_endpoint *ep)
// end::host_buf_sel_fix[]
#endif
+ // Get tranferred bytes after adjusted buf sel
+ uint16_t const transferred_bytes = buf_ctrl & USB_BUF_CTRL_LEN_MASK;
+
// We are continuing a transfer here. If we are TX, we have successfullly
// sent some data can increase the length we have sent
if (!ep->rx)
@@ -249,7 +249,7 @@ void _hw_endpoint_xfer_sync(struct hw_endpoint *ep)
// Sometimes the host will send less data than we expect...
// If this is a short out transfer update the total length of the transfer
// to be the current length
- if ((ep->rx) && (transferred_bytes < ep->transfer_size))
+ if ((ep->rx) && (transferred_bytes < ep->wMaxPacketSize))
{
pico_trace("Short rx transfer\n");
// Reduce total length as this is last packet
@@ -289,8 +289,7 @@ bool _hw_endpoint_xfer_continue(struct hw_endpoint *ep)
{
pico_trace("Completed transfer of %d bytes on ep %d %s\n",
ep->len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]);
- // Notify caller we are done so it can notify the tinyusb
- // stack
+ // Notify caller we are done so it can notify the tinyusb stack
_hw_endpoint_lock_update(ep, -1);
return true;
}
diff --git a/src/tusb_option.h b/src/tusb_option.h
index 7e147966f..2a75cf515 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -114,6 +114,9 @@
#define OPT_MCU_RX63X 1400 ///< Renesas RX63N/631
#define OPT_MCU_RX72N 1401 ///< Renesas RX72N
+// Mind Motion
+#define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327
+
/** @} */
/** \defgroup group_supported_os Supported RTOS