⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbtarget.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    
    CYG_ASSERTC((usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) || \
                (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism));
    if (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) {
        if (((const char*)0 == usbs_testing_endpoints[ep_index].devtab_entry) ||
            (0 != cyg_io_lookup(usbs_testing_endpoints[ep_index].devtab_entry, &io_handle))) {
            
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk OUT transfer on endpoint %d: no devtab entry", endpoint_number);
            return;
        }
    }

    // Make sure nobody else is using this endpoint
    lock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT);

    for (i = 0; i < test->test_params.bulk.number_packets; i++) {
        int rx_size = test->test_params.bulk.rx_size;
        int tx_size = test->test_params.bulk.tx_size;

        VERBOSE(2, "Bulk OUT test %d: iteration %d, rx size %d, tx size %d\n", test->id, i, rx_size, tx_size);
        
        if (rx_size < tx_size) {
            rx_size = tx_size;
            VERBOSE(2, "Bulk OUT test %d: iteration %d, packet size reset to %d to match tx size\n",
                    test->id, i, rx_size);
        }
                                                              
        test->recovery.endpoint     = endpoint_number | USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT;
        test->recovery.protocol     = USB_ENDPOINT_DESCRIPTOR_ATTR_BULK;
        test->recovery.size         = rx_size;

        // Make sure there is no old data lying around
        if (usbtestdata_none != test->test_params.bulk.data.format) {
            memset(buf, 0, rx_size);
        }

        // Do the actual transfer, using the I/O mechanism specified for this test.
        switch (test->test_params.bulk.io_mechanism)
        {
          case usb_io_mechanism_usb :
          {
              test->transferred = 0;
              usbs_start_rx_buffer(endpoint, buf, rx_size, &run_test_bulk_in_out_callback, (void*) test);
              cyg_semaphore_wait(&(test->sem));
              transferred = test->transferred;
              break;
          }

          case usb_io_mechanism_dev :
          {
              int result;
              transferred   = rx_size;
              result = cyg_io_read(io_handle, (void*) buf, &transferred);
              if (result < 0) {
                  transferred = result;
              }
              break;
          }

          default:
            CYG_FAIL("Invalid test mechanism specified");
            break;
        }

        // Has this test been aborted for some reason?
        if (current_tests_terminated) {
            VERBOSE(2, "Bulk OUT test %d: iteration %d, termination detected\n", test->id, i);
            test->result_pass = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk OUT transfer on endpoint %d: transfer aborted after iteration %d", endpoint_number, i);
            break;
        }

        // If an error occurred, abort this run
        if (transferred < 0) {
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk OUT transfer on endpoint %d: transfer failed with %d", endpoint_number, transferred);
            VERBOSE(2, "Bulk OUT test %d: iteration %d, error:\n    %s\n", test->id, i, test->result_message);
            break;
        }

        // Did the host send the expected amount of data?
        if (transferred < test->test_params.bulk.tx_size) {
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk OUT transfer on endpoint %d : the host only sent %d bytes when %d were expected",
                     endpoint_number, transferred, tx_size);
            VERBOSE(2, "Bulk OUT test %d: iteration %d, error:\n    %s\n", test->id, i, test->result_message);
            break;
        }

        if (verbose >= 3) {
            // Output the first 32 bytes of data
            char msg[256];
            int  index;
            int  j;
            index = snprintf(msg, 255, "Bulk OUT test %d: iteration %d, transferred %d\n    Data %s:",
                             test->id, i, transferred,
                             (usbtestdata_none == test->test_params.bulk.data.format) ? "(uninitialized)" : "");

            for (j = 0; ((j + 3) < transferred) && (j < 32); j+= 4) {
                index += snprintf(msg+index, 255-index, " %02x%02x%02x%02x",
                                  buf[j], buf[j+1], buf[j+2], buf[j+3]);
            }
            if (j < 32) {
                index += snprintf(msg+index, 255-index, " ");
                for ( ; j < transferred; j++) {
                    index += snprintf(msg+index, 255-index, "%02x", buf[j]);
                }
                
            }
            VERBOSE(3, "%s\n", msg);
        }
        
        // Is the data correct?
        if (!usbtest_check_buffer(&(test->test_params.bulk.data), buf, transferred)) {
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk OUT transfer on endpoint %d : mismatch between received and expected data", endpoint_number);
            VERBOSE(2, "Bulk OUt test %d: iteration %d, error:\n    %s\n", test->id, i, test->result_message);
            break;
        }

        if (0 != test->test_params.bulk.rx_delay) {
            VERBOSE(2, "Bulk OUT test %d: iteration %d, sleeping for %d nanoseconds\n", test->id, \
                    i, test->test_params.bulk.rx_delay);
            usbs_nanosleep(test->test_params.bulk.rx_delay);
        }
        
        // Move on to the next transfer
        USBTEST_BULK_NEXT(test->test_params.bulk);
    }

    // Always unlock the endpoint on completion
    unlock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT);

    // If all the packets have been transferred this test has passed.
    if (i >= test->test_params.bulk.number_packets) {
        test->result_pass   = 1;
    }
    
    VERBOSE(1, "Test %d bulk OUT on endpoint %d, result %d\n", test->id, endpoint_number, test->result_pass);
}

/*}}}*/
/*{{{  run_test_bulk_in()                                       */

