This commit is contained in:
Wini-Buh 2021-06-11 22:36:17 +02:00
commit 60d8ecbfe6
26 changed files with 723 additions and 158 deletions

View File

@ -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
View File

@ -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

View File

@ -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

@ -0,0 +1 @@
Subproject commit b6b99de3ab26218784ec158488bdd91377288f94

View File

@ -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);
}

View File

@ -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
{

View File

@ -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 =
{

View File

@ -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 \

View File

@ -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);

View File

@ -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);
}
//--------------------------------------------------------------------+

View File

@ -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

View File

@ -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);

View File

@ -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) )

View File

@ -34,7 +34,7 @@
#endif
//--------------------------------------------------------------------+
// Class Drivers
// Class Driver API
//--------------------------------------------------------------------+
typedef struct

View File

@ -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);
//--------------------------------------------------------------------+

View File

@ -29,6 +29,7 @@
#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_HUB)
#include "usbh.h"
#include "usbh_classdriver.h"
#include "hub.h"
//--------------------------------------------------------------------+

View File

@ -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
//--------------------------------------------------------------------+

View File

@ -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

View 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

View File

@ -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

View File

@ -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);

View 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

View File

@ -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);

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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