mirror of
https://github.com/hathach/tinyusb.git
synced 2026-02-05 11:15:44 +00:00
Merge branch 'master' into fork/ennebi/mtp
This commit is contained in:
@ -1,5 +1,3 @@
|
||||
DEPS_SUBMODULES += lib/lwip
|
||||
|
||||
include ../../make.mk
|
||||
|
||||
# suppress warning caused by lwip
|
||||
|
||||
@ -124,11 +124,5 @@ endif
|
||||
|
||||
# Log level is mapped to TUSB DEBUG option
|
||||
ifneq ($(LOG),)
|
||||
CMAKE_DEFSYM += -DLOG=$(LOG)
|
||||
CFLAGS += -DCFG_TUSB_DEBUG=$(LOG)
|
||||
endif
|
||||
|
||||
# Logger: default is uart, can be set to rtt or swo
|
||||
ifneq ($(LOGGER),)
|
||||
CMAKE_DEFSYM += -DLOGGER=$(LOGGER)
|
||||
endif
|
||||
|
||||
@ -143,7 +143,7 @@ endif
|
||||
# get depenecies
|
||||
.PHONY: get-deps
|
||||
get-deps:
|
||||
$(PYTHON) $(TOP)/tools/get_deps.py $(DEPS_SUBMODULES)
|
||||
$(PYTHON) $(TOP)/tools/get_deps.py $(FAMILY)
|
||||
|
||||
size: $(BUILD)/$(PROJECT)
|
||||
-@echo ''
|
||||
|
||||
@ -28,14 +28,20 @@ def main():
|
||||
else:
|
||||
toolchain = 'arm-gcc'
|
||||
|
||||
if 'build' in board and 'flags_on' in board['build']:
|
||||
for f in board['build']['flags_on']:
|
||||
if f == '':
|
||||
matrix[toolchain].append(f'-b {name}')
|
||||
else:
|
||||
matrix[toolchain].append(f'-b {name} -f1 {f.replace(" ", " -f1 ")}')
|
||||
build_board = f'-b {name}'
|
||||
if 'build' in board:
|
||||
if 'args' in board['build']:
|
||||
build_board += ' ' + ' '.join(f'-D{a}' for a in board['build']['args'])
|
||||
if 'flags_on' in board['build']:
|
||||
for f in board['build']['flags_on']:
|
||||
if f == '':
|
||||
matrix[toolchain].append(build_board)
|
||||
else:
|
||||
matrix[toolchain].append(f'{build_board} -f1 {f.replace(" ", " -f1 ")}')
|
||||
else:
|
||||
matrix[toolchain].append(build_board)
|
||||
else:
|
||||
matrix[toolchain].append(f'-b {name}')
|
||||
matrix[toolchain].append(build_board)
|
||||
|
||||
print(json.dumps(matrix))
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ def get_serial_dev(id, vendor_str, product_str, ifnum):
|
||||
return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}'
|
||||
else:
|
||||
# just use id: mostly for cp210x/ftdi flasher
|
||||
pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*'
|
||||
pattern = f'/dev/serial/by-id/usb-*_{id}-if*'
|
||||
port_list = glob.glob(pattern)
|
||||
return port_list[0]
|
||||
|
||||
@ -98,20 +98,18 @@ def get_hid_dev(id, vendor_str, product_str, event):
|
||||
def open_serial_dev(port):
|
||||
timeout = ENUM_TIMEOUT
|
||||
ser = None
|
||||
while timeout:
|
||||
while timeout > 0:
|
||||
if os.path.exists(port):
|
||||
try:
|
||||
# slight delay since kernel may occupy the port briefly
|
||||
time.sleep(0.5)
|
||||
timeout = timeout - 0.5
|
||||
ser = serial.Serial(port, baudrate=115200, timeout=5)
|
||||
break
|
||||
except serial.SerialException:
|
||||
print(f'serial {port} not reaady {timeout} sec')
|
||||
pass
|
||||
time.sleep(0.5)
|
||||
timeout = timeout - 0.5
|
||||
time.sleep(0.1)
|
||||
timeout -= 0.1
|
||||
|
||||
assert timeout, f'Cannot open port f{port}' if os.path.exists(port) else f'Port {port} not existed'
|
||||
assert timeout > 0, f'Cannot open port f{port}' if os.path.exists(port) else f'Port {port} not existed'
|
||||
return ser
|
||||
|
||||
|
||||
@ -119,7 +117,7 @@ def read_disk_file(uid, lun, fname):
|
||||
# open_fs("fat://{dev}) require 'pip install pyfatfs'
|
||||
dev = get_disk_dev(uid, 'TinyUSB', lun)
|
||||
timeout = ENUM_TIMEOUT
|
||||
while timeout:
|
||||
while timeout > 0:
|
||||
if os.path.exists(dev):
|
||||
fat = fs.open_fs(f'fat://{dev}?read_only=true')
|
||||
try:
|
||||
@ -132,7 +130,7 @@ def read_disk_file(uid, lun, fname):
|
||||
time.sleep(1)
|
||||
timeout -= 1
|
||||
|
||||
assert timeout, f'Storage {dev} not existed'
|
||||
assert timeout > 0, f'Storage {dev} not existed'
|
||||
return None
|
||||
|
||||
|
||||
@ -202,14 +200,14 @@ def reset_stflash(board):
|
||||
def flash_openocd(board, firmware):
|
||||
flasher = board['flasher']
|
||||
ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" '
|
||||
f'{flasher["args"]} -c init -c halt -c "program {firmware}.elf verify" -c reset -c exit')
|
||||
f'{flasher["args"]} -c "init; halt; program {firmware}.elf verify; reset; exit"')
|
||||
return ret
|
||||
|
||||
|
||||
def reset_openocd(board):
|
||||
flasher = board['flasher']
|
||||
ret = run_cmd(f'openocd -c "tcl_port disabled" -c "gdb_port disabled" -c "adapter serial {flasher["uid"]}" '
|
||||
f'{flasher["args"]} -c "reset exit"')
|
||||
f'{flasher["args"]} -c "init; reset run; exit"')
|
||||
return ret
|
||||
|
||||
|
||||
@ -304,11 +302,11 @@ def test_dual_host_info_to_device_cdc(board):
|
||||
ser = open_serial_dev(port)
|
||||
|
||||
# read from cdc, first line should contain vid/pid and serial
|
||||
data = ser.read(1000)
|
||||
data = ser.read(10000)
|
||||
ser.close()
|
||||
if len(data) == 0:
|
||||
assert False, 'No data from device'
|
||||
lines = data.decode('utf-8').splitlines()
|
||||
lines = data.decode('utf-8', errors='ignore').splitlines()
|
||||
|
||||
enum_dev_sn = []
|
||||
for l in lines:
|
||||
@ -319,6 +317,7 @@ def test_dual_host_info_to_device_cdc(board):
|
||||
|
||||
if set(declared_devs) != set(enum_dev_sn):
|
||||
failed_msg = f'Expected {declared_devs}, Enumerated {enum_dev_sn}'
|
||||
print('\n'.join(lines))
|
||||
assert False, failed_msg
|
||||
return 0
|
||||
|
||||
@ -337,12 +336,12 @@ def test_host_device_info(board):
|
||||
ret = globals()[f'reset_{flasher["name"].lower()}'](board)
|
||||
assert ret.returncode == 0, 'Failed to reset device'
|
||||
|
||||
data = ser.read(1000)
|
||||
data = ser.read(10000)
|
||||
ser.close()
|
||||
if len(data) == 0:
|
||||
assert False, 'No data from device'
|
||||
lines = data.decode('utf-8', errors='ignore').splitlines()
|
||||
|
||||
lines = data.decode('utf-8').splitlines()
|
||||
enum_dev_sn = []
|
||||
for l in lines:
|
||||
vid_pid_sn = re.search(r'ID ([0-9a-fA-F]+):([0-9a-fA-F]+) SN (\w+)', l)
|
||||
@ -352,8 +351,8 @@ def test_host_device_info(board):
|
||||
|
||||
if set(declared_devs) != set(enum_dev_sn):
|
||||
failed_msg = f'Expected {declared_devs}, Enumerated {enum_dev_sn}'
|
||||
print('\n'.join(lines))
|
||||
assert False, failed_msg
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@ -419,7 +418,7 @@ def test_device_dfu(board):
|
||||
|
||||
# Wait device enum
|
||||
timeout = ENUM_TIMEOUT
|
||||
while timeout:
|
||||
while timeout > 0:
|
||||
ret = run_cmd(f'dfu-util -l')
|
||||
stdout = ret.stdout.decode()
|
||||
if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout:
|
||||
@ -427,7 +426,7 @@ def test_device_dfu(board):
|
||||
time.sleep(1)
|
||||
timeout = timeout - 1
|
||||
|
||||
assert timeout, 'Device not available'
|
||||
assert timeout > 0, 'Device not available'
|
||||
|
||||
f_dfu0 = f'dfu0_{uid}'
|
||||
f_dfu1 = f'dfu1_{uid}'
|
||||
@ -460,7 +459,7 @@ def test_device_dfu_runtime(board):
|
||||
|
||||
# Wait device enum
|
||||
timeout = ENUM_TIMEOUT
|
||||
while timeout:
|
||||
while timeout > 0:
|
||||
ret = run_cmd(f'dfu-util -l')
|
||||
stdout = ret.stdout.decode()
|
||||
if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout:
|
||||
@ -468,7 +467,7 @@ def test_device_dfu_runtime(board):
|
||||
time.sleep(1)
|
||||
timeout = timeout - 1
|
||||
|
||||
assert timeout, 'Device not available'
|
||||
assert timeout > 0, 'Device not available'
|
||||
|
||||
|
||||
def test_device_hid_boot_interface(board):
|
||||
@ -478,13 +477,13 @@ def test_device_hid_boot_interface(board):
|
||||
mouse2 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse')
|
||||
# Wait device enum
|
||||
timeout = ENUM_TIMEOUT
|
||||
while timeout:
|
||||
while timeout > 0:
|
||||
if os.path.exists(kbd) and os.path.exists(mouse1) and os.path.exists(mouse2):
|
||||
break
|
||||
time.sleep(1)
|
||||
timeout = timeout - 1
|
||||
|
||||
assert timeout, 'HID device not available'
|
||||
assert timeout > 0, 'HID device not available'
|
||||
|
||||
|
||||
def test_device_hid_composite_freertos(id):
|
||||
@ -515,6 +514,64 @@ host_test = [
|
||||
]
|
||||
|
||||
|
||||
def test_example(board, f1, example):
|
||||
"""
|
||||
Test example firmware
|
||||
:param board: board dict
|
||||
:param f1: flags on
|
||||
:param example: example name
|
||||
:return: 0 if success/skip, 1 if failed
|
||||
"""
|
||||
name = board['name']
|
||||
err_count = 0
|
||||
|
||||
f1_str = ""
|
||||
if f1 != "":
|
||||
f1_str = '-f1_' + f1.replace(' ', '_')
|
||||
|
||||
fw_dir = f'{TINYUSB_ROOT}/cmake-build/cmake-build-{name}{f1_str}/{example}'
|
||||
if not os.path.exists(fw_dir):
|
||||
fw_dir = f'{TINYUSB_ROOT}/examples/cmake-build-{name}{f1_str}/{example}'
|
||||
fw_name = f'{fw_dir}/{os.path.basename(example)}'
|
||||
print(f'{name+f1_str:40} {example:30} ...', end='')
|
||||
|
||||
if not os.path.exists(fw_dir) or not (os.path.exists(f'{fw_name}.elf') or os.path.exists(f'{fw_name}.bin')):
|
||||
print('Skip (no binary)')
|
||||
return 0
|
||||
|
||||
if verbose:
|
||||
print(f'Flashing {fw_name}.elf')
|
||||
|
||||
# flash firmware. It may fail randomly, retry a few times
|
||||
max_rety = 3
|
||||
start_s = time.time()
|
||||
for i in range(max_rety):
|
||||
ret = globals()[f'flash_{board["flasher"]["name"].lower()}'](board, fw_name)
|
||||
if ret.returncode == 0:
|
||||
try:
|
||||
globals()[f'test_{example.replace("/", "_")}'](board)
|
||||
print(' OK', end='')
|
||||
break
|
||||
except Exception as e:
|
||||
if i == max_rety - 1:
|
||||
err_count += 1
|
||||
print(f'{STATUS_FAILED}: {e}')
|
||||
else:
|
||||
print(f'\n Test failed: {e}, retry {i+2}/{max_rety}', end='')
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
print(f'\n Flash failed, retry {i+2}/{max_rety}', end='')
|
||||
time.sleep(0.5)
|
||||
|
||||
if ret.returncode != 0:
|
||||
err_count += 1
|
||||
print(f' Flash {STATUS_FAILED}', end='')
|
||||
|
||||
print(f' in {time.time() - start_s:.1f}s')
|
||||
|
||||
return err_count
|
||||
|
||||
|
||||
def test_board(board):
|
||||
name = board['name']
|
||||
flasher = board['flasher']
|
||||
@ -538,56 +595,19 @@ def test_board(board):
|
||||
test_list.remove(skip)
|
||||
print(f'{name:25} {skip:30} ... Skip')
|
||||
|
||||
# board_test is added last to disable board's usb
|
||||
test_list.append('device/board_test')
|
||||
|
||||
err_count = 0
|
||||
flags_on_list = [""]
|
||||
if 'build' in board and 'flags_on' in board['build']:
|
||||
flags_on_list = board['build']['flags_on']
|
||||
|
||||
for f1 in flags_on_list:
|
||||
f1_str = ""
|
||||
if f1 != "":
|
||||
f1_str = '-f1_' + f1.replace(' ', '_')
|
||||
for test in test_list:
|
||||
fw_dir = f'{TINYUSB_ROOT}/cmake-build/cmake-build-{name}{f1_str}/{test}'
|
||||
if not os.path.exists(fw_dir):
|
||||
fw_dir = f'{TINYUSB_ROOT}/examples/cmake-build-{name}{f1_str}/{test}'
|
||||
fw_name = f'{fw_dir}/{os.path.basename(test)}'
|
||||
print(f'{name+f1_str:40} {test:30} ... ', end='')
|
||||
err_count += test_example(board, f1, test)
|
||||
|
||||
if not os.path.exists(fw_dir) or not (os.path.exists(f'{fw_name}.elf') or os.path.exists(f'{fw_name}.bin')):
|
||||
print('Skip (no binary)')
|
||||
continue
|
||||
# flash board_test last to disable board's usb
|
||||
test_example(board, flags_on_list[0], 'device/board_test')
|
||||
|
||||
# flash firmware. It may fail randomly, retry a few times
|
||||
max_rety = 2
|
||||
for i in range(max_rety):
|
||||
ret = globals()[f'flash_{flasher["name"].lower()}'](board, fw_name)
|
||||
if ret.returncode == 0:
|
||||
try:
|
||||
globals()[f'test_{test.replace("/", "_")}'](board)
|
||||
print('OK')
|
||||
break
|
||||
except Exception as e:
|
||||
if i == max_rety - 1:
|
||||
err_count += 1
|
||||
print(STATUS_FAILED)
|
||||
print(f' {e}')
|
||||
else:
|
||||
print()
|
||||
print(f' Test failed: {e}, retry {i+1}')
|
||||
time.sleep(1)
|
||||
else:
|
||||
print(f'Flashing failed, retry {i+1}')
|
||||
time.sleep(1)
|
||||
|
||||
if ret.returncode != 0:
|
||||
err_count += 1
|
||||
print(f'Flash {STATUS_FAILED}')
|
||||
|
||||
return err_count
|
||||
return name, err_count
|
||||
|
||||
|
||||
def main():
|
||||
@ -601,11 +621,13 @@ def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('config_file', help='Configuration JSON file')
|
||||
parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified')
|
||||
parser.add_argument('-s', '--skip', action='append', default=[], help='Skip boards from test')
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
|
||||
args = parser.parse_args()
|
||||
|
||||
config_file = args.config_file
|
||||
boards = args.board
|
||||
skip_boards = args.skip
|
||||
verbose = args.verbose
|
||||
|
||||
# if config file is not found, try to find it in the same directory as this script
|
||||
@ -615,12 +637,22 @@ def main():
|
||||
config = json.load(f)
|
||||
|
||||
if len(boards) == 0:
|
||||
config_boards = config['boards']
|
||||
config_boards = [e for e in config['boards'] if e['name'] not in skip_boards]
|
||||
else:
|
||||
config_boards = [e for e in config['boards'] if e['name'] in boards]
|
||||
|
||||
err_count = 0
|
||||
with Pool(processes=os.cpu_count()) as pool:
|
||||
err_count = sum(pool.map(test_board, config_boards))
|
||||
mret = pool.map(test_board, config_boards)
|
||||
err_count = sum(e[1] for e in mret)
|
||||
# generate skip list for next re-run if failed
|
||||
skip_fname = f'{config_file}.skip'
|
||||
if err_count > 0:
|
||||
skip_boards += [name for name, err in mret if err == 0]
|
||||
with open(skip_fname, 'w') as f:
|
||||
f.write(' '.join(f'-s {i}' for i in skip_boards))
|
||||
elif os.path.exists(skip_fname):
|
||||
os.remove(skip_fname)
|
||||
|
||||
duration = time.time() - duration
|
||||
print()
|
||||
|
||||
@ -21,16 +21,18 @@
|
||||
"name": "espressif_s3_devkitm",
|
||||
"uid": "84F703C084E4",
|
||||
"build" : {
|
||||
"flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE"]
|
||||
"flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE"]
|
||||
},
|
||||
"tests": {
|
||||
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"]
|
||||
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"],
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2005402"}]
|
||||
},
|
||||
"flasher": {
|
||||
"name": "esptool",
|
||||
"uid": "3ea619acd1cdeb11a0a0b806e93fd3f1",
|
||||
"args": "-b 1500000"
|
||||
}
|
||||
},
|
||||
"comment": "Use TS3USB30 mux to test both device and host"
|
||||
},
|
||||
{
|
||||
"name": "feather_nrf52840_express",
|
||||
@ -59,8 +61,11 @@
|
||||
{
|
||||
"name": "metro_m4_express",
|
||||
"uid": "9995AD485337433231202020FF100A34",
|
||||
"build" : {
|
||||
"args": ["MAX3421_HOST=1"]
|
||||
},
|
||||
"tests": {
|
||||
"device": true, "host": false, "dual": false,
|
||||
"device": true, "host": false, "dual": true,
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}]
|
||||
},
|
||||
"flasher": {
|
||||
@ -69,6 +74,19 @@
|
||||
"args": "-device ATSAMD51J19"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mimxrt1064_evk",
|
||||
"uid": "BAE96FB95AFA6DBB8F00005002001200",
|
||||
"tests": {
|
||||
"device": true, "host": true, "dual": true,
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2023299"}]
|
||||
},
|
||||
"flasher": {
|
||||
"name": "jlink",
|
||||
"uid": "000725299165",
|
||||
"args": "-device MIMXRT1064xxx6A"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lpcxpresso11u37",
|
||||
"uid": "17121919",
|
||||
@ -98,8 +116,11 @@
|
||||
{
|
||||
"name": "raspberry_pi_pico",
|
||||
"uid": "E6614C311B764A37",
|
||||
"build" : {
|
||||
"flags_on": ["CFG_TUH_RPI_PIO_USB"]
|
||||
},
|
||||
"tests": {
|
||||
"device": true, "host": false, "dual": false,
|
||||
"device": true, "host": true, "dual": true,
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}]
|
||||
},
|
||||
"flasher": {
|
||||
@ -108,11 +129,28 @@
|
||||
"args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "raspberry_pi_pico_w",
|
||||
"uid": "E6614C311B764A37",
|
||||
"tests": {
|
||||
"device": false, "host": true, "dual": false,
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2023934"}]
|
||||
},
|
||||
"flasher": {
|
||||
"name": "openocd",
|
||||
"uid": "E6633861A3819D38",
|
||||
"args": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\""
|
||||
},
|
||||
"comment": "Test native host"
|
||||
},
|
||||
{
|
||||
"name": "raspberry_pi_pico2",
|
||||
"uid": "560AE75E1C7152C9",
|
||||
"build" : {
|
||||
"flags_on": ["CFG_TUH_RPI_PIO_USB"]
|
||||
},
|
||||
"tests": {
|
||||
"device": true, "host": false, "dual": false,
|
||||
"device": true, "host": true, "dual": true,
|
||||
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}]
|
||||
},
|
||||
"flasher": {
|
||||
@ -157,9 +195,9 @@
|
||||
"device": true, "host": false, "dual": false
|
||||
},
|
||||
"flasher": {
|
||||
"name": "stlink",
|
||||
"name": "openocd",
|
||||
"uid": "004C00343137510F39383538",
|
||||
"args": ""
|
||||
"args": "-f interface/stlink.cfg -f target/stm32h7x.cfg"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@ -94,19 +94,21 @@ enum
|
||||
|
||||
uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE];
|
||||
|
||||
// Invoked when received SCSI_CMD_INQUIRY
|
||||
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||
{
|
||||
// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
|
||||
// Some inquiry_resp's fields are already filled with default values, application can update them
|
||||
// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
|
||||
uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp, uint32_t bufsize) {
|
||||
(void) lun;
|
||||
|
||||
(void) bufsize;
|
||||
const char vid[] = "TinyUSB";
|
||||
const char pid[] = "Mass Storage";
|
||||
const char rev[] = "1.0";
|
||||
|
||||
memcpy(vendor_id , vid, strlen(vid));
|
||||
memcpy(product_id , pid, strlen(pid));
|
||||
memcpy(product_rev, rev, strlen(rev));
|
||||
memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
|
||||
memcpy(inquiry_resp->product_id, pid, strlen(pid));
|
||||
memcpy(inquiry_resp->product_rev, rev, strlen(rev));
|
||||
|
||||
return sizeof(scsi_inquiry_resp_t); // 36 bytes
|
||||
}
|
||||
|
||||
// Invoked when received Test Unit Ready command.
|
||||
|
||||
Reference in New Issue
Block a user