1 /*************************************************************************** 2 * Copyright (c) 2024 Microsoft Corporation 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the MIT License which is available at 6 * https://opensource.org/licenses/MIT. 7 * 8 * SPDX-License-Identifier: MIT 9 **************************************************************************/ 10 11 /**************************************************************************/ 12 /**************************************************************************/ 13 /** */ 14 /** USBX Component */ 15 /** */ 16 /** Device CDC Class */ 17 /** */ 18 /**************************************************************************/ 19 /**************************************************************************/ 20 21 #define UX_SOURCE_CODE 22 23 24 /* Include necessary system files. */ 25 26 #include "ux_api.h" 27 #include "ux_device_class_cdc_acm.h" 28 #include "ux_device_stack.h" 29 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _ux_device_class_cdc_acm_control_request PORTABLE C */ 36 /* 6.1.12 */ 37 /* AUTHOR */ 38 /* */ 39 /* Chaoqiong Xiao, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function manages the based sent by the host on the control */ 44 /* endpoints with a CLASS or VENDOR SPECIFIC type. */ 45 /* */ 46 /* INPUT */ 47 /* */ 48 /* cdc_acm Pointer to cdc_acm class */ 49 /* */ 50 /* OUTPUT */ 51 /* */ 52 /* None */ 53 /* */ 54 /* CALLS */ 55 /* */ 56 /* _ux_device_stack_transfer_request Transfer request */ 57 /* */ 58 /* CALLED BY */ 59 /* */ 60 /* CDC Class */ 61 /* */ 62 /* RELEASE HISTORY */ 63 /* */ 64 /* DATE NAME DESCRIPTION */ 65 /* */ 66 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ 67 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ 68 /* resulting in version 6.1 */ 69 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ 70 /* fixed parameter/variable */ 71 /* names conflict C++ keyword, */ 72 /* resulting in version 6.1.12 */ 73 /* */ 74 /**************************************************************************/ _ux_device_class_cdc_acm_control_request(UX_SLAVE_CLASS_COMMAND * command)75UINT _ux_device_class_cdc_acm_control_request(UX_SLAVE_CLASS_COMMAND *command) 76 { 77 UX_SLAVE_CLASS_CDC_ACM *cdc_acm; 78 UX_SLAVE_CLASS *class_ptr; 79 UX_SLAVE_TRANSFER *transfer_request; 80 UX_SLAVE_DEVICE *device; 81 ULONG request; 82 ULONG value; 83 ULONG request_length; 84 ULONG transmit_length; 85 86 /* Get the class container. */ 87 class_ptr = command -> ux_slave_class_command_class_ptr; 88 89 /* Get the class instance in the container. */ 90 cdc_acm = (UX_SLAVE_CLASS_CDC_ACM *) class_ptr -> ux_slave_class_instance; 91 92 /* Get the pointer to the device. */ 93 device = &_ux_system_slave -> ux_system_slave_device; 94 95 /* Get the pointer to the transfer request associated with the control endpoint. */ 96 transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request; 97 98 /* Extract all necessary fields of the request. */ 99 request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST); 100 101 /* Extract all necessary fields of the value. */ 102 value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE); 103 104 /* Pickup the request length. */ 105 request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); 106 107 transmit_length = request_length ; 108 109 /* Here we proceed only the standard request we know of at the device level. */ 110 switch (request) 111 { 112 113 case UX_SLAVE_CLASS_CDC_ACM_SET_CONTROL_LINE_STATE: 114 115 /* Reset current line state values. */ 116 cdc_acm -> ux_slave_class_cdc_acm_data_dtr_state = 0; 117 cdc_acm -> ux_slave_class_cdc_acm_data_rts_state = 0; 118 119 /* Get the line state parameters from the host. DTR signal. */ 120 if (value & UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_DTR) 121 cdc_acm -> ux_slave_class_cdc_acm_data_dtr_state = UX_TRUE; 122 123 /* Get the line state parameters from the host. RTS signal. */ 124 if (value & UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_RTS) 125 cdc_acm -> ux_slave_class_cdc_acm_data_rts_state = UX_TRUE; 126 127 /* If there is a parameter change function call it. */ 128 if (cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change != UX_NULL) 129 { 130 131 /* Invoke the application. */ 132 cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change(cdc_acm); 133 } 134 135 break ; 136 137 case UX_SLAVE_CLASS_CDC_ACM_GET_LINE_CODING: 138 139 /* Setup the length appropriately. */ 140 if (request_length > UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_RESPONSE_SIZE) 141 transmit_length = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_RESPONSE_SIZE; 142 143 /* Send the line coding default parameters back to the host. */ 144 _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_BAUDRATE_STRUCT, 145 cdc_acm -> ux_slave_class_cdc_acm_baudrate); 146 *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_STRUCT) = cdc_acm -> ux_slave_class_cdc_acm_stop_bit; 147 *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY_STRUCT) = cdc_acm -> ux_slave_class_cdc_acm_parity; 148 *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_DATA_BIT_STRUCT) = cdc_acm -> ux_slave_class_cdc_acm_data_bit; 149 150 /* Set the phase of the transfer to data out. */ 151 transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT; 152 153 /* Perform the data transfer. */ 154 _ux_device_stack_transfer_request(transfer_request, transmit_length, request_length); 155 break; 156 157 case UX_SLAVE_CLASS_CDC_ACM_SET_LINE_CODING: 158 159 /* Get the line coding parameters from the host. */ 160 cdc_acm -> ux_slave_class_cdc_acm_baudrate = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_BAUDRATE_STRUCT); 161 cdc_acm -> ux_slave_class_cdc_acm_stop_bit = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_STRUCT); 162 cdc_acm -> ux_slave_class_cdc_acm_parity = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY_STRUCT); 163 cdc_acm -> ux_slave_class_cdc_acm_data_bit = *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_DATA_BIT_STRUCT); 164 165 /* If there is a parameter change function call it. */ 166 if (cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change != UX_NULL) 167 { 168 169 /* Invoke the application. */ 170 cdc_acm -> ux_slave_class_cdc_acm_parameter.ux_slave_class_cdc_acm_parameter_change(cdc_acm); 171 } 172 173 break ; 174 175 default: 176 177 /* Unknown function. It's not handled. */ 178 return(UX_ERROR); 179 } 180 181 /* It's handled. */ 182 return(UX_SUCCESS); 183 } 184 185