// IN transfers, i.e. the host is expected to receive some data. These are slightly
// easier than OUT transfers because it is the host that will do the checking.
static void
run_test_bulk_in(UsbTest* test)
{
    unsigned char*      buf;
    int                 endpoint_number = test->test_params.bulk.endpoint & ~USB_DEVREQ_DIRECTION_MASK;
    int                 ep_index;
    usbs_tx_endpoint*   endpoint        = 0;
    cyg_io_handle_t     io_handle       = (cyg_io_handle_t)0;
    int                 alignment;
    int                 transferred;
    int                 i;

    VERBOSE(1, "Starting test %d, bulk IN on endpoint %d\n", test->id, endpoint_number);
    
    ep_index = lookup_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN, USB_ENDPOINT_DESCRIPTOR_ATTR_BULK);
    if (ep_index == -1) {
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk IN transfer on endpoint %d: no such bulk endpoint", endpoint_number);
            return;
    }
    endpoint    = (usbs_tx_endpoint*) usbs_testing_endpoints[ep_index].endpoint;
    alignment   = usbs_testing_endpoints[ep_index].alignment;
    if (0 != alignment) {
        buf         = (unsigned char*) ((((cyg_uint32)test->buffer) + alignment - 1) & ~(alignment - 1));
    } else {
        buf = test->buffer;
    }
    
    CYG_ASSERTC((usb_io_mechanism_usb == test->test_params.bulk.io_mechanism) || \
                (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism));
    if (usb_io_mechanism_dev == test->test_params.bulk.io_mechanism) {
        if (((const char*)0 == usbs_testing_endpoints[ep_index].devtab_entry) ||
            (0 != cyg_io_lookup(usbs_testing_endpoints[ep_index].devtab_entry, &io_handle))) {
            
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk IN transfer on endpoint %d: no devtab entry", endpoint_number);
            return;
        }
    }

    // Make sure nobody else is using this endpoint
    lock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);
    
    for (i = 0; i < test->test_params.bulk.number_packets; i++) {
        int packet_size = test->test_params.bulk.tx_size;
        
        test->recovery.endpoint     = endpoint_number | USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN;
        test->recovery.protocol     = USB_ENDPOINT_DESCRIPTOR_ATTR_BULK;
        test->recovery.size         = packet_size + usbs_testing_endpoints[ep_index].max_in_padding;

        CYG_ASSERTC(sizeof(test->buffer) > packet_size);
        
        // Make sure the buffer contains the data expected by the host
        usbtest_fill_buffer(&(test->test_params.bulk.data), buf, packet_size);

        if (verbose < 3) {
            VERBOSE(2, "Bulk OUT test %d: iteration %d, packet size %d\n", test->id, i, packet_size);
        } else {
            // Output the first 32 bytes of data as well.
            char msg[256];
            int  index;
            int  j;
            index = snprintf(msg, 255, "Bulk IN test %d: iteration %d, packet size %d\n    Data %s:",
                             test->id, i, packet_size,
                             (usbtestdata_none == test->test_params.bulk.data.format) ? "(uninitialized)" : "");

            for (j = 0; ((j + 3) < packet_size) && (j < 32); j+= 4) {
                index += snprintf(msg+index, 255-index, " %02x%02x%02x%02x",
                                  buf[j], buf[j+1], buf[j+2], buf[j+3]);
            }
            if (j < 32) {
                index += snprintf(msg+index, 255-index, " ");
                for ( ; j < packet_size; j++) {
                    index += snprintf(msg+index, 255-index, "%02x", buf[j]);
                }
                
            }
            VERBOSE(3, "%s\n", msg);
        }
        
        // Do the actual transfer, using the I/O mechanism specified for this test.
        switch (test->test_params.bulk.io_mechanism)
        {
          case usb_io_mechanism_usb :
          {
              test->transferred = 0;
              usbs_start_tx_buffer(endpoint, buf, packet_size, &run_test_bulk_in_out_callback, (void*) test);
              cyg_semaphore_wait(&(test->sem));
              transferred = test->transferred;
              break;
          }

          case usb_io_mechanism_dev :
          {
              int result;
              transferred   = packet_size;
              result = cyg_io_write(io_handle, (void*) buf, &transferred);
              if (result < 0) {
                  transferred = result;
              }
              break;
          }

          default:
            CYG_FAIL("Invalid test mechanism specified");
            break;
        }

        // Has this test been aborted for some reason?
        if (current_tests_terminated) {
            VERBOSE(2, "Bulk IN test %d: iteration %d, termination detected\n", test->id, i);
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk IN transfer on endpoint %d : terminated on iteration %d, packet_size %d\n",
                     endpoint_number, i, packet_size);
            break;
        }

        // If an error occurred, abort this run
        if (transferred < 0) {
            test->result_pass   = 0;
            snprintf(test->result_message, USBTEST_MAX_MESSAGE,
                     "Target, bulk IN transfer on endpoint %d: transfer failed with %d", endpoint_number, transferred);
            VERBOSE(2, "Bulk IN test %d: iteration %d, error:\n    %s\n", test->id, i, test->result_message);
            break;
        }

        // No need to check the transfer size, the USB code is only
        // allowed to send the exact amount of data requested.

        if (0 != test->test_params.bulk.tx_delay) {
            VERBOSE(2, "Bulk IN test %d: iteration %d, sleeping for %d nanoseconds\n", test->id, i, \
                    test->test_params.bulk.tx_delay);
            usbs_nanosleep(test->test_params.bulk.tx_delay);
        }
        
        // Move on to the next transfer
        USBTEST_BULK_NEXT(test->test_params.bulk);
    }

    // Always unlock the endpoint on completion
    unlock_endpoint(endpoint_number, USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN);

    // If all the packets have been transferred this test has passed.
    if (i >= test->test_params.bulk.number_packets) {
        test->result_pass   = 1;
    }
    
    VERBOSE(1, "Test %d bulk IN on endpoint %d, result %d\n", test->id, endpoint_number, test->result_pass);
}

/*}}}*/

/*}}}*/
/*{{{  Control IN transfers                                     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -