1 /* This test is designed to test the simple dpump host/device class operation. */
2
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8
9 #include "fx_api.h"
10
11 #include "ux_device_class_storage.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_stack.h"
14 #include "ux_host_class_storage.h"
15
16 #include "ux_test_dcd_sim_slave.h"
17 #include "ux_test_hcd_sim_host.h"
18 #include "ux_test_utility_sim.h"
19
20 /* Define constants. */
21 #define UX_DEMO_STACK_SIZE 2048
22 #define UX_DEMO_MEMORY_SIZE (256*1024)
23 #define UX_DEMO_BUFFER_SIZE 2048
24
25 #define UX_RAM_DISK_SIZE (200 * 1024)
26 #define UX_RAM_DISK_LAST_LBA ((UX_RAM_DISK_SIZE / 512) -1)
27
28 /* Define local/extern function prototypes. */
29
30 VOID _fx_ram_driver(FX_MEDIA *media_ptr);
31 void _fx_ram_drive_format(ULONG disk_size, UINT sector_size, UINT sectors_per_cluster,
32 UINT fat_entries, UINT root_directory_entries);
33
34 static void demo_thread_entry(ULONG);
35 static TX_THREAD tx_demo_thread_host_simulation;
36 static TX_THREAD tx_demo_thread_slave_simulation;
37 static void tx_demo_thread_host_simulation_entry(ULONG);
38
39 static UINT demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
40 static UINT demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status);
41 static UINT demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status);
42 static UINT demo_thread_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status);
43
44 /* Define global data structures. */
45
46 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
47 static UCHAR buffer[UX_DEMO_BUFFER_SIZE];
48 static UCHAR cbw_buffer[UX_SLAVE_CLASS_STORAGE_CBW_LENGTH];
49 static UCHAR cbw_fail_sim = UX_FALSE;
50 static UCHAR csw_buffer[UX_SLAVE_CLASS_STORAGE_CSW_LENGTH];
51 static ULONG csw_sense_sim = 0;
52
53 static ULONG error_counter;
54
55 static TX_THREAD demo_thread;
56
57 static UX_HOST_CLASS_STORAGE *storage;
58 static UX_SLAVE_CLASS_STORAGE_PARAMETER global_storage_parameter;
59
60 static FX_MEDIA ram_disk_media1;
61 static FX_MEDIA ram_disk_media2;
62 static CHAR ram_disk_buffer1[512];
63 static CHAR ram_disk_buffer2[512];
64 static CHAR ram_disk_memory1[UX_RAM_DISK_SIZE];
65 static CHAR ram_disk_memory2[UX_RAM_DISK_SIZE];
66 static CHAR *ram_disk_memory[] =
67 {
68 ram_disk_memory1, ram_disk_memory2
69 };
70 static UINT ram_disk_status = UX_SUCCESS;
71 static ULONG ram_disk_media_status = 0;
72 static CHAR ram_disk_status_sent = 0;
73
74 static UINT ram_disk_read_status = UX_SUCCESS;
75 static ULONG ram_disk_read_media_status = 0;
76 static CHAR ram_disk_read_sent = 0;
77
78 static UINT ram_disk_write_status = UX_SUCCESS;
79 static ULONG ram_disk_write_media_status = 0;
80 static CHAR ram_disk_write_sent = 0;
81
82 static CHAR ram_disk_flush = 0;
83 static UINT ram_disk_flush_status = UX_SUCCESS;
84
85 static ULONG set_cfg_counter;
86
87 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
88 static ULONG rsc_sem_on_set_cfg;
89 static ULONG rsc_sem_get_on_set_cfg;
90 static ULONG rsc_mutex_on_set_cfg;
91
92 static ULONG rsc_enum_sem_usage;
93 static ULONG rsc_enum_sem_get_count;
94 static ULONG rsc_enum_mutex_usage;
95 static ULONG rsc_enum_mem_alloc_count;
96
97 static ULONG rsc_storage_sem_usage;
98 static ULONG rsc_storage_sem_get_count;
99 static ULONG rsc_storage_mutex_usage;
100 static ULONG rsc_storage_mem_alloc_count;
101
102 static ULONG interaction_count;
103
104 static UCHAR error_callback_ignore = UX_TRUE;
105 static ULONG error_callback_counter;
106
107 static ULONG loop_try = 0; /* 0: no loop */
108
109 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
110 static UCHAR device_framework_full_speed[] = {
111
112 /* Device descriptor */
113 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
114 0x81, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
115 0x03, 0x01,
116
117 /* Configuration descriptor */
118 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
119 0x32,
120
121 /* Interface descriptor */
122 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
123 0x00,
124
125 /* Endpoint descriptor (Bulk Out) */
126 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
127
128 /* Endpoint descriptor (Bulk In) */
129 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
130
131 };
132
133
134 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
135 static UCHAR device_framework_high_speed[] = {
136
137 /* Device descriptor */
138 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
139 0x81, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
140 0x03, 0x01,
141
142 /* Device qualifier descriptor */
143 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
144 0x01, 0x00,
145
146 /* Configuration descriptor */
147 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
148 0x32,
149
150 /* Interface descriptor */
151 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50,
152 0x00,
153
154 /* Endpoint descriptor (Bulk Out) */
155 0x07, 0x05, 0x02, 0x02, 0x00, 0x01, 0x00,
156
157 /* Endpoint descriptor (Bulk In) */
158 0x07, 0x05, 0x81, 0x02, 0x00, 0x01, 0x00,
159
160 };
161
162
163 /* String Device Framework :
164 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
165 Byte 2 : Byte containing the index of the descriptor
166 Byte 3 : Byte containing the length of the descriptor string
167 */
168
169 #define STRING_FRAMEWORK_LENGTH 38
170 static UCHAR string_framework[] = {
171
172 /* Manufacturer string descriptor : Index 1 */
173 0x09, 0x04, 0x01, 0x0c,
174 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
175 0x6f, 0x67, 0x69, 0x63,
176
177 /* Product string descriptor : Index 2 */
178 0x09, 0x04, 0x02, 0x0a,
179 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20, 0x44, 0x69,
180 0x73, 0x6b,
181
182 /* Serial Number string descriptor : Index 3 */
183 0x09, 0x04, 0x03, 0x04,
184 0x30, 0x30, 0x30, 0x31
185 };
186
187
188 /* Multiple languages are supported on the device, to add
189 a language besides english, the unicode language code must
190 be appended to the language_id_framework array and the length
191 adjusted accordingly. */
192 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
193 static UCHAR language_id_framework[] = {
194
195 /* English. */
196 0x09, 0x04
197 };
198
199 struct request_sense_response {
200 UCHAR valid_error_code; /* 0x70 */
201 UCHAR reserved;
202 UCHAR sense_key;
203 UCHAR information[4];
204 UCHAR additional_sense_length;
205 UCHAR reserved1[4];
206 UCHAR additional_sense_code;
207 UCHAR additional_sense_code_qualifier;
208 UCHAR reserved2;
209 UCHAR reserved3[3];
210 };
211 static struct request_sense_response request_sense_data = {
212 .valid_error_code = 0x70,
213 .sense_key = 0,
214 .additional_sense_length = 10,
215 .additional_sense_code = 0,
216 .additional_sense_code_qualifier = 0
217 };
218
219 static UX_TEST_SETUP _GetMaxLun = UX_TEST_SETUP_STORAGE_GetMaxLun;
220
221 static UX_TEST_HCD_SIM_ACTION stall_GetMaxLun[] = {
222 /* function, request to match,
223 port action, port status,
224 request action, request EP, request data, request actual length, request status,
225 status, additional callback,
226 no_return */
227 { UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
228 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
229 UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 1, UX_TRANSFER_STALLED,
230 UX_TRANSFER_STALLED, UX_NULL},
231 { 0 }
232 };
233
234 static UX_TEST_HCD_SIM_ACTION length_error_GetMaxLun[] = {
235 /* function, request to match,
236 port action, port status,
237 request action, request EP, request data, request actual length, request status,
238 status, additional callback,
239 no_return */
240 { UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
241 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
242 UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 2, UX_SUCCESS,
243 UX_SUCCESS, UX_NULL},
244 { 0 }
245 };
246
247 static UX_TEST_HCD_SIM_ACTION replaced_GetMaxLun[] = {
248 /* function, request to match,
249 port action, port status,
250 request action, request EP, request data, request actual length, request status,
251 status, additional callback,
252 no_return */
253 { UX_HCD_TRANSFER_REQUEST, &_GetMaxLun,
254 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
255 UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, buffer, 1, UX_SUCCESS,
256 UX_SUCCESS, UX_NULL},
257 { 0 }
258 };
259
260 static UX_TEST_HCD_SIM_ACTION fail_bulk_out[] = {
261 /* function, request to match,
262 port action, port status,
263 request action, request EP, request data, request actual length, request status,
264 status, additional callback,
265 no_return */
266 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
267 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
268 UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
269 UX_ERROR, UX_NULL},
270 { 0 }
271 };
272
273 static UX_TEST_HCD_SIM_ACTION fail_2nd_bulk_out[] = {
274 /* function, request to match,
275 port action, port status,
276 request action, request EP, request data, request actual length, request status,
277 status, additional callback,
278 no_return */
279 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
280 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
281 UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_SUCCESS,
282 UX_SUCCESS, UX_NULL,
283 UX_TRUE},
284 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
285 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
286 UX_TEST_MATCH_EP, 0x02, UX_NULL, 0, UX_ERROR,
287 UX_ERROR, UX_NULL},
288 { 0 }
289 };
290
cbw_general(UCHAR * cbw,UX_TRANSFER * transfer_request)291 static VOID cbw_general(UCHAR *cbw, UX_TRANSFER *transfer_request)
292 {
293 _ux_utility_memory_copy(cbw_buffer, cbw, 31);
294 // printf("CBW >"); for(int i = 0; i < 31; i ++) printf(" %2x", cbw[i]); printf("\n");
295
296 /* Prepare CSW. */
297 _ux_utility_memory_copy(csw_buffer + 0, cbw_buffer + 0, 4); /* dCBWSignature -> dCSWSignature */
298 _ux_utility_memory_copy(csw_buffer + 4, cbw_buffer + 4, 4); /* dCBWTag -> dCSWTag */
299 _ux_utility_memory_set (csw_buffer + 8, 0x00, 4); /* dCSWDataResidue <= 0 */
300 // _ux_utility_memory_set (csw_buffer + 12, 0x00, 1); /* bCSWStatus <= 0 */
301
302 transfer_request->ux_transfer_request_completion_code = UX_SUCCESS;
303 }
304
cbw_start_stop(struct UX_TEST_ACTION_STRUCT * action,VOID * params)305 static VOID cbw_start_stop(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
306 {
307
308 UCHAR *cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
309 UX_TRANSFER *transfer_request = &storage -> ux_host_class_storage_bulk_out_endpoint -> ux_endpoint_transfer_request;
310
311
312 cbw_general(cbw, transfer_request);
313 _ux_utility_memory_set (csw_buffer + 12, 0x01, 1); /* bCSWStatus <= 1 */
314
315 if (!cbw_fail_sim)
316 _ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
317 }
csw_start_stop(struct UX_TEST_ACTION_STRUCT * action,VOID * params)318 static VOID csw_start_stop(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
319 {
320
321 UCHAR *csw = (UCHAR *)storage -> ux_host_class_storage_csw;
322 UX_TRANSFER *transfer_request = &storage -> ux_host_class_storage_bulk_in_endpoint -> ux_endpoint_transfer_request;
323
324
325 _ux_utility_memory_copy(csw, csw_buffer, 13);
326 // printf("CSW >"); for(int i = 0; i < 13; i ++) printf(" %2x", csw[i]); printf("\n");
327
328 _ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
329 }
330
cbw_request_sense(struct UX_TEST_ACTION_STRUCT * action,VOID * params)331 static VOID cbw_request_sense(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
332 {
333
334 UCHAR *cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
335 UX_TRANSFER *transfer_request = &storage -> ux_host_class_storage_bulk_out_endpoint -> ux_endpoint_transfer_request;
336
337
338 cbw_general(cbw, transfer_request);
339 _ux_utility_memory_set (csw_buffer + 12, 0x00, 1); /* bCSWStatus <= 0 */
340 _ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
341 }
data_request_sense(struct UX_TEST_ACTION_STRUCT * action,VOID * params)342 static VOID data_request_sense(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
343 {
344
345 UCHAR *cbw = (UCHAR *)storage -> ux_host_class_storage_cbw;
346 UX_TRANSFER *transfer_request = &storage -> ux_host_class_storage_bulk_in_endpoint -> ux_endpoint_transfer_request;
347 UCHAR *sense_data = transfer_request->ux_transfer_request_data_pointer;
348
349
350 _ux_utility_memory_copy(sense_data, &request_sense_data, sizeof(request_sense_data));
351 // printf("DTA >"); for(int i = 0; i < sizeof(request_sense_data); i ++) printf(" %2x", sense_data[i]); printf("\n");
352 transfer_request->ux_transfer_request_actual_length = sizeof(request_sense_data);
353 transfer_request->ux_transfer_request_completion_code = UX_SUCCESS;
354 _ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
355 }
356
357 static VOID csw_request_sense(struct UX_TEST_ACTION_STRUCT *action, VOID *params);
358 static UX_TEST_HCD_SIM_ACTION replace_start_stop_sense_loop[] = {
359 /* function, request to match,
360 port action, port status,
361 request action, request EP, request data, request actual length, request status,
362 status, additional callback,
363 no_return */
364 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
365 UX_FALSE, 0,
366 UX_TEST_MATCH_EP, 0x02, UX_NULL, 31, UX_SUCCESS,
367 UX_SUCCESS,
368 .action_func = cbw_start_stop,
369 .no_return = UX_FALSE,
370 .do_after = UX_FALSE},
371 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
372 UX_FALSE, 0,
373 UX_TEST_MATCH_EP | UX_TEST_SIM_REQ_ANSWER, 0x81, csw_buffer, 13, UX_SUCCESS,
374 UX_SUCCESS,
375 .action_func = csw_start_stop,
376 .no_return = UX_FALSE,
377 .do_after = UX_FALSE},
378 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
379 UX_FALSE, 0,
380 UX_TEST_MATCH_EP, 0x02, UX_NULL, 31, UX_SUCCESS,
381 UX_SUCCESS,
382 .action_func = cbw_request_sense,
383 .no_return = UX_FALSE,
384 .do_after = UX_FALSE},
385 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
386 UX_FALSE, 0,
387 UX_TEST_MATCH_EP, 0x81, UX_NULL, 0, UX_SUCCESS,
388 UX_SUCCESS,
389 .action_func = data_request_sense,
390 .no_return = UX_FALSE,
391 .do_after = UX_FALSE},
392 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
393 UX_FALSE, 0,
394 UX_TEST_MATCH_EP | UX_TEST_SIM_REQ_ANSWER, 0x81, csw_buffer, 13, UX_SUCCESS,
395 UX_SUCCESS,
396 .action_func = csw_request_sense,
397 .no_return = UX_FALSE,
398 .do_after = UX_FALSE},
399 { 0 }
400 };
401
402
csw_request_sense(struct UX_TEST_ACTION_STRUCT * action,VOID * params)403 static VOID csw_request_sense(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
404 {
405
406 UCHAR *csw = (UCHAR *)storage -> ux_host_class_storage_csw;
407 UX_TRANSFER *transfer_request = &storage -> ux_host_class_storage_bulk_in_endpoint -> ux_endpoint_transfer_request;
408
409
410 _ux_utility_memory_copy(csw, csw_buffer, 13);
411 // printf("CSW1:"); for(int i = 0; i < 13; i ++) printf(" %2x", csw[i]); printf("\n");
412
413 if (loop_try) {
414
415 ux_test_hcd_sim_host_set_actions(replace_start_stop_sense_loop);
416
417 if (loop_try != 0xFFFFFFFF)
418 loop_try --;
419 }
420
421 _ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
422 }
423
424 /* Define the ISR dispatch. */
425
426 extern VOID (*test_isr_dispatch)(void);
427
428
429 /* Prototype for test control return. */
430
431 void test_control_return(UINT status);
432
433
434 /* Define the ISR dispatch routine. */
435
test_isr(void)436 static void test_isr(void)
437 {
438
439 /* For further expansion of interrupt-level testing. */
440 }
441
442
error_callback(UINT system_level,UINT system_context,UINT error_code)443 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
444 {
445
446 error_callback_counter ++;
447
448 if (!error_callback_ignore)
449 {
450 {
451 /* Failed test. */
452 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
453 test_control_return(1);
454 }
455 }
456 }
457
host_storage_instance_get(ULONG timeout_x10ms)458 static UINT host_storage_instance_get(ULONG timeout_x10ms)
459 {
460
461 UINT status;
462 UX_HOST_CLASS *class;
463
464
465 /* Find the main storage container */
466 status = ux_host_stack_class_get(_ux_system_host_class_storage_name, &class);
467 if (status != UX_SUCCESS)
468 return(status);
469
470 /* Get storage instance, wait it to be live and media attached. */
471 do
472 {
473 if (timeout_x10ms)
474 {
475 ux_utility_delay_ms(10);
476 if (timeout_x10ms != 0xFFFFFFFF)
477 timeout_x10ms --;
478 }
479
480 status = ux_host_stack_class_instance_get(class, 0, (void **) &storage);
481 if (status == UX_SUCCESS)
482 {
483 if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_LIVE &&
484 class -> ux_host_class_media != UX_NULL)
485 return(UX_SUCCESS);
486 }
487
488 } while(timeout_x10ms > 0);
489
490 return(UX_ERROR);
491 }
492
sleep_break_on_error(VOID)493 static UINT sleep_break_on_error(VOID)
494 {
495
496 if (error_callback_counter >= 3)
497 return error_callback_counter;
498
499 return UX_SUCCESS;
500 }
501
502
503 /* Define what the initial system looks like. */
504
505 #ifdef CTEST
test_application_define(void * first_unused_memory)506 void test_application_define(void *first_unused_memory)
507 #else
508 void usbx_ux_host_class_storage_start_stop_test_application_define(void *first_unused_memory)
509 #endif
510 {
511
512 UINT status;
513 CHAR * stack_pointer;
514 CHAR * memory_pointer;
515
516
517 /* Inform user. */
518 printf("Running ux_host_class_storage_start_stop Test....................... ");
519 stepinfo("\n");
520
521 /* Initialize the free memory pointer */
522 stack_pointer = (CHAR *) usbx_memory;
523 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
524
525 /* Initialize USBX. Memory */
526 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
527
528 /* Check for error. */
529 if (status != UX_SUCCESS)
530 {
531
532 printf("ERROR #%d\n", __LINE__);
533 test_control_return(1);
534 }
535
536 /* Register the error callback. */
537 _ux_utility_error_callback_register(error_callback);
538
539 /* Reset ram disks memory. */
540 ux_utility_memory_set(ram_disk_memory1, 0, UX_RAM_DISK_SIZE);
541 ux_utility_memory_set(ram_disk_memory2, 0, UX_RAM_DISK_SIZE);
542
543 /* Initialize FileX. */
544 fx_system_initialize();
545
546 /* Change the ram drive values. */
547 fx_media_format(&ram_disk_media1, _fx_ram_driver, ram_disk_memory1, ram_disk_buffer1, 512, "RAM DISK1", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
548 fx_media_format(&ram_disk_media2, _fx_ram_driver, ram_disk_memory2, ram_disk_buffer2, 512, "RAM DISK2", 2, 512, 0, UX_RAM_DISK_SIZE/512, 512, 4, 1, 1);
549
550 /* The code below is required for installing the device portion of USBX.
551 In this demo, DFU is possible and we have a call back for state change. */
552 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
553 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
554 string_framework, STRING_FRAMEWORK_LENGTH,
555 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
556 if(status!=UX_SUCCESS)
557 {
558
559 printf("ERROR #%d\n", __LINE__);
560 test_control_return(1);
561 }
562
563 /* Store the number of LUN in this device storage instance. */
564 global_storage_parameter.ux_slave_class_storage_parameter_number_lun = 2;
565
566 /* Initialize the storage class parameters for reading/writing to the first Flash Disk. */
567 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_last_lba = UX_RAM_DISK_LAST_LBA;
568 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;
569 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;
570 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;
571 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = demo_thread_media_read;
572 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = demo_thread_media_write;
573 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = demo_thread_media_status;
574 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_flush = demo_thread_media_flush;
575 global_storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read_only_flag = UX_FALSE;
576
577 /* Initialize the storage class parameters for reading/writing to the second Flash Disk. */
578 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_last_lba = UX_RAM_DISK_LAST_LBA;
579 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_block_length = 512;
580 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_type = 0;
581 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_removable_flag = 0x80;
582 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read = demo_thread_media_read;
583 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_write = demo_thread_media_write;
584 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_status = demo_thread_media_status;
585 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_flush = demo_thread_media_flush;
586 global_storage_parameter.ux_slave_class_storage_parameter_lun[1].ux_slave_class_storage_media_read_only_flag = UX_FALSE;
587
588 /* Initialize the device storage class. The class is connected with interface 0 on configuration 1. */
589 status = ux_device_stack_class_register(_ux_system_slave_class_storage_name, ux_device_class_storage_entry,
590 1, 0, (VOID *)&global_storage_parameter);
591 if(status!=UX_SUCCESS)
592 {
593
594 printf("ERROR #%d\n", __LINE__);
595 test_control_return(1);
596 }
597
598 /* Initialize the simulated device controller. */
599 // status = _ux_test_dcd_sim_slave_initialize();
600 status = ux_dcd_sim_slave_initialize();
601
602 /* Check for error. */
603 if (status != UX_SUCCESS)
604 {
605
606 printf("ERROR #%d\n", __LINE__);
607 test_control_return(1);
608 }
609
610 /* The code below is required for installing the host portion of USBX */
611 status = ux_host_stack_initialize(UX_NULL);
612 if (status != UX_SUCCESS)
613 {
614
615 printf("ERROR #%d\n", __LINE__);
616 test_control_return(1);
617 }
618
619 /* Register storage class. */
620 status = ux_host_stack_class_register(_ux_system_host_class_storage_name, ux_host_class_storage_entry);
621 if (status != UX_SUCCESS)
622 {
623
624 printf("ERROR #%d\n", __LINE__);
625 test_control_return(1);
626 }
627
628 /* Register all the USB host controllers available in this system */
629 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
630 // status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
631
632 /* Check for error. */
633 if (status != UX_SUCCESS)
634 {
635
636 printf("ERROR #%d\n", __LINE__);
637 test_control_return(1);
638 }
639
640 /* Create the main host simulation thread. */
641 status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
642 stack_pointer, UX_DEMO_STACK_SIZE,
643 20, 20, 1, TX_AUTO_START);
644
645 /* Check for error. */
646 if (status != TX_SUCCESS)
647 {
648
649 printf("ERROR #%d\n", __LINE__);
650 test_control_return(1);
651 }
652
653 }
654
storage_media_status_wait(UX_HOST_CLASS_STORAGE_MEDIA * storage_media,ULONG status,ULONG timeout)655 static UINT storage_media_status_wait(UX_HOST_CLASS_STORAGE_MEDIA *storage_media, ULONG status, ULONG timeout)
656 {
657
658 while(1)
659 {
660 #if !defined(UX_HOST_CLASS_STORAGE_NO_FILEX)
661 if (storage_media->ux_host_class_storage_media_status == status)
662 return UX_SUCCESS;
663 #else
664 if ((status == UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED &&
665 storage_media->ux_host_class_storage_media_storage != UX_NULL) ||
666 (status == UX_HOST_CLASS_STORAGE_MEDIA_UNMOUNTED &&
667 storage_media->ux_host_class_storage_media_storage == UX_NULL))
668 return(UX_SUCCESS);
669 #endif
670 if (timeout == 0)
671 break;
672 if (timeout != 0xFFFFFFFF)
673 timeout --;
674 _ux_utility_delay_ms(10);
675 }
676 return UX_ERROR;
677 }
678
679
tx_demo_thread_host_simulation_entry(ULONG arg)680 static void tx_demo_thread_host_simulation_entry(ULONG arg)
681 {
682
683 UINT status;
684 UX_HOST_CLASS *class;
685 UX_HOST_CLASS_STORAGE_MEDIA *storage_media;
686 UX_ENDPOINT *control_endpoint;
687 UX_TRANSFER *transfer_request;
688 UX_DEVICE *device;
689 UX_CONFIGURATION *configuration;
690 UX_INTERFACE *interface;
691 UX_SLAVE_DEVICE *slave_device;
692 UX_SLAVE_CLASS *slave_class;
693 UX_SLAVE_CLASS_STORAGE *slave_storage;
694
695
696 /* Find the storage class. */
697 status = host_storage_instance_get(100);
698 if (status != UX_SUCCESS)
699 {
700 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
701 test_control_return(1);
702 }
703
704 status = ux_host_stack_device_get(0, &device);
705 if (status != UX_SUCCESS)
706 {
707
708 printf("ERROR #%d: device_get fail\n", __LINE__);
709 test_control_return(1);
710 }
711 control_endpoint = &device->ux_device_control_endpoint;
712 transfer_request = &control_endpoint->ux_endpoint_transfer_request;
713
714 /* Wait enough time for media mounting. */
715 _ux_utility_delay_ms(UX_HOST_CLASS_STORAGE_DEVICE_INIT_DELAY);
716
717 class = storage->ux_host_class_storage_class;
718 storage_media = (UX_HOST_CLASS_STORAGE_MEDIA *)class->ux_host_class_media;
719
720 /* Confirm media enum done (). */
721 status = storage_media_status_wait(storage_media, UX_HOST_CLASS_STORAGE_MEDIA_MOUNTED, 100);
722 if (status != UX_SUCCESS)
723 {
724 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
725 test_control_return(1);
726 }
727
728 /* Pause the class driver thread. */
729 _ux_utility_thread_suspend(&((UX_HOST_CLASS_STORAGE_EXT*)class->ux_host_class_ext)->ux_host_class_thread);
730
731 configuration = device -> ux_device_first_configuration;
732 interface = configuration -> ux_configuration_first_interface;
733
734 slave_device = &_ux_system_slave->ux_system_slave_device;
735 slave_class = _ux_system_slave->ux_system_slave_interface_class_array[0];
736 slave_storage = (UX_SLAVE_CLASS_STORAGE *)slave_class->ux_slave_class_instance;
737
738 stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_start_stop - UX_SUCCESS\n");
739 status = _ux_host_class_storage_start_stop(storage, UX_SUCCESS);
740 if (status != UX_SUCCESS)
741 {
742 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
743 test_control_return(1);
744 }
745
746 stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_start_stop - transfer error\n");
747 cbw_fail_sim = UX_TRUE;
748 ux_test_hcd_sim_host_set_actions(replace_start_stop_sense_loop);
749 status = _ux_host_class_storage_start_stop(storage, 0);
750 if (status == UX_SUCCESS)
751 {
752 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
753 test_control_return(1);
754 }
755 cbw_fail_sim = UX_FALSE;
756 ux_test_hcd_sim_host_set_actions(UX_NULL);
757
758 stepinfo(">>>>>>>>>>>>>>> ux_host_class_storage_start_stop - sense code error\n");
759 loop_try = 60;
760 request_sense_data.sense_key = 0x2;
761 ux_test_hcd_sim_host_set_actions(replace_start_stop_sense_loop);
762 status = _ux_host_class_storage_start_stop(storage, 0);
763 if (status == UX_SUCCESS)
764 {
765 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
766 test_control_return(1);
767 }
768 ux_test_hcd_sim_host_set_actions(UX_NULL);
769
770 /* Wait a while so the thread goes. */
771 _ux_utility_delay_ms(10);
772
773 /* Finally disconnect the device. */
774 ux_device_stack_disconnect();
775
776 /* And deinitialize the class. */
777 status = ux_device_stack_class_unregister(_ux_system_slave_class_storage_name, ux_device_class_storage_entry);
778
779 /* Deinitialize the device side of usbx. */
780 _ux_device_stack_uninitialize();
781
782 /* And finally the usbx system resources. */
783 _ux_system_uninitialize();
784
785 /* Successful test. */
786 printf("SUCCESS!\n");
787 test_control_return(0);
788 }
789
790
demo_thread_media_status(VOID * storage,ULONG lun,ULONG media_id,ULONG * media_status)791 static UINT demo_thread_media_status(VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
792 {
793
794 UINT status = ram_disk_status;
795
796
797 (void)storage;
798 (void)media_id;
799
800 if (media_status)
801 *media_status = ram_disk_media_status;
802
803 /* If there is attention, it must be changed to ready after reported. */
804 if (ram_disk_media_status == (UX_SLAVE_CLASS_STORAGE_SENSE_KEY_UNIT_ATTENTION | (0x28 << 8)))
805 {
806 ram_disk_status = UX_SUCCESS;
807 ram_disk_media_status = 0;
808 }
809 else
810 ram_disk_status_sent = UX_TRUE;
811
812 return status;
813 }
814
demo_thread_media_read(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)815 static UINT demo_thread_media_read(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
816 {
817 (void)storage;
818
819 if (lun > 1)
820 return UX_ERROR;
821
822 ram_disk_read_sent = UX_TRUE;
823 if (ram_disk_read_status != UX_SUCCESS)
824 {
825 if (media_status != UX_NULL)
826 *media_status = ram_disk_read_media_status;
827
828 return ram_disk_read_status;
829 }
830
831 ux_utility_memory_copy(data_pointer, &ram_disk_memory[lun][lba * 512], number_blocks * 512);
832
833 return UX_SUCCESS;
834 }
835
demo_thread_media_write(VOID * storage,ULONG lun,UCHAR * data_pointer,ULONG number_blocks,ULONG lba,ULONG * media_status)836 static UINT demo_thread_media_write(VOID *storage, ULONG lun, UCHAR * data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
837 {
838 (void)storage;
839
840 if (lun > 1)
841 return UX_ERROR;
842
843 ram_disk_write_sent = UX_TRUE;
844 if (ram_disk_write_status != UX_SUCCESS)
845 {
846 if (media_status != UX_NULL)
847 *media_status = ram_disk_write_media_status;
848
849 return ram_disk_write_status;
850 }
851
852 ux_utility_memory_copy(&ram_disk_memory[lun][lba * 512], data_pointer, number_blocks * 512);
853
854 return UX_SUCCESS;
855 }
856
demo_thread_media_flush(VOID * storage,ULONG lun,ULONG number_blocks,ULONG lba,ULONG * media_status)857 static UINT demo_thread_media_flush(VOID *storage, ULONG lun, ULONG number_blocks, ULONG lba, ULONG *media_status)
858 {
859 (void)storage;
860 (void)number_blocks;
861 (void)lba;
862 (void)media_status;
863
864 if (lun > 1)
865 return UX_ERROR;
866
867 ram_disk_flush = UX_TRUE;
868 return ram_disk_flush_status;
869 }