mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
clean up
This commit is contained in:
commit
60d8ecbfe6
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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)
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
@ -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
|
||||
|
1
hw/mcu/mindmotion/mm32sdk
Submodule
1
hw/mcu/mindmotion/mm32sdk
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b6b99de3ab26218784ec158488bdd91377288f94
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 =
|
||||
{
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) )
|
||||
|
@ -34,7 +34,7 @@
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Class Drivers
|
||||
// Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
typedef struct
|
||||
|
@ -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);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -29,6 +29,7 @@
|
||||
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB)
|
||||
|
||||
#include "usbh.h"
|
||||
#include "usbh_classdriver.h"
|
||||
#include "hub.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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
|
||||
|
83
src/host/usbh_classdriver.h
Normal file
83
src/host/usbh_classdriver.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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);
|
||||
|
471
src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
Normal file
471
src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user