Skip to content

Commit

Permalink
Merge pull request #2356 from hathach/hil-esp32s3
Browse files Browse the repository at this point in the history
update esp32 to also be supported by hil test
  • Loading branch information
hathach authored Nov 29, 2023
2 parents be4d652 + c1dbeb5 commit 0877a48
Show file tree
Hide file tree
Showing 18 changed files with 103 additions and 36 deletions.
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

0 comments on commit 0877a48

Please sign in to comment.