summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2025-11-09 22:29:02 +0800
committersakumisu <[email protected]>2025-11-10 20:34:55 +0800
commita2352bffdb4a8aa6d7a80895a0e8ce70487b2d05 (patch)
tree85713bd78d98ec51a214ed8495999c21c82c6f1c
parent9a1ead9e8ade2c4ee7bcf7cbdce56e52d7f708ae (diff)
ci: update bl & hpm demo
Signed-off-by: sakumisu <[email protected]>
-rw-r--r--.github/workflows/build_tests.yml28
-rw-r--r--tests/bouffalolab/CMakeLists.txt46
-rw-r--r--tests/bouffalolab/Makefile13
-rw-r--r--tests/bouffalolab/flash_prog_cfg.ini14
-rw-r--r--tests/bouffalolab/inc/FreeRTOSConfig.h128
-rw-r--r--tests/bouffalolab/inc/fatfs_conf_user.h270
-rw-r--r--tests/bouffalolab/inc/lwipopts_user.h442
-rw-r--r--tests/bouffalolab/inc/usb_config.h325
-rw-r--r--tests/bouffalolab/proj.conf16
-rw-r--r--tests/bouffalolab/src/main.c158
-rw-r--r--tests/hpmicro/CMakeLists.txt13
-rw-r--r--tests/hpmicro/inc/FreeRTOSConfig.h10
-rw-r--r--tests/hpmicro/inc/arch/cc.h18
-rw-r--r--tests/hpmicro/inc/arch/sys_arch.c596
-rw-r--r--tests/hpmicro/inc/lwipopts.h534
-rw-r--r--tests/hpmicro/inc/usb_config.h11
-rw-r--r--tests/hpmicro/src/font24x48.c1066
-rw-r--r--tests/hpmicro/src/iperf/iperf.c763
-rw-r--r--tests/hpmicro/src/iperf/iperf.h82
-rw-r--r--tests/hpmicro/src/iperf/iperf_cli.c115
-rw-r--r--tests/hpmicro/src/iperf/utils_getopt.c377
-rw-r--r--tests/hpmicro/src/iperf/utils_getopt.h107
-rw-r--r--tests/hpmicro/src/main.c104
-rw-r--r--tests/hpmicro/src/ping.c257
-rw-r--r--tests/hpmicro/src/uvc2lcd.c157
25 files changed, 5169 insertions, 481 deletions
diff --git a/.github/workflows/build_tests.yml b/.github/workflows/build_tests.yml
index fe51da16..5ce6e416 100644
--- a/.github/workflows/build_tests.yml
+++ b/.github/workflows/build_tests.yml
@@ -37,7 +37,33 @@ jobs:
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
+ cmake -S . -B build -GNinja -DBOARD=hpm6800evk -DHPM_BUILD_TYPE=flash_sdram_xip -DCMAKE_BUILD_TYPE=debug -DEXTRA_C_FLAGS="-Werror";cmake --build build
+
+ build_bouffalolab:
+ 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 make
+
+ - name: Download bouffalo_sdk
+ run: |
+ cd ~
+ git clone https://github.com/bouffalolab/bouffalo_sdk.git
+
+ - name: Download RISC-V toolchain
+ run: |
+ cd ~
+ git clone https://github.com/bouffalolab/toolchain_gcc_t-head_linux.git
+
+ - name: Build bouffalo demo
+ run: |
+ cd tests/bouffalolab
+ export BL_SDK_BASE=~/bouffalo_sdk
+ export PATH=~/toolchain_gcc_t-head_linux/bin:$PATH
+ make CHIP=bl616 BOARD=bl616dk -j12
build_espressif:
strategy:
diff --git a/tests/bouffalolab/CMakeLists.txt b/tests/bouffalolab/CMakeLists.txt
new file mode 100644
index 00000000..7d56aaa9
--- /dev/null
+++ b/tests/bouffalolab/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 3.15)
+
+include(proj.conf)
+
+find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE})
+
+sdk_add_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_ECM)
+sdk_add_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_NCM)
+sdk_add_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_RNDIS)
+sdk_add_compile_definitions(-DCONFIG_USBHOST_PLATFORM_ASIX)
+sdk_add_compile_definitions(-DCONFIG_USBHOST_PLATFORM_RTL8152)
+sdk_add_include_directories(inc)
+
+target_sources(app PRIVATE ../../demo/usb_host.c)
+
+set(CONFIG_CHERRYMP 1)
+set(CONFIG_CHERRYUSB 1)
+set(CONFIG_CHERRYUSB_DEVICE 1)
+set(CONFIG_CHERRYUSB_HOST 1)
+
+set(CONFIG_CHERRYUSB_DEVICE_CDC_RNDIS 1)
+set(CONFIG_CHERRYUSB_DEVICE_CDC_ECM 1)
+
+# add_subdirectory(src/cherryusb_hostuvcuac)
+add_subdirectory(../.. cherryusb)
+
+# sdk_add_link_options(-uusbd_cdc_acm_init_intf)
+# sdk_add_link_options(-uusbd_hid_init_intf)
+# sdk_add_link_options(-uusbd_msc_init_intf)
+# sdk_add_link_options(-uusbd_video_init_intf)
+# sdk_add_link_options(-uusbd_audio_init_intf)
+# sdk_add_link_options(-uusbd_cdc_ecm_init_intf)
+# sdk_add_link_options(-uusbd_rndis_init_intf)
+# sdk_add_link_options(-uusbd_initialize)
+# sdk_add_link_options(-uusbd_desc_register)
+# sdk_add_link_options(-uusbd_add_interface)
+# sdk_add_link_options(-uusbd_add_endpoint)
+# sdk_add_link_options(-uusbd_rndis_start_write)
+# sdk_add_link_options(-uusbd_rndis_start_read)
+# sdk_add_link_options(-uusbd_cdc_ecm_start_write)
+# sdk_add_link_options(-uusbd_cdc_ecm_start_read)
+# sdk_add_link_options(-uusbd_video_stream_start_write)
+# sdk_add_link_options(-uusbd_video_stream_split_transfer)
+
+sdk_set_main_file(src/main.c)
+project(cherryusb)
diff --git a/tests/bouffalolab/Makefile b/tests/bouffalolab/Makefile
new file mode 100644
index 00000000..c5b7d56d
--- /dev/null
+++ b/tests/bouffalolab/Makefile
@@ -0,0 +1,13 @@
+SDK_DEMO_PATH ?= .
+BL_SDK_BASE ?= /home/sakumisu/repo/bouffalolab/bouffalo_sdk_github
+
+export BL_SDK_BASE
+
+CHIP ?= bl616
+BOARD ?= bl616dk
+CROSS_COMPILE = riscv64-unknown-elf-
+
+# add custom cmake definition
+#cmake_definition+=-Dxxx=sss
+
+include $(BL_SDK_BASE)/project.build
diff --git a/tests/bouffalolab/flash_prog_cfg.ini b/tests/bouffalolab/flash_prog_cfg.ini
new file mode 100644
index 00000000..d0077a95
--- /dev/null
+++ b/tests/bouffalolab/flash_prog_cfg.ini
@@ -0,0 +1,14 @@
+[cfg]
+# 0: no erase, 1:programmed section erase, 2: chip erase
+erase = 1
+# skip mode set first para is skip addr, second para is skip len, multi-segment region with ; separated
+skip_mode = 0x0, 0x0
+# 0: not use isp mode, #1: isp mode
+boot2_isp_mode = 0
+pre_program =
+pre_program_args =
+
+[FW]
+filedir = ./build/build_out/cherryusb*_$(CHIPNAME).bin
+address = 0x000000
+
diff --git a/tests/bouffalolab/inc/FreeRTOSConfig.h b/tests/bouffalolab/inc/FreeRTOSConfig.h
new file mode 100644
index 00000000..064b2b22
--- /dev/null
+++ b/tests/bouffalolab/inc/FreeRTOSConfig.h
@@ -0,0 +1,128 @@
+/*
+ * FreeRTOS Kernel V10.2.1
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+#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.
+ *----------------------------------------------------------*/
+#if defined(BL602) || defined(BL702) || defined(BL702L)
+#define configMTIME_BASE_ADDRESS (0x02000000UL + 0xBFF8UL)
+#define configMTIMECMP_BASE_ADDRESS (0x02000000UL + 0x4000UL)
+#else
+#if __riscv_xlen == 64
+#define configMTIME_BASE_ADDRESS (0)
+#define configMTIMECMP_BASE_ADDRESS ((0xE4000000UL) + 0x4000UL)
+#else
+#define configMTIME_BASE_ADDRESS ((0xE0000000UL) + 0xBFF8UL)
+#define configMTIMECMP_BASE_ADDRESS ((0xE0000000UL) + 0x4000UL)
+#endif
+#endif
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configUSE_PREEMPTION 1
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configCPU_CLOCK_HZ ((uint32_t)(1 * 1000 * 1000))
+#define configTICK_RATE_HZ ((TickType_t)1000)
+#define configMAX_PRIORITIES (32)
+#define configMINIMAL_STACK_SIZE ((unsigned short)128) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
+#define configTOTAL_HEAP_SIZE ((size_t)24 * 1024)
+#define configMAX_TASK_NAME_LEN (16)
+#define configUSE_TRACE_FACILITY 1
+#define configUSE_STATS_FORMATTING_FUNCTIONS 1
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 0
+#define configUSE_MUTEXES 1
+#define configQUEUE_REGISTRY_SIZE 8
+#define configCHECK_FOR_STACK_OVERFLOW 2
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_MALLOC_FAILED_HOOK 1
+#define configUSE_APPLICATION_TASK_TAG 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
+#define configUSE_TICKLESS_IDLE 0
+#define configUSE_POSIX_ERRNO 1
+
+#define configTHREAD_LOCAL_STORAGE_DELETE_CALLBACKS 0
+
+/* 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 (512)
+/* Task priorities. Allow these to be overridden. */
+#ifndef uartPRIMARY_PRIORITY
+#define uartPRIMARY_PRIORITY (configMAX_PRIORITIES - 3)
+#endif
+/* 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_eTaskGetState 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 1
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xSemaphoreGetMutexHolder 1
+/* Normal assert() semantics without relying on the provision of an assert.h
+header file. */
+void vApplicationMallocFailedHook(void);
+void vAssertCalled(void);
+
+#include <stdio.h>
+
+#define configASSERT(x) \
+ if ((x) == 0) { \
+ printf("file [%s]\r\n", __FILE__); \
+ printf("func [%s]\r\n", __FUNCTION__); \
+ printf("line [%d]\r\n", __LINE__); \
+ printf("%s\r\n", (const char *)(#x)); \
+ vAssertCalled(); \
+ }
+#if (configUSE_TICKLESS_IDLE != 0)
+void vApplicationSleep(uint32_t xExpectedIdleTime);
+#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vApplicationSleep(xExpectedIdleTime)
+#endif
+// #define portUSING_MPU_WRAPPERS
+#endif /* FREERTOS_CONFIG_H */ \ No newline at end of file
diff --git a/tests/bouffalolab/inc/fatfs_conf_user.h b/tests/bouffalolab/inc/fatfs_conf_user.h
new file mode 100644
index 00000000..a1addd77
--- /dev/null
+++ b/tests/bouffalolab/inc/fatfs_conf_user.h
@@ -0,0 +1,270 @@
+/*---------------------------------------------------------------------------/
+/ Configurations of FatFs Module
+/---------------------------------------------------------------------------*/
+
+/* User external configuration, User need to use this file as a template.
+All configuration items must be included in the file */
+
+/*---------------------------------------------------------------------------/
+/ Function Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_CONTINUOUS 1
+/* Read and write as much data as possible at one time, regardless of the cluster size */
+
+#define FF_FS_READONLY 0
+/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
+/ Read-only configuration removes writing API functions, f_write(), f_sync(),
+/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
+/ and optional writing functions as well. */
+
+#define FF_FS_MINIMIZE 0
+/* This option defines minimization level to remove some basic API functions.
+/
+/ 0: Basic functions are fully enabled.
+/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
+/ are removed.
+/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
+/ 3: f_lseek() function is removed in addition to 2. */
+
+#define FF_USE_FIND 1
+/* This option switches filtered directory read functions, f_findfirst() and
+/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
+
+#define FF_USE_MKFS 1
+/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
+
+#define FF_USE_FASTSEEK 1
+/* This option switches fast seek function. (0:Disable or 1:Enable) */
+
+#define FF_USE_EXPAND 0
+/* This option switches f_expand function. (0:Disable or 1:Enable) */
+
+#define FF_USE_CHMOD 0
+/* This option switches attribute manipulation functions, f_chmod() and f_utime().
+/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
+
+#define FF_USE_LABEL 0
+/* This option switches volume label functions, f_getlabel() and f_setlabel().
+/ (0:Disable or 1:Enable) */
+
+#define FF_USE_FORWARD 0
+/* This option switches f_forward() function. (0:Disable or 1:Enable) */
+
+#define FF_USE_STRFUNC 0
+#define FF_PRINT_LLI 1
+#define FF_PRINT_FLOAT 1
+#define FF_STRF_ENCODE 3
+/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
+/ f_printf().
+/
+/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
+/ 1: Enable without LF-CRLF conversion.
+/ 2: Enable with LF-CRLF conversion.
+/
+/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
+/ makes f_printf() support floating point argument. These features want C99 or later.
+/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
+/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
+/ to be read/written via those functions.
+/
+/ 0: ANSI/OEM in current CP
+/ 1: Unicode in UTF-16LE
+/ 2: Unicode in UTF-16BE
+/ 3: Unicode in UTF-8
+*/
+
+/*---------------------------------------------------------------------------/
+/ Locale and Namespace Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_CODE_PAGE 437
+/* This option specifies the OEM code page to be used on the target system.
+/ Incorrect code page setting can cause a file open failure.
+/
+/ 437 - U.S.
+/ 720 - Arabic
+/ 737 - Greek
+/ 771 - KBL
+/ 775 - Baltic
+/ 850 - Latin 1
+/ 852 - Latin 2
+/ 855 - Cyrillic
+/ 857 - Turkish
+/ 860 - Portuguese
+/ 861 - Icelandic
+/ 862 - Hebrew
+/ 863 - Canadian French
+/ 864 - Arabic
+/ 865 - Nordic
+/ 866 - Russian
+/ 869 - Greek 2
+/ 932 - Japanese (DBCS)
+/ 936 - Simplified Chinese (DBCS)
+/ 949 - Korean (DBCS)
+/ 950 - Traditional Chinese (DBCS)
+/ 0 - Include all code pages above and configured by f_setcp()
+*/
+
+#define FF_USE_LFN 2
+#define FF_MAX_LFN 255
+/* The FF_USE_LFN switches the support for LFN (long file name).
+/
+/ 0: Disable LFN. FF_MAX_LFN has no effect.
+/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
+/ 2: Enable LFN with dynamic working buffer on the STACK.
+/ 3: Enable LFN with dynamic working buffer on the HEAP.
+/
+/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
+/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
+/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
+/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
+/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
+/ specification.
+/ When use stack for the working buffer, take care on stack overflow. When use heap
+/ memory for the working buffer, memory management functions, ff_memalloc() and
+/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
+
+#define FF_LFN_UNICODE 0
+/* This option switches the character encoding on the API when LFN is enabled.
+/
+/ 0: ANSI/OEM in current CP (TCHAR = char)
+/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
+/ 2: Unicode in UTF-8 (TCHAR = char)
+/ 3: Unicode in UTF-32 (TCHAR = DWORD)
+/
+/ Also behavior of string I/O functions will be affected by this option.
+/ When LFN is not enabled, this option has no effect. */
+
+#define FF_LFN_BUF 255
+#define FF_SFN_BUF 12
+/* This set of options defines size of file name members in the FILINFO structure
+/ which is used to read out directory items. These values should be suffcient for
+/ the file names to read. The maximum possible length of the read file name depends
+/ on character encoding. When LFN is not enabled, these options have no effect. */
+
+#define FF_FS_RPATH 0
+/* This option configures support for relative path.
+/
+/ 0: Disable relative path and remove related functions.
+/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
+/ 2: f_getcwd() function is available in addition to 1.
+*/
+
+/*---------------------------------------------------------------------------/
+/ Drive/Volume Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_VOLUMES 5
+/* Number of volumes (logical drives) to be used. (1-10) */
+
+#define FF_STR_VOLUME_ID 2
+#define FF_VOLUME_STRS "ram", "flash", "sd", "sd2", "usb"
+/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
+/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
+/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
+/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
+/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
+/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
+/ not defined, a user defined volume string table is needed as:
+/
+/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
+*/
+
+#define FF_MULTI_PARTITION 0
+/* This option switches support for multiple volumes on the physical drive.
+/ By default (0), each logical drive number is bound to the same physical drive
+/ number and only an FAT volume found on the physical drive will be mounted.
+/ When this function is enabled (1), each logical drive number can be bound to
+/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
+/ function will be available. */
+
+#define FF_MIN_SS 512
+#define FF_MAX_SS 512
+/* This set of options configures the range of sector size to be supported. (512,
+/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
+/ harddisk, but a larger value may be required for on-board flash memory and some
+/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
+/ for variable sector size mode and disk_ioctl() function needs to implement
+/ GET_SECTOR_SIZE command. */
+
+#define FF_LBA64 0
+/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
+/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
+
+#define FF_MIN_GPT 0x10000000
+/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
+/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
+
+#define FF_USE_TRIM 0
+/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
+/ To enable Trim function, also CTRL_TRIM command should be implemented to the
+/ disk_ioctl() function. */
+
+/*---------------------------------------------------------------------------/
+/ System Configurations
+/---------------------------------------------------------------------------*/
+
+#define FF_FS_TINY 0
+/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
+/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
+/ Instead of private sector buffer eliminated from the file object, common sector
+/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
+
+#define FF_FS_EXFAT 0
+/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
+/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
+/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
+
+#define FF_FS_NORTC 1
+#define FF_NORTC_MON 1
+#define FF_NORTC_MDAY 1
+#define FF_NORTC_YEAR 2022
+/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
+/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
+/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
+/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
+/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
+/ added to the project to read current time form real-time clock. FF_NORTC_MON,
+/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
+/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
+
+#define FF_FS_NOFSINFO 0
+/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
+/ option, and f_getfree() function at the first time after volume mount will force
+/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
+/
+/ bit0=0: Use free cluster count in the FSINFO if available.
+/ bit0=1: Do not trust free cluster count in the FSINFO.
+/ bit1=0: Use last allocated cluster number in the FSINFO if available.
+/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
+*/
+
+#define FF_FS_LOCK 0
+/* The option FF_FS_LOCK switches file lock function to control duplicated file open
+/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
+/ is 1.
+/
+/ 0: Disable file lock function. To avoid volume corruption, application program
+/ should avoid illegal open, remove and rename to the open objects.
+/ >0: Enable file lock function. The value defines how many files/sub-directories
+/ can be opened simultaneously under file lock control. Note that the file
+/ lock control is independent of re-entrancy. */
+
+#define FF_FS_REENTRANT 0
+#define FF_FS_TIMEOUT 1000
+/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
+/ module itself. Note that regardless of this option, file access to different
+/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
+/ and f_fdisk() function, are always not re-entrant. Only file/directory access
+/ to the same volume is under control of this featuer.
+/
+/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
+/ 1: Enable re-entrancy. Also user provided synchronization handlers,
+/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
+/ function, must be added to the project. Samples are available in ffsystem.c.
+/
+/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
+*/
+
+/*--- End of configuration options ---*/
diff --git a/tests/bouffalolab/inc/lwipopts_user.h b/tests/bouffalolab/inc/lwipopts_user.h
new file mode 100644
index 00000000..3792fa93
--- /dev/null
+++ b/tests/bouffalolab/inc/lwipopts_user.h
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2025, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef LWIPOPTS_H
+#define LWIPOPTS_H
+
+#ifdef USE_LWIPOPTS_APP_H
+#include "lwipopts_app.h"
+#endif
+
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT 1
+#define IP_REASSEMBLY 0
+#define IP_FRAG 0
+#define ARP_QUEUEING 0
+#define NO_SYS 0
+#define LWIP_RAND rand
+
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_TIMERS 1
+#define LWIP_RAW 1
+#define LWIP_IPV4 1
+#define LWIP_IGMP 1
+#define LWIP_ICMP 1
+#define ICMP_TTL 64
+#define LWIP_TCP 1
+#define TCP_TTL 255
+#define LWIP_UDP 1
+#define UDP_TTL 255
+#define LWIP_DNS 1
+
+/**
+ * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
+ */
+#define LWIP_NETIF_API 1
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN 1
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET 1
+
+/* ---------- Memory options ---------- */
+#define MEMP_MEM_MALLOC 0
+
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+ lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+ byte alignment -> define MEM_ALIGNMENT to 2. */
+#ifndef MEM_ALIGNMENT
+#define MEM_ALIGNMENT 64
+#endif
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#ifndef MEM_SIZE
+#define MEM_SIZE (32 * 1024)
+#endif
+
+/* 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. */
+#ifndef MEMP_NUM_PBUF
+#define MEMP_NUM_PBUF 100
+#endif
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
+ */
+#ifndef MEMP_NUM_RAW_PCB
+#define MEMP_NUM_RAW_PCB 4
+#endif
+
+/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
+ per active UDP "connection". */
+#ifndef MEMP_NUM_UDP_PCB
+#define MEMP_NUM_UDP_PCB 4
+#endif
+
+/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
+ connections. */
+#ifndef MEMP_NUM_TCP_PCB
+#define MEMP_NUM_TCP_PCB 4
+#endif
+
+/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
+ connections. */
+#ifndef MEMP_NUM_TCP_PCB_LISTEN
+#define MEMP_NUM_TCP_PCB_LISTEN 5
+#endif
+
+/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
+ segments. */
+#ifndef MEMP_NUM_TCP_SEG
+#define MEMP_NUM_TCP_SEG 40
+#endif
+
+/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
+ timeouts. */
+#ifndef MEMP_NUM_SYS_TIMEOUT
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL)
+#endif
+
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#ifndef MEMP_NUM_NETCONN
+#define MEMP_NUM_NETCONN 4
+#endif
+
+/* ---------- Pbuf options ---------- */
+/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
+#ifndef PBUF_POOL_SIZE
+#define PBUF_POOL_SIZE 20
+#endif
+
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#ifndef PBUF_POOL_BUFSIZE
+#define PBUF_POOL_BUFSIZE 1600
+#endif
+
+/* ---------- TCP options ---------- */
+/* Controls if TCP should queue segments that arrive out of
+ order. Define to 0 if your device is low on memory. */
+#ifndef TCP_QUEUE_OOSEQ
+#define TCP_QUEUE_OOSEQ 0
+#endif
+
+/* TCP Maximum segment size. */
+#ifndef TCP_MSS
+#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
+#endif
+
+/* TCP sender buffer space (bytes). */
+#ifndef TCP_SND_BUF
+#define TCP_SND_BUF (8 * TCP_MSS)
+#endif
+
+/* 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. */
+#ifndef TCP_SND_QUEUELEN
+#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF / TCP_MSS)
+#endif
+
+/* TCP receive window. */
+#ifndef TCP_WND
+#define TCP_WND (16 * TCP_MSS)
+#endif
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+ interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
+ turning this on does currently not work. */
+#ifndef LWIP_DHCP
+#define LWIP_DHCP 1
+#endif
+
+/* ---------- Statistics options ---------- */
+#ifndef LWIP_STATS
+#define LWIP_STATS 0
+#endif
+
+#ifndef LWIP_PROVIDE_ERRNO
+#define LWIP_PROVIDE_ERRNO 1
+#endif
+
+/*
+ ------------------------------------------------
+ ---------- Network Interfaces options ----------
+ ------------------------------------------------
+*/
+/**
+ * LWIP_SINGLE_NETIF==1: use a single netif only. This is the common case for
+ * small real-life targets. Some code like routing etc. can be left out.
+ */
+#ifndef LWIP_SINGLE_NETIF
+#define LWIP_SINGLE_NETIF 1
+#endif
+
+/* ---------- link callback options ---------- */
+/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#ifndef LWIP_NETIF_LINK_CALLBACK
+#define LWIP_NETIF_LINK_CALLBACK 1
+#endif
+
+/**
+ * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data
+ * to be sent into one single pbuf. This is for compatibility with DMA-enabled
+ * MACs that do not support scatter-gather.
+ * Beware that this might involve CPU-memcpy before transmitting that would not
+ * be needed without this flag! Use this only if you need to!
+ *
+ * ATTENTION: a driver should *NOT* rely on getting single pbufs but check TX
+ * pbufs for being in one piece. If not, @ref pbuf_clone can be used to get
+ * a single pbuf:
+ * if (p->next != NULL) {
+ * struct pbuf *q = pbuf_clone(PBUF_RAW, PBUF_RAM, p);
+ * if (q == NULL) {
+ * return ERR_MEM;
+ * }
+ * p = q; ATTENTION: do NOT free the old 'p' as the ref belongs to the caller!
+ * }
+ */
+#ifndef LWIP_NETIF_TX_SINGLE_PBUF
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#endif
+
+/*
+ --------------------------------------
+ ---------- Checksum options ----------
+ --------------------------------------
+*/
+
+/*
+ * Some MCUs allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
+ * To use this feature let the following define uncommented.
+ * To disable it and process by CPU comment the the checksum.
+*/
+#ifdef CHECKSUM_BY_HARDWARE
+/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
+#define CHECKSUM_GEN_IP 0
+/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
+#define CHECKSUM_GEN_UDP 0
+/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
+#define CHECKSUM_GEN_TCP 0
+/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
+#define CHECKSUM_CHECK_IP 0
+/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
+#define CHECKSUM_CHECK_UDP 0
+/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
+#define CHECKSUM_CHECK_TCP 0
+/* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
+#define CHECKSUM_GEN_ICMP 0
+#else
+/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
+#define CHECKSUM_GEN_IP 1
+/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
+#define CHECKSUM_GEN_UDP 1
+/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
+#define CHECKSUM_GEN_TCP 1
+/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
+#define CHECKSUM_CHECK_IP 1
+/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
+#define CHECKSUM_CHECK_UDP 1
+/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
+#define CHECKSUM_CHECK_TCP 1
+/* CHECKSUM_CHECK_ICMP==1: Check checksums by software for incoming ICMP packets.*/
+#define CHECKSUM_GEN_ICMP 1
+#endif
+
+/*
+ -----------------------------------
+ ---------- DEBUG options ----------
+ -----------------------------------
+*/
+#ifdef LWIP_DEBUG
+
+#ifndef LWIP_DBG_MIN_LEVEL
+#define LWIP_DBG_MIN_LEVEL 0
+#endif
+
+#ifndef PPP_DEBUG
+#define PPP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef MEM_DEBUG
+#define MEM_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef MEMP_DEBUG
+#define MEMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef PBUF_DEBUG
+#define PBUF_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef API_LIB_DEBUG
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef API_MSG_DEBUG
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCPIP_DEBUG
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef NETIF_DEBUG
+#define NETIF_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef SOCKETS_DEBUG
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef DNS_DEBUG
+#define DNS_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef AUTOIP_DEBUG
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef DHCP_DEBUG
+#define DHCP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef IP_DEBUG
+#define IP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef IP_REASS_DEBUG
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef ICMP_DEBUG
+#define ICMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef IGMP_DEBUG
+#define IGMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef UDP_DEBUG
+#define UDP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_DEBUG
+#define TCP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_INPUT_DEBUG
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_OUTPUT_DEBUG
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_RTO_DEBUG
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_CWND_DEBUG
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_WND_DEBUG
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_FR_DEBUG
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_QLEN_DEBUG
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_RST_DEBUG
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef ETHARP_DEBUG
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#endif
+
+#endif
+
+/*
+ ---------------------------------
+ ---------- OS options ----------
+ ---------------------------------
+*/
+#ifndef TCPIP_THREAD_NAME
+#define TCPIP_THREAD_NAME "tcpip"
+#endif
+
+#ifndef TCPIP_THREAD_STACKSIZE
+#define TCPIP_THREAD_STACKSIZE 2048
+#endif
+
+#ifndef TCPIP_MBOX_SIZE
+#define TCPIP_MBOX_SIZE 8
+#endif
+
+#ifndef DEFAULT_RAW_RECVMBOX_SIZE
+#define DEFAULT_RAW_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_UDP_RECVMBOX_SIZE
+#define DEFAULT_UDP_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_TCP_RECVMBOX_SIZE
+#define DEFAULT_TCP_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_ACCEPTMBOX_SIZE
+#define DEFAULT_ACCEPTMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_THREAD_STACKSIZE
+#define DEFAULT_THREAD_STACKSIZE 500
+#endif
+
+#ifndef TCPIP_THREAD_PRIO
+#define TCPIP_THREAD_PRIO 10
+#endif
+
+#define LWIP_COMPAT_MUTEX 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+
+#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT
+#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
+#endif
+
+#ifndef LWIP_MEM_SECTION
+#define LWIP_MEM_SECTION ".bss"
+#endif
+
+// bouffalo patch
+#define LWIP_DNS_SERVER 0
+#define LWIP_SUPPORT_CUSTOM_PBUF 1
+
+#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)] __attribute__((section(LWIP_MEM_SECTION)))
+
+#endif /* __LWIPOPTS_H__ */
diff --git a/tests/bouffalolab/inc/usb_config.h b/tests/bouffalolab/inc/usb_config.h
new file mode 100644
index 00000000..d158eb92
--- /dev/null
+++ b/tests/bouffalolab/inc/usb_config.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2022, sakumisu
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#ifndef CHERRYUSB_CONFIG_H
+#define CHERRYUSB_CONFIG_H
+
+/* ================ USB common Configuration ================ */
+#include "bflb_core.h"
+
+#ifdef __RTTHREAD__
+#include <rtthread.h>
+
+#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
+
+/* 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 32 // 32 or 64
+#else
+#define CONFIG_USB_ALIGN_SIZE 4
+#endif
+
+/* attribute data into no cache ram */
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
+
+/* 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
+
+/* 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 "CherryUSB"
+#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 4
+
+#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 4096
+#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 ================*/
+
+#ifndef CONFIG_USBDEV_MAX_BUS
+#define CONFIG_USBDEV_MAX_BUS 1
+#endif
+
+// #define CONFIG_USBDEV_SOF_ENABLE
+
+/* ---------------- FSDEV Configuration ---------------- */
+//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
+
+/* ---------------- DWC2 Configuration ---------------- */
+/* enable dwc2 buffer dma mode for device
+ * in xxx32 chips, only pb14/pb15 can support dma mode, pa11/pa12 is not supported(only a few supports, but we ignore them)
+*/
+// #define CONFIG_USB_DWC2_DMA_ENABLE
+
+/* ---------------- MUSB Configuration ---------------- */
+#define CONFIG_USB_MUSB_EP_NUM 8
+// #define CONFIG_USB_MUSB_SUNXI
+
+/* ================ USB Host Port Configuration ==================*/
+#ifndef CONFIG_USBHOST_MAX_BUS
+#define CONFIG_USBHOST_MAX_BUS 1
+#endif
+
+/* ---------------- EHCI Configuration ---------------- */
+
+#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0)
+#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
+#define CONFIG_USB_EHCI_QH_NUM 10
+#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3)
+#define CONFIG_USB_EHCI_ITD_NUM 4
+#define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
+// #define CONFIG_USB_EHCI_CONFIGFLAG
+// #define CONFIG_USB_EHCI_ISO
+// #define CONFIG_USB_EHCI_WITH_OHCI
+// #define CONFIG_USB_EHCI_DESC_DCACHE_ENABLE
+
+/* ---------------- OHCI Configuration ---------------- */
+#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0)
+#define CONFIG_USB_OHCI_ED_NUM 10
+#define CONFIG_USB_OHCI_TD_NUM 3
+// #define CONFIG_USB_OHCI_DESC_DCACHE_ENABLE
+
+/* ---------------- XHCI Configuration ---------------- */
+#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
+
+/* ---------------- DWC2 Configuration ---------------- */
+// nothing to define
+
+/* ---------------- MUSB Configuration ---------------- */
+#define CONFIG_USB_MUSB_PIPE_NUM 8
+// #define CONFIG_USB_MUSB_SUNXI
+// #define CONFIG_USB_MUSB_WITHOUT_MULTIPOINT
+
+/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
+ * the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
+ *
+ * in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
+*/
+// #define CONFIG_USB_HS
+
+#ifndef usb_phyaddr2ramaddr
+#define usb_phyaddr2ramaddr(addr) (addr)
+#endif
+
+#ifndef usb_ramaddr2phyaddr
+#define usb_ramaddr2phyaddr(addr) (addr)
+#endif
+
+#define ATTR_FAST_RAM_SECTION ATTR_TCM_SECTION
+#define CONFIG_USB_HS
+
+#endif
diff --git a/tests/bouffalolab/proj.conf b/tests/bouffalolab/proj.conf
new file mode 100644
index 00000000..0e597231
--- /dev/null
+++ b/tests/bouffalolab/proj.conf
@@ -0,0 +1,16 @@
+set(CONFIG_FREERTOS 1)
+
+# do not use sdk cherryusb because its version is lower than master.
+
+#set(CONFIG_CHERRYUSB 1)
+#set(CONFIG_CHERRYUSB_HOST 1)
+#set(CONFIG_CHERRYUSB_HOST_ECM 1)
+
+set(CONFIG_PSRAM 1)
+set(CONFIG_FATFS 1)
+set(CONFIG_FATFS_USBH 1)
+
+set(CONFIG_LWIP 1)
+set(CONFIG_PING 1)
+set(CONFIG_IPERF 1)
+set(CONFIG_SHELL 1)
diff --git a/tests/bouffalolab/src/main.c b/tests/bouffalolab/src/main.c
new file mode 100644
index 00000000..7ff88b71
--- /dev/null
+++ b/tests/bouffalolab/src/main.c
@@ -0,0 +1,158 @@
+#include <FreeRTOS.h>
+#include "semphr.h"
+#include "usbh_core.h"
+#include "bflb_uart.h"
+#include "board.h"
+#include "shell.h"
+#ifdef CONFIG_USB_EHCI_ISO
+#include "usbh_uvc_stream.h"
+#include "usbh_uac_stream.h"
+#endif
+#include "lwip/tcpip.h"
+
+static struct bflb_device_s *uart0;
+
+extern void shell_init_with_task(struct bflb_device_s *shell);
+
+#ifdef CONFIG_USB_EHCI_ISO
+static ATTR_NOINIT_PSRAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer1[640 * 480 * 2];
+static ATTR_NOINIT_PSRAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer2[640 * 480 * 2];
+static struct usbh_videoframe frame_pool[2];
+
+static ATTR_NOINIT_PSRAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[AUDIO_MIC_EP_MPS * 8];
+static struct usbh_audioframe frame_pool2[8];
+
+void usbh_video_run(struct usbh_video *video_class)
+{
+ usbh_video_stream_start(640, 480, USBH_VIDEO_FORMAT_MJPEG);
+}
+
+void usbh_video_stop(struct usbh_video *video_class)
+{
+ usbh_video_stream_stop();
+}
+
+void usbh_video_frame_callback(struct usbh_videoframe *frame)
+{
+ USB_LOG_RAW("frame buf:%p,frame len:%d\r\n", frame->frame_buf, frame->frame_size);
+}
+#endif
+
+int main(void)
+{
+ board_init();
+
+ uart0 = bflb_device_get_by_name("uart0");
+ shell_init_with_task(uart0);
+
+ /* Initialize the LwIP stack */
+ tcpip_init(NULL, NULL);
+
+ printf("Starting usb host task...\r\n");
+#ifdef CONFIG_USB_EHCI_ISO
+ extern void usbh_video_fps_init(void);
+ usbh_video_fps_init();
+ frame_pool[0].frame_buf = frame_buffer1;
+ frame_pool[0].frame_bufsize = 640 * 480 * 2;
+ frame_pool[1].frame_buf = frame_buffer2;
+ frame_pool[1].frame_bufsize = 640 * 480 * 2;
+
+ usbh_video_stream_init(5, frame_pool, 2);
+
+ for (uint8_t i = 0; i < 8; i++) {
+ frame_pool2[i].frame_buf = frame_buffer + i * AUDIO_MIC_EP_MPS;
+ frame_pool2[i].frame_bufsize = AUDIO_MIC_EP_MPS;
+ }
+
+ usbh_audio_mic_stream_init(5, frame_pool2, 8);
+#endif
+ vTaskStartScheduler();
+
+ while (1) {
+ }
+}
+
+int usbh_deinit(int argc, char **argv)
+{
+ printf("usbh_deinit\r\n");
+ usbh_deinitialize(0);
+ return 0;
+}
+SHELL_CMD_EXPORT_ALIAS(usbh_deinit, usbh_deinit, usbh deinit);
+
+int usbh_init(int argc, char **argv)
+{
+ printf("usbh_init\r\n");
+ usbh_initialize(0, 0x20072000, NULL);
+ return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(usbh_init, usbh_init, usbh init);
+
+SHELL_CMD_EXPORT_ALIAS(lsusb, lsusb, ls usb);
+
+// int uvcinit(int argc, char **argv)
+// {
+// video_init(0, 0x20072000);
+// return 0;
+// }
+// SHELL_CMD_EXPORT_ALIAS(uvcinit, uvcinit, usbh init);
+
+// int uvcsend(int argc, char **argv)
+// {
+// extern void video_test(uint8_t busid);
+// video_test(0);
+// return 0;
+// }
+// SHELL_CMD_EXPORT_ALIAS(uvcsend, uvcsend, usbh init);
+
+#ifdef CONFIG_USB_EHCI_ISO
+int usbh_uvc_start(int argc, char **argv)
+{
+ uint8_t type;
+
+ if (argc < 2) {
+ USB_LOG_ERR("please input correct command: usbh_uvc_start type\r\n");
+ USB_LOG_ERR("type 0:yuyv, type 1:mjpeg\r\n");
+ return -1;
+ }
+
+ type = atoi(argv[1]);
+ usbh_video_stream_start(640, 480, type);
+ return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(usbh_uvc_start, usbh_uvc_start, usbh_uvc_start);
+
+int usbh_uvc_stop(int argc, char **argv)
+{
+ usbh_video_stream_stop();
+ return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(usbh_uvc_stop, usbh_uvc_stop, usbh_uvc_stop);
+
+int usbh_uac_start(int argc, char **argv)
+{
+ uint32_t freq;
+
+ if (argc < 2) {
+ USB_LOG_ERR("please input correct command: usbh_uac_start freq\r\n");
+ return -1;
+ }
+
+ freq = atoi(argv[1]);
+ usbh_audio_mic_stream_start(freq);
+ return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(usbh_uac_start, usbh_uac_start, usbh_uac_start);
+
+int usbh_uac_stop(int argc, char **argv)
+{
+ usbh_audio_mic_stream_stop();
+ return 0;
+}
+
+SHELL_CMD_EXPORT_ALIAS(usbh_uac_stop, usbh_uac_stop, usbh_uac_stop);
+#endif \ No newline at end of file
diff --git a/tests/hpmicro/CMakeLists.txt b/tests/hpmicro/CMakeLists.txt
index 5824878c..40b0e56c 100644
--- a/tests/hpmicro/CMakeLists.txt
+++ b/tests/hpmicro/CMakeLists.txt
@@ -23,6 +23,7 @@ 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(-DLWIP_TIMEVAL_PRIVATE=0)
sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_ECM)
sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_NCM)
@@ -30,23 +31,23 @@ sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_CDC_RNDIS)
sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_ASIX)
sdk_compile_definitions(-DCONFIG_USBHOST_PLATFORM_RTL8152)
+sdk_compile_options("-O2")
+
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)
+sdk_inc(src/iperf)
+sdk_app_src(src/iperf/iperf.c src/iperf/iperf_cli.c src/iperf/utils_getopt.c src/ping.c)
set(CONFIG_CHERRYMP 1)
set(CONFIG_CHERRYUSB 1)
set(CONFIG_CHERRYUSB_DEVICE 1)
set(CONFIG_CHERRYUSB_HOST 1)
+# sdk_app_src(src/uvc2lcd.c)
+# sdk_app_src(src/font24x48.c)
# add_subdirectory(src/cherryusb_hostuvcuac)
add_subdirectory(../.. cherryusb)
diff --git a/tests/hpmicro/inc/FreeRTOSConfig.h b/tests/hpmicro/inc/FreeRTOSConfig.h
index d2169531..89fd13a7 100644
--- a/tests/hpmicro/inc/FreeRTOSConfig.h
+++ b/tests/hpmicro/inc/FreeRTOSConfig.h
@@ -29,6 +29,14 @@
#define configMTIMECMP_BASE_ADDRESS (HPM_MCHTMR_BASE + 8UL)
#endif
+/* When USE_SYSCALL_INTERRUPT_PRIORITY is set, interrupts whose priority is higher than configMAX_SYSCALL_INTERRUPT_PRIORITY
+ will not be delayed by anything FreeRTOS do. */
+#if defined (USE_SYSCALL_INTERRUPT_PRIORITY) && USE_SYSCALL_INTERRUPT_PRIORITY
+#ifndef configMAX_SYSCALL_INTERRUPT_PRIORITY
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+#endif
+#endif
+
#define configUSE_PREEMPTION 1
#define configCPU_CLOCK_HZ ((uint32_t) 24000000)
#define configTICK_RATE_HZ ((TickType_t) 1000)
@@ -47,7 +55,7 @@
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#ifndef configTOTAL_HEAP_SIZE
-#define configTOTAL_HEAP_SIZE ((size_t) (120 * 1024))
+#define configTOTAL_HEAP_SIZE ((size_t) (64 * 1024))
#endif
/* Hook function definitions. */
diff --git a/tests/hpmicro/inc/arch/cc.h b/tests/hpmicro/inc/arch/cc.h
index 4c527c03..cca22bc8 100644
--- a/tests/hpmicro/inc/arch/cc.h
+++ b/tests/hpmicro/inc/arch/cc.h
@@ -31,7 +31,7 @@
*/
/*
- * Copyright (c) 2021-2022 HPMicro
+ * Copyright (c) 2021-2024 HPMicro
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -68,11 +68,23 @@
#elif defined (__GNUC__)
+#include <sys/time.h>
+#include <time.h>
+
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
+#elif defined(__ICCRISCV__)
+
+#include <time.h>
+#define PACK_STRUCT_BEGIN
+#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
+#define PACK_STRUCT_END
+#define PACK_STRUCT_FIELD(x) x
+typedef unsigned long clockid_t;
+
#elif defined (__TASKING__)
#define PACK_STRUCT_BEGIN
@@ -84,8 +96,4 @@
#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
index 24e2dda8..cb32e9ca 100644
--- a/tests/hpmicro/inc/arch/sys_arch.c
+++ b/tests/hpmicro/inc/arch/sys_arch.c
@@ -124,9 +124,9 @@ 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",
+ /* 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 */
}
@@ -136,424 +136,400 @@ sys_init(void)
#endif
#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
-u32_t
-sys_now(void)
+u32_t sys_now(void)
{
- return xTaskGetTickCount() * portTICK_PERIOD_MS;
+ return xTaskGetTickCount() * portTICK_PERIOD_MS;
}
#else
-u32_t
-sys_now(void)
+u32_t sys_now(void)
{
- return 0;
+ return 0;
}
#endif
-u32_t
-sys_jiffies(void)
+u32_t sys_jiffies(void)
{
- return xTaskGetTickCount();
+ return xTaskGetTickCount();
}
#if SYS_LIGHTWEIGHT_PROT
-sys_prot_t
-sys_arch_protect(void)
+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);
+ 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;
- }
+ 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;
+ return 1;
#endif
}
-void
-sys_arch_unprotect(sys_prot_t pval)
+void sys_arch_unprotect(sys_prot_t pval)
{
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
- BaseType_t ret;
+ 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);
+ 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);
+ 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);
+ 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();
+ taskEXIT_CRITICAL();
#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
- LWIP_UNUSED_ARG(pval);
+ LWIP_UNUSED_ARG(pval);
}
#endif /* SYS_LIGHTWEIGHT_PROT */
-void
-sys_arch_msleep(u32_t delay_ms)
+void sys_arch_msleep(u32_t delay_ms)
{
- TickType_t delay_ticks = delay_ms / portTICK_RATE_MS;
- vTaskDelay(delay_ticks);
+ 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)
+err_t sys_mutex_new(sys_mutex_t *mutex)
{
- LWIP_ASSERT("mutex != NULL", mutex != NULL);
+ 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;
+ 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)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("mutex != NULL", mutex != NULL);
+ LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); /* NOLINT */
- ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY);
- LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
+ ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY);
+ LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
}
-void
-sys_mutex_unlock(sys_mutex_t *mutex)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("mutex != NULL", mutex != NULL);
+ LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); /* NOLINT */
- ret = xSemaphoreGiveRecursive(mutex->mut);
- LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
+ ret = xSemaphoreGiveRecursive(mutex->mut);
+ LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
}
-void
-sys_mutex_free(sys_mutex_t *mutex)
+void sys_mutex_free(sys_mutex_t *mutex)
{
- LWIP_ASSERT("mutex != NULL", mutex != NULL);
- LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
+ LWIP_ASSERT("mutex != NULL", mutex != NULL);
+ LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL); /* NOLINT */
- SYS_STATS_DEC(mutex.used);
- vSemaphoreDelete(mutex->mut);
- 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)
+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));
+ 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);
+ 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;
+ 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)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("sem != NULL", sem != NULL);
+ LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); /* NOLINT */
- 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));
+ 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)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("sem != NULL", sem != NULL);
+ LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); /* NOLINT */
- 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;
+ 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);
}
- 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. */
+ /* 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)
+void sys_sem_free(sys_sem_t *sem)
{
- LWIP_ASSERT("sem != NULL", sem != NULL);
- LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
+ LWIP_ASSERT("sem != NULL", sem != NULL);
+ LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL); /* NOLINT */
- SYS_STATS_DEC(sem.used);
- vSemaphoreDelete(sem->sem);
- 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)
+err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
- LWIP_ASSERT("mbox != NULL", mbox != NULL);
- LWIP_ASSERT("size > 0", size > 0);
+ LWIP_ASSERT("mbox != NULL", mbox != NULL); /* NOLINT */
+ 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;
+ 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)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
- ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY);
- LWIP_ASSERT("mbox post failed", ret == pdTRUE);
+ 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)
+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);
+ BaseType_t ret;
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
- 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;
- }
+ 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)
+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);
+ BaseType_t ret;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
- ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken);
- if (ret == pdTRUE) {
- if (xHigherPriorityTaskWoken == pdTRUE) {
- return ERR_NEED_SCHED;
+ 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;
}
- 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)
+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);
+ BaseType_t ret;
+ void *msg_dummy;
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
- if (!msg) {
- msg = &msg_dummy;
- }
+ 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;
+ 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);
}
- 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;
+ /* 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)
+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);
+ BaseType_t ret;
+ void *msg_dummy;
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
- if (!msg) {
- msg = &msg_dummy;
- }
+ 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);
+ 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;
+ /* 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)
+void sys_mbox_free(sys_mbox_t *mbox)
{
- LWIP_ASSERT("mbox != NULL", mbox != NULL);
- LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
+ LWIP_ASSERT("mbox != NULL", mbox != NULL);
+ LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL); /* NOLINT */
#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
- {
- UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx);
- LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
+ {
+ 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);
+ if (msgs_waiting != 0) {
+ SYS_STATS_INC(mbox.err);
+ }
}
- }
#endif
- vQueueDelete(mbox->mbx);
+ vQueueDelete(mbox->mbx);
- SYS_STATS_DEC(mbox.used);
+ SYS_STATS_DEC(mbox.used);
}
-sys_thread_t
-sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
+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;
+ TaskHandle_t rtos_task;
+ BaseType_t ret;
+ sys_thread_t lwip_thread;
+ size_t rtos_stacksize;
- LWIP_ASSERT("invalid stacksize", stacksize > 0);
+ LWIP_ASSERT("invalid stacksize", stacksize > 0);
#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
- rtos_stacksize = (size_t)stacksize;
+ rtos_stacksize = (size_t)stacksize;
#else
- rtos_stacksize = (size_t)stacksize / sizeof(StackType_t);
+ 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'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;
+ 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)
+sys_sem_t *sys_arch_netconn_sem_get(void)
{
- void *ret;
- TaskHandle_t task = xTaskGetCurrentTaskHandle();
- LWIP_ASSERT("task != NULL", task != NULL);
+ void *ret;
+ TaskHandle_t task = xTaskGetCurrentTaskHandle();
+ LWIP_ASSERT("task != NULL", task != NULL);
- ret = pvTaskGetThreadLocalStoragePointer(task, 0);
- return ret;
+ ret = pvTaskGetThreadLocalStoragePointer(task, 0);
+ return ret;
}
-void
-sys_arch_netconn_sem_alloc(void)
+void sys_arch_netconn_sem_alloc(void)
{
- void *ret;
- TaskHandle_t task = xTaskGetCurrentTaskHandle();
- LWIP_ASSERT("task != NULL", task != NULL);
+ 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);
- }
+ 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);
+ 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);
- }
+ 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 */
@@ -569,24 +545,22 @@ void sys_arch_netconn_sem_free(void)
static u8_t lwip_core_lock_count;
static TaskHandle_t lwip_core_lock_holder_thread;
-void
-sys_lock_tcpip_core(void)
+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++;
+ 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)
+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);
+ 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 */
@@ -595,36 +569,34 @@ sys_unlock_tcpip_core(void)
static TaskHandle_t lwip_tcpip_thread;
#endif
-void
-sys_mark_tcpip_thread(void)
+void sys_mark_tcpip_thread(void)
{
#if !NO_SYS
- lwip_tcpip_thread = xTaskGetCurrentTaskHandle();
+ lwip_tcpip_thread = xTaskGetCurrentTaskHandle();
#endif
}
-void
-sys_check_core_locking(void)
+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 );
+ /* 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();
+ 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_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);
+ 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);
+ LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread);
#endif /* LWIP_TCPIP_CORE_LOCKING */
- }
+ }
#endif /* !NO_SYS */
}
diff --git a/tests/hpmicro/inc/lwipopts.h b/tests/hpmicro/inc/lwipopts.h
index e8898bc5..09ec2fdc 100644
--- a/tests/hpmicro/inc/lwipopts.h
+++ b/tests/hpmicro/inc/lwipopts.h
@@ -1,202 +1,436 @@
/*
- * 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
+ * Copyright (c) 2025, sakumisu
*
+ * SPDX-License-Identifier: Apache-2.0
*/
-#ifndef __LWIPOPTS_H__
-#define __LWIPOPTS_H__
+#ifndef LWIPOPTS_H
+#define LWIPOPTS_H
-#include <stdint.h>
-
-#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
+#ifdef USE_LWIPOPTS_APP_H
+#include "lwipopts_app.h"
#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
+/**
+ * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
+ * critical regions during buffer allocation, deallocation and memory
+ * allocation and deallocation.
+ */
+#define SYS_LIGHTWEIGHT_PROT 1
+#define IP_REASSEMBLY 0
+#define IP_FRAG 0
+#define ARP_QUEUEING 0
+#define NO_SYS 0
+#define LWIP_RAND rand
-#define LWIP_HTTPD_CGI 0
-#define LWIP_HTTPD_SSI 0
-#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
+#define LWIP_NETIF_HOSTNAME 0
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_TIMERS 1
+#define LWIP_RAW 1
+#define LWIP_IPV4 1
+#define LWIP_IGMP 1
+#define LWIP_ICMP 1
+#define ICMP_TTL 64
+#define LWIP_TCP 1
+#define TCP_TTL 255
+#define LWIP_UDP 1
+#define UDP_TTL 255
+#define LWIP_DNS 1
/**
- * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator.
+ * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
*/
-#define MEMP_MEM_MALLOC 1
+#define LWIP_NETIF_API 1
+/**
+ * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
+ */
+#define LWIP_NETCONN 1
+/**
+ * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
+ */
+#define LWIP_SOCKET 1
+
+/* ---------- Memory options ---------- */
+#define MEMP_MEM_MALLOC 0
+
+/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
+ lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
+ byte alignment -> define MEM_ALIGNMENT to 2. */
+#ifndef MEM_ALIGNMENT
+#define MEM_ALIGNMENT 64
+#endif
+
+/* MEM_SIZE: the size of the heap memory. If the application will send
+a lot of data that needs to be copied, this should be set high. */
+#ifndef MEM_SIZE
+#define MEM_SIZE (32 * 1024)
+#endif
/* 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.
+ sends a lot of data out of ROM (or other static memory), this
+ should be set high. */
+#ifndef MEMP_NUM_PBUF
+#define MEMP_NUM_PBUF 100
+#endif
+
+/**
+ * MEMP_NUM_RAW_PCB: Number of raw connection PCBs
+ * (requires the LWIP_RAW option)
*/
-#define MEMP_NUM_PBUF 100
+#ifndef MEMP_NUM_RAW_PCB
+#define MEMP_NUM_RAW_PCB 4
+#endif
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
- * per active UDP "connection".
- */
-#define MEMP_NUM_UDP_PCB 6
+ per active UDP "connection". */
+#ifndef MEMP_NUM_UDP_PCB
+#define MEMP_NUM_UDP_PCB 4
+#endif
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
- * connections.
- */
-#define MEMP_NUM_TCP_PCB 10
+ connections. */
+#ifndef MEMP_NUM_TCP_PCB
+#define MEMP_NUM_TCP_PCB 4
+#endif
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
- * connections.
- */
+ connections. */
+#ifndef MEMP_NUM_TCP_PCB_LISTEN
#define MEMP_NUM_TCP_PCB_LISTEN 5
+#endif
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
- * segments.
- */
-#define MEMP_NUM_TCP_SEG 20
+ segments. */
+#ifndef MEMP_NUM_TCP_SEG
+#define MEMP_NUM_TCP_SEG 40
+#endif
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
- * timeouts.
- */
-#define MEMP_NUM_SYS_TIMEOUT 10
+ timeouts. */
+#ifndef MEMP_NUM_SYS_TIMEOUT
+#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL)
+#endif
+/**
+ * MEMP_NUM_NETCONN: the number of struct netconns.
+ * (only needed if you use the sequential API, like api_lib.c)
+ */
+#ifndef MEMP_NUM_NETCONN
+#define MEMP_NUM_NETCONN 4
+#endif
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
-#define PBUF_POOL_SIZE 20
+#ifndef PBUF_POOL_SIZE
+#define PBUF_POOL_SIZE 20
+#endif
-/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool.*/
-#define PBUF_POOL_BUFSIZE 1600
+/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
+#ifndef PBUF_POOL_BUFSIZE
+#define PBUF_POOL_BUFSIZE 1600
+#endif
+/* ---------- TCP options ---------- */
/* 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
+ order. Define to 0 if your device is low on memory. */
+#ifndef TCP_QUEUE_OOSEQ
+#define TCP_QUEUE_OOSEQ 0
+#endif
+
+/* TCP Maximum segment size. */
+#ifndef TCP_MSS
+#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
+#endif
+
+/* TCP sender buffer space (bytes). */
+#ifndef TCP_SND_BUF
+#define TCP_SND_BUF (8 * TCP_MSS)
+#endif
/* 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)
+ as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
+#ifndef TCP_SND_QUEUELEN
+#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF / TCP_MSS)
+#endif
/* TCP receive window. */
-#define TCP_WND (16*TCP_MSS)
+#ifndef TCP_WND
+#define TCP_WND (16 * TCP_MSS)
+#endif
+
+/* ---------- DHCP options ---------- */
+/* Define LWIP_DHCP to 1 if you want DHCP configuration of
+ interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
+ turning this on does currently not work. */
+#ifndef LWIP_DHCP
+#define LWIP_DHCP 1
+#endif
+
+/* ---------- Statistics options ---------- */
+#ifndef LWIP_STATS
+#define LWIP_STATS 0
+#endif
+
+#ifndef LWIP_PROVIDE_ERRNO
+#define LWIP_PROVIDE_ERRNO 1
+#endif
/*
- * -----------------------------------
- * ---------- DEBUG options ----------
- * -----------------------------------
+ ------------------------------------------------
+ ---------- Network Interfaces options ----------
+ ------------------------------------------------
+*/
+/**
+ * LWIP_SINGLE_NETIF==1: use a single netif only. This is the common case for
+ * small real-life targets. Some code like routing etc. can be left out.
*/
+#ifndef LWIP_SINGLE_NETIF
+#define LWIP_SINGLE_NETIF 1
+#endif
+
+/* ---------- link callback options ---------- */
+/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
+ * whenever the link changes (i.e., link down)
+ */
+#ifndef LWIP_NETIF_LINK_CALLBACK
+#define LWIP_NETIF_LINK_CALLBACK 1
+#endif
+
+/**
+ * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data
+ * to be sent into one single pbuf. This is for compatibility with DMA-enabled
+ * MACs that do not support scatter-gather.
+ * Beware that this might involve CPU-memcpy before transmitting that would not
+ * be needed without this flag! Use this only if you need to!
+ *
+ * ATTENTION: a driver should *NOT* rely on getting single pbufs but check TX
+ * pbufs for being in one piece. If not, @ref pbuf_clone can be used to get
+ * a single pbuf:
+ * if (p->next != NULL) {
+ * struct pbuf *q = pbuf_clone(PBUF_RAW, PBUF_RAM, p);
+ * if (q == NULL) {
+ * return ERR_MEM;
+ * }
+ * p = q; ATTENTION: do NOT free the old 'p' as the ref belongs to the caller!
+ * }
+ */
+#ifndef LWIP_NETIF_TX_SINGLE_PBUF
+#define LWIP_NETIF_TX_SINGLE_PBUF 0
+#endif
-#define LWIP_DEBUG 1
+/*
+ --------------------------------------
+ ---------- Checksum options ----------
+ --------------------------------------
+*/
+/*
+ * Some MCUs allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
+ * To use this feature let the following define uncommented.
+ * To disable it and process by CPU comment the the checksum.
+*/
+#ifdef CHECKSUM_BY_HARDWARE
+/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
+#define CHECKSUM_GEN_IP 0
+/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
+#define CHECKSUM_GEN_UDP 0
+/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
+#define CHECKSUM_GEN_TCP 0
+/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
+#define CHECKSUM_CHECK_IP 0
+/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
+#define CHECKSUM_CHECK_UDP 0
+/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
+#define CHECKSUM_CHECK_TCP 0
+/* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
+#define CHECKSUM_GEN_ICMP 0
+#else
+/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
+#define CHECKSUM_GEN_IP 1
+/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
+#define CHECKSUM_GEN_UDP 1
+/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
+#define CHECKSUM_GEN_TCP 1
+/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
+#define CHECKSUM_CHECK_IP 1
+/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
+#define CHECKSUM_CHECK_UDP 1
+/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
+#define CHECKSUM_CHECK_TCP 1
+/* CHECKSUM_CHECK_ICMP==1: Check checksums by software for incoming ICMP packets.*/
+#define CHECKSUM_GEN_ICMP 1
+#endif
+
+/*
+ -----------------------------------
+ ---------- DEBUG options ----------
+ -----------------------------------
+*/
#ifdef LWIP_DEBUG
-#define LWIP_DBG_MIN_LEVEL 1
+#ifndef LWIP_DBG_MIN_LEVEL
+#define LWIP_DBG_MIN_LEVEL 0
+#endif
+
+#ifndef PPP_DEBUG
+#define PPP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef MEM_DEBUG
+#define MEM_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef MEMP_DEBUG
+#define MEMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef PBUF_DEBUG
+#define PBUF_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef API_LIB_DEBUG
+#define API_LIB_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef API_MSG_DEBUG
+#define API_MSG_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCPIP_DEBUG
+#define TCPIP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef NETIF_DEBUG
+#define NETIF_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef SOCKETS_DEBUG
+#define SOCKETS_DEBUG LWIP_DBG_OFF
+#endif
-#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
+#ifndef DNS_DEBUG
+#define DNS_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef AUTOIP_DEBUG
+#define AUTOIP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef DHCP_DEBUG
+#define DHCP_DEBUG LWIP_DBG_OFF
+#endif
+#ifndef IP_DEBUG
+#define IP_DEBUG LWIP_DBG_OFF
#endif
-#define DHCP_DOES_ARP_CHECK 0
+#ifndef IP_REASS_DEBUG
+#define IP_REASS_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef ICMP_DEBUG
+#define ICMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef IGMP_DEBUG
+#define IGMP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef UDP_DEBUG
+#define UDP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_DEBUG
+#define TCP_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_INPUT_DEBUG
+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_OUTPUT_DEBUG
+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_RTO_DEBUG
+#define TCP_RTO_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_CWND_DEBUG
+#define TCP_CWND_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_WND_DEBUG
+#define TCP_WND_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_FR_DEBUG
+#define TCP_FR_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_QLEN_DEBUG
+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef TCP_RST_DEBUG
+#define TCP_RST_DEBUG LWIP_DBG_OFF
+#endif
+
+#ifndef ETHARP_DEBUG
+#define ETHARP_DEBUG LWIP_DBG_OFF
+#endif
+
+#endif
/*
- * ---------------------------------
- * ---------- OS options ----------
- * ---------------------------------
- */
+ ---------------------------------
+ ---------- OS options ----------
+ ---------------------------------
+*/
+#ifndef TCPIP_THREAD_NAME
+#define TCPIP_THREAD_NAME "tcpip"
+#endif
-#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
+#ifndef TCPIP_THREAD_STACKSIZE
+#define TCPIP_THREAD_STACKSIZE 2048
+#endif
+#ifndef TCPIP_MBOX_SIZE
+#define TCPIP_MBOX_SIZE 8
+#endif
+
+#ifndef DEFAULT_RAW_RECVMBOX_SIZE
+#define DEFAULT_RAW_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_UDP_RECVMBOX_SIZE
+#define DEFAULT_UDP_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_TCP_RECVMBOX_SIZE
+#define DEFAULT_TCP_RECVMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_ACCEPTMBOX_SIZE
+#define DEFAULT_ACCEPTMBOX_SIZE 50
+#endif
+
+#ifndef DEFAULT_THREAD_STACKSIZE
+#define DEFAULT_THREAD_STACKSIZE 500
+#endif
+
+#ifndef TCPIP_THREAD_PRIO
+#define TCPIP_THREAD_PRIO 10
+#endif
+
+#define LWIP_COMPAT_MUTEX 0
+#define LWIP_TCPIP_CORE_LOCKING 1
+
+#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
-#define LWIP_TCPIP_CORE_LOCKING 1
+#endif
+
+#ifndef LWIP_MEM_SECTION
+#define LWIP_MEM_SECTION ".bss"
+#endif
-#include <FreeRTOS.h>
-#include <task.h>
-#endif /* __LWIPOPTS_H__ */ \ No newline at end of file
+#endif /* __LWIPOPTS_H__ */
diff --git a/tests/hpmicro/inc/usb_config.h b/tests/hpmicro/inc/usb_config.h
index 1700635e..a9ee4fc5 100644
--- a/tests/hpmicro/inc/usb_config.h
+++ b/tests/hpmicro/inc/usb_config.h
@@ -47,7 +47,7 @@
#define USBD_MAX_POWER 200
/* attribute data into no cache ram */
-#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable.non_init")))
+#define USB_NOCACHE_RAM_SECTION __attribute__((section(".fast_ram.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.
@@ -172,7 +172,7 @@
#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_ENDPOINTS 4
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
#define CONFIG_USBHOST_MAX_HID_CLASS 4
@@ -198,7 +198,7 @@
/* Ep0 max transfer buffer */
#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN
-#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
+#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 4096
#endif
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
@@ -213,7 +213,7 @@
* 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)
+#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (16 * 1024)
#endif
/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */
@@ -306,4 +306,7 @@
#define usb_ramaddr2phyaddr(addr) sys_address_to_core_local_mem(BOARD_RUNNING_CORE, addr)
#endif
+#define ATTR_FAST_RAM_SECTION __attribute__((section(".fast")))
+// #define CONFIG_USB_EHCI_ISO
+
#endif
diff --git a/tests/hpmicro/src/font24x48.c b/tests/hpmicro/src/font24x48.c
new file mode 100644
index 00000000..c11c609b
--- /dev/null
+++ b/tests/hpmicro/src/font24x48.c
@@ -0,0 +1,1066 @@
+/*
+ * Copyright (c) 2022 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+const unsigned char nAsciiDot24x48[]=
+{
+//0x0020( )
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0021(!)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x1C,0x00,0x00,0x18,0x00,0x00,
+0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0022(")
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x00,0x3C,0x1E,0x00,0x3C,0x1E,0x00,0x3C,0x1E,
+0x00,0x18,0x0C,0x00,0x18,0x0C,0x00,0x18,0x0C,0x00,0x18,0x0C,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0023(#)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x00,0x60,0x18,0x00,0x30,0x0C,0x00,0x30,0x0C,
+0x00,0x30,0x0C,0x00,0x30,0x0C,0x00,0xFF,0x3F,0x00,0xFF,0x3F,0x00,0x18,0x06,0x00,
+0x18,0x06,0x00,0x18,0x06,0x00,0x18,0x06,0x00,0xFF,0x3F,0x00,0xFF,0x3F,0x00,0x0C,
+0x03,0x00,0x0C,0x03,0x00,0x8C,0x03,0x00,0x86,0x01,0x00,0x86,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0024($)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x80,0x00,0x00,0xE0,0x07,0x00,0x98,0x1E,0x00,0x8C,0x18,0x00,0x8E,0x18,
+0x00,0x8E,0x10,0x00,0x9E,0x00,0x00,0xFE,0x00,0x00,0xFC,0x00,0x00,0xF8,0x03,0x00,
+0xF0,0x07,0x00,0xC0,0x1F,0x00,0x80,0x1F,0x00,0x80,0x3E,0x00,0x80,0x3C,0x00,0x82,
+0x38,0x00,0x86,0x38,0x00,0x86,0x18,0x00,0x9E,0x0C,0x00,0xF8,0x03,0x00,0x80,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0025(%)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x0C,0x98,0x01,0x06,0x9C,0x03,0x03,0x9C,0x03,
+0x03,0x9C,0x83,0x01,0x9C,0x83,0x01,0x9C,0xC3,0x00,0x9C,0x63,0x00,0x98,0x61,0x00,
+0xF0,0x30,0x3C,0x00,0x18,0x66,0x00,0x18,0xE7,0x00,0x0C,0xE7,0x00,0x0E,0xE7,0x00,
+0x06,0xE7,0x00,0x03,0xE7,0x00,0x03,0xE7,0x80,0x01,0x66,0xC0,0x00,0x3C,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0026(&)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x73,0x00,0x80,0xE1,0x00,0xC0,0xE1,
+0x00,0xC0,0xE1,0x00,0xC0,0x63,0x00,0xC0,0x3B,0x00,0xC0,0x07,0x00,0xC0,0x87,0x1F,
+0xF0,0x0F,0x0F,0x18,0x1F,0x06,0x1C,0x3F,0x03,0x1E,0x3E,0x01,0x1E,0xFC,0x01,0x3E,
+0xF8,0x00,0x7E,0xF0,0x33,0xFC,0xF8,0x1F,0xFC,0xCF,0x0F,0xF0,0x83,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0027(')
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0028(()
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0xC0,0x00,0x00,0x60,0x00,0x00,0x70,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,
+0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,
+0x00,0x00,0x1E,0x00,0x00,0x1C,0x00,0x00,0x1C,0x00,0x00,0x3C,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x70,0x00,0x00,0x60,0x00,0x00,0xC0,0x00,0x00,0x00,0x01,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0029())
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x1C,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,
+0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,
+0x00,0x00,0xF0,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x1C,0x00,0x00,0x0C,0x00,0x00,0x06,0x00,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002A(*)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0xC0,0x01,0x00,0x98,0x0C,
+0x00,0xB8,0x0E,0x00,0xF0,0x07,0x00,0xC0,0x00,0x00,0x60,0x03,0x00,0x70,0x07,0x00,
+0x30,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002B(+)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,
+0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,
+0xFE,0x7F,0x00,0xFE,0x7F,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,
+0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002C(,)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x1C,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x30,0x00,
+0x00,0x30,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002D(-)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002E(.)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x0C,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x002F(/)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0x60,0x00,0x00,0x60,0x00,
+0x00,0x60,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x18,0x00,0x00,
+0x18,0x00,0x00,0x18,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x06,
+0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x03,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0030(0)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x30,0x07,0x00,0x18,0x06,0x00,0x1C,0x0E,
+0x00,0x1C,0x0E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,
+0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1C,
+0x0E,0x00,0x1C,0x0E,0x00,0x18,0x06,0x00,0x30,0x03,0x00,0xE0,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0031(1)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0xE0,0x01,0x00,0xF8,0x01,0x00,0xFC,0x01,
+0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,
+0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,
+0x01,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x03,0x00,0xFC,0x0F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0032(2)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xFC,0x03,0x00,0xFE,0x03,0x00,0xC6,0x07,
+0x00,0x83,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x03,0x00,0x80,0x03,0x00,
+0xC0,0x01,0x00,0xC0,0x00,0x00,0xE0,0x00,0x00,0x60,0x00,0x00,0x30,0x08,0x00,0x18,
+0x08,0x00,0xF8,0x0F,0x00,0xFC,0x07,0x00,0xFE,0x07,0x00,0xFF,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0033(3)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0xF8,0x03,0x00,0xC4,0x07,0x00,0x82,0x07,
+0x00,0x80,0x07,0x00,0x80,0x03,0x00,0xC0,0x01,0x00,0xE0,0x01,0x00,0xF0,0x03,0x00,
+0xE0,0x07,0x00,0x80,0x0F,0x00,0x80,0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,
+0x0F,0x00,0x07,0x07,0x00,0x8F,0x03,0x00,0xFF,0x01,0x00,0x7E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0034(4)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x07,0x00,0x80,0x07,
+0x00,0xC0,0x07,0x00,0xA0,0x07,0x00,0xA0,0x07,0x00,0x90,0x07,0x00,0x88,0x07,0x00,
+0x88,0x07,0x00,0x84,0x07,0x00,0x82,0x07,0x00,0xFE,0x1F,0x00,0xFE,0x1F,0x00,0xFE,
+0x1F,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0035(5)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xF0,0x1F,0x00,0xF8,0x0F,0x00,0xF8,0x0F,
+0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x7C,0x00,0x00,0xFC,0x03,0x00,0xFE,0x07,0x00,
+0xFE,0x0F,0x00,0xC0,0x1F,0x00,0x00,0x1E,0x00,0x00,0x1C,0x00,0x00,0x18,0x00,0x00,
+0x18,0x00,0x0E,0x08,0x00,0x1E,0x08,0x00,0x7E,0x04,0x00,0xF8,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0036(6)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x80,0x07,0x00,0xC0,0x01,0x00,0x70,0x00,
+0x00,0x70,0x00,0x00,0x38,0x00,0x00,0x3C,0x00,0x00,0xFC,0x03,0x00,0x1C,0x0F,0x00,
+0x1E,0x0F,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,
+0x1E,0x00,0x1C,0x0E,0x00,0x3C,0x0E,0x00,0x38,0x07,0x00,0xE0,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0037(7)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFC,0x1F,0x00,0xFC,0x1F,0x00,0xFC,0x0F,0x00,0xFC,0x0F,
+0x00,0x06,0x0C,0x00,0x02,0x06,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x03,0x00,
+0x00,0x03,0x00,0x00,0x03,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0x80,0x01,0x00,0xC0,
+0x00,0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0x60,0x00,0x00,0x60,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0038(8)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x38,0x0E,0x00,0x1C,0x1C,0x00,0x1E,0x1C,
+0x00,0x1E,0x1C,0x00,0x3E,0x1C,0x00,0x7E,0x0E,0x00,0xFC,0x07,0x00,0xF8,0x03,0x00,
+0xF0,0x07,0x00,0xF8,0x0F,0x00,0x9C,0x1F,0x00,0x0E,0x1F,0x00,0x0E,0x1E,0x00,0x0E,
+0x1E,0x00,0x0E,0x1E,0x00,0x0C,0x0E,0x00,0x1C,0x07,0x00,0xF0,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0039(9)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xE0,0x01,0x00,0x38,0x07,0x00,0x1C,0x0F,0x00,0x1C,0x0E,
+0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,
+0x3C,0x1E,0x00,0x3C,0x1E,0x00,0xF0,0x0F,0x00,0x00,0x0E,0x00,0x00,0x07,0x00,0x80,
+0x07,0x00,0x80,0x03,0x00,0xE0,0x01,0x00,0x78,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003A(:)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003B(;)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x38,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x78,0x00,0x00,0x60,0x00,
+0x00,0x60,0x00,0x00,0x30,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003C(<)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+0x00,0x00,0xF0,0x00,0x00,0x7C,0x00,0x80,0x0F,0x00,0xE0,0x03,0x00,0x7C,0x00,0x00,
+0x1E,0x00,0x00,0x7C,0x00,0x00,0xE0,0x03,0x00,0x80,0x0F,0x00,0x00,0x7C,0x00,0x00,
+0xF0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003D(=)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x00,0xFE,0xFF,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x00,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003E(>)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
+0x00,0x0F,0x00,0x00,0x3E,0x00,0x00,0xF0,0x01,0x00,0xC0,0x07,0x00,0x00,0x3E,0x00,
+0x00,0x78,0x00,0x00,0x3E,0x00,0xC0,0x07,0x00,0xF0,0x01,0x00,0x3E,0x00,0x00,0x0F,
+0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x003F(?)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x18,0x0F,0x00,0x1C,0x1E,0x00,0x3C,0x1E,
+0x00,0x3C,0x1E,0x00,0x38,0x1E,0x00,0x00,0x1E,0x00,0x00,0x0F,0x00,0x00,0x07,0x00,
+0x00,0x03,0x00,0x80,0x01,0x00,0x80,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0xC0,0x00,0x00,0xE0,0x01,0x00,0xE0,0x01,0x00,0xC0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0040(@)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x03,0x00,0x07,0x0E,0xC0,0x00,0x18,0x60,0x00,
+0x20,0x10,0x00,0x60,0x18,0x00,0x40,0x08,0x70,0x8F,0x04,0x98,0x87,0x04,0x8E,0x87,
+0x06,0x8F,0x87,0x02,0x87,0x87,0x82,0x87,0x83,0x82,0xC7,0x83,0xC2,0xC3,0x43,0xC2,
+0xE3,0x41,0xC2,0xF3,0x21,0xC2,0xFB,0x11,0xC4,0xEF,0x09,0x84,0xC7,0x87,0x08,0x00,
+0x80,0x18,0x00,0x40,0x30,0x00,0x20,0x60,0x00,0x18,0x80,0x01,0x06,0x00,0xFE,0x01,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0041(A)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x0E,0x00,0x00,0x0F,
+0x00,0x00,0x1F,0x00,0x80,0x1E,0x00,0x80,0x1E,0x00,0x80,0x3C,0x00,0x40,0x3C,0x00,
+0x40,0x7C,0x00,0x20,0x78,0x00,0x20,0x78,0x00,0x10,0xF0,0x00,0xF0,0xFF,0x00,0x10,
+0xF0,0x01,0x08,0xE0,0x01,0x0C,0xE0,0x03,0x0C,0xC0,0x07,0x3F,0xF8,0x0F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0042(B)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0x7F,0x00,0xF0,0xF0,0x00,0xF0,0xE0,0x01,0xF0,0xC0,
+0x03,0xF0,0xC0,0x03,0xF0,0xC0,0x03,0xF0,0xC0,0x03,0xF0,0xE0,0x01,0xF0,0xF0,0x00,
+0xF0,0x7F,0x00,0xF0,0xF0,0x01,0xF0,0xC0,0x03,0xF0,0xC0,0x07,0xF0,0xC0,0x07,0xF0,
+0xC0,0x07,0xF0,0xC0,0x07,0xF0,0xE0,0x03,0xF0,0xF0,0x01,0xFE,0x7F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0043(C)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x02,0xE0,0xC1,0x03,0xF0,0x80,0x03,0x78,0x00,
+0x03,0x78,0x00,0x02,0x3C,0x00,0x02,0x3C,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,
+0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0x7C,
+0x00,0x00,0x78,0x00,0x02,0xF0,0x00,0x03,0xE0,0xC1,0x01,0x80,0x7F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0044(D)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0x00,0x3C,0x7C,0x00,0x3C,0xF0,0x00,0x3C,0xF0,
+0x01,0x3C,0xE0,0x03,0x3C,0xE0,0x03,0x3C,0xC0,0x07,0x3C,0xC0,0x07,0x3C,0xC0,0x07,
+0x3C,0xC0,0x07,0x3C,0xC0,0x07,0x3C,0xC0,0x07,0x3C,0xC0,0x07,0x3C,0xC0,0x03,0x3C,
+0xE0,0x03,0x3C,0xE0,0x01,0x3C,0xF0,0x00,0x3C,0x78,0x00,0xFF,0x0F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0045(E)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0xF0,0xC0,0x01,0xF0,0x80,0x01,0xF0,0x00,
+0x01,0xF0,0x00,0x01,0xF0,0x10,0x00,0xF0,0x10,0x00,0xF0,0x18,0x00,0xF0,0x1C,0x00,
+0xF0,0x1F,0x00,0xF0,0x1C,0x00,0xF0,0x18,0x00,0xF0,0x10,0x00,0xF0,0x10,0x00,0xF0,
+0x00,0x02,0xF0,0x00,0x02,0xF0,0x00,0x03,0xF0,0xC0,0x01,0xFE,0xFF,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0046(F)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0xF0,0xC0,0x01,0xF0,0x80,0x01,0xF0,0x00,
+0x01,0xF0,0x00,0x01,0xF0,0x10,0x00,0xF0,0x10,0x00,0xF0,0x18,0x00,0xF0,0x18,0x00,
+0xF0,0x1F,0x00,0xF0,0x18,0x00,0xF0,0x18,0x00,0xF0,0x10,0x00,0xF0,0x10,0x00,0xF0,
+0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xFE,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0047(G)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x04,0xE0,0xC1,0x07,0xF0,0x00,0x07,0x78,0x00,
+0x06,0x7C,0x00,0x06,0x7C,0x00,0x04,0x3C,0x00,0x00,0x3E,0x00,0x00,0x3E,0x00,0x00,
+0x3E,0x00,0x00,0x3E,0x00,0x00,0x3E,0xF0,0x3F,0x3E,0x80,0x0F,0x3C,0x80,0x07,0x7C,
+0x80,0x07,0x78,0x80,0x07,0xF0,0x80,0x07,0xE0,0x83,0x07,0x00,0xFF,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0048(H)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0xF3,0x3F,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,
+0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,
+0xF8,0xFF,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,
+0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0x78,0x80,0x07,0xFF,0xF3,0x3F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0049(I)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0x03,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
+0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,
+0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,
+0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004A(J)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x3F,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,
+0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,
+0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x86,0x07,0x00,0x8F,
+0x07,0x00,0x8F,0x07,0x00,0x87,0x03,0x00,0xC6,0x01,0x00,0xF8,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004B(K)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0x87,0x3F,0xF0,0x00,0x0E,0xF0,0x00,0x02,0xF0,0x00,
+0x01,0xF0,0x80,0x00,0xF0,0x60,0x00,0xF0,0x10,0x00,0xF0,0x08,0x00,0xF0,0x0E,0x00,
+0xF0,0x1F,0x00,0xF0,0x3E,0x00,0xF0,0x7C,0x00,0xF0,0xF8,0x00,0xF0,0xF0,0x01,0xF0,
+0xF0,0x01,0xF0,0xE0,0x03,0xF0,0xC0,0x07,0xF0,0xC0,0x1F,0xFE,0xE7,0x7F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004C(L)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,
+0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,
+0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x02,0xF0,0x00,0x02,0xF0,
+0x00,0x03,0xF0,0x00,0x03,0xF0,0x80,0x01,0xF0,0xC0,0x01,0xFE,0xFF,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004D(M)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF8,0xF8,0x00,0x7C,0xF8,0x00,0x7C,0xF8,0x01,
+0x7A,0xE8,0x01,0x7A,0xE8,0x03,0x7A,0xC8,0x03,0x79,0xC8,0x03,0x79,0xC8,0x87,0x78,
+0x88,0x87,0x78,0x88,0x8F,0x78,0x08,0x4F,0x78,0x08,0x5F,0x78,0x08,0x3E,0x78,0x08,
+0x3E,0x78,0x08,0x3C,0x78,0x08,0x1C,0x78,0x08,0x18,0x78,0x7F,0x08,0xFF,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004E(N)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x7E,0xE0,0x0F,0xF8,0x80,0x03,0xF8,0x01,0x01,0xE8,0x03,
+0x01,0xC8,0x03,0x01,0xC8,0x07,0x01,0x88,0x0F,0x01,0x08,0x1F,0x01,0x08,0x1E,0x01,
+0x08,0x3E,0x01,0x08,0x7C,0x01,0x08,0xF8,0x01,0x08,0xF0,0x01,0x08,0xF0,0x01,0x08,
+0xE0,0x01,0x08,0xC0,0x01,0x08,0x80,0x01,0x1C,0x80,0x01,0x7F,0x00,0x01,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x004F(O)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x80,0x7F,0x00,0xE0,0xE1,0x01,0xF0,0xC0,0x03,0x78,0x80,
+0x07,0x7C,0x80,0x0F,0x3C,0x00,0x0F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,
+0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3C,0x00,0x0F,0x7C,
+0x80,0x0F,0x78,0x80,0x07,0xF0,0xC0,0x03,0xE0,0xE1,0x01,0x80,0x7F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0050(P)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0x1F,0x00,0x78,0x78,0x00,0x78,0xF0,0x00,0x78,0xE0,
+0x01,0x78,0xE0,0x01,0x78,0xE0,0x01,0x78,0xE0,0x01,0x78,0xF0,0x00,0x78,0x78,0x00,
+0xF8,0x1F,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,
+0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0xFF,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0051(Q)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0xE0,0xE1,0x01,0xF0,0xC0,0x03,0x78,0x80,
+0x07,0x7C,0x80,0x0F,0x3C,0x00,0x0F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,
+0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3E,0x00,0x1F,0x3C,0x00,0x0F,0x7C,
+0x80,0x0F,0x78,0x80,0x07,0xF0,0xC0,0x03,0xE0,0xE1,0x01,0x80,0x7F,0x00,0x00,0x3E,
+0x00,0x00,0x3E,0x00,0x00,0x7C,0x00,0x00,0xF8,0x00,0x00,0xE0,0x0F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0052(R)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0x78,0xF0,0x00,0x78,0xE0,0x01,0x78,0xC0,
+0x03,0x78,0xC0,0x03,0x78,0xC0,0x03,0x78,0xC0,0x03,0x78,0xE0,0x01,0x78,0xF0,0x00,
+0xF8,0x7F,0x00,0x78,0x3E,0x00,0x78,0x3C,0x00,0x78,0x7C,0x00,0x78,0xF8,0x00,0x78,
+0xF0,0x01,0x78,0xE0,0x01,0x78,0xE0,0x03,0x78,0xC0,0x07,0xFF,0x83,0x0F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0053(S)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF0,0x23,0x00,0x38,0x3C,0x00,0x1C,0x38,0x00,0x1E,0x30,
+0x00,0x1E,0x20,0x00,0x3E,0x20,0x00,0xFE,0x00,0x00,0xFC,0x01,0x00,0xF8,0x07,0x00,
+0xF0,0x0F,0x00,0xC0,0x3F,0x00,0x00,0x3F,0x00,0x02,0x7E,0x00,0x02,0x7C,0x00,0x06,
+0x78,0x00,0x06,0x78,0x00,0x0E,0x38,0x00,0x3E,0x1C,0x00,0xE2,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0054(T)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x01,0x8E,0xC7,0x01,0x86,0x87,0x01,0x82,0x07,
+0x01,0x82,0x07,0x01,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,
+0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,
+0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0x80,0x07,0x00,0xF0,0x3F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0055(U)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0xE3,0x0F,0x78,0x80,0x03,0x78,0x00,0x01,0x78,0x00,
+0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,
+0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,0x00,0x01,0x78,
+0x00,0x01,0x78,0x80,0x00,0xF0,0x80,0x00,0xE0,0x61,0x00,0x80,0x1F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0056(V)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0xC1,0x0F,0x7C,0x00,0x07,0x78,0x00,0x03,0x78,0x00,
+0x01,0xF0,0x80,0x00,0xF0,0x80,0x00,0xF0,0x81,0x00,0xE0,0x41,0x00,0xE0,0x41,0x00,
+0xC0,0x23,0x00,0xC0,0x23,0x00,0xC0,0x17,0x00,0x80,0x17,0x00,0x80,0x17,0x00,0x00,
+0x0F,0x00,0x00,0x0F,0x00,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0057(W)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0xFC,0xC7,0x3E,0xF0,0x01,0x3C,0xF0,0x01,0x78,0xE0,
+0x01,0x78,0xE0,0x83,0xF8,0xE0,0x83,0xF0,0xE0,0x83,0xF0,0xE0,0x47,0xF0,0x91,0x47,
+0xE0,0x91,0x47,0xE0,0x11,0x2F,0xC0,0x0B,0x2F,0xC0,0x0B,0x2F,0xC0,0x07,0x1E,0x80,
+0x07,0x1E,0x80,0x07,0x1E,0x80,0x03,0x0C,0x00,0x03,0x0C,0x00,0x03,0x0C,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0058(X)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFF,0xF1,0x03,0x7C,0xC0,0x00,0x78,0x40,0x00,0xF8,0x20,
+0x00,0xF0,0x31,0x00,0xE0,0x11,0x00,0xE0,0x0B,0x00,0xC0,0x07,0x00,0x80,0x07,0x00,
+0x80,0x0F,0x00,0x00,0x0F,0x00,0x80,0x1F,0x00,0x40,0x3E,0x00,0x40,0x3C,0x00,0x20,
+0x7C,0x00,0x10,0xF8,0x00,0x08,0xF0,0x00,0x1C,0xF0,0x01,0x7F,0xFC,0x07,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0059(Y)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0xC1,0x0F,0x7C,0x00,0x03,0x78,0x00,0x01,0xF0,0x00,
+0x01,0xF0,0x81,0x00,0xE0,0x41,0x00,0xE0,0x43,0x00,0xC0,0x23,0x00,0xC0,0x27,0x00,
+0x80,0x17,0x00,0x80,0x1F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,
+0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0x00,0x0F,0x00,0xE0,0x7F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005A(Z)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x00,0x1E,0x78,0x00,0x06,0x3C,0x00,0x06,0x3E,
+0x00,0x02,0x1E,0x00,0x00,0x1F,0x00,0x00,0x0F,0x00,0x80,0x07,0x00,0xC0,0x07,0x00,
+0xC0,0x03,0x00,0xE0,0x03,0x00,0xE0,0x01,0x00,0xF0,0x00,0x01,0xF8,0x00,0x01,0x78,
+0x80,0x01,0x7C,0x80,0x01,0x3C,0xC0,0x01,0x1E,0xF0,0x00,0xFF,0xFF,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005B([)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xF8,0x01,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,
+0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,
+0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0xF8,0x01,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005C(\)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,
+0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x18,0x00,0x00,
+0x18,0x00,0x00,0x18,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x60,
+0x00,0x00,0x60,0x00,0x00,0x60,0x00,0x00,0xE0,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005D(])
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,
+0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,
+0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,
+0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x3F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005E(^)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x80,0x03,0x00,0xC0,0x06,0x00,0xC0,0x06,
+0x00,0x60,0x0C,0x00,0x60,0x0C,0x00,0x30,0x18,0x00,0x18,0x30,0x00,0x18,0x30,0x00,
+0x0C,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x005F(_)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x3F,0x00,0xFF,0x3F,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0060(`)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x1C,0x00,0x00,0x18,0x00,
+0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0061(a)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x0C,0x07,0x00,0x0E,0x0F,0x00,
+0x1E,0x0F,0x00,0x8C,0x0F,0x00,0x40,0x0F,0x00,0x30,0x0F,0x00,0x18,0x0F,0x00,0x1C,
+0x0F,0x00,0x1E,0x0F,0x00,0x9E,0x0F,0x00,0x7E,0x1F,0x00,0x3C,0x0E,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0062(b)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x0F,0x00,0xFC,0x1F,0x00,0x7C,0x3C,0x00,
+0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,
+0x78,0x00,0x3C,0x38,0x00,0x3C,0x38,0x00,0x7C,0x1C,0x00,0xCC,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0063(c)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x01,0x00,0xB8,0x07,0x00,0x1C,0x07,0x00,
+0x1C,0x07,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x3E,
+0x00,0x00,0x3E,0x00,0x00,0x7C,0x06,0x00,0xF8,0x03,0x00,0xF0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0064(d)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0xF0,0x3C,0x00,0x38,0x3F,0x00,0x1C,0x3E,0x00,
+0x1C,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,
+0x3C,0x00,0x3E,0x3C,0x00,0x3C,0x3E,0x00,0xF8,0x7F,0x00,0xF0,0x1C,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0065(e)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xB8,0x03,0x00,0x1C,0x03,0x00,
+0x1C,0x07,0x00,0x1E,0x07,0x00,0xFE,0x07,0x00,0x1E,0x00,0x00,0x1E,0x00,0x00,0x1E,
+0x00,0x00,0x3E,0x04,0x00,0x7C,0x02,0x00,0xF8,0x01,0x00,0xF0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0066(f)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x00,0x38,0x07,0x00,0x3C,0x07,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0xFF,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0067(g)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x1F,0x00,0xBC,0x1F,0x00,0x1E,0x07,0x00,
+0x1E,0x0F,0x00,0x1E,0x0F,0x00,0x1E,0x0F,0x00,0x1C,0x0F,0x00,0xBC,0x07,0x00,0xF0,
+0x01,0x00,0x0C,0x00,0x00,0x0E,0x00,0x00,0xFE,0x07,0x00,0xFE,0x0F,0x00,0xFC,0x1F,
+0x00,0x0C,0x1C,0x00,0x06,0x18,0x00,0x06,0x08,0x00,0x0C,0x0C,0x00,0xF8,0x03,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0068(h)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x0F,0x00,0xBC,0x1F,0x00,0x7C,0x3C,0x00,
+0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,
+0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x7E,0x7E,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0069(i)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006A(j)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x30,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,
+0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,
+0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,0x00,0x78,0x00,
+0x00,0x78,0x00,0x00,0x79,0x00,0x00,0x79,0x00,0x00,0x39,0x00,0x00,0x1F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006B(k)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x3E,0x00,0x3C,0x1C,0x00,0x3C,0x0C,0x00,
+0x3C,0x04,0x00,0x3C,0x02,0x00,0xBC,0x03,0x00,0xFC,0x07,0x00,0xBC,0x0F,0x00,0x3C,
+0x0F,0x00,0x3C,0x1E,0x00,0x3C,0x3E,0x00,0x3C,0x7C,0x00,0x7E,0xFE,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006C(l)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006D(m)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x87,0x03,0xBC,0xCF,0x07,0x7C,0x3E,0x0F,
+0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,
+0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x3C,0x1E,0x0F,0x7E,0xBF,0x1F,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006E(n)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x0F,0x00,0xBC,0x1F,0x00,0x7C,0x3C,0x00,
+0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,
+0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x7E,0x7E,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x006F(o)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x03,0x00,0x38,0x07,0x00,0x1C,0x0E,0x00,
+0x1C,0x0E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,0x1E,0x00,0x1E,
+0x1E,0x00,0x1C,0x0E,0x00,0x1C,0x0E,0x00,0x38,0x07,0x00,0xF0,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0070(p)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE,0x0F,0x00,0xFC,0x1F,0x00,0x7C,0x3C,0x00,
+0x3C,0x38,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,0x78,0x00,0x3C,
+0x78,0x00,0x3C,0x38,0x00,0x3C,0x38,0x00,0x7C,0x1C,0x00,0xBC,0x0F,0x00,0x3C,0x00,
+0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0071(q)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x33,0x00,0x38,0x3E,0x00,0x3C,0x3C,0x00,
+0x1C,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,0x3C,0x00,0x1E,
+0x3C,0x00,0x1E,0x3C,0x00,0x3C,0x3E,0x00,0xF8,0x3F,0x00,0xF0,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0072(r)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x07,0x00,0xBC,0x0F,0x00,0x7C,0x0F,0x00,
+0x3C,0x06,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0073(s)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x01,0x00,0xCC,0x01,0x00,0x8E,0x01,0x00,
+0x1E,0x01,0x00,0x3E,0x00,0x00,0xFC,0x00,0x00,0xFC,0x01,0x00,0xF0,0x03,0x00,0xE0,
+0x03,0x00,0x82,0x03,0x00,0x86,0x03,0x00,0x8E,0x01,0x00,0xF2,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0074(t)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x30,0x00,
+0x00,0x38,0x00,0x00,0x3E,0x00,0x00,0xFF,0x01,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,
+0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,0x00,0x00,0x3C,
+0x00,0x00,0x3C,0x00,0x00,0x3C,0x01,0x00,0xFC,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0075(u)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x3E,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,
+0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3C,0x00,0x3C,
+0x3C,0x00,0x3C,0x3C,0x00,0x3C,0x3E,0x00,0xF8,0x3F,0x00,0xF0,0x7C,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0076(v)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x3C,0x00,0x3E,0x18,0x00,0x3C,0x08,0x00,
+0x3C,0x04,0x00,0x78,0x04,0x00,0x78,0x04,0x00,0xF0,0x02,0x00,0xF0,0x02,0x00,0xF0,
+0x01,0x00,0xE0,0x01,0x00,0xE0,0x00,0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0077(w)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBF,0xBF,0x07,0x1E,0x0F,0x03,0x3E,0x1E,0x01,
+0x3C,0x1E,0x01,0x3C,0xBF,0x00,0x78,0xBD,0x00,0x78,0xBD,0x00,0xF8,0x7C,0x00,0xF0,
+0x78,0x00,0xF0,0x78,0x00,0x70,0x78,0x00,0x60,0x30,0x00,0x60,0x30,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0078(x)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x1F,0x00,0x7C,0x0C,0x00,0x78,0x04,0x00,
+0xF0,0x02,0x00,0xF0,0x01,0x00,0xE0,0x01,0x00,0xE0,0x03,0x00,0xC0,0x03,0x00,0xE0,
+0x07,0x00,0xA0,0x07,0x00,0x10,0x0F,0x00,0x18,0x1F,0x00,0xBE,0x3F,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x0079(y)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x3C,0x00,0x3E,0x18,0x00,0x3C,0x08,0x00,
+0x7C,0x08,0x00,0x78,0x04,0x00,0xF8,0x04,0x00,0xF0,0x02,0x00,0xF0,0x03,0x00,0xE0,
+0x03,0x00,0xE0,0x01,0x00,0xC0,0x01,0x00,0xC0,0x00,0x00,0x80,0x00,0x00,0x80,0x00,
+0x00,0x40,0x00,0x00,0x4E,0x00,0x00,0x2F,0x00,0x00,0x3F,0x00,0x00,0x1E,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007A(z)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x07,0x00,0xC6,0x03,0x00,0xC2,0x03,0x00,
+0xE2,0x01,0x00,0xE0,0x01,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x78,0x00,0x00,0x78,
+0x00,0x00,0x3C,0x04,0x00,0x3C,0x06,0x00,0x1E,0x07,0x00,0xFF,0x07,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007B({)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0xE0,0x00,0x00,0x60,0x00,0x00,0x70,0x00,
+0x00,0x70,0x00,0x00,0x70,0x00,0x00,0xF0,0x00,0x00,0xE0,0x00,0x00,0xE0,0x00,0x00,
+0xE0,0x00,0x00,0x60,0x00,0x00,0x30,0x00,0x00,0x0C,0x00,0x00,0x30,0x00,0x00,0x60,
+0x00,0x00,0xE0,0x00,0x00,0xE0,0x00,0x00,0xE0,0x00,0x00,0xF0,0x00,0x00,0x70,0x00,
+0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x60,0x00,0x00,0xE0,0x00,0x00,0x80,0x03,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007C(|)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,
+0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,
+0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,
+0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,
+0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,0x0C,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007D(})
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x70,0x00,
+0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x78,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,
+0x38,0x00,0x00,0x30,0x00,0x00,0x60,0x00,0x00,0x80,0x01,0x00,0x60,0x00,0x00,0x30,
+0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x78,0x00,0x00,0x70,0x00,
+0x00,0x70,0x00,0x00,0x70,0x00,0x00,0x30,0x00,0x00,0x38,0x00,0x00,0x0E,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007E(~)
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x3C,0x40,0x00,0xFE,0x61,0x00,0xC3,0x3F,0x00,0x01,0x1E,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+//0x007F()
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,
+0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,
+0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,
+0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,
+0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xC6,0x01,0x00,0xFE,0x01,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+};
diff --git a/tests/hpmicro/src/iperf/iperf.c b/tests/hpmicro/src/iperf/iperf.c
new file mode 100644
index 00000000..a7e1fa8f
--- /dev/null
+++ b/tests/hpmicro/src/iperf/iperf.c
@@ -0,0 +1,763 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#include <lwip/sockets.h>
+#include <FreeRTOS.h>
+#include <task.h>
+
+#include "iperf.h"
+
+#include "hpm_clock_drv.h"
+#include "hpm_csr_drv.h"
+#include "board.h"
+
+// TODO move to common
+#define xTaskCreatePinnedToCore(pvTaskCode, pcName, usStackDepth, \
+ pvParameters, uxPriority, \
+ pvCreatedTask, xCoreID_) \
+ xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, \
+ uxPriority, pvCreatedTask)
+
+int64_t iperf_timer_get_time()
+{
+ return (hpm_csr_get_core_mcycle() / (clock_get_frequency(clock_cpu0) / 1000000));
+}
+
+#define iperf_delay_us board_delay_us
+#define IRAM_ATTR __attribute__((section(".fast"))) // on tcm run
+#define IPERF_V6 0 // TODO sync with lwip config
+#define iperf_err_t int
+#define IPERF_OK 0 /*!< iperf_err_t value indicating success (no error) */
+#define IPERF_FAIL -1 /*!< Generic iperf_err_t code indicating failure */
+
+#define IPERF_LOGE(tag, format, ...) \
+ do { \
+ (void)tag; \
+ printf("[%s] " format "\r\n", tag, ##__VA_ARGS__); \
+ } while (0)
+
+#define IPERF_LOGW(tag, format, ...) \
+ do { \
+ (void)tag; \
+ printf("[%s] " format "\r\n", tag, ##__VA_ARGS__); \
+ } while (0)
+
+#define IPERF_LOGI(tag, format, ...) \
+ do { \
+ (void)tag; \
+ printf("[%s] " format "\r\n", tag, ##__VA_ARGS__); \
+ } while (0)
+
+#define IPERF_LOGD(tag, format, ...) \
+ do { \
+ (void)tag; \
+ printf("[%s] " format "\r\n", tag, ##__VA_ARGS__); \
+ } while (0)
+
+#define IPERF_LOGV(tag, format, ...) \
+ do { \
+ (void)tag; \
+ printf("[%s] " format "\r\n", tag, ##__VA_ARGS__); \
+ } while (0)
+
+#define IPERF_GOTO_ON_FALSE(a, err_code, goto_tag, log_tag, format, ...) \
+ do { \
+ (void)log_tag; \
+ if ((!(a))) { \
+ ret = err_code; \
+ goto goto_tag; \
+ } \
+ } while (0)
+
+#define NL "\r\n"
+
+typedef struct {
+ iperf_cfg_t cfg;
+ bool finish;
+ uint32_t actual_len;
+ uint32_t tot_len;
+ uint32_t buffer_len;
+ uint8_t *buffer;
+ uint32_t sockfd;
+} iperf_ctrl_t;
+
+static bool s_iperf_is_running = false;
+static iperf_ctrl_t s_iperf_ctrl;
+static const char *TAG = "iperf";
+
+inline static bool iperf_is_udp_client(void)
+{
+ return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_CLIENT) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_UDP));
+}
+
+inline static bool iperf_is_udp_server(void)
+{
+ return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_SERVER) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_UDP));
+}
+
+inline static bool iperf_is_tcp_client(void)
+{
+ return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_CLIENT) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_TCP));
+}
+
+inline static bool iperf_is_tcp_dual_client(void)
+{
+ return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_CLIENT) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_TCP) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_DUAL));
+}
+
+inline static bool iperf_is_tcp_server(void)
+{
+ return ((s_iperf_ctrl.cfg.flag & IPERF_FLAG_SERVER) && (s_iperf_ctrl.cfg.flag & IPERF_FLAG_TCP));
+}
+
+static int iperf_get_socket_error_code(int sockfd)
+{
+ return errno;
+}
+
+static int iperf_show_socket_error_reason(const char *str, int sockfd)
+{
+ int err = errno;
+ if (err != 0) {
+ IPERF_LOGW(TAG, "%s error, error code: %d, reason: %s", str, err, strerror(err));
+ }
+
+ return err;
+}
+
+static void iperf_report_task(void *arg)
+{
+ uint32_t interval = s_iperf_ctrl.cfg.interval;
+ uint32_t time = s_iperf_ctrl.cfg.time;
+ TickType_t delay_interval = (interval * 1000) / portTICK_PERIOD_MS;
+ uint32_t cur = 0;
+ double average = 0;
+ double actual_bandwidth = 0;
+ double actual_transfer = 0;
+ int k = 1;
+
+ printf("[ ID] Interval Transfer Bandwidth\r\n");
+ while (!s_iperf_ctrl.finish) {
+ vTaskDelay(delay_interval);
+ actual_bandwidth = (s_iperf_ctrl.actual_len / 1e6 * 8) / interval;
+ actual_transfer = s_iperf_ctrl.actual_len / 1e6;
+ printf("[%3d] %2d.0-%2d.0 sec %.2f MByte %.2f Mbits/sec\r\n",
+ s_iperf_ctrl.sockfd, cur, cur + interval, actual_transfer, actual_bandwidth);
+ cur += interval;
+ average = ((average * (k - 1) / k) + (actual_bandwidth / k));
+ k++;
+ s_iperf_ctrl.actual_len = 0;
+ if (cur >= time) {
+ actual_transfer = s_iperf_ctrl.tot_len / 1e6;
+ printf("[%3d] %2d.0-%2d.0 sec %.2f MByte %.2f Mbits/sec\r\n",
+ s_iperf_ctrl.sockfd, 0, time, actual_transfer, average);
+ break;
+ }
+ }
+
+ s_iperf_ctrl.finish = true;
+ vTaskDelete(NULL);
+}
+
+static iperf_err_t iperf_start_report(void)
+{
+ int ret;
+
+ ret = xTaskCreatePinnedToCore(iperf_report_task, IPERF_REPORT_TASK_NAME, IPERF_REPORT_TASK_STACK, NULL, s_iperf_ctrl.cfg.traffic_task_priority, NULL, portNUM_PROCESSORS - 1);
+
+ if (ret != pdPASS) {
+ IPERF_LOGE(TAG, "create task %s failed", IPERF_REPORT_TASK_NAME);
+ return IPERF_FAIL;
+ }
+
+ return IPERF_OK;
+}
+
+static void socket_recv(int recv_socket, struct sockaddr_storage listen_addr, uint8_t type)
+{
+ bool iperf_recv_start = true;
+ uint8_t *buffer;
+ int want_recv = 0;
+ int actual_recv = 0;
+#if IPERF_V6
+ socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+#else
+ socklen_t socklen = sizeof(struct sockaddr_in);
+#endif
+ const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp server recv" : "udp server recv";
+
+ buffer = s_iperf_ctrl.buffer;
+ want_recv = s_iperf_ctrl.buffer_len;
+ while (!s_iperf_ctrl.finish) {
+ actual_recv = recvfrom(recv_socket, buffer, want_recv, 0, (struct sockaddr *)&listen_addr, &socklen);
+ if (actual_recv < 0) {
+ iperf_show_socket_error_reason(error_log, recv_socket);
+ s_iperf_ctrl.finish = true;
+ break;
+ } else {
+ if (iperf_recv_start) {
+ iperf_start_report();
+ iperf_recv_start = false;
+ }
+ s_iperf_ctrl.actual_len += actual_recv;
+ s_iperf_ctrl.tot_len += actual_recv;
+ if (s_iperf_ctrl.cfg.num_bytes > 0 && s_iperf_ctrl.tot_len > s_iperf_ctrl.cfg.num_bytes) {
+ break;
+ }
+ }
+ }
+}
+
+static void socket_recv_dual(int recv_socket, struct sockaddr_storage listen_addr, uint8_t type)
+{
+ uint8_t *buffer;
+ int want_recv = 0;
+ int actual_recv = 0;
+ socklen_t socklen = sizeof(struct sockaddr_in);
+
+#define RECV_DUAL_BUF_LEN (16 * 1024)
+ buffer = pvPortMalloc(RECV_DUAL_BUF_LEN);
+ want_recv = RECV_DUAL_BUF_LEN;
+ if (!buffer) {
+ return;
+ }
+ while (1) {
+ actual_recv = recvfrom(recv_socket, buffer, want_recv, 0, (struct sockaddr *)&listen_addr, &socklen);
+ if (actual_recv <= 0) {
+ break;
+ }
+ }
+ vPortFree(buffer);
+}
+
+typedef struct {
+ int32_t flags;
+ int32_t numThreads;
+ int32_t mPort;
+ int32_t bufferlen;
+ int32_t mWindowSize;
+ int32_t mAmount;
+ int32_t mRate;
+ int32_t mUDPRateUnits;
+ int32_t mRealtime;
+} iperf_client_hdr_t;
+#define HEADER_VERSION1 0x80000000
+#define RUN_NOW 0x00000001
+#define UNITS_PPS 0x00000002
+
+static void send_dual_header(int sock, struct sockaddr *addr, socklen_t socklen)
+{
+ iperf_client_hdr_t hdr = {};
+ iperf_cfg_t *cfg = &s_iperf_ctrl.cfg;
+
+ hdr.flags = htonl(HEADER_VERSION1 | RUN_NOW);
+ hdr.numThreads = htonl(1);
+ hdr.mPort = htonl(cfg->sport);
+ hdr.mAmount = htonl(-(cfg->time * 100));
+
+ sendto(sock, &hdr, sizeof(hdr), 0, addr, socklen);
+}
+
+static void socket_send(int send_socket, struct sockaddr_storage dest_addr, uint8_t type, int bw_lim)
+{
+ uint8_t *buffer;
+ int32_t *pkt_id_p;
+ int32_t pkt_cnt = 0;
+ int actual_send = 0;
+ int want_send = 0;
+ int period_us = -1;
+ int delay_us = 0;
+ int64_t prev_time = 0;
+ int64_t send_time = 0;
+ int err = 0;
+#if IPERF_V6
+ const socklen_t socklen = (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+#else
+ const socklen_t socklen = sizeof(struct sockaddr_in);
+#endif
+ const char *error_log = (type == IPERF_TRANS_TYPE_TCP) ? "tcp client send" : "udp client send";
+
+ buffer = s_iperf_ctrl.buffer;
+ pkt_id_p = (int32_t *)s_iperf_ctrl.buffer;
+ want_send = s_iperf_ctrl.buffer_len;
+ iperf_start_report();
+
+ if (bw_lim > 0) {
+ period_us = want_send * 8 / bw_lim;
+ }
+
+ if (iperf_is_tcp_dual_client()) {
+ send_dual_header(send_socket, (struct sockaddr *)&dest_addr, socklen);
+ }
+
+ while (!s_iperf_ctrl.finish) {
+ if (period_us > 0) {
+ send_time = iperf_timer_get_time();
+ if (actual_send > 0) {
+ // Last packet "send" was successful, check how much off the previous loop duration was to the ideal send period. Result will adjust the
+ // next send delay.
+ delay_us += period_us + (int32_t)(prev_time - send_time);
+ } else {
+ // Last packet "send" was not successful. Ideally we should try to catch up the whole previous loop duration (e.g. prev_time - send_time).
+ // However, that's not possible since the most probable reason why the send was unsuccessful is the HW was not able to process the packet.
+ // Hence, we cannot queue more packets with shorter (or no) delay to catch up since we are already at the performance edge. The best we
+ // can do is to reset the send delay (which is probably big negative number) and start all over again.
+ delay_us = 0;
+ }
+ prev_time = send_time;
+ }
+ *pkt_id_p = htonl(pkt_cnt); // datagrams need to be sequentially numbered
+ if (pkt_cnt >= INT32_MAX) {
+ pkt_cnt = 0;
+ } else {
+ pkt_cnt++;
+ }
+ actual_send = sendto(send_socket, buffer, want_send, 0, (struct sockaddr *)&dest_addr, socklen);
+ if (actual_send != want_send) {
+ if (type == IPERF_TRANS_TYPE_UDP) {
+ err = iperf_get_socket_error_code(send_socket);
+ // ENOMEM is expected under heavy load => do not print it
+ if (err != ENOMEM) {
+ iperf_show_socket_error_reason(error_log, send_socket);
+ }
+ } else if (type == IPERF_TRANS_TYPE_TCP) {
+ iperf_show_socket_error_reason(error_log, send_socket);
+ break;
+ }
+ } else {
+ s_iperf_ctrl.actual_len += actual_send;
+ s_iperf_ctrl.tot_len += actual_send;
+ if (s_iperf_ctrl.cfg.num_bytes > 0 && s_iperf_ctrl.tot_len >= s_iperf_ctrl.cfg.num_bytes) {
+ break;
+ }
+ }
+ // The send delay may be negative, it indicates we are trying to catch up and hence to not delay the loop at all.
+ if (delay_us > 0) {
+ iperf_delay_us(delay_us);
+ }
+ }
+}
+
+static iperf_err_t IRAM_ATTR iperf_run_tcp_server(void)
+{
+ int listen_socket = -1;
+ int client_socket = -1;
+ int opt = 1;
+ int err = 0;
+ iperf_err_t ret = IPERF_OK;
+ struct sockaddr_in remote_addr;
+ struct timeval timeout = { 0 };
+ socklen_t addr_len = sizeof(struct sockaddr);
+ struct sockaddr_storage listen_addr = { 0 };
+#if IPERF_V6
+ struct sockaddr_in6 listen_addr6 = { 0 };
+#endif
+ struct sockaddr_in listen_addr4 = { 0 };
+
+ IPERF_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), IPERF_FAIL, exit, TAG, "Ivalid AF types");
+
+#if IPERF_V6
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
+ // The TCP server listen at the address "::", which means all addresses can be listened to.
+ inet6_aton("::", &listen_addr6.sin6_addr);
+ listen_addr6.sin6_family = AF_INET6;
+ listen_addr6.sin6_port = htons(s_iperf_ctrl.cfg.sport);
+
+ listen_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
+ IPERF_GOTO_ON_FALSE((listen_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ setsockopt(listen_socket, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
+
+ IPERF_LOGI(TAG, "Socket created");
+
+ err = bind(listen_socket, (struct sockaddr *)&listen_addr6, sizeof(listen_addr6));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET6);
+ err = listen(listen_socket, 1);
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
+
+ timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
+ setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
+ } else
+#endif
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+ listen_addr4.sin_family = AF_INET;
+ listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
+ listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
+
+ listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ IPERF_GOTO_ON_FALSE((listen_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ IPERF_LOGI(TAG, "Socket created");
+
+ err = bind(listen_socket, (struct sockaddr *)&listen_addr4, sizeof(listen_addr4));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET);
+
+ err = listen(listen_socket, 5);
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
+ memcpy(&listen_addr, &listen_addr4, sizeof(listen_addr4));
+ }
+
+ client_socket = accept(listen_socket, (struct sockaddr *)&remote_addr, &addr_len);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to accept connection: errno %d", errno);
+ IPERF_LOGI(TAG, "accept: %s,%d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port));
+
+ timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
+ setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ socket_recv(client_socket, listen_addr, IPERF_TRANS_TYPE_TCP);
+exit:
+ if (client_socket != -1) {
+ close(client_socket);
+ }
+
+ if (listen_socket != -1) {
+ shutdown(listen_socket, 0);
+ close(listen_socket);
+ IPERF_LOGI(TAG, "TCP Socket server is closed.");
+ }
+ s_iperf_ctrl.finish = true;
+ return ret;
+}
+
+static void IRAM_ATTR iperf_tcp_dual_server_task(void *pvParameters)
+{
+ int listen_socket = -1;
+ int client_socket = -1;
+ int opt = 1;
+ int err = 0;
+ iperf_err_t ret = IPERF_OK;
+ struct sockaddr_in remote_addr;
+ struct timeval timeout = { 0 };
+ socklen_t addr_len = sizeof(struct sockaddr);
+ struct sockaddr_storage listen_addr = { 0 };
+ struct sockaddr_in listen_addr4 = { 0 };
+
+ (void)ret;
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+ listen_addr4.sin_family = AF_INET;
+ listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
+ listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
+
+ listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ IPERF_GOTO_ON_FALSE((listen_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ IPERF_LOGI(TAG, "Socket created");
+
+ err = bind(listen_socket, (struct sockaddr *)&listen_addr4, sizeof(listen_addr4));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to bind: errno %d, IPPROTO: %d", errno, AF_INET);
+
+ err = listen(listen_socket, 5);
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Error occurred during listen: errno %d", errno);
+ memcpy(&listen_addr, &listen_addr4, sizeof(listen_addr4));
+ }
+
+ client_socket = accept(listen_socket, (struct sockaddr *)&remote_addr, &addr_len);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to accept connection: errno %d", errno);
+ IPERF_LOGI(TAG, "accept: %s,%d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port));
+
+ timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
+ setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ socket_recv_dual(client_socket, listen_addr, IPERF_TRANS_TYPE_TCP);
+exit:
+ if (client_socket != -1) {
+ close(client_socket);
+ }
+
+ if (listen_socket != -1) {
+ shutdown(listen_socket, 0);
+ close(listen_socket);
+ IPERF_LOGI(TAG, "TCP Socket server is closed.");
+ }
+
+ vTaskDelete(NULL);
+}
+
+static iperf_err_t iperf_run_tcp_client(void)
+{
+ int client_socket = -1;
+ int err = 0;
+ iperf_err_t ret = IPERF_OK;
+ struct sockaddr_storage dest_addr = { 0 };
+#if IPERF_V6
+ struct sockaddr_in6 dest_addr6 = { 0 };
+#endif
+ struct sockaddr_in dest_addr4 = { 0 };
+ int opt = s_iperf_ctrl.cfg.tos;
+
+ IPERF_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), IPERF_FAIL, exit, TAG, "Ivalid AF types");
+
+ if (iperf_is_tcp_dual_client()) {
+ xTaskCreate(iperf_tcp_dual_server_task, "dual_rx", IPERF_TRAFFIC_TASK_STACK, NULL, s_iperf_ctrl.cfg.traffic_task_priority, NULL);
+ vTaskDelay(pdMS_TO_TICKS(100));
+ }
+#if IPERF_V6
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
+ client_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ setsockopt(client_socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt));
+
+ inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
+ dest_addr6.sin6_family = AF_INET6;
+ dest_addr6.sin6_port = htons(s_iperf_ctrl.cfg.dport);
+
+ err = connect(client_socket, (struct sockaddr *)&dest_addr6, sizeof(struct sockaddr_in6));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
+ IPERF_LOGI(TAG, "Successfully connected");
+ memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
+ } else
+#endif
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+ client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ setsockopt(client_socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt));
+
+ dest_addr4.sin_family = AF_INET;
+ dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
+ dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;
+ err = connect(client_socket, (struct sockaddr *)&dest_addr4, sizeof(struct sockaddr_in));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to connect: errno %d", errno);
+ IPERF_LOGI(TAG, "Successfully connected");
+ memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4));
+ }
+
+ socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_TCP, s_iperf_ctrl.cfg.bw_lim);
+exit:
+ if (client_socket != -1) {
+ shutdown(client_socket, 0);
+ close(client_socket);
+ IPERF_LOGI(TAG, "TCP Socket client is closed.");
+ }
+ s_iperf_ctrl.finish = true;
+ return ret;
+}
+
+static iperf_err_t IRAM_ATTR iperf_run_udp_server(void)
+{
+ int listen_socket = -1;
+ int opt = 1;
+ int err = 0;
+ iperf_err_t ret = IPERF_OK;
+ struct timeval timeout = { 0 };
+ struct sockaddr_storage listen_addr = { 0 };
+#if IPERF_V6
+ struct sockaddr_in6 listen_addr6 = { 0 };
+#endif
+ struct sockaddr_in listen_addr4 = { 0 };
+
+ IPERF_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), IPERF_FAIL, exit, TAG, "Ivalid AF types");
+
+#if IPERF_V6
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
+ // The UDP server listen at the address "::", which means all addresses can be listened to.
+ inet6_aton("::", &listen_addr6.sin6_addr);
+ listen_addr6.sin6_family = AF_INET6;
+ listen_addr6.sin6_port = htons(s_iperf_ctrl.cfg.sport);
+
+ listen_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ IPERF_GOTO_ON_FALSE((listen_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket created");
+
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ err = bind(listen_socket, (struct sockaddr *)&listen_addr6, sizeof(struct sockaddr_in6));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to bind: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket bound, port %d", listen_addr6.sin6_port);
+
+ memcpy(&listen_addr, &listen_addr6, sizeof(listen_addr6));
+ } else
+#endif
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+ listen_addr4.sin_family = AF_INET;
+ listen_addr4.sin_port = htons(s_iperf_ctrl.cfg.sport);
+ listen_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.source_ip4;
+
+ listen_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ IPERF_GOTO_ON_FALSE((listen_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket created");
+
+ setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+ err = bind(listen_socket, (struct sockaddr *)&listen_addr4, sizeof(struct sockaddr_in));
+ IPERF_GOTO_ON_FALSE((err == 0), IPERF_FAIL, exit, TAG, "Socket unable to bind: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket bound, port %d", listen_addr4.sin_port);
+ memcpy(&listen_addr, &listen_addr4, sizeof(listen_addr4));
+ }
+
+ timeout.tv_sec = IPERF_SOCKET_RX_TIMEOUT;
+ setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ socket_recv(listen_socket, listen_addr, IPERF_TRANS_TYPE_UDP);
+exit:
+ if (listen_socket != -1) {
+ shutdown(listen_socket, 0);
+ close(listen_socket);
+ }
+ IPERF_LOGI(TAG, "Udp socket server is closed.");
+ s_iperf_ctrl.finish = true;
+ return ret;
+}
+
+static iperf_err_t iperf_run_udp_client(void)
+{
+ int client_socket = -1;
+ int opt = 1;
+ iperf_err_t ret = IPERF_OK;
+ struct sockaddr_storage dest_addr = { 0 };
+#if IPERF_V6
+ struct sockaddr_in6 dest_addr6 = { 0 };
+#endif
+ struct sockaddr_in dest_addr4 = { 0 };
+
+ IPERF_GOTO_ON_FALSE((s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6 || s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4), IPERF_FAIL, exit, TAG, "Ivalid AF types");
+
+#if IPERF_V6
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV6) {
+ inet6_aton(s_iperf_ctrl.cfg.destination_ip6, &dest_addr6.sin6_addr);
+ dest_addr6.sin6_family = AF_INET6;
+ dest_addr6.sin6_port = htons(s_iperf_ctrl.cfg.dport);
+
+ client_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket created, sending to %s:%d", s_iperf_ctrl.cfg.destination_ip6, s_iperf_ctrl.cfg.dport);
+
+ setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ opt = s_iperf_ctrl.cfg.tos;
+ setsockopt(client_socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt));
+ memcpy(&dest_addr, &dest_addr6, sizeof(dest_addr6));
+ } else
+#endif
+ if (s_iperf_ctrl.cfg.type == IPERF_IP_TYPE_IPV4) {
+ dest_addr4.sin_family = AF_INET;
+ dest_addr4.sin_port = htons(s_iperf_ctrl.cfg.dport);
+ dest_addr4.sin_addr.s_addr = s_iperf_ctrl.cfg.destination_ip4;
+
+ client_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ IPERF_GOTO_ON_FALSE((client_socket >= 0), IPERF_FAIL, exit, TAG, "Unable to create socket: errno %d", errno);
+ IPERF_LOGI(TAG, "Socket created, sending to %d:%d", s_iperf_ctrl.cfg.destination_ip4, s_iperf_ctrl.cfg.dport);
+
+ setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ opt = s_iperf_ctrl.cfg.tos;
+ setsockopt(client_socket, IPPROTO_IP, IP_TOS, &opt, sizeof(opt));
+ memcpy(&dest_addr, &dest_addr4, sizeof(dest_addr4));
+ }
+
+ socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_UDP, s_iperf_ctrl.cfg.bw_lim);
+exit:
+ if (client_socket != -1) {
+ shutdown(client_socket, 0);
+ close(client_socket);
+ }
+ s_iperf_ctrl.finish = true;
+ IPERF_LOGI(TAG, "UDP Socket client is closed");
+ return ret;
+}
+
+static void iperf_task_traffic(void *arg)
+{
+ if (iperf_is_udp_client()) {
+ iperf_run_udp_client();
+ } else if (iperf_is_udp_server()) {
+ iperf_run_udp_server();
+ } else if (iperf_is_tcp_client()) {
+ iperf_run_tcp_client();
+ } else {
+ iperf_run_tcp_server();
+ }
+
+ if (s_iperf_ctrl.buffer) {
+ vPortFree(s_iperf_ctrl.buffer);
+ s_iperf_ctrl.buffer = NULL;
+ }
+ printf("iperf exit\r\n");
+ s_iperf_is_running = false;
+ vTaskDelete(NULL);
+}
+
+static uint32_t iperf_get_buffer_len(void)
+{
+ if (iperf_is_udp_client()) {
+ return (s_iperf_ctrl.cfg.len_buf == 0 ? IPERF_UDP_TX_LEN : s_iperf_ctrl.cfg.len_buf);
+ } else if (iperf_is_udp_server()) {
+ return IPERF_UDP_RX_LEN;
+ } else if (iperf_is_tcp_client()) {
+ return (s_iperf_ctrl.cfg.len_buf == 0 ? IPERF_TCP_TX_LEN : s_iperf_ctrl.cfg.len_buf);
+ } else {
+ return (s_iperf_ctrl.cfg.len_buf == 0 ? IPERF_TCP_RX_LEN : s_iperf_ctrl.cfg.len_buf);
+ }
+ return 0;
+}
+
+static void net_iperf_print_header(iperf_cfg_t *cfg)
+{
+ printf("------------------------------------------------------------\r\n");
+ if (iperf_is_udp_server()) {
+ printf("Server listening on UDP port %d\r\n",
+ cfg->sport);
+ } else if (iperf_is_tcp_server()) {
+ printf("Server listening on TCP port %d\r\n",
+ cfg->sport);
+ } else if (iperf_is_udp_client()) {
+ printf("Client connecting to %s, UDP port %d\r\n"
+ "Sending %d byte datagrams\r\n",
+ inet_ntoa(cfg->destination_ip4),
+ cfg->dport, cfg->num_bytes);
+ } else if (iperf_is_tcp_client()) {
+ printf("Client connecting to %s, TCP port %d\r\n",
+ inet_ntoa(cfg->destination_ip4), cfg->dport);
+ }
+ printf("------------------------------------------------------------\r\n");
+}
+
+iperf_err_t iperf_start(iperf_cfg_t *cfg)
+{
+ BaseType_t ret;
+
+ if (!cfg) {
+ return IPERF_FAIL;
+ }
+
+ if (s_iperf_is_running) {
+ IPERF_LOGW(TAG, "iperf is running");
+ printf("iperf is running\r\n");
+ return IPERF_FAIL;
+ }
+
+ memset(&s_iperf_ctrl, 0, sizeof(s_iperf_ctrl));
+ memcpy(&s_iperf_ctrl.cfg, cfg, sizeof(*cfg));
+ s_iperf_is_running = true;
+ s_iperf_ctrl.finish = false;
+ s_iperf_ctrl.buffer_len = iperf_get_buffer_len();
+ s_iperf_ctrl.buffer = (uint8_t *)pvPortMalloc(s_iperf_ctrl.buffer_len);
+ if (!s_iperf_ctrl.buffer) {
+ IPERF_LOGE(TAG, "create buffer: not enough memory");
+ return IPERF_FAIL;
+ }
+ memset(s_iperf_ctrl.buffer, 0, s_iperf_ctrl.buffer_len);
+ ret = xTaskCreatePinnedToCore(iperf_task_traffic, IPERF_TRAFFIC_TASK_NAME, IPERF_TRAFFIC_TASK_STACK, NULL, s_iperf_ctrl.cfg.traffic_task_priority, NULL, portNUM_PROCESSORS - 1);
+ if (ret != pdPASS) {
+ IPERF_LOGE(TAG, "create task %s failed", IPERF_TRAFFIC_TASK_NAME);
+ vPortFree(s_iperf_ctrl.buffer);
+ s_iperf_ctrl.buffer = NULL;
+ return IPERF_FAIL;
+ }
+ net_iperf_print_header(cfg);
+ return IPERF_OK;
+}
+
+iperf_err_t iperf_stop(void)
+{
+ if (s_iperf_is_running) {
+ s_iperf_ctrl.finish = true;
+ }
+
+ return IPERF_OK;
+}
diff --git a/tests/hpmicro/src/iperf/iperf.h b/tests/hpmicro/src/iperf/iperf.h
new file mode 100644
index 00000000..ea69b4ba
--- /dev/null
+++ b/tests/hpmicro/src/iperf/iperf.h
@@ -0,0 +1,82 @@
+/* Iperf Example - iperf declaration
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#ifndef __IPERF_H_
+#define __IPERF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IPERF_IP_TYPE_IPV4 0
+#define IPERF_IP_TYPE_IPV6 1
+#define IPERF_TRANS_TYPE_TCP 0
+#define IPERF_TRANS_TYPE_UDP 1
+
+#define IPERF_FLAG_SET(cfg, flag) ((cfg) |= (flag))
+#define IPERF_FLAG_CLR(cfg, flag) ((cfg) &= (~(flag)))
+
+#define IPERF_FLAG_CLIENT (1)
+#define IPERF_FLAG_SERVER (1 << 1)
+#define IPERF_FLAG_TCP (1 << 2)
+#define IPERF_FLAG_UDP (1 << 3)
+#define IPERF_FLAG_DUAL (1 << 4)
+
+#define IPERF_DEFAULT_PORT 5001
+#define IPERF_DEFAULT_INTERVAL 1
+#define IPERF_DEFAULT_TIME 10
+#define IPERF_DEFAULT_NO_BW_LIMIT -1
+
+#define IPERF_TRAFFIC_TASK_NAME "iperf_traffic"
+#define IPERF_TRAFFIC_TASK_PRIORITY 10
+#define IPERF_TRAFFIC_TASK_STACK 2048
+#define IPERF_REPORT_TASK_NAME "iperf_report"
+#define IPERF_REPORT_TASK_STACK 2048
+
+#define IPERF_UDP_TX_LEN (1470)
+#define IPERF_UDP_RX_LEN (1470)
+#define IPERF_TCP_TX_LEN (8 << 10)
+#define IPERF_TCP_RX_LEN (8 << 10)
+
+#define IPERF_MAX_DELAY 64
+
+#define IPERF_SOCKET_RX_TIMEOUT 10
+#define IPERF_SOCKET_ACCEPT_TIMEOUT 5
+
+typedef struct {
+ uint32_t flag;
+ union {
+ uint32_t destination_ip4;
+ char *destination_ip6;
+ };
+ union {
+ uint32_t source_ip4;
+ char *source_ip6;
+ };
+ uint8_t type;
+ uint16_t dport;
+ uint16_t sport;
+ uint32_t interval;
+ uint32_t time;
+ uint16_t len_buf;
+ int32_t bw_lim;
+ uint8_t tos;
+ uint8_t traffic_task_priority;
+ uint32_t num_bytes;
+} iperf_cfg_t;
+
+int iperf_start(iperf_cfg_t *cfg);
+
+int iperf_stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tests/hpmicro/src/iperf/iperf_cli.c b/tests/hpmicro/src/iperf/iperf_cli.c
new file mode 100644
index 00000000..8db3e050
--- /dev/null
+++ b/tests/hpmicro/src/iperf/iperf_cli.c
@@ -0,0 +1,115 @@
+#include <string.h>
+#include <stdint.h>
+#include <utils_getopt.h>
+#include <iperf.h>
+#include <lwip/ip_addr.h>
+
+#define NL "\r\n"
+
+static void iperf_cmd(int argc, char **argv)
+{
+ int opt;
+ getopt_env_t opt_env;
+ int o_c = 0, o_s = 0, o_u = 0, o_a = 0;
+ int o_p = IPERF_DEFAULT_PORT, o_l = 0, o_i = IPERF_DEFAULT_INTERVAL, o_t = IPERF_DEFAULT_TIME, o_b = IPERF_DEFAULT_NO_BW_LIMIT, o_S = 0, o_n = 0;
+ int o_d = 0;
+ int o_P = IPERF_TRAFFIC_TASK_PRIORITY;
+ uint32_t dst_addr = 0;
+
+ iperf_cfg_t cfg;
+
+ utils_getopt_init(&opt_env, 0);
+ while ((opt = utils_getopt(&opt_env, argc, argv, ":c:sup:l:i:t:b:S:n:P:ad")) != -1) {
+ #define ARG_READ(v) v = atoi(opt_env.optarg)
+ switch (opt) {
+ case 'c':
+ ++o_c;
+ dst_addr = ipaddr_addr(opt_env.optarg);
+ break;
+ case 's': ++o_s; break;
+ case 'u': ++o_u; break;
+ case 'p': ARG_READ(o_p); break;
+ case 'l': ARG_READ(o_l); break;
+ case 'i': ARG_READ(o_i); break;
+ case 't': ARG_READ(o_t); break;
+ case 'b': ARG_READ(o_b); break;
+ case 'S': ARG_READ(o_S); break;
+ case 'n': ARG_READ(o_n); break;
+ case 'P': ARG_READ(o_P); break;
+ case 'd': ++o_d; break;
+ case 'a': ++o_a; break;
+ }
+ #undef ARG_READ
+ }
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.type = IPERF_IP_TYPE_IPV4;
+
+ if (o_a) {
+ iperf_stop();
+ return;
+ }
+ if (!((o_c && !o_s) || (!o_c && o_s))) {
+ printf("client/server required" NL);
+ return;
+ }
+ if (o_c) {
+ cfg.destination_ip4 = dst_addr;
+ cfg.flag |= IPERF_FLAG_CLIENT;
+ } else {
+ cfg.flag |= IPERF_FLAG_SERVER;
+ }
+ if (o_u) {
+ cfg.flag |= IPERF_FLAG_UDP;
+ } else {
+ cfg.flag |= IPERF_FLAG_TCP;
+ }
+
+ if (o_c && !o_u && o_d) {
+ cfg.flag |= IPERF_FLAG_DUAL;
+ }
+
+ cfg.len_buf = o_l;
+ cfg.sport = o_p;
+ cfg.dport = o_p;
+ cfg.interval = o_i;
+ cfg.time = o_t;
+ if (cfg.time < cfg.interval) {
+ cfg.time = cfg.interval;
+ }
+ cfg.bw_lim = o_b;
+ cfg.tos = o_S;
+ cfg.num_bytes = o_n * 1000 * 1000;
+ if (cfg.bw_lim <= 0) {
+ cfg.bw_lim = IPERF_DEFAULT_NO_BW_LIMIT;
+ }
+ cfg.traffic_task_priority = o_P;
+
+ iperf_start(&cfg);
+}
+
+#include <shell.h>
+#define ML(s) s NL
+#define IPERF_USAGE \
+ ML("iperf") \
+ ML(" -c server_addr: run in client mode") \
+ ML(" -s: run in server mode") \
+ ML(" -u: UDP") \
+ ML(" -p port: specify port") \
+ ML(" -l length: set read/write buffer size") \
+ ML(" -i interval: seconds between bandwidth reports") \
+ ML(" -t time: time in seconds to run") \
+ ML(" -b bandwith: bandwidth to send in Mbps") \
+ ML(" -S tos: TOS") \
+ ML(" -n MB: number of MB to send/recv") \
+ ML(" -P priority: traffic task priority") \
+ ML(" -d: dual mode") \
+ ML(" -a: abort running iperf") \
+
+#if 0
+const static struct cli_command iperf_cmds[] STATIC_CLI_CMD_ATTRIBUTE = {
+ {"iperf", IPERF_USAGE, iperf_cmd},
+};
+#endif
+CSH_CMD_EXPORT_ALIAS(iperf_cmd, iperf, iperf command);
+
diff --git a/tests/hpmicro/src/iperf/utils_getopt.c b/tests/hpmicro/src/iperf/utils_getopt.c
new file mode 100644
index 00000000..f012b67c
--- /dev/null
+++ b/tests/hpmicro/src/iperf/utils_getopt.c
@@ -0,0 +1,377 @@
+/*
+ * This file is derived from musl v1.2.0.
+ * Modifications are applied.
+ * Copyright (C) Bouffalo Lab 2016-2020
+ */
+
+/*
+ * Copyright © 2005-2020 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <utils_getopt.h>
+
+int utils_getopt_init(getopt_env_t *env, int opterr)
+{
+ if (!env) {
+ return -1;
+ }
+ env->optarg = NULL;
+ env->optind = 1;
+ env->opterr = opterr;
+ env->optopt = 0;
+ env->__optpos = 0;
+ return 0;
+}
+
+#define NEWLINE "\r\n"
+
+int utils_getopt(getopt_env_t *env, int argc, char *const argv[], const char *optstring)
+{
+ int i;
+ char c, d;
+ char *optchar;
+
+ if (!env) {
+ return -1;
+ }
+
+ if (env->optind >= argc || !argv[env->optind])
+ return -1;
+
+ if (argv[env->optind][0] != '-') {
+ if (optstring[0] == '-') {
+ env->optarg = argv[env->optind++];
+ return 1;
+ }
+ return -1;
+ }
+
+ if (!argv[env->optind][1])
+ return -1;
+
+ if (argv[env->optind][1] == '-' && !argv[env->optind][2])
+ return env->optind++, -1;
+
+ if (!env->__optpos)
+ env->__optpos++;
+ c = argv[env->optind][env->__optpos];
+ optchar = argv[env->optind] + env->__optpos;
+ env->__optpos += !!c;
+
+ if (!argv[env->optind][env->__optpos]) {
+ env->optind++;
+ env->__optpos = 0;
+ }
+
+ if (optstring[0] == '-' || optstring[0] == '+')
+ optstring++;
+
+ i = 0;
+ do
+ d = optstring[i++];
+ while (d && d != c);
+
+ if (d != c || c == ':') {
+ env->optopt = c;
+ if (optstring[0] != ':' && env->opterr)
+ printf("%s: unrecognized option: %c" NEWLINE, argv[0], *optchar);
+ return '?';
+ }
+ if (optstring[i] == ':') {
+ env->optarg = 0;
+ if (optstring[i + 1] != ':' || env->__optpos) {
+ env->optarg = argv[env->optind++] + env->__optpos;
+ env->__optpos = 0;
+ }
+ if (env->optind > argc) {
+ env->optopt = c;
+ if (optstring[0] == ':')
+ return ':';
+ if (env->opterr) {
+ printf("%s: option requires an argument: %c" NEWLINE, argv[0], *optchar);
+ }
+ return '?';
+ }
+ }
+ return c;
+}
+
+static int params_filter(char **params, uint32_t *r)
+{
+ char *p;
+ uint32_t result = 0;
+ uint8_t base = 0;
+
+ p = *params;
+
+ if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X'))) {
+ p = p + 2;
+ base = 16;
+
+ } else {
+ base = 10;
+ }
+
+ while (*p) {
+ result *= base;
+ if (*p >= '0' && *p <= '9')
+ result += *p - '0';
+ else if (base == 10)
+ return -1;
+
+ if (base == 16) {
+ if (*p >= 'a' && *p <= 'f')
+ result += *p - 'a' + 10;
+ else if (*p >= 'A' && *p <= 'F')
+ result += *p - 'A' + 10;
+ }
+ p++;
+ }
+
+ *r = result;
+ return 0;
+}
+
+void get_bytearray_from_string(char **params, uint8_t *result, int array_size)
+{
+ int i = 0;
+ char rand[3];
+
+ for (i = 0; i < array_size; i++) {
+ memcpy(rand, *params, 2);
+ rand[2] = '\0';
+ result[i] = strtol(rand, NULL, 16);
+ *params = *params + 2;
+ }
+}
+
+void get_uint8_from_string(char **params, uint8_t *result)
+{
+ uint32_t p = 0;
+ int state = 0;
+
+ state = params_filter(params, &p);
+ if (!state) {
+ *result = p & 0xff;
+ } else
+ *result = 0;
+}
+
+void get_uint16_from_string(char **params, uint16_t *result)
+{
+ uint32_t p = 0;
+ int state = 0;
+
+ state = params_filter(params, &p);
+ if (!state) {
+ *result = p & 0xffff;
+ } else
+ *result = 0;
+}
+
+void get_uint32_from_string(char **params, uint32_t *result)
+{
+ uint32_t p = 0;
+ int state = 0;
+
+ state = params_filter(params, &p);
+ if (!state) {
+ *result = p;
+ } else
+ *result = 0;
+}
+
+void utils_parse_number(const char *str, char sep, uint8_t *buf, int buflen, int base)
+{
+ int i;
+ for (i = 0; i < buflen; i++) {
+ buf[i] = (uint8_t)strtol(str, NULL, base);
+ str = strchr(str, sep);
+ if (str == NULL || *str == '\0') {
+ break;
+ }
+ str++;
+ }
+}
+
+void utils_parse_number_adv(const char *str, char sep, uint8_t *buf, int buflen, int base, int *count)
+{
+ int i;
+
+ for (i = 0; i < buflen; i++) {
+ buf[i] = (uint8_t)strtol(str, NULL, base);
+ str = strchr(str, sep);
+ if (str == NULL || *str == '\0') {
+ break;
+ }
+ str++;
+ }
+ *count = (i + 1);
+}
+
+unsigned long long convert_arrayToU64(uint8_t *inputArray)
+{
+ unsigned long long result = 0;
+ for (uint8_t i = 0; i < 8; i++) {
+ result <<= 8;
+ result |= (unsigned long long)inputArray[7 - i];
+ }
+
+ return result;
+}
+
+void convert_u64ToArray(unsigned long long inputU64, uint8_t result[8])
+{
+ for (int i = 0; i < 8; i++) {
+ result[i] = inputU64 >> (i * 8);
+ }
+}
+
+void utils_memdrain8(void *src, size_t len)
+{
+ volatile uint8_t *s = (uint8_t *)src;
+ uint8_t tmp;
+
+ while (len--) {
+ tmp = *s++;
+ }
+
+ (void)tmp;
+}
+
+void utils_memdrain16(void *src, size_t len)
+{
+ volatile uint16_t *s = (uint16_t *)src;
+ uint16_t tmp;
+
+ len >>= 1; //convert to half words
+
+ while (len--) {
+ tmp = *s++;
+ }
+
+ (void)tmp;
+}
+
+void utils_memdrain32(void *src, size_t len)
+{
+ volatile uint32_t *s = (uint32_t *)src;
+ uint32_t tmp;
+
+ len >>= 2; //convert to words
+
+ while (len--) {
+ tmp = *s++;
+ }
+
+ (void)tmp;
+}
+
+void utils_memdrain64(void *src, size_t len)
+{
+ volatile uint64_t *s = (uint64_t *)src;
+ uint64_t tmp;
+
+ len >>= 3; //convert to two words
+
+ while (len--) {
+ tmp = *s++;
+ }
+
+ (void)tmp;
+}
+
+void *utils_memdrain8_with_check(void *src, size_t len, uint8_t seq)
+{
+ volatile uint8_t *s = (uint8_t *)src;
+ uint8_t tmp;
+
+ (void)tmp;
+
+ while (len--) {
+ tmp = *s++;
+ if ((seq++) != tmp) {
+ return (uint8_t *)s - 1;
+ }
+ }
+
+ return NULL;
+}
+
+void *utils_memdrain16_with_check(void *src, size_t len, uint16_t seq)
+{
+ volatile uint16_t *s = (uint16_t *)src;
+ uint16_t tmp;
+ (void)tmp;
+
+ len >>= 1; //convert to half words
+
+ while (len--) {
+ tmp = *s++;
+ if ((seq++) != tmp) {
+ return (uint16_t *)s - 1;
+ }
+ }
+
+ return NULL;
+}
+
+void *utils_memdrain32_with_check(void *src, size_t len, uint32_t seq)
+{
+ volatile uint32_t *s = (uint32_t *)src;
+ uint32_t tmp;
+ (void)tmp;
+
+ len >>= 2; //convert to words
+
+ while (len--) {
+ tmp = *s++;
+ if ((seq++) != tmp) {
+ return (uint32_t *)s - 1;
+ }
+ }
+
+ return NULL;
+}
+
+void *utils_memdrain64_with_check(void *src, size_t len, uint64_t seq)
+{
+ volatile uint64_t *s = (uint64_t *)src;
+ uint64_t tmp;
+ (void)tmp;
+
+ len >>= 3; //convert to two words
+
+ while (len--) {
+ tmp = *s++;
+ if ((seq++) != tmp) {
+ return (uint64_t *)s - 1;
+ }
+ }
+
+ return NULL;
+}
diff --git a/tests/hpmicro/src/iperf/utils_getopt.h b/tests/hpmicro/src/iperf/utils_getopt.h
new file mode 100644
index 00000000..5f6c9c97
--- /dev/null
+++ b/tests/hpmicro/src/iperf/utils_getopt.h
@@ -0,0 +1,107 @@
+#ifndef __GETOPT_H__
+#define __GETOPT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Parameters needed to parse the command line
+ *
+ */
+typedef struct getopt_env {
+ char *optarg; /*!< if the option accepts parameters, then optarg point to the option parameter*/
+ int optind; /*!< current index of argv*/
+ int opterr; /*!< non-zero enable error message output, while 0,no error message output*/
+ int optopt; /*!< contain unrecognized option character*/
+ int __optpos;
+} getopt_env_t;
+
+/**
+ * @brief Initialize struct getopt_env
+ *
+ * @param env pointer to struct getopt_env
+ * @param opterr set error message output method
+ *
+ * @return
+ * - 0: success
+ * - -1: fail
+ */
+int utils_getopt_init(getopt_env_t *env, int opterr);
+
+/**
+ * @brief Parses the command-line arguments
+ *
+ * @param env pointer to struct getopt_env
+ * @param argc the argument count
+ * @param argv the argument array
+ *
+ * @return
+ * - option character : an option was successfully found
+ * - -1 : all command-line options have been parsed
+ * - '?' : option character was not in optstring
+ * - ':' or '?' : If utils_getopt() encounters an option with a missing argument, then the return value depends on the first character in optstring: if it is ':', then ':' is returned; otherwise '?' is returned
+ *
+ * @note Example
+ * @code
+ *
+ * #include <utils_getopt.h>
+ * #include <stdio.h>
+ *
+ * void cmd(char *buf, int len, int argc, char **argv)
+ * {
+ * int opt;
+ getopt_env_t getopt_env;
+ utils_getopt_init(&getopt_env, 0);
+ * //put ':' in the starting of the string so that program can distinguish between '?' and ':'
+ * while ((opt = utils_getopt(&getopt_env, argc, argv, ":if:lr")) != -1) {
+ * switch(opt)
+ * {
+ * case 'i':
+ * case 'l':
+ * case 'r':
+ * printf("option: %c\r\n", opt);
+ * break;
+ * case 'f':
+ * printf("filename: %s\r\n", getopt_env.optarg);
+ * break;
+ * case ':':
+ printf("%s: %c requires an argument\r\n", *argv, getopt_env.optopt);
+ * break;
+ * case '?':
+ * printf("unknow option: %c\r\n", getopt_env.optopt);
+ * break;
+ * }
+ * }
+ * //optind is for the extra arguments which are not parsed
+ * for(; getopt_env.optind < argc; getopt_env.optind++){
+ * printf("extra arguments: %s\r\n", argv[getopt_env.optind]);
+ * }
+ *
+ * }
+ * @endcode
+ */
+int utils_getopt(getopt_env_t *env, int argc, char *const argv[], const char *optstring);
+
+void get_bytearray_from_string(char **params, uint8_t *result, int array_size);
+void get_uint8_from_string(char **params, uint8_t *result);
+void get_uint16_from_string(char **params, uint16_t *result);
+void get_uint32_from_string(char **params, uint32_t *result);
+void utils_parse_number(const char *str, char sep, uint8_t *buf, int buflen, int base);
+void utils_parse_number_adv(const char *str, char sep, uint8_t *buf, int buflen, int base, int *count);
+unsigned long long convert_arrayToU64(uint8_t *inputArray);
+void convert_u64ToArray(unsigned long long inputU64, uint8_t result[8]);
+void utils_memdrain8(void *src, size_t len);
+void utils_memdrain16(void *src, size_t len);
+void utils_memdrain32(void *src, size_t len);
+void utils_memdrain64(void *src, size_t len);
+void *utils_memdrain8_with_check(void *src, size_t len, uint8_t seq);
+void *utils_memdrain16_with_check(void *src, size_t len, uint16_t seq);
+void *utils_memdrain32_with_check(void *src, size_t len, uint32_t seq);
+void *utils_memdrain64_with_check(void *src, size_t len, uint64_t seq);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __GETOPT_H__ */
diff --git a/tests/hpmicro/src/main.c b/tests/hpmicro/src/main.c
index 3572bae0..679d65ae 100644
--- a/tests/hpmicro/src/main.c
+++ b/tests/hpmicro/src/main.c
@@ -13,9 +13,14 @@
#include <stdio.h>
#include "board.h"
#include "hpm_clock_drv.h"
+#include "hpm_l1c_drv.h"
#include "shell.h"
#include "usbh_core.h"
#include "lwip/tcpip.h"
+#ifdef CONFIG_USB_EHCI_ISO
+#include "usbh_uvc_stream.h"
+#include "usbh_uac_stream.h"
+#endif
SDK_DECLARE_EXT_ISR_M(BOARD_CONSOLE_UART_IRQ, shell_uart_isr)
@@ -36,7 +41,11 @@ int main(void)
tcpip_init(NULL, NULL);
printf("Start usb host task...\r\n");
+#ifdef CONFIG_USB_EHCI_ISO
+ extern void uvc2lcd_init(void);
+ uvc2lcd_init();
+#endif
usbh_initialize(0, CONFIG_HPM_USBH_BASE, NULL);
if (pdPASS != xTaskCreate(task_start, "task_start", 1024U, NULL, task_start_PRIORITY, NULL)) {
@@ -100,5 +109,96 @@ static void task_start(void *param)
vTaskDelete(NULL);
}
-extern int lsusb(int argc, char **argv);
-CSH_CMD_EXPORT(lsusb, ); \ No newline at end of file
+CSH_CMD_EXPORT(lsusb, );
+
+#ifdef CONFIG_USB_EHCI_ISO
+// clang-format off
+USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t src_buffer[1024 * 10];
+ATTR_PLACE_AT_WITH_ALIGNMENT(".framebuffer", 64) uint8_t dst_buffer[1024 * 10];
+// clang-format on
+
+void usb_dma_test()
+{
+ usbh_video_dma_init();
+ for (size_t i = 0; i < 10 * 1024; i++) {
+ src_buffer[i] = i & 0xff;
+ }
+ memset(dst_buffer, 0, 10 * 1024);
+
+ for (uint8_t i = 0; i < 10; i++) {
+ usbh_video_dma_lli_fill(i, (uint32_t)src_buffer + i * 1024, (uint32_t)dst_buffer + i * 1024, 1024);
+ }
+ volatile uint64_t start_tick = hpm_csr_get_core_mcycle();
+ usbh_video_dma_start();
+
+ while (usbh_video_dma_isbusy()) {
+ }
+ volatile uint64_t end_tick = hpm_csr_get_core_mcycle();
+
+ double consumed_seconds = (end_tick - start_tick) * 1.0l / (clock_get_frequency(clock_cpu0) / 1000000);
+ printf("dma done:%.2f us\n", consumed_seconds);
+ l1c_dc_invalidate((uint32_t)dst_buffer, 10 * 1024);
+ for (size_t i = 0; i < 10 * 1024; i++) {
+ if (dst_buffer[i] != src_buffer[i]) {
+ printf("error:%d\n", i);
+ break;
+ }
+ }
+}
+
+int dma_test(int argc, char **argv)
+{
+ usb_dma_test();
+ return 0;
+}
+CSH_CMD_EXPORT(dma_test, );
+
+int usbh_uvc_start(int argc, char **argv)
+{
+ uint8_t type;
+
+ if (argc < 2) {
+ USB_LOG_ERR("please input correct command: usbh_uvc_start type\r\n");
+ USB_LOG_ERR("type 0:yuyv, type 1:mjpeg\r\n");
+ return -1;
+ }
+
+ type = atoi(argv[1]);
+ usbh_video_stream_start(640, 480, type);
+ return 0;
+}
+
+CSH_CMD_EXPORT(usbh_uvc_start, usbh_uvc_start);
+
+int usbh_uvc_stop(int argc, char **argv)
+{
+ usbh_video_stream_stop();
+ return 0;
+}
+
+CSH_CMD_EXPORT(usbh_uvc_stop, usbh_uvc_stop);
+
+int usbh_uac_start(int argc, char **argv)
+{
+ uint32_t freq;
+
+ if (argc < 2) {
+ USB_LOG_ERR("please input correct command: usbh_uac_start freq\r\n");
+ return -1;
+ }
+
+ freq = atoi(argv[1]);
+ usbh_audio_mic_stream_start(freq);
+ return 0;
+}
+
+CSH_CMD_EXPORT(usbh_uac_start, usbh_uac_start);
+
+int usbh_uac_stop(int argc, char **argv)
+{
+ usbh_audio_mic_stream_stop();
+ return 0;
+}
+
+CSH_CMD_EXPORT(usbh_uac_stop, usbh_uac_stop);
+#endif \ No newline at end of file
diff --git a/tests/hpmicro/src/ping.c b/tests/hpmicro/src/ping.c
new file mode 100644
index 00000000..49e984a0
--- /dev/null
+++ b/tests/hpmicro/src/ping.c
@@ -0,0 +1,257 @@
+/*
+ * netutils: ping implementation
+ */
+
+#include <FreeRTOS.h>
+#include <task.h>
+
+#include <lwip/opt.h>
+#include <lwip/init.h>
+#include <lwip/mem.h>
+#include <lwip/icmp.h>
+#include <lwip/netif.h>
+#include <lwip/sys.h>
+#include <lwip/inet.h>
+#include <lwip/inet_chksum.h>
+#include <lwip/ip.h>
+#include <lwip/netdb.h>
+#include <lwip/sockets.h>
+
+/**
+ * PING_DEBUG: Enable debugging for PING.
+ */
+#ifndef PING_DEBUG
+#define PING_DEBUG LWIP_DBG_ON
+#endif
+
+/** ping receive timeout - in milliseconds */
+#define PING_RCV_TIMEO (2000 * portTICK_PERIOD_MS)
+/** ping delay - in milliseconds */
+#define PING_DELAY (1000 * portTICK_PERIOD_MS)
+
+/** ping identifier - must fit on a u16_t */
+#ifndef PING_ID
+#define PING_ID 0xAFAF
+#endif
+
+/** ping additional data size to include in the packet */
+#ifndef PING_DATA_SIZE
+#define PING_DATA_SIZE 32
+#endif
+
+/* ping variables */
+static u16_t ping_seq_num;
+struct _ip_addr {
+ uint8_t addr0, addr1, addr2, addr3;
+};
+
+/** Prepare a echo ICMP request */
+static void ping_prepare_echo(struct icmp_echo_hdr *iecho, u16_t len)
+{
+ size_t i;
+ size_t data_len = len - sizeof(struct icmp_echo_hdr);
+
+ ICMPH_TYPE_SET(iecho, ICMP_ECHO);
+ ICMPH_CODE_SET(iecho, 0);
+ iecho->chksum = 0;
+ iecho->id = PING_ID;
+ iecho->seqno = htons(++ping_seq_num);
+
+ /* fill the additional data buffer with some data */
+ for (i = 0; i < data_len; i++) {
+ ((char *)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
+ }
+
+ iecho->chksum = inet_chksum(iecho, len);
+}
+
+/* Ping using the socket ip */
+err_t lwip_ping_send(int s, ip_addr_t *addr, int size)
+{
+ int err;
+ struct icmp_echo_hdr *iecho;
+ struct sockaddr_in to;
+ int ping_size = sizeof(struct icmp_echo_hdr) + size;
+ LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
+
+ iecho = mem_malloc(ping_size);
+ if (iecho == NULL) {
+ return ERR_MEM;
+ }
+
+ ping_prepare_echo(iecho, (u16_t)ping_size);
+
+ to.sin_len = sizeof(to);
+ to.sin_family = AF_INET;
+#if LWIP_IPV4 && LWIP_IPV6
+ to.sin_addr.s_addr = addr->u_addr.ip4.addr;
+#elif LWIP_IPV4
+ to.sin_addr.s_addr = addr->addr;
+#elif LWIP_IPV6
+#error Not supported IPv6.
+#endif
+
+ err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr *)&to, sizeof(to));
+ mem_free(iecho);
+
+ return (err == ping_size ? ERR_OK : ERR_VAL);
+}
+
+int lwip_ping_recv(int s, int *ttl)
+{
+ char buf[64];
+ int fromlen = sizeof(struct sockaddr_in), len;
+ struct sockaddr_in from;
+ struct ip_hdr *iphdr;
+ struct icmp_echo_hdr *iecho;
+
+ while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, (socklen_t *)&fromlen)) > 0) {
+ if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) {
+ iphdr = (struct ip_hdr *)buf;
+ iecho = (struct icmp_echo_hdr *)(buf + (IPH_HL(iphdr) * 4));
+ if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num))) {
+ *ttl = iphdr->_ttl;
+ return len;
+ }
+ }
+ }
+
+ return len;
+}
+
+/* using the lwIP custom ping */
+uint32_t cmd_ping(char *target_name, uint16_t interval, uint16_t size, uint32_t count)
+{
+#if LWIP_VERSION_MAJOR >= 2U
+ struct timeval timeout = { PING_RCV_TIMEO / (1000 * portTICK_PERIOD_MS), PING_RCV_TIMEO % (1000 * portTICK_PERIOD_MS) };
+#else
+ int timeout = PING_RCV_TIMEO * 1000UL / (1000 * portTICK_PERIOD_MS);
+#endif
+
+ int s, ttl = 0, recv_len;
+ ip_addr_t target_addr;
+ uint32_t send_times;
+ uint32_t recv_start_tick;
+ struct addrinfo hint, *res = NULL;
+ struct sockaddr_in *h = NULL;
+ struct in_addr ina;
+
+ send_times = 0;
+ ping_seq_num = 0;
+
+ if (size == 0) {
+ size = PING_DATA_SIZE;
+ }
+
+ memset(&hint, 0, sizeof(hint));
+ /* convert URL to IP */
+ if (lwip_getaddrinfo(target_name, NULL, &hint, &res) != 0) {
+ printf("ping: unknown host %s\n\r", target_name);
+ return -1;
+ }
+ memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
+ memcpy(&ina, &h->sin_addr, sizeof(ina));
+ lwip_freeaddrinfo(res);
+ if (inet_aton(inet_ntoa(ina), &target_addr) == 0) {
+ printf("ping: unknown host %s\n\r", target_name);
+ return -1;
+ }
+ /* new a socket */
+ if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0) {
+ printf("ping: create socket failed\n\r");
+ return -1;
+ }
+
+ lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
+
+ while (1) {
+ int elapsed_time;
+
+ if (lwip_ping_send(s, &target_addr, size) == ERR_OK) {
+ recv_start_tick = sys_now();
+ if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0) {
+ elapsed_time = (sys_now() - recv_start_tick) * 1000UL / (1000 * portTICK_PERIOD_MS);
+ printf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n\r", recv_len, inet_ntoa(ina), send_times,
+ ttl, elapsed_time);
+ } else {
+ printf("From %s icmp_seq=%d timeout\n\r", inet_ntoa(ina), send_times);
+ }
+ } else {
+ printf("Send %s - error\n\r", inet_ntoa(ina));
+ }
+
+ send_times++;
+ if (send_times >= count) {
+ /* send ping times reached, stop */
+ break;
+ }
+
+ vTaskDelay(interval); /* take a delay */
+ }
+
+ lwip_close(s);
+
+ return 0;
+}
+
+#include <shell.h>
+#include "utils_getopt.h"
+
+#define PING_USAGE \
+"ping [-c count] [-i interval] [-s size] [-h help] destination\r\n" \
+"\t\t-c count of ping requests. default is 4\r\n" \
+"\t\t-i interval in ms. default is 1000\r\n" \
+"\t\t-s ICMP payload size in bytes. default is 32\r\n" \
+"\t\t-h print this help\r\n"
+
+int ping(int argc, char **argv)
+{
+ int opt;
+ getopt_env_t getopt_env;
+ u16_t interval = PING_DELAY;
+ u16_t data_size = PING_DATA_SIZE;
+ u32_t total_count = 4;
+
+ if (argc == 1) {
+ goto usage;
+ } else {
+ utils_getopt_init(&getopt_env, 0);
+
+ while ((opt = utils_getopt(&getopt_env, argc, argv, ":i:s:c:W:h")) != -1) {
+ switch (opt) {
+ case 'i':
+ interval = atoi(getopt_env.optarg);
+ break;
+ case 's':
+ data_size = atoi(getopt_env.optarg);
+ break;
+ case 'c':
+ total_count = atoi(getopt_env.optarg);
+ break;
+ case 'h':
+ goto usage;
+ case ':':
+ printf("%s: %c requires an argument\r\n", *argv, getopt_env.optopt);
+ goto usage;
+ case '?':
+ printf("%s: unknown option %c\r\n", *argv, getopt_env.optopt);
+ goto usage;
+ }
+ }
+
+ if (getopt_env.optind + 1 == argc) {
+ cmd_ping(argv[getopt_env.optind], interval, data_size, total_count);
+ } else {
+ printf("Need target address\r\n");
+ goto usage;
+ }
+ }
+
+ return 0;
+
+usage:
+ printf("%s", PING_USAGE);
+ return 0;
+}
+CSH_CMD_EXPORT(ping, ping network host);
+
diff --git a/tests/hpmicro/src/uvc2lcd.c b/tests/hpmicro/src/uvc2lcd.c
new file mode 100644
index 00000000..71d36865
--- /dev/null
+++ b/tests/hpmicro/src/uvc2lcd.c
@@ -0,0 +1,157 @@
+#include "board.h"
+#include "hpm_lcdc_drv.h"
+#include "hpm_l1c_drv.h"
+#include "usbh_uvc_stream.h"
+
+#define LCD BOARD_LCD_BASE
+#define PIXEL_FORMAT display_pixel_format_ycbcr422
+
+#define IMAGE_WIDTH 640
+#define IMAGE_HEIGHT 480
+
+static ATTR_PLACE_AT_WITH_ALIGNMENT(".framebuffer", 64) uint8_t frame_buffer1[IMAGE_WIDTH * IMAGE_HEIGHT * 2];
+static ATTR_PLACE_AT_WITH_ALIGNMENT(".framebuffer", 64) uint8_t frame_buffer2[IMAGE_WIDTH * IMAGE_HEIGHT * 2];
+static struct usbh_videoframe frame_pool[2];
+
+void writefont2screen(uint16_t or_x, uint16_t or_y, uint16_t x_end, uint16_t y_end, uint8_t assic_id, uint16_t colour,
+ uint8_t clearflag, uint8_t *str_font, uint32_t screen_addr, uint16_t font_size)
+{
+ uint8_t *strdisp;
+ uint16_t x, y;
+ uint8_t bit;
+ uint8_t temp1;
+ strdisp = (uint8_t *)screen_addr;
+ str_font += font_size * (assic_id - 0x20); /*get end encode*/
+ bit = 0;
+ for (y = or_y; y <= y_end; y++) {
+ for (x = or_x; x <= x_end; x++) {
+ if (clearflag == true) {
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x) = colour & 0x00ff;
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x + 1) = colour >> 8;
+ } else {
+ temp1 = (*str_font) >> bit;
+ if ((temp1 & 0x01) == 0x01) {
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x) = colour & 0x00ff;
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x + 1) = colour >> 8;
+ } else {
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x) = 0;
+ *(strdisp + y * (IMAGE_WIDTH * 2) + 2 * x + 1) = 0;
+ }
+ bit++;
+ if (bit == 8) {
+ bit = 0;
+ str_font += 1;
+ }
+ }
+ }
+ }
+}
+
+char string2font(uint16_t line, uint16_t column, uint8_t *string, uint8_t string_num, uint16_t colour,
+ uint8_t *str_font, uint32_t screen_addr, uint8_t font_width, uint8_t font_height)
+{
+ uint8_t i = 0, j = 0, numtemp = 0;
+ uint16_t or_x, or_y, x_end, y_end;
+ uint16_t font_stroage_size;
+ or_x = column * font_width;
+ or_y = line * font_height;
+ x_end = or_x + font_width - 1;
+ y_end = or_y + font_height - 1;
+ font_stroage_size = font_width * font_height / 8;
+ for (numtemp = 0; numtemp < string_num; numtemp++) {
+ if ((*(string + numtemp) != 10) && (*(string + numtemp) != 0)) { /*enter or end*/
+ if (*(string + numtemp) != 8) { /*delete*/
+ writefont2screen(or_x + font_width * i, or_y + font_height * j, x_end + font_width * i, y_end + font_height * j,
+ *(string + numtemp), colour, false, str_font, screen_addr, font_stroage_size);
+ } else {
+ writefont2screen(or_x + font_width * i, or_y + font_height * j, x_end + font_width * i, y_end + font_height * j,
+ *(string + numtemp), colour, true, str_font, screen_addr, font_stroage_size);
+ }
+ } else if (*(string + numtemp) == 10) {
+ i = 19; /* jump next line */
+ } else if (*(string + numtemp) == 0) {
+ return true;
+ }
+ i++;
+ if (i * font_width == IMAGE_WIDTH) {
+ j++;
+ i = 0;
+ }
+ }
+ return true;
+}
+
+extern const unsigned char nAsciiDot24x48[];
+extern volatile uint32_t g_uvc_fps;
+
+void usbh_video_run(struct usbh_video *video_class)
+{
+ usbh_video_stream_start(640, 480, USBH_VIDEO_FORMAT_UNCOMPRESSED);
+ lcdc_turn_on_display(LCD);
+}
+
+void usbh_video_stop(struct usbh_video *video_class)
+{
+ usbh_video_stream_stop();
+ lcdc_turn_off_display(LCD);
+}
+
+void usbh_video_frame_callback(struct usbh_videoframe *frame)
+{
+ char font_display_buf[50];
+
+ //USB_LOG_RAW("frame buf:%p,frame len:%d\r\n", frame->frame_buf, frame->frame_size);
+ l1c_dc_invalidate((uint32_t)frame->frame_buf, IMAGE_WIDTH * IMAGE_HEIGHT * 2);
+ sprintf(font_display_buf, "fps:%d", g_uvc_fps);
+ string2font(1, 1, (uint8_t *)font_display_buf, sizeof(font_display_buf), 0x001f, (uint8_t *)nAsciiDot24x48, (uint32_t)frame->frame_buf, 24, 48);
+ l1c_dc_writeback((uint32_t)frame->frame_buf, IMAGE_WIDTH * IMAGE_HEIGHT * 2);
+ lcdc_layer_set_next_buffer(LCD, 0, (uint32_t)frame->frame_buf);
+}
+
+void init_lcd(void)
+{
+ uint8_t layer_index = 0;
+ lcdc_config_t config = { 0 };
+ lcdc_layer_config_t layer = { 0 };
+
+ lcdc_get_default_config(LCD, &config);
+ board_panel_para_to_lcdc(&config);
+ lcdc_init(LCD, &config);
+
+ lcdc_get_default_layer_config(LCD, &layer, PIXEL_FORMAT, layer_index);
+
+ layer.position_x = (BOARD_LCD_WIDTH - IMAGE_WIDTH) / 2;
+ layer.position_y = (BOARD_LCD_HEIGHT - IMAGE_HEIGHT) / 2;
+ layer.width = IMAGE_WIDTH;
+ layer.height = IMAGE_HEIGHT;
+
+ layer.buffer = core_local_mem_to_sys_address(HPM_CORE0, (uint32_t)frame_buffer1);
+ layer.alphablend.src_alpha = 0xF4; /* src */
+ layer.alphablend.dst_alpha = 0xF0; /* dst */
+ layer.alphablend.src_alpha_op = display_alpha_op_override;
+ layer.alphablend.dst_alpha_op = display_alpha_op_override;
+ layer.background.u = 0xffff0000;
+ layer.alphablend.mode = display_alphablend_mode_xor;
+
+ if (status_success != lcdc_config_layer(LCD, layer_index, &layer, true)) {
+ printf("failed to configure layer\n");
+ while (1)
+ ;
+ }
+}
+
+void uvc2lcd_init(void)
+{
+ board_init_lcd();
+ init_lcd();
+
+ frame_pool[0].frame_buf = frame_buffer1;
+ frame_pool[0].frame_bufsize = IMAGE_WIDTH * IMAGE_HEIGHT * 2;
+ frame_pool[1].frame_buf = frame_buffer2;
+ frame_pool[1].frame_bufsize = IMAGE_WIDTH * IMAGE_HEIGHT * 2;
+
+ usbh_video_stream_init(5, frame_pool, 2);
+
+ extern void usbh_video_fps_init(void);
+ usbh_video_fps_init();
+} \ No newline at end of file