summaryrefslogtreecommitdiff
path: root/tinyusb/class
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-07-05 16:22:42 +0700
committerhathach <[email protected]>2013-07-05 16:22:42 +0700
commit355fd7e64867093ee5974056c7735a60dd0f64e7 (patch)
tree5928919e8df2a80437ecaa6bd6c67cffa06aafb1 /tinyusb/class
parente4ff63c6049929d400ae326509399704f0d3c01c (diff)
adding subclass RNDIS-CDC driver API
- implement init - close - xfer_isr - open adding waiting for notification after send rndis_initalize_msg
Diffstat (limited to 'tinyusb/class')
-rw-r--r--tinyusb/class/cdc.h2
-rw-r--r--tinyusb/class/cdc_host.c28
-rw-r--r--tinyusb/class/cdc_host.h4
-rw-r--r--tinyusb/class/cdc_rndis_host.c40
-rw-r--r--tinyusb/class/cdc_rndis_host.h15
5 files changed, 81 insertions, 8 deletions
diff --git a/tinyusb/class/cdc.h b/tinyusb/class/cdc.h
index b8a60bee2..faa6310fa 100644
--- a/tinyusb/class/cdc.h
+++ b/tinyusb/class/cdc.h
@@ -265,7 +265,7 @@ typedef ATTR_PACKED_STRUCT(struct) {
uint8_t bDataInterface;
}cdc_desc_func_call_management_t;
-typedef struct {
+typedef ATTR_PACKED_STRUCT(struct) {
uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
uint8_t support_send_break : 1; ///< Device supports the request Send_Break
diff --git a/tinyusb/class/cdc_host.c b/tinyusb/class/cdc_host.c
index 2b81b9ab6..ebe108658 100644
--- a/tinyusb/class/cdc_host.c
+++ b/tinyusb/class/cdc_host.c
@@ -125,6 +125,9 @@ tusb_error_t tusbh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t lengt
void cdch_init(void)
{
memclr_(cdch_data, sizeof(cdch_data_t)*TUSB_CFG_HOST_DEVICE_MAX);
+#if TUSB_CFG_HOST_CDC_RNDIS
+ rndish_init();
+#endif
}
tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length)
@@ -200,12 +203,19 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
#if TUSB_CFG_HOST_CDC_RNDIS // TODO move to rndis_host.c
//------------- RNDIS -------------//
- if ( 0xff == p_cdc->interface_protocol )
+ if ( 0xff == p_cdc->interface_protocol && pipehandle_is_valid(p_cdc->pipe_notification) )
{
+ p_cdc->is_rndis = true; // set as true at first
+
OSAL_SUBTASK_INVOKED_AND_WAIT( rndish_open_subtask(dev_addr, p_cdc), error );
+
+ if (TUSB_ERROR_NONE != error)
+ {
+ p_cdc->is_rndis = false;
+ }
}
- if ( !(0xff == p_cdc->interface_protocol && TUSB_ERROR_NONE == error) ) // device is not an rndis
+ if ( !p_cdc->is_rndis ) // device is not an rndis
#endif
// FIXME mounted class flag is not set yet
@@ -219,6 +229,14 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
void cdch_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes)
{
+ cdch_data_t *p_cdc = cdch_data + (pipe_hdl.dev_addr - 1);
+
+#if TUSB_CFG_HOST_CDC_RNDIS
+ if ( p_cdc->is_rndis )
+ {
+ rndish_xfer_isr(p_cdc, pipe_hdl, event, xferred_bytes);
+ } else
+#endif
if (tusbh_cdc_xfer_isr)
{
tusbh_cdc_xfer_isr( pipe_hdl.dev_addr, event, get_app_pipeid(pipe_hdl), xferred_bytes );
@@ -230,6 +248,12 @@ void cdch_close(uint8_t dev_addr)
tusb_error_t err1, err2, err3;
cdch_data_t * p_cdc = &cdch_data[dev_addr-1];
+#if TUSB_CFG_HOST_CDC_RNDIS
+ if (p_cdc->is_rndis)
+ {
+ rndish_close(dev_addr);
+ }
+#endif
if ( pipehandle_is_valid(p_cdc->pipe_notification) )
{
diff --git a/tinyusb/class/cdc_host.h b/tinyusb/class/cdc_host.h
index 1d852c4eb..d45b047ab 100644
--- a/tinyusb/class/cdc_host.h
+++ b/tinyusb/class/cdc_host.h
@@ -71,7 +71,6 @@ tusb_error_t tusbh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t lengt
//------------- CDC Application Callback -------------//
void tusbh_cdc_mounted_cb(uint8_t dev_addr) ATTR_WEAK;
void tusbh_cdc_unmounted_isr(uint8_t dev_addr) ATTR_WEAK;
-void tusbh_cdc_isr(uint8_t dev_addr, tusb_event_t event) ATTR_WEAK;
void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) ATTR_WEAK;
//------------- RNDIS Application Callback (overshadow CDC callbacks) -------------//
@@ -79,7 +78,7 @@ void tusbh_cdc_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_
void tusbh_cdc_rndis_mounted_cb(uint8_t dev_addr) ATTR_WEAK;
void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr) ATTR_WEAK;
-
+void tusbh_cdc_rndis_xfer_isr(uint8_t dev_addr, tusb_event_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes) ATTR_WEAK;
#endif
@@ -91,6 +90,7 @@ void tusbh_cdc_rndis_unmounted_isr(uint8_t dev_addr) ATTR_WEAK;
typedef struct {
uint8_t interface_number;
uint8_t interface_protocol;
+ bool is_rndis;
cdc_acm_capability_t acm_capability;
pipe_handle_t pipe_notification, pipe_out, pipe_in;
diff --git a/tinyusb/class/cdc_rndis_host.c b/tinyusb/class/cdc_rndis_host.c
index 585cf7d42..b01bebc7a 100644
--- a/tinyusb/class/cdc_rndis_host.c
+++ b/tinyusb/class/cdc_rndis_host.c
@@ -53,6 +53,7 @@
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
static uint8_t msg_notification[TUSB_CFG_HOST_DEVICE_MAX][8] TUSB_CFG_ATTR_USBRAM;
+STATIC_ rndish_data_t rndish_data[TUSB_CFG_HOST_DEVICE_MAX];
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -91,7 +92,26 @@ static tusb_error_t rndis_body_subtask(void)
OSAL_SUBTASK_END
}
+//--------------------------------------------------------------------+
+// RNDIS-CDC Driver API
+//--------------------------------------------------------------------+
+void rndish_init(void)
+{
+ memclr_(rndish_data, sizeof(rndish_data_t)*TUSB_CFG_HOST_DEVICE_MAX);
+
+ //------------- Task creation -------------//
+
+ //------------- semaphore creation for notificaiton pipe -------------//
+ for(uint8_t i=0; i<TUSB_CFG_HOST_DEVICE_MAX; i++)
+ {
+ rndish_data[i].sem_notification_hdl = osal_semaphore_create( OSAL_SEM_REF(rndish_data[i].semaphore_notification) );
+ }
+}
+void rndish_close(uint8_t dev_addr)
+{
+ osal_semaphore_reset( rndish_data[dev_addr-1].sem_notification_hdl );
+}
tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
{
@@ -109,6 +129,7 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
OSAL_SUBTASK_BEGIN
+ //------------- Send & Receive Initialize -------------//
OSAL_SUBTASK_INVOKED_AND_WAIT(
usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_INTERFACE),
SEND_ENCAPSULATED_COMMAND, 0, p_cdc->interface_number,
@@ -116,10 +137,15 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
error
);
- if ( TUSB_ERROR_NONE != error)
- {
+ if ( TUSB_ERROR_NONE != error )
+ SUBTASK_EXIT(error);
+
+ //------------- waiting for Response Available notification -------------//
+ (void) hcd_pipe_xfer(p_cdc->pipe_notification, msg_notification[dev_addr], 8, true);
+ osal_semaphore_wait(rndish_data[dev_addr-1].sem_notification_hdl, OSAL_TIMEOUT_NORMAL, &error);
+
+ if ( TUSB_ERROR_NONE != error )
SUBTASK_EXIT(error);
- }
if ( tusbh_cdc_rndis_mounted_cb )
{
@@ -129,4 +155,12 @@ tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc)
OSAL_SUBTASK_END
}
+void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes)
+{
+ if ( pipehandle_is_equal(pipe_hdl, p_cdc->pipe_notification) )
+ {
+ osal_semaphore_post( rndish_data[pipe_hdl.dev_addr-1].sem_notification_hdl );
+ }
+}
+
#endif
diff --git a/tinyusb/class/cdc_rndis_host.h b/tinyusb/class/cdc_rndis_host.h
index ce8e4bced..8a2bca397 100644
--- a/tinyusb/class/cdc_rndis_host.h
+++ b/tinyusb/class/cdc_rndis_host.h
@@ -54,7 +54,22 @@
extern "C" {
#endif
+//--------------------------------------------------------------------+
+// RNDIS-CDC Driver API
+//--------------------------------------------------------------------+
+#ifdef _TINY_USB_SOURCE_FILE_
+
+typedef struct {
+ OSAL_SEM_DEF(semaphore_notification);
+ osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe
+}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;
+void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes);
+void rndish_close(uint8_t dev_addr);
+
+#endif
#ifdef __cplusplus
}