Merge remote-tracking branch 'upstream/master' into edpt_ISO_xfer

This commit is contained in:
Reinhard Panhuber
2021-02-12 18:05:20 +01:00
388 changed files with 11115 additions and 10689 deletions

View File

@@ -26,7 +26,7 @@
#include "tusb_option.h"
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RT)
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RUNTIME)
#include "dfu_rt_device.h"
#include "device/usbd_pvt.h"
@@ -110,7 +110,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
{
case DFU_REQUEST_DETACH:
tud_control_status(rhport, request);
tud_dfu_rt_reboot_to_dfu();
tud_dfu_runtime_reboot_to_dfu_cb();
break;
case DFU_REQUEST_GETSTATUS:

View File

@@ -58,7 +58,7 @@ typedef enum
//--------------------------------------------------------------------+
// Invoked when received new data
TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void); // TODO rename to _cb convention
TU_ATTR_WEAK void tud_dfu_runtime_reboot_to_dfu_cb(void);
//--------------------------------------------------------------------+
// Internal Class Driver API

View File

@@ -143,6 +143,97 @@ typedef enum
/** @} */
//--------------------------------------------------------------------+
// GAMEPAD
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Gamepad Gamepad
* @{ */
/* From https://www.kernel.org/doc/html/latest/input/gamepad.html
____________________________ __
/ [__ZL__] [__ZR__] \ |
/ [__ TL __] [__ TR __] \ | Front Triggers
__/________________________________\__ __|
/ _ \ |
/ /\ __ (N) \ |
/ || __ |MO| __ _ _ \ | Main Pad
| <===DP===> |SE| |ST| (W) -|- (E) | |
\ || ___ ___ _ / |
/\ \/ / \ / \ (S) /\ __|
/ \________ | LS | ____ | RS | ________/ \ |
| / \ \___/ / \ \___/ / \ | | Control Sticks
| / \_____/ \_____/ \ | __|
| / \ |
\_____/ \_____/
|________|______| |______|___________|
D-Pad Left Right Action Pad
Stick Stick
|_____________|
Menu Pad
Most gamepads have the following features:
- Action-Pad 4 buttons in diamonds-shape (on the right side) NORTH, SOUTH, WEST and EAST.
- D-Pad (Direction-pad) 4 buttons (on the left side) that point up, down, left and right.
- Menu-Pad Different constellations, but most-times 2 buttons: SELECT - START.
- Analog-Sticks provide freely moveable sticks to control directions, Analog-sticks may also
provide a digital button if you press them.
- Triggers are located on the upper-side of the pad in vertical direction. The upper buttons
are normally named Left- and Right-Triggers, the lower buttons Z-Left and Z-Right.
- Rumble Many devices provide force-feedback features. But are mostly just simple rumble motors.
*/
/// HID Gamepad Protocol Report.
typedef struct TU_ATTR_PACKED
{
int8_t x; ///< Delta x movement of left analog-stick
int8_t y; ///< Delta y movement of left analog-stick
int8_t z; ///< Delta z movement of right analog-joystick
int8_t rz; ///< Delta Rz movement of right analog-joystick
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
}hid_gamepad_report_t;
/// Standard Gamepad Buttons Bitmap (from Linux input event codes)
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
}hid_gamepad_button_bm_t;
/// Standard Gamepad HAT/DPAD Buttons (from Linux input event codes)
typedef enum
{
GAMEPAD_HAT_CENTERED = 0, ///< DPAD_CENTERED
GAMEPAD_HAT_UP = 1, ///< DPAD_UP
GAMEPAD_HAT_UP_RIGHT = 2, ///< DPAD_UP_RIGHT
GAMEPAD_HAT_RIGHT = 3, ///< DPAD_RIGHT
GAMEPAD_HAT_DOWN_RIGHT = 4, ///< DPAD_DOWN_RIGHT
GAMEPAD_HAT_DOWN = 5, ///< DPAD_DOWN
GAMEPAD_HAT_DOWN_LEFT = 6, ///< DPAD_DOWN_LEFT
GAMEPAD_HAT_LEFT = 7, ///< DPAD_LEFT
GAMEPAD_HAT_UP_LEFT = 8, ///< DPAD_UP_LEFT
}hid_gamepad_hat_t;
/// @}
//--------------------------------------------------------------------+
// MOUSE
//--------------------------------------------------------------------+

View File

