summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorWilliam D. Jones <[email protected]>2019-01-10 09:58:06 -0500
committerWilliam D. Jones <[email protected]>2019-01-10 09:58:06 -0500
commitb367baeaf1d64930654f136a2409f1322fc73ab2 (patch)
tree710698145d52c72b807971d05512330fde2cc9b1 /src/class
parente4d6f336f0d5004fd9ee3074305b7980ba777dfd (diff)
parent5804e56e3c2ab4480bf72d94d997f769a645af47 (diff)
Merge branch 'master' of https://github.com/hathach/tinyusb into stm32f4
Diffstat (limited to 'src/class')
-rw-r--r--src/class/audio/audio.h78
-rw-r--r--src/class/cdc/cdc_device.c74
-rw-r--r--src/class/cdc/cdc_device.h8
-rw-r--r--src/class/cdc/cdc_host.c174
-rw-r--r--src/class/cdc/cdc_host.h39
-rw-r--r--src/class/cdc/cdc_rndis_host.c2
-rw-r--r--src/class/cdc/cdc_rndis_host.h2
-rw-r--r--src/class/custom/custom_device.c14
-rw-r--r--src/class/custom/custom_device.h4
-rw-r--r--src/class/custom/custom_host.c8
-rw-r--r--src/class/custom/custom_host.h4
-rw-r--r--src/class/hid/hid.h36
-rw-r--r--src/class/hid/hid_device.c33
-rw-r--r--src/class/hid/hid_device.h5
-rw-r--r--src/class/hid/hid_host.c73
-rw-r--r--src/class/hid/hid_host.h30
-rw-r--r--src/class/midi/midi.h84
-rw-r--r--src/class/midi/midi_device.c360
-rw-r--r--src/class/midi/midi_device.h120
-rw-r--r--src/class/msc/msc_device.c45
-rw-r--r--src/class/msc/msc_device.h10
-rw-r--r--src/class/msc/msc_host.c191
-rw-r--r--src/class/msc/msc_host.h29
23 files changed, 1018 insertions, 405 deletions
diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h
new file mode 100644
index 000000000..1ea3f1166
--- /dev/null
+++ b/src/class/audio/audio.h
@@ -0,0 +1,78 @@
+/**************************************************************************/
+/*!
+ @file cdc.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_class
+ * \defgroup ClassDriver_Audio Audio
+ * Currently only MIDI subclass is supported
+ * @{ */
+
+#ifndef _TUSB_CDC_H__
+#define _TUSB_CDC_H__
+
+#include "common/tusb_common.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/// Audio Interface Subclass Codes
+typedef enum
+{
+ AUDIO_SUBCLASS_AUDIO_CONTROL = 0x01 , ///< Audio Control
+ AUDIO_SUBCLASS_AUDIO_STREAMING , ///< Audio Streaming
+ AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
+} audio_subclass_type_t;
+
+/// Audio Protocol Codes
+typedef enum
+{
+ AUDIO_PROTOCOL_V1 = 0x00, ///< Version 1.0
+ AUDIO_PROTOCOL_V2 = 0x20, ///< Version 2.0
+ AUDIO_PROTOCOL_V3 = 0x30, ///< Version 3.0
+} audio_protocol_type_t;
+
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
+
+/** @} */
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index b68a6a7ff..b8678c1c4 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -41,9 +41,7 @@
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_CDC)
#define _TINY_USB_SOURCE_FILE_
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
+
#include "cdc_device.h"
#include "device/usbd_pvt.h"
@@ -95,7 +93,7 @@ CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
bool tud_cdc_n_connected(uint8_t itf)
{
// DTR (bit 0) active is considered as connected
- return BIT_TEST_(_cdcd_itf[itf].line_state, 0);
+ return TU_BIT_TEST(_cdcd_itf[itf].line_state, 0);
}
uint8_t tud_cdc_n_get_line_state (uint8_t itf)
@@ -231,17 +229,14 @@ void cdcd_reset(uint8_t rhport)
}
}
-tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
+bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length)
{
- if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS;
+ // Only support ACM subclass
+ TU_ASSERT ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
// Only support AT commands, no protocol and vendor specific commands.
- if ( !(tu_within(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
- p_interface_desc->bInterfaceProtocol == CDC_COMM_PROTOCOL_NONE ||
- p_interface_desc->bInterfaceProtocol == 0xff ) )
- {
- return TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL;
- }
+ TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
+ itf_desc->bInterfaceProtocol == 0xff);
// Find available interface
cdcd_interface_t * p_cdc = NULL;
@@ -253,55 +248,59 @@ tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface
break;
}
}
+ TU_ASSERT(p_cdc);
//------------- Control Interface -------------//
- p_cdc->itf_num = p_interface_desc->bInterfaceNumber;
+ p_cdc->itf_num = itf_desc->bInterfaceNumber;
- uint8_t const * p_desc = descriptor_next ( (uint8_t const *) p_interface_desc );
+ uint8_t const * p_desc = tu_desc_next( itf_desc );
(*p_length) = sizeof(tusb_desc_interface_t);
// Communication Functional Descriptors
- while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] )
+ while ( TUSB_DESC_CLASS_SPECIFIC == tu_desc_type(p_desc) )
{
- (*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ (*p_length) += tu_desc_len(p_desc);
+ p_desc = tu_desc_next(p_desc);
}
- if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
- { // notification endpoint if any
- TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED);
+ if ( TUSB_DESC_ENDPOINT == tu_desc_type(p_desc) )
+ {
+ // notification endpoint if any
+ TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc) );
p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
(*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
}
//------------- Data Interface (if any) -------------//
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
{
- // next to endpoint descritpor
- (*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ // next to endpoint descriptor
+ (*p_length) += tu_desc_len(p_desc);
+ p_desc = tu_desc_next(p_desc);
// Open endpoint pair with usbd helper
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) p_desc;
- TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
+ TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
(*p_length) += 2*sizeof(tusb_desc_endpoint_t);
}
// Prepare for incoming data
- TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER);
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
- return TUSB_ERROR_NONE;
+ return true;
}
// Invoked when class request DATA stage is finished.
// return false to stall control endpoint (e.g Host send non-sense DATA)
bool cdcd_control_request_complete(uint8_t rhport, tusb_control_request_t const * request)
{
+ (void) rhport;
+
//------------- Class Specific Request -------------//
TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
@@ -347,9 +346,10 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
// This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
p_cdc->line_state = (uint8_t) request->wValue;
- // Invoke callback
- if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, BIT_TEST_(request->wValue, 0), BIT_TEST_(request->wValue, 1));
usbd_control_status(rhport, request);
+
+ // Invoke callback
+ if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, TU_BIT_TEST(request->wValue, 0), TU_BIT_TEST(request->wValue, 1));
break;
default: return false; // stall unsupported request
@@ -358,8 +358,10 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
return true;
}
-tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
+bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{
+ (void) result;
+
// TODO Support multiple interfaces
uint8_t const itf = 0;
cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
@@ -367,29 +369,27 @@ tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
// receive new data
if ( ep_addr == p_cdc->ep_out )
{
- char const wanted = p_cdc->wanted_char;
-
for(uint32_t i=0; i<xferred_bytes; i++)
{
tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]);
// Check for wanted char and invoke callback if needed
- if ( tud_cdc_rx_wanted_cb && ( wanted != -1 ) && ( wanted == p_cdc->epout_buf[i] ) )
+ if ( tud_cdc_rx_wanted_cb && ( ((signed char) p_cdc->wanted_char) != -1 ) && ( p_cdc->wanted_char == p_cdc->epout_buf[i] ) )
{
- tud_cdc_rx_wanted_cb(itf, wanted);
+ tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
}
}
// invoke receive callback (if there is still data)
if (tud_cdc_rx_cb && tu_fifo_count(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
- // prepare for next
- TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE), TUSB_ERROR_DCD_EDPT_XFER );
+ // prepare for incoming data
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, p_cdc->epout_buf, CFG_TUD_CDC_EPSIZE) );
}
// nothing to do with in and notif endpoint
- return TUSB_ERROR_NONE;
+ return true;
}
#endif
diff --git a/src/class/cdc/cdc_device.h b/src/class/cdc/cdc_device.h
index ad1100e9c..5ee649c4b 100644
--- a/src/class/cdc/cdc_device.h
+++ b/src/class/cdc/cdc_device.h
@@ -112,12 +112,12 @@ ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_li
//--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_
-void cdcd_init (void);
-tusb_error_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+void cdcd_init (void);
+bool cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * p_request);
bool cdcd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
-tusb_error_t cdcd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
-void cdcd_reset (uint8_t rhport);
+bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
+void cdcd_reset (uint8_t rhport);
#endif
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 0a3661878..d6767d0a7 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -38,100 +38,92 @@
#include "tusb_option.h"
-#if (MODE_HOST_SUPPORTED && CFG_TUSB_HOST_CDC)
+#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC)
#define _TINY_USB_SOURCE_FILE_
-//--------------------------------------------------------------------+
-// INCLUDE
-//--------------------------------------------------------------------+
#include "common/tusb_common.h"
#include "cdc_host.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
+typedef struct {
+ uint8_t itf_num;
+ uint8_t itf_protocol;
-//--------------------------------------------------------------------+
-// INTERNAL OBJECT & FUNCTION DECLARATION
-//--------------------------------------------------------------------+
-STATIC_VAR cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX]; // TODO to be static
+ uint8_t ep_notif;
+ uint8_t ep_in;
+ uint8_t ep_out;
-static inline cdc_pipeid_t get_app_pipeid(pipe_handle_t pipe_hdl)
-{
- cdch_data_t const * p_cdc = &cdch_data[pipe_hdl.dev_addr-1];
+ cdc_acm_capability_t acm_capability;
- return pipehandle_is_equal( pipe_hdl, p_cdc->pipe_notification ) ? CDC_PIPE_NOTIFICATION :
- pipehandle_is_equal( pipe_hdl, p_cdc->pipe_in ) ? CDC_PIPE_DATA_IN :
- pipehandle_is_equal( pipe_hdl, p_cdc->pipe_out ) ? CDC_PIPE_DATA_OUT : CDC_PIPE_ERROR;
-}
+} cdch_data_t;
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+static cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX];
-static inline bool tusbh_cdc_is_mounted(uint8_t dev_addr)
+bool tuh_cdc_mounted(uint8_t dev_addr)
{
-// FIXME cannot use mounted class flag as at the point _open_sublass is called, the flag is not set yet
-#ifdef _TEST_
- return (tusbh_device_get_mounted_class_flag(dev_addr) & BIT_(TUSB_CLASS_CDC)) != 0;
-#else
- return pipehandle_is_valid(cdch_data[dev_addr-1].pipe_in) &&
- pipehandle_is_valid(cdch_data[dev_addr-1].pipe_out);
-#endif
+ cdch_data_t* cdc = &cdch_data[dev_addr-1];
+ return cdc->ep_in && cdc->ep_out;
}
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid)
{
- if ( !tusbh_cdc_is_mounted(dev_addr) ) return false;
+ if ( !tuh_cdc_mounted(dev_addr) ) return false;
cdch_data_t const * p_cdc = &cdch_data[dev_addr-1];
switch (pipeid)
{
case CDC_PIPE_NOTIFICATION:
- return hcd_pipe_is_busy( p_cdc->pipe_notification );
+ return hcd_edpt_busy(dev_addr, p_cdc->ep_notif );
case CDC_PIPE_DATA_IN:
- return hcd_pipe_is_busy( p_cdc->pipe_in );
+ return hcd_edpt_busy(dev_addr, p_cdc->ep_in );
case CDC_PIPE_DATA_OUT:
- return hcd_pipe_is_busy( p_cdc->pipe_out );
+ return hcd_edpt_busy(dev_addr, p_cdc->ep_out );
default:
return false;
}
}
-
//--------------------------------------------------------------------+
// APPLICATION API (parameter validation needed)
//--------------------------------------------------------------------+
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr)
{
// TODO consider all AT Command as serial candidate
- return tusbh_cdc_is_mounted(dev_addr) &&
- (CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].interface_protocol) &&
- (cdch_data[dev_addr-1].interface_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA);
+ return tuh_cdc_mounted(dev_addr) &&
+ (CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].itf_protocol) &&
+ (cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA);
}
-tusb_error_t tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify)
+bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify)
{
- TU_ASSERT( tusbh_cdc_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED);
- TU_ASSERT( p_data != NULL && length, TUSB_ERROR_INVALID_PARA);
+ TU_VERIFY( tuh_cdc_mounted(dev_addr) );
+ TU_VERIFY( p_data != NULL && length, TUSB_ERROR_INVALID_PARA);
- pipe_handle_t pipe_out = cdch_data[dev_addr-1].pipe_out;
- if ( hcd_pipe_is_busy(pipe_out) ) return TUSB_ERROR_INTERFACE_IS_BUSY;
+ uint8_t const ep_out = cdch_data[dev_addr-1].ep_out;
+ if ( hcd_edpt_busy(dev_addr, ep_out) ) return false;
- return hcd_pipe_xfer( pipe_out, (void *) p_data, length, is_notify);
+ return hcd_pipe_xfer(dev_addr, ep_out, (void *) p_data, length, is_notify);
}
-tusb_error_t tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify)
+bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify)
{
- TU_ASSERT( tusbh_cdc_is_mounted(dev_addr), TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED);
- TU_ASSERT( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA);
+ TU_VERIFY( tuh_cdc_mounted(dev_addr) );
+ TU_VERIFY( p_buffer != NULL && length, TUSB_ERROR_INVALID_PARA);
- pipe_handle_t pipe_in = cdch_data[dev_addr-1].pipe_in;
- if ( hcd_pipe_is_busy(pipe_in) ) return TUSB_ERROR_INTERFACE_IS_BUSY;
+ uint8_t const ep_in = cdch_data[dev_addr-1].ep_in;
+ if ( hcd_edpt_busy(dev_addr, ep_in) ) return false;
- return hcd_pipe_xfer( pipe_in, p_buffer, length, is_notify);
+ return hcd_pipe_xfer(dev_addr, ep_in, p_buffer, length, is_notify);
}
//--------------------------------------------------------------------+
@@ -142,102 +134,106 @@ void cdch_init(void)
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
}
-tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
+bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
{
- OSAL_SUBTASK_BEGIN
- // TODO change following assert to subtask_assert
-
- if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS;
+ // Only support ACM
+ TU_VERIFY( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass);
- if ( !(tu_within(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
- 0xff == p_interface_desc->bInterfaceProtocol) )
- {
- return TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL;
- }
+ // Only support AT commands, no protocol and vendor specific commands.
+ TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
+ 0xff == itf_desc->bInterfaceProtocol);
uint8_t const * p_desc;
cdch_data_t * p_cdc;
- p_desc = descriptor_next ( (uint8_t const *) p_interface_desc );
- p_cdc = &cdch_data[dev_addr-1]; // non-static variable cannot be used after OS service call
+ p_desc = tu_desc_next(itf_desc);
+ p_cdc = &cdch_data[dev_addr-1];
- p_cdc->interface_number = p_interface_desc->bInterfaceNumber;
- p_cdc->interface_protocol = p_interface_desc->bInterfaceProtocol; // TODO 0xff is consider as rndis candidate, other is virtual Com
+ p_cdc->itf_num = itf_desc->bInterfaceNumber;
+ p_cdc->itf_protocol = itf_desc->bInterfaceProtocol; // TODO 0xff is consider as rndis candidate, other is virtual Com
//------------- Communication Interface -------------//
(*p_length) = sizeof(tusb_desc_interface_t);
+ // Communication Functional Descriptors
while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] )
- { // Communication Functional Descriptors
+ {
if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) )
- { // save ACM bmCapabilities
+ {
+ // save ACM bmCapabilities
p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities;
}
(*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
}
if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
- { // notification endpoint if any
- p_cdc->pipe_notification = hcd_pipe_open(dev_addr, (tusb_desc_endpoint_t const *) p_desc, TUSB_CLASS_CDC);
+ {
+ // notification endpoint
+ tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) p_desc;
- (*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ TU_ASSERT( hcd_edpt_open(rhport, dev_addr, ep_desc) );
+ p_cdc->ep_notif = ep_desc->bEndpointAddress;
- TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification), TUSB_ERROR_HCD_OPEN_PIPE_FAILED);
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
}
//------------- Data Interface (if any) -------------//
if ( (TUSB_DESC_INTERFACE == p_desc[DESC_OFFSET_TYPE]) &&
- (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
+ (TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
{
(*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
// data endpoints expected to be in pairs
for(uint32_t i=0; i<2; i++)
{
- tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc;
- TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED);
- TU_ASSERT(TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED);
+ tusb_desc_endpoint_t const *ep_desc = (tusb_desc_endpoint_t const *) p_desc;
+ TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
+ TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
- pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
- &p_cdc->pipe_in : &p_cdc->pipe_out;
+ TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
- (*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_CDC);
- TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
+ if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
+ {
+ p_cdc->ep_in = ep_desc->bEndpointAddress;
+ }else
+ {
+ p_cdc->ep_out = ep_desc->bEndpointAddress;
+ }
(*p_length) += p_desc[DESC_OFFSET_LEN];
- p_desc = descriptor_next( p_desc );
+ p_desc = tu_desc_next( p_desc );
}
}
+ // FIXME move to seperate API : connect
+ tusb_control_request_t request =
{
- // FIXME mounted class flag is not set yet
- tuh_cdc_mounted_cb(dev_addr);
- }
+ .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
+ .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE,
+ .wValue = 0x03, // dtr on, cst on
+ .wIndex = p_cdc->itf_num,
+ .wLength = 0
+ };
+
+ TU_ASSERT( usbh_control_xfer(dev_addr, &request, NULL) );
- OSAL_SUBTASK_END
+ return true;
}
-void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
+void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
{
- tuh_cdc_xfer_isr( pipe_hdl.dev_addr, event, get_app_pipeid(pipe_hdl), xferred_bytes );
+ (void) ep_addr;
+ tuh_cdc_xfer_isr( dev_addr, event, 0, xferred_bytes );
}
void cdch_close(uint8_t dev_addr)
{
cdch_data_t * p_cdc = &cdch_data[dev_addr-1];
-
- (void) hcd_pipe_close(p_cdc->pipe_notification);
- (void) hcd_pipe_close(p_cdc->pipe_in);
- (void) hcd_pipe_close(p_cdc->pipe_out);
-
tu_memclr(p_cdc, sizeof(cdch_data_t));
-
- tuh_cdc_unmounted_cb(dev_addr);
-
}
#endif
diff --git a/src/class/cdc/cdc_host.h b/src/class/cdc/cdc_host.h
index 0b863bb61..5388a8f60 100644
--- a/src/class/cdc/cdc_host.h
+++ b/src/class/cdc/cdc_host.h
@@ -62,7 +62,7 @@
* \retval true if device supports
* \retval false if device does not support or is not mounted
*/
-bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_cdc_serial_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
@@ -73,7 +73,7 @@ bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESU
* can be scheduled. User needs to make sure the corresponding interface is mounted
* (by \ref tuh_cdc_serial_is_mounted) before calling this function.
*/
-bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid);
/** \brief Perform USB OUT transfer to device
* \param[in] dev_addr device address
@@ -86,7 +86,7 @@ bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid) ATTR_PURE ATTR_WARN
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
*/
-tusb_error_t tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
+bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
/** \brief Perform USB IN transfer to get data from device
* \param[in] dev_addr device address
@@ -99,22 +99,11 @@ tusb_error_t tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
*/
-tusb_error_t tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
+bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
//--------------------------------------------------------------------+
// CDC APPLICATION CALLBACKS
//--------------------------------------------------------------------+
-/** \brief Callback function that will be invoked when a device with CDC Abstract Control Model interface is mounted
- * \param[in] dev_addr Address of newly mounted device
- * \note This callback should be used by Application to set-up interface-related data
- */
-void tuh_cdc_mounted_cb(uint8_t dev_addr);
-
-/** \brief Callback function that will be invoked when a device with CDC Abstract Control Model interface is unmounted
- * \param[in] dev_addr Address of newly unmounted device
- * \note This callback should be used by Application to tear-down interface-related data
- */
-void tuh_cdc_unmounted_cb(uint8_t dev_addr);
/** \brief Callback function that is invoked when an transferring event occurred
* \param[in] dev_addr Address of device
@@ -137,22 +126,10 @@ void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_i
//--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_
-typedef struct {
- uint8_t interface_number;
- uint8_t interface_protocol;
-
- cdc_acm_capability_t acm_capability;
-
- pipe_handle_t pipe_notification, pipe_out, pipe_in;
-
-} cdch_data_t;
-
-extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX]; // TODO consider to move to cdch internal header file
-
-void cdch_init(void);
-tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
-void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
-void cdch_close(uint8_t dev_addr);
+void cdch_init(void);
+bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
+void cdch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
+void cdch_close(uint8_t dev_addr);
#endif
diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c
index 89ea3b32f..ae61bf8b5 100644
--- a/src/class/cdc/cdc_rndis_host.c
+++ b/src/class/cdc/cdc_rndis_host.c
@@ -38,7 +38,7 @@
#include "tusb_option.h"
-#if (MODE_HOST_SUPPORTED && CFG_TUSB_HOST_CDC && CFG_TUSB_HOST_CDC_RNDIS)
+#if (TUSB_OPT_HOST_ENABLED && CFG_TUH_CDC && CFG_TUH_CDC_RNDIS)
#define _TINY_USB_SOURCE_FILE_
diff --git a/src/class/cdc/cdc_rndis_host.h b/src/class/cdc/cdc_rndis_host.h
index 3b92d3f23..730df2e23 100644
--- a/src/class/cdc/cdc_rndis_host.h
+++ b/src/class/cdc/cdc_rndis_host.h
@@ -64,7 +64,7 @@ typedef struct {
}rndish_data_t;
void rndish_init(void);
-tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc) ATTR_WARN_UNUSED_RESULT;
+tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc);
void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
void rndish_close(uint8_t dev_addr);
diff --git a/src/class/custom/custom_device.c b/src/class/custom/custom_device.c
index 194963c17..129d405a4 100644
--- a/src/class/custom/custom_device.c
+++ b/src/class/custom/custom_device.c
@@ -71,22 +71,22 @@ void cusd_init(void)
tu_varclr(&_cusd_itf);
}
-tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
+bool cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
{
cusd_interface_t* p_itf = &_cusd_itf;
// Open endpoint pair with usbd helper
- tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
- TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_itf->ep_out, &p_itf->ep_in) );
+ tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(p_desc_itf);
+ TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_itf->ep_out, &p_itf->ep_in) );
p_itf->itf_num = p_desc_itf->bInterfaceNumber;
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
// TODO Prepare for incoming data
-// TU_ASSERT( dcd_edpt_xfer(rhport, p_itf->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
+// TU_ASSERT( dcd_edpt_xfer(rhport, p_itf->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) );
- return TUSB_ERROR_NONE;
+ return true;
}
bool cusd_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
@@ -94,9 +94,9 @@ bool cusd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
return false;
}
-tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes)
+bool cusd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
{
- return TUSB_ERROR_NONE;
+ return true;
}
void cusd_reset(uint8_t rhport)
diff --git a/src/class/custom/custom_device.h b/src/class/custom/custom_device.h
index 0a8f05e7d..aae06d503 100644
--- a/src/class/custom/custom_device.h
+++ b/src/class/custom/custom_device.h
@@ -63,10 +63,10 @@
#ifdef _TINY_USB_SOURCE_FILE_
void cusd_init(void);
-tusb_error_t cusd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+bool cusd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
bool cusd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request);
bool cusd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
-tusb_error_t cusd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
+bool cusd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void cusd_reset(uint8_t rhport);
#endif
diff --git a/src/class/custom/custom_host.c b/src/class/custom/custom_host.c
index 9f0b70afb..894e641e8 100644
--- a/src/class/custom/custom_host.c
+++ b/src/class/custom/custom_host.c
@@ -38,7 +38,7 @@
#include "tusb_option.h"
-#if (MODE_HOST_SUPPORTED && CFG_TUSB_HOST_CUSTOM_CLASS)
+#if (TUSB_OPT_HOST_ENABLED && CFG_TUSB_HOST_CUSTOM_CLASS)
#define _TINY_USB_SOURCE_FILE_
@@ -111,7 +111,7 @@ tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
{
// FIXME quick hack to test lpc1k custom class with 2 bulk endpoints
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
- p_desc = descriptor_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
//------------- Bulk Endpoints Descriptor -------------//
for(uint32_t i=0; i<2; i++)
@@ -121,10 +121,10 @@ tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
&custom_interface[dev_addr-1].pipe_in : &custom_interface[dev_addr-1].pipe_out;
- *p_pipe_hdl = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
+ *p_pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint, TUSB_CLASS_VENDOR_SPECIFIC);
TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED );
- p_desc = descriptor_next(p_desc);
+ p_desc = tu_desc_next(p_desc);
}
(*p_length) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
diff --git a/src/class/custom/custom_host.h b/src/class/custom/custom_host.h
index 5f9c25dda..a5fcb6fb4 100644
--- a/src/class/custom/custom_host.h
+++ b/src/class/custom/custom_host.h
@@ -62,7 +62,7 @@ static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id,
{
(void) vendor_id; // TODO check this later
(void) product_id;
-// return (tusbh_device_get_mounted_class_flag(dev_addr) & BIT_(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0;
+// return (tusbh_device_get_mounted_class_flag(dev_addr) & TU_BIT(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0;
return false;
}
@@ -72,7 +72,7 @@ tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t p
#ifdef _TINY_USB_SOURCE_FILE_
void cush_init(void);
-tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
+tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event);
void cush_close(uint8_t dev_addr);
diff --git a/src/class/hid/hid.h b/src/class/hid/hid.h
index 8bfede2da..6abc71e0d 100644
--- a/src/class/hid/hid.h
+++ b/src/class/hid/hid.h
@@ -173,11 +173,11 @@ typedef struct ATTR_PACKED
/// Standard Mouse Buttons Bitmap
typedef enum
{
- MOUSE_BUTTON_LEFT = BIT_(0), ///< Left button
- MOUSE_BUTTON_RIGHT = BIT_(1), ///< Right button
- MOUSE_BUTTON_MIDDLE = BIT_(2), ///< Middle button
- MOUSE_BUTTON_BACKWARD = BIT_(3), ///< Backward button,
- MOUSE_BUTTON_FORWARD = BIT_(4), ///< Forward button,
+ MOUSE_BUTTON_LEFT = TU_BIT(0), ///< Left button
+ MOUSE_BUTTON_RIGHT = TU_BIT(1), ///< Right button
+ MOUSE_BUTTON_MIDDLE = TU_BIT(2), ///< Middle button
+ MOUSE_BUTTON_BACKWARD = TU_BIT(3), ///< Backward button,
+ MOUSE_BUTTON_FORWARD = TU_BIT(4), ///< Forward button,
}hid_mouse_button_bm_t;
/// @}
@@ -199,23 +199,23 @@ typedef struct ATTR_PACKED
/// Keyboard modifier codes bitmap
typedef enum
{
- KEYBOARD_MODIFIER_LEFTCTRL = BIT_(0), ///< Left Control
- KEYBOARD_MODIFIER_LEFTSHIFT = BIT_(1), ///< Left Shift
- KEYBOARD_MODIFIER_LEFTALT = BIT_(2), ///< Left Alt
- KEYBOARD_MODIFIER_LEFTGUI = BIT_(3), ///< Left Window
- KEYBOARD_MODIFIER_RIGHTCTRL = BIT_(4), ///< Right Control
- KEYBOARD_MODIFIER_RIGHTSHIFT = BIT_(5), ///< Right Shift
- KEYBOARD_MODIFIER_RIGHTALT = BIT_(6), ///< Right Alt
- KEYBOARD_MODIFIER_RIGHTGUI = BIT_(7) ///< Right Window
+ KEYBOARD_MODIFIER_LEFTCTRL = TU_BIT(0), ///< Left Control
+ KEYBOARD_MODIFIER_LEFTSHIFT = TU_BIT(1), ///< Left Shift
+ KEYBOARD_MODIFIER_LEFTALT = TU_BIT(2), ///< Left Alt
+ KEYBOARD_MODIFIER_LEFTGUI = TU_BIT(3), ///< Left Window
+ KEYBOARD_MODIFIER_RIGHTCTRL = TU_BIT(4), ///< Right Control
+ KEYBOARD_MODIFIER_RIGHTSHIFT = TU_BIT(5), ///< Right Shift
+ KEYBOARD_MODIFIER_RIGHTALT = TU_BIT(6), ///< Right Alt
+ KEYBOARD_MODIFIER_RIGHTGUI = TU_BIT(7) ///< Right Window
}hid_keyboard_modifier_bm_t;
typedef enum
{
- KEYBOARD_LED_NUMLOCK = BIT_(0), ///< Num Lock LED
- KEYBOARD_LED_CAPSLOCK = BIT_(1), ///< Caps Lock LED
- KEYBOARD_LED_SCROLLLOCK = BIT_(2), ///< Scroll Lock LED
- KEYBOARD_LED_COMPOSE = BIT_(3), ///< Composition Mode
- KEYBOARD_LED_KANA = BIT_(4) ///< Kana mode
+ KEYBOARD_LED_NUMLOCK = TU_BIT(0), ///< Num Lock LED
+ KEYBOARD_LED_CAPSLOCK = TU_BIT(1), ///< Caps Lock LED
+ KEYBOARD_LED_SCROLLLOCK = TU_BIT(2), ///< Scroll Lock LED
+ KEYBOARD_LED_COMPOSE = TU_BIT(3), ///< Composition Mode
+ KEYBOARD_LED_KANA = TU_BIT(4) ///< Kana mode
}hid_keyboard_led_bm_t;
/// @}
diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c
index c89c15acc..3b882f705 100644
--- a/src/class/hid/hid_device.c
+++ b/src/class/hid/hid_device.c
@@ -207,6 +207,7 @@ bool tud_hid_keyboard_key_press(char ch)
return tud_hid_keyboard_keycode(modifier, keycode);
}
+#if 0 // should be at application
bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms)
{
// Send each key in string
@@ -231,6 +232,7 @@ bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms)
return true;
}
+#endif
#endif // CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
@@ -318,29 +320,29 @@ void hidd_reset(uint8_t rhport)
#endif
}
-tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
+bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len)
{
uint8_t const *p_desc = (uint8_t const *) desc_itf;
- // TODO not support HID OUT Endpoint
- TU_ASSERT(desc_itf->bNumEndpoints == 1, ERR_TUD_INVALID_DESCRIPTOR);
+ // TODO support HID OUT Endpoint
+ TU_ASSERT(desc_itf->bNumEndpoints == 1);
//------------- HID descriptor -------------//
- p_desc += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
- TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
+ TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType);
//------------- Endpoint Descriptor -------------//
- p_desc += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
tusb_desc_endpoint_t const *desc_edpt = (tusb_desc_endpoint_t const *) p_desc;
- TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType, ERR_TUD_INVALID_DESCRIPTOR);
+ TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType);
hidd_interface_t * p_hid = NULL;
/*------------- Boot protocol only keyboard & mouse -------------*/
if (desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT)
{
- TU_ASSERT(desc_itf->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD || desc_itf->bInterfaceProtocol == HID_PROTOCOL_MOUSE, ERR_TUD_INVALID_DESCRIPTOR);
+ TU_ASSERT(desc_itf->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD || desc_itf->bInterfaceProtocol == HID_PROTOCOL_MOUSE);
#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
if (desc_itf->bInterfaceProtocol == HID_PROTOCOL_KEYBOARD)
@@ -374,7 +376,7 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
}
#endif
- TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
+ TU_ASSERT(p_hid);
p_hid->boot_protocol = true; // default mode is BOOT
}
/*------------- Generic (multiple report) -------------*/
@@ -386,12 +388,10 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
p_hid->desc_report = usbd_desc_set->hid_report.generic;
p_hid->get_report_cb = tud_hid_generic_get_report_cb;
p_hid->set_report_cb = tud_hid_generic_set_report_cb;
-
- TU_ASSERT(p_hid, ERR_TUD_INVALID_DESCRIPTOR);
}
- TU_VERIFY(p_hid->desc_report, ERR_TUD_INVALID_DESCRIPTOR);
- TU_ASSERT( dcd_edpt_open(rhport, desc_edpt), ERR_TUD_EDPT_OPEN_FAILED );
+ TU_ASSERT(p_hid->desc_report);
+ TU_ASSERT(dcd_edpt_open(rhport, desc_edpt));
p_hid->itf_num = desc_itf->bInterfaceNumber;
p_hid->ep_in = desc_edpt->bEndpointAddress;
@@ -399,7 +399,7 @@ tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, u
*p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
- return TUSB_ERROR_NONE;
+ return true;
}
// Handle class control request
@@ -418,7 +418,6 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
{
- // Cast away the const on p_hid->desc_report because we know it won't be modified.
usbd_control_xfer(rhport, p_request, (void *)p_hid->desc_report, p_hid->desc_len);
}else
{
@@ -511,10 +510,10 @@ bool hidd_control_request_complete(uint8_t rhport, tusb_control_request_t const
return true;
}
-tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes)
+bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
{
// nothing to do
- return TUSB_ERROR_NONE;
+ return true;
}
diff --git a/src/class/hid/hid_device.h b/src/class/hid/hid_device.h
index 7aff7f34d..f3d5087a2 100644
--- a/src/class/hid/hid_device.h
+++ b/src/class/hid/hid_device.h
@@ -95,7 +95,6 @@ static inline bool tud_hid_keyboard_key_release(void) { return tud_hid_keyboard_
#if CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP
bool tud_hid_keyboard_key_press(char ch);
-bool tud_hid_keyboard_key_sequence(const char* str, uint32_t interval_ms);
typedef struct{
uint8_t shift;
@@ -377,10 +376,10 @@ ATTR_WEAK void tud_hid_mouse_set_report_cb(uint8_t report_id, hid_report_type_t
#ifdef _TINY_USB_SOURCE_FILE_
void hidd_init(void);
-tusb_error_t hidd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
bool hidd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
-tusb_error_t hidd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
+bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void hidd_reset(uint8_t rhport);
#endif
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index 6aa0748df..b01cd9d59 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -38,7 +38,7 @@
#include "tusb_option.h"
-#if (MODE_HOST_SUPPORTED && HOST_CLASS_HID)
+#if (TUSB_OPT_HOST_ENABLED && HOST_CLASS_HID)
#define _TINY_USB_SOURCE_FILE_
//--------------------------------------------------------------------+
@@ -54,20 +54,19 @@
//--------------------------------------------------------------------+
// HID Interface common functions
//--------------------------------------------------------------------+
-static inline tusb_error_t hidh_interface_open(uint8_t dev_addr, uint8_t interface_number, tusb_desc_endpoint_t const *p_endpoint_desc, hidh_interface_info_t *p_hid)
+static inline bool hidh_interface_open(uint8_t dev_addr, uint8_t interface_number, tusb_desc_endpoint_t const *p_endpoint_desc, hidh_interface_info_t *p_hid)
{
- p_hid->pipe_hdl = hcd_pipe_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
+ p_hid->pipe_hdl = hcd_edpt_open(dev_addr, p_endpoint_desc, TUSB_CLASS_HID);
p_hid->report_size = p_endpoint_desc->wMaxPacketSize.size; // TODO get size from report descriptor
p_hid->interface_number = interface_number;
- TU_ASSERT (pipehandle_is_valid(p_hid->pipe_hdl), TUSB_ERROR_HCD_FAILED);
+ TU_ASSERT (pipehandle_is_valid(p_hid->pipe_hdl));
- return TUSB_ERROR_NONE;
+ return true;
}
static inline void hidh_interface_close(hidh_interface_info_t *p_hid)
{
- (void) hcd_pipe_close(p_hid->pipe_hdl);
tu_memclr(p_hid, sizeof(hidh_interface_info_t));
}
@@ -78,7 +77,7 @@ tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_int
// TODO change to use is configured function
TU_ASSERT (TUSB_DEVICE_STATE_CONFIGURED == tuh_device_get_state(dev_addr), TUSB_ERROR_DEVICE_NOT_READY);
TU_VERIFY (report, TUSB_ERROR_INVALID_PARA);
- TU_ASSSERT (!hcd_pipe_is_busy(p_hid->pipe_hdl), TUSB_ERROR_INTERFACE_IS_BUSY);
+ TU_ASSERT (!hcd_edpt_busy(p_hid->pipe_hdl), TUSB_ERROR_INTERFACE_IS_BUSY);
TU_ASSERT_ERR( hcd_pipe_xfer(p_hid->pipe_hdl, report, p_hid->report_size, true) ) ;
@@ -88,8 +87,9 @@ tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_int
//--------------------------------------------------------------------+
// KEYBOARD
//--------------------------------------------------------------------+
-#if CFG_TUSB_HOST_HID_KEYBOARD
+#if CFG_TUH_HID_KEYBOARD
+#if 0
#define EXPAND_KEYCODE_TO_ASCII(keycode, ascii, shift_modified) \
[0][keycode] = ascii,\
[1][keycode] = shift_modified,\
@@ -99,8 +99,9 @@ uint8_t const hid_keycode_to_ascii_tbl[2][128] =
{
HID_KEYCODE_TABLE(EXPAND_KEYCODE_TO_ASCII)
};
+#endif
-STATIC_VAR hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
+static hidh_interface_info_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
//------------- KEYBOARD PUBLIC API (parameter validation required) -------------//
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr)
@@ -116,7 +117,7 @@ tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void* p_report)
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr)
{
return tuh_hid_keyboard_is_mounted(dev_addr) &&
- hcd_pipe_is_busy( keyboardh_data[dev_addr-1].pipe_hdl );
+ hcd_edpt_busy( keyboardh_data[dev_addr-1].pipe_hdl );
}
#endif
@@ -124,7 +125,7 @@ bool tuh_hid_keyboard_is_busy(uint8_t dev_addr)
//--------------------------------------------------------------------+
// MOUSE
//--------------------------------------------------------------------+
-#if CFG_TUSB_HOST_HID_MOUSE
+#if CFG_TUH_HID_MOUSE
STATIC_VAR hidh_interface_info_t mouseh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1
@@ -137,7 +138,7 @@ bool tuh_hid_mouse_is_mounted(uint8_t dev_addr)
bool tuh_hid_mouse_is_busy(uint8_t dev_addr)
{
return tuh_hid_mouse_is_mounted(dev_addr) &&
- hcd_pipe_is_busy( mouseh_data[dev_addr-1].pipe_hdl );
+ hcd_edpt_busy( mouseh_data[dev_addr-1].pipe_hdl );
}
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report)
@@ -163,11 +164,11 @@ tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report)
//--------------------------------------------------------------------+
void hidh_init(void)
{
-#if CFG_TUSB_HOST_HID_KEYBOARD
+#if CFG_TUH_HID_KEYBOARD
tu_memclr(&keyboardh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
#endif
-#if CFG_TUSB_HOST_HID_MOUSE
+#if CFG_TUH_HID_MOUSE
tu_memclr(&mouseh_data, sizeof(hidh_interface_info_t)*CFG_TUSB_HOST_DEVICE_MAX);
#endif
@@ -180,9 +181,8 @@ void hidh_init(void)
CFG_TUSB_MEM_SECTION uint8_t report_descriptor[256];
#endif
-tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
+bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
{
- tusb_error_t error;
uint8_t const *p_desc = (uint8_t const *) p_interface_desc;
//------------- HID descriptor -------------//
@@ -195,16 +195,15 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
tusb_desc_endpoint_t const * p_endpoint_desc = (tusb_desc_endpoint_t const *) p_desc;
TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint_desc->bDescriptorType, TUSB_ERROR_INVALID_PARA);
- OSAL_SUBTASK_BEGIN
-
//------------- SET IDLE (0) request -------------//
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE),
- HID_REQ_CONTROL_SET_IDLE, 0, p_interface_desc->bInterfaceNumber,
- 0, NULL ),
- error
- );
- (void) error; // skip if set idle is failed
+ tusb_control_request_t request = {
+ .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
+ .bRequest = HID_REQ_CONTROL_SET_IDLE,
+ .wValue = 0, // idle_rate = 0
+ .wIndex = p_interface_desc->bInterfaceNumber,
+ .wLength = 0
+ };
+ TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
#if 0
//------------- Get Report Descriptor TODO HID parser -------------//
@@ -222,40 +221,42 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
if ( HID_SUBCLASS_BOOT == p_interface_desc->bInterfaceSubClass )
{
- #if CFG_TUSB_HOST_HID_KEYBOARD
+ #if CFG_TUH_HID_KEYBOARD
if ( HID_PROTOCOL_KEYBOARD == p_interface_desc->bInterfaceProtocol)
{
- STASK_ASSERT_ERR ( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &keyboardh_data[dev_addr-1]) );
+ TU_ASSERT( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &keyboardh_data[dev_addr-1]) );
tuh_hid_keyboard_mounted_cb(dev_addr);
} else
#endif
- #if CFG_TUSB_HOST_HID_MOUSE
+ #if CFG_TUH_HID_MOUSE
if ( HID_PROTOCOL_MOUSE == p_interface_desc->bInterfaceProtocol)
{
- STASK_ASSERT_ERR ( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &mouseh_data[dev_addr-1]) );
+ TU_ASSERT ( hidh_interface_open(dev_addr, p_interface_desc->bInterfaceNumber, p_endpoint_desc, &mouseh_data[dev_addr-1]) );
tuh_hid_mouse_mounted_cb(dev_addr);
} else
#endif
{
- STASK_RETURN(TUSB_ERROR_HIDH_NOT_SUPPORTED_PROTOCOL); // exit & restart task
+ // Not supported protocol
+ return false;
}
}else
{
- STASK_RETURN(TUSB_ERROR_HIDH_NOT_SUPPORTED_SUBCLASS); // exit & restart task
+ // Not supported subclass
+ return false;
}
*p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t);
- OSAL_SUBTASK_END
+ return true;
}
void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
{
(void) xferred_bytes; // TODO may need to use this para later
-#if CFG_TUSB_HOST_HID_KEYBOARD
+#if CFG_TUH_HID_KEYBOARD
if ( pipehandle_is_equal(pipe_hdl, keyboardh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
{
tuh_hid_keyboard_isr(pipe_hdl.dev_addr, event);
@@ -263,7 +264,7 @@ void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_byte
}
#endif
-#if CFG_TUSB_HOST_HID_MOUSE
+#if CFG_TUH_HID_MOUSE
if ( pipehandle_is_equal(pipe_hdl, mouseh_data[pipe_hdl.dev_addr-1].pipe_hdl) )
{
tuh_hid_mouse_isr(pipe_hdl.dev_addr, event);
@@ -278,7 +279,7 @@ void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_byte
void hidh_close(uint8_t dev_addr)
{
-#if CFG_TUSB_HOST_HID_KEYBOARD
+#if CFG_TUH_HID_KEYBOARD
if ( pipehandle_is_valid( keyboardh_data[dev_addr-1].pipe_hdl ) )
{
hidh_interface_close(&keyboardh_data[dev_addr-1]);
@@ -286,7 +287,7 @@ void hidh_close(uint8_t dev_addr)
}
#endif
-#if CFG_TUSB_HOST_HID_MOUSE
+#if CFG_TUH_HID_MOUSE
if( pipehandle_is_valid( mouseh_data[dev_addr-1].pipe_hdl ) )
{
hidh_interface_close(&mouseh_data[dev_addr-1]);
diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h
index cb0230e8a..9d4b2b5b6 100644
--- a/src/class/hid/hid_host.h
+++ b/src/class/hid/hid_host.h
@@ -67,7 +67,7 @@ extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if
* \retval true if device supports Keyboard interface
* \retval false if device does not support Keyboard interface or is not mounted
*/
-bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
@@ -76,7 +76,7 @@ bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_keyboard_get_report.
* Alternatively, asynchronous event API can be used
*/
-bool tuh_hid_keyboard_is_busy(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_hid_keyboard_is_busy(uint8_t dev_addr);
/** \brief Perform a get report from Keyboard interface
* \param[in] dev_addr device address
@@ -88,7 +88,7 @@ bool tuh_hid_keyboard_is_busy(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNU
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
*/
-tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report) /*ATTR_WARN_UNUSED_RESULT*/;
+tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report);
//------------- Application Callback -------------//
/** \brief Callback function that is invoked when an transferring event occurred
@@ -132,7 +132,7 @@ void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
* \retval true if device supports Mouse interface
* \retval false if device does not support Mouse interface or is not mounted
*/
-bool tuh_hid_mouse_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_hid_mouse_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
@@ -141,7 +141,7 @@ bool tuh_hid_mouse_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNU
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_mouse_get_report.
* Alternatively, asynchronous event API can be used
*/
-bool tuh_hid_mouse_is_busy(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_hid_mouse_is_busy(uint8_t dev_addr);
/** \brief Perform a get report from Mouse interface
* \param[in] dev_addr device address
@@ -153,7 +153,7 @@ bool tuh_hid_mouse_is_busy(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
*/
-tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report) /*ATTR_WARN_UNUSED_RESULT*/;
+tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report);
//------------- Application Callback -------------//
/** \brief Callback function that is invoked when an transferring event occurred
@@ -192,11 +192,11 @@ void tuh_hid_mouse_unmounted_cb(uint8_t dev_addr);
* The interface API includes status checking function, data transferring function and callback functions
* @{ */
-bool tuh_hid_generic_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
-tusb_error_t tuh_hid_generic_get_report(uint8_t dev_addr, void* p_report, bool int_on_complete) ATTR_WARN_UNUSED_RESULT;
-tusb_error_t tuh_hid_generic_set_report(uint8_t dev_addr, void* p_report, bool int_on_complete) ATTR_WARN_UNUSED_RESULT;
-tusb_interface_status_t tuh_hid_generic_get_status(uint8_t dev_addr) ATTR_WARN_UNUSED_RESULT;
-tusb_interface_status_t tuh_hid_generic_set_status(uint8_t dev_addr) ATTR_WARN_UNUSED_RESULT;
+bool tuh_hid_generic_is_mounted(uint8_t dev_addr);
+tusb_error_t tuh_hid_generic_get_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
+tusb_error_t tuh_hid_generic_set_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
+tusb_interface_status_t tuh_hid_generic_get_status(uint8_t dev_addr);
+tusb_interface_status_t tuh_hid_generic_set_status(uint8_t dev_addr);
//------------- Application Callback -------------//
void tuh_hid_generic_isr(uint8_t dev_addr, xfer_result_t event);
@@ -215,10 +215,10 @@ typedef struct {
uint8_t interface_number;
}hidh_interface_info_t;
-void hidh_init(void);
-tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
-void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
-void hidh_close(uint8_t dev_addr);
+void hidh_init(void);
+bool hidh_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
+void hidh_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
+void hidh_close(uint8_t dev_addr);
#endif
diff --git a/src/class/midi/midi.h b/src/class/midi/midi.h
new file mode 100644
index 000000000..21c43be20
--- /dev/null
+++ b/src/class/midi/midi.h
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*!
+ @file cdc.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup group_class
+ * \defgroup ClassDriver_CDC Communication Device Class (CDC)
+ * Currently only Abstract Control Model subclass is supported
+ * @{ */
+
+#ifndef _TUSB_MIDI_H__
+#define _TUSB_MIDI_H__
+
+#include "common/tusb_common.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// FUNCTIONAL DESCRIPTOR (COMMUNICATION INTERFACE)
+//--------------------------------------------------------------------+
+/// Header Functional Descriptor (Communication Interface)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above MIDI_FUCN_DESC_
+ uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
+ uint16_t wTotalLength ;
+}midi_desc_func_header_t;
+
+/// Union Functional Descriptor (Communication Interface)
+typedef struct ATTR_PACKED
+{
+ uint8_t bLength ; ///< Size of this descriptor in bytes.
+ uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
+ uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
+ uint8_t bControlInterface ; ///< Interface number of Communication Interface
+ uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
+}cdc_desc_func_union_t;
+
+/** @} */
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
+
+/** @} */
diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c
new file mode 100644
index 000000000..87c338ab2
--- /dev/null
+++ b/src/class/midi/midi_device.c
@@ -0,0 +1,360 @@
+/**************************************************************************/
+/*!
+ @file cdc_device.c
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#include "tusb_option.h"
+
+#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_MIDI)
+
+#define _TINY_USB_SOURCE_FILE_
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "midi_device.h"
+#include "class/audio/audio.h"
+#include "device/usbd_pvt.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+typedef struct
+{
+ uint8_t itf_num;
+ uint8_t ep_in;
+ uint8_t ep_out;
+
+ // FIFO
+ tu_fifo_t rx_ff;
+ tu_fifo_t tx_ff;
+ uint8_t rx_ff_buf[CFG_TUD_MIDI_RX_BUFSIZE];
+ uint8_t tx_ff_buf[CFG_TUD_MIDI_TX_BUFSIZE];
+
+ #if CFG_FIFO_MUTEX
+ osal_mutex_def_t rx_ff_mutex;
+ osal_mutex_def_t tx_ff_mutex;
+ #endif
+
+ // We need to pack messages into words before queueing their transmission so buffer across write
+ // calls.
+ uint8_t message_buffer[4];
+ uint8_t message_buffer_length;
+ uint8_t message_target_length;
+
+ // Endpoint Transfer buffer
+ CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_MIDI_EPSIZE];
+ CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_MIDI_EPSIZE];
+
+} midid_interface_t;
+
+#define ITF_MEM_RESET_SIZE offsetof(midid_interface_t, rx_ff)
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+CFG_TUSB_ATTR_USBRAM midid_interface_t _midid_itf[CFG_TUD_MIDI];
+
+bool tud_midi_n_connected(uint8_t itf) {
+ midid_interface_t* midi = &_midid_itf[itf];
+ return midi->itf_num != 0;
+}
+
+//--------------------------------------------------------------------+
+// READ API
+//--------------------------------------------------------------------+
+uint32_t tud_midi_n_available(uint8_t itf, uint8_t jack_id)
+{
+ return tu_fifo_count(&_midid_itf[itf].rx_ff);
+}
+
+char tud_midi_n_read_char(uint8_t itf, uint8_t jack_id)
+{
+ char ch;
+ return tu_fifo_read(&_midid_itf[itf].rx_ff, &ch) ? ch : (-1);
+}
+
+uint32_t tud_midi_n_read(uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize)
+{
+ return tu_fifo_read_n(&_midid_itf[itf].rx_ff, buffer, bufsize);
+}
+
+void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id)
+{
+ tu_fifo_clear(&_midid_itf[itf].rx_ff);
+}
+
+
+void midi_rx_done_cb(midid_interface_t* midi, uint8_t const* buffer, uint32_t bufsize) {
+ if (bufsize % 4 != 0) {
+ return;
+ }
+
+ for(uint32_t i=0; i<bufsize; i += 4) {
+ uint8_t header = buffer[i];
+ // uint8_t cable_number = (header & 0xf0) >> 4;
+ uint8_t code_index = header & 0x0f;
+ // We always copy over the first byte.
+ uint8_t count = 1;
+ // Ignore subsequent bytes based on the code.
+ if (code_index != 0x5 && code_index != 0xf) {
+ count = 2;
+ if (code_index != 0x2 && code_index != 0x6 && code_index != 0xc && code_index != 0xd) {
+ count = 3;
+ }
+ }
+ tu_fifo_write_n(&midi->rx_ff, &buffer[i + 1], count);
+ }
+}
+
+
+//--------------------------------------------------------------------+
+// WRITE API
+//--------------------------------------------------------------------+
+
+static bool maybe_transmit(midid_interface_t* midi, uint8_t itf_index)
+{
+ TU_VERIFY( !dcd_edpt_busy(TUD_OPT_RHPORT, midi->ep_in) ); // skip if previous transfer not complete
+
+ uint16_t count = tu_fifo_read_n(&midi->tx_ff, midi->epin_buf, CFG_TUD_MIDI_EPSIZE);
+ if (count > 0)
+ {
+ TU_VERIFY( tud_midi_n_connected(itf_index) ); // fifo is empty if not connected
+ TU_ASSERT( dcd_edpt_xfer(TUD_OPT_RHPORT, midi->ep_in, midi->epin_buf, count) );
+ }
+ return true;
+}
+
+uint32_t tud_midi_n_write(uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize)
+{
+ midid_interface_t* midi = &_midid_itf[itf];
+ if (midi->itf_num == 0) {
+ return 0;
+ }
+
+ uint32_t i = 0;
+ while (i < bufsize) {
+ uint8_t data = buffer[i];
+ if (midi->message_buffer_length == 0) {
+ uint8_t msg = data >> 4;
+ midi->message_buffer[1] = data;
+ midi->message_buffer_length = 2;
+ // Check to see if we're still in a SysEx transmit.
+ if (midi->message_buffer[0] == 0x4) {
+ if (data == 0xf7) {
+ midi->message_buffer[0] = 0x5;
+ } else {
+ midi->message_buffer_length = 4;
+ }
+ } else if ((msg >= 0x8 && msg <= 0xB) || msg == 0xE) {
+ midi->message_buffer[0] = jack_id << 4 | msg;
+ midi->message_target_length = 4;
+ } else if (msg == 0xf) {
+ if (data == 0xf0) {
+ midi->message_buffer[0] = 0x4;
+ midi->message_target_length = 4;
+ } else if (data == 0xf1 || data == 0xf3) {
+ midi->message_buffer[0] = 0x2;
+ midi->message_target_length = 3;
+ } else if (data == 0xf2) {
+ midi->message_buffer[0] = 0x3;
+ midi->message_target_length = 4;
+ } else {
+ midi->message_buffer[0] = 0x5;
+ midi->message_target_length = 2;
+ }
+ } else {
+ // Pack individual bytes if we don't support packing them into words.
+ midi->message_buffer[0] = jack_id << 4 | 0xf;
+ midi->message_buffer[2] = 0;
+ midi->message_buffer[3] = 0;
+ midi->message_buffer_length = 2;
+ midi->message_target_length = 2;
+ }
+ } else {
+ midi->message_buffer[midi->message_buffer_length] = data;
+ midi->message_buffer_length += 1;
+ // See if this byte ends a SysEx.
+ if (midi->message_buffer[0] == 0x4 && data == 0xf7) {
+ midi->message_buffer[0] = 0x4 + (midi->message_buffer_length - 1);
+ midi->message_target_length = midi->message_buffer_length;
+ }
+ }
+
+ if (midi->message_buffer_length == midi->message_target_length) {
+ uint16_t written = tu_fifo_write_n(&midi->tx_ff, midi->message_buffer, 4);
+ if (written < 4) {
+ TU_ASSERT( written == 0 );
+ break;
+ }
+ midi->message_buffer_length = 0;
+ }
+ i++;
+ }
+ maybe_transmit(midi, itf);
+
+ return i;
+}
+
+//--------------------------------------------------------------------+
+// USBD Driver API
+//--------------------------------------------------------------------+
+void midid_init(void)
+{
+ tu_memclr(_midid_itf, sizeof(_midid_itf));
+
+ for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
+ {
+ 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);
+ #if CFG_FIFO_MUTEX
+ tu_fifo_config_mutex(&midi->rx_ff, osal_mutex_create(&midi->rx_ff_mutex));
+ tu_fifo_config_mutex(&midi->tx_ff, osal_mutex_create(&midi->tx_ff_mutex));
+ #endif
+ }
+}
+
+void midid_reset(uint8_t rhport)
+{
+ (void) rhport;
+
+ for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
+ {
+ midid_interface_t* midi = &_midid_itf[i];
+ tu_memclr(midi, ITF_MEM_RESET_SIZE);
+ tu_fifo_clear(&midi->rx_ff);
+ tu_fifo_clear(&midi->tx_ff);
+ }
+}
+
+bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length)
+{
+ // For now handle the audio control interface as well.
+ if ( AUDIO_SUBCLASS_AUDIO_CONTROL == p_interface_desc->bInterfaceSubClass) {
+ uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc );
+ (*p_length) = sizeof(tusb_desc_interface_t);
+
+ // Skip over the class specific descriptor.
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
+ return true;
+ }
+
+ if ( AUDIO_SUBCLASS_MIDI_STREAMING != p_interface_desc->bInterfaceSubClass ||
+ p_interface_desc->bInterfaceProtocol != AUDIO_PROTOCOL_V1 ) {
+ return false;
+ }
+
+ // Find available interface
+ midid_interface_t * p_midi = NULL;
+ for(uint8_t i=0; i<CFG_TUD_MIDI; i++)
+ {
+ if ( _midid_itf[i].ep_in == 0 && _midid_itf[i].ep_out == 0 )
+ {
+ p_midi = &_midid_itf[i];
+ break;
+ }
+ }
+
+ p_midi->itf_num = p_interface_desc->bInterfaceNumber;
+
+ uint8_t const * p_desc = tu_desc_next( (uint8_t const *) p_interface_desc );
+ (*p_length) = sizeof(tusb_desc_interface_t);
+
+ uint8_t found_endpoints = 0;
+ while (found_endpoints < p_interface_desc->bNumEndpoints) {
+ if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE])
+ {
+ TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), false);
+ uint8_t ep_addr = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress;
+ if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) {
+ p_midi->ep_in = ep_addr;
+ } else {
+ p_midi->ep_out = ep_addr;
+ }
+
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
+ found_endpoints += 1;
+ }
+ (*p_length) += p_desc[DESC_OFFSET_LEN];
+ p_desc = tu_desc_next(p_desc);
+ }
+
+ // Prepare for incoming data
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false);
+
+ return true;
+}
+
+bool midid_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ return false;
+}
+
+bool midid_control_request(uint8_t rhport, tusb_control_request_t const * p_request)
+{
+ //------------- Class Specific Request -------------//
+ if (p_request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) return false;
+
+ return false;
+}
+
+bool midid_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes)
+{
+ // TODO Support multiple interfaces
+ uint8_t const itf = 0;
+ midid_interface_t* p_midi = &_midid_itf[itf];
+
+ // receive new data
+ if ( edpt_addr == p_midi->ep_out )
+ {
+ midi_rx_done_cb(p_midi, p_midi->epout_buf, xferred_bytes);
+
+ // prepare for next
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false );
+ } else if ( edpt_addr == p_midi->ep_in ) {
+ maybe_transmit(p_midi, itf);
+ }
+
+ // nothing to do with in and notif endpoint
+
+ return TUSB_ERROR_NONE;
+}
+
+#endif
diff --git a/src/class/midi/midi_device.h b/src/class/midi/midi_device.h
new file mode 100644
index 000000000..70030f2ce
--- /dev/null
+++ b/src/class/midi/midi_device.h
@@ -0,0 +1,120 @@
+/**************************************************************************/
+/*!
+ @file midi_device.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+#ifndef _TUSB_MIDI_DEVICE_H_
+#define _TUSB_MIDI_DEVICE_H_
+
+#include "common/tusb_common.h"
+#include "device/usbd.h"
+#include "class/audio/audio.h"
+
+//--------------------------------------------------------------------+
+// Class Driver Configuration
+//--------------------------------------------------------------------+
+#ifndef CFG_TUD_MIDI_EPSIZE
+#define CFG_TUD_MIDI_EPSIZE 64
+#endif
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** \addtogroup MIDI_Serial Serial
+ * @{
+ * \defgroup MIDI_Serial_Device Device
+ * @{ */
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Multiple Interfaces)
+// CFG_TUD_MIDI > 1
+//--------------------------------------------------------------------+
+bool tud_midi_n_connected (uint8_t itf);
+
+uint32_t tud_midi_n_available (uint8_t itf, uint8_t jack_id);
+char tud_midi_n_read_char (uint8_t itf, uint8_t jack_id);
+uint32_t tud_midi_n_read (uint8_t itf, uint8_t jack_id, void* buffer, uint32_t bufsize);
+void tud_midi_n_read_flush (uint8_t itf, uint8_t jack_id);
+char tud_midi_n_peek (uint8_t itf, uint8_t jack_id, int pos);
+
+uint32_t tud_midi_n_write_char (uint8_t itf, char ch);
+uint32_t tud_midi_n_write (uint8_t itf, uint8_t jack_id, uint8_t const* buffer, uint32_t bufsize);
+bool tud_midi_n_write_flush (uint8_t itf);
+
+//--------------------------------------------------------------------+
+// APPLICATION API (Interface0)
+//--------------------------------------------------------------------+
+static inline bool tud_midi_connected (void) { return tud_midi_n_connected(0); }
+
+static inline uint32_t tud_midi_available (void) { return tud_midi_n_available(0, 0); }
+static inline char tud_midi_read_char (void) { return tud_midi_n_read_char(0, 0); }
+static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize) { return tud_midi_n_read(0, 0, buffer, bufsize); }
+static inline void tud_midi_read_flush (void) { tud_midi_n_read_flush(0, 0); }
+static inline char tud_midi_peek (int pos) { return tud_midi_n_peek(0, 0, pos); }
+
+static inline uint32_t tud_midi_write_char (char ch) { return tud_midi_n_write_char(0, ch); }
+static inline uint32_t tud_midi_write (uint8_t jack_id, void const* buffer, uint32_t bufsize) { return tud_midi_n_write(0, jack_id, buffer, bufsize); }
+static inline bool tud_midi_write_flush (void) { return tud_midi_n_write_flush(0); }
+
+//--------------------------------------------------------------------+
+// APPLICATION CALLBACK API (WEAK is optional)
+//--------------------------------------------------------------------+
+ATTR_WEAK void tud_midi_rx_cb(uint8_t itf);
+
+//--------------------------------------------------------------------+
+// USBD-CLASS DRIVER API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+void midid_init (void);
+bool midid_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+bool midid_control_request (uint8_t rhport, tusb_control_request_t const * p_request);
+bool midid_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
+bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
+void midid_reset (uint8_t rhport);
+
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_MIDI_DEVICE_H_ */
+
+/** @} */
+/** @} */
diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c
index 88f8da6db..5d2758414 100644
--- a/src/class/msc/msc_device.c
+++ b/src/class/msc/msc_device.c
@@ -62,7 +62,7 @@ enum
typedef struct {
CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
-//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13UXX)
+//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX)
// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member
//#endif
@@ -146,28 +146,29 @@ void mscd_init(void)
void mscd_reset(uint8_t rhport)
{
+ (void) rhport;
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
}
-tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_desc_itf, uint16_t *p_len)
+bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len)
{
// only support SCSI's BOT protocol
- TU_VERIFY( ( MSC_SUBCLASS_SCSI == p_desc_itf->bInterfaceSubClass &&
- MSC_PROTOCOL_BOT == p_desc_itf->bInterfaceProtocol ), TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL );
+ TU_ASSERT(MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
+ MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
mscd_interface_t * p_msc = &_mscd_itf;
// Open endpoint pair with usbd helper
- tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_desc_itf );
- TU_ASSERT_ERR( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
+ tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next( itf_desc );
+ TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
- p_msc->itf_num = p_desc_itf->bInterfaceNumber;
+ p_msc->itf_num = itf_desc->bInterfaceNumber;
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
- //------------- Queue Endpoint OUT for Command Block Wrapper -------------//
- TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_DCD_EDPT_XFER );
+ // Prepare for Command Block Wrapper
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)) );
- return TUSB_ERROR_NONE;
+ return true;
}
// Handle class control request
@@ -201,6 +202,9 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
// return false to stall control endpoint (e.g Host send non-sense DATA)
bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request)
{
+ (void) rhport;
+ (void) p_request;
+
// nothing to do
return true;
}
@@ -208,6 +212,7 @@ bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const
// return length of response (copied to buffer), -1 if it is not an built-in commands
int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize)
{
+ (void) bufsize; // TODO refractor later
int32_t ret;
switch ( p_cbw->command[0] )
@@ -324,7 +329,7 @@ int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t buf
return ret;
}
-tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
+bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
{
mscd_interface_t* p_msc = &_mscd_itf;
msc_cbw_t const * p_cbw = &p_msc->cbw;
@@ -335,10 +340,10 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
case MSC_STAGE_CMD:
//------------- new CBW received -------------//
// Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it
- if(ep_addr != p_msc->ep_out) return TUSB_ERROR_NONE;
+ if(ep_addr != p_msc->ep_out) return true;
TU_ASSERT( event == XFER_RESULT_SUCCESS &&
- xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE, TUSB_ERROR_INVALID_PARA );
+ xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE );
p_csw->signature = MSC_CSW_SIGNATURE;
p_csw->tag = p_cbw->tag;
@@ -380,10 +385,10 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
p_csw->status = MSC_CSW_STATUS_PASSED;
}
}
- else if ( !BIT_TEST_(p_cbw->dir, 7) )
+ else if ( !TU_BIT_TEST(p_cbw->dir, 7) )
{
// OUT transfer
- TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, p_msc->total_len) );
}
else
{
@@ -404,8 +409,8 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
p_msc->total_len = (uint32_t) cb_result;
p_csw->status = MSC_CSW_STATUS_PASSED;
- TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len, TUSB_ERROR_INVALID_PARA ); // cannot return more than host expect
- TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len), TUSB_ERROR_DCD_EDPT_XFER );
+ TU_ASSERT( p_cbw->total_bytes >= p_msc->total_len ); // cannot return more than host expect
+ TU_ASSERT( dcd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, p_msc->total_len) );
}else
{
p_msc->total_len = 0;
@@ -421,7 +426,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
case MSC_STAGE_DATA:
// OUT transfer, invoke callback if needed
- if ( !BIT_TEST_(p_cbw->dir, 7) )
+ if ( !TU_BIT_TEST(p_cbw->dir, 7) )
{
if ( SCSI_CMD_WRITE_10 != p_cbw->command[0] )
{
@@ -469,7 +474,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
// simulate an transfer complete with adjusted parameters --> this driver callback will fired again
dcd_event_xfer_complete(rhport, p_msc->ep_out, xferred_bytes-nbytes, XFER_RESULT_SUCCESS, false);
- return TUSB_ERROR_NONE; // skip the rest
+ return true; // skip the rest
}
else
{
@@ -544,7 +549,7 @@ tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
}
}
- return TUSB_ERROR_NONE;
+ return true;
}
/*------------------------------------------------------------------*/
diff --git a/src/class/msc/msc_device.h b/src/class/msc/msc_device.h
index c4476f56f..c9e4139e9 100644
--- a/src/class/msc/msc_device.h
+++ b/src/class/msc/msc_device.h
@@ -71,12 +71,6 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
#error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined
#endif
-// TODO highspeed device is 512
-#ifndef CFG_TUD_MSC_EPSIZE
-#define CFG_TUD_MSC_EPSIZE 64
-#endif
-
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -177,10 +171,10 @@ ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
#ifdef _TINY_USB_SOURCE_FILE_
void mscd_init(void);
-tusb_error_t mscd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
+bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length);
bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
bool mscd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
-tusb_error_t mscd_xfer_cb(uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes);
+bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void mscd_reset(uint8_t rhport);
#endif
diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c
index baef7ff44..86669b279 100644
--- a/src/class/msc/msc_host.c
+++ b/src/class/msc/msc_host.c
@@ -38,7 +38,7 @@
#include "tusb_option.h"
-#if MODE_HOST_SUPPORTED & CFG_TUSB_HOST_MSC
+#if TUSB_OPT_HOST_ENABLED & CFG_TUH_MSC
#define _TINY_USB_SOURCE_FILE_
@@ -51,13 +51,14 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-CFG_TUSB_MEM_SECTION STATIC_VAR msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
+CFG_TUSB_MEM_SECTION static msch_interface_t msch_data[CFG_TUSB_HOST_DEVICE_MAX];
//------------- Initalization Data -------------//
+static osal_semaphore_def_t msch_sem_def;
static osal_semaphore_t msch_sem_hdl;
// buffer used to read scsi information when mounted, largest response data currently is inquiry
-CFG_TUSB_MEM_SECTION ATTR_ALIGNED(4) STATIC_VAR uint8_t msch_buffer[sizeof(scsi_inquiry_data_t)];
+CFG_TUSB_MEM_SECTION ATTR_ALIGNED(4) static uint8_t msch_buffer[sizeof(scsi_inquiry_resp_t)];
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -75,7 +76,7 @@ bool tuh_msc_is_mounted(uint8_t dev_addr)
bool tuh_msc_is_busy(uint8_t dev_addr)
{
return msch_data[dev_addr-1].is_initialized &&
- hcd_pipe_is_busy(msch_data[dev_addr-1].bulk_in);
+ hcd_edpt_busy(dev_addr, msch_data[dev_addr-1].ep_in);
}
uint8_t const* tuh_msc_get_vendor_name(uint8_t dev_addr)
@@ -109,23 +110,22 @@ static inline void msc_cbw_add_signature(msc_cbw_t *p_cbw, uint8_t lun)
p_cbw->lun = lun;
}
-static tusb_error_t msch_command_xfer(msch_interface_t * p_msch, void* p_buffer) ATTR_WARN_UNUSED_RESULT;
-static tusb_error_t msch_command_xfer(msch_interface_t * p_msch, void* p_buffer)
+static tusb_error_t msch_command_xfer(uint8_t dev_addr, msch_interface_t * p_msch, void* p_buffer)
{
if ( NULL != p_buffer)
{ // there is data phase
if (p_msch->cbw.dir & TUSB_DIR_IN_MASK)
{
- TU_ASSERT_ERR( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false) );
- TU_ASSERT_ERR( hcd_pipe_queue_xfer(p_msch->bulk_in , p_buffer, p_msch->cbw.xfer_bytes) );
+ TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
+ TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_in , p_buffer, p_msch->cbw.total_bytes), TUSB_ERROR_FAILED );
}else
{
- TU_ASSERT_ERR( hcd_pipe_queue_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t)) );
- TU_ASSERT_ERR( hcd_pipe_xfer(p_msch->bulk_out , p_buffer, p_msch->cbw.xfer_bytes, false) );
+ TU_ASSERT( hcd_pipe_queue_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t)), TUSB_ERROR_FAILED );
+ TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out , p_buffer, p_msch->cbw.total_bytes, false), TUSB_ERROR_FAILED );
}
}
- TU_ASSERT_ERR( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) &p_msch->csw, sizeof(msc_csw_t), true) );
+ TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) &p_msch->csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED);
return TUSB_ERROR_NONE;
}
@@ -136,7 +136,7 @@ tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
//------------- Command Block Wrapper -------------//
msc_cbw_add_signature(&p_msch->cbw, lun);
- p_msch->cbw.xfer_bytes = sizeof(scsi_inquiry_data_t);
+ p_msch->cbw.total_bytes = sizeof(scsi_inquiry_resp_t);
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
p_msch->cbw.cmd_len = sizeof(scsi_inquiry_t);
@@ -144,12 +144,12 @@ tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, uint8_t lun, uint8_t *p_data)
scsi_inquiry_t cmd_inquiry =
{
.cmd_code = SCSI_CMD_INQUIRY,
- .alloc_length = sizeof(scsi_inquiry_data_t)
+ .alloc_length = sizeof(scsi_inquiry_resp_t)
};
memcpy(p_msch->cbw.command, &cmd_inquiry, p_msch->cbw.cmd_len);
- TU_ASSERT_ERR ( msch_command_xfer(p_msch, p_data) );
+ TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
return TUSB_ERROR_NONE;
}
@@ -160,7 +160,7 @@ tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, uint8_t lun, uint8_t *p
//------------- Command Block Wrapper -------------//
msc_cbw_add_signature(&p_msch->cbw, lun);
- p_msch->cbw.xfer_bytes = sizeof(scsi_read_capacity10_data_t);
+ p_msch->cbw.total_bytes = sizeof(scsi_read_capacity10_resp_t);
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
p_msch->cbw.cmd_len = sizeof(scsi_read_capacity10_t);
@@ -174,7 +174,7 @@ tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, uint8_t lun, uint8_t *p
memcpy(p_msch->cbw.command, &cmd_read_capacity10, p_msch->cbw.cmd_len);
- TU_ASSERT_ERR ( msch_command_xfer(p_msch, p_data) );
+ TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
return TUSB_ERROR_NONE;
}
@@ -186,7 +186,7 @@ tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_dat
msch_interface_t* p_msch = &msch_data[dev_addr-1];
//------------- Command Block Wrapper -------------//
- p_msch->cbw.xfer_bytes = 18;
+ p_msch->cbw.total_bytes = 18;
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
p_msch->cbw.cmd_len = sizeof(scsi_request_sense_t);
@@ -199,7 +199,7 @@ tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_dat
memcpy(p_msch->cbw.command, &cmd_request_sense, p_msch->cbw.cmd_len);
- TU_ASSERT_ERR ( msch_command_xfer(p_msch, p_data) );
+ TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_data) );
return TUSB_ERROR_NONE;
}
@@ -211,7 +211,7 @@ tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t *
//------------- Command Block Wrapper -------------//
msc_cbw_add_signature(&p_msch->cbw, lun);
- p_msch->cbw.xfer_bytes = 0; // Number of bytes
+ p_msch->cbw.total_bytes = 0; // Number of bytes
p_msch->cbw.dir = TUSB_DIR_OUT;
p_msch->cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
@@ -225,8 +225,8 @@ tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t *
memcpy(p_msch->cbw.command, &cmd_test_unit_ready, p_msch->cbw.cmd_len);
// TODO MSCH refractor test uinit ready
- TU_ASSERT_ERR( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false) );
- TU_ASSERT_ERR( hcd_pipe_xfer(p_msch->bulk_in , (uint8_t*) p_csw, sizeof(msc_csw_t), true) );
+ TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cbw_t), false), TUSB_ERROR_FAILED );
+ TU_ASSERT( hcd_pipe_xfer(dev_addr, p_msch->ep_in , (uint8_t*) p_csw, sizeof(msc_csw_t), true), TUSB_ERROR_FAILED );
return TUSB_ERROR_NONE;
}
@@ -238,7 +238,7 @@ tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uin
//------------- Command Block Wrapper -------------//
msc_cbw_add_signature(&p_msch->cbw, lun);
- p_msch->cbw.xfer_bytes = p_msch->block_size*block_count; // Number of bytes
+ p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
p_msch->cbw.dir = TUSB_DIR_IN_MASK;
p_msch->cbw.cmd_len = sizeof(scsi_read10_t);
@@ -247,12 +247,12 @@ tusb_error_t tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uin
{
.cmd_code = SCSI_CMD_READ_10,
.lba = __n2be(lba),
- .block_count = u16_le2be(block_count)
+ .block_count = tu_u16_le2be(block_count)
};
memcpy(p_msch->cbw.command, &cmd_read10, p_msch->cbw.cmd_len);
- TU_ASSERT_ERR ( msch_command_xfer(p_msch, p_buffer));
+ TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, p_buffer));
return TUSB_ERROR_NONE;
}
@@ -264,7 +264,7 @@ tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffe
//------------- Command Block Wrapper -------------//
msc_cbw_add_signature(&p_msch->cbw, lun);
- p_msch->cbw.xfer_bytes = p_msch->block_size*block_count; // Number of bytes
+ p_msch->cbw.total_bytes = p_msch->block_size*block_count; // Number of bytes
p_msch->cbw.dir = TUSB_DIR_OUT;
p_msch->cbw.cmd_len = sizeof(scsi_write10_t);
@@ -273,12 +273,12 @@ tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffe
{
.cmd_code = SCSI_CMD_WRITE_10,
.lba = __n2be(lba),
- .block_count = u16_le2be(block_count)
+ .block_count = tu_u16_le2be(block_count)
};
memcpy(p_msch->cbw.command, &cmd_write10, p_msch->cbw.cmd_len);
- TU_ASSERT_ERR ( msch_command_xfer(p_msch, (void*) p_buffer));
+ TU_ASSERT_ERR ( msch_command_xfer(dev_addr, p_msch, (void*) p_buffer));
return TUSB_ERROR_NONE;
}
@@ -289,133 +289,130 @@ tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffe
void msch_init(void)
{
tu_memclr(msch_data, sizeof(msch_interface_t)*CFG_TUSB_HOST_DEVICE_MAX);
- msch_sem_hdl = osal_semaphore_create(1, 0);
+ msch_sem_hdl = osal_semaphore_create(&msch_sem_def);
}
-tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
+bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length)
{
- tusb_error_t error;
+ TU_VERIFY (MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass &&
+ MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol);
- OSAL_SUBTASK_BEGIN
-
- if (! ( MSC_SUBCLASS_SCSI == p_interface_desc->bInterfaceSubClass &&
- MSC_PROTOCOL_BOT == p_interface_desc->bInterfaceProtocol ) )
- {
- return TUSB_ERROR_MSC_UNSUPPORTED_PROTOCOL;
- }
+ msch_interface_t* p_msc = &msch_data[dev_addr-1];
//------------- Open Data Pipe -------------//
- tusb_desc_endpoint_t const *p_endpoint;
- p_endpoint = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_interface_desc );
+ tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
for(uint32_t i=0; i<2; i++)
{
- STASK_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType);
- STASK_ASSERT(TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer);
+ TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType);
+ TU_ASSERT(TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
- pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
- &msch_data[dev_addr-1].bulk_in : &msch_data[dev_addr-1].bulk_out;
+ TU_ASSERT(hcd_edpt_open(rhport, dev_addr, ep_desc));
- (*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_MSC);
- STASK_ASSERT( pipehandle_is_valid(*p_pipe_hdl) );
+ if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
+ {
+ p_msc->ep_in = ep_desc->bEndpointAddress;
+ }else
+ {
+ p_msc->ep_out = ep_desc->bEndpointAddress;
+ }
- p_endpoint = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_endpoint );
+ ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc);
}
- msch_data[dev_addr-1].interface_number = p_interface_desc->bInterfaceNumber;
+ p_msc->itf_numr = itf_desc->bInterfaceNumber;
(*p_length) += sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
-
//------------- Get Max Lun -------------//
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE),
- MSC_REQ_GET_MAX_LUN, 0, msch_data[dev_addr-1].interface_number,
- 1, msch_buffer ),
- error
- );
-
- STASK_ASSERT( TUSB_ERROR_NONE == error /* && TODO STALL means zero */);
- msch_data[dev_addr-1].max_lun = msch_buffer[0];
+ tusb_control_request_t request = {
+ .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_IN },
+ .bRequest = MSC_REQ_GET_MAX_LUN,
+ .wValue = 0,
+ .wIndex = p_msc->itf_numr,
+ .wLength = 1
+ };
+ // TODO STALL means zero
+ TU_ASSERT( usbh_control_xfer( dev_addr, &request, msch_buffer ) );
+ p_msc->max_lun = msch_buffer[0];
#if 0
//------------- Reset -------------//
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_INTERFACE),
- MSC_REQ_RESET, 0, msch_data[dev_addr-1].interface_number,
- 0, NULL ),
- error
- );
+ request = (tusb_control_request_t) {
+ .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_INTERFACE, .type = TUSB_REQ_TYPE_CLASS, .direction = TUSB_DIR_OUT },
+ .bRequest = MSC_REQ_RESET,
+ .wValue = 0,
+ .wIndex = p_msc->itf_numr,
+ .wLength = 0
+ };
+ TU_ASSERT( usbh_control_xfer( dev_addr, &request, NULL ) );
#endif
enum { SCSI_XFER_TIMEOUT = 2000 };
//------------- SCSI Inquiry -------------//
tusbh_msc_inquiry(dev_addr, 0, msch_buffer);
- osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error);
- STASK_ASSERT_ERR(error);
+ TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) );
- memcpy(msch_data[dev_addr-1].vendor_id , ((scsi_inquiry_data_t*) msch_buffer)->vendor_id , 8);
- memcpy(msch_data[dev_addr-1].product_id, ((scsi_inquiry_data_t*) msch_buffer)->product_id, 16);
+ memcpy(p_msc->vendor_id , ((scsi_inquiry_resp_t*) msch_buffer)->vendor_id , 8);
+ memcpy(p_msc->product_id, ((scsi_inquiry_resp_t*) msch_buffer)->product_id, 16);
//------------- SCSI Read Capacity 10 -------------//
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
- osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error);
- STASK_ASSERT_ERR(error);
+ TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
// NOTE: my toshiba thumb-drive stall the first Read Capacity and require the sequence
// Read Capacity --> Stalled --> Clear Stall --> Request Sense --> Read Capacity (2) to work
- if ( hcd_pipe_is_stalled(msch_data[dev_addr-1].bulk_in) )
- { // clear stall TODO abstract clear stall function
- STASK_INVOKE(
- usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_STANDARD, TUSB_REQ_RCPT_ENDPOINT),
- TUSB_REQ_CLEAR_FEATURE, 0, hcd_pipe_get_endpoint_addr(msch_data[dev_addr-1].bulk_in),
- 0, NULL ),
- error
- );
- STASK_ASSERT_ERR(error);
+ if ( hcd_edpt_stalled(dev_addr, p_msc->ep_in) )
+ {
+ // clear stall TODO abstract clear stall function
+ request = (tusb_control_request_t) {
+ .bmRequestType_bit = { .recipient = TUSB_REQ_RCPT_ENDPOINT, .type = TUSB_REQ_TYPE_STANDARD, .direction = TUSB_DIR_OUT },
+ .bRequest = TUSB_REQ_CLEAR_FEATURE,
+ .wValue = 0,
+ .wIndex = p_msc->ep_in,
+ .wLength = 0
+ };
- hcd_pipe_clear_stall(msch_data[dev_addr-1].bulk_in);
- osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); // wait for SCSI status
- STASK_ASSERT_ERR(error);
+ TU_ASSERT(usbh_control_xfer( dev_addr, &request, NULL ));
+
+ hcd_edpt_clear_stall(dev_addr, p_msc->ep_in);
+ TU_ASSERT( osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT) ); // wait for SCSI status
//------------- SCSI Request Sense -------------//
(void) tuh_msc_request_sense(dev_addr, 0, msch_buffer);
- osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error);
- STASK_ASSERT_ERR(error);
+ TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
//------------- Re-read SCSI Read Capactity -------------//
tusbh_msc_read_capacity10(dev_addr, 0, msch_buffer);
- osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error);
- STASK_ASSERT_ERR(error);
+ TU_ASSERT(osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT));
}
- msch_data[dev_addr-1].last_lba = __be2n( ((scsi_read_capacity10_data_t*)msch_buffer)->last_lba );
- msch_data[dev_addr-1].block_size = (uint16_t) __be2n( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size );
+ p_msc->last_lba = __be2n( ((scsi_read_capacity10_resp_t*)msch_buffer)->last_lba );
+ p_msc->block_size = (uint16_t) __be2n( ((scsi_read_capacity10_resp_t*)msch_buffer)->block_size );
+
+ p_msc->is_initialized = true;
- msch_data[dev_addr-1].is_initialized = true;
tuh_msc_mounted_cb(dev_addr);
- OSAL_SUBTASK_END
+ return true;
}
-void msch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)
+void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
{
- if ( pipehandle_is_equal(pipe_hdl, msch_data[pipe_hdl.dev_addr-1].bulk_in) )
+ msch_interface_t* p_msc = &msch_data[dev_addr-1];
+ if ( ep_addr == p_msc->ep_in )
{
- if (msch_data[pipe_hdl.dev_addr-1].is_initialized)
+ if (p_msc->is_initialized)
{
- tuh_msc_isr(pipe_hdl.dev_addr, event, xferred_bytes);
+ tuh_msc_isr(dev_addr, event, xferred_bytes);
}else
{ // still initializing under open subtask
- osal_semaphore_post(msch_sem_hdl);
+ osal_semaphore_post(msch_sem_hdl, true);
}
}
}
void msch_close(uint8_t dev_addr)
{
- (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_in);
- (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_out);
-
tu_memclr(&msch_data[dev_addr-1], sizeof(msch_interface_t));
osal_semaphore_reset(msch_sem_hdl);
diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h
index a408bbeaf..9035cb845 100644
--- a/src/class/msc/msc_host.h
+++ b/src/class/msc/msc_host.h
@@ -60,7 +60,7 @@
* \retval true if device supports
* \retval false if device does not support or is not mounted
*/
-bool tuh_msc_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_msc_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
@@ -70,7 +70,7 @@ bool tuh_msc_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RE
* can be scheduled. User needs to make sure the corresponding interface is mounted (by \ref tuh_msc_is_mounted)
* before calling this function
*/
-bool tuh_msc_is_busy(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT;
+bool tuh_msc_is_busy(uint8_t dev_addr);
/** \brief Get SCSI vendor's name of MassStorage device
* \param[in] dev_addr device address
@@ -113,7 +113,7 @@ tusb_error_t tuh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint32
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
*/
-tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT;
+tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count);
/** \brief Perform SCSI WRITE 10 command to write data to MassStorage device
* \param[in] dev_addr device address
@@ -127,7 +127,7 @@ tusb_error_t tuh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uin
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
*/
-tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT;
+tusb_error_t tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * p_buffer, uint32_t lba, uint16_t block_count);
/** \brief Perform SCSI REQUEST SENSE command, used to retrieve sense data from MassStorage device
* \param[in] dev_addr device address
@@ -150,11 +150,11 @@ tusb_error_t tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_dat
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the interface's callback function
*/
-tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw) ATTR_WARN_UNUSED_RESULT; // TODO to be refractor
+tusb_error_t tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_csw_t * p_csw); // TODO to be refractor
//tusb_error_t tusbh_msc_scsi_send(uint8_t dev_addr, uint8_t lun, bool is_direction_in,
// uint8_t const * p_command, uint8_t cmd_len,
-// uint8_t * p_response, uint32_t resp_len) ATTR_WARN_UNUSED_RESULT;
+// uint8_t * p_response, uint32_t resp_len);
//------------- Application Callback -------------//
/** \brief Callback function that will be invoked when a device with MassStorage interface is mounted
@@ -187,9 +187,11 @@ void tuh_msc_isr(uint8_t dev_addr, xfer_result_t event, uint32_t xferred_bytes);
//--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_
-typedef struct {
- pipe_handle_t bulk_in, bulk_out;
- uint8_t interface_number;
+typedef struct
+{
+ uint8_t itf_numr;
+ uint8_t ep_in;
+ uint8_t ep_out;
uint8_t max_lun;
uint16_t block_size;
@@ -203,10 +205,11 @@ typedef struct {
msc_csw_t csw;
}msch_interface_t;
-void msch_init(void);
-tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
-void msch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
-void msch_close(uint8_t dev_addr);
+void msch_init(void);
+bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
+void msch_isr(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
+void msch_close(uint8_t dev_addr);
+
#endif
#ifdef __cplusplus