From 0c220ea127a85ab75c84f141400a1fc532612d72 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Sat, 1 Nov 2025 00:20:49 +0800 Subject: [PATCH] chore: add build ci Signed-off-by: sakumisu <1203593632@qq.com> --- .github/workflows/build_tests.yml | 57 ++ .gitignore | 1 + README.md | 2 +- README_zh.md | 2 +- tests/espressif/device/CMakeLists.txt | 9 + tests/espressif/device/main/CMakeLists.txt | 4 + tests/espressif/device/main/main.c | 27 + tests/espressif/device/sdkconfig.defaults | 7 + tests/espressif/host/CMakeLists.txt | 9 + tests/espressif/host/main/CMakeLists.txt | 4 + tests/espressif/host/main/main.c | 33 ++ tests/espressif/host/sdkconfig.defaults | 8 + tests/hpmicro/CMakeLists.txt | 53 ++ tests/hpmicro/inc/FreeRTOSConfig.h | 154 +++++ tests/hpmicro/inc/arch/cc.h | 91 +++ tests/hpmicro/inc/arch/sys_arch.c | 646 +++++++++++++++++++++ tests/hpmicro/inc/arch/sys_arch.h | 108 ++++ tests/hpmicro/inc/lwipopts.h | 202 +++++++ tests/hpmicro/inc/usb_config.h | 309 ++++++++++ tests/hpmicro/src/main.c | 104 ++++ 20 files changed, 1828 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/build_tests.yml create mode 100644 tests/espressif/device/CMakeLists.txt create mode 100644 tests/espressif/device/main/CMakeLists.txt create mode 100644 tests/espressif/device/main/main.c create mode 100644 tests/espressif/device/sdkconfig.defaults create mode 100644 tests/espressif/host/CMakeLists.txt create mode 100644 tests/espressif/host/main/CMakeLists.txt create mode 100644 tests/espressif/host/main/main.c create mode 100644 tests/espressif/host/sdkconfig.defaults create mode 100644 tests/hpmicro/CMakeLists.txt create mode 100644 tests/hpmicro/inc/FreeRTOSConfig.h create mode 100644 tests/hpmicro/inc/arch/cc.h create mode 100644 tests/hpmicro/inc/arch/sys_arch.c create mode 100644 tests/hpmicro/inc/arch/sys_arch.h create mode 100644 tests/hpmicro/inc/lwipopts.h create mode 100644 tests/hpmicro/inc/usb_config.h create mode 100644 tests/hpmicro/src/main.c diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml new file mode 100644 index 00000000..fe51da16 --- /dev/null +++ b/.github/workflows/build_tests.yml @@ -0,0 +1,57 @@ +name: Build Tests + +on: + push: + branches: + - master + - release/v1.5 + pull_request: + branches: + - master + - release/v1.5 + +jobs: + build_hpmicro: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y cmake ninja-build + + - name: Download hpm_sdk + run: | + cd ~ + git clone https://github.com/hpmicro/hpm_sdk.git + + - name: Download RISC-V toolchain + run: | + cd ~ + wget https://github.com/hpmicro/riscv-gnu-toolchain/releases/download/2023.10.18/rv32imac_zicsr_zifencei_multilib_b_ext-linux.tar.gz + tar -xzf rv32imac_zicsr_zifencei_multilib_b_ext-linux.tar.gz + + - name: Build hpm demo + run: | + cd tests/hpmicro + export HPM_SDK_BASE=~/hpm_sdk + export GNURISCV_TOOLCHAIN_PATH=~/rv32imac_zicsr_zifencei_multilib_b_ext-linux + export HPM_SDK_TOOLCHAIN_VARIANT= + cmake -S . -B build -GNinja -DBOARD=hpm6750evk2 -DCMAKE_BUILD_TYPE=flash_sdram_xip -DEXTRA_C_FLAGS="-Werror";cmake --build build + + build_espressif: + strategy: + matrix: + idf_ver: ["latest"] + runs-on: ubuntu-latest + container: espressif/idf:${{ matrix.idf_ver }} + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Build espressif demo + shell: bash + run: | + . ${IDF_PATH}/export.sh + pip install idf-component-manager ruamel.yaml idf-build-apps --upgrade + idf-build-apps build -p ./tests/espressif --recursive --target esp32s3 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 22b1a7fa..9ebda7a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode +build **/Drivers/** **/MDK-ARM/DebugConfig/** **/MDK-ARM/RTE/** diff --git a/README.md b/README.md index 2b570971..d364ed64 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ TODO |Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | |Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | |Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing | +|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official | |Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | |Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | |SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | diff --git a/README_zh.md b/README_zh.md index 64287a55..1e1ec40c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -197,7 +197,7 @@ TODO |Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | |Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | |Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing | +|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)/[espressif](https://github.com/espressif/esp-idf/tree/master/examples/peripherals/usb)|<= latest | Official | |Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | |Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | |SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | diff --git a/tests/espressif/device/CMakeLists.txt b/tests/espressif/device/CMakeLists.txt new file mode 100644 index 00000000..81106a1f --- /dev/null +++ b/tests/espressif/device/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +list(APPEND EXTRA_COMPONENT_DIRS "../../../../CherryUSB") + +project(cherryusb) diff --git a/tests/espressif/device/main/CMakeLists.txt b/tests/espressif/device/main/CMakeLists.txt new file mode 100644 index 00000000..c45ba355 --- /dev/null +++ b/tests/espressif/device/main/CMakeLists.txt @@ -0,0 +1,4 @@ + +idf_component_register(SRCS "main.c" + INCLUDE_DIRS "." + WHOLE_ARCHIVE) diff --git a/tests/espressif/device/main/main.c b/tests/espressif/device/main/main.c new file mode 100644 index 00000000..5bac5dc7 --- /dev/null +++ b/tests/espressif/device/main/main.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "usbd_core.h" +#include "usbh_core.h" +#include "demo/cdc_acm_msc_template.c" + +extern void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base); + +void app_main(void) +{ + USB_LOG_INFO("Hello CherryUSB!\n"); + + cdc_acm_msc_init(0, 0x60080000); + while(1) + { + vTaskDelay(10); + } +} diff --git a/tests/espressif/device/sdkconfig.defaults b/tests/espressif/device/sdkconfig.defaults new file mode 100644 index 00000000..5b0ebb57 --- /dev/null +++ b/tests/espressif/device/sdkconfig.defaults @@ -0,0 +1,7 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# +CONFIG_CHERRYUSB=y +CONFIG_CHERRYUSB_DEVICE=y +CONFIG_CHERRYUSB_DEVICE_CDC_ACM=y +CONFIG_CHERRYUSB_DEVICE_HID=y +CONFIG_CHERRYUSB_DEVICE_MSC=y diff --git a/tests/espressif/host/CMakeLists.txt b/tests/espressif/host/CMakeLists.txt new file mode 100644 index 00000000..81106a1f --- /dev/null +++ b/tests/espressif/host/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +list(APPEND EXTRA_COMPONENT_DIRS "../../../../CherryUSB") + +project(cherryusb) diff --git a/tests/espressif/host/main/CMakeLists.txt b/tests/espressif/host/main/CMakeLists.txt new file mode 100644 index 00000000..c45ba355 --- /dev/null +++ b/tests/espressif/host/main/CMakeLists.txt @@ -0,0 +1,4 @@ + +idf_component_register(SRCS "main.c" + INCLUDE_DIRS "." + WHOLE_ARCHIVE) diff --git a/tests/espressif/host/main/main.c b/tests/espressif/host/main/main.c new file mode 100644 index 00000000..3d18171b --- /dev/null +++ b/tests/espressif/host/main/main.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "esp_log.h" +#include "usbd_core.h" +#include "usbh_core.h" +#include "demo/usb_host.c" + +void app_main(void) +{ + USB_LOG_INFO("Hello CherryUSB!\n"); + + // Initialize TCP/IP network interface aka the esp-netif (should be called only once in application) + ESP_ERROR_CHECK(esp_netif_init()); + // Create default event loop that running in background + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + usbh_initialize(0, 0x60080000, NULL); + while(1) + { + vTaskDelay(10); + } +} diff --git a/tests/espressif/host/sdkconfig.defaults b/tests/espressif/host/sdkconfig.defaults new file mode 100644 index 00000000..409082e9 --- /dev/null +++ b/tests/espressif/host/sdkconfig.defaults @@ -0,0 +1,8 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# +CONFIG_CHERRYUSB=y +CONFIG_CHERRYUSB_HOST=y +CONFIG_CHERRYUSB_HOST_CUSTOM=y +CONFIG_CHERRYUSB_HOST_CDC_ACM=y +CONFIG_CHERRYUSB_HOST_HID=y +CONFIG_CHERRYUSB_HOST_CDC_RNDIS=y diff --git a/tests/hpmicro/CMakeLists.txt b/tests/hpmicro/CMakeLists.txt new file mode 100644 index 00000000..5824878c --- /dev/null +++ b/tests/hpmicro/CMakeLists.txt @@ -0,0 +1,53 @@ +# Copyright (c) 2021 HPMicro +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.13) + +set(CONFIG_CHERRYSH 1) +set(CONFIG_CHERRYSH_INTERFACE "uart") +set(CONFIG_USB_DEVICE 1) + +set(CONFIG_FREERTOS 1) +set(CONFIG_LWIP 1) +set(CONFIG_LWIP_IPERF 1) +set(CONFIG_LWIP_STRERR 1) +set(CONFIG_LWIP_NETDB 1) +set(CONFIG_LWIP_SOCKET_API 1) + +set(CONFIG_HPM_PANEL 1) + +find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE}) +project(cherryusb) + +sdk_compile_definitions(-D__freertos_irq_stack_top=_stack) +sdk_compile_definitions(-DCONFIG_FREERTOS=1) +sdk_compile_definitions(-DUSE_NONVECTOR_MODE=1) +sdk_compile_definitions(-DDISABLE_IRQ_PREEMPTIVE=1) + +sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_ECM) +sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_NCM) +sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_RNDIS) +sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_ASIX) +sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_RTL8152) + +sdk_inc(inc) +sdk_app_src(inc/arch/sys_arch.c) +sdk_app_src(src/main.c) +sdk_app_src(../../demo/usb_host.c) +# sdk_app_src(src/uvc2lcd.c) +# sdk_app_src(src/font24x48.c) + +# sdk_inc(src/iperf) +# sdk_app_src(src/iperf/iperf.c src/iperf/iperf_cli.c src/iperf/utils_getopt.c src/ping.c) + +# sdk_app_src(src/usbh_uvc_port.c) + +set(CONFIG_CHERRYMP 1) +set(CONFIG_CHERRYUSB 1) +set(CONFIG_CHERRYUSB_DEVICE 1) +set(CONFIG_CHERRYUSB_HOST 1) + +# add_subdirectory(src/cherryusb_hostuvcuac) +add_subdirectory(../.. cherryusb) + +generate_ses_project() diff --git a/tests/hpmicro/inc/FreeRTOSConfig.h b/tests/hpmicro/inc/FreeRTOSConfig.h new file mode 100644 index 00000000..d2169531 --- /dev/null +++ b/tests/hpmicro/inc/FreeRTOSConfig.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + */ + +#include "board.h" +#if (portasmHAS_MTIME == 0) +#define configMTIME_BASE_ADDRESS (0) +#define configMTIMECMP_BASE_ADDRESS (0) +#else +#define configMTIME_BASE_ADDRESS (HPM_MCHTMR_BASE) +#define configMTIMECMP_BASE_ADDRESS (HPM_MCHTMR_BASE + 8UL) +#endif + +#define configUSE_PREEMPTION 1 +#define configCPU_CLOCK_HZ ((uint32_t) 24000000) +#define configTICK_RATE_HZ ((TickType_t) 1000) +#define configMAX_PRIORITIES (32) +#define configMINIMAL_STACK_SIZE (256) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configGENERATE_RUN_TIME_STATS 0 + +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_MUTEXES 1 + +/* Memory allocation definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#ifndef configTOTAL_HEAP_SIZE +#define configTOTAL_HEAP_SIZE ((size_t) (120 * 1024)) +#endif + +/* Hook function definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH 4 +#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE) + +/* Task priorities.*/ +#ifndef uartPRIMARY_PRIORITY + #define uartPRIMARY_PRIORITY (configMAX_PRIORITIES - 3) +#endif + +/* Normal assert() semantics without relying on the provision of an assert.h header file. */ +#define configASSERT(x) if ((x) == 0) { taskDISABLE_INTERRUPTS(); __asm volatile("ebreak"); for (;;); } + +/* + * The size of the global output buffer that is available for use when there + * are multiple command interpreters running at once (for example, one on a UART + * and one on TCP/IP). This is done to prevent an output buffer being defined by + * each implementation - which would waste RAM. In this case, there is only one + * command interpreter running. + */ + +/* + * The buffer into which output generated by FreeRTOS+CLI is placed. This must + * be at least big enough to contain the output of the task-stats command, as the + * example implementation does not include buffer overlow checking. + */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096 +#define configINCLUDE_QUERY_HEAP_COMMAND 1 + +/* This file is included from assembler files - make sure C code is not included in assembler files. */ +#ifndef __ASSEMBLER__ + void vAssertCalled(const char *pcFile, unsigned long ulLine); + void vConfigureTickInterrupt(void); + void vClearTickInterrupt(void); + void vPreSleepProcessing(unsigned long uxExpectedIdleTime); + void vPostSleepProcessing(unsigned long uxExpectedIdleTime); +#endif /* __ASSEMBLER__ */ + +/****** Hardware/compiler specific settings. *******/ +/* + * The application must provide a function that configures a peripheral to + * create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT() + * in FreeRTOSConfig.h to call the function. + */ +#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt() +#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt() + +/* + * The configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros + * allow the application writer to add additional code before and after the MCU is + * placed into the low power state respectively. The empty implementations + * provided in this demo can be extended to save even more power. + */ +#define configPRE_SLEEP_PROCESSING(uxExpectedIdleTime) vPreSleepProcessing(uxExpectedIdleTime); +#define configPOST_SLEEP_PROCESSING(uxExpectedIdleTime) vPostSleepProcessing(uxExpectedIdleTime); + + +/* Compiler specifics. */ +#define fabs(x) __builtin_fabs(x) + +/* Enable Hardware Stack Protection and Recording mechanism. */ +#define configHSP_ENABLE 0 + +/* Record the highest address of stack. */ +#if (configHSP_ENABLE == 1 && configRECORD_STACK_HIGH_ADDRESS != 1) +#define configRECORD_STACK_HIGH_ADDRESS 1 +#endif + +#endif /* FREERTOS_CONFIG_H */ diff --git a/tests/hpmicro/inc/arch/cc.h b/tests/hpmicro/inc/arch/cc.h new file mode 100644 index 00000000..4c527c03 --- /dev/null +++ b/tests/hpmicro/inc/arch/cc.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * Copyright (c) 2021-2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef __CC_H__ +#define __CC_H__ + +#include + +#define U16_F "hu" +#define S16_F "d" +#define X16_F "hx" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) printf(x) + +#ifndef LWIP_MEM_SECTION +#define LWIP_MEM_SECTION ".framebuffer" +#endif + +#endif /* __CC_H__ */ diff --git a/tests/hpmicro/inc/arch/sys_arch.c b/tests/hpmicro/inc/arch/sys_arch.c new file mode 100644 index 00000000..24e2dda8 --- /dev/null +++ b/tests/hpmicro/inc/arch/sys_arch.c @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2017 Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +/* + * Copyright (c) 2021-2022 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "lwip/tcpip.h" + +#if !NO_SYS +#include "FreeRTOS.h" +#include "semphr.h" +#endif + +#if !NO_SYS +#include "sys_arch.h" +#endif + +int errno; +#if !NO_SYS +/** Set this to 1 if you want the stack size passed to sys_thread_new() to be + * interpreted as number of stack words (FreeRTOS-like). + * Default is that they are interpreted as byte count (lwIP-like). + */ +#ifndef LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS +#define LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS 0 +#endif + +/** Set this to 1 to use a mutex for SYS_ARCH_PROTECT() critical regions. + * Default is 0 and locks interrupts/scheduler for SYS_ARCH_PROTECT(). + */ +#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX +#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX 0 +#endif + +/** Set this to 1 to include a sanity check that SYS_ARCH_PROTECT() and + * SYS_ARCH_UNPROTECT() are called matching. + */ +#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK +#define LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK 0 +#endif + +/** Set this to 1 to let sys_mbox_free check that queues are empty when freed */ +#ifndef LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE +#define LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE 0 +#endif + +/** Set this to 1 to enable core locking check functions in this port. + * For this to work, you'll have to define LWIP_ASSERT_CORE_LOCKED() + * and LWIP_MARK_TCPIP_THREAD() correctly in your lwipopts.h! */ +#ifndef LWIP_FREERTOS_CHECK_CORE_LOCKING +#define LWIP_FREERTOS_CHECK_CORE_LOCKING 1 +#endif + +/** Set this to 0 to implement sys_now() yourself, e.g. using a hw timer. + * Default is 1, where FreeRTOS ticks are used to calculate back to ms. + */ +#ifndef LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS +#define LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS 1 +#endif + +#if !configSUPPORT_DYNAMIC_ALLOCATION +# error "lwIP FreeRTOS port requires configSUPPORT_DYNAMIC_ALLOCATION" +#endif +#if !INCLUDE_vTaskDelay +# error "lwIP FreeRTOS port requires INCLUDE_vTaskDelay" +#endif +#if !INCLUDE_vTaskSuspend +# error "lwIP FreeRTOS port requires INCLUDE_vTaskSuspend" +#endif +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX || !LWIP_COMPAT_MUTEX +#if !configUSE_MUTEXES +# error "lwIP FreeRTOS port requires configUSE_MUTEXES" +#endif +#endif + +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX +static SemaphoreHandle_t sys_arch_protect_mutex; +#endif +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK +static sys_prot_t sys_arch_protect_nesting; +#endif + +/* Initialize this module (see description in sys.h) */ +void +sys_init(void) +{ +#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + /* initialize sys_arch_protect global mutex */ + sys_arch_protect_mutex = xSemaphoreCreateRecursiveMutex(); + LWIP_ASSERT("failed to create sys_arch_protect mutex", + sys_arch_protect_mutex != NULL); +#endif /* SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ +} + +#if configUSE_16_BIT_TICKS == 1 +#error This port requires 32 bit ticks or timer overflow will fail +#endif + +#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS +u32_t +sys_now(void) +{ + return xTaskGetTickCount() * portTICK_PERIOD_MS; +} +#else +u32_t +sys_now(void) +{ + return 0; +} +#endif + +u32_t +sys_jiffies(void) +{ + return xTaskGetTickCount(); +} + +#if SYS_LIGHTWEIGHT_PROT + +sys_prot_t +sys_arch_protect(void) +{ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + BaseType_t ret; + LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL); + + ret = xSemaphoreTakeRecursive(sys_arch_protect_mutex, portMAX_DELAY); + LWIP_ASSERT("sys_arch_protect failed to take the mutex", ret == pdTRUE); +#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + taskENTER_CRITICAL(); +#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK + { + /* every nested call to sys_arch_protect() returns an increased number */ + sys_prot_t ret = sys_arch_protect_nesting; + sys_arch_protect_nesting++; + LWIP_ASSERT("sys_arch_protect overflow", sys_arch_protect_nesting > ret); + return ret; + } +#else + return 1; +#endif +} + +void +sys_arch_unprotect(sys_prot_t pval) +{ +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + BaseType_t ret; +#endif +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK + LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting > 0); + sys_arch_protect_nesting--; + LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting == pval); +#endif + +#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX + LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL); + + ret = xSemaphoreGiveRecursive(sys_arch_protect_mutex); + LWIP_ASSERT("sys_arch_unprotect failed to give the mutex", ret == pdTRUE); +#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + taskEXIT_CRITICAL(); +#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */ + LWIP_UNUSED_ARG(pval); +} + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +void +sys_arch_msleep(u32_t delay_ms) +{ + TickType_t delay_ticks = delay_ms / portTICK_RATE_MS; + vTaskDelay(delay_ticks); +} + +#if !LWIP_COMPAT_MUTEX + +/* Create a new mutex*/ +err_t +sys_mutex_new(sys_mutex_t *mutex) +{ + LWIP_ASSERT("mutex != NULL", mutex != NULL); + + mutex->mut = xSemaphoreCreateRecursiveMutex(); + if (mutex->mut == NULL) { + SYS_STATS_INC(mutex.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(mutex); + return ERR_OK; +} + +void +sys_mutex_lock(sys_mutex_t *mutex) +{ + BaseType_t ret; + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY); + LWIP_ASSERT("failed to take the mutex", ret == pdTRUE); +} + +void +sys_mutex_unlock(sys_mutex_t *mutex) +{ + BaseType_t ret; + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + ret = xSemaphoreGiveRecursive(mutex->mut); + LWIP_ASSERT("failed to give the mutex", ret == pdTRUE); +} + +void +sys_mutex_free(sys_mutex_t *mutex) +{ + LWIP_ASSERT("mutex != NULL", mutex != NULL); + LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); + + SYS_STATS_DEC(mutex.used); + vSemaphoreDelete(mutex->mut); + mutex->mut = NULL; +} + +#endif /* !LWIP_COMPAT_MUTEX */ + +err_t +sys_sem_new(sys_sem_t *sem, u8_t initial_count) +{ + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("initial_count invalid (not 0 or 1)", + (initial_count == 0) || (initial_count == 1)); + + sem->sem = xSemaphoreCreateBinary(); + if (sem->sem == NULL) { + SYS_STATS_INC(sem.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(sem); + + if (initial_count == 1) { + BaseType_t ret = xSemaphoreGive(sem->sem); + LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE); + } + return ERR_OK; +} + +void +sys_sem_signal(sys_sem_t *sem) +{ + BaseType_t ret; + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + ret = xSemaphoreGive(sem->sem); + /* queue full is OK, this is a signal only... */ + LWIP_ASSERT("sys_sem_signal: sane return value", + (ret == pdTRUE) || (ret == errQUEUE_FULL)); +} + +u32_t +sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms) +{ + BaseType_t ret; + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + if (!timeout_ms) { + /* wait infinite */ + ret = xSemaphoreTake(sem->sem, portMAX_DELAY); + LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); + } else { + TickType_t timeout_ticks = timeout_ms / portTICK_RATE_MS; + ret = xSemaphoreTake(sem->sem, timeout_ticks); + if (ret == errQUEUE_EMPTY) { + /* timed out */ + return SYS_ARCH_TIMEOUT; + } + LWIP_ASSERT("taking semaphore failed", ret == pdTRUE); + } + + /* Old versions of lwIP required us to return the time waited. + This is not the case any more. Just returning != SYS_ARCH_TIMEOUT + here is enough. */ + return 1; +} + +void +sys_sem_free(sys_sem_t *sem) +{ + LWIP_ASSERT("sem != NULL", sem != NULL); + LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); + + SYS_STATS_DEC(sem.used); + vSemaphoreDelete(sem->sem); + sem->sem = NULL; +} + +err_t +sys_mbox_new(sys_mbox_t *mbox, int size) +{ + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("size > 0", size > 0); + + mbox->mbx = xQueueCreate((UBaseType_t)size, sizeof(void *)); + if (mbox->mbx == NULL) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + SYS_STATS_INC_USED(mbox); + return ERR_OK; +} + +void +sys_mbox_post(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY); + LWIP_ASSERT("mbox post failed", ret == pdTRUE); +} + +err_t +sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBack(mbox->mbx, &msg, 0); + if (ret == pdTRUE) { + return ERR_OK; + } else { + LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL); + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } +} + +err_t +sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) +{ + BaseType_t ret; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken); + if (ret == pdTRUE) { + if (xHigherPriorityTaskWoken == pdTRUE) { + return ERR_NEED_SCHED; + } + return ERR_OK; + } else { + LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL); + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } +} + +u32_t +sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms) +{ + BaseType_t ret; + void *msg_dummy; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + if (!msg) { + msg = &msg_dummy; + } + + if (!timeout_ms) { + /* wait infinite */ + ret = xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY); + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + } else { + TickType_t timeout_ticks = timeout_ms / portTICK_RATE_MS; + ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks); + if (ret == errQUEUE_EMPTY) { + /* timed out */ + *msg = NULL; + return SYS_ARCH_TIMEOUT; + } + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + } + + /* Old versions of lwIP required us to return the time waited. + This is not the case any more. Just returning != SYS_ARCH_TIMEOUT + here is enough. */ + return 1; +} + +u32_t +sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ + BaseType_t ret; + void *msg_dummy; + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + + if (!msg) { + msg = &msg_dummy; + } + + ret = xQueueReceive(mbox->mbx, &(*msg), 0); + if (ret == errQUEUE_EMPTY) { + *msg = NULL; + return SYS_MBOX_EMPTY; + } + LWIP_ASSERT("mbox fetch failed", ret == pdTRUE); + + /* Old versions of lwIP required us to return the time waited. + This is not the case any more. Just returning != SYS_ARCH_TIMEOUT + here is enough. */ + return 1; +} + +void +sys_mbox_free(sys_mbox_t *mbox) +{ + LWIP_ASSERT("mbox != NULL", mbox != NULL); + LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); + +#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE + { + UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx); + LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0); + + if (msgs_waiting != 0) { + SYS_STATS_INC(mbox.err); + } + } +#endif + + vQueueDelete(mbox->mbx); + + SYS_STATS_DEC(mbox.used); +} + +sys_thread_t +sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio) +{ + TaskHandle_t rtos_task; + BaseType_t ret; + sys_thread_t lwip_thread; + size_t rtos_stacksize; + + LWIP_ASSERT("invalid stacksize", stacksize > 0); +#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS + rtos_stacksize = (size_t)stacksize; +#else + rtos_stacksize = (size_t)stacksize / sizeof(StackType_t); +#endif + + /* lwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the + thread function without adaption here. */ + ret = xTaskCreate(thread, name, (configSTACK_DEPTH_TYPE)rtos_stacksize, arg, prio, &rtos_task); + LWIP_ASSERT("task creation failed", ret == pdTRUE); + + lwip_thread.thread_handle = rtos_task; + return lwip_thread; +} + +#if LWIP_NETCONN_SEM_PER_THREAD +#if configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 + +sys_sem_t * +sys_arch_netconn_sem_get(void) +{ + void *ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + return ret; +} + +void +sys_arch_netconn_sem_alloc(void) +{ + void *ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + if (ret == NULL) { + sys_sem_t *sem; + err_t err; + /* need to allocate the memory for this semaphore */ + sem = mem_malloc(sizeof(sys_sem_t)); + LWIP_ASSERT("sem != NULL", sem != NULL); + err = sys_sem_new(sem, 0); + LWIP_ASSERT("err == ERR_OK", err == ERR_OK); + LWIP_ASSERT("sem invalid", sys_sem_valid(sem)); + vTaskSetThreadLocalStoragePointer(task, 0, sem); + } +} + +void sys_arch_netconn_sem_free(void) +{ + void *ret; + TaskHandle_t task = xTaskGetCurrentTaskHandle(); + LWIP_ASSERT("task != NULL", task != NULL); + + ret = pvTaskGetThreadLocalStoragePointer(task, 0); + if (ret != NULL) { + sys_sem_t *sem = ret; + sys_sem_free(sem); + mem_free(sem); + vTaskSetThreadLocalStoragePointer(task, 0, NULL); + } +} + +#else /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */ +#error LWIP_NETCONN_SEM_PER_THREAD needs configNUM_THREAD_LOCAL_STORAGE_POINTERS +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */ + +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +#if LWIP_FREERTOS_CHECK_CORE_LOCKING +#if LWIP_TCPIP_CORE_LOCKING + +/** Flag the core lock held. A counter for recursive locks. */ +static u8_t lwip_core_lock_count; +static TaskHandle_t lwip_core_lock_holder_thread; + +void +sys_lock_tcpip_core(void) +{ + sys_mutex_lock(&lock_tcpip_core); + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle(); + } + lwip_core_lock_count++; +} + +void +sys_unlock_tcpip_core(void) +{ + lwip_core_lock_count--; + if (lwip_core_lock_count == 0) { + lwip_core_lock_holder_thread = 0; + } + sys_mutex_unlock(&lock_tcpip_core); +} + +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +#if !NO_SYS +static TaskHandle_t lwip_tcpip_thread; +#endif + +void +sys_mark_tcpip_thread(void) +{ +#if !NO_SYS + lwip_tcpip_thread = xTaskGetCurrentTaskHandle(); +#endif +} + +void +sys_check_core_locking(void) +{ + /* Embedded systems should check we are NOT in an interrupt context here */ + /* E.g. core Cortex-M3/M4 ports: + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + + Instead, we use more generic FreeRTOS functions here, which should fail from ISR: */ + taskENTER_CRITICAL(); + taskEXIT_CRITICAL(); + +#if !NO_SYS + if (lwip_tcpip_thread != 0) { + TaskHandle_t current_thread = xTaskGetCurrentTaskHandle(); + +#if LWIP_TCPIP_CORE_LOCKING + LWIP_ASSERT("Function called without core lock", + current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0); +#else /* LWIP_TCPIP_CORE_LOCKING */ + LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } +#endif /* !NO_SYS */ +} + +#endif /* LWIP_FREERTOS_CHECK_CORE_LOCKING*/ + +#else +static uint32_t sys_tick = 0; + +void sys_timer_callback(void) +{ + sys_tick++; +} + +u32_t sys_now(void) +{ + return (u32_t)sys_tick; +} + +#endif \ No newline at end of file diff --git a/tests/hpmicro/inc/arch/sys_arch.h b/tests/hpmicro/inc/arch/sys_arch.h new file mode 100644 index 00000000..2f805923 --- /dev/null +++ b/tests/hpmicro/inc/arch/sys_arch.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2017 Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmdit + * + */ + +/* + * Copyright (c) 2021-2023 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +#ifndef LWIP_ARCH_SYS_ARCH_H +#define LWIP_ARCH_SYS_ARCH_H + +#include "lwip/opt.h" +#include "lwip/arch.h" + + +#if !NO_SYS +/** This is returned by _fromisr() sys functions to tell the outermost function + * that a higher priority task was woken and the scheduler needs to be invoked. + */ +#define ERR_NEED_SCHED 123 + +/* This port includes FreeRTOS headers in sys_arch.c only. + * FreeRTOS uses pointers as object types. We use wrapper structs instead of + * void pointers directly to get a tiny bit of type safety. + */ + +void sys_arch_msleep(u32_t delay_ms); +#define sys_msleep(ms) sys_arch_msleep(ms) + +#if SYS_LIGHTWEIGHT_PROT +typedef u32_t sys_prot_t; +#endif /* SYS_LIGHTWEIGHT_PROT */ + + +#if !LWIP_COMPAT_MUTEX +struct _sys_mut { + void *mut; +}; +typedef struct _sys_mut sys_mutex_t; +#define sys_mutex_valid_val(mutex) ((mutex).mut != NULL) +#define sys_mutex_valid(mutex) (((mutex) != NULL) && sys_mutex_valid_val(*(mutex))) +#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL) +#endif /* !LWIP_COMPAT_MUTEX */ + +struct _sys_sem { + void *sem; +}; +typedef struct _sys_sem sys_sem_t; +#define sys_sem_valid_val(sema) ((sema).sem != NULL) +#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema))) +#define sys_sem_set_invalid(sema) ((sema)->sem = NULL) + +struct _sys_mbox { + void *mbx; +}; +typedef struct _sys_mbox sys_mbox_t; +#define sys_mbox_valid_val(mbox) ((mbox).mbx != NULL) +#define sys_mbox_valid(mbox) (((mbox) != NULL) && sys_mbox_valid_val(*(mbox))) +#define sys_mbox_set_invalid(mbox) ((mbox)->mbx = NULL) + +struct _sys_thread { + void *thread_handle; +}; +typedef struct _sys_thread sys_thread_t; + +#if LWIP_NETCONN_SEM_PER_THREAD +sys_sem_t *sys_arch_netconn_sem_get(void); +void sys_arch_netconn_sem_alloc(void); +void sys_arch_netconn_sem_free(void); +#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get() +#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc() +#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free() +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ +#else +void sys_timer_callback(void); +#endif /* !NO_SYS */ +#endif /* LWIP_ARCH_SYS_ARCH_H */ diff --git a/tests/hpmicro/inc/lwipopts.h b/tests/hpmicro/inc/lwipopts.h new file mode 100644 index 00000000..e8898bc5 --- /dev/null +++ b/tests/hpmicro/inc/lwipopts.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2023 HPMicro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#include + +#define SYS_LIGHTWEIGHT_PROT 0 +#define LWIP_PROVIDE_ERRNO 1 + +#if defined(__SEGGER_RTL_VERSION) +#define LWIP_TIMEVAL_PRIVATE 1 +#else +#define LWIP_TIMEVAL_PRIVATE 0 +#endif + +#define LWIP_RAND rand + +#define NO_SYS 0 +#define MEM_ALIGNMENT 4 +#define LWIP_DNS 1 +#define LWIP_DNS_SERVER 0 +#define LWIP_RAW 1 +#define LWIP_NETCONN 1 +#define LWIP_SOCKET 1 +#define LWIP_DHCP 1 +#define LWIP_ICMP 1 +#define ICMP_TTL 64 +#define LWIP_UDP 1 +#define LWIP_TCP 1 +#define TCP_TTL 255 +#define LWIP_IPV4 1 +#define LWIP_IPV6 0 +#define ETH_PAD_SIZE 0 +#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67)) +#define LWIP_WND_SCALE 1 +#define TCP_RCV_SCALE 0 + +#define MEM_SIZE (150 * 1024) +#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/) +#define TCP_SND_BUF (50 * TCP_MSS) +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#define LWIP_HTTPD_CGI 0 +#define LWIP_HTTPD_SSI 0 +#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 + +/** + * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. + */ +#define MEMP_MEM_MALLOC 1 + +/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application + * sends a lot of data out of ROM (or other static memory), this + * should be set high. + */ +#define MEMP_NUM_PBUF 100 + +/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + */ +#define MEMP_NUM_UDP_PCB 6 + +/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP + * connections. + */ +#define MEMP_NUM_TCP_PCB 10 + +/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP + * connections. + */ +#define MEMP_NUM_TCP_PCB_LISTEN 5 + +/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP + * segments. + */ +#define MEMP_NUM_TCP_SEG 20 + +/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active + * timeouts. + */ +#define MEMP_NUM_SYS_TIMEOUT 10 + + +/* ---------- Pbuf options ---------- */ +/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ +#define PBUF_POOL_SIZE 20 + +/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool.*/ +#define PBUF_POOL_BUFSIZE 1600 + +/* Controls if TCP should queue segments that arrive out of + order. Define to 0 if your device is low on memory +*/ +#define TCP_QUEUE_OOSEQ 1 + +/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. +*/ +#define TCP_SND_QUEUELEN (4* TCP_SND_BUF/TCP_MSS) + +/* TCP receive window. */ +#define TCP_WND (16*TCP_MSS) + +/* + * ----------------------------------- + * ---------- DEBUG options ---------- + * ----------------------------------- + */ + +#define LWIP_DEBUG 1 + +#ifdef LWIP_DEBUG + +#define LWIP_DBG_MIN_LEVEL 1 + +#define PPP_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF + +#endif + +#define DHCP_DOES_ARP_CHECK 0 + +/* + * --------------------------------- + * ---------- OS options ---------- + * --------------------------------- + */ + +#define TCPIP_THREAD_NAME "tcpip" +#define TCPIP_THREAD_STACKSIZE 1500 +#define TCPIP_MBOX_SIZE 64 +#define DEFAULT_RAW_RECVMBOX_SIZE 1000 +#define DEFAULT_UDP_RECVMBOX_SIZE 100 +#define DEFAULT_TCP_RECVMBOX_SIZE 100 +#define DEFAULT_ACCEPTMBOX_SIZE 1500 +#define DEFAULT_THREAD_STACKSIZE 500 +#define TCPIP_THREAD_PRIO 31 +#define LWIP_SINGLE_NETIF 1 +#define LWIP_COMPAT_MUTEX 0 + +#define LWIP_TCPIP_CORE_LOCKING_INPUT 1 +#define LWIP_TCPIP_CORE_LOCKING 1 + +#include +#include +#endif /* __LWIPOPTS_H__ */ \ No newline at end of file diff --git a/tests/hpmicro/inc/usb_config.h b/tests/hpmicro/inc/usb_config.h new file mode 100644 index 00000000..1700635e --- /dev/null +++ b/tests/hpmicro/inc/usb_config.h @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2022, sakumisu + * Copyright (c) 2022-2025, HPMicro + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef CHERRYUSB_CONFIG_H +#define CHERRYUSB_CONFIG_H + +#include "board.h" + +/* ================ USB common Configuration ================ */ + +#ifdef __RTTHREAD__ +#include + +#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__) +#endif + +#ifndef CONFIG_USB_DBG_LEVEL +#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO +#endif + +#if defined(CONFIG_USB_DEVICE_FS) || defined(CONFIG_USB_DEVICE_FORCE_FULL_SPEED) +#undef CONFIG_USB_HS +#else +#define CONFIG_USB_HS +#endif + +/* Enable print with color */ +#define CONFIG_USB_PRINTF_COLOR_ENABLE + +/* #define CONFIG_USB_DCACHE_ENABLE */ + +/* data align size when use dma or use dcache */ +#ifdef CONFIG_USB_DCACHE_ENABLE +#define CONFIG_USB_ALIGN_SIZE HPM_L1C_CACHELINE_SIZE +#else +#define CONFIG_USB_ALIGN_SIZE 4 +#endif + +/* descriptor common define */ +#define USBD_VID 0x34B7 /* HPMicro VID */ +#define USBD_PID 0xFFFF +#define USBD_MAX_POWER 200 + +/* attribute data into no cache ram */ +#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable.non_init"))) + +/* use usb_memcpy default for high performance but cost more flash memory. + * And, arm libc has a bug that memcpy() may cause data misalignment when the size is not a multiple of 4. +*/ +/* #define CONFIG_USB_MEMCPY_DISABLE */ + +/* ================= USB Device Stack Configuration ================ */ + +/* Ep0 in and out transfer buffer */ +#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN +#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512 +#endif + +/* Setup packet log for debug */ +/* #define CONFIG_USBDEV_SETUP_LOG_PRINT */ + +/* Send ep0 in data from user buffer instead of copying into ep0 reqdata + * Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE + */ +/* #define CONFIG_USBDEV_EP0_INDATA_NO_COPY */ + +/* Check if the input descriptor is correct */ +/* #define CONFIG_USBDEV_DESC_CHECK */ + +/* Enable test mode */ +#define CONFIG_USBDEV_TEST_MODE + +/* enable advance desc register api */ +#define CONFIG_USBDEV_ADVANCE_DESC + +/* move ep0 setup handler from isr to thread */ +/* #define CONFIG_USBDEV_EP0_THREAD */ + +#ifndef CONFIG_USBDEV_EP0_PRIO +#define CONFIG_USBDEV_EP0_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_EP0_STACKSIZE +#define CONFIG_USBDEV_EP0_STACKSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MSC_MAX_LUN +#define CONFIG_USBDEV_MSC_MAX_LUN 1 +#endif + +#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE +#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 512 +#endif + +#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING +#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" +#endif + +#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING +#define CONFIG_USBDEV_MSC_PRODUCT_STRING "" +#endif + +#ifndef CONFIG_USBDEV_MSC_VERSION_STRING +#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" +#endif + +/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */ +/* #define CONFIG_USBDEV_MSC_POLLING */ + +/* move msc read & write from isr to thread */ +/* #define CONFIG_USBDEV_MSC_THREAD */ + +#ifndef CONFIG_USBDEV_MSC_PRIO +#define CONFIG_USBDEV_MSC_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_MSC_STACKSIZE +#define CONFIG_USBDEV_MSC_STACKSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_BUFSIZE +#define CONFIG_USBDEV_MTP_MAX_BUFSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_OBJECTS +#define CONFIG_USBDEV_MTP_MAX_OBJECTS 256 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_PATHNAME +#define CONFIG_USBDEV_MTP_MAX_PATHNAME 256 +#endif + +#define CONFIG_USBDEV_MTP_THREAD + +#ifndef CONFIG_USBDEV_MTP_PRIO +#define CONFIG_USBDEV_MTP_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_MTP_STACKSIZE +#define CONFIG_USBDEV_MTP_STACKSIZE 4096 +#endif + +#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE +#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156 +#endif + +/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/ +#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE +#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580 +#endif + +#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID +#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff +#endif + +#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC +#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "HPMicro" +#endif + +#define CONFIG_USBDEV_RNDIS_USING_LWIP +#define CONFIG_USBDEV_CDC_ECM_USING_LWIP + +/* ================ USB HOST Stack Configuration ================== */ + +#define CONFIG_USBHOST_MAX_RHPORTS 1 +#define CONFIG_USBHOST_MAX_EXTHUBS 1 +#define CONFIG_USBHOST_MAX_EHPORTS 4 +#define CONFIG_USBHOST_MAX_INTERFACES 8 +#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 +#define CONFIG_USBHOST_MAX_ENDPOINTS 8 + +#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4 +#define CONFIG_USBHOST_MAX_HID_CLASS 4 +#define CONFIG_USBHOST_MAX_MSC_CLASS 2 +#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1 +#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1 + +#define CONFIG_USBHOST_DEV_NAMELEN 16 + +#ifndef CONFIG_USBHOST_PSC_PRIO +#define CONFIG_USBHOST_PSC_PRIO 0 +#endif +#ifndef CONFIG_USBHOST_PSC_STACKSIZE +#define CONFIG_USBHOST_PSC_STACKSIZE 2048 +#endif + +/* #define CONFIG_USBHOST_GET_STRING_DESC */ + +/* #define CONFIG_USBHOST_MSOS_ENABLE */ +#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE +#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00 +#endif + +/* Ep0 max transfer buffer */ +#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN +#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512 +#endif + +#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT +#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 +#endif + +#ifndef CONFIG_USBHOST_MSC_TIMEOUT +#define CONFIG_USBHOST_MSC_TIMEOUT 5000 +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048) +#endif + +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048) +#endif + +#define CONFIG_USBHOST_BLUETOOTH_HCI_H4 +/* #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG */ + +#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE +#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048 +#endif +#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE +#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048 +#endif + +/* ================ USB Device Port Configuration ================*/ + +#define CONFIG_USBDEV_MAX_BUS USB_SOC_MAX_COUNT + +#ifndef CONFIG_USBDEV_EP_NUM +#define CONFIG_USBDEV_EP_NUM USB_SOC_DCD_MAX_ENDPOINT_COUNT +#endif + +#ifndef CONFIG_HPM_USBD_BASE +#define CONFIG_HPM_USBD_BASE HPM_USB0_BASE +#endif +#ifndef CONFIG_HPM_USBD_IRQn +#define CONFIG_HPM_USBD_IRQn IRQn_USB0 +#endif + +/* ================ USB Host Port Configuration ==================*/ +#define CONFIG_USBHOST_MAX_BUS USB_SOC_MAX_COUNT +#define CONFIG_USBHOST_PIPE_NUM 10 + +#ifndef CONFIG_HPM_USBH_BASE +#define CONFIG_HPM_USBH_BASE HPM_USB0_BASE +#endif +#ifndef CONFIG_HPM_USBH_IRQn +#define CONFIG_HPM_USBH_IRQn IRQn_USB0 +#endif + +/* ================ EHCI Configuration ================ */ + +#define CONFIG_USB_EHCI_HPMICRO (1) +#define CONFIG_USB_EHCI_HCCR_OFFSET (0x100u) +#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024 +#define CONFIG_USB_EHCI_QTD_NUM 64 + +/* ================ Addr Convert Configuration ==================*/ +#ifndef usb_phyaddr2ramaddr +#define usb_phyaddr2ramaddr(addr) core_local_mem_to_sys_address(BOARD_RUNNING_CORE, addr) +#endif + +#ifndef usb_ramaddr2phyaddr +#define usb_ramaddr2phyaddr(addr) sys_address_to_core_local_mem(BOARD_RUNNING_CORE, addr) +#endif + +#endif diff --git a/tests/hpmicro/src/main.c b/tests/hpmicro/src/main.c new file mode 100644 index 00000000..3572bae0 --- /dev/null +++ b/tests/hpmicro/src/main.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 HPMicro + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ + +/* FreeRTOS kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* HPM example includes. */ +#include +#include "board.h" +#include "hpm_clock_drv.h" +#include "shell.h" +#include "usbh_core.h" +#include "lwip/tcpip.h" + +SDK_DECLARE_EXT_ISR_M(BOARD_CONSOLE_UART_IRQ, shell_uart_isr) + +#define task_start_PRIORITY (configMAX_PRIORITIES - 2U) + +static void task_start(void *param); + +int main(void) +{ + board_init(); + board_init_led_pins(); + board_init_usb((USB_Type *)CONFIG_HPM_USBH_BASE); + + /* set irq priority */ + intc_set_irq_priority(CONFIG_HPM_USBH_IRQn, 1); + + /* Initialize the LwIP stack */ + tcpip_init(NULL, NULL); + + printf("Start usb host task...\r\n"); + + usbh_initialize(0, CONFIG_HPM_USBH_BASE, NULL); + + if (pdPASS != xTaskCreate(task_start, "task_start", 1024U, NULL, task_start_PRIORITY, NULL)) { + printf("Task start creation failed!\r\n"); + for (;;) { + ; + } + } + + vTaskStartScheduler(); + printf("Unexpected scheduler exit!\r\n"); + for (;;) { + ; + } + + return 0; +} + +static void task_start(void *param) +{ + (void)param; + + printf("Try to initialize the uart\r\n" + " if you are using the console uart as the shell uart\r\n" + " failure to initialize may result in no log\r\n"); + + uart_config_t shell_uart_config = { 0 }; + uart_default_config(BOARD_CONSOLE_UART_BASE, &shell_uart_config); + shell_uart_config.src_freq_in_hz = clock_get_frequency(BOARD_CONSOLE_UART_CLK_NAME); + shell_uart_config.baudrate = 115200; + + if (status_success != uart_init(BOARD_CONSOLE_UART_BASE, &shell_uart_config)) { + /* uart failed to be initialized */ + printf("Failed to initialize uart\r\n"); + for (;;) { + ; + } + } + + printf("Initialize shell uart successfully\r\n"); + + /* default password is : 12345678 */ + /* shell_init() must be called in-task */ + if (0 != shell_init(BOARD_CONSOLE_UART_BASE, false)) { + /* shell failed to be initialized */ + printf("Failed to initialize shell\r\n"); + for (;;) { + ; + } + } + + printf("Initialize shell successfully\r\n"); + + /* irq must be enabled after shell_init() */ + uart_enable_irq(BOARD_CONSOLE_UART_BASE, uart_intr_rx_data_avail_or_timeout); + intc_m_enable_irq_with_priority(BOARD_CONSOLE_UART_IRQ, 1); + + printf("Enable shell uart interrupt\r\n"); + + printf("Exit start task\r\n"); + vTaskDelete(NULL); +} + +extern int lsusb(int argc, char **argv); +CSH_CMD_EXPORT(lsusb, ); \ No newline at end of file