mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
USB: Make unit test mock classes common
This commit moves the mock classes used for HCD unit tests into a common header so that other layers of the USB Host stack can also utilzie them for their own unit tests.
This commit is contained in:
parent
d7928bf1db
commit
b901cbd273
@ -5,7 +5,7 @@ if(NOT "${target}" MATCHES "^esp32s[2-3]")
|
||||
return()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRC_DIRS "hcd"
|
||||
PRIV_INCLUDE_DIRS "../private_include" "." "hcd"
|
||||
idf_component_register(SRC_DIRS "common" "hcd"
|
||||
PRIV_INCLUDE_DIRS "../private_include" "common" "hcd"
|
||||
PRIV_REQUIRES cmock usb test_utils
|
||||
)
|
||||
|
86
components/usb/test/common/test_usb_mock_classes.c
Normal file
86
components/usb/test/common/test_usb_mock_classes.c
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "usb.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag)
|
||||
{
|
||||
cbw->dCBWSignature = 0x43425355; //Fixed value
|
||||
cbw->dCBWTag = tag; //Random value that is echoed back
|
||||
cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE;
|
||||
cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag
|
||||
cbw->bCBWLUN = MOCK_MSC_SCSI_LUN;
|
||||
cbw->bCBWCBLength = 10; //The length of the SCSI command
|
||||
//Initialize SCSI CMD as READ10 or WRITE 10
|
||||
cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; //SCSI CMD READ10 or WRITE10
|
||||
cbw->CBWCB.flags = 0;
|
||||
cbw->CBWCB.lba_3 = (offset >> 24);
|
||||
cbw->CBWCB.lba_2 = (offset >> 16);
|
||||
cbw->CBWCB.lba_1 = (offset >> 8);
|
||||
cbw->CBWCB.lba_0 = (offset >> 0);
|
||||
cbw->CBWCB.group = 0;
|
||||
cbw->CBWCB.len_1 = (num_sectors >> 8);
|
||||
cbw->CBWCB.len_0 = (num_sectors >> 0);
|
||||
cbw->CBWCB.control = 0;
|
||||
}
|
||||
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect)
|
||||
{
|
||||
bool no_issues = true;
|
||||
if (csw->dCSWSignature != 0x53425355) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw signature corrupt (0x%X)\n", csw->dCSWSignature);
|
||||
}
|
||||
if (csw->dCSWTag != tag_expect) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw tag unexpected! Expected %d got %d\n", tag_expect, csw->dCSWTag);
|
||||
}
|
||||
if (csw->dCSWDataResidue) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates data residue of %d bytes!\n", csw->dCSWDataResidue);
|
||||
}
|
||||
if (csw->bCSWStatus) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus);
|
||||
}
|
||||
return no_issues;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter)
|
||||
{
|
||||
static int x_pos = 0;
|
||||
static int y_pos = 0;
|
||||
//Update X position
|
||||
if (report->x_movement & 0x80) { //Positive movement
|
||||
x_pos += report->x_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
x_pos -= report->x_movement & 0x7F;
|
||||
}
|
||||
//Update Y position
|
||||
if (report->y_movement & 0x80) { //Positive movement
|
||||
y_pos += report->y_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
y_pos -= report->y_movement & 0x7F;
|
||||
}
|
||||
printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter);
|
||||
}
|
256
components/usb/test/common/test_usb_mock_classes.h
Normal file
256
components/usb/test/common/test_usb_mock_classes.h
Normal file
@ -0,0 +1,256 @@
|
||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/*
|
||||
This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB
|
||||
Host stack.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "usb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should...
|
||||
|
||||
- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
|
||||
- It's configuration 1 should have the following endpoints
|
||||
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 0
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x125f
|
||||
idProduct 0xc08a
|
||||
bcdDevice 1.00
|
||||
iManufacturer 1
|
||||
iProduct 2
|
||||
iSerial 3
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 0x0020
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 480mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 8 Mass Storage
|
||||
bInterfaceSubClass 6 SCSI
|
||||
bInterfaceProtocol 80 Bulk-Only
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x01 EP 1 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
|
||||
If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
|
||||
*/
|
||||
|
||||
static const usb_desc_ep_t mock_msc_scsi_bulk_out_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01, //EP 1 OUT
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
static const usb_desc_ep_t mock_msc_scsi_bulk_in_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x82, //EP 2 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
#define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x125F
|
||||
#define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0xc08A
|
||||
#define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64
|
||||
#define MOCK_MSC_SCSI_SECTOR_SIZE 512
|
||||
#define MOCK_MSC_SCSI_LUN 0
|
||||
#define MOCK_MSC_SCSI_INTF_NUMBER 0
|
||||
#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
|
||||
#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x01
|
||||
#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x82
|
||||
#define MOCK_MSC_SCSI_BULK_EP_MPS 64
|
||||
|
||||
#define MOCK_MSC_SCSI_REQ_INIT_RESET(ctrl_req_ptr, intf_num) ({ \
|
||||
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_OUT | USB_B_REQUEST_TYPE_TYPE_CLASS | USB_B_REQUEST_TYPE_RECIP_INTERFACE; \
|
||||
(ctrl_req_ptr)->bRequest = 0xFF; \
|
||||
(ctrl_req_ptr)->wValue = 0; \
|
||||
(ctrl_req_ptr)->wIndex = (intf_num); \
|
||||
(ctrl_req_ptr)->wLength = 0; \
|
||||
})
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
|
||||
uint8_t flags;
|
||||
uint8_t lba_3;
|
||||
uint8_t lba_2;
|
||||
uint8_t lba_1;
|
||||
uint8_t lba_0;
|
||||
uint8_t group;
|
||||
uint8_t len_1;
|
||||
uint8_t len_0;
|
||||
uint8_t control;
|
||||
} mock_scsi_cmd10_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
mock_scsi_cmd10_t CBWCB;
|
||||
uint8_t padding[6];
|
||||
} mock_msc_bulk_cbw_t;
|
||||
|
||||
// USB Bulk Transfer Command Status Wrapper data
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bCSWStatus;
|
||||
} mock_msc_bulk_csw_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command
|
||||
*
|
||||
* @param cbw CBW structure
|
||||
* @param is_read Is a read command
|
||||
* @param offset Block offset
|
||||
* @param num_sectors Number of sectors to read
|
||||
* @param tag Tag (this is simply echoed back
|
||||
*/
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag);
|
||||
|
||||
/**
|
||||
* @brief Check that returned Command Status Wrapper (CSW) is valid
|
||||
*
|
||||
* @param csw CSW structure
|
||||
* @param tag_expect Expected tag
|
||||
* @return true CSW is valid
|
||||
* @return false CSW is not valid
|
||||
*/
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect);
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should...
|
||||
|
||||
- Be implement the HID with standard report format used by mice
|
||||
- It's configuration 1 should have the following endpoint
|
||||
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0004 1x 4 bytes
|
||||
bInterval 10
|
||||
|
||||
If you're using another mice with different endpoints, modify the endpoint descriptor below
|
||||
*/
|
||||
static const usb_desc_ep_t mock_hid_mouse_in_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81, //EP 1 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
|
||||
.wMaxPacketSize = 4, //MPS of 4 bytes
|
||||
.bInterval = 10, //Interval of 10ms
|
||||
};
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t left_button: 1;
|
||||
uint32_t right_button: 1;
|
||||
uint32_t middle_button: 1;
|
||||
uint32_t reserved5: 5;
|
||||
uint8_t x_movement;
|
||||
uint8_t y_movement;
|
||||
} __attribute__((packed));
|
||||
uint8_t val[3];
|
||||
} mock_hid_mouse_report_t;
|
||||
_Static_assert(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect");
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter);
|
||||
|
||||
// ---------------------------------------------------- Mock ISOC ------------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for
|
||||
ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below:
|
||||
*/
|
||||
|
||||
#define MOCK_ISOC_EP_NUM 2
|
||||
#define MOCK_ISOC_EP_MPS 512
|
||||
|
||||
|
||||
static const usb_desc_ep_t mock_isoc_out_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_ISOC_EP_NUM,
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
|
||||
.wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
|
||||
.bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -18,101 +18,10 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
// ------------------------------------------------- Mock MSC SCSI -----------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: The following test requires that USB flash drive be connected. The flash drive should...
|
||||
|
||||
- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
|
||||
- It's configuration 1 should have the following endpoints
|
||||
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x01 EP 1 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
|
||||
If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
|
||||
*/
|
||||
|
||||
static const usb_desc_ep_t bulk_out_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01, //EP 1 OUT
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
static const usb_desc_ep_t bulk_in_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x82, //EP 2 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
#define MOCK_MSC_SCSI_SECTOR_SIZE 512
|
||||
#define MOCK_MSC_SCSI_LUN 0
|
||||
#define MOCK_MSC_SCSI_INTF_NUMBER 0
|
||||
|
||||
#define MOCK_MSC_SCSI_REQ_INIT_RESET(ctrl_req_ptr, intf_num) ({ \
|
||||
(ctrl_req_ptr)->bRequestType = USB_B_REQUEST_TYPE_DIR_OUT | USB_B_REQUEST_TYPE_TYPE_CLASS | USB_B_REQUEST_TYPE_RECIP_INTERFACE; \
|
||||
(ctrl_req_ptr)->bRequest = 0xFF; \
|
||||
(ctrl_req_ptr)->wValue = 0; \
|
||||
(ctrl_req_ptr)->wIndex = (intf_num); \
|
||||
(ctrl_req_ptr)->wLength = 0; \
|
||||
})
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
|
||||
uint8_t flags;
|
||||
uint8_t lba_3;
|
||||
uint8_t lba_2;
|
||||
uint8_t lba_1;
|
||||
uint8_t lba_0;
|
||||
uint8_t group;
|
||||
uint8_t len_1;
|
||||
uint8_t len_0;
|
||||
uint8_t control;
|
||||
} mock_scsi_cmd10_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
mock_scsi_cmd10_t CBWCB;
|
||||
uint8_t padding[6];
|
||||
} mock_msc_bulk_cbw_t;
|
||||
|
||||
// USB Bulk Transfer Command Status Wrapper data
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bCSWStatus;
|
||||
} mock_msc_bulk_csw_t;
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
||||
static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe)
|
||||
{
|
||||
@ -130,51 +39,6 @@ static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe)
|
||||
test_hcd_free_urb(urb);
|
||||
}
|
||||
|
||||
static void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag)
|
||||
{
|
||||
cbw->dCBWSignature = 0x43425355; //Fixed value
|
||||
cbw->dCBWTag = tag; //Random value that is echoed back
|
||||
cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE;
|
||||
cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag
|
||||
cbw->bCBWLUN = MOCK_MSC_SCSI_LUN;
|
||||
cbw->bCBWCBLength = 10; //The length of the SCSI command
|
||||
//Initialize SCSI CMD as READ10 or WRITE 10
|
||||
cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; //SCSI CMD READ10 or WRITE10
|
||||
cbw->CBWCB.flags = 0;
|
||||
cbw->CBWCB.lba_3 = (offset >> 24);
|
||||
cbw->CBWCB.lba_2 = (offset >> 16);
|
||||
cbw->CBWCB.lba_1 = (offset >> 8);
|
||||
cbw->CBWCB.lba_0 = (offset >> 0);
|
||||
cbw->CBWCB.group = 0;
|
||||
cbw->CBWCB.len_1 = (num_sectors >> 8);
|
||||
cbw->CBWCB.len_0 = (num_sectors >> 0);
|
||||
cbw->CBWCB.control = 0;
|
||||
}
|
||||
|
||||
static bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect)
|
||||
{
|
||||
bool no_issues = true;
|
||||
if (csw->dCSWSignature != 0x53425355) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw signature corrupt (0x%X)\n", csw->dCSWSignature);
|
||||
}
|
||||
if (csw->dCSWTag != tag_expect) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw tag unexpected! Expected %d got %d\n", tag_expect, csw->dCSWTag);
|
||||
}
|
||||
if (csw->dCSWDataResidue) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates data residue of %d bytes!\n", csw->dCSWDataResidue);
|
||||
}
|
||||
if (csw->bCSWStatus) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus);
|
||||
}
|
||||
return no_issues;
|
||||
}
|
||||
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
||||
/*
|
||||
Test HCD bulk pipe URBs
|
||||
|
||||
@ -209,15 +73,15 @@ TEST_CASE("Test HCD bulk pipe URBs", "[hcd][ignore]")
|
||||
mock_msc_reset_req(default_pipe);
|
||||
|
||||
//Create BULK IN and BULK OUT pipes for SCSI
|
||||
hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, &bulk_out_ep_desc, dev_addr, port_speed);
|
||||
hcd_pipe_handle_t bulk_in_pipe = test_hcd_pipe_alloc(port_hdl, &bulk_in_ep_desc, dev_addr, port_speed);
|
||||
hcd_pipe_handle_t bulk_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_out_ep_desc, dev_addr, port_speed);
|
||||
hcd_pipe_handle_t bulk_in_pipe = test_hcd_pipe_alloc(port_hdl, &mock_msc_scsi_bulk_in_ep_desc, dev_addr, port_speed);
|
||||
//Create URBs for CBW, Data, and CSW transport. IN Buffer sizes are rounded up to nearest MPS
|
||||
urb_t *urb_cbw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_cbw_t));
|
||||
urb_t *urb_data = test_hcd_alloc_urb(0, TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE);
|
||||
urb_t *urb_csw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_csw_t) + (bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % bulk_in_ep_desc.wMaxPacketSize)));
|
||||
urb_t *urb_csw = test_hcd_alloc_urb(0, sizeof(mock_msc_bulk_csw_t) + (mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize)));
|
||||
urb_cbw->transfer.num_bytes = sizeof(mock_msc_bulk_cbw_t);
|
||||
urb_data->transfer.num_bytes = TEST_NUM_SECTORS_PER_XFER * MOCK_MSC_SCSI_SECTOR_SIZE;
|
||||
urb_csw->transfer.num_bytes = sizeof(mock_msc_bulk_csw_t) + (bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % bulk_in_ep_desc.wMaxPacketSize));
|
||||
urb_csw->transfer.num_bytes = sizeof(mock_msc_bulk_csw_t) + (mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize - (sizeof(mock_msc_bulk_csw_t) % mock_msc_scsi_bulk_in_ep_desc.wMaxPacketSize));
|
||||
|
||||
for (int block_num = 0; block_num < TEST_NUM_SECTORS_TOTAL; block_num += TEST_NUM_SECTORS_PER_XFER) {
|
||||
//Initialize CBW URB, then send it on the BULK OUT pipe
|
||||
|
@ -12,14 +12,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
|
||||
//Todo: Move all the port and PHY to here
|
||||
//Have a separate test file for INTR (HID), ISOC (UVC), and BULK (SCSI)
|
||||
//Each test case has a fixed HW device
|
||||
//Implements bare minimum for a MOCK protocol
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
@ -17,70 +17,9 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
// ------------------------------------------------- Mock HID Mice -----------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: The following test requires that USB low speed mouse be connected. The mouse should...
|
||||
|
||||
- Be implement the HID with standard report format used by mice
|
||||
- It's configuration 1 should have the following endpoint
|
||||
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0004 1x 4 bytes
|
||||
bInterval 10
|
||||
|
||||
If you're using another mice with different endpoints, modify the endpoint descriptor below
|
||||
*/
|
||||
static const usb_desc_ep_t in_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81, //EP 1 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
|
||||
.wMaxPacketSize = 4, //MPS of 4 bytes
|
||||
.bInterval = 10, //Interval of 10ms
|
||||
};
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t left_button: 1;
|
||||
uint32_t right_button: 1;
|
||||
uint32_t middle_button: 1;
|
||||
uint32_t reserved5: 5;
|
||||
uint8_t x_movement;
|
||||
uint8_t y_movement;
|
||||
} __attribute__((packed));
|
||||
uint8_t val[3];
|
||||
} mock_hid_mouse_report_t;
|
||||
_Static_assert(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect");
|
||||
|
||||
static void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter)
|
||||
{
|
||||
static int x_pos = 0;
|
||||
static int y_pos = 0;
|
||||
//Update X position
|
||||
if (report->x_movement & 0x80) { //Positive movement
|
||||
x_pos += report->x_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
x_pos -= report->x_movement & 0x7F;
|
||||
}
|
||||
//Update Y position
|
||||
if (report->y_movement & 0x80) { //Positive movement
|
||||
y_pos += report->y_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
y_pos -= report->y_movement & 0x7F;
|
||||
}
|
||||
printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter);
|
||||
}
|
||||
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
||||
/*
|
||||
@ -119,7 +58,7 @@ TEST_CASE("Test HCD interrupt pipe URBs", "[hcd][ignore]")
|
||||
uint8_t dev_addr = test_hcd_enum_device(default_pipe);
|
||||
|
||||
//Allocate interrupt pipe and URBS
|
||||
hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, &in_ep_desc, dev_addr, port_speed);
|
||||
hcd_pipe_handle_t intr_pipe = test_hcd_pipe_alloc(port_hdl, &mock_hid_mouse_in_ep_desc, dev_addr, port_speed);
|
||||
urb_t *urb_list[NUM_URBS];
|
||||
for (int i = 0; i < NUM_URBS; i++) {
|
||||
urb_list[i] = test_hcd_alloc_urb(0, URB_DATA_BUFF_SIZE);
|
||||
|
@ -18,26 +18,14 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
//We talk to a non-existent device. Since ISOC out requires no ACK, there should be no errors.
|
||||
#define MOCK_ISOC_EP_NUM 2
|
||||
#define MOCK_ISOC_EP_MPS 512
|
||||
|
||||
#define NUM_URBS 3
|
||||
#define NUM_PACKETS_PER_URB 3
|
||||
#define ISOC_PACKET_SIZE MOCK_ISOC_EP_MPS
|
||||
#define URB_DATA_BUFF_SIZE (NUM_PACKETS_PER_URB * ISOC_PACKET_SIZE)
|
||||
|
||||
static const usb_desc_ep_t isoc_out_ep_desc = {
|
||||
.bLength = sizeof(usb_desc_ep_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_ISOC_EP_NUM,
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
|
||||
.wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
|
||||
.bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
|
||||
};
|
||||
|
||||
/*
|
||||
Test HCD ISOC pipe URBs
|
||||
|
||||
@ -71,7 +59,7 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[hcd][ignore]")
|
||||
uint8_t dev_addr = test_hcd_enum_device(default_pipe);
|
||||
|
||||
//Create ISOC OUT pipe to non-existent device
|
||||
hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &isoc_out_ep_desc, dev_addr + 1, port_speed);
|
||||
hcd_pipe_handle_t isoc_out_pipe = test_hcd_pipe_alloc(port_hdl, &mock_isoc_out_ep_desc, dev_addr + 1, port_speed);
|
||||
//Create URBs
|
||||
urb_t *urb_list[NUM_URBS];
|
||||
//Initialize URBs
|
||||
|
Loading…
Reference in New Issue
Block a user