1 /**************************************************************************/ 2 /* */ 3 /* Copyright (c) Microsoft Corporation. All rights reserved. */ 4 /* */ 5 /* This software is licensed under the Microsoft Software License */ 6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */ 7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ 8 /* and in the root directory of this software. */ 9 /* */ 10 /**************************************************************************/ 11 12 /**************************************************************************/ 13 /** */ 14 /** USBX Component */ 15 /** */ 16 /** Device Video 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_video.h" 28 #include "ux_device_stack.h" 29 30 31 /**************************************************************************/ 32 /* */ 33 /* FUNCTION RELEASE */ 34 /* */ 35 /* _ux_device_class_video_activate PORTABLE C */ 36 /* 6.2.0 */ 37 /* AUTHOR */ 38 /* */ 39 /* Chaoqiong Xiao, Microsoft Corporation */ 40 /* */ 41 /* DESCRIPTION */ 42 /* */ 43 /* This function initializes the USB Video device. */ 44 /* */ 45 /* INPUT */ 46 /* */ 47 /* command Pointer to video command */ 48 /* */ 49 /* OUTPUT */ 50 /* */ 51 /* Completion Status */ 52 /* */ 53 /* CALLS */ 54 /* */ 55 /* _ux_system_error_handler System error trap */ 56 /* */ 57 /* CALLED BY */ 58 /* */ 59 /* Device Video Class */ 60 /* */ 61 /* RELEASE HISTORY */ 62 /* */ 63 /* DATE NAME DESCRIPTION */ 64 /* */ 65 /* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */ 66 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */ 67 /* fixed parameter/variable */ 68 /* names conflict C++ keyword, */ 69 /* resulting in version 6.1.12 */ 70 /* 10-31-2022 Chaoqiong Xiao Modified comment(s), */ 71 /* added standalone support, */ 72 /* resulting in version 6.2.0 */ 73 /* */ 74 /**************************************************************************/ _ux_device_class_video_activate(UX_SLAVE_CLASS_COMMAND * command)75UINT _ux_device_class_video_activate(UX_SLAVE_CLASS_COMMAND *command) 76 { 77 78 UX_SLAVE_DEVICE *device; 79 UX_SLAVE_INTERFACE *interface_ptr; 80 UX_SLAVE_CLASS *class_ptr; 81 UX_SLAVE_INTERFACE *control_interface; 82 UX_SLAVE_INTERFACE *stream_interface; 83 UX_DEVICE_CLASS_VIDEO *video; 84 UX_DEVICE_CLASS_VIDEO_STREAM *stream; 85 ULONG stream_index; 86 87 88 /* Get the class container. */ 89 class_ptr = command -> ux_slave_class_command_class_ptr; 90 91 /* Get the class instance in the container. */ 92 video = (UX_DEVICE_CLASS_VIDEO *) class_ptr -> ux_slave_class_instance; 93 94 /* Get the interface that owns this instance. */ 95 interface_ptr = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface; 96 97 /* Get the device instance. */ 98 device = &_ux_system_slave -> ux_system_slave_device; 99 video -> ux_device_class_video_device = device; 100 101 /* We only support video interface here. */ 102 if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceClass != UX_DEVICE_CLASS_VIDEO_CLASS) 103 return(UX_NO_CLASS_MATCH); 104 105 /* It's control interface? */ 106 if (interface_ptr -> ux_slave_interface_descriptor.bInterfaceSubClass == UX_DEVICE_CLASS_VIDEO_SUBCLASS_CONTROL) 107 { 108 109 /* Store the interface in the class instance. */ 110 video -> ux_device_class_video_interface = interface_ptr; 111 112 /* Store the class instance into the interface. */ 113 interface_ptr -> ux_slave_interface_class_instance = (VOID *)video; 114 } 115 else 116 { 117 118 /* It's streaming interface. */ 119 stream_interface = interface_ptr; 120 121 /* Separate driver for each interface (IAD not used)? */ 122 if (video -> ux_device_class_video_interface == UX_NULL) 123 { 124 125 /* Always use just 1 stream for 1 interface. */ 126 stream_index = 0; 127 } 128 129 /* Re-use the same driver (IAD used)? */ 130 else 131 { 132 133 /* Re-use saved control interface. */ 134 control_interface = video -> ux_device_class_video_interface; 135 136 /* Calculate stream index. */ 137 stream_index = stream_interface -> ux_slave_interface_descriptor.bInterfaceNumber; 138 stream_index -= control_interface -> ux_slave_interface_descriptor.bInterfaceNumber; 139 stream_index --; 140 141 } 142 143 /* Sanity check. */ 144 if (stream_index >= video -> ux_device_class_video_streams_nb) 145 { 146 147 /* Error trap! */ 148 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT); 149 return(UX_MEMORY_INSUFFICIENT); 150 } 151 152 /* Locate stream based on interface number. */ 153 stream = &video -> ux_device_class_video_streams[stream_index]; 154 155 /* Store the interface for the stream. */ 156 stream -> ux_device_class_video_stream_interface = stream_interface; 157 158 /* Store the class instance into the interface. */ 159 stream_interface -> ux_slave_interface_class_instance = (VOID *)video; 160 161 #if defined(UX_DEVICE_STANDALONE) 162 163 /* Reset stream task state. */ 164 stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET; 165 stream -> ux_device_class_video_stream_task_status = UX_SUCCESS; 166 #endif 167 168 } 169 170 /* If there is a activate function call it. */ 171 if (video -> ux_device_class_video_callbacks.ux_slave_class_video_instance_activate != UX_NULL) 172 { 173 174 /* Invoke the application. */ 175 video -> ux_device_class_video_callbacks.ux_slave_class_video_instance_activate(video); 176 } 177 178 /* Return completion status. */ 179 return(UX_SUCCESS); 180 } 181