Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update esp32 to also be supported by hil test #2356

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_esp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
# ESP32-S2
- 'espressif_kaluga_1'
# ESP32-S3
- 'espressif_s3_devkitm'
- 'espressif_s3_devkitc'

steps:
- name: Setup Python
Expand Down
1 change: 1 addition & 0 deletions examples/device/audio_4_channel_mic/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ mcu:SAMD11
mcu:SAME5X
mcu:SAMG
family:broadcom_64bit
family:espressif
1 change: 1 addition & 0 deletions examples/device/audio_test/skip.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:SAMD11
mcu:SAME5X
mcu:SAMG
family:espressif
1 change: 1 addition & 0 deletions examples/device/audio_test_multi_rate/skip.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:SAMD11
mcu:SAME5X
mcu:SAMG
family:espressif
5 changes: 5 additions & 0 deletions examples/device/board_test/src/tusb_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
#define CFG_TUSB_OS OPT_OS_NONE
#endif

// Espressif IDF requires "freertos/" prefix in include path
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
#define CFG_TUSB_OS_INC_PATH freertos/
#endif

// This example only test LED & GPIO, disable both device and host stack
#define CFG_TUD_ENABLED 0
#define CFG_TUH_ENABLED 0
Expand Down
1 change: 1 addition & 0 deletions examples/device/cdc_msc/skip.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mcu:SAMD11
family:espressif
8 changes: 4 additions & 4 deletions examples/device/cdc_msc_freertos/src/msc_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buff
uint8_t const* addr = msc_disk[lba] + offset;
memcpy(buffer, addr, bufsize);

return bufsize;
return (int32_t) bufsize;
}

// Callback invoked when received WRITE10 command.
Expand All @@ -203,7 +203,7 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t*
(void) lba; (void) offset; (void) buffer;
#endif

return bufsize;
return (int32_t) bufsize;
}

// Callback invoked when received an SCSI command not in built-in list below
Expand Down Expand Up @@ -237,14 +237,14 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
{
if(in_xfer)
{
memcpy(buffer, response, resplen);
memcpy(buffer, response, (size_t) resplen);
}else
{
// SCSI output
}
}

return resplen;
return (int32_t) resplen;
}

#endif
1 change: 1 addition & 0 deletions examples/device/dfu/skip.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mcu:TM4C123
mcu:BCM2835
family:espressif
1 change: 1 addition & 0 deletions examples/device/dynamic_configuration/skip.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mcu:SAMD11
family:espressif
1 change: 1 addition & 0 deletions examples/device/msc_dual_lun/skip.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mcu:SAMD11
mcu:MKL25ZXX
family:espressif
1 change: 1 addition & 0 deletions examples/device/net_lwip_webserver/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ family:broadcom_64bit
family:broadcom_32bit
board:curiosity_nano
board:frdm_kl25z
family:espressif
1 change: 1 addition & 0 deletions examples/device/uac2_headset/skip.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mcu:SAMD11
mcu:SAME5X
mcu:SAMG
board:stm32l052dap52
family:espressif
1 change: 1 addition & 0 deletions examples/device/usbtmc/skip.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mcu:BCM2835
family:espressif
1 change: 1 addition & 0 deletions examples/device/video_capture/skip.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mcu:MSP430x5xx
mcu:NUC121
mcu:SAMD11
family:espressif
8 changes: 8 additions & 0 deletions hw/bsp/espressif/boards/espressif_s3_devkitc/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
#define BUTTON_PIN 0
#define BUTTON_STATE_ACTIVE 0

// SPI for USB host shield
#define MAX3421_SPI_HOST SPI2_HOST
#define MAX3421_SCK_PIN 39
#define MAX3421_MOSI_PIN 42
#define MAX3421_MISO_PIN 21
#define MAX3421_CS_PIN 15
#define MAX3421_INTR_PIN 14

#ifdef __cplusplus
}
#endif
Expand Down
7 changes: 7 additions & 0 deletions hw/bsp/espressif/boards/family.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "board.h"

#include "esp_rom_gpio.h"
#include "esp_mac.h"
#include "hal/gpio_ll.h"
#include "hal/usb_hal.h"
#include "soc/usb_periph.h"
Expand Down Expand Up @@ -149,6 +150,12 @@ static void configure_pins(usb_hal_context_t* usb) {
// Board porting API
//--------------------------------------------------------------------+

size_t board_get_unique_id(uint8_t id[], size_t max_len) {
// use factory default MAC as serial ID
esp_efuse_mac_get_default(id);
return 6;
}

void board_led_write(bool state) {
#ifdef NEOPIXEL_PIN
strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00);
Expand Down
97 changes: 66 additions & 31 deletions test/hil/hil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,21 @@
import serial
import subprocess
import json
import glob

ENUM_TIMEOUT = 10


# get usb serial by id
def get_serial_dev(id, vendor_str, product_str, ifnum):
# get usb serial by id
return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}'
if vendor_str and product_str:
# known vendor and product
return f'/dev/serial/by-id/usb-{vendor_str}_{product_str}_{id}-if{ifnum:02d}'
else:
# just use id: mostly for cp210x/ftdi debugger
pattern = f'/dev/serial/by-id/usb-*_{id}-if{ifnum:02d}*'
port_list = glob.glob(pattern)
return port_list[0]