@@ -107,9 +107,6 @@ bool tud_hid_n_boot_mode(uint8_t itf)
return _hidd_itf[itf].boot_mode;
}
//--------------------------------------------------------------------+
// KEYBOARD API
//--------------------------------------------------------------------+
bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier, uint8_t keycode[6])
{
hid_keyboard_report_t report;
@@ -127,10 +124,8 @@ bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier,
return tud_hid_n_report(itf, report_id, &report, sizeof(report));
}
//--------------------------------------------------------------------+
// MOUSE APPLICATION API
//--------------------------------------------------------------------+
bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal)
bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id,
uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal)
{
hid_mouse_report_t report =
{
@@ -144,6 +139,24 @@ bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id, uint8_t buttons, int
return tud_hid_n_report(itf, report_id, &report, sizeof(report));
}
bool tud_hid_n_gamepad_report(uint8_t itf, 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)
{
hid_gamepad_report_t report =
{
.x = x,
.y = y,
.z = z,
.rz = rz,
.rx = rx,
.ry = ry,
.hat = hat,
.buttons = buttons,
};
return tud_hid_n_report(itf, report_id, &report, sizeof(report));
}
//--------------------------------------------------------------------+
// USBD-CLASS API
//--------------------------------------------------------------------+
@@ -368,14 +381,24 @@ bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
uint8_t itf = 0;
hidd_interface_t * p_hid = _hidd_itf;
for ( ; ; itf++, p_hid++)
// Identify which interface to use
for (itf = 0; itf < CFG_TUD_HID; itf++)
{
if (itf >= TU_ARRAY_SIZE(_hidd_itf)) return false;
if ( ep_addr == p_hid->ep_out ) break;
p_hid = &_hidd_itf[itf];
if ( (ep_addr == p_hid->ep_out) || (ep_addr == p_hid->ep_in) ) break;
}
TU_ASSERT(itf < CFG_TUD_HID);
if (ep_addr == p_hid->ep_out)
// Sent report successfully
if (ep_addr == p_hid->ep_in)
{
if (tud_hid_report_complete_cb)
{
tud_hid_report_complete_cb(itf, p_hid->epin_buf, (uint8_t) xferred_bytes);
}
}
// Received report
else if (ep_addr == p_hid->ep_out)
{
tud_hid_set_report_cb(
#if CFG_TUD_HID > 1

View File

@@ -71,6 +71,10 @@ bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier,
// use template layout report as defined by hid_mouse_report_t
bool tud_hid_n_mouse_report(uint8_t itf, 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
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
bool tud_hid_n_gamepad_report(uint8_t itf, 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);
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
@@ -119,6 +123,11 @@ TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate);
#endif
// Invoked when sent REPORT successfully to host
// Application can use this to send the next report
// Note: For composite reports, report[0] is report ID
TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t itf, uint8_t const* report, uint8_t len);
//--------------------------------------------------------------------+
// Inline Functions
@@ -301,14 +310,37 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8
HID_COLLECTION_END \
// Gamepad Report Descriptor Template
// with 16 buttons and 2 joysticks with following layout
// | Button Map (2 bytes) | X | Y | Z | Rz
// with 16 buttons, 2 joysticks and 1 hat/dpad with following layout
// | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (2 bytes) |
#define TUD_HID_REPORT_DESC_GAMEPAD(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
/* 8 bit X, Y, Z, Rz, Rx, Ry (min -127, max 127 ) */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\
HID_LOGICAL_MIN ( 0x81 ) ,\
HID_LOGICAL_MAX ( 0x7f ) ,\
HID_REPORT_COUNT ( 6 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 8 bit DPad/Hat Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\
HID_LOGICAL_MIN ( 1 ) ,\
HID_LOGICAL_MAX ( 8 ) ,\
HID_PHYSICAL_MIN ( 0 ) ,\
HID_PHYSICAL_MAX_N ( 315, 2 ) ,\
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 16 bit Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
HID_USAGE_MIN ( 1 ) ,\
@@ -318,17 +350,6 @@ static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8
HID_REPORT_COUNT ( 16 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* X, Y, Z, Rz (min -127, max 127 ) */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_LOGICAL_MIN ( 0x81 ) ,\
HID_LOGICAL_MAX ( 0x7f ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
HID_REPORT_COUNT ( 4 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
HID_COLLECTION_END \
// HID Generic Input & Output

View File

@@ -39,6 +39,7 @@ typedef struct {
uint8_t itf_num;
uint8_t ep_in;
uint8_t ep_out;
bool valid;
uint16_t report_size;
}hidh_interface_t;
@@ -53,6 +54,7 @@ static inline bool hidh_interface_open(uint8_t rhport, uint8_t dev_addr, uint8_t
p_hid->ep_in = p_endpoint_desc->bEndpointAddress;
p_hid->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor
p_hid->itf_num = interface_number;
p_hid->valid = true;
return true;
}
@@ -246,14 +248,14 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num)
usbh_driver_set_config_complete(dev_addr, itf_num);
#if CFG_TUH_HID_KEYBOARD
if ( keyboardh_data[dev_addr-1].itf_num == itf_num)
if (( keyboardh_data[dev_addr-1].itf_num == itf_num) && keyboardh_data[dev_addr-1].valid)
{
tuh_hid_keyboard_mounted_cb(dev_addr);
}
#endif
#if CFG_TUH_HID_MOUSE
if ( mouseh_data[dev_addr-1].ep_in == itf_num )
if (( mouseh_data[dev_addr-1].ep_in == itf_num ) && mouseh_data[dev_addr-1].valid)
{
tuh_hid_mouse_mounted_cb(dev_addr);
}

View File

@@ -85,6 +85,32 @@ bool tud_midi_n_mounted (uint8_t itf)
return midi->ep_in && midi->ep_out;
}
static void _prep_out_transaction (midid_interface_t* p_midi)
{
uint8_t const rhport = TUD_OPT_RHPORT;
uint16_t available = tu_fifo_remaining(&p_midi->rx_ff);
// Prepare for incoming data but only allow what we can store in the ring buffer.
// TODO Actually we can still carry out the transfer, keeping count of received bytes
// and slowly move it to the FIFO when read().
// This pre-check reduces endpoint claiming
TU_VERIFY(available >= sizeof(p_midi->epout_buf), );
// claim endpoint
TU_VERIFY(usbd_edpt_claim(rhport, p_midi->ep_out), );
// fifo can be changed before endpoint is claimed
available = tu_fifo_remaining(&p_midi->rx_ff);
if ( available >= sizeof(p_midi->epout_buf) ) {
usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, sizeof(p_midi->epout_buf));
}else
{
// Release endpoint since we don't make any transfer
usbd_edpt_release(rhport, p_midi->ep_out);
}
}
//--------------------------------------------------------------------+
// READ API
//--------------------------------------------------------------------+
@@ -135,12 +161,17 @@ uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bu
void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
{
(void) jack_id;
tu_fifo_clear(&_midid_itf[itf].rx_ff);
midid_interface_t* p_midi = &_midid_itf[itf];
tu_fifo_clear(&p_midi->rx_ff);
_prep_out_transaction(p_midi);
}
bool tud_midi_n_receive (uint8_t itf, uint8_t packet[4])
{
return tu_fifo_read_n(&_midid_itf[itf].rx_ff, packet, 4);
midid_interface_t* p_midi = &_midid_itf[itf];
uint32_t num_read = tu_fifo_read_n(&p_midi->rx_ff, packet, 4);
_prep_out_transaction(p_midi);
return (num_read == 4);
}
void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
@@ -192,6 +223,7 @@ uint32_t tud_midi_n_write(uint8_t itf, uint8_t jack_id, uint8_t const* buffer, u
if (midi->write_buffer[0] == 0x4) {
if (data == 0xf7) {
midi->write_buffer[0] = 0x5;
midi->write_target_length = 2;
} else {
midi->write_target_length = 4;
}
@@ -274,8 +306,8 @@ void midid_init(void)
midid_interface_t* midi = &_midid_itf[i];
// config fifo
tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, true);
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, true);
tu_fifo_config(&midi->rx_ff, midi->rx_ff_buf, CFG_TUD_MIDI_RX_BUFSIZE, 1, false); // true, true
tu_fifo_config(&midi->tx_ff, midi->tx_ff_buf, CFG_TUD_MIDI_TX_BUFSIZE, 1, false); // OBVS.
#if CFG_FIFO_MUTEX
tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
@@ -366,11 +398,7 @@ uint16_t midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint
}
// Prepare for incoming data
if ( !usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EP_BUFSIZE) )
{
TU_LOG1_FAILED();
TU_BREAKPOINT();
}
_prep_out_transaction(p_midi);
return drv_len;
}
@@ -391,6 +419,7 @@ bool midid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{
(void) result;
(void) rhport;
uint8_t itf;
midid_interface_t* p_midi;
@@ -414,7 +443,7 @@ bool midid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32
// prepare for next
// TODO for now ep_out is not used by public API therefore there is no race condition,
// and does not need to claim like ep_in
TU_ASSERT(usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EP_BUFSIZE), false);
_prep_out_transaction(p_midi);
}
else if ( ep_addr == p_midi->ep_in )
{