1 #include <stdio.h>
2 #include "tx_api.h"
3 #include "ux_api.h"
4 #include "ux_system.h"
5 #include "ux_utility.h"
6 #include "ux_device_stack.h"
7 #include "ux_test.h"
8 #include "ux_host_class_printer.h"
9 #include "ux_device_class_dummy_printer.h"
10
11 #define PORT_START 1
12 #define PORT_STATUS_PORT_POWER_BIT 8
13
14 UCHAR _ux_device_class_printer_name[] = "_ux_device_class_printer";
15
_ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND * command)16 static VOID _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command)
17 {
18
19 UX_SLAVE_CLASS *printer_class = (UX_SLAVE_CLASS *)command->ux_slave_class_command_class_ptr;
20 UX_DEVICE_CLASS_PRINTER_PARAMS *printer_params = (UX_DEVICE_CLASS_PRINTER_PARAMS *)command->ux_slave_class_command_parameter;
21 UX_DEVICE_CLASS_PRINTER *printer;
22
23 printer = (UX_DEVICE_CLASS_PRINTER *) _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_DEVICE_CLASS_PRINTER));
24 UX_TEST_ASSERT(printer != UX_NULL);
25
26 printer_class->ux_slave_class_instance = printer;
27
28 /* Save parameters. */
29 _ux_utility_memory_copy(&printer->params, printer_params, sizeof(*printer_params));
30 }
31
_ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND * command)32 static VOID _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
33 {
34 UX_DEVICE_CLASS_PRINTER *printer = NULL;
35 UX_SLAVE_CLASS *class;
36
37
38 /* Get the class container. */
39 class = command -> ux_slave_class_command_class_ptr;
40
41 /* Get the class instance in the container. */
42 printer = (UX_DEVICE_CLASS_PRINTER *) class -> ux_slave_class_instance;
43
44 if (printer != UX_NULL)
45 _ux_utility_memory_free(printer);
46 return;
47 }
48
_ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND * command)49 static UINT _ux_device_class_printer_activate(UX_SLAVE_CLASS_COMMAND *command)
50 {
51
52 UX_SLAVE_CLASS *printer_class = command->ux_slave_class_command_class_ptr;
53 UX_SLAVE_INTERFACE *interface = (UX_SLAVE_INTERFACE *)command->ux_slave_class_command_interface;
54 UX_SLAVE_ENDPOINT *endpoint;
55 UX_DEVICE_CLASS_PRINTER *printer;
56 UINT i;
57
58 printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
59 interface -> ux_slave_interface_class_instance = (VOID *)printer;
60 printer -> interface = interface;
61
62 /* We need to get the bulk endpoints. */
63 printer -> bulk_in_endpoint = UX_NULL;
64 printer -> bulk_out_endpoint = UX_NULL;
65 endpoint = interface->ux_slave_interface_first_endpoint;
66 while (endpoint)
67 {
68 /* Is this bulk endpoint? */
69 if (endpoint->ux_slave_endpoint_descriptor.bmAttributes == UX_BULK_ENDPOINT)
70 {
71 /* Is this endpoint IN? */
72 if (endpoint->ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_IN)
73 {
74 printer -> bulk_in_endpoint = endpoint;
75 if (printer -> bulk_out_endpoint)
76 break;
77 }
78 else
79 {
80 printer -> bulk_out_endpoint = endpoint;
81 if (printer -> bulk_in_endpoint)
82 break;
83 }
84 }
85 endpoint = endpoint->ux_slave_endpoint_next_endpoint;
86 }
87 /* Endpoints must be available. */
88 if (printer->bulk_in_endpoint == UX_NULL || printer->bulk_out_endpoint == UX_NULL)
89 return(UX_ERROR);
90 /* Invoke activate callback. */
91 if (printer->params.instance_activate)
92 {
93 printer->params.instance_activate(printer);
94 }
95 return(UX_SUCCESS);
96 }
97
_ux_device_class_printer_deactivate(UX_SLAVE_CLASS_COMMAND * command)98 static VOID _ux_device_class_printer_deactivate(UX_SLAVE_CLASS_COMMAND *command)
99 {
100
101 UX_SLAVE_CLASS *printer_class = command->ux_slave_class_command_class_ptr;
102 UX_DEVICE_CLASS_PRINTER *printer;
103
104 printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
105 _ux_device_stack_transfer_all_request_abort(printer->bulk_in_endpoint, UX_TRANSFER_BUS_RESET);
106 _ux_device_stack_transfer_all_request_abort(printer->bulk_out_endpoint, UX_TRANSFER_BUS_RESET);
107 if (printer->params.instance_deactivate)
108 {
109 printer->params.instance_deactivate(printer);
110 }
111 }
112
_ux_device_class_printer_change(UX_SLAVE_CLASS_COMMAND * command)113 static VOID _ux_device_class_printer_change(UX_SLAVE_CLASS_COMMAND *command)
114 {
115 UX_TEST_ASSERT(0);
116 }
117
_configure_index_value(ULONG index)118 static UINT _configure_index_value(ULONG index)
119 {
120 UCHAR *descriptor;
121 ULONG configuration_index;
122 ULONG length;
123 UCHAR type;
124 descriptor = _ux_system_slave->ux_system_slave_device_framework;
125 configuration_index = 0;
126 while(1)
127 {
128 length = descriptor[0];
129 type = descriptor[1];
130
131 if (type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
132 {
133 if (configuration_index == index)
134 return(descriptor[5]);
135 /* Length is total length. */
136 length = _ux_utility_short_get(&descriptor[2]);
137 /* Next configuration. */
138 configuration_index ++;
139 }
140
141 /* Next descriptor. */
142 descriptor += length;
143 }
144 }
145
_ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND * command)146 static UINT _ux_device_class_printer_control_request(UX_SLAVE_CLASS_COMMAND *command)
147 {
148
149 UCHAR *setup_data;
150 UCHAR bmRequestType;
151 UCHAR bRequest;
152 USHORT wValue;
153 USHORT wIndex;
154 USHORT wLength;
155 UCHAR port_index;
156 UCHAR descriptor_type;
157 UCHAR *data_ptr;
158 UX_SLAVE_DEVICE *device;
159 UX_SLAVE_TRANSFER *transfer_request;
160 UX_SLAVE_CLASS *printer_class = (UX_SLAVE_CLASS *)command->ux_slave_class_command_class_ptr;
161 UX_DEVICE_CLASS_PRINTER *printer = (UX_DEVICE_CLASS_PRINTER *)printer_class->ux_slave_class_instance;
162 UX_SLAVE_INTERFACE *interface=printer->interface;
163 ULONG length;
164
165 /* Get the pointer to the device. */
166 device = &_ux_system_slave->ux_system_slave_device;
167
168 /* Get the pointer to the transfer request associated with the control endpoint. */
169 transfer_request = &device->ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
170
171 setup_data = transfer_request->ux_slave_transfer_request_setup;
172 bmRequestType = setup_data[0];
173 bRequest = setup_data[1];
174 wValue = (USHORT)_ux_utility_short_get(&setup_data[2]);
175 wIndex = (USHORT)_ux_utility_short_get(&setup_data[4]);
176 wLength = (USHORT)_ux_utility_short_get(&setup_data[6]);
177
178 data_ptr = transfer_request->ux_slave_transfer_request_data_pointer;
179
180 switch (bRequest)
181 {
182 case UX_HOST_CLASS_PRINTER_GET_DEVICE_ID:
183 /* Check configuration INDEX (wValue), interface (HIGH wIndex), alt (LOW wIndex). */
184 if (_configure_index_value(wValue) != interface->ux_slave_interface_class->ux_slave_class_configuration_number ||
185 setup_data[4] != interface->ux_slave_interface_descriptor.bAlternateSetting ||
186 setup_data[5] != interface->ux_slave_interface_descriptor.bInterfaceNumber)
187 return(UX_ERROR);
188 /* Send device ID. */
189 transfer_request->ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
190 length = UX_MIN(UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH, wLength);
191 length = UX_MIN(length, printer->params.device_id_length + 2);
192 if (length)
193 {
194 _ux_utility_short_put_big_endian(data_ptr, length - 2);
195 _ux_utility_memory_copy(data_ptr + 2, printer->params.device_id, length - 2);
196 }
197 return _ux_device_stack_transfer_request(transfer_request, length, wLength);
198
199 case UX_HOST_CLASS_PRINTER_GET_STATUS:
200 /* Check interface number. */
201 if (wIndex != interface->ux_slave_interface_descriptor.bInterfaceNumber)
202 return(UX_ERROR);
203 /* Send status. */
204 transfer_request->ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
205 *data_ptr = printer->port_status;
206 return _ux_device_stack_transfer_request(transfer_request, 1, wLength);
207
208 case UX_HOST_CLASS_PRINTER_SOFT_RESET:
209 /* Check interface number. */
210 if (wIndex != interface->ux_slave_interface_descriptor.bInterfaceNumber)
211 return(UX_ERROR);
212 /* Execute soft reset. */
213 _ux_device_stack_transfer_all_request_abort(printer->bulk_in_endpoint, UX_TRANSFER_BUS_RESET);
214 _ux_device_stack_transfer_all_request_abort(printer->bulk_out_endpoint, UX_TRANSFER_BUS_RESET);
215 printer->soft_reset = UX_TRUE;
216 return(UX_SUCCESS);
217
218 default:
219
220 UX_TEST_ASSERT(0);
221 break;
222 }
223 }
224
_ux_device_class_printer_entry(UX_SLAVE_CLASS_COMMAND * command)225 UINT _ux_device_class_printer_entry(UX_SLAVE_CLASS_COMMAND *command)
226 {
227
228 switch(command -> ux_slave_class_command_request)
229 {
230
231 case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
232 _ux_device_class_printer_initialize(command);
233 break;
234
235 case UX_SLAVE_CLASS_COMMAND_UNINITIALIZE:
236 _ux_device_class_printer_uninitialize(command);
237 break;
238
239 case UX_SLAVE_CLASS_COMMAND_QUERY:
240 /* For now, always return success. */
241 break;
242
243 case UX_SLAVE_CLASS_COMMAND_ACTIVATE:
244 return _ux_device_class_printer_activate(command);
245
246 case UX_SLAVE_CLASS_COMMAND_CHANGE:
247 UX_TEST_ASSERT(0);
248 break;
249
250 case UX_SLAVE_CLASS_COMMAND_DEACTIVATE:
251 _ux_device_class_printer_deactivate(command);
252 break;
253
254 case UX_SLAVE_CLASS_COMMAND_REQUEST:
255 return _ux_device_class_printer_control_request(command);
256
257 default:
258 UX_TEST_ASSERT(0);
259 break;
260
261 }
262 return(UX_SUCCESS);
263 }
264