# Currently not used, left as reference
Expand All @@ -57,13 +65,14 @@ def open_serial_dev(port):
if os.path.exists(port):
try:
# slight delay since kernel may occupy the port briefly
time.sleep(0.2)
time.sleep(0.5)
timeout = timeout - 0.5
ser = serial.Serial(port, timeout=1)
break
except serial.SerialException:
pass
time.sleep(0.8)
timeout = timeout - 1
time.sleep(0.5)
timeout = timeout - 0.5
assert timeout, 'Device not available or Cannot open port'
return ser

Expand Down Expand Up @@ -92,23 +101,35 @@ def read_disk_file(id, fname):
# -------------------------------------------------------------
# Flash with debugger
# -------------------------------------------------------------
def flash_jlink(sn, dev, firmware):
def flash_jlink(board, firmware):
script = ['halt', 'r', f'loadfile {firmware}', 'r', 'go', 'exit']
f = open('flash.jlink', 'w')
f.writelines(f'{s}\n' for s in script)
f.close()
ret = subprocess.run(f'JLinkExe -USB {sn} -device {dev} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = ret.stdout.decode()
with open('flash.jlink', 'w') as f:
f.writelines(f'{s}\n' for s in script)
ret = subprocess.run(
f'JLinkExe -USB {board["debugger_sn"]} -device {board["cpu"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
os.remove('flash.jlink')
assert ret.returncode == 0, 'Flash failed\n' + stdout
return ret


def flash_openocd(sn, args, firmware):
ret = subprocess.run(f'openocd {args} -c "program {firmware} reset exit"',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = ret.stdout.decode()
assert ret.returncode == 0, 'Flash failed\n' + stdout
def flash_openocd(board, firmware):
ret = subprocess.run(
f'openocd -c "adapter serial {board["debugger_sn"]}" {board["debugger_args"]} -c "program {firmware} reset exit"',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return ret


def flash_esptool(board, firmware):
port = get_serial_dev(board["debugger_sn"], None, None, 0)
dir = os.path.dirname(firmware)
with open(f'{dir}/config.env') as f:
IDF_TARGET = json.load(f)['IDF_TARGET']
with open(f'{dir}/flash_args') as f:
flash_args = f.read().strip().replace('\n', ' ')
command = (f'esptool.py --chip {IDF_TARGET} -p {port} {board["debugger_args"]} '
f'--before=default_reset --after=hard_reset write_flash {flash_args}')
ret = subprocess.run(command, shell=True, cwd=dir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return ret


# -------------------------------------------------------------
Expand Down Expand Up @@ -160,12 +181,16 @@ def test_cdc_msc(id):
assert data == readme, 'MSC wrong data'


def test_cdc_msc_freertos(id):
test_cdc_msc(id)


def test_dfu(id):
# Wait device enum
timeout = ENUM_TIMEOUT
while timeout:
ret = subprocess.run(f'dfu-util -l',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = ret.stdout.decode()
if f'serial="{id}"' in stdout and 'Found DFU: [cafe:4000]' in stdout:
break
Expand All @@ -190,10 +215,10 @@ def test_dfu(id):
assert ret.returncode == 0, 'Upload failed'

with open('dfu0') as f:
assert 'Hello world from TinyUSB DFU! - Partition 0' in f.read(), 'Wrong uploaded data'
assert 'Hello world from TinyUSB DFU! - Partition 0' in f.read(), 'Wrong uploaded data'

with open('dfu1') as f:
assert 'Hello world from TinyUSB DFU! - Partition 1' in f.read(), 'Wrong uploaded data'
assert 'Hello world from TinyUSB DFU! - Partition 1' in f.read(), 'Wrong uploaded data'

os.remove('dfu0')
os.remove('dfu1')
Expand All @@ -204,7 +229,7 @@ def test_dfu_runtime(id):
timeout = ENUM_TIMEOUT
while timeout:
ret = subprocess.run(f'dfu-util -l',
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout = ret.stdout.decode()
if f'serial="{id}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout:
break
Expand All @@ -229,6 +254,14 @@ def test_hid_boot_interface(id):
assert timeout, 'Device not available'


def test_hid_composite_freertos(id):
# TODO implement later
pass


# -------------------------------------------------------------
# Main
# -------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage:')
Expand All @@ -238,10 +271,9 @@ def test_hid_boot_interface(id):
with open(f'{os.path.dirname(__file__)}/{sys.argv[1]}') as f:
config = json.load(f)

# all possible tests, board_test is last to disable board's usb
# all possible tests
all_tests = [
'cdc_dual_ports', 'cdc_msc', 'dfu', 'dfu_runtime', 'hid_boot_interface',
'board_test'
]

for board in config['boards']:
Expand All @@ -254,6 +286,9 @@ def test_hid_boot_interface(id):
else:
test_list = all_tests

# board_test is added last to disable board's usb
test_list.append('board_test')

# remove skip_tests
if 'tests_skip' in board:
for skip in board['tests_skip']:
Expand All @@ -278,13 +313,13 @@ def test_hid_boot_interface(id):
print(f'Cannot find firmware file for {test}')
sys.exit(-1)

if debugger == 'jlink':
flash_jlink(board['debugger_sn'], board['cpu'], elf)
elif debugger == 'openocd':
flash_openocd(board['debugger_sn'], board['debugger_args'], elf)
else:
# ToDo
pass
print(f' {test} ...', end='')

# flash firmware
ret = locals()[f'flash_{debugger}'](board, elf)
assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode()

# run test
locals()[f'test_{test}'](board['uid'])

print('OK')
1 change: 1 addition & 0 deletions tools/build_esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def filter_with_input(mylist):
# Build all examples if not specified
all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")]
filter_with_input(all_examples)
all_examples.append('device/board_test')
all_examples.sort()

# Build all boards if not specified
Expand Down