| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     @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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-12 13:23:52 +07:00
										 |  |  | #if (MODE_DEVICE_SUPPORTED && CFG_TUD_CDC)
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define _TINY_USB_SOURCE_FILE_
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							|  |  |  | // INCLUDE
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							| 
									
										
										
										
											2018-03-22 14:15:16 +07:00
										 |  |  | #include "common/tusb_common.h"
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | #include "cdc_device.h"
 | 
					
						
							| 
									
										
										
										
											2018-03-22 14:15:16 +07:00
										 |  |  | #include "device/usbd_pvt.h"
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							|  |  |  | // MACRO CONSTANT TYPEDEF
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							| 
									
										
										
										
											2018-04-10 14:31:11 +07:00
										 |  |  | CFG_TUSB_ATTR_USBRAM STATIC_VAR cdc_line_coding_t cdcd_line_coding[CONTROLLER_DEVICE_NUMBER]; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   uint8_t interface_number; | 
					
						
							|  |  |  |   cdc_acm_capability_t acm_capability; | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Bit 0:  DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
 | 
					
						
							|  |  |  |   uint8_t line_state; | 
					
						
							| 
									
										
										
										
											2018-03-22 15:55:35 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   uint8_t ep_notif; | 
					
						
							|  |  |  |   uint8_t ep_in; | 
					
						
							|  |  |  |   uint8_t ep_out; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | }cdcd_data_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | // TODO multiple rhport
 | 
					
						
							| 
									
										
										
										
											2018-04-12 13:14:59 +07:00
										 |  |  | #if CFG_TUSB_MCU == OPT_MCU_NRF5X
 | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  | // FIXME nrf52 OUT bug ( Controller ACK data even we didn't prepare transfer )
 | 
					
						
							| 
									
										
										
										
											2018-04-14 14:05:07 +07:00
										 |  |  | CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_rx_buf[600]; | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  | #else
 | 
					
						
							|  |  |  | CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_rx_buf[64]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_tx_buf[64]; | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | FIFO_DEF(_rx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, true); | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  | FIFO_DEF(_tx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, false); | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | //--------------------------------------------------------------------+
 | 
					
						
							|  |  |  | // INTERNAL OBJECT & FUNCTION DECLARATION
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							| 
									
										
										
										
											2014-04-17 18:02:51 +07:00
										 |  |  | STATIC_VAR cdcd_data_t cdcd_data[CONTROLLER_DEVICE_NUMBER]; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | //--------------------------------------------------------------------+
 | 
					
						
							|  |  |  | // APPLICATION API
 | 
					
						
							|  |  |  | //--------------------------------------------------------------------+
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | bool tud_n_cdc_connected(uint8_t rhport) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  |   // Either RTS or DTR active considered as connected
 | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  |   return (cdcd_data[rhport].line_state != 0); | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | uint32_t tud_n_cdc_available(uint8_t rhport) | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | { | 
					
						
							|  |  |  |   return fifo_count(&_rx_ff); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-09 18:48:38 +07:00
										 |  |  | int8_t tud_n_cdc_read_char(uint8_t rhport) | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-04-09 18:48:38 +07:00
										 |  |  |   int8_t ch; | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  |   return fifo_read(&_rx_ff, &ch) ? ch : (-1); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | uint32_t tud_n_cdc_read(uint8_t rhport, void* buffer, uint32_t bufsize) | 
					
						
							| 
									
										
										
										
											2013-11-08 14:46:48 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  |   return fifo_read_n(&_rx_ff, buffer, bufsize); | 
					
						
							| 
									
										
										
										
											2013-11-08 14:46:48 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | uint32_t tud_n_cdc_write_char(uint8_t rhport, char ch) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  |   return fifo_write(&_tx_ff, &ch) ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | uint32_t tud_n_cdc_write(uint8_t rhport, void const* buffer, uint32_t bufsize) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  |   return fifo_write_n(&_tx_ff, buffer, bufsize); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  | bool tud_n_cdc_flush (uint8_t rhport) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   uint8_t  edpt = cdcd_data[rhport].ep_in; | 
					
						
							|  |  |  |   VERIFY( !dcd_edpt_busy(rhport, edpt) ); // skip if previous transfer not complete
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   uint16_t count = fifo_read_n(&_tx_ff, _tmp_tx_buf, sizeof(_tmp_tx_buf)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   VERIFY( tud_n_cdc_connected(rhport) ); // fifo is empty if not connected
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( count ) TU_ASSERT( dcd_edpt_xfer(rhport, edpt, _tmp_tx_buf, count) ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | //--------------------------------------------------------------------+
 | 
					
						
							| 
									
										
										
										
											2018-03-08 15:00:38 +07:00
										 |  |  | // USBD Driver API
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | //--------------------------------------------------------------------+
 | 
					
						
							|  |  |  | void cdcd_init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   memclr_(cdcd_data, sizeof(cdcd_data_t)*CONTROLLER_DEVICE_NUMBER); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // default line coding is : stop bit = 1, parity = none, data bits = 8
 | 
					
						
							|  |  |  |   memclr_(cdcd_line_coding, sizeof(cdc_line_coding_t)*CONTROLLER_DEVICE_NUMBER); | 
					
						
							| 
									
										
										
										
											2018-03-07 11:01:23 +07:00
										 |  |  |   for(uint8_t i=0; i<CONTROLLER_DEVICE_NUMBER; i++) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     cdcd_line_coding[i].bit_rate  = 115200; | 
					
						
							|  |  |  |     cdcd_line_coding[i].stop_bits = 0; | 
					
						
							|  |  |  |     cdcd_line_coding[i].parity    = 0; | 
					
						
							|  |  |  |     cdcd_line_coding[i].data_bits = 8; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:32:40 +07:00
										 |  |  | tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							|  |  |  |   if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ( !(is_in_range(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) || | 
					
						
							|  |  |  |          0xff == p_interface_desc->bInterfaceProtocol) ) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return TUSB_ERROR_CDC_UNSUPPORTED_PROTOCOL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   uint8_t const * p_desc = descriptor_next ( (uint8_t const *) p_interface_desc ); | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  |   cdcd_data_t * p_cdc = &cdcd_data[rhport]; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   //------------- Communication Interface -------------//
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:32:40 +07:00
										 |  |  |   (*p_length) = sizeof(tusb_desc_interface_t); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 19:44:08 +07:00
										 |  |  |   // Communication Functional Descriptors
 | 
					
						
							| 
									
										
										
										
											2018-03-11 21:16:51 +07:00
										 |  |  |   while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESCRIPTOR_OFFSET_TYPE] ) | 
					
						
							| 
									
										
										
										
											2018-04-10 19:44:08 +07:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |     if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) ) | 
					
						
							|  |  |  |     { // save ACM bmCapabilities
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:42:30 +07:00
										 |  |  |       p_cdc->acm_capability = ((cdc_desc_func_acm_t const *) p_desc)->bmCapabilities; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; | 
					
						
							|  |  |  |     p_desc = descriptor_next(p_desc); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 21:16:51 +07:00
										 |  |  |   if ( TUSB_DESC_ENDPOINT == p_desc[DESCRIPTOR_OFFSET_TYPE]) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   { // notification endpoint if any
 | 
					
						
							| 
									
										
										
										
											2018-03-28 13:47:58 +07:00
										 |  |  |     TU_ASSERT( dcd_edpt_open(rhport, (tusb_desc_endpoint_t const *) p_desc), TUSB_ERROR_DCD_OPEN_PIPE_FAILED); | 
					
						
							| 
									
										
										
										
											2018-03-11 15:20:27 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:32:40 +07:00
										 |  |  |     p_cdc->ep_notif = ((tusb_desc_endpoint_t const *) p_desc)->bEndpointAddress; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; | 
					
						
							|  |  |  |     p_desc = descriptor_next(p_desc); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //------------- Data Interface (if any) -------------//
 | 
					
						
							| 
									
										
										
										
											2018-03-11 21:16:51 +07:00
										 |  |  |   if ( (TUSB_DESC_INTERFACE == p_desc[DESCRIPTOR_OFFSET_TYPE]) && | 
					
						
							| 
									
										
										
										
											2018-03-23 12:32:40 +07:00
										 |  |  |        (TUSB_CLASS_CDC_DATA      == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) ) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   { | 
					
						
							|  |  |  |     (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; | 
					
						
							|  |  |  |     p_desc = descriptor_next(p_desc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // data endpoints expected to be in pairs
 | 
					
						
							|  |  |  |     for(uint32_t i=0; i<2; i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-03-23 12:32:40 +07:00
										 |  |  |       tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc; | 
					
						
							| 
									
										
										
										
											2018-03-11 21:16:51 +07:00
										 |  |  |       TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_DESCRIPTOR_CORRUPTED); | 
					
						
							| 
									
										
										
										
											2018-03-11 15:20:27 +07:00
										 |  |  |       TU_ASSERT(TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-28 13:47:58 +07:00
										 |  |  |       TU_ASSERT( dcd_edpt_open(rhport, p_endpoint), TUSB_ERROR_DCD_OPEN_PIPE_FAILED); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 20:20:59 +07:00
										 |  |  |       if ( p_endpoint->bEndpointAddress &  TUSB_DIR_IN_MASK ) | 
					
						
							| 
									
										
										
										
											2018-03-11 15:20:27 +07:00
										 |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-03-22 15:55:35 +07:00
										 |  |  |         p_cdc->ep_in = p_endpoint->bEndpointAddress; | 
					
						
							| 
									
										
										
										
											2018-03-11 15:20:27 +07:00
										 |  |  |       }else | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-03-22 15:55:35 +07:00
										 |  |  |         p_cdc->ep_out = p_endpoint->bEndpointAddress; | 
					
						
							| 
									
										
										
										
											2018-03-11 15:20:27 +07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       (*p_length) += p_desc[DESCRIPTOR_OFFSET_LENGTH]; | 
					
						
							|  |  |  |       p_desc = descriptor_next( p_desc ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   p_cdc->interface_number   = p_interface_desc->bInterfaceNumber; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  |   // Prepare for incoming data
 | 
					
						
							| 
									
										
										
										
											2018-03-28 13:47:58 +07:00
										 |  |  |   TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, _tmp_rx_buf, sizeof(_tmp_rx_buf)), TUSB_ERROR_DCD_EDPT_XFER); | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   return TUSB_ERROR_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | void cdcd_close(uint8_t rhport) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							|  |  |  |   // no need to close opened pipe, dcd bus reset will put controller's endpoints to default state
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  |   memclr_(&cdcd_data[rhport], sizeof(cdcd_data_t)); | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fifo_clear(&_rx_ff); | 
					
						
							|  |  |  |   fifo_clear(&_tx_ff); | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | tusb_error_t cdcd_control_request_st(uint8_t rhport, tusb_control_request_t const * p_request) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-15 13:22:28 +07:00
										 |  |  |   OSAL_SUBTASK_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   //------------- Class Specific Request -------------//
 | 
					
						
							| 
									
										
										
										
											2018-03-11 21:05:27 +07:00
										 |  |  |   if (p_request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-31 14:09:48 +07:00
										 |  |  |   if ( (CDC_REQUEST_GET_LINE_CODING == p_request->bRequest) || (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest) ) | 
					
						
							| 
									
										
										
										
											2018-03-15 13:22:28 +07:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-03-31 14:09:48 +07:00
										 |  |  |     uint16_t len = min16_of(sizeof(cdc_line_coding_t), p_request->wLength); | 
					
						
							|  |  |  |     usbd_control_xfer_st(rhport, p_request->bmRequestType_bit.direction, (uint8_t*) &cdcd_line_coding[rhport], len); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  |     // Invoke callback
 | 
					
						
							| 
									
										
										
										
											2018-04-10 19:44:08 +07:00
										 |  |  |     if (CDC_REQUEST_SET_LINE_CODING == p_request->bRequest) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(rhport, &cdcd_line_coding[rhport]); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-15 13:22:28 +07:00
										 |  |  |   } | 
					
						
							|  |  |  |   else if (CDC_REQUEST_SET_CONTROL_LINE_STATE == p_request->bRequest ) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-04-09 18:48:38 +07:00
										 |  |  |     // CDC PSTN v1.2 section 6.3.12
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  |     // Bit 0: Indicates if DTE is present or not.
 | 
					
						
							|  |  |  |     //        This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR (Data Terminal Ready)
 | 
					
						
							|  |  |  |     // Bit 1: Carrier control for half-duplex modems.
 | 
					
						
							|  |  |  |     //        This signal corresponds to V.24 signal 105 and RS-232 signal RTS (Request to Send)
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  |     cdcd_data_t * p_cdc = &cdcd_data[rhport]; | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  |     p_cdc->line_state = (uint8_t) p_request->wValue; | 
					
						
							| 
									
										
										
										
											2018-04-09 18:48:38 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     dcd_control_status(rhport, p_request->bmRequestType_bit.direction); // ACK control request
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Invoke callback
 | 
					
						
							|  |  |  |     if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(rhport, BIT_TEST_(p_request->wValue, 0), BIT_TEST_(p_request->wValue, 1)); | 
					
						
							| 
									
										
										
										
											2018-03-15 13:22:28 +07:00
										 |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-03-28 13:54:28 +07:00
										 |  |  |     dcd_control_stall(rhport); // stall unsupported request
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 13:22:28 +07:00
										 |  |  |   OSAL_SUBTASK_END | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, uint32_t xferred_bytes) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  |   cdcd_data_t const * p_cdc = &cdcd_data[rhport]; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-22 15:55:35 +07:00
										 |  |  |   if ( ep_addr == p_cdc->ep_out ) | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  |   { | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  |     fifo_write_n(&_rx_ff, _tmp_rx_buf, xferred_bytes); | 
					
						
							| 
									
										
										
										
											2013-12-01 13:53:36 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  |     // preparing for next
 | 
					
						
							| 
									
										
										
										
											2018-04-12 00:33:31 +07:00
										 |  |  |     TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, _tmp_rx_buf, sizeof(_tmp_rx_buf)), TUSB_ERROR_DCD_EDPT_XFER ); | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // fire callback
 | 
					
						
							| 
									
										
										
										
											2018-04-10 02:16:48 +07:00
										 |  |  |     if (tud_cdc_rx_cb) tud_cdc_rx_cb(rhport); | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-03-07 15:30:32 +07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-01 13:53:36 +07:00
										 |  |  |   return TUSB_ERROR_NONE; | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  | void cdcd_sof(uint8_t rhport) | 
					
						
							| 
									
										
										
										
											2018-03-20 18:33:06 +07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-04-10 19:44:08 +07:00
										 |  |  | #if CFG_TUD_CDC_FLUSH_ON_SOF
 | 
					
						
							| 
									
										
										
										
											2018-03-23 12:17:47 +07:00
										 |  |  |   tud_n_cdc_flush(rhport); | 
					
						
							| 
									
										
										
										
											2018-04-10 19:44:08 +07:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-03-08 14:38:06 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-08 12:03:32 +07:00
										 |  |  | #endif
